Skip to content
Snippets Groups Projects
riscv_decode_tb.vhd 5.82 KiB
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

  -- Write to a register, no checking of what's coming out
  -- TODO: Adapter
  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: Adapter
  procedure test_vector (
   constant period : in time) is
  begin
      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;

  constant PERIOD : time := 10 ns;

begin

  -- Instanciation du DUT
  --dut: entity work.riscv_rf
  --  port map (
  --    i_clk     => clk, 
  --    i_rstn    => rstn,
  --    i_we      => we,
  --    i_addr_ra => addr_ra,
  --    o_data_ra => data_ra,
  --    i_addr_rb => addr_rb,
  --    o_data_rb => data_rb,
  --    i_addr_w  => addr_w,
  --    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
  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 => '-');
    --addr_rb <= (others => '-');

    --addr_w  <= (others => '-');
    --data_w  <= (others => '-');
    --we      <= '-';
    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(
        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
    -- TODO: Adapter mais le laisser faire la même chose
    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)-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;

    report "Test every instruction in supported ISA"; 

    -- LUI: registre 0x03 <- pattern 0101 répété sur 20 bits

    -- 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;