From a39b94c26f1fb3627b6edf6b6e08d37f00ecd543 Mon Sep 17 00:00:00 2001 From: yannickreiss Date: Thu, 5 Oct 2023 08:49:21 +0200 Subject: [PATCH] Fix jumping bug --- fpga/src/bfpu.vhd | 6 +- fpga/src/branch.vhd | 110 +++++++++++++++++++-------------- fpga/src/instructionMemory.vhd | 4 +- 3 files changed, 70 insertions(+), 50 deletions(-) diff --git a/fpga/src/bfpu.vhd b/fpga/src/bfpu.vhd index 7788ed4..6af19b6 100644 --- a/fpga/src/bfpu.vhd +++ b/fpga/src/bfpu.vhd @@ -73,6 +73,7 @@ architecture arch of bfpu is component branch port( clk : in std_logic; + state : in std_logic; instruction : in std_logic_vector(2 downto 0); instr_addr : in std_logic_vector(7 downto 0); cell_value : in std_logic_vector(7 downto 0); @@ -85,8 +86,8 @@ architecture arch of bfpu is end component; signal s_clk : std_logic; - signal s_in : std_logic_vector(7 downto 0); - signal s_out : std_logic_vector(7 downto 0); + signal s_in : std_logic_vector(7 downto 0) := (others => '0'); + signal s_out : std_logic_vector(7 downto 0) := (others => '0'); signal s_instrAddr : std_logic_vector(7 downto 0) := "00000000"; signal s_instruction : std_logic_vector(2 downto 0) := "000"; @@ -184,6 +185,7 @@ begin branch_bf : branch port map( clk => s_clk, + state => processor_state, instruction => s_instruction, instr_addr => s_instrAddr, cell_value => s_cell_out, diff --git a/fpga/src/branch.vhd b/fpga/src/branch.vhd index b49cdeb..d44b3ff 100644 --- a/fpga/src/branch.vhd +++ b/fpga/src/branch.vhd @@ -12,6 +12,7 @@ use ieee.numeric_std.all; entity branch is port( clk : in std_logic; + state : in std_logic; instruction : in std_logic_vector(2 downto 0); instr_addr : in std_logic_vector(7 downto 0); cell_value : in std_logic_vector(7 downto 0); @@ -27,76 +28,93 @@ end branch; architecture impl of branch is type stack is array(0 to 255) of std_logic_vector(7 downto 0); - signal addr_stack : stack := (others => (others => '0')); - signal nested : std_logic_vector(7 downto 0) := (others => '0'); -- count nested loops - signal skip_internal : std_logic := '0'; - signal stack_ptr : std_logic_vector(7 downto 0) := (others => '0'); - signal pc_enable_internal : std_logic := '1'; + signal addr_stack : stack := (others => (others => '0')); + signal nested : std_logic_vector(7 downto 0) := (others => '0'); -- count nested loops + signal skip_internal : std_logic := '0'; + signal stack_ptr : std_logic_vector(7 downto 0) := (others => '0'); + signal pc_enable_internal : std_logic := '1'; begin - -- Process p_branch: set skip to true - p_branch : process (clk, skip_internal, instruction, cell_value) + -- Process branch_compute Thing that does things. + branch_compute : process (all) -- runs only, when all changed begin if rising_edge(clk) then - if instruction = "110" and unsigned(cell_value) = 0 and unsigned(nested) = 0 and skip_internal = '0' then - skip_internal <= '1'; - end if; + -- set addr_stack + if skip = '0' then + -- pop part 1 - -- set skip to false - if instruction = "111" and unsigned(nested) = 0 and skip_internal = '1' then - skip_internal <= '0'; - end if; - - -- Process p_nest : raise nest by one as [ is passed - if instruction = "110" and skip_internal = '1' then - nested <= std_logic_vector(unsigned(nested) + 1); - end if; - - -- Process p_unnest : lower nest, as ] is passed - if instruction = "111" and unsigned(nested) > 0 and skip_internal = '1' then - nested <= std_logic_vector(unsigned(nested) - 1); - end if; - - -- Process p_push : raise stack and push address - if instruction = "110" and unsigned(cell_value) > 0 and skip_internal = '0' then - - if pc_enable_internal = '0' then - -- restore push_state and push address + -- push part 2 + if state = '1' and instruction = "110" then addr_stack(to_integer(unsigned(stack_ptr))) <= instr_addr; - pc_enable_internal <= '1'; - else - -- raise stack, disable pc and unset push_state - stack_ptr <= std_logic_vector(unsigned(stack_ptr) + 1); - pc_enable_internal <= '0'; end if; end if; - -- Process p_pop : read address to jump address and lower stack - if instruction = "111" and unsigned(cell_value) > 0 and skip_internal = '1' then - if pc_enable_internal = '0' then - -- set address to pc_out, disable pc and unset push_state - -- pc_out <= addr_stack(to_integer(unsigned(stack_ptr))); TODO: restore if error with continuous assignment - pc_enable_internal <= '1'; + -- set nested + if state = '0' and skip_internal = '1' then + + -- deeper nest + if instruction = "110" then + nested <= std_logic_vector(unsigned(nested) + 1); + end if; + + -- nested loop ended + if instruction = "111" then + nested <= std_logic_vector(unsigned(nested) - 1); + end if; + end if; + + -- set skip + -- on instruction [ + if instruction = "110" and state = '0' then + if unsigned(cell_value) > 0 and not ( skip_internal = '1' or unsigned(nested) > 0 ) then + skip_internal <= '0'; else - -- set pc to enabled, restore push_state and lower stack - pc_enable_internal <= '0'; + skip_internal <= '1'; + end if; + end if; + + -- on instruction ] + if state = '0' and instruction = "111" then + if skip_internal = '1' and unsigned(nested) > 0 then + skip_internal <= '1'; + else + skip_internal <= '0'; + end if; + end if; + + -- set stack_ptr + if skip_internal = '0' then + -- pop part 2 + if state = '1' and instruction = "111" then stack_ptr <= std_logic_vector(unsigned(stack_ptr) - 1); end if; + + -- push part 1 + if state = '0' and instruction = "110" then + stack_ptr <= std_logic_vector(unsigned(stack_ptr) + 1); + end if; end if; - -- regulate jump - if instruction = "111" and unsigned(cell_value) > 0 and skip_internal = '0' and pc_enable_internal = '1' then + + -- set pc_enable + pc_enable_internal <= not state; + + -- set jump + if instruction = "111" and skip = '0' and state = '0' then jump <= '1'; else jump <= '0'; end if; + + end if; end process; + -- connect signals to pins skip <= skip_internal; pc_enable <= pc_enable_internal; - pc_out <= addr_stack(to_integer(unsigned(stack_ptr))); + pc_out <= addr_stack(to_integer(unsigned(stack_ptr))); end impl; diff --git a/fpga/src/instructionMemory.vhd b/fpga/src/instructionMemory.vhd index f18aae7..1b70214 100644 --- a/fpga/src/instructionMemory.vhd +++ b/fpga/src/instructionMemory.vhd @@ -20,8 +20,8 @@ end instructionMemory; architecture arch of instructionMemory is type imem is array(0 to 255) of std_logic_vector(2 downto 0); - -- ,>+<.>. - signal memory : imem := (b"100", b"000", b"010", b"001", b"101", b"000", b"101", others => "000"); + -- +[+.] + signal memory : imem := (b"010", b"110", b"010", b"101", b"111", others => "000"); begin -- Process clk_read -- clk_read : process (clk) -- runs only, when clk changed