init
This commit is contained in:
263
tb/tb_alu.vhd
Normal file
263
tb/tb_alu.vhd
Normal file
@@ -0,0 +1,263 @@
|
||||
-- tb_alu.vhd
|
||||
-- Created on: Mo 21. Nov 11:21:12 CET 2022
|
||||
-- Author(s): Carl Ries, Yannick Reiß, Alexander Graf
|
||||
-- Content: Testbench for ALU
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use ieee.math_real.uniform;
|
||||
use ieee.math_real.floor;
|
||||
|
||||
library work;
|
||||
use work.riscv_types.all;
|
||||
|
||||
library std;
|
||||
use std.textio.all;
|
||||
|
||||
-- Entity alu_tb: dummy entity
|
||||
entity alu_tb is
|
||||
end alu_tb;
|
||||
|
||||
-- Architecture testing of alu_tb: testing calculations
|
||||
architecture testing of alu_tb is
|
||||
-- clock definition
|
||||
signal clk : std_logic;
|
||||
constant clk_period : time := 10 ns;
|
||||
|
||||
-- Inputs
|
||||
signal alu_opc_tb : aluOP;
|
||||
signal input1_tb : word;
|
||||
signal input2_tb : word;
|
||||
|
||||
-- Outputs
|
||||
signal result_tb : word;
|
||||
|
||||
-- unittest signals
|
||||
signal random_slv : word;
|
||||
signal check_slt : word;
|
||||
signal check_sltu : word;
|
||||
signal rand_num : integer := 0;
|
||||
|
||||
-- function for random_std_logic_vector
|
||||
impure function get_random_slv return std_logic_vector is
|
||||
|
||||
-- random number variabeln
|
||||
variable seed1 : integer := 1337;
|
||||
variable seed2 : integer := rand_num; --Zufallszahl
|
||||
variable r : real;
|
||||
variable slv : std_logic_vector(wordWidth - 1 downto 0);
|
||||
|
||||
begin
|
||||
for i in slv'range loop
|
||||
uniform(seed1, seed2, r);
|
||||
seed1 := seed1 + 2;
|
||||
end loop;
|
||||
seed2 := seed2 + 2;
|
||||
return slv;
|
||||
end function get_random_slv;
|
||||
|
||||
begin
|
||||
-- Entity work.alu(implementation): Init of Unit Under Test
|
||||
uut : entity work.alu(implementation)
|
||||
port map (
|
||||
alu_opc => alu_opc_tb,
|
||||
input1 => input1_tb,
|
||||
input2 => input2_tb,
|
||||
result => result_tb
|
||||
);
|
||||
|
||||
|
||||
-- Process Random Integer
|
||||
rand_process : process -- Prozess um einen Zufälligen Integer zu generieren
|
||||
|
||||
variable seed1, seed2 : positive; -- Startwert der Zufallszahl
|
||||
variable rand : real; -- Zufallszahl zwischen 0 und 1
|
||||
variable range_of_rand : real := 10000.0; -- Die Range wird auf 10000 festgelegt
|
||||
|
||||
begin
|
||||
uniform(seed1, seed2, rand); -- Generiert Zufallszahl
|
||||
rand_num <= integer(rand*range_of_rand); -- Zahl wird zwischen 0 und range_of_rand skaliert
|
||||
wait for 10 ns;
|
||||
end process;
|
||||
|
||||
|
||||
-- Process clk_process operating the clock
|
||||
clk_process : process -- runs only, when changed
|
||||
begin
|
||||
clk <= '0';
|
||||
wait for clk_period/2;
|
||||
clk <= '1';
|
||||
wait for clk_period/2;
|
||||
end process;
|
||||
|
||||
-- Process stim_proc control device for uut
|
||||
stim_proc : process -- runs only, when changed
|
||||
-- Text I/O
|
||||
variable lineBuffer : line;
|
||||
begin
|
||||
-- wait for the rising edge
|
||||
wait until rising_edge(clk);
|
||||
|
||||
-- Print the top element
|
||||
write(lineBuffer, string'("Start the simulator"));
|
||||
writeline(output, lineBuffer);
|
||||
|
||||
-- For schleife für 20 Testdurchläufe
|
||||
for i in 1 to 20 loop
|
||||
|
||||
--create example inputs
|
||||
input1_tb <= std_logic_vector( to_unsigned(10, 32) );
|
||||
wait for 10 ns;
|
||||
input2_tb <= std_logic_vector( to_unsigned(7, 32) );
|
||||
alu_opc_tb <= uNop;
|
||||
wait for 10 ns;
|
||||
|
||||
-- Ausgabe input1_tb und input2_tb
|
||||
-- Dient zur Kontrolle das zufällige Zahlen ausgegeben werden.
|
||||
write(lineBuffer, string'("Zufahlszahl 1: "));
|
||||
|
||||
write(lineBuffer, string'("Zufahlszahl 2: "));
|
||||
|
||||
-- NOP
|
||||
if (unsigned(result_tb) = 0) then
|
||||
write(lineBuffer, string'("NOP: +"));
|
||||
writeline(output, lineBuffer);
|
||||
else
|
||||
write(lineBuffer, string'("NOP: -"));
|
||||
writeline(output, lineBuffer);
|
||||
end if;
|
||||
alu_opc_tb <= uADD;
|
||||
wait for 10 ns;
|
||||
|
||||
-- ADD
|
||||
if (unsigned(result_tb) = unsigned(input1_tb) + unsigned(input2_tb)) then
|
||||
write(lineBuffer, string'("ADD: +"));
|
||||
writeline(output, lineBuffer);
|
||||
else
|
||||
write(lineBuffer, string'("ADD: -"));
|
||||
writeline(output, lineBuffer);
|
||||
end if;
|
||||
alu_opc_tb <= uSUB;
|
||||
wait for 10 ns;
|
||||
|
||||
-- SUB
|
||||
if (unsigned(result_tb) = unsigned(input1_tb) - unsigned(input2_tb)) then
|
||||
write(lineBuffer, string'("SUB: +"));
|
||||
writeline(output, lineBuffer);
|
||||
else
|
||||
write(lineBuffer, string'("SUB: -"));
|
||||
writeline(output, lineBuffer);
|
||||
end if;
|
||||
alu_opc_tb <= uSLL;
|
||||
wait for 10 ns;
|
||||
|
||||
-- SLL
|
||||
if (unsigned(result_tb) = (unsigned(input1_tb) sll 1)) then
|
||||
write(lineBuffer, string'("SLL: +"));
|
||||
writeline(output, lineBuffer);
|
||||
else
|
||||
write(lineBuffer, string'("SLL: -"));
|
||||
writeline(output, lineBuffer);
|
||||
end if;
|
||||
alu_opc_tb <= uSLT;
|
||||
wait for 10 ns;
|
||||
|
||||
-- SLT
|
||||
if(signed(input1_tb) < signed(input2_tb)) then
|
||||
check_slt <= std_logic_vector(to_unsigned(1, wordWidth));
|
||||
else
|
||||
check_slt <= std_logic_vector(to_unsigned(0, wordWidth));
|
||||
end if; -- Set lower than
|
||||
wait for 10 ns;
|
||||
if (result_tb = check_slt) then
|
||||
write(lineBuffer, string'("SLT: +"));
|
||||
writeline(output, lineBuffer);
|
||||
else
|
||||
write(lineBuffer, string'("SLT: -"));
|
||||
writeline(output, lineBuffer);
|
||||
end if;
|
||||
alu_opc_tb <= uSLTU;
|
||||
wait for 10 ns;
|
||||
|
||||
-- SLTU
|
||||
if(unsigned(input1_tb) < unsigned(input2_tb)) then
|
||||
check_sltu <= std_logic_vector(to_unsigned(1, wordWidth));
|
||||
else
|
||||
check_sltu <= std_logic_vector(to_unsigned(0, wordWidth));
|
||||
end if; -- Set lower than unsigned
|
||||
wait for 10 ns;
|
||||
if (result_tb = check_sltu) then
|
||||
write(lineBuffer, string'("SLTU: +"));
|
||||
writeline(output, lineBuffer);
|
||||
else
|
||||
write(lineBuffer, string'("SLTU: -"));
|
||||
writeline(output, lineBuffer);
|
||||
end if;
|
||||
alu_opc_tb <= uXOR;
|
||||
wait for 10 ns;
|
||||
|
||||
-- XOR
|
||||
if (result_tb = (input1_tb xor input2_tb)) then
|
||||
write(lineBuffer, string'("XOR: +"));
|
||||
writeline(output, lineBuffer);
|
||||
else
|
||||
write(lineBuffer, string'("XOR: -"));
|
||||
writeline(output, lineBuffer);
|
||||
end if;
|
||||
alu_opc_tb <= uSRL;
|
||||
wait for 10 ns;
|
||||
|
||||
-- SRL
|
||||
if (unsigned(result_tb) = (unsigned(input1_tb) srl 1)) then
|
||||
write(lineBuffer, string'("SRL: +"));
|
||||
writeline(output, lineBuffer);
|
||||
else
|
||||
write(lineBuffer, string'("SRL: -"));
|
||||
writeline(output, lineBuffer);
|
||||
end if;
|
||||
alu_opc_tb <= uSRA;
|
||||
wait for 10 ns;
|
||||
|
||||
-- SRA
|
||||
if (unsigned(result_tb) = unsigned(std_logic_vector(to_stdlogicvector(to_bitvector(input1_tb) sra 1)))) then
|
||||
write(lineBuffer, string'("SRA: +"));
|
||||
writeline(output, lineBuffer);
|
||||
else
|
||||
write(lineBuffer, string'("SRA: -"));
|
||||
writeline(output, lineBuffer);
|
||||
end if;
|
||||
alu_opc_tb <= uOR;
|
||||
wait for 10 ns;
|
||||
|
||||
-- OR
|
||||
if (result_tb = (input1_tb or input2_tb)) then
|
||||
write(lineBuffer, string'("OR: +"));
|
||||
writeline(output, lineBuffer);
|
||||
else
|
||||
write(lineBuffer, string'("OR: -"));
|
||||
writeline(output, lineBuffer);
|
||||
end if;
|
||||
alu_opc_tb <= uAND;
|
||||
wait for 10 ns;
|
||||
|
||||
-- AND
|
||||
if (result_tb = (input1_tb and input2_tb)) then
|
||||
write(lineBuffer, string'("AND: +"));
|
||||
writeline(output, lineBuffer);
|
||||
else
|
||||
write(lineBuffer, string'("AND: -"));
|
||||
writeline(output, lineBuffer);
|
||||
end if;
|
||||
|
||||
-- end loop
|
||||
end loop;
|
||||
|
||||
-- end simulation
|
||||
write(lineBuffer, string'("end of simulation"));
|
||||
writeline(output, lineBuffer);
|
||||
|
||||
-- I'm still waiting
|
||||
wait;
|
||||
end process;
|
||||
end testing;
|
||||
|
||||
49
tb/tb_cpu.vhd
Normal file
49
tb/tb_cpu.vhd
Normal 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;
|
||||
end process;
|
||||
end architecture;
|
||||
84
tb/tb_decoder.vhd
Normal file
84
tb/tb_decoder.vhd
Normal file
@@ -0,0 +1,84 @@
|
||||
-- tb_decoder.vhd
|
||||
-- Created on: Di 6. Dez 10:50:02 CET 2022
|
||||
-- Author(s): Yannick Reiß, Car Ries, Alexander Graf
|
||||
-- Content: Testbench for decoder (NOT AUTOMATED, ONLY STIMULI)
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use ieee.math_real.uniform;
|
||||
|
||||
library work;
|
||||
use work.riscv_types.all;
|
||||
|
||||
library std;
|
||||
use std.textio.all;
|
||||
|
||||
-- Entity decoder_tb: dummy entity for decoder
|
||||
entity decoder_tb is
|
||||
end decoder_tb;
|
||||
|
||||
-- Architecture testingdecoder of decoder_tb: testing instruction decode
|
||||
architecture testingdecoder of decoder_tb is
|
||||
-- clk
|
||||
signal clk : std_logic;
|
||||
constant clk_period : time := 10 ns;
|
||||
|
||||
-- inputs
|
||||
signal instrDecode : instruction;
|
||||
|
||||
-- outputs
|
||||
signal aluOpCode : uOP;
|
||||
signal regOp1 : reg_idx;
|
||||
signal regOp2 : reg_idx;
|
||||
signal regWrite : reg_idx;
|
||||
begin
|
||||
uut : entity work.decoder(decode)
|
||||
port map (
|
||||
instrDecode => instrDecode,
|
||||
op_code => aluOpCode,
|
||||
regOp1 => regOp1,
|
||||
regOp2 => regOp2,
|
||||
regWrite => regWrite);
|
||||
|
||||
-- clk-prog
|
||||
clk_process : process -- runs only, when changed
|
||||
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 5 ns;
|
||||
|
||||
-- add x9, x0, x3
|
||||
instrDecode <= "00000000001100000000010010110011";
|
||||
wait for 10 ns;
|
||||
|
||||
-- add x1, x2, x3
|
||||
instrDecode <= "00000000001100010000000010110011";
|
||||
wait for 10 ns;
|
||||
|
||||
-- sll x1, x0, x2
|
||||
instrDecode <= "00000000001000000001000010110011";
|
||||
wait for 10 ns;
|
||||
|
||||
-- sub x6, x3, x1
|
||||
instrDecode <= "01000000000100011000001100110011";
|
||||
wait for 10 ns;
|
||||
|
||||
-- nop x6, x3, x1
|
||||
instrDecode <= "01000000000100011000001100110111";
|
||||
wait for 10 ns;
|
||||
|
||||
wait;
|
||||
end process;
|
||||
end testingdecoder;
|
||||
77
tb/tb_imm.vhd
Normal file
77
tb/tb_imm.vhd
Normal file
@@ -0,0 +1,77 @@
|
||||
-- tb_imm.vhd
|
||||
-- Created on: Tu 10. Jan 21:10:00 CET 2023
|
||||
-- Author(s): Yannick Reiß
|
||||
-- Content: testbench for immediate entity
|
||||
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 imm_tb: dummy entity
|
||||
entity imm_tb is
|
||||
end imm_tb;
|
||||
|
||||
architecture testing of imm_tb is
|
||||
|
||||
-- clock definition
|
||||
signal clk : std_logic;
|
||||
constant clk_period : time := 10 ns;
|
||||
|
||||
-- inputs imm
|
||||
signal s_instruction : instruction;
|
||||
signal s_opcode : uOP;
|
||||
|
||||
-- outputs imm
|
||||
signal s_immediate : word;
|
||||
|
||||
begin
|
||||
uut : entity work.imm
|
||||
port map(
|
||||
|
||||
instruction => s_instruction,
|
||||
opcode => s_opcode,
|
||||
immediate => s_immediate
|
||||
);
|
||||
|
||||
-- Process clk_process operating the clock
|
||||
clk_process : process
|
||||
begin
|
||||
clk <= '0';
|
||||
wait for clk_period/2;
|
||||
clk <= '1';
|
||||
wait for clk_period/2;
|
||||
end process;
|
||||
|
||||
-- stimulation process
|
||||
stim_proc : process
|
||||
variable lineBuffer : line;
|
||||
begin
|
||||
-- wait for the rising edge
|
||||
wait until rising_edge(clk);
|
||||
|
||||
wait for 10 ns;
|
||||
|
||||
write(lineBuffer, string'("Start the simulator"));
|
||||
writeline(output, lineBuffer);
|
||||
|
||||
-- testcases
|
||||
-- addi x3, x0, 5
|
||||
s_instruction <= x"00500193";
|
||||
s_opcode <= uADDI;
|
||||
|
||||
wait for 10 ns;
|
||||
|
||||
-- addi x2, x0, 1
|
||||
s_instruction <= x"00100113";
|
||||
s_opcode <= uADDI;
|
||||
|
||||
wait;
|
||||
|
||||
end process;
|
||||
|
||||
end architecture; -- testing
|
||||
133
tb/tb_pc.vhd
Normal file
133
tb/tb_pc.vhd
Normal file
@@ -0,0 +1,133 @@
|
||||
-- tb_pc.vhd
|
||||
-- Created on: Mo 05. Dec 15:44:55 CET 2022
|
||||
-- Author(s): Carl Ries, Yannick Reiß, Alexander Graf
|
||||
-- Content: Testbench for program counter
|
||||
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 pc_tb: dummy entity
|
||||
entity pc_tb is
|
||||
end pc_tb;
|
||||
|
||||
-- Architecture testing of pc_tb: testing calculations
|
||||
architecture testing of pc_tb is
|
||||
-- clock definition
|
||||
signal clk : std_logic;
|
||||
constant clk_period : time := 10 ns;
|
||||
|
||||
-- Inputs pc
|
||||
signal en_pc : one_bit;
|
||||
signal addr_calc : ram_addr_t;
|
||||
signal doJump : one_bit;
|
||||
|
||||
-- Outputs pc
|
||||
signal addr : ram_addr_t;
|
||||
|
||||
-- unittest signals pc
|
||||
signal addr_calc_tb : ram_addr_t;
|
||||
|
||||
begin
|
||||
-- Entity work.pc(pro_count): Init of Unit Under Test
|
||||
uut1 : entity work.pc
|
||||
port map (
|
||||
clk => clk,
|
||||
en_pc => en_pc,
|
||||
addr_calc => addr_calc,
|
||||
doJump => doJump,
|
||||
addr => addr
|
||||
);
|
||||
|
||||
-- Process clk_process operating the clock
|
||||
clk_process : process -- runs only, when changed
|
||||
begin
|
||||
clk <= '0';
|
||||
wait for clk_period/2;
|
||||
clk <= '1';
|
||||
wait for clk_period/2;
|
||||
end process;
|
||||
|
||||
-- Process stim_proc control device for uut
|
||||
stim_proc : process -- runs only, when changed
|
||||
-- Text I/O
|
||||
variable lineBuffer : line;
|
||||
begin
|
||||
|
||||
-- wait for the rising edge
|
||||
wait until rising_edge(clk);
|
||||
|
||||
wait for 10 ns;
|
||||
|
||||
-- Print the top element
|
||||
write(lineBuffer, string'("Start the simulator"));
|
||||
writeline(output, lineBuffer);
|
||||
|
||||
-- testcases
|
||||
|
||||
-- Case 1: addr_calc
|
||||
write(lineBuffer, string'("Testing Case 1: "));
|
||||
writeline(output, lineBuffer);
|
||||
|
||||
en_pc <= std_logic_vector(to_unsigned(1, 1));
|
||||
doJump <= std_logic_vector(to_unsigned(1, 1));
|
||||
addr_calc <= std_logic_vector(to_unsigned(30, ram_addr_size));
|
||||
wait for 10 ns;
|
||||
|
||||
if addr = std_logic_vector(to_unsigned(30, ram_addr_size)) then
|
||||
write(lineBuffer, string'("Result 1: +"));
|
||||
writeline(output, lineBuffer);
|
||||
else
|
||||
write(lineBuffer, string'("Result 1: -"));
|
||||
writeline(output, lineBuffer);
|
||||
end if;
|
||||
|
||||
-- Case 2: count
|
||||
write(lineBuffer, string'("Testing Case 2: "));
|
||||
writeline(output, lineBuffer);
|
||||
|
||||
en_pc <= std_logic_vector(to_unsigned(1, 1));
|
||||
doJump <= std_logic_vector(to_unsigned(0, 1));
|
||||
addr_calc <= std_logic_vector(to_unsigned(60, ram_addr_size));
|
||||
wait for 10 ns;
|
||||
|
||||
--same value from
|
||||
if addr = std_logic_vector(to_unsigned(31, ram_addr_size)) then
|
||||
write(lineBuffer, string'("Result 2: +"));
|
||||
writeline(output, lineBuffer);
|
||||
else
|
||||
write(lineBuffer, string'("Result 2: -"));
|
||||
writeline(output, lineBuffer);
|
||||
end if;
|
||||
|
||||
-- Case 3: hold
|
||||
write(lineBuffer, string'("Testing Case 3: "));
|
||||
writeline(output, lineBuffer);
|
||||
|
||||
en_pc <= std_logic_vector(to_unsigned(0, 1));
|
||||
doJump <= std_logic_vector(to_unsigned(0, 1));
|
||||
addr_calc <= std_logic_vector(to_unsigned(90, ram_addr_size));
|
||||
wait for 10 ns;
|
||||
|
||||
--same value from
|
||||
if addr = std_logic_vector(to_unsigned(31, ram_addr_size)) then
|
||||
write(lineBuffer, string'("Result 3: +"));
|
||||
writeline(output, lineBuffer);
|
||||
else
|
||||
write(lineBuffer, string'("Result 3: -"));
|
||||
writeline(output, lineBuffer);
|
||||
end if;
|
||||
|
||||
-- I'm still waiting
|
||||
wait;
|
||||
end process;
|
||||
end testing;
|
||||
|
||||
|
||||
|
||||
|
||||
106
tb/tb_ram.vhd
Normal file
106
tb/tb_ram.vhd
Normal file
@@ -0,0 +1,106 @@
|
||||
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 ram_tb is
|
||||
end ram_tb;
|
||||
|
||||
architecture Behavioral of ram_tb is
|
||||
|
||||
-- Clock
|
||||
signal clk : std_logic;
|
||||
|
||||
-- Inputs
|
||||
signal addr_a : std_logic_vector(ram_addr_size - 1 downto 0);
|
||||
signal write_b : std_logic_vector(1-1 downto 0);
|
||||
signal addr_b : std_logic_vector(ram_addr_size - 1 downto 0);
|
||||
signal data_write_b : std_logic_vector(wordWidth - 1 downto 0);
|
||||
|
||||
-- Outputs
|
||||
signal data_read_a : std_logic_vector(wordWidth - 1 downto 0);
|
||||
signal data_read_b : std_logic_vector(wordWidth - 1 downto 0);
|
||||
|
||||
-- Clock period definitions
|
||||
constant clk_period : time := 10 ns;
|
||||
|
||||
-- Unittest Signale
|
||||
signal tb_addr_a : integer;
|
||||
signal tb_addr_b : integer;
|
||||
signal tb_test_v : std_logic_vector(wordWidth - 1 downto 0);
|
||||
signal tb_check_v : std_logic_vector(wordWidth - 1 downto 0);
|
||||
signal tb_validate : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
-- Instantiate the Unit Under Test (UUT)
|
||||
uut : entity work.ram(Behavioral)
|
||||
port map (clk => clk,
|
||||
instructionAdr => addr_a,
|
||||
dataAdr => addr_b,
|
||||
writeEnable => write_b,
|
||||
dataIn => data_write_b,
|
||||
instruction => data_read_a,
|
||||
dataOut => data_read_b);
|
||||
|
||||
-- Clock process definitions
|
||||
clk_process : process
|
||||
begin
|
||||
clk <= '0';
|
||||
wait for clk_period/2;
|
||||
clk <= '1';
|
||||
wait for clk_period/2;
|
||||
end process;
|
||||
|
||||
-- Stimulus process
|
||||
stim_proc : process
|
||||
variable lineBuffer : line;
|
||||
begin
|
||||
|
||||
wait for 5 ns;
|
||||
|
||||
-- Wait for the first rising edge
|
||||
wait until rising_edge(clk);
|
||||
|
||||
-- manual test
|
||||
addr_a <= "001101001110";
|
||||
addr_b <= "011100110010";
|
||||
write_b <= "1";
|
||||
|
||||
wait for 10 ns;
|
||||
|
||||
-- Testing Mem
|
||||
tb_validate <= '1';
|
||||
write_b <= std_logic_vector(to_unsigned(1, 1));
|
||||
for test_case in 0 to 1000 loop
|
||||
for tb_addr in 0 to 4096 loop
|
||||
-- assign test values
|
||||
tb_test_v <= std_logic_vector(to_unsigned(tb_addr, wordWidth));
|
||||
tb_check_v <= std_logic_vector(to_unsigned(tb_addr, wordWidth));
|
||||
|
||||
-- Test this value
|
||||
addr_a <= std_logic_vector(to_unsigned(tb_addr, ram_addr_size));
|
||||
addr_b <= std_logic_vector(to_unsigned(tb_addr, ram_addr_size));
|
||||
data_write_b <= tb_test_v;
|
||||
|
||||
if (data_read_a = tb_check_v and data_read_b = tb_check_v) then
|
||||
tb_validate <= '0';
|
||||
write(lineBuffer, string'("Everything fine!"));
|
||||
writeline(output, lineBuffer);
|
||||
else
|
||||
tb_validate <= '1';
|
||||
end if;
|
||||
wait for 10 ns;
|
||||
end loop;
|
||||
end loop;
|
||||
|
||||
-- Simply wait forever
|
||||
wait;
|
||||
|
||||
end process;
|
||||
end architecture;
|
||||
231
tb/tb_reg.vhd
Normal file
231
tb/tb_reg.vhd
Normal file
@@ -0,0 +1,231 @@
|
||||
-- tb_reg.vhd
|
||||
-- Created on: Mo 14. Nov 11:55:58 CET 2022
|
||||
-- Author(s): Yannick Reiß, Alexander Graf, Carl Ries
|
||||
-- Content: Testbench for the registerblock
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use ieee.math_real.uniform;
|
||||
|
||||
library work;
|
||||
use work.riscv_types.all;
|
||||
|
||||
library std;
|
||||
use std.textio.all;
|
||||
|
||||
-- Entity regs_tb: Entity providing testinputs, receiving testoutputs for registerbench
|
||||
entity regs_tb is
|
||||
end regs_tb;
|
||||
|
||||
-- Architecture testing of regs_tb: testing read / write operations
|
||||
architecture testing of regs_tb is
|
||||
-- clock definition
|
||||
signal clk : std_logic;
|
||||
constant clk_period : time := 10 ns;
|
||||
|
||||
-- Inputs
|
||||
signal en_reg_wb_tb : one_bit;
|
||||
signal data_in_tb : word;
|
||||
signal wr_idx_tb : reg_idx;
|
||||
signal r1_idx_tb : reg_idx;
|
||||
signal r2_idx_tb : reg_idx;
|
||||
signal write_enable_tb : one_bit;
|
||||
|
||||
-- Outputs
|
||||
signal r1_out_tb : word;
|
||||
signal r2_out_tb : word;
|
||||
|
||||
-- unittest signals
|
||||
signal random_slv: word;
|
||||
|
||||
--function for random_std_logic_vector
|
||||
function get_random_slv return std_logic_vector is
|
||||
|
||||
-- random number variablen
|
||||
variable seed1 : integer := 1;
|
||||
variable seed2 : integer := 1;
|
||||
variable r : real;
|
||||
variable slv : std_logic_vector(wordWidth - 1 downto 0);
|
||||
|
||||
begin
|
||||
for i in slv'range loop
|
||||
uniform(seed1, seed2, r);
|
||||
slv(i) := '1' when r > 0.5 else '0';
|
||||
end loop;
|
||||
return slv;
|
||||
end function;
|
||||
|
||||
begin
|
||||
|
||||
-- Init of Unit Under Test
|
||||
uut : entity work.registers(Structure)
|
||||
port map (
|
||||
clk => clk,
|
||||
en_reg_wb => en_reg_wb_tb,
|
||||
data_in => data_in_tb,
|
||||
wr_idx => wr_idx_tb,
|
||||
r1_idx => r1_idx_tb,
|
||||
r2_idx => r2_idx_tb,
|
||||
write_enable => write_enable_tb,
|
||||
r1_out => r1_out_tb,
|
||||
r2_out => r2_out_tb
|
||||
);
|
||||
|
||||
-- Process clk_process operating the clock
|
||||
clk_process : process -- runs always
|
||||
begin
|
||||
clk <= '0';
|
||||
wait for clk_period/2;
|
||||
clk <= '1';
|
||||
wait for clk_period/2;
|
||||
end process;
|
||||
|
||||
-- Stimulating the UUT
|
||||
-- Process stim_proc control device for
|
||||
stim_proc : process
|
||||
-- Text I/O
|
||||
variable lineBuffer : line;
|
||||
|
||||
begin
|
||||
|
||||
-- wait for the rising edge
|
||||
wait until rising_edge(clk);
|
||||
|
||||
wait for 5 ns;
|
||||
|
||||
-- Print the top element
|
||||
write(lineBuffer, string'("Start the simulation: "));
|
||||
writeline(output, lineBuffer);
|
||||
|
||||
-- set the stimuli here
|
||||
|
||||
-- Case 1: write to x=7 + read x=4
|
||||
write(lineBuffer, string'("Testing Case 1: "));
|
||||
writeline(output, lineBuffer);
|
||||
|
||||
write_enable_tb <= std_logic_vector(to_unsigned(1, 1));
|
||||
data_in_tb<= std_logic_vector(to_unsigned(7, wordWidth));
|
||||
wr_idx_tb <= std_logic_vector(to_unsigned(7, reg_adr_size));
|
||||
r1_idx_tb <= std_logic_vector(to_unsigned(4, reg_adr_size));
|
||||
r2_idx_tb <= std_logic_vector(to_unsigned(7, reg_adr_size));
|
||||
wait for 10 ns;
|
||||
|
||||
if r1_out_tb = std_logic_vector(to_unsigned(0, wordWidth)) and r2_out_tb = std_logic_vector(to_unsigned(7, wordWidth)) then
|
||||
write(lineBuffer, string'("Result 1: +"));
|
||||
writeline(output, lineBuffer);
|
||||
else
|
||||
write(lineBuffer, string'("Result 1: -"));
|
||||
writeline(output, lineBuffer);
|
||||
end if;
|
||||
|
||||
-- Case 2: write to x=27 + read x=0
|
||||
write(lineBuffer, string'("Testing Case 2: "));
|
||||
writeline(output, lineBuffer);
|
||||
|
||||
write_enable_tb <= std_logic_vector(to_unsigned(1, 1));
|
||||
data_in_tb<= std_logic_vector(to_unsigned(7, wordWidth));
|
||||
wr_idx_tb <= std_logic_vector(to_unsigned(27, reg_adr_size));
|
||||
r1_idx_tb <= std_logic_vector(to_unsigned(0, reg_adr_size));
|
||||
r2_idx_tb <= std_logic_vector(to_unsigned(27, reg_adr_size));
|
||||
wait for 10 ns;
|
||||
|
||||
if r1_out_tb = std_logic_vector(to_unsigned(0, wordWidth)) and r2_out_tb = std_logic_vector(to_unsigned(7, wordWidth)) then
|
||||
write(lineBuffer, string'("Result 2: +"));
|
||||
writeline(output, lineBuffer);
|
||||
else
|
||||
write(lineBuffer, string'("Result 2: -"));
|
||||
writeline(output, lineBuffer);
|
||||
end if;
|
||||
|
||||
-- Case 3: write to zero + read from zero x2
|
||||
write(lineBuffer, string'("Testing Case 3: "));
|
||||
writeline(output, lineBuffer);
|
||||
|
||||
write_enable_tb <= std_logic_vector(to_unsigned(1, 1));
|
||||
data_in_tb<= std_logic_vector(to_unsigned(7, wordWidth));
|
||||
wr_idx_tb <= std_logic_vector(to_unsigned(0, reg_adr_size));
|
||||
r1_idx_tb <= std_logic_vector(to_unsigned(0, reg_adr_size));
|
||||
r2_idx_tb <= std_logic_vector(to_unsigned(27, reg_adr_size));
|
||||
wait for 10 ns;
|
||||
|
||||
if r1_out_tb = std_logic_vector(to_unsigned(0, wordWidth)) then
|
||||
write(lineBuffer, string'("Result 3: +"));
|
||||
writeline(output, lineBuffer);
|
||||
else
|
||||
write(lineBuffer, string'("Result 3: -"));
|
||||
writeline(output, lineBuffer);
|
||||
end if;
|
||||
|
||||
-- Case 4: write to 31 + read from 31
|
||||
write(lineBuffer, string'("Testing Case 4: "));
|
||||
writeline(output, lineBuffer);
|
||||
|
||||
write_enable_tb <= std_logic_vector(to_unsigned(1, 1));
|
||||
data_in_tb<= std_logic_vector(to_unsigned(7, wordWidth));
|
||||
wr_idx_tb <= std_logic_vector(to_unsigned(31, reg_adr_size));
|
||||
r1_idx_tb <= std_logic_vector(to_unsigned(31, reg_adr_size));
|
||||
r2_idx_tb <= std_logic_vector(to_unsigned(0, reg_adr_size));
|
||||
wait for 10 ns;
|
||||
|
||||
if r1_out_tb = std_logic_vector(to_unsigned(7, wordWidth)) then
|
||||
write(lineBuffer, string'("Result 4: +"));
|
||||
writeline(output, lineBuffer);
|
||||
else
|
||||
write(lineBuffer, string'("Result 4: -"));
|
||||
writeline(output, lineBuffer);
|
||||
end if;
|
||||
|
||||
-- Case 5: read x=7 + read x=18
|
||||
write(lineBuffer, string'("Testing Case 5: "));
|
||||
writeline(output, lineBuffer);
|
||||
|
||||
write_enable_tb <= std_logic_vector(to_unsigned(0, 1));
|
||||
data_in_tb<= std_logic_vector(to_unsigned(9, wordWidth));
|
||||
wr_idx_tb <= std_logic_vector(to_unsigned(7, reg_adr_size));
|
||||
r1_idx_tb <= std_logic_vector(to_unsigned(7, reg_adr_size));
|
||||
r2_idx_tb <= std_logic_vector(to_unsigned(18, reg_adr_size));
|
||||
wait for 10 ns;
|
||||
|
||||
-- Not allowed to change, last value was 7, new "would" be 9
|
||||
if r1_out_tb = std_logic_vector(to_unsigned(7, wordWidth)) then
|
||||
write(lineBuffer, string'("Result 5: +"));
|
||||
writeline(output, lineBuffer);
|
||||
else
|
||||
write(lineBuffer, string'("Result 5: -"));
|
||||
writeline(output, lineBuffer);
|
||||
end if;
|
||||
|
||||
-- Case 6: RANDOM_Test write to 12 + read from 12
|
||||
write(lineBuffer, string'("Testing Case 6: "));
|
||||
writeline(output, lineBuffer);
|
||||
|
||||
-- get random_logic_vector
|
||||
random_slv <= get_random_slv;
|
||||
|
||||
wait for 10 ns;
|
||||
|
||||
write_enable_tb <= std_logic_vector(to_unsigned(1, 1));
|
||||
data_in_tb <= random_slv;
|
||||
wr_idx_tb <= std_logic_vector(to_unsigned(12, reg_adr_size));
|
||||
r1_idx_tb <= std_logic_vector(to_unsigned(12, reg_adr_size));
|
||||
r2_idx_tb <= std_logic_vector(to_unsigned(0, reg_adr_size));
|
||||
wait for 10 ns;
|
||||
|
||||
if r1_out_tb = random_slv then
|
||||
write(lineBuffer, string'("Result 6: +"));
|
||||
writeline(output, lineBuffer);
|
||||
else
|
||||
write(lineBuffer, string'("Result 6: -"));
|
||||
writeline(output, lineBuffer);
|
||||
end if;
|
||||
|
||||
-- end simulation
|
||||
write(lineBuffer, string'("end of simulation"));
|
||||
writeline(output, lineBuffer);
|
||||
|
||||
-- I'm still waiting
|
||||
wait;
|
||||
end process;
|
||||
|
||||
end testing;
|
||||
Reference in New Issue
Block a user