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_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;

View File

@ -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;

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 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;

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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