- Muchas notas - Fran Acién

20201016 - VHDL 8 - Simulaciones

WITHOUT DEFINING THE COMPONENT

------------------------------------------------------------------------------/
-- Description:       Simple test bench for SPI Master module
------------------------------------------------------------------------------/
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity SPI_rx_tb is
end entity SPI_rx_tb;

architecture TB of SPI_rx_tb is

  
  signal r_Rst_L    : std_logic := '0';
  signal r_Clk      : std_logic := '0';
  signal r_SPI_MISO : std_logic := '0';
  signal r_SPI_nCS  : std_logic := '1';
  
  -- Master Specific
  signal r_Master_CS_n     : std_logic := '1';
  signal r_Master_RX_DV    : std_logic := '0';
  signal r_Master_RX  : std_logic_vector(13 downto 0) := (others => '0');
  
begin  -- architecture TB

   -- Clock Generators:
  r_Clk <= not r_Clk after 10 ns;  -- 50 MHz -> frequency of 100 MHz

  -- Instantiate Master
  UUT : entity work.SPI_rx
    port map (
      -- Control/Data Signals,
      i_Rst_L    => r_Rst_L,            -- FPGA Reset
      i_Clk      => r_Clk,              -- FPGA Clock
      
      -- RX (MISO) Signals
      o_RX_DV    => r_Master_RX_DV,            -- Data Valid pulse
      o_RX  => r_Master_RX,          -- Byte received on MISO
      -- SPI Interface
      i_SPI_MISO => r_SPI_MISO,
      i_SPI_nCS => r_SPI_nCS
      );

  Testing : process is
  begin
  
    wait for 100 ns;
    r_Rst_L <= '0';
    wait for 100 ns;
    r_Rst_L <= '1';
    
    r_SPI_nCS <= '0';
    wait for 100 ns;
    
    r_SPI_nCS <= '1';
    wait for 140 ns;
    
    
    wait for 5000 ns;
    r_Rst_L <= '0';
    assert false report "Test Complete" severity failure;
  end process Testing;

end architecture TB;

mult_2x2_tb

La parte del report es para comprobar que funciona correctamente las operaciones. Sino, imprime el error por pantalla.


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity mult_2x2_tb is

end mult_2x2_tb;

architecture Behavioral of mult_2x2_tb is
    component mult_2x2 port(
        a : in std_logic_vector (1 downto 0);
        b: in std_logic_vector (1 downto 0);
        y: out std_logic_vector (3 downto 0)
    );
    end component;
    
    -- input signals
    signal a, b: std_logic_vector (1 downto 0);
    
    --output signal
    signal y: std_logic_vector (3 downto 0);
    
    --Time interval between two test vectors
    constant DELTA : time := 10 ns;
begin
    DUT: mult_2x2 port map(
        a => a,
        b => b,
        y => y
    );
    process
        procedure send_vectors (constant in1: in natural;
                                constant in2: in natural) is
                                variable out: std_logic_vector(3 downto 0);
         begin
            --Assign values
            a <= std_logic_vector(to_unsigned(in1, a'length));
            b <= std_logic_vector(to_unsigned(in2, b'length));
            --Wait a time interval to assign the new vectors
            wait for DELTA;
            --Calculate the correct output
            mult := std_logic_vector(to_unsigned(in1 * in2, y'length));
            --Check actual output against expected result
            assert (y = mult)
            report "Wrong result: " &
                "a = " & integer'image(in1) & "; " &
                "b = " & integer'image(in2) & "; " &
                "y = " & integer'image(to_integer(unsigned(y))) & "; " &
                "y_expected = " & integer'image(to_integer(unsigned(mult))) & ";"
            severity error;
            report "TEST OK";
        end procedure send_vectors;
    begin
       send_vectors(0,0); -- 0
       send_vectors(0,1); -- 0
       send_vectors(1,0); -- 0
       send_vectors(1,1); -- 1
       send_vectors(0,2); -- 0
       send_vectors(2,0); -- 0
       send_vectors(1,2); -- 2
       send_vectors(2,1); -- 2
       send_vectors(2,2); -- 4
       send_vectors(3,0); -- 0
       send_vectors(0,3); -- 0
       send_vectors(3,1); -- 3
       send_vectors(1,3); -- 3
       send_vectors(3,2); -- 6
       send_vectors(2,3); -- 6
       send_vectors(3,3); -- 9
    end process;

end Behavioral;

my_count_tb

Un contador con una máquina de estados

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;

entity my_count_tb is
--  Port ( );
end my_count_tb;

architecture Behavioral of my_count_tb is
    component my_count port(
        rst : in STD_LOGIC;
        clk : in STD_LOGIC;
        en : in STD_LOGIC;
        count : out UNSIGNED (2 downto 0)
    );
    end component;

    -- input signals
    signal rst, clk, en: STD_LOGIC;

    --output signal
    signal count: UNSIGNED (2 downto 0);

    --Time interval between two test vectors
    constant clk_period : time := 1 ns;
begin
    DUT: my_count port map(
        rst => rst,
        clk => clk,
        en => en,
        count => count
    );

    process

    begin
        en <= '1';
        wait for clk_period/2;
        rst <= '0';
        wait for clk_period/2;
        rst <= '1';
        wait for clk_period/2;
        rst <= '0';
        wait for clk_period/2;
    end process;
end Behavioral;

mult_accum_tb

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.all;

entity mult_accum_tb is
--  Port ( );
end mult_accum_tb;

architecture Behavioral of mult_accum_tb is

    component mult_accum port(
      clk            : in  std_logic;
      acc_en         : in  std_logic := '0';
      a              : in  signed;
      b              : in  signed;
      c              : in  signed;
      q              : out signed 
    );
    end component;
    
    constant DL : natural := 4;   -- Data lenght
    
    signal clk, acc_en : std_logic := '1';
    signal a, b, c, q: SIGNED(0 to DL-1) := (others => '0');
    
    constant clk_period : time := 83.3 ns;  -- 12 MHz
    CONSTANT delta : TIME := 500 ns;
begin
    DUT: mult_accum port map(
        clk => clk,
        acc_en => acc_en,
        a => a,
        b => b,
        c => c,
        q => q
    );
    
    clk <= NOT clk AFTER clk_period/2;
    
    process
    begin
        acc_en <= '1';       -- Turn on the component
        
        wait for clk_period;
        
        -- TEST 1
        a <= "0100"; -- 4
        b <= "0100"; -- 4
        c <= "0000";
        
        -- It takes 4 cycles to see the output
        
        wait for clk_period;
        
        -- TEST 2
        a <= "0100"; --4
        b <= "0010"; --2
        c <= "0000";
        
        wait for clk_period;
        
        -- TEST 3
        a <= "0100"; --4
        b <= "0011"; --3
        c <= "0000";
        
        wait for clk_period;
        
        -- TEST 4
        a <= "0100"; --4
        b <= "0100"; --4
        c <= "0000";
        
        
        wait for clk_period;
        
        -- TEST 5
        a <= "0100"; --4
        b <= "0101"; --5
        c <= "0000";
        
        -- Expected result -> 4 * 4 = 16 = "0001 0000"
        -- After truncation 16 / 2^(a'length + b'length - q'length-1) = 16 / 8 = 2 = "0010"
        
        assert q = "0010" report "1. Unexpected result of operation" severity error;
        
        
        wait for clk_period;
        
        -- TEST 6
        a <= "1001"; -- -7
        b <= "0111"; -- 7
        c <= "0000";
        
        -- Test if the acumulator is working
        -- Expected result -> 16 + (4*2) = 24 = "0001 1000"
        -- After truncation 24 / 8 = 3 = "0011"
        
        assert q = "0011" report "2. Unexpected result of operation" severity error;
        
        
        wait for clk_period;
        
        -- TEST 7
        a <= "1001"; -- -7
        b <= "0111"; -- 7
        c <= "0000";
        
        -- Expected result -> 24 + (4*3) = 36 = "0010 0100"
        -- After truncation 36 / 8 = 4 = "0100"
        
        assert q = "0100" report "3. Unexpected result of operation" severity error;
        
        wait for clk_period;
        
        -- Set to 0
        a <= "0000"; -- 0
        b <= "0000"; -- 0
        c <= "0000";
        
        -- Test if the acumulator is working
        -- Expected result -> 36 + (4*4) = 52 = "0011 0100"
        -- After truncation 52 / 8 = 6 = "0110"
        
        assert q = "0110" report "4. Unexpected result of operation" severity error;
        
        wait for clk_period;
        
        -- Test if the acumulator is working
        -- Expected result -> 52 + (4*5) = 72 = "0100 1000"
        -- After truncation 72 / 8 = 9 = "1001"
        
        assert q = "1001" report "5. Unexpected result of operation" severity error;
        
        wait for clk_period;
        
        -- Test if the acumulator is working
        -- Expected result -> 72 + (-7*7) = 23 = "0001 0111"
        -- After truncation 23 / 8 = 2 = "0010"
        
        assert q = "0010" report "6. Unexpected result of operation" severity error;
        
        -- Test if the acumulator is working
        -- Expected result -> 23 + (-7*7) = -26 = "1110 0110"
        -- After truncation -26 / 8 = -2 = "1100"
        
        assert q = "1100" report "7. Unexpected result of operation" severity error;
        
        
    end process;

end Behavioral;