Implement state machine, arith and I/O instructions now working.

This commit is contained in:
Yannick Reiß 2023-10-04 19:32:13 +02:00
parent 65c6f85bb9
commit b530f66702
No known key found for this signature in database
GPG Key ID: 5A3AF456F0A0338C
8 changed files with 117 additions and 78 deletions

14
fpga/Makefile Normal file
View File

@ -0,0 +1,14 @@
CHDL = ghdl
FLAGS = --std=08
STOP = 9000ns
all: tb/tb_bfpu.vhd src/bfpu.vhd
$(CHDL) -a $(FLAGS) src/alu.vhd src/branch.vhd src/cellMemory.vhd src/instructionMemory.vhd src/memoryPointer.vhd src/programCounter.vhd src/bfpu.vhd tb/tb_bfpu.vhd
$(CHDL) -e $(FLAGS) bfpu_tb
$(CHDL) -r $(FLAGS) bfpu_tb --wave=bpfu.ghw --stop-time=$(STOP)
clean:
find . -name '*.o' -exec rm -r {} \;
find . -name '*.cf' -exec rm -r {} \;
find . -name '*.ghw' -exec rm -r {} \;
find . -name '*_tb' -exec rm -r {} \;

View File

@ -36,35 +36,35 @@ begin
new_pointer <= std_logic_vector(unsigned(old_pointer) + 1); new_pointer <= std_logic_vector(unsigned(old_pointer) + 1);
new_cell <= old_cell; new_cell <= old_cell;
buffer_out <= "00000000"; -- buffer_out <= "00000000";
when "001" => when "001" =>
enable_cell <= '0'; enable_cell <= '0';
enable_ptr <= '1'; enable_ptr <= '1';
new_pointer <= std_logic_vector(unsigned(old_pointer) - 1); new_pointer <= std_logic_vector(unsigned(old_pointer) - 1);
new_cell <= old_cell; new_cell <= old_cell;
buffer_out <= "00000000"; -- buffer_out <= "00000000";
when "010" => when "010" =>
enable_cell <= '1'; enable_cell <= '1';
enable_ptr <= '0'; enable_ptr <= '0';
new_cell <= std_logic_vector(unsigned(old_cell) + 1); new_cell <= std_logic_vector(unsigned(old_cell) + 1);
new_pointer <= old_pointer; new_pointer <= old_pointer;
buffer_out <= "00000000"; -- buffer_out <= "00000000";
when "011" => when "011" =>
enable_cell <= '1'; enable_cell <= '1';
enable_ptr <= '0'; enable_ptr <= '0';
new_cell <= std_logic_vector(unsigned(old_cell) - 1); new_cell <= std_logic_vector(unsigned(old_cell) - 1);
new_pointer <= old_pointer; new_pointer <= old_pointer;
buffer_out <= "00000000"; -- buffer_out <= "00000000";
when "100" => when "100" =>
enable_cell <= '1'; enable_cell <= '1';
enable_ptr <= '0'; enable_ptr <= '0';
new_cell <= extern_in; new_cell <= extern_in;
new_pointer <= old_pointer; new_pointer <= old_pointer;
buffer_out <= "00000000"; -- buffer_out <= "00000000";
when "101" => when "101" =>
enable_cell <= '0'; enable_cell <= '0';
enable_ptr <= '0'; enable_ptr <= '0';
@ -78,7 +78,7 @@ begin
new_pointer <= old_pointer; new_pointer <= old_pointer;
new_cell <= old_cell; new_cell <= old_cell;
buffer_out <= "00000000"; -- buffer_out <= "00000000";
end case; end case;
end process; end process;

View File

@ -21,7 +21,6 @@ architecture arch of bfpu is
component instructionMemory component instructionMemory
port( port(
clk : in std_logic;
instructionAddr : in std_logic_vector(7 downto 0); instructionAddr : in std_logic_vector(7 downto 0);
instruction : out std_logic_vector(2 downto 0) instruction : out std_logic_vector(2 downto 0)
); );
@ -86,32 +85,58 @@ architecture arch of bfpu is
end component; end component;
signal s_clk : std_logic; signal s_clk : std_logic;
signal s_instrAddr : std_logic_vector(7 downto 0); signal s_in : std_logic_vector(7 downto 0);
signal s_instruction : std_logic_vector(2 downto 0); signal s_out : std_logic_vector(7 downto 0);
signal s_cell_out : std_logic_vector(7 downto 0); signal s_instrAddr : std_logic_vector(7 downto 0) := "00000000";
signal s_cell_in : std_logic_vector(7 downto 0); signal s_instruction : std_logic_vector(2 downto 0) := "000";
signal s_ptr_out : std_logic_vector(15 downto 0);
signal s_ptr_in : std_logic_vector(15 downto 0);
signal s_enable_cells : std_logic; signal s_cell_out : std_logic_vector(7 downto 0) := (others => '0');
signal s_enable_ptr : std_logic; signal s_cell_in : std_logic_vector(7 downto 0) := (others => '0');
signal s_ptr_out : std_logic_vector(15 downto 0) := (others => '0');
signal s_ptr_in : std_logic_vector(15 downto 0) := (others => '0');
signal s_enable_pc : std_logic; signal s_enable_cells : std_logic := '0';
signal s_jmp_pc : std_logic; signal s_enable_ptr : std_logic := '0';
signal s_jmp_addr_pc : std_logic_vector(7 downto 0);
signal s_skip : std_logic; signal s_enable_pc : std_logic := '1';
signal s_enable_cells_o : std_logic; signal s_jmp_pc : std_logic := '0';
signal s_enable_ptr_o : std_logic; signal s_jmp_addr_pc : std_logic_vector(7 downto 0) := "00000000";
signal s_skip : std_logic := '0';
signal s_enable_cells_o : std_logic := '0';
signal s_enable_ptr_o : std_logic := '0';
signal processor_state : std_logic := '0'; -- 0: execute; 1: write back
begin begin
-- clock and state logic
s_clk <= clk; s_clk <= clk;
-- Process state change state between execute and write back
state : process (s_clk) -- runs only, when s_clk changed
begin
if rising_edge(s_clk) then
processor_state <= not processor_state;
end if;
end process;
-- Process in_out set in- and output on clk high and exec/write back
in_out : process (s_clk) -- runs only, when s_clk changed
begin
if rising_edge(s_clk) then
if processor_state = '1' then
led <= s_out;
else
s_in <= sw;
end if;
end if;
end process;
instrMemory : instructionMemory instrMemory : instructionMemory
port map( port map(
clk => s_clk,
instructionAddr => s_instrAddr, instructionAddr => s_instrAddr,
instruction => s_instruction instruction => s_instruction
); );
@ -121,13 +146,13 @@ begin
instruction => s_instruction, instruction => s_instruction,
old_cell => s_cell_out, old_cell => s_cell_out,
old_pointer => s_ptr_out, old_pointer => s_ptr_out,
extern_in => sw, extern_in => s_in,
new_cell => s_cell_in, new_cell => s_cell_in,
new_pointer => s_ptr_in, new_pointer => s_ptr_in,
enable_cell => s_enable_cells_o, enable_cell => s_enable_cells_o,
enable_ptr => s_enable_ptr_o, enable_ptr => s_enable_ptr_o,
extern_out => led extern_out => s_out
); );
ptr_bf : ptr ptr_bf : ptr
@ -150,7 +175,7 @@ begin
pc : program_counter pc : program_counter
port map( port map(
clk => s_clk, clk => s_clk,
enable => s_enable_pc, enable => s_enable_pc and processor_state,
jmp => s_jmp_pc, jmp => s_jmp_pc,
pc_in => s_jmp_addr_pc, pc_in => s_jmp_addr_pc,
pc_out => s_instrAddr pc_out => s_instrAddr
@ -168,8 +193,8 @@ begin
pc_out => s_jmp_addr_pc pc_out => s_jmp_addr_pc
); );
s_enable_ptr <= s_skip and s_enable_ptr_o; s_enable_ptr <= not s_skip and s_enable_ptr_o and processor_state;
s_enable_cells <= s_skip and s_enable_cells_o; s_enable_cells <= not s_skip and s_enable_cells_o and processor_state;
debug <= s_cell_out; debug <= s_cell_out;
end arch; end arch;

View File

@ -31,6 +31,7 @@ architecture impl of branch is
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';
begin begin
@ -38,61 +39,55 @@ begin
p_branch : process (clk, skip_internal, instruction, cell_value) p_branch : process (clk, skip_internal, instruction, cell_value)
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 if instruction = "110" and unsigned(cell_value) = 0 and unsigned(nested) = 0 and skip_internal = '0' then
skip_internal <= '1'; skip_internal <= '1';
end if; end if;
end if;
-- set skip to false -- set skip to false
if rising_edge(clk) then
if instruction = "111" and unsigned(nested) = 0 and skip_internal = '1' then if instruction = "111" and unsigned(nested) = 0 and skip_internal = '1' then
skip_internal <= '0'; skip_internal <= '0';
end if; end if;
end if;
-- Process p_nest : raise nest by one as [ is passed -- Process p_nest : raise nest by one as [ is passed
if rising_edge(clk) then
if instruction = "110" and skip_internal = '1' then if instruction = "110" and skip_internal = '1' then
nested <= std_logic_vector(unsigned(nested) + 1); nested <= std_logic_vector(unsigned(nested) + 1);
end if; end if;
end if;
-- Process p_unnest : lower nest, as ] is passed -- Process p_unnest : lower nest, as ] is passed
if rising_edge(clk) then
if instruction = "111" and unsigned(nested) > 0 and skip_internal = '1' then if instruction = "111" and unsigned(nested) > 0 and skip_internal = '1' then
nested <= std_logic_vector(unsigned(nested) - 1); nested <= std_logic_vector(unsigned(nested) - 1);
end if; end if;
end if;
-- Process p_push : raise stack and push address -- Process p_push : raise stack and push address
if rising_edge(clk) and instruction = "110" and unsigned(cell_value) > 0 and skip_internal = '0' then if instruction = "110" and unsigned(cell_value) > 0 and skip_internal = '0' then
if pc_enable = '0' then
if pc_enable_internal = '0' then
-- restore push_state and push address -- 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 <= '1'; pc_enable_internal <= '1';
else else
-- raise stack, disable pc and unset push_state -- raise stack, disable pc and unset push_state
stack_ptr <= std_logic_vector(unsigned(stack_ptr) + 1); stack_ptr <= std_logic_vector(unsigned(stack_ptr) + 1);
pc_enable <= '0'; pc_enable_internal <= '0';
end if; end if;
end if; end if;
-- Process p_pop : read address to jump address and lower stack -- Process p_pop : read address to jump address and lower stack
if rising_edge(clk) and instruction = "111" and unsigned(cell_value) > 0 and skip_internal = '0' then if instruction = "111" and unsigned(cell_value) > 0 and skip_internal = '1' then
if pc_enable = '0' then if pc_enable_internal = '0' then
-- set address to pc_out, disable pc and unset push_state -- set address to pc_out, disable pc and unset push_state
pc_out <= addr_stack(to_integer(unsigned(stack_ptr))); -- pc_out <= addr_stack(to_integer(unsigned(stack_ptr))); TODO: restore if error with continuous assignment
pc_enable <= '1'; pc_enable_internal <= '1';
else else
-- set pc to enabled, restore push_state and lower stack -- set pc to enabled, restore push_state and lower stack
pc_enable <= '0'; pc_enable_internal <= '0';
stack_ptr <= std_logic_vector(unsigned(stack_ptr) - 1); stack_ptr <= std_logic_vector(unsigned(stack_ptr) - 1);
end if; end if;
end if; end if;
-- regulate jump -- regulate jump
if rising_edge(clk) then if instruction = "111" and unsigned(cell_value) > 0 and skip_internal = '0' and pc_enable_internal = '1' then
if instruction = "111" and unsigned(cell_value) > 0 and skip_internal = '0' and pc_enable = '1' then
jump <= '1'; jump <= '1';
else else
jump <= '0'; jump <= '0';
@ -101,5 +96,7 @@ begin
end process; end process;
skip <= skip_internal; skip <= skip_internal;
pc_enable <= pc_enable_internal;
pc_out <= addr_stack(to_integer(unsigned(stack_ptr)));
end impl; end impl;

View File

@ -10,7 +10,6 @@ use ieee.numeric_std.all;
entity instructionMemory is entity instructionMemory is
port( port(
clk : in std_logic; -- clock with speed of board clock; Read on clock cycle
instructionAddr : in std_logic_vector(7 downto 0); -- We start with 256 instructions instructionAddr : in std_logic_vector(7 downto 0); -- We start with 256 instructions
instruction : out std_logic_vector(2 downto 0) -- instruction in current cell instruction : out std_logic_vector(2 downto 0) -- instruction in current cell
@ -21,18 +20,20 @@ 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"110", b"010", b"101", b"111", others => "000"); signal memory : imem := (b"100", b"000", b"010", b"001", b"101", b"000", b"101", 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
begin -- begin
--
if rising_edge(clk) then -- if rising_edge(clk) then
--
-- instruction <= memory(to_integer(unsigned(instructionAddr)));
--
-- end if;
-- end process;
instruction <= memory(to_integer(unsigned(instructionAddr))); instruction <= memory(to_integer(unsigned(instructionAddr)));
end if;
end process;
end arch; end arch;

View File

@ -19,7 +19,7 @@ end ptr;
-- Architecture implement_ptr of ptr: -- Architecture implement_ptr of ptr:
architecture implement_ptr of ptr is architecture implement_ptr of ptr is
signal reg : std_logic_vector(15 downto 0); signal reg : std_logic_vector(15 downto 0) := (others => '0');
begin begin
-- Process Write set new_ptr -- Process Write set new_ptr

View File

@ -23,7 +23,7 @@ architecture pc of program_counter is
begin begin
-- Process count -- Process count
count : process (clk, enable) -- runs only, when clk, enable, jmp changed count : process (clk, enable, jmp) -- runs only, when clk, enable, jmp changed
begin begin
if rising_edge(clk) and enable = '1' then if rising_edge(clk) and enable = '1' then
if jmp = '1' then if jmp = '1' then

View File

@ -28,13 +28,15 @@ architecture implementation of bfpu_tb is
begin begin
uut : entity bfpu uut : entity work.bfpu(arch)
port map ( port map (
clk => clk, clk => clk,
sw => sw, sw => sw,
debug => debug, debug => debug,
led => led); led => led);
sw <= "00110011";
-- Clock process definitions -- Clock process definitions
clk_process : process clk_process : process
begin begin