Fix jumping bug

This commit is contained in:
Yannick Reiß 2023-10-05 08:49:21 +02:00
parent b530f66702
commit a39b94c26f
No known key found for this signature in database
GPG Key ID: 5A3AF456F0A0338C
3 changed files with 70 additions and 50 deletions

View File

@ -73,6 +73,7 @@ architecture arch of bfpu is
component branch component branch
port( port(
clk : in std_logic; clk : in std_logic;
state : in std_logic;
instruction : in std_logic_vector(2 downto 0); instruction : in std_logic_vector(2 downto 0);
instr_addr : in std_logic_vector(7 downto 0); instr_addr : in std_logic_vector(7 downto 0);
cell_value : 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; end component;
signal s_clk : std_logic; signal s_clk : std_logic;
signal s_in : 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); signal s_out : std_logic_vector(7 downto 0) := (others => '0');
signal s_instrAddr : std_logic_vector(7 downto 0) := "00000000"; signal s_instrAddr : std_logic_vector(7 downto 0) := "00000000";
signal s_instruction : std_logic_vector(2 downto 0) := "000"; signal s_instruction : std_logic_vector(2 downto 0) := "000";
@ -184,6 +185,7 @@ begin
branch_bf : branch branch_bf : branch
port map( port map(
clk => s_clk, clk => s_clk,
state => processor_state,
instruction => s_instruction, instruction => s_instruction,
instr_addr => s_instrAddr, instr_addr => s_instrAddr,
cell_value => s_cell_out, cell_value => s_cell_out,

View File

@ -12,6 +12,7 @@ use ieee.numeric_std.all;
entity branch is entity branch is
port( port(
clk : in std_logic; clk : in std_logic;
state : in std_logic;
instruction : in std_logic_vector(2 downto 0); instruction : in std_logic_vector(2 downto 0);
instr_addr : in std_logic_vector(7 downto 0); instr_addr : in std_logic_vector(7 downto 0);
cell_value : 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 architecture impl of branch is
type stack is array(0 to 255) of std_logic_vector(7 downto 0); type stack is array(0 to 255) of std_logic_vector(7 downto 0);
signal addr_stack : stack := (others => (others => '0')); signal addr_stack : stack := (others => (others => '0'));
signal nested : std_logic_vector(7 downto 0) := (others => '0'); -- count nested loops signal nested : std_logic_vector(7 downto 0) := (others => '0'); -- count nested loops
signal skip_internal : std_logic := '0'; signal skip_internal : std_logic := '0';
signal stack_ptr : std_logic_vector(7 downto 0) := (others => '0'); signal stack_ptr : std_logic_vector(7 downto 0) := (others => '0');
signal pc_enable_internal : std_logic := '1'; signal pc_enable_internal : std_logic := '1';
begin begin
-- Process p_branch: set skip to true -- Process branch_compute Thing that does things.
p_branch : process (clk, skip_internal, instruction, cell_value) branch_compute : process (all) -- runs only, when all changed
begin begin
if rising_edge(clk) then if rising_edge(clk) then
if instruction = "110" and unsigned(cell_value) = 0 and unsigned(nested) = 0 and skip_internal = '0' then -- set addr_stack
skip_internal <= '1'; if skip = '0' then
end if; -- pop part 1
-- set skip to false -- push part 2
if instruction = "111" and unsigned(nested) = 0 and skip_internal = '1' then if state = '1' and instruction = "110" 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
addr_stack(to_integer(unsigned(stack_ptr))) <= instr_addr; 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;
end if; end if;
-- Process p_pop : read address to jump address and lower stack -- set nested
if instruction = "111" and unsigned(cell_value) > 0 and skip_internal = '1' then if state = '0' and skip_internal = '1' then
if pc_enable_internal = '0' then
-- set address to pc_out, disable pc and unset push_state -- deeper nest
-- pc_out <= addr_stack(to_integer(unsigned(stack_ptr))); TODO: restore if error with continuous assignment if instruction = "110" then
pc_enable_internal <= '1'; 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 else
-- set pc to enabled, restore push_state and lower stack skip_internal <= '1';
pc_enable_internal <= '0'; 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); stack_ptr <= std_logic_vector(unsigned(stack_ptr) - 1);
end if; 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; 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'; jump <= '1';
else else
jump <= '0'; jump <= '0';
end if; end if;
end if; end if;
end process; end process;
-- connect signals to pins
skip <= skip_internal; skip <= skip_internal;
pc_enable <= pc_enable_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; end impl;

View File

@ -20,8 +20,8 @@ end instructionMemory;
architecture arch of instructionMemory is architecture arch of instructionMemory is
type imem is array(0 to 255) of std_logic_vector(2 downto 0); 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 begin
-- Process clk_read -- Process clk_read
-- clk_read : process (clk) -- runs only, when clk changed -- clk_read : process (clk) -- runs only, when clk changed