Merge branch 'fpga' into 'master'
Fpga See merge request schnick/bfpu!3
This commit is contained in:
commit
f05c1a9ae3
|
@ -1,4 +1,9 @@
|
|||
Endless loop
|
||||
Affect: cell(ptr)
|
||||
|
||||
+[ >< ]
|
||||
+[]
|
||||
|
||||
If clause
|
||||
Affects: cell(ptr); ???
|
||||
|
||||
[ do stuff here [-] ]
|
||||
|
|
|
@ -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 {} \;
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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'));
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
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
Loading…
Reference in New Issue