-------------------------------------------------------------------------------
-- Project  ELE8304 : Circuits intégrés à très grande échelle
-------------------------------------------------------------------------------
-- File     shifter_tb.vhd
-- Authors  Titouan Luard <luardtitouan@gmail.com> 
--          Yann Roberge <yann.roberge@polymtl.ca> 
-- Lab      GRM - Polytechnique Montreal
-- Date     2021-10-29
-------------------------------------------------------------------------------
-- Brief    Single-bit half-adder with carry out
-------------------------------------------------------------------------------
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 shifter_tb is
end shifter_tb;

architecture tb of shifter_tb is

  signal src1    : std_logic_vector(3 downto 0);
  signal arith  : std_logic;
  signal opcode : std_logic_vector(2 downto 0);
  signal shamt  : std_logic_vector(6 downto 0);
  signal output : std_logic_vector(3 downto 0);

  constant PERIOD   : time := 10 ns;

begin

  -- DUT
  dut: entity work.shifter
    port map (
      i_src1  => src1,
      i_opcode => opcode,
      i_arith => arith,
      i_shamt => shamt,
      o_sh => output);
      
  -- Main TB process
  p_main : process
  begin
    report "BEGIN SIMULATION";
    report "SHIFT";
    -- decalage logique à droite
    src1 <= "0100";
    opcode <= "000";
    shamt<= '1';
    wait for PERIOD;

    assert out = "0010"
      report "Shift droite logique error" severity error;
    wait for PERIOD;
    -- decalage arithmetique à droite
    src1 <= "1010";
    opcode <= "001";
    arith <= '1'
    shamt<= '1'
    
    wait for PERIOD;

    assert out = "0101"
      report "Shift error" severity error;
    wait for PERIOD;
    -- decalage arithmetique à droite
    src1 <= "1010";
    opcode <= "0110011";
    funct3 <= "101"
    arith <= '1'
    shamt<= '1'
    
    wait for PERIOD;

    assert out = "1101"
      report "Shift error" severity error;
    wait for PERIOD;

     report "SHIFT IMMEDIATE";
    -- decalage logique à gauche
    src1 <= "0100";
    opcode <= "0010011";
    funct3 <= "001"
    shamt<= '1'
    wait for PERIOD;

    assert out = "0101"
      report "Shift error" severity error;
    wait for PERIOD;
    -- decalage logique à droite
    src1 <="1010";
    opcode <= "0010011";
    funct3 <= "101"
    arith <= '0'
    shamt<= '1'
    
    wait for PERIOD;

    assert out = "0101"
      report "Shift error" severity error;
    wait for PERIOD;
    -- decalage arithmetique à droite
    src1 <= "1010";
    opcode <= "0010011";
    funct3 <= "101"
    arith <= '1'
    shamt<= '1'
    
    wait for PERIOD;

    assert out = "1101"
      report "Shift error" severity error;
    wait for PERIOD;

  end process p_main;

end architecture tb;