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
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_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)
);
@ -74,6 +73,7 @@ architecture arch of bfpu is
component branch
port(
clk : in std_logic;
state : in std_logic;
instruction : in std_logic_vector(2 downto 0);
instr_addr : 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;
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) := (others => '0');
signal s_out : std_logic_vector(7 downto 0) := (others => '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 +147,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 +176,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
@ -159,6 +185,7 @@ begin
branch_bf : branch
port map(
clk => s_clk,
state => processor_state,
instruction => s_instruction,
instr_addr => s_instrAddr,
cell_value => s_cell_out,
@ -168,8 +195,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

@ -12,6 +12,7 @@ use ieee.numeric_std.all;
entity branch is
port(
clk : in std_logic;
state : in std_logic;
instruction : in std_logic_vector(2 downto 0);
instr_addr : 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
type stack is array(0 to 255) of std_logic_vector(7 downto 0);
signal addr_stack : stack := (others => (others => '0'));
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 addr_stack : stack := (others => (others => '0'));
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
-- Process p_branch: set skip to true
p_branch : process (clk, skip_internal, instruction, cell_value)
-- Process branch_compute Thing that does things.
branch_compute : process (all) -- runs only, when all changed
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
if instruction = "111" and unsigned(nested) = 0 and skip_internal = '1' then
skip_internal <= '0';
end if;
end if;
-- set addr_stack
if skip = '0' then
-- pop part 1
-- Process p_nest : raise nest by one as [ is passed
if rising_edge(clk) then
if instruction = "110" and skip_internal = '1' then
nested <= std_logic_vector(unsigned(nested) + 1);
-- push part 2
if state = '1' and instruction = "110" then
addr_stack(to_integer(unsigned(stack_ptr))) <= instr_addr;
end if;
end if;
end if;
-- 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
nested <= std_logic_vector(unsigned(nested) - 1);
-- set nested
if state = '0' and skip_internal = '1' then
-- 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;
-- 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';
-- 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
skip_internal <= '1';
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);
-- 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;
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
-- 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);
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';
else
jump <= '0';
end if;
end if;
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;

View File

@ -22,7 +22,7 @@ end cellblock;
-- Architecture arch of cellblock: read on every clock cycle to cell.
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'));

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,21 @@ 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"010", b"110", b"000", b"010", b"101", b"001", b"111", 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

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