Working version

This commit is contained in:
Yannick Reiß 2024-08-07 18:30:30 +02:00
parent b3cc87a6d3
commit 1772ac2af2
No known key found for this signature in database
GPG Key ID: 5A3AF456F0A0338C
14 changed files with 249 additions and 218 deletions

View File

@ -1,8 +1,6 @@
# Makefile for the different parts of the RISC-V COntroller # Makefile for the different parts of the RISC-V COntroller
# Project by # Project by
# Yannick Reiß # Yannick Reiß
# Carl Ries
# Alexander Graf
# Variable section # Variable section
PARTS = ram regs alu decoder pc cpu PARTS = ram regs alu decoder pc cpu
@ -10,14 +8,14 @@ CHDL = ghdl
FLAGS = --std=08 FLAGS = --std=08
REGSSRC = src/riscv_types.vhd src/registers.vhd tb/tb_reg.vhd REGSSRC = src/riscv_types.vhd src/registers.vhd tb/tb_reg.vhd
ALUSRC = src/riscv_types.vhd src/alu.vhd tb/tb_alu.vhd ALUSRC = src/riscv_types.vhd src/alu.vhd tb/tb_alu.vhd
RAMSRC = src/riscv_types.vhd src/ram_block.vhd src/imem.vhd src/ram_entity_only.vhd tb/tb_ram.vhd RAMSRC = src/riscv_types.vhd src/ram_block.vhd src/imem.vhd src/ram.vhd tb/tb_ram.vhd
PCSRC = src/riscv_types.vhd src/pc.vhd tb/tb_pc.vhd PCSRC = src/riscv_types.vhd src/pc.vhd tb/tb_pc.vhd
DECSRC = src/riscv_types.vhd src/decoder.vhd tb/tb_decoder.vhd DECSRC = src/riscv_types.vhd src/decoder.vhd tb/tb_decoder.vhd
CPUSRC = src/riscv_types.vhd src/ram_block.vhd src/branch.vhd src/imem.vhd src/ram_entity_only.vhd src/registers.vhd src/alu.vhd src/pc.vhd src/decoder.vhd src/imm.vhd src/cpu.vhd tb/tb_cpu.vhd CPUSRC = src/riscv_types.vhd src/ram_block.vhd src/branch.vhd src/imem.vhd src/ram.vhd src/registers.vhd src/alu.vhd src/pc.vhd src/decoder.vhd src/imm.vhd src/cpu.vhd tb/tb_cpu.vhd
ENTITY = regs_tb ENTITY = regs_tb
ALUENTITY = alu_tb ALUENTITY = alu_tb
PCENTITY = pc_tb PCENTITY = pc_tb
STOP = 9000ns STOP = 100ns
TBENCH = alu_tb regs_tb TBENCH = alu_tb regs_tb
# Build all # Build all

View File

@ -1,6 +1,6 @@
-- cpu.vhd -- cpu.vhd
-- Created on: Mo 19. Dez 11:07:17 CET 2022 -- Created on: Mo 19. Dez 11:07:17 CET 2022
-- Author(s): Yannick Reiß, Carl Ries, Alexander Graf -- Author(s): Yannick Reiss
-- Content: Entity cpu -- Content: Entity cpu
library IEEE; library IEEE;
use ieee.std_logic_1164.all; use ieee.std_logic_1164.all;
@ -13,13 +13,13 @@ use work.riscv_types.all;
entity cpu is entity cpu is
port( port(
clk : in std_logic; -- clk to control the unit clk : in std_logic; -- clk to control the unit
rst : in std_logic;
-- Led Output instruction_read : in word;
led : out std_logic_vector(15 downto 0); -- output to 16 LEDS ram_read_data : in word;
ram_enable_writing : out std_logic;
-- RGB Output instruction_pointer : out ram_addr_t;
RGB1 : out std_logic_vector(2 downto 0); -- output to RGB 1 data_address : out ram_addr_t;
RGB2 : out std_logic_vector(2 downto 0) -- output to RGB 2 ram_write_data : out word
); );
end cpu; end cpu;
@ -36,18 +36,6 @@ architecture implementation of cpu is
); );
end component; end component;
component ram
port(
clk : in std_logic; -- Clock input for timing
instructionAdr : in ram_addr_t; -- Address instruction
dataAdr : in ram_addr_t; -- Address data
writeEnable : in one_bit; -- Read or write mode
dataIn : in word; -- Write data
instruction : out word; -- Get instruction
dataOut : out word -- Read data
);
end component;
component alu component alu
port ( port (
alu_opc : in aluOP; -- alu opcode. alu_opc : in aluOP; -- alu opcode.
@ -69,7 +57,7 @@ architecture implementation of cpu is
component imm component imm
port ( port (
instruction : in instruction; instr : in instruction;
opcode : in uOP; opcode : in uOP;
immediate : out word immediate : out word
); );
@ -85,8 +73,7 @@ architecture implementation of cpu is
r2_idx : in reg_idx; -- second register to read from r2_idx : in reg_idx; -- second register to read from
write_enable : in one_bit; -- enable writing to wr_idx write_enable : in one_bit; -- enable writing to wr_idx
r1_out : out word; -- data from first register r1_out : out word; -- data from first register
r2_out : out word; -- data from second register r2_out : out word -- data from second register
led_out : out word -- output led
); );
end component; end component;
@ -100,15 +87,12 @@ architecture implementation of cpu is
end component; end component;
-- SIGNALS GLOBAL -- SIGNALS GLOBAL
signal s_clock : std_logic; signal s_clock : std_logic := '0';
signal s_reg_wb_enable : one_bit; --enables: register writeback signal s_reg_wb_enable : one_bit := "0"; --enables: register writeback
signal s_reg_wr_enable : one_bit; --enables: register write to index signal s_reg_wr_enable : one_bit := "0"; --enables: register write to index
signal s_pc_enable : one_bit; --enables: pc signal s_pc_enable : one_bit := "0"; --enables: pc
signal s_pc_jump_enable : one_bit; --enables: pc jump to address signal s_pc_jump_enable : one_bit := "0"; --enables: pc jump to address
signal s_ram_enable : one_bit; --enables: ram write enalbe signal s_ram_enable : std_logic := '0'; --enables: ram write enalbe
signal s_led_out : word := "10110011100001110111010110101110"; -- stores the exact output
-- decoder -> registers -- decoder -> registers
signal s_idx_1 : reg_idx; signal s_idx_1 : reg_idx;
@ -123,7 +107,7 @@ architecture implementation of cpu is
signal s_reg_data2 : word; signal s_reg_data2 : word;
-- pc -> ram -- pc -> ram
signal s_instAdr : ram_addr_t; signal s_instAddr : ram_addr_t;
signal s_cycle_cnt : cpuStates := stIF; signal s_cycle_cnt : cpuStates := stIF;
signal s_branch_jump_enable : one_bit; signal s_branch_jump_enable : one_bit;
@ -137,8 +121,6 @@ architecture implementation of cpu is
signal s_inst : instruction; signal s_inst : instruction;
signal s_data_in_addr : ram_addr_t; signal s_data_in_addr : ram_addr_t;
-- v dummy signals below v -- v dummy signals below v
--imm -> ??? --imm -> ???
@ -167,7 +149,14 @@ architecture implementation of cpu is
begin begin
-- External assignments
s_clock <= clk; s_clock <= clk;
ram_enable_writing <= s_ram_enable;
instruction_pointer <= s_instAddr;
data_address <= s_data_in_addr;
ram_write_data <= s_alu_data;
s_inst <= instruction_read;
s_ram_data <= ram_read_data;
decoder_RISCV : decoder decoder_RISCV : decoder
port map( port map(
@ -188,13 +177,12 @@ begin
r2_idx => s_idx_2, r2_idx => s_idx_2,
write_enable => s_reg_wr_enable, write_enable => s_reg_wr_enable,
r1_out => s_reg_data1, r1_out => s_reg_data1,
r2_out => s_reg_data2, r2_out => s_reg_data2
led_out => s_led_out
); );
imm_RISCV : imm imm_RISCV : imm
port map( port map(
instruction => s_inst, instr => s_inst,
opcode => s_opcode, opcode => s_opcode,
immediate => s_immediate immediate => s_immediate
); );
@ -205,7 +193,7 @@ begin
en_pc => s_pc_enable, en_pc => s_pc_enable,
addr_calc => X_addr_calc, addr_calc => X_addr_calc,
doJump => s_pc_jump_enable, doJump => s_pc_jump_enable,
addr => s_instAdr addr => s_instAddr
); );
alu_RISCV : alu alu_RISCV : alu
@ -216,17 +204,6 @@ begin
result => s_alu_data result => s_alu_data
); );
ram_RISCV : ram
port map(
clk => s_clock, --
instructionAdr => s_instAdr, -- instruction from pc
dataAdr => s_data_in_addr, -- data address from alu
writeEnable => s_ram_enable, --
dataIn => s_reg_data2, -- data from register
instruction => s_inst, --
dataOut => s_ram_data
);
branch_RISCV : Branch branch_RISCV : Branch
port map( port map(
op_code => s_opcode, op_code => s_opcode,
@ -243,8 +220,6 @@ begin
----------------------------------------- -----------------------------------------
-- Output -- Output
----------------------------------------- -----------------------------------------
led <= s_led_out(15 downto 0);
RGB1 <= s_clock & s_clock & s_clock;
alu_control : process (s_immediate, s_opcode, s_reg_data1, s_reg_data2) -- runs only, when item in list changed alu_control : process (s_immediate, s_opcode, s_reg_data1, s_reg_data2) -- runs only, when item in list changed
begin begin
@ -298,42 +273,42 @@ begin
end process; end process;
-- Process pc input -- Process pc input
pc_addr_input : process(s_opcode, s_cycle_cnt, s_instAdr, s_immediate) pc_addr_input : process(s_opcode, s_cycle_cnt, s_instAddr, s_immediate)
begin begin
if s_cycle_cnt = stWB then if s_cycle_cnt = stWB then
s_pc_enable <= "1"; s_pc_enable <= "1";
else else
s_pc_enable <= "0"; s_pc_enable <= "0";
-- X_addr_calc <= s_instAdr; -- should not be necessary, every case option sets X_addr_calc -- X_addr_calc <= s_instAddr; -- should not be necessary, every case option sets X_addr_calc
end if; end if;
case s_opcode is case s_opcode is
when uJALR | uJAL => when uJALR | uJAL =>
s_pc_jump_enable <= "1"; s_pc_jump_enable <= "1";
X_addr_calc <= std_logic_vector(signed(s_immediate(11 downto 0)) + signed(s_instAdr)); X_addr_calc <= std_logic_vector(signed(s_immediate(11 downto 0)) + signed(s_instAddr));
-- Branch op_codes -- Branch op_codes
when uBEQ | uBNE | uBLT | uBGE | uBLTU | uBGEU => when uBEQ | uBNE | uBLT | uBGE | uBLTU | uBGEU =>
-- always load address from immediate on B-Type -- always load address from immediate on B-Type
X_addr_calc <= std_logic_vector(signed(s_immediate(11 downto 0)) + signed(s_instAdr)); X_addr_calc <= std_logic_vector(signed(s_immediate(11 downto 0)) + signed(s_instAddr));
-- check for opcodes and evaluate condition -- check for opcodes and evaluate condition
s_pc_jump_enable <= s_branch_jump_enable; s_pc_jump_enable <= s_branch_jump_enable;
when others => when others =>
s_pc_jump_enable <= "0"; s_pc_jump_enable <= "0";
X_addr_calc <= s_instAdr; X_addr_calc <= s_instAddr;
end case; end case;
end process; end process;
-- process ram -- process ram
ram_input : process(s_opcode, s_cycle_cnt) ram_input : process(s_opcode, s_cycle_cnt)
begin begin
s_data_in_addr <= std_logic_vector(signed(s_immediate(11 downto 0)) + signed(s_reg_data1(11 downto 0))); s_data_in_addr <= std_logic_vector(signed(s_immediate) + signed(s_reg_data1));
if s_cycle_cnt = stWB then if s_cycle_cnt = stWB then
case s_opcode is case s_opcode is
when uSB | uSH | uSW => s_ram_enable <= "1"; when uSB | uSH | uSW => s_ram_enable <= '1';
when others => s_ram_enable <= "0"; when others => s_ram_enable <= '0';
end case; end case;
else else
s_ram_enable <= "0"; s_ram_enable <= '0';
end if; end if;
end process; end process;
@ -343,15 +318,10 @@ begin
if rising_edge(s_clock) then if rising_edge(s_clock) then
case s_cycle_cnt is case s_cycle_cnt is
when stIF => s_cycle_cnt <= stDEC; when stIF => s_cycle_cnt <= stDEC;
RGB2 <= "001";
when stDEC => s_cycle_cnt <= stOF; when stDEC => s_cycle_cnt <= stOF;
RGB2 <= "010";
when stOF => s_cycle_cnt <= stEXEC; when stOF => s_cycle_cnt <= stEXEC;
RGB2 <= "011";
when stEXEC => s_cycle_cnt <= stWB; when stEXEC => s_cycle_cnt <= stWB;
RGB2 <= "100";
when others => s_cycle_cnt <= stIF; when others => s_cycle_cnt <= stIF;
RGB2 <= "101";
end case; end case;
end if; end if;
end process pc_cycle_control; end process pc_cycle_control;

View File

@ -14,11 +14,9 @@ entity instr_memory is
generic (initMem : ram_t := (others => (others => '0'))); generic (initMem : ram_t := (others => (others => '0')));
port (clk : in std_logic; port (clk : in std_logic;
addr_a : in std_logic_vector(ram_addr_size - 3 downto 0); addr_a : in std_logic_vector(ram_addr_size - 3 downto 0);
data_read_a : out std_logic_vector(wordWidth - 1 downto 0); data_read_a : out std_logic_vector(wordWidth - 1 downto 0);
write_b : in std_logic;
write_b : in one_bit;
addr_b : in std_logic_vector(ram_addr_size - 3 downto 0); addr_b : in std_logic_vector(ram_addr_size - 3 downto 0);
data_read_b : out std_logic_vector(wordWidth - 1 downto 0); data_read_b : out std_logic_vector(wordWidth - 1 downto 0);
data_write_b : in std_logic_vector(wordWidth - 1 downto 0) data_write_b : in std_logic_vector(wordWidth - 1 downto 0)
@ -27,28 +25,18 @@ entity instr_memory is
end instr_memory; end instr_memory;
-- START:
-- addi x1 x0 1
-- add x2 x0 x0
-- add x3 x0 x0
-- addi x4 x0 2047
-- slli x4 x4 5
-- REG2UP:
-- add x2 x2 x1
-- add x3 x0 x0
-- REG3UP:
-- add x3 x3 x1
-- bgeu x3 x4 REG2UP
-- jal REG3UP
architecture behavioral of instr_memory is architecture behavioral of instr_memory is
signal store : ram_t := signal store : ram_t :=
( (
x"00100093", x"00000133", x"000001b3", x"7ff00213", x"00521213", x"00110133", x"000001b3", x"001181b3", x"fe41fae3", x"ff9ff0ef", others => (others => '0') b"00000000000000000000001010010011",
b"00000000000100101000001010010011",
b"11111111110111111111000011101111",
others => (others => '0')
); );
begin begin
-- Two synchron read ports -- Two synchron read ports
data_read_a <= store(to_integer(unsigned(addr_a(9 downto 2)))); data_read_a <= store(to_integer(unsigned(addr_a(ram_addr_size - 3 downto 2))));
data_read_b <= store(to_integer(unsigned(addr_b(9 downto 2)))); data_read_b <= store(to_integer(unsigned(addr_b(ram_addr_size - 3 downto 2))));
end behavioral; end behavioral;

View File

@ -7,7 +7,7 @@ use work.riscv_types.all;
entity imm is entity imm is
port ( port (
instruction : in instruction; instr : in instruction;
opcode : in uOP; opcode : in uOP;
immediate : out word immediate : out word
); );
@ -18,23 +18,23 @@ architecture slicing of imm is
begin begin
-- Process immediate slice -- Process immediate slice
process (opcode, instruction) process (opcode, instr)
begin begin
case opcode is case opcode is
-- I-Type -- I-Type
when uLB | uLH | uLW | uLBU | uLHU | uADDI | uSLTI | uSLTIU | uXORI | uORI | uANDI => immediate <= std_logic_vector(to_unsigned(0, wordWidth - 12)) & instruction(31 downto 20); when uLB | uLH | uLW | uLBU | uLHU | uADDI | uSLTI | uSLTIU | uXORI | uORI | uANDI => immediate <= std_logic_vector(to_unsigned(0, wordWidth - 12)) & instr(31 downto 20);
-- S-Type -- S-Type
when uSB | uSH | uSW => immediate <= std_logic_vector(to_unsigned(0, wordWidth-12)) & instruction(31 downto 25) & instruction(11 downto 7); when uSB | uSH | uSW => immediate <= std_logic_vector(to_unsigned(0, wordWidth-12)) & instr(31 downto 25) & instr(11 downto 7);
-- B-Type -- B-Type
when uBEQ | uBNE | uBLT | uBGE | uBLTU | uBGEU => immediate <= std_logic_vector(to_unsigned(0, 19)) & instruction(31) & instruction(7) & instruction(30 downto 25) & instruction(11 downto 8) & "0"; when uBEQ | uBNE | uBLT | uBGE | uBLTU | uBGEU => immediate <= std_logic_vector(to_unsigned(0, 19)) & instr(31) & instr(7) & instr(30 downto 25) & instr(11 downto 8) & "0";
-- U-Type -- U-Type
when uLUI | uAUIPC => immediate <= instruction(31 downto 12) & std_logic_vector(to_unsigned(0, 12)); when uLUI | uAUIPC => immediate <= instr(31 downto 12) & std_logic_vector(to_unsigned(0, 12));
-- J-Type -- J-Type
when uJAL => immediate <= std_logic_vector(to_unsigned(0, wordWidth - 21)) & instruction(31) & instruction(19 downto 12) & instruction(20) & instruction(30 downto 21) & "0"; when uJAL => immediate <= std_logic_vector(to_unsigned(0, wordWidth - 21)) & instr(31) & instr(19 downto 12) & instr(20) & instr(30 downto 21) & "0";
when others => immediate <= x"C000FFEE"; when others => immediate <= x"C000FFEE";
end case; end case;

View File

@ -14,11 +14,9 @@ entity ram is
generic (zeros : ram_t := (others => (others => '0'))); generic (zeros : ram_t := (others => (others => '0')));
port( port(
clk : in std_logic; -- Clock input for timing clk : in std_logic; -- Clock input for timing
instructionAdr : in ram_addr_t; -- Address instruction instructionAddr : in ram_addr_t; -- Address instruction
dataAdr : in ram_addr_t; -- Address data dataAddr : in ram_addr_t; -- Address data
writeEnable : in std_logic; -- Read or write mode
writeEnable : in one_bit; -- Read or write mode
dataIn : in word; -- Write data dataIn : in word; -- Write data
instruction : out word; -- Get instruction instruction : out word; -- Get instruction
dataOut : out word -- Read data dataOut : out word -- Read data
@ -28,10 +26,10 @@ end ram;
-- Architecture behavioral of ram: control different ram blocks -- Architecture behavioral of ram: control different ram blocks
architecture behavioral of ram is architecture behavioral of ram is
-- write signals -- write signals
signal wr1 : one_bit := "0"; signal wr1 : std_logic := '0';
signal wr2 : one_bit := "0"; signal wr2 : std_logic := '0';
signal wr3 : one_bit := "0"; signal wr3 : std_logic := '0';
signal wr4 : one_bit := "0"; signal wr4 : std_logic := '0';
-- instruction signals -- instruction signals
signal inst1 : std_logic_vector(wordWidth - 1 downto 0); signal inst1 : std_logic_vector(wordWidth - 1 downto 0);
@ -50,9 +48,9 @@ begin
block1 : entity work.instr_memory(behavioral) block1 : entity work.instr_memory(behavioral)
port map ( port map (
clk => clk, clk => clk,
addr_a => instructionAdr(ram_addr_size - 3 downto 0), addr_a => instructionAddr(ram_addr_size - 3 downto 0),
write_b => wr1, write_b => wr1,
addr_b => dataAdr(ram_addr_size - 3 downto 0), addr_b => dataAddr(ram_addr_size - 3 downto 0),
data_write_b => dataIn, data_write_b => dataIn,
data_read_a => inst1, data_read_a => inst1,
@ -62,9 +60,9 @@ begin
block2 : entity work.ram_block(behavioral) block2 : entity work.ram_block(behavioral)
port map ( port map (
clk => clk, clk => clk,
addr_a => instructionAdr(9 downto 0), addr_a => instructionAddr(ram_addr_size - 3 downto 0),
write_b => wr2, write_b => wr2,
addr_b => dataAdr(9 downto 0), addr_b => dataAddr(ram_addr_size - 3 downto 0),
data_write_b => dataIn, data_write_b => dataIn,
data_read_a => inst2, data_read_a => inst2,
@ -74,9 +72,9 @@ begin
block3 : entity work.ram_block(behavioral) block3 : entity work.ram_block(behavioral)
port map ( port map (
clk => clk, clk => clk,
addr_a => instructionAdr(9 downto 0), addr_a => instructionAddr(ram_addr_size - 3 downto 0),
write_b => wr3, write_b => wr3,
addr_b => dataAdr(9 downto 0), addr_b => dataAddr(ram_addr_size - 3 downto 0),
data_write_b => dataIn, data_write_b => dataIn,
data_read_a => inst3, data_read_a => inst3,
@ -86,50 +84,50 @@ begin
block4 : entity work.ram_block(behavioral) block4 : entity work.ram_block(behavioral)
port map ( port map (
clk => clk, clk => clk,
addr_a => instructionAdr(9 downto 0), addr_a => instructionAddr(ram_addr_size - 3 downto 0),
write_b => wr4, write_b => wr4,
addr_b => dataAdr(9 downto 0), addr_b => dataAddr(ram_addr_size - 3 downto 0),
data_write_b => dataIn, data_write_b => dataIn,
data_read_a => inst4, data_read_a => inst4,
data_read_b => data4 data_read_b => data4
); );
addr_block : process (data1, data2, data3, data4, dataAdr(11 downto 10), addr_block : process (data1, data2, data3, data4, dataAddr(11 downto 10),
inst1, inst2, inst3, inst4, inst1, inst2, inst3, inst4,
instructionAdr(11 downto 10), writeEnable) -- run process addr_block when list changes instructionAddr(11 downto 10), writeEnable) -- run process addr_block when list changes
begin begin
-- enable write -- enable write
case dataAdr(11 downto 10) is case dataAddr(11 downto 10) is
when "00" => when "00" =>
wr1 <= writeEnable; wr1 <= writeEnable;
wr2 <= "0"; wr2 <= '0';
wr3 <= "0"; wr3 <= '0';
wr4 <= "0"; wr4 <= '0';
when "01" => when "01" =>
wr1 <= "0"; wr1 <= '0';
wr2 <= writeEnable; wr2 <= writeEnable;
wr3 <= "0"; wr3 <= '0';
wr4 <= "0"; wr4 <= '0';
when "10" => when "10" =>
wr1 <= "0"; wr1 <= '0';
wr2 <= "0"; wr2 <= '0';
wr3 <= writeEnable; wr3 <= writeEnable;
wr4 <= "0"; wr4 <= '0';
when "11" => when "11" =>
wr1 <= "0"; wr1 <= '0';
wr2 <= "0"; wr2 <= '0';
wr3 <= "0"; wr3 <= '0';
wr4 <= writeEnable; wr4 <= writeEnable;
when others => when others =>
wr1 <= "0"; wr1 <= '0';
wr2 <= "0"; wr2 <= '0';
wr3 <= "0"; wr3 <= '0';
wr4 <= "0"; wr4 <= '0';
end case; end case;
-- instruction data -- instruction data
case instructionAdr(11 downto 10) is case instructionAddr(11 downto 10) is
when "00" => instruction <= inst1; when "00" => instruction <= inst1;
when "01" => instruction <= inst2; when "01" => instruction <= inst2;
when "10" => instruction <= inst3; when "10" => instruction <= inst3;
@ -137,7 +135,7 @@ begin
end case; end case;
-- data data -- data data
case dataAdr(11 downto 10) is case dataAddr(11 downto 10) is
when "00" => dataOut <= data1; when "00" => dataOut <= data1;
when "01" => dataOut <= data2; when "01" => dataOut <= data2;
when "10" => dataOut <= data3; when "10" => dataOut <= data3;

View File

@ -14,15 +14,12 @@ entity ram_block is
generic (initMem : ram_t := (others => (others => '0'))); generic (initMem : ram_t := (others => (others => '0')));
port (clk : in std_logic; port (clk : in std_logic;
addr_a : in std_logic_vector(ram_addr_size - 3 downto 0); addr_a : in std_logic_vector(ram_addr_size - 3 downto 0);
data_read_a : out std_logic_vector(wordWidth - 1 downto 0); data_read_a : out std_logic_vector(wordWidth - 1 downto 0);
write_b : in std_logic;
write_b : in one_bit;
addr_b : in std_logic_vector(ram_addr_size - 3 downto 0); addr_b : in std_logic_vector(ram_addr_size - 3 downto 0);
data_read_b : out std_logic_vector(wordWidth - 1 downto 0); data_read_b : out std_logic_vector(wordWidth - 1 downto 0);
data_write_b : in std_logic_vector(wordWidth - 1 downto 0) data_write_b : in std_logic_vector(wordWidth - 1 downto 0)
); );
end ram_block; end ram_block;
@ -39,7 +36,7 @@ begin
if rising_edge(clk) then if rising_edge(clk) then
-- One synchron write port -- One synchron write port
if write_b = "1" then if write_b = '1' then
store(to_integer(unsigned(addr_b(9 downto 2)))) <= data_write_b; store(to_integer(unsigned(addr_b(9 downto 2)))) <= data_write_b;
end if; end if;
@ -48,7 +45,6 @@ begin
-- Two synchron read ports -- Two synchron read ports
data_read_a <= store(to_integer(unsigned(addr_a(9 downto 2)))); data_read_a <= store(to_integer(unsigned(addr_a(9 downto 2))));
data_read_b <= store(to_integer(unsigned(addr_b(9 downto 2)))); data_read_b <= store(to_integer(unsigned(addr_b(5 downto 2))));
end behavioral; end behavioral;

View File

@ -29,8 +29,7 @@ entity registers is
r2_idx : in reg_idx; -- second register to read from r2_idx : in reg_idx; -- second register to read from
write_enable : in one_bit; -- enable writing to wr_idx write_enable : in one_bit; -- enable writing to wr_idx
r1_out : out word; -- data from first register r1_out : out word; -- data from first register
r2_out : out word; -- data from second register r2_out : out word -- data from second register
led_out : out word -- output reg 2 to led
); );
end registers; end registers;
@ -54,6 +53,5 @@ begin
-- read from both reading registers -- read from both reading registers
r1_out <= registerbench(to_integer(unsigned(r1_idx))); r1_out <= registerbench(to_integer(unsigned(r1_idx)));
r2_out <= registerbench(to_integer(unsigned(r2_idx))); r2_out <= registerbench(to_integer(unsigned(r2_idx)));
led_out <= registerbench(2);
end structure; end structure;

View File

@ -109,13 +109,12 @@ package riscv_types is
type regFile is array (reg_size - 1 downto 0) of word; type regFile is array (reg_size - 1 downto 0) of word;
-- ram constants and type -- ram constants and type
constant ram_size : natural := 4096; constant ram_size : natural := 16384;
constant ram_block_size : natural := 1024; constant ram_block_size : natural := 4096;
constant ram_addr_size : natural := 12; constant ram_addr_size : natural := 32;
subtype ram_addr_t is std_logic_vector(ram_addr_size -1 downto 0); subtype ram_addr_t is std_logic_vector(ram_addr_size -1 downto 0);
-- type ram_t is array(0 to ram_addr_size - 1) of word; type ram_t is array(0 to ram_block_size) of word;
type ram_t is array(0 to 255) of word;
-- const for multiplexer sources -- const for multiplexer sources
constant mul_wr_alures : two_bit := "00"; constant mul_wr_alures : two_bit := "00";

View File

@ -22,11 +22,43 @@ architecture Behavioral of cpu_tb is
-- Clock period definitions -- Clock period definitions
constant clk_period : time := 10 ns; constant clk_period : time := 10 ns;
-- CPU and RAM constraints
signal cpu_reset : std_logic := '0';
signal cpu_instruction : word := (others => '0');
signal cpu_data : word := (others => '0');
signal ram_enable : std_logic := '0';
signal instr_pointer : ram_addr_t := (others => '0');
signal ram_address : ram_addr_t := (others => '0');
signal ram_data : word := (others => '0');
signal ram_cut_zeros : ram_addr_t := (others => '0');
signal instr_pointer_zeros : ram_addr_t := (others => '0');
begin begin
ram_cut_zeros <= "00000000000000000000" & ram_address(11 downto 0);
instr_pointer_zeros <= "00000000000000000000" & instr_pointer(11 downto 0);
-- Instantiate the Unit Under Test (UUT) -- Instantiate the Unit Under Test (UUT)
uut : entity work.cpu(implementation) uut : entity work.cpu(implementation)
port map (clk => clk); port map (clk => clk,
rst => cpu_reset,
instruction_read => cpu_instruction,
ram_read_data => cpu_data,
ram_enable_writing => ram_enable,
instruction_pointer => instr_pointer,
data_address => ram_address,
ram_write_data => ram_data
);
rut : entity work.ram (behavioral)
port map(clk => clk,
instructionAddr => instr_pointer_zeros,
dataAddr => ram_cut_zeros,
writeEnable => ram_enable,
dataIn => ram_data,
instruction => cpu_instruction,
dataOut => cpu_data
);
-- Clock process definitions -- Clock process definitions
clk_process : process clk_process : process

View File

@ -13,8 +13,8 @@ library std;
use std.textio.all; use std.textio.all;
-- Entity imm_tb: dummy entity -- Entity imm_tb: dummy entity
entity imm_tb is entity imm_tb is
end imm_tb; end imm_tb;
architecture testing of imm_tb is architecture testing of imm_tb is
@ -33,7 +33,7 @@ begin
uut : entity work.imm uut : entity work.imm
port map( port map(
instruction => s_instruction, instr => s_instruction,
opcode => s_opcode, opcode => s_opcode,
immediate => s_immediate immediate => s_immediate
); );

View File

@ -14,35 +14,35 @@ end ram_tb;
architecture Behavioral of ram_tb is architecture Behavioral of ram_tb is
-- Clock -- Clock
signal clk : std_logic; signal clk : std_logic := '0';
-- Inputs -- Inputs
signal addr_a : std_logic_vector(ram_addr_size - 1 downto 0); signal addr_a : std_logic_vector(ram_addr_size - 1 downto 0) := (others => '0');
signal write_b : std_logic_vector(1-1 downto 0); signal write_b : std_logic := '0';
signal addr_b : std_logic_vector(ram_addr_size - 1 downto 0); signal addr_b : std_logic_vector(ram_addr_size - 1 downto 0) := (others => '0');
signal data_write_b : std_logic_vector(wordWidth - 1 downto 0); signal data_write_b : std_logic_vector(wordWidth - 1 downto 0) := (others => '0');
-- Outputs -- Outputs
signal data_read_a : std_logic_vector(wordWidth - 1 downto 0); signal data_read_a : std_logic_vector(wordWidth - 1 downto 0) := (others => '0');
signal data_read_b : std_logic_vector(wordWidth - 1 downto 0); signal data_read_b : std_logic_vector(wordWidth - 1 downto 0) := (others => '0');
-- Clock period definitions -- Clock period definitions
constant clk_period : time := 10 ns; constant clk_period : time := 10 ns;
-- Unittest Signale -- Unittest Signale
signal tb_addr_a : integer; signal tb_addr_a : integer := 0;
signal tb_addr_b : integer; signal tb_addr_b : integer := 0;
signal tb_test_v : std_logic_vector(wordWidth - 1 downto 0); signal tb_test_v : std_logic_vector(wordWidth - 1 downto 0) := (others => '0');
signal tb_check_v : std_logic_vector(wordWidth - 1 downto 0); signal tb_check_v : std_logic_vector(wordWidth - 1 downto 0) := (others => '0');
signal tb_validate : std_logic; signal tb_validate : std_logic := '0';
begin begin
-- Instantiate the Unit Under Test (UUT) -- Instantiate the Unit Under Test (UUT)
uut : entity work.ram(Behavioral) uut : entity work.ram(Behavioral)
port map (clk => clk, port map (clk => clk,
instructionAdr => addr_a, instructionAddr => addr_a,
dataAdr => addr_b, dataAddr => addr_b,
writeEnable => write_b, writeEnable => write_b,
dataIn => data_write_b, dataIn => data_write_b,
instruction => data_read_a, instruction => data_read_a,
@ -68,17 +68,17 @@ begin
wait until rising_edge(clk); wait until rising_edge(clk);
-- manual test -- manual test
addr_a <= "001101001110"; addr_a <= "00000000000000000000000000000110";
addr_b <= "011100110010"; addr_b <= "00000000000000000000000000000010";
write_b <= "1"; write_b <= '1';
wait for 10 ns; wait for 10 ns;
-- Testing Mem -- Testing Mem
tb_validate <= '1'; tb_validate <= '1';
write_b <= std_logic_vector(to_unsigned(1, 1)); write_b <= '1';
for test_case in 0 to 1000 loop for test_case in 0 to 12 loop
for tb_addr in 0 to 4096 loop for tb_addr in 0 to 12 loop
-- assign test values -- assign test values
tb_test_v <= std_logic_vector(to_unsigned(tb_addr, wordWidth)); tb_test_v <= std_logic_vector(to_unsigned(tb_addr, wordWidth));
tb_check_v <= std_logic_vector(to_unsigned(tb_addr, wordWidth)); tb_check_v <= std_logic_vector(to_unsigned(tb_addr, wordWidth));

49
tb/tb_riscv.vhd Normal file
View File

@ -0,0 +1,49 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.riscv_types.all;
library std;
use std.textio.all;
entity cpu_tb is
end cpu_tb;
architecture Behavioral of cpu_tb is
-- Clock
signal clk : std_logic;
-- Inputs
-- Outputs
-- Clock period definitions
constant clk_period : time := 10 ns;
begin
-- Instantiate the Unit Under Test (UUT)
uut : entity work.cpu(implementation)
port map (clk => clk);
-- 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 stimulate uut
stim_proc : process -- runs only, when changed
variable lineBuffer : line;
begin
write(lineBuffer, string'("Start the simulator"));
writeline(output, lineBuffer);
wait for 0 ns;
end process;
end architecture;

3
test.S Normal file
View File

@ -0,0 +1,3 @@
addi x5 x0 0
addi x5 x5 1
jal x1 -4