diff --git a/sources/riscv_rf_tb.vhd b/sources/riscv_rf_tb.vhd index 8c7a6d79ba7929d96404bd27658a4066fcdfbcdb..5fe1d3f062e14d5c33d0a7f1ffacf7d3d43e952a 100644 --- a/sources/riscv_rf_tb.vhd +++ b/sources/riscv_rf_tb.vhd @@ -24,49 +24,88 @@ end riscv_rf_tb; architecture tb of riscv_rf_tb is -- Entrées/Sorties du DUT - --TODO - signal clk : std_logic; - signal rstn : std_logic; - signal we : std_logic_vector; - signal addr_ra : std_logic; - signal data_ra : std_logic; - signal addr_rb : std_logic; - signal data_rb : std_logic; - signal addr_w : std_logic; - signal data_w : std_logic; + signal clk : std_logic; + signal rstn : std_logic; + signal we : std_logic; + signal addr_ra : std_logic_vector(REG_WIDTH-1 downto 0); + signal data_ra : std_logic_vector(XLEN-1 downto 0); + signal addr_rb : std_logic_vector(REG_WIDTH-1 downto 0); + signal data_rb : std_logic_vector(XLEN-1 downto 0); + signal addr_w : std_logic_vector(REG_WIDTH-1 downto 0); + signal data_w : std_logic_vector(XLEN-1 downto 0); + + -- Write to a register, no checking of what's coming out + procedure write_reg ( + signal rstn : out std_logic; + signal addr_ra : out std_logic_vector(REG_WIDTH-1 downto 0); + signal addr_rb : out std_logic_vector(REG_WIDTH-1 downto 0); + + 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 + rstn <= '1'; + addr_ra <= (others => '-'); + addr_rb <= (others => '-'); + + 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); + addr_w <= (others => '-'); + data_w <= (others => '-'); + we <= '0'; + wait for period; + + end procedure write_reg; -- Procédure pour un vecteur de test - --TODO procedure test_vector ( - constant test_arith : in std_logic; - constant test_sign : in std_logic; - constant test_opcode : in std_logic_vector(ALUOP_WIDTH-1 downto 0); - constant test_shamt : in std_logic_vector(SHAMT_WIDTH-1 downto 0); - constant test_src1 : in std_logic_vector(XLEN-1 downto 0); - constant test_src2 : in std_logic_vector(XLEN-1 downto 0); - - signal arith : out std_logic; - signal sign : out std_logic; - signal opcode : out std_logic_vector(ALUOP_WIDTH-1 downto 0); - signal shamt : out std_logic_vector(SHAMT_WIDTH-1 downto 0); - signal src1 : out std_logic_vector(XLEN-1 downto 0); - signal src2 : out std_logic_vector(XLEN-1 downto 0); - signal res : in std_logic_vector(XLEN-1 downto 0); - - constant expected_result: in std_logic_vector(XLEN-1 downto 0); + signal rstn : out std_logic; + signal addr_ra : out std_logic_vector(REG_WIDTH-1 downto 0); + signal addr_rb : out std_logic_vector(REG_WIDTH-1 downto 0); + + 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; + + signal data_ra : in std_logic_vector(XLEN-1 downto 0); + signal data_rb : in std_logic_vector(XLEN-1 downto 0); + + constant test_addr_ra : in std_logic_vector(REG_WIDTH-1 downto 0); + constant test_addr_rb : in std_logic_vector(REG_WIDTH-1 downto 0); + + 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 test_we : in std_logic; + + constant expected_ra: in std_logic_vector(XLEN-1 downto 0); + constant expected_rb: in std_logic_vector(XLEN-1 downto 0); constant period : in time) is begin - arith <= test_arith; - sign <= test_sign; - opcode <= test_opcode; - shamt <= test_shamt; - src1 <= test_src1; - src2 <= test_src2; - - wait for period; - assert res = expected_result - report "RESULT DIFFERS FROM EXPECTED" severity error; + rstn <= '1'; + addr_ra <= test_addr_ra; + addr_rb <= test_addr_rb; + + addr_w <= test_addr_w; + data_w <= test_data_w; + we <= test_we; + wait for period; + + assert data_ra = expected_ra + report "REGISTER A DIFFERS FROM EXPECTED" severity error; + assert data_rb = expected_rb + report "REGISTER B DIFFERS FROM EXPECTED" severity error; + end procedure test_vector; @@ -88,42 +127,166 @@ begin i_data_w => data_w ); + -- 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 - --TODO - p_main : process + p_main : process is + constant DUMMY_DATA : std_logic_vector(XLEN-1 downto 0) := (3 downto 0 => "1010", others => '1'); begin -- Tests des cas représentatif report "BEGIN SIMULATION"; + rstn <= '0'; + addr_ra <= (others => '0'); + addr_rb <= (others => '0'); + + addr_w <= (others => '0'); + data_w <= (others => '0'); + we <= '0'; + wait for PERIOD; + rstn <= '1'; + wait for 2*PERIOD; -- Write all registers - report "Write" - test_vector ( - test_arith => SHIFT_LOGIC, - test_sign => '-', - test_opcode => ALUOP_SH_LEFT, - test_shamt => std_logic_vector(to_unsigned(2, shamt'length)), - test_src1 => (others => '1'), - test_src2 => (others => '-'), - - arith => arith, - sign => sign, - opcode => opcode, - shamt => shamt, - src1 => src1, - src2 => src2, - res => res, - - expected_result => (1 downto 0 => "00", others => '1'), - period => PERIOD - ); + report "Write all registers including 0x00"; + for i in 1 to 2**(REG_WIDTH-1)-1 loop + write_reg( + rstn => rstn, + addr_ra => addr_ra, + addr_rb => addr_rb, + + addr_w => addr_w, + data_w => data_w, + we => we, + + test_addr_w => std_logic_vector(to_unsigned(i, REG_WIDTH)), + test_data_w => std_logic_vector(to_unsigned(i + 3, XLEN)), + + period => PERIOD + ); + end loop; -- Read back all registers + report "Read back all registers"; + test_vector( -- special case for register 0 + rstn => rstn, + addr_ra => addr_ra, + addr_rb => addr_rb, + + addr_w => addr_w, + data_w => data_w, + we => we, + + data_ra => data_ra, + data_rb => data_rb, + + test_addr_ra => std_logic_vector(to_unsigned(0, addr_ra'length)), + test_addr_rb => std_logic_vector(to_unsigned(0, addr_rb'length)), + + test_addr_w => (others => '-'), + test_data_w => (others => '-'), + test_we => '0', + + expected_ra => (others => '0'), + expected_rb => (others => '0'), + period => PERIOD + ); + + for i in 1 to 2**(REG_WIDTH-1)-2 loop + test_vector( + rstn => rstn, + addr_ra => addr_ra, + addr_rb => addr_rb, + + addr_w => addr_w, + data_w => data_w, + we => we, + + data_ra => data_ra, + data_rb => data_rb, + + test_addr_ra => std_logic_vector(to_unsigned(i, addr_ra'length)), + test_addr_rb => std_logic_vector(to_unsigned(i+1, addr_rb'length)), + + test_addr_w => (others => '-'), + test_data_w => (others => '-'), + test_we => '0', + + expected_ra => std_logic_vector(to_unsigned(i+3, data_ra'length)), + expected_rb => std_logic_vector(to_unsigned(i+4, data_rb'length)), + period => PERIOD + ); + end loop; -- Read & Write all registers at the same time + -- Note: Can't write into 0 + report "Read & Write at the same time"; + for i in 1 to 2**(REG_WIDTH-1)-2 loop + test_vector( + rstn => rstn, + addr_ra => addr_ra, + addr_rb => addr_rb, + + addr_w => addr_w, + data_w => data_w, + we => we, + + data_ra => data_ra, + data_rb => data_rb, + + test_addr_ra => std_logic_vector(to_unsigned(i, addr_ra'length)), + test_addr_rb => std_logic_vector(to_unsigned(i+1, addr_rb'length)), + + test_addr_w => std_logic_vector(to_unsigned(i, addr_w'length)), + test_data_w => DUMMY_DATA, + test_we => '1', + + expected_ra => DUMMY_DATA, + expected_rb => std_logic_vector(to_unsigned(i+4, data_rb'length)), + period => PERIOD + ); + end loop; -- Reset file + report "Reset"; + rstn <= '0'; + wait for PERIOD; + rstn <= '1'; + wait for PERIOD; -- Read all registers + report "Verify reset worked"; + for i in 0 to 2**(REG_WIDTH-1)-2 loop + test_vector( + rstn => rstn, + addr_ra => addr_ra, + addr_rb => addr_rb, + + addr_w => addr_w, + data_w => data_w, + we => we, + + data_ra => data_ra, + data_rb => data_rb, + + test_addr_ra => std_logic_vector(to_unsigned(i, addr_ra'length)), + test_addr_rb => std_logic_vector(to_unsigned(i+1, addr_rb'length)), + + test_addr_w => (others => '-'), + test_data_w => (others => '-'), + test_we => '0', + + expected_ra => (others => '0'), + expected_rb => (others => '0'), + period => PERIOD + ); + end loop; report "SIMULATION DONE"; wait;