From b530f66702307a8cfe214ea882ebddb6628aef6b Mon Sep 17 00:00:00 2001 From: yannickreiss Date: Wed, 4 Oct 2023 19:32:13 +0200 Subject: [PATCH] Implement state machine, arith and I/O instructions now working. --- fpga/Makefile | 14 +++++++ fpga/src/alu.vhd | 12 +++--- fpga/src/bfpu.vhd | 67 ++++++++++++++++++++++----------- fpga/src/branch.vhd | 69 ++++++++++++++++------------------ fpga/src/instructionMemory.vhd | 25 ++++++------ fpga/src/memoryPointer.vhd | 2 +- fpga/src/programCounter.vhd | 2 +- fpga/tb/tb_bfpu.vhd | 4 +- 8 files changed, 117 insertions(+), 78 deletions(-) create mode 100644 fpga/Makefile diff --git a/fpga/Makefile b/fpga/Makefile new file mode 100644 index 0000000..7f5df71 --- /dev/null +++ b/fpga/Makefile @@ -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 {} \; diff --git a/fpga/src/alu.vhd b/fpga/src/alu.vhd index 5f791b6..d6d36ad 100644 --- a/fpga/src/alu.vhd +++ b/fpga/src/alu.vhd @@ -36,35 +36,35 @@ begin new_pointer <= std_logic_vector(unsigned(old_pointer) + 1); new_cell <= old_cell; - buffer_out <= "00000000"; + -- buffer_out <= "00000000"; when "001" => enable_cell <= '0'; enable_ptr <= '1'; new_pointer <= std_logic_vector(unsigned(old_pointer) - 1); new_cell <= old_cell; - buffer_out <= "00000000"; + -- buffer_out <= "00000000"; when "010" => enable_cell <= '1'; enable_ptr <= '0'; new_cell <= std_logic_vector(unsigned(old_cell) + 1); new_pointer <= old_pointer; - buffer_out <= "00000000"; + -- buffer_out <= "00000000"; when "011" => enable_cell <= '1'; enable_ptr <= '0'; new_cell <= std_logic_vector(unsigned(old_cell) - 1); new_pointer <= old_pointer; - buffer_out <= "00000000"; + -- buffer_out <= "00000000"; when "100" => enable_cell <= '1'; enable_ptr <= '0'; new_cell <= extern_in; new_pointer <= old_pointer; - buffer_out <= "00000000"; + -- buffer_out <= "00000000"; when "101" => enable_cell <= '0'; enable_ptr <= '0'; @@ -78,7 +78,7 @@ begin new_pointer <= old_pointer; new_cell <= old_cell; - buffer_out <= "00000000"; + -- buffer_out <= "00000000"; end case; end process; diff --git a/fpga/src/bfpu.vhd b/fpga/src/bfpu.vhd index ce188a0..7788ed4 100644 --- a/fpga/src/bfpu.vhd +++ b/fpga/src/bfpu.vhd @@ -21,7 +21,6 @@ architecture arch of bfpu is component instructionMemory port( - clk : in std_logic; instructionAddr : in std_logic_vector(7 downto 0); instruction : out std_logic_vector(2 downto 0) ); @@ -86,32 +85,58 @@ architecture arch of bfpu is end component; signal s_clk : std_logic; - signal s_instrAddr : std_logic_vector(7 downto 0); - signal s_instruction : std_logic_vector(2 downto 0); + signal s_in : std_logic_vector(7 downto 0); + signal s_out : std_logic_vector(7 downto 0); - signal s_cell_out : std_logic_vector(7 downto 0); - signal s_cell_in : std_logic_vector(7 downto 0); - signal s_ptr_out : std_logic_vector(15 downto 0); - signal s_ptr_in : std_logic_vector(15 downto 0); + signal s_instrAddr : std_logic_vector(7 downto 0) := "00000000"; + signal s_instruction : std_logic_vector(2 downto 0) := "000"; - signal s_enable_cells : std_logic; - signal s_enable_ptr : std_logic; + signal s_cell_out : std_logic_vector(7 downto 0) := (others => '0'); + 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_jmp_pc : std_logic; - signal s_jmp_addr_pc : std_logic_vector(7 downto 0); + signal s_enable_cells : std_logic := '0'; + signal s_enable_ptr : std_logic := '0'; - signal s_skip : std_logic; - signal s_enable_cells_o : std_logic; - signal s_enable_ptr_o : std_logic; + signal s_enable_pc : std_logic := '1'; + signal s_jmp_pc : std_logic := '0'; + 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 + -- clock and state logic 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 port map( - clk => s_clk, instructionAddr => s_instrAddr, instruction => s_instruction ); @@ -121,13 +146,13 @@ begin instruction => s_instruction, old_cell => s_cell_out, old_pointer => s_ptr_out, - extern_in => sw, + extern_in => s_in, new_cell => s_cell_in, new_pointer => s_ptr_in, enable_cell => s_enable_cells_o, enable_ptr => s_enable_ptr_o, - extern_out => led + extern_out => s_out ); ptr_bf : ptr @@ -150,7 +175,7 @@ begin pc : program_counter port map( clk => s_clk, - enable => s_enable_pc, + enable => s_enable_pc and processor_state, jmp => s_jmp_pc, pc_in => s_jmp_addr_pc, pc_out => s_instrAddr @@ -168,8 +193,8 @@ begin pc_out => s_jmp_addr_pc ); - s_enable_ptr <= s_skip and s_enable_ptr_o; - s_enable_cells <= s_skip and s_enable_cells_o; + s_enable_ptr <= not s_skip and s_enable_ptr_o and processor_state; + s_enable_cells <= not s_skip and s_enable_cells_o and processor_state; debug <= s_cell_out; end arch; diff --git a/fpga/src/branch.vhd b/fpga/src/branch.vhd index cafd8d8..b49cdeb 100644 --- a/fpga/src/branch.vhd +++ b/fpga/src/branch.vhd @@ -31,6 +31,7 @@ architecture impl of branch is 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 @@ -38,61 +39,55 @@ begin p_branch : process (clk, skip_internal, instruction, cell_value) 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; - end if; - -- set skip to false - if rising_edge(clk) then + -- set skip to false if instruction = "111" and unsigned(nested) = 0 and skip_internal = '1' then skip_internal <= '0'; end if; - end if; - -- Process p_nest : raise nest by one as [ is passed - if rising_edge(clk) then + -- 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; - end if; - -- Process p_unnest : lower nest, as ] is passed - if rising_edge(clk) then + -- 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; - end if; - -- 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 pc_enable = '0' then - -- restore push_state and push address - addr_stack(to_integer(unsigned(stack_ptr))) <= instr_addr; - pc_enable <= '1'; - else - -- raise stack, disable pc and unset push_state - stack_ptr <= std_logic_vector(unsigned(stack_ptr) + 1); - pc_enable <= '0'; + -- 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; + 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; - -- 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 pc_enable = '0' then - -- set address to pc_out, disable pc and unset push_state - pc_out <= addr_stack(to_integer(unsigned(stack_ptr))); - pc_enable <= '1'; - else - -- set pc to enabled, restore push_state and lower stack - pc_enable <= '0'; - stack_ptr <= std_logic_vector(unsigned(stack_ptr) - 1); + -- 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'; + else + -- set pc to enabled, restore push_state and lower stack + pc_enable_internal <= '0'; + stack_ptr <= std_logic_vector(unsigned(stack_ptr) - 1); + end if; end if; - end if; - -- regulate jump - if rising_edge(clk) then - if instruction = "111" and unsigned(cell_value) > 0 and skip_internal = '0' and pc_enable = '1' then + -- regulate jump + if instruction = "111" and unsigned(cell_value) > 0 and skip_internal = '0' and pc_enable_internal = '1' then jump <= '1'; else jump <= '0'; @@ -100,6 +95,8 @@ begin end if; end process; - skip <= skip_internal; + skip <= skip_internal; + pc_enable <= pc_enable_internal; + pc_out <= addr_stack(to_integer(unsigned(stack_ptr))); end impl; diff --git a/fpga/src/instructionMemory.vhd b/fpga/src/instructionMemory.vhd index b30f97d..f18aae7 100644 --- a/fpga/src/instructionMemory.vhd +++ b/fpga/src/instructionMemory.vhd @@ -10,7 +10,6 @@ use ieee.numeric_std.all; entity instructionMemory is 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 instruction : out std_logic_vector(2 downto 0) -- instruction in current cell @@ -19,20 +18,22 @@ end instructionMemory; -- Architecture arch of instructionMemory: read on every clock cycle to instruction. architecture arch of instructionMemory is - + 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 -- Process clk_read - clk_read : process (clk) -- runs only, when clk changed - begin +-- clk_read : process (clk) -- runs only, when clk changed +-- begin +-- +-- if rising_edge(clk) then +-- +-- instruction <= memory(to_integer(unsigned(instructionAddr))); +-- +-- end if; +-- end process; - if rising_edge(clk) then - - instruction <= memory(to_integer(unsigned(instructionAddr))); - - end if; - end process; + instruction <= memory(to_integer(unsigned(instructionAddr))); end arch; diff --git a/fpga/src/memoryPointer.vhd b/fpga/src/memoryPointer.vhd index 857afa6..e63b258 100644 --- a/fpga/src/memoryPointer.vhd +++ b/fpga/src/memoryPointer.vhd @@ -19,7 +19,7 @@ end ptr; -- Architecture implement_ptr of ptr: 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 -- Process Write set new_ptr diff --git a/fpga/src/programCounter.vhd b/fpga/src/programCounter.vhd index 22e1d69..5846e07 100644 --- a/fpga/src/programCounter.vhd +++ b/fpga/src/programCounter.vhd @@ -23,7 +23,7 @@ architecture pc of program_counter is begin -- 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 if rising_edge(clk) and enable = '1' then if jmp = '1' then diff --git a/fpga/tb/tb_bfpu.vhd b/fpga/tb/tb_bfpu.vhd index 5b81fad..99a4641 100644 --- a/fpga/tb/tb_bfpu.vhd +++ b/fpga/tb/tb_bfpu.vhd @@ -28,13 +28,15 @@ architecture implementation of bfpu_tb is begin - uut : entity bfpu + uut : entity work.bfpu(arch) port map ( clk => clk, sw => sw, debug => debug, led => led); + sw <= "00110011"; + -- Clock process definitions clk_process : process begin