------------------------------------------------------------------------------- -- 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(REG_WIDTH-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 addr_w : out std_logic_vector(REG_WIDTH-1 downto 0); signal data_w : out std_logic_vector(XLEN-1 downto 0); signal we : out std_logic; constant test_addr_w : in std_logic_vector(REG_WIDTH-1 downto 0); constant test_data_w : in std_logic_vector(XLEN-1 downto 0); constant period : in time) is begin addr_w <= test_addr_w; data_w <= test_data_w; we <= '1'; wait for period; report "Wrote " & to_string(data_w) & " to reg " & to_string(addr_w); 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(REG_WIDTH-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); signal test_instruction : in std_logic_vector(XLEN-1 downto 0); signal test_pc_i : in std_logic_vector(XLEN-1 downto 0); signal test_wr_addr : in std_logic_vector(REG_WIDTH-1 downto 0); signal test_wr_data : in std_logic_vector(REG_WIDTH-1 downto 0); signal test_we : in std_logic; signal 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); 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 EXAMPLE_PC : std_logic_vector(XLEN-1 downto 0) := (3 downto 0 => "1010", others => '1'); begin -- 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( addr_w => addr_w, data_w => data_w, we => we, test_addr_w => std_logic_vector(to_unsigned(i, addr_w)), test_data_w => std_logic_vector(to_unsigned(i + 3, data_w)), 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 & 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 => (others => '-'), expected_sign => (others => '-'), expected_jump => (others => '-'), expected_branch => (others => '-'), expected_pc_o => EXAMPLE_PC, expected_imm => (others => '0'), PERIOD ); for i in 1 to 2**(REG_WIDTH)-2 loop -- ADDI 0 to reg[i], 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(i, REG_WIDTH)) & FUNCT3_ADD & 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 => (others => '-'), expected_sign => (others => '-'), expected_jump => (others => '-'), expected_branch => (others => '-'), expected_pc_o => EXAMPLE_PC, expected_imm => (others => '0'), PERIOD ); 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" & "00011" & 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 => (others => '-'), expected_sign => (others => '-'), expected_jump => (others => '-'), expected_branch => (others => '-'), expected_pc_o => EXAMPLE_PC, expected_imm => (XLEN-1 downto 12 => "11110000111100001111", others => '0'), PERIOD ); -- JAL -- JALR -- 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;