Merge branch 'fpga' into 'master'

Fpga

See merge request schnick/bfpu!3
This commit is contained in:
schnick 2023-10-05 10:32:02 +00:00
commit f05c1a9ae3
14 changed files with 196654 additions and 95 deletions

View File

@ -1,4 +1,9 @@
Endless loop Endless loop
Affect: cell(ptr) Affect: cell(ptr)
+[ >< ] +[]
If clause
Affects: cell(ptr); ???
[ do stuff here [-] ]

14
fpga/Makefile Normal file
View File

@ -0,0 +1,14 @@
CHDL = ghdl
FLAGS = --std=08
STOP = 90000ns
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)
); );
@ -74,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);
@ -86,32 +86,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) := (others => '0');
signal s_instruction : std_logic_vector(2 downto 0); signal s_out : std_logic_vector(7 downto 0) := (others => '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 +147,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 +176,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
@ -159,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,
@ -168,8 +195,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

@ -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,79 +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';
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
skip_internal <= '1';
end if;
end if;
-- set skip to false -- set addr_stack
if rising_edge(clk) then if skip = '0' then
if instruction = "111" and unsigned(nested) = 0 and skip_internal = '1' then -- pop part 1
skip_internal <= '0';
end if;
end if;
-- Process p_nest : raise nest by one as [ is passed -- push part 2
if rising_edge(clk) then if state = '1' and instruction = "110" then
if instruction = "110" and skip_internal = '1' then addr_stack(to_integer(unsigned(stack_ptr))) <= instr_addr;
nested <= std_logic_vector(unsigned(nested) + 1); end if;
end if; end if;
end if;
-- Process p_unnest : lower nest, as ] is passed -- set nested
if rising_edge(clk) then if state = '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); -- 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; end if;
end if;
-- Process p_push : raise stack and push address -- set skip
if rising_edge(clk) and instruction = "110" and unsigned(cell_value) > 0 and skip_internal = '0' then -- on instruction [
if pc_enable = '0' then if instruction = "110" and state = '0' then
-- restore push_state and push address if unsigned(cell_value) > 0 and not ( skip_internal = '1' or unsigned(nested) > 0 ) then
addr_stack(to_integer(unsigned(stack_ptr))) <= instr_addr; skip_internal <= '0';
pc_enable <= '1'; else
else skip_internal <= '1';
-- raise stack, disable pc and unset push_state end if;
stack_ptr <= std_logic_vector(unsigned(stack_ptr) + 1);
pc_enable <= '0';
end if; end if;
end if;
-- Process p_pop : read address to jump address and lower stack -- on instruction ]
if rising_edge(clk) and instruction = "111" and unsigned(cell_value) > 0 and skip_internal = '0' then if state = '0' and instruction = "111" then
if pc_enable = '0' then if skip_internal = '1' and unsigned(nested) > 0 then
-- set address to pc_out, disable pc and unset push_state skip_internal <= '1';
pc_out <= addr_stack(to_integer(unsigned(stack_ptr))); else
pc_enable <= '1'; skip_internal <= '0';
else end if;
-- set pc to enabled, restore push_state and lower stack
pc_enable <= '0';
stack_ptr <= std_logic_vector(unsigned(stack_ptr) - 1);
end if; end if;
end if;
-- regulate jump -- set stack_ptr
if rising_edge(clk) then if skip_internal = '0' then
if instruction = "111" and unsigned(cell_value) > 0 and skip_internal = '0' and pc_enable = '1' 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;
-- 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;
skip <= skip_internal; -- connect signals to pins
skip <= skip_internal;
pc_enable <= pc_enable_internal;
pc_out <= addr_stack(to_integer(unsigned(stack_ptr)));
end impl; end impl;

View File

@ -22,7 +22,7 @@ end cellblock;
-- Architecture arch of cellblock: read on every clock cycle to cell. -- Architecture arch of cellblock: read on every clock cycle to cell.
architecture arch of cellblock is architecture arch of cellblock is
type empty is array(0 to 65536) of std_logic_vector(7 downto 0); type empty is array(0 to 65535) of std_logic_vector(7 downto 0);
signal memory : empty := (others => (others => '0')); signal memory : empty := (others => (others => '0'));

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,19 @@ 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"010", b"110", b"000", b"010", b"101", b"001", b"111", others => "000");
signal memory : imem := (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
begin -- 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)));
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

59
fpga/tb/tb_bfpu.vhd Normal file
View File

@ -0,0 +1,59 @@
-- tb_bfpu
-- 2023-10-04
-- Author: Yannick Reiß
-- E-Mail: yannick.reiss@protonmail.ch
-- Copyright: MIT
-- Content: Entity tb_bfpu - Run bfpu for testbench.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library std;
use std.textio.all;
entity bfpu_tb is
end bfpu_tb;
architecture implementation of bfpu_tb is
-- input
signal clk : std_logic;
signal sw : std_logic_vector(7 downto 0);
-- output
signal debug : std_logic_vector(7 downto 0);
signal led : std_logic_vector(7 downto 0);
constant clk_period : time := 10 ns;
begin
uut : entity work.bfpu(arch)
port map (
clk => clk,
sw => sw,
debug => debug,
led => led);
sw <= "00001011";
-- Clock process definitions
clk_process : process
begin
clk <= '0';
wait for clk_period / 2;
clk <= '1';
wait for clk_period / 2;
end process;
-- Process stim_proc
stim_proc : process
variable lineBuffer : line;
begin
write(lineBuffer, string'("Start the simulator"));
writeline(output, lineBuffer);
wait;
end process;
end implementation ; -- implementation

33077
images/Synthesis_Result.pdf Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff