Newer
Older
-------------------------------------------------------------------------------
-- Project ELE8304 : Circuits intégrés à très grande échelle
-------------------------------------------------------------------------------
-- File riscv_decode_tb.vhd
-- Authors Titouan Luard <luardtitouan@gmail.com>
-- Yann Roberge <yann.roberge@polymtl.ca>
-- Lab ELE8304-9
-- Date 2021-11-28
-------------------------------------------------------------------------------
-- Brief RISC-V Register file
--
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
library work;
use work.riscv_pkg.all;
entity riscv_decode_tb is
end riscv_decode_tb;
architecture tb of riscv_decode_tb is
-- Entrées/Sorties du DUT
signal instruction : std_logic_vector(XLEN-1 downto 0);
signal pc_i : std_logic_vector(XLEN-1 downto 0);
signal wr_addr : std_logic_vector(REG_WIDTH-1 downto 0);
signal wr_data : std_logic_vector(XLEN-1 downto 0);
signal we : std_logic;
signal flush : std_logic;
signal rstn : std_logic;
signal clk : std_logic;
signal rs1_data : std_logic_vector(XLEN-1 downto 0);
signal rs2_data : std_logic_vector(XLEN-1 downto 0);
signal shamt : std_logic_vector(SHAMT_WIDTH-1 downto 0);
signal arith : std_logic;
signal sign : std_logic;
signal jump : std_logic;
signal branch : std_logic;
signal pc_o : std_logic_vector(XLEN-1 downto 0);
signal imm : std_logic_vector(XLEN-1 downto 0);
-- Write to a register, no checking of what's coming out
-- TODO: Adapter
procedure write_reg (
signal wr_addr : out std_logic_vector(REG_WIDTH-1 downto 0);
signal wr_data : out std_logic_vector(XLEN-1 downto 0);
signal we : out std_logic;
constant test_wr_addr : in std_logic_vector(REG_WIDTH-1 downto 0);
constant test_wr_data : in std_logic_vector(XLEN-1 downto 0);
constant period : in time) is
begin
wr_addr <= test_wr_addr;
wr_data <= test_wr_data;
we <= '1';
wait for period;
report "Wrote " & to_string(wr_data) & " to reg " & to_string(wr_addr);
end procedure write_reg;
-- Procédure pour un vecteur de test
-- TODO: Adapter
procedure test_vector (
signal instruction : out std_logic_vector(XLEN-1 downto 0);
signal pc_i : out std_logic_vector(XLEN-1 downto 0);
signal wr_addr : out std_logic_vector(REG_WIDTH-1 downto 0);
signal wr_data : out std_logic_vector(XLEN-1 downto 0);
signal we : out std_logic;
signal flush : out std_logic;
signal rs1_data : in std_logic_vector(XLEN-1 downto 0);
signal rs2_data : in std_logic_vector(XLEN-1 downto 0);
signal shamt : in std_logic_vector(SHAMT_WIDTH-1 downto 0);
signal arith : in std_logic;
signal sign : in std_logic;
signal jump : in std_logic;
signal branch : in std_logic;
signal pc_o : in std_logic_vector(XLEN-1 downto 0);
signal imm : in std_logic_vector(XLEN-1 downto 0);
constant test_instruction : in std_logic_vector(XLEN-1 downto 0);
constant test_pc_i : in std_logic_vector(XLEN-1 downto 0);
constant test_wr_addr : in std_logic_vector(REG_WIDTH-1 downto 0);
constant test_wr_data : in std_logic_vector(XLEN-1 downto 0);
constant test_we : in std_logic;
constant test_flush : in std_logic;
constant expected_rs1_data : in std_logic_vector(XLEN-1 downto 0);
constant expected_rs2_data : in std_logic_vector(XLEN-1 downto 0);
constant expected_shamt : in std_logic_vector(SHAMT_WIDTH-1 downto 0);
constant expected_arith : in std_logic;
constant expected_sign : in std_logic;
constant expected_jump : in std_logic;
constant expected_branch : in std_logic;
constant expected_pc_o : in std_logic_vector(XLEN-1 downto 0);
constant expected_imm : in std_logic_vector(XLEN-1 downto 0);
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
constant period : in time) is
begin
-- Set test signals
instruction <= test_instruction;
pc_i <= test_pc_i;
wr_addr <= test_wr_addr;
wr_data <= test_wr_data;
we <= test_we;
flush <= test_flush;
-- Wait a cycle
wait for period;
-- Assert all outputs are what we expect
assert rs1_data = expected_rs1_data
report "RS1_DATA DIFFERS FROM EXPECTED" severity error;
assert rs2_data = expected_rs2_data
report "RS2_DATA DIFFERS FROM EXPECTED" severity error;
assert shamt = expected_shamt
report "SHAMT DIFFERS FROM EXPECTED" severity error;
assert arith = expected_arith
report "ARITH DIFFERS FROM EXPECTED" severity error;
assert sign = expected_sign
report "SIGN DIFFERS FROM EXPECTED" severity error;
assert jump = expected_jump
report "JUMP DIFFERS FROM EXPECTED" severity error;
assert branch = expected_branch
report "BRANCH DIFFERS FROM EXPECTED" severity error;
assert pc_o = expected_pc_o
report "PC_O DIFFERS FROM EXPECTED" severity error;
assert imm = expected_imm
report "IMM DIFFERS FROM EXPECTED" severity error;
end procedure test_vector;
constant PERIOD : time := 10 ns;
begin
-- Instanciation du DUT
dut: entity work.riscv_decode
port map (
i_instruction => instruction,
i_pc => pc_i,
i_wr_addr => wr_addr,
i_wr_data => wr_data,
i_we => we,
i_flush => flush,
i_rstn => rstn,
i_clk => clk,
o_rs1_data => rs1_data,
o_rs2_data => rs2_data,
o_shamt => shamt,
o_arith => arith,
o_sign => sign,
o_jump => jump,
o_branch => branch,
o_pc => pc_o,
o_imm => imm
);
-- Drive clock
drive_clk : process is
begin
clk <= '0';
wait for PERIOD/2;
clk <= '1';
wait for PERIOD/2;
end process drive_clk;
-- Main TB process
p_main : process is
constant DUMMY_DATA : std_logic_vector(XLEN-1 downto 0) := (3 downto 0 => "1010", others => '1');
constant DUMMY_REG_ADDR : std_logic_vector(REG_WIDTH-1 downto 0) := (others => '1');
constant EXAMPLE_PC : std_logic_vector(XLEN-1 downto 0) := (3 downto 0 => "1010", others => '1');
-- Tests des cas représentatif
report "BEGIN SIMULATION";
instruction <= (others => '-');
pc_i <= (others => '-');
wr_data <= (others => '-');
we <= '-';
flush <= '0';
rstn <= '0';
wait for PERIOD;
rstn <= '1';
wait for 2*PERIOD;
-- Write all registers
-- TODO: Adapter mais le laisser faire la même chose
report "Write all registers except 0x00";
for i in 1 to 2**(REG_WIDTH)-1 loop
write_reg(
wr_addr => wr_addr,
wr_data => wr_data,
we => we,
test_wr_addr => std_logic_vector(to_unsigned(i, wr_addr'length)),
test_wr_data => std_logic_vector(to_unsigned(i + 3, wr_data'length)),
period => PERIOD
);
end loop;
-- Read back all registers
-- TODO: Adapter mais le laisser faire la même chose
report "Read back all registers";
-- ADDI 0 to reg[0] specifically, check result
test_vector(
instruction, pc_i, wr_addr, wr_data, we, flush, rs1_data, rs2_data,
shamt, arith, sign, jump, branch, pc_o, imm,
test_instruction => "000000000000" & std_logic_vector(to_unsigned(0, REG_WIDTH)) & FUNCT3_ADD & DUMMY_REG_ADDR & OPCODE_ALU_I_TYPE,
test_pc_i => EXAMPLE_PC,
test_wr_addr => (others => '-'),
test_wr_data => (others => '-'),
test_we => '0',
test_flush => '0',
expected_rs1_data => (others => '0'),
expected_rs2_data => (others => '-'),
expected_shamt => (others => '-'),
expected_arith => '-',
expected_sign => '-',
expected_jump => '-',
expected_branch => '-',
expected_pc_o => EXAMPLE_PC,
expected_imm => (others => '0'),
for i in 1 to 2**(REG_WIDTH)-2 loop
-- ADDI 0 to reg[i], check result
instruction, pc_i, wr_addr, wr_data, we, flush, rs1_data, rs2_data,
shamt, arith, sign, jump, branch, pc_o, imm,
test_instruction => "000000000000" & std_logic_vector(to_unsigned(i, REG_WIDTH)) & FUNCT3_ADD & DUMMY_REG_ADDR & OPCODE_ALU_I_TYPE,
test_pc_i => EXAMPLE_PC,
test_wr_addr => (others => '-'),
test_wr_data => (others => '-'),
test_we => '0',
test_flush => '0',
expected_rs1_data => std_logic_vector(to_unsigned(i+3, rs1_data'length)),
expected_rs2_data => (others => '-'),
expected_shamt => (others => '-'),
expected_arith => '-',
expected_sign => '-',
expected_jump => '-',
expected_branch => '-',
expected_pc_o => EXAMPLE_PC,
expected_imm => (others => '0'),
);
end loop;
report "Test every instruction in supported ISA";
-- LUI: registre 0x03 <- pattern 0101 répété sur 20 bits
test_vector(
instruction, pc_i, wr_addr, wr_data, we, flush, rs1_data, rs2_data,
shamt, arith, sign, jump, branch, pc_o, imm,
test_instruction => "11110000111100001111" & DUMMY_REG_ADDR & OPCODE_LUI,
test_pc_i => EXAMPLE_PC,
test_wr_addr => (others => '-'),
test_wr_data => (others => '-'),
test_we => '0',
test_flush => '0',
expected_rs1_data => (others => '-'),
expected_rs2_data => (others => '-'),
expected_shamt => (others => '-'),
expected_arith => '0',
expected_sign => '0',
expected_jump => '0',
expected_branch => '0',
expected_pc_o => EXAMPLE_PC,
expected_imm => (XLEN-1 downto 12 => "11110000111100001111", others => '0'),
test_vector(
instruction, pc_i, wr_addr, wr_data, we, flush, rs1_data, rs2_data,
shamt, arith, sign, jump, branch, pc_o, imm,
test_instruction => "11110000111100001111" & DUMMY_DEST_REG & OPCODE_JAL,
test_pc_i => EXAMPLE_PC,
test_wr_addr => (others => '-'),
test_wr_data => (others => '-'),
test_we => '0',
test_flush => '0',
expected_rs1_data => (others => '-'),
expected_rs2_data => (others => '-'),
expected_shamt => (others => '-'),
expected_arith => '0',
expected_sign => '0',
expected_jump => '1',
expected_branch => '0',
expected_pc_o => EXAMPLE_PC,
expected_imm => (XLEN-1 downto 12 => "11110000111100001111", others => '0'),
period => PERIOD
);
test_vector(
instruction, pc_i, wr_addr, wr_data, we, flush, rs1_data, rs2_data,
shamt, arith, sign, jump, branch, pc_o, imm,
test_instruction => "111100001111" & DUMMY_REG_ADDR & FUNCT3_JALR & DUMMY_DEST_REG & OPCODE_JALR,
test_pc_i => EXAMPLE_PC,
test_wr_addr => (others => '-'),
test_wr_data => (others => '-'),
test_we => '0',
test_flush => '0',
expected_rs1_data => (others => '-'),
expected_rs2_data => (others => '-'),
expected_shamt => (others => '-'),
expected_arith => '-',
expected_sign => '-',
expected_jump => '-',
expected_branch => '-',
expected_pc_o => EXAMPLE_PC,
expected_imm => (XLEN-1 downto 12 => "111100001111", others => '0'),
period => PERIOD
);
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
-- BEQ
-- LW
-- SW
-- ADDI
-- SLTI
-- SLTUI
-- XORI
-- ORI
-- ANDI
-- SLLI
-- SRLI
-- SRAI
-- ADD
-- SUB
-- SLL
-- SLT
-- SLTU
-- XOR
-- SRL
-- SRA
-- OR
-- AND
-- Flush pipeline
-- Reset entire stage
report "Reset";
rstn <= '0';
wait for PERIOD;
rstn <= '1';
wait for PERIOD;
report "SIMULATION DONE";
wait;
end process p_main;
end architecture tb;