Skip to content
Snippets Groups Projects
riscv_alu_tb.vhd 10.6 KiB
Newer Older
-------------------------------------------------------------------------------
-- Project  ELE8304 : Circuits intégrés à très grande échelle
-------------------------------------------------------------------------------
-- File     riscv_alu_tb.vhd
-- Authors  Titouan Luard <luardtitouan@gmail.com> 
--          Yann Roberge <yann.roberge@polymtl.ca> 
-- Lab      ELE8304-9
-- Date     2021-11-13
-------------------------------------------------------------------------------
-- Brief    Mini RISC-V ALU capable of performing add, shift and bitwise
--          AND, OR & XOR operations
-------------------------------------------------------------------------------
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_alu_tb is
end riscv_alu_tb;

architecture tb of riscv_alu_tb is

  -- Entrées/Sorties du DUT
  signal arith  : std_logic;
  signal sign   : std_logic;
  signal opcode : std_logic_vector(ALUOP_WIDTH-1 downto 0);
  signal shamt  : std_logic_vector(SHAMT_WIDTH-1 downto 0);
  signal src1   : std_logic_vector(XLEN-1 downto 0);
  signal src2   : std_logic_vector(XLEN-1 downto 0);
  signal res    : std_logic_vector(XLEN-1 downto 0);

  -- Procédure pour un vecteur de test
  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);
    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;
      wait for period;
  end procedure test_vector;


  constant PERIOD : time := 10 ns;

  --constant SHAMT_TESTED := std_logic_vector(SHAMT_WIDTH-1 downto 0) := 
begin

  -- Instanciation du DUT
  dut: entity work.riscv_alu
    port map (
      i_arith   => arith,
      i_sign    => sign,
      i_opcode  => opcode,
      i_shamt   => shamt,
      i_src1    => src1,
      i_src2    => src2,
      o_res     => res
    );

  -- Main TB process
  p_main : process
  begin
    -- Tests des cas représentatif
    report "BEGIN SIMULATION";

    -- Shift left
    report "Shift left (logique)";
    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 => (XLEN-1 downto XLEN-2 => "00", others => '1'),
      period => PERIOD
    );

    -- Shift right logique
    report "Shift right (logique)";
    test_vector (
      test_arith  => SHIFT_LOGIC,
      test_sign   => '-',
      test_opcode => ALUOP_SH_RIGHT, 
      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
    );

    -- Shift right arithmétique
    report "Shift right (arithmétique), signe à 1";
    test_vector (
      test_arith  => SHIFT_ARITH,
      test_sign   => '-',
      test_opcode => ALUOP_SH_RIGHT, 
      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 => (others => '1'),
      period => PERIOD
    );

    report "Shift right (arithmétique), signe à 0";
    test_vector (
      test_arith  => SHIFT_ARITH,
      test_sign   => '-',
      test_opcode => ALUOP_SH_RIGHT, 
      test_shamt  => std_logic_vector(to_unsigned(2, shamt'length)),
      test_src1   => (XLEN-1 => '0', others => '1'),
      test_src2   => (others => '-'),

      arith  => arith,
      sign   => sign,
      opcode => opcode, 
      shamt  => shamt,
      src1   => src1,
      src2   => src2,
      res    => res,

      expected_result => (XLEN-1 downto XLEN-3 => "000", others => '1'),
      period => PERIOD
    );

    -- Unsigned addition
    report "Unsigned addition";
    test_vector (
      test_arith  => ARITH_ADD,
      test_sign   => SIGN_UNSIGNED,
      test_opcode => ALUOP_ADD, 
      test_shamt  => (others => '-'),
      test_src1   => std_logic_vector(to_unsigned(12345, XLEN)),
      test_src2   => std_logic_vector(to_unsigned(2345, XLEN)),

      arith  => arith,
      sign   => sign,
      opcode => opcode, 
      shamt  => shamt,
      src1   => src1,
      src2   => src2,
      res    => res,

      expected_result => std_logic_vector(to_unsigned(12345 + 2345, XLEN)),
      period => PERIOD
    );

    -- Signed addition
    report "Signed addition";
    test_vector (
      test_arith  => ARITH_ADD,
      test_sign   => SIGN_SIGNED,
      test_opcode => ALUOP_ADD, 
      test_shamt  => (others => '-'),
      test_src1   => std_logic_vector(to_signed(12345, XLEN)),
      test_src2   => std_logic_vector(to_signed(-2345, XLEN)),

      arith  => arith,
      sign   => sign,
      opcode => opcode, 
      shamt  => shamt,
      src1   => src1,
      src2   => src2,
      res    => res,

      expected_result => std_logic_vector(to_unsigned(12345 - 2345, XLEN)),
      period => PERIOD
    );

    -- Unsigned subtraction
    report "Unsigned addition";
    test_vector (
      test_arith  => ARITH_SUBTRACT,
      test_sign   => SIGN_UNSIGNED,
      test_opcode => ALUOP_ADD, 
      test_shamt  => (others => '-'),
      test_src1   => std_logic_vector(to_unsigned(12345, XLEN)),
      test_src2   => std_logic_vector(to_unsigned(2345, XLEN)),

      arith  => arith,
      sign   => sign,
      opcode => opcode, 
      shamt  => shamt,
      src1   => src1,
      src2   => src2,
      res    => res,

      expected_result => std_logic_vector(to_unsigned(12345 - 2345, XLEN)),
      period => PERIOD
    );

    -- Signed subtraction
    report "Signed subtraction";
    test_vector (
      test_arith  => ARITH_SUBTRACT,
      test_sign   => SIGN_SIGNED,
      test_opcode => ALUOP_ADD, 
      test_shamt  => (others => '-'),
      test_src1   => std_logic_vector(to_signed(12345, XLEN)),
      test_src2   => std_logic_vector(to_signed(-2345, XLEN)),

      arith  => arith,
      sign   => sign,
      opcode => opcode, 
      shamt  => shamt,
      src1   => src1,
      src2   => src2,
      res    => res,

      expected_result => std_logic_vector(to_unsigned(12345 + 2345, XLEN)),
      period => PERIOD
    );


    -- Set-Less-Than (SLT) négatif (1)
    report "Set-Less-Than (SLT) négatif (1)";
    test_vector (
      test_arith  => ARITH_ADD,
      test_sign   => SIGN_SIGNED,
      test_opcode => ALUOP_SLT, 
      test_shamt  => (others => '-'),
      test_src1   => std_logic_vector(to_signed(-12345, XLEN)),
      test_src2   => std_logic_vector(to_signed(2345, XLEN)),

      arith  => arith,
      sign   => sign,
      opcode => opcode,
      shamt  => shamt,
      src1   => src1,
      src2   => src2,
      res    => res,

      expected_result => (0 => '1', others => '0'),
      period => PERIOD
    );

    -- Set-Less-Than (SLT) positif (0)
    report "Set-Less-Than (SLT) positif (0)";
    test_vector (
      test_arith  => ARITH_ADD,
      test_sign   => SIGN_SIGNED,
      test_opcode => ALUOP_SLT, 
      test_shamt  => (others => '-'),
      test_src1   => std_logic_vector(to_signed(+12345, XLEN)),
      test_src2   => std_logic_vector(to_signed(-2345, XLEN)),

      arith  => arith,
      sign   => sign,
      opcode => opcode,
      shamt  => shamt,
      src1   => src1,
      src2   => src2,
      res    => res,

      expected_result => (others => '0'),
      period => PERIOD
    );


    -- Bitwise AND
    report "Bitwise AND";
    test_vector (
      test_arith  => '-',
      test_sign   => '-',
      test_opcode => ALUOP_AND, 
      test_shamt  => (others => '-'),
      test_src1   => (XLEN-1 downto XLEN-4 => "0011", others => '0'),
      test_src2   => (XLEN-1 downto XLEN-4 => "0101", others => '0'),

      arith  => arith,
      sign   => sign,
      opcode => opcode,
      shamt  => shamt,
      src1   => src1,
      src2   => src2,
      res    => res,

      expected_result => (XLEN-1 downto XLEN-4 => "0001", others => '0'),
      period => PERIOD
    );

    -- Bitwise XOR
    report "Bitwise XOR";
    test_vector (
      test_arith  => '-',
      test_sign   => '-',
      test_opcode => ALUOP_XOR, 
      test_shamt  => (others => '-'),
      test_src1   => (XLEN-1 downto XLEN-4 => "0011", others => '0'),
      test_src2   => (XLEN-1 downto XLEN-4 => "0101", others => '0'),

      arith  => arith,
      sign   => sign,
      opcode => opcode,
      shamt  => shamt,
      src1   => src1,
      src2   => src2,
      res    => res,

      expected_result => (XLEN-1 downto XLEN-4 => "0110", others => '0'),
      period => PERIOD
    );

    -- Bitwise OR
    report "Bitwise OR";
    test_vector (
      test_arith  => '-',
      test_sign   => '-',
      test_opcode => ALUOP_OR, 
      test_shamt  => (others => '-'),
      test_src1   => (XLEN-1 downto XLEN-4 => "0011", others => '0'),
      test_src2   => (XLEN-1 downto XLEN-4 => "0101", others => '0'),

      arith  => arith,
      sign   => sign,
      opcode => opcode,
      shamt  => shamt,
      src1   => src1,
      src2   => src2,
      res    => res,

      expected_result => (XLEN-1 downto XLEN-4 => "0111", others => '0'),
      period => PERIOD
    );

    report "SIMULATION DONE";
    wait;
  end process p_main;

end architecture tb;