Skip to content

Commit

Permalink
Run non-branching instructions
Browse files Browse the repository at this point in the history
Closes #12.
  • Loading branch information
cbebe committed Feb 6, 2024
1 parent 2c41669 commit 3d5ee8f
Show file tree
Hide file tree
Showing 10 changed files with 122 additions and 42 deletions.
9 changes: 9 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ FMT_SRC := $(patsubst %, fmt-%,$(VHDL_SRC) $(VHDL_TEST_SRC))

export GHDL_FLAGS := compile --std=08
# GHDL_FLAGS += -frelaxed
export RUN_FLAGS := --ieee-asserts=disable # If you wanna silence annoying errors
# export RUN_FLAGS := --assert-level=warning # If you wanna be super strict

test: $(VHDL_TEST_BENCHES)
Expand All @@ -31,6 +32,14 @@ rtl/core/rom_pkg.vhd: scripts/asm/main.go \
%_tb: $(TEST_DIR)/%_tb.vhd $(SRC_DIR)/%.vhd
@TB="$@" ./scripts/run_test.sh $^

_CONTROLLER := control_fsm \
fysh_fyve_pkg \

CONTROLLER := $(patsubst %, $(SRC_DIR)/%.vhd, $(_CONTROLLER))

control_fsm_tb: $(TEST_DIR)/control_fsm_tb.vhd $(CONTROLLER)
@TB="$@" ./scripts/run_test.sh $^

_ALU := alu \
fysh_fyve_pkg \

Expand Down
7 changes: 7 additions & 0 deletions docs/controller.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,12 @@ done_o : out std_logic
| ----------- | ------- | ------- | ---- | ----- | ----- | ------------ | ------ | ------ | ------ | ------ | ------- | ---- |
| lui | 01 | 0 | 1 | [1] | 1 | 0 | dr | dr | dr | 1 | 0 | 0 |
| auipc | 01 | 0 | 1 | 1 | 1 | 0 | dr | dr | dr | 0 | 0 | 0 |
| addi | 01 | 0 | 1 | 0 | 1 | 0 | dr | dr | dr | 1 | 0 | 0 |

| A | B | A ^ B |
| ----- | ------------------ | -------- |
| lui | auipc | bit 5 | -- LUI is just immediate
| auipc | register-immediate | bit 2 |
| lui | register-immediate | bit 2, 5 |

[^1] This somehow has to be pointing to 0! how? and the op bits should be add!
Binary file added docs/rv32i-timing.pdf
Binary file not shown.
25 changes: 23 additions & 2 deletions rtl/core/alu_control.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,13 @@ architecture rtl of alu_control is
signal lt : std_ulogic := '0';
signal ltu : std_ulogic := '0';

signal rs1_or_zero : std_ulogic_vector (31 downto 0) := (others => '0');

signal alu_a_sel : std_ulogic := '0';
signal alu_b_sel : std_ulogic := '0';

signal addr_sel : std_ulogic := '0';
signal rd_clk : std_ulogic := '0';
signal rd_sel : std_ulogic_vector (1 downto 0) := (others => '0');
signal alu : std_ulogic_vector (31 downto 0) := (others => '0');
signal pc : std_ulogic_vector (31 downto 0) := (others => '0');
Expand All @@ -63,8 +66,20 @@ begin
if rising_edge(clk_i) then
write(l, string'("pc_clk: "));
write(l, pc_clk);
write(l, string'(" rd_clk: "));
write(l, rd_clk);
write(l, string'(" pc: "));
write(l, to_hstring(pc));
write(l, string'(" instruction_i: "));
write(l, to_hstring(instruction_i));
write(l, string'(" func3: "));
write(l, instruction_i(14 downto 12));
write(l, string'(" alu_a_op: "));
write(l, to_hstring(alu_a_op));
write(l, string'(" alu_b_op: "));
write(l, to_hstring(alu_b_op));
write(l, string'(" alu_o: "));
write(l, to_hstring(alu_o));
writeline(output, l);
end if;
end process print;
Expand All @@ -73,6 +88,11 @@ begin
instruction_i => instruction_i,
imm_val_o => imm_ex);

-- Hacky way to make rs1_val hardwire to 0
with instruction_i(6 downto 0) select rs1_or_zero <=
(others => '0') when "0110111",
reg_val_1_i when others;

program_counter_inst : entity work.program_counter(rtl) port map (
pc_clk_i => pc_clk,
reset_i => reset_i,
Expand Down Expand Up @@ -111,19 +131,20 @@ begin
alu_b_sel_o => alu_b_sel,
rd_sel_o => rd_sel,
mem_write_en_o => mem_write_en_o,
rd_clk_o => rd_clk_o,
rd_clk_o => rd_clk,
pc_clk_o => pc_clk,
ir_clk_o => ir_clk_o,
pc_alu_sel_o => pc_alu_sel,
pc_next_sel_o => pc_next_sel);

addr_sel_o <= addr_sel;
rd_clk_o <= rd_clk;
rd_sel_o <= rd_sel;
alu_o <= alu;
pc_o <= pc;

with alu_a_sel select alu_a_op <=
reg_val_1_i when '0',
rs1_or_zero when '0',
pc when '1',
(others => 'X') when others;

Expand Down
78 changes: 53 additions & 25 deletions rtl/core/control_fsm.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
--! @cond Doxygen_Suppress
library ieee;
use ieee.std_logic_1164.all;
use work.fysh_fyve.all;
--! @endcond

--! The Big Brain of the CPU.\n
Expand Down Expand Up @@ -37,52 +38,79 @@ entity control_fsm is
end control_fsm;

architecture rtl of control_fsm is
type state_t is (decode, drive, done);
type state_t is (init, decode, drive, done);
signal pc_clk : std_ulogic := '0';
signal ir_clk : std_ulogic := '0';
signal rd_clk : std_ulogic := '0';
signal mem_write_en : std_ulogic := '0';

signal state : state_t := decode;
signal write_mem : std_ulogic := '0';
signal write_reg : std_ulogic := '0';

signal state : state_t := init;
begin
alu_a_sel_o <= opcode_i(2) and not opcode_i(5);
alu_b_sel_o <= opcode_i(2) or not opcode_i(5);
addr_sel_o <= '1';

with opcode_i(2) select op_bits_o <=
OP_OR when '1',
op_bits_i(2 downto 0) when others;
sub_sra_o <= sub_sra_i and not opcode_i(2);

drive_clock : process(clk_i, halt_i, opcode_i, pc_clk, ir_clk, mem_write_en)
use std.textio.all;
variable l : line;
begin
if falling_edge(reset_i) then
state <= decode;
state <= init;
done_o <= '0';
elsif rising_edge(halt_i) then
state <= done;
elsif clk_i'event then
elsif rising_edge(clk_i) then
--! TODO: Decode kinda like 410
case state is
when init =>
state <= decode;
when decode =>
alu_b_sel_o <= not opcode_i(5); -- immediate value ('1') or rs2 ('0')
-- TODO: Figure this out
alu_a_sel_o <= opcode_i(0); -- pc ('1') or rs1 ('0')
addr_sel_o <= opcode_i(0); -- alu ('1') or pc ('0')
pc_alu_sel_o <= '1'; -- 4 ('1') or immediate value ('0')
pc_next_sel_o <= opcode_i(0); -- alu ('1') or pc alu ('0')
rd_sel_o <= opcode_i(1 downto 0); -- mem_sx ("11"), alu ("01"), or pc alu ("00")

sub_sra_o <= sub_sra_i;
op_bits_o <= op_bits_i(2 downto 0);

-- TODO!!
rd_clk_o <= opcode_i(0);
state <= drive;
case opcode_i(2) is
when '1' => -- LUI/AUIPC (for now!)
-- TODO: Handle the case where it's not!
rd_sel_o <= "01";
write_reg <= '1';
pc_alu_sel_o <= '1';
pc_next_sel_o <= '0';
when others => -- The typical ALU stuff
rd_sel_o <= "01"; -- mem_sx ("11"), alu ("01"), or pc alu ("00")
write_reg <= '1';
pc_alu_sel_o <= '1'; -- 4 ('1') or immediate value ('0')
pc_next_sel_o <= '0'; -- alu ('1') or pc alu ('0')
end case;
mem_write_en <= '0';
rd_clk <= '0';
ir_clk <= '1';
pc_clk <= '0';
state <= drive;
when drive =>
pc_clk <= not pc_clk;
ir_clk <= not ir_clk;
mem_write_en <= not mem_write_en;
state <= decode;
if (write_mem = '1') then
mem_write_en <= '1';
write_mem <= '0';
end if;
if (write_reg = '1') then
rd_clk <= '1';
write_reg <= '0';
end if;
ir_clk <= '0';
pc_clk <= '1';
state <= decode;
when done =>
done_o <= '1';
end case;
end if;
pc_clk_o <= pc_clk;
ir_clk_o <= ir_clk;
mem_write_en_o <= mem_write_en;
end process drive_clock;

rd_clk_o <= rd_clk;
pc_clk_o <= pc_clk;
ir_clk_o <= ir_clk;
mem_write_en_o <= mem_write_en;
end rtl;
19 changes: 10 additions & 9 deletions rtl/core/memory.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,14 @@ architecture rtl of memory is
signal addr, mem_out, mem_sx : std_ulogic_vector (31 downto 0);
signal reg_val_1, reg_val_2 : std_ulogic_vector (31 downto 0);
begin
wtf : process(insn_o)
use std.textio.all;
variable l : line;
begin
write(l, string'("insn_o: "));
write(l, insn_o);
writeline(output, l);
end process wtf;
-- wtf : process(insn_o)
-- use std.textio.all;
-- variable l : line;
-- begin
-- write(l, string'("insn_o: "));
-- write(l, insn_o);
-- writeline(output, l);
-- end process wtf;

mem_inst : entity work.phy_map(rtl) port map (
clk_i => clk_i,
Expand All @@ -66,7 +66,8 @@ begin

reg_val_2_o <= reg_val_2;
reg_val_1_o <= reg_val_1;
insn_o <= insn;

insn_o <= insn;

with addr_sel_i select addr <=
pc_out_i when '1',
Expand Down
8 changes: 4 additions & 4 deletions rtl/core/program_counter.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@ begin
use std.textio.all;
variable l : line;
begin
write(l, string'("next_ins: "));
write(l, to_hstring(next_ins));
writeline(output, l);
if falling_edge(reset_i) then
pc <= (others => '0');
elsif pc_clk_i'event then
elsif rising_edge(pc_clk_i) then
write(l, string'("next_ins: "));
write(l, to_hstring(next_ins));
writeline(output, l);
pc <= next_ins;
end if;
end process;
Expand Down
7 changes: 7 additions & 0 deletions rtl/core/register_file.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,18 @@ begin
registers_g :
for i in 1 to 31 generate
register_write : process(reset_i, rd_clk_i)
use std.textio.all;
variable l : line;
begin
if falling_edge(reset_i) then
reg_file(i) <= (others => '0');
elsif rising_edge(rd_clk_i) then
if (i = to_integer(unsigned(dest_reg_i))) then
write(l, string'("wrote value "));
write(l, to_hstring(dest_reg_val_i));
write(l, string'(" to register"));
write(l, i);
writeline(output, l);
reg_file(i) <= dest_reg_val_i;
end if;
end if;
Expand Down
5 changes: 4 additions & 1 deletion rtl/test/alu_control_tb.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,21 @@ architecture test_bench of alu_control_tb is
signal rd_sel : std_ulogic_vector (1 downto 0) := (others => '0');
signal reset : std_ulogic := '0';
signal addr_sel : std_ulogic := '0';

signal rs1_or_zero : std_ulogic_vector (31 downto 0);
begin
clock : process
begin
clk <= not clk;
wait for 1 ns;
end process clock;


alu_control_inst : entity work.alu_control(rtl) port map (
clk_i => clk,
reset_i => reset,
instruction_i => insn,
reg_val_1_i => rs1_val,
reg_val_1_i => rs1_or_zero,
reg_val_2_i => rs2_val,
alu_o => alu,
pc_o => pc,
Expand Down
6 changes: 5 additions & 1 deletion rtl/test/topmodule_tb.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ begin
reset <= '0';
wait for 1 ns;
reset <= '1';
wait for 10 ns;
wait for 1 ns;
reset <= '0';
wait for 1 ns;
reset <= '1';
wait for 30 ns;
stop;
end process;
end test_bench;

0 comments on commit 3d5ee8f

Please sign in to comment.