samedi 20 février 2016

How to/Can you use if statement to an Assert Report Severity Statement in VHDL Testbench?

Okay. So to say why I'm asking this question. We have been told to develop the system that can work out the system that can resolve the formula:

O <= (A*3 + B*C)/D + C +5

There is a two cycle propagation delay in the system as it currently stands. However as it gets more complicated as we develop it, so I'm using a constant propagation_delay to represent how the delay can change.

There is a much simpler way to make a self checking test bench for this system, have two processes, one that inputs the test vectors, and one that waits for the delay, and then starts checking. However we were told that there was a more tricky way of doing it which involved only one process. I have decided to attempt this way as I enjoy VHDL a whole deal so I want to explore it as much I can!

Another constraint from the lecturer was that there had to be change every clock cycle.

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;

ENTITY algorith_TB IS
END algorith_TB;

ARCHITECTURE behavior OF algorith_TB IS 

    -- Component Declaration for the Unit Under Test (UUT)

    COMPONENT algorithm
    PORT(
         A : IN  std_logic_vector(15 downto 0);
         B : IN  std_logic_vector(15 downto 0);
         C : IN  std_logic_vector(15 downto 0);
         D : IN  std_logic_vector(15 downto 0);
         O : OUT  std_logic_vector(31 downto 0);
         clk : IN  std_logic;
         rst : IN  std_logic
        );
    END COMPONENT;


   --Inputs
   signal A : std_logic_vector(15 downto 0); --:= (others => '0');
   signal B : std_logic_vector(15 downto 0); --:= (others => '0');
   signal C : std_logic_vector(15 downto 0); --:= (others => '0');
   signal D : std_logic_vector(15 downto 0); --:= (others => '0');
   signal clk : std_logic; --:= '0';
   signal rst : std_logic; --:= '0';

    --Outputs
   signal O : std_logic_vector(31 downto 0);
    -- Delay Constants Definition
   constant propagation_delay : integer := 2;
    constant num_vectors : integer := 5;
   -- Clock period definitions
   constant clk_period : time := 120 ns;

    type test_vector is record
        A : STD_LOGIC_VECTOR(15 downto 0);
        B : STD_LOGIC_VECTOR(15 downto 0);
        C : STD_LOGIC_VECTOR(15 downto 0);
        D : STD_LOGIC_VECTOR(15 downto 0);
        O :  STD_LOGIC_VECTOR(31 downto 0);
    end record;

    type test_vector_array is array
        (natural range<>) of test_vector;
    constant test_vectors : test_vector_array := (
    --        A                B                    C                  D               O
       (x"0001",    x"0002",      x"0003",      x"0004",     x"0000000A") ,
        (x"AAAA",    x"0202",      x"4131",      x"4123",     x"00004340") ,
      (x"0001",    x"0003",      x"0005",      x"0007",     x"0000000C") ,
        (x"AAAA",    x"0202",      x"4131",      x"4123",     x"00004340") ,
        (x"0001",    x"0003",      x"0005",      x"0007",     x"0000000C") );

BEGIN

    -- Instantiate the Unit Under Test (UUT)
   uut: algorithm PORT MAP (
          A => A,
          B => B,
          C => C,
          D => D,
          O => O,
          clk => clk,
          rst => rst
        );

   -- Clock process definitions
   clk_process :process
   begin
        clk <= '0';
        wait for clk_period/2;
        clk <= '1';
        wait for clk_period/2;
   end process;


   -- Stimulus process
   stim_proc: process
   begin        
      -- hold reset state for 100 ns.
      wait for 500 ns;  
      rst <= '1'; -- initial reset
        wait for clk_period;
        rst <= '0';
      wait for clk_period*10; -- warm up period
        wait until falling_edge(clk); -- resynchronise with falling edge
        for i in 0 to 4 loop -- cycle through test vectors
            if (i < num_vectors) then
                A <= test_vectors(i).A;
                B <= test_vectors(i).B;
                C <= test_vectors(i).C;
                D <= test_vectors(i).D;
            wait for clk_period;
            end if; -- end input loop if
            if (i > propagation_delay) then -- pause for 2
                assert (O = test_vectors(i-propagation_delay).O)    
                report "Test vector " & integer'image(i-propagation_delay) &
                                    " failed for input A = " & integer'image(to_integer(unsigned(a))) &
                                    "and b = " & integer'image(to_integer(unsigned(b))) &
                                    " and C = " & integer'image(to_integer(unsigned(c))) &
                                    "and D = " & integer'image(to_integer(unsigned(d)))                             
                severity error;
              end if; -- end assert check if
      end loop; -- end for loop
      wait;
   end process;

END;

This works, in terms of simulation output. There is a two cycle delay between inputs and outputs.

However I am having a problem with the printing to console as it allows that i = 2,3,4 are all correct. But says that i = 0 , 1 are incorrect. Which are the two input vectors where i < propogation_delay. I understand I'm facing a problem here but just can't figure out how to fix it.

One way I've thought of fixing it but I get a syntax error I can't fix is:

   -- Stimulus process
   stim_proc: process
   begin        
      -- hold reset state for 100 ns.
      wait for 500 ns;  
      rst <= '1'; -- initial reset
        wait for clk_period;
        rst <= '0';
      wait for clk_period*10; -- warm up period
        wait until falling_edge(clk); -- resynchronise with falling edge
        for i in 0 to 4 loop -- cycle through test vectors
            if (i < num_vectors) then
                A <= test_vectors(i).A;
                B <= test_vectors(i).B;
                C <= test_vectors(i).C;
                D <= test_vectors(i).D;
            wait for clk_period;
            end if; -- end input loop if
            if (i > propagation_delay) then -- pause for 2
                assert (O = test_vectors(i-propagation_delay).O)    
            end if; -- end assert check if
         if (i - propagation_delay < 0) then            
                report "Test vector " & integer'image(i) &
                                    " failed for input A = " & integer'image(to_integer(unsigned(a))) &
                                    "and b = " & integer'image(to_integer(unsigned(b))) &
                                    " and C = " & integer'image(to_integer(unsigned(c))) &
                                    "and D = " & integer'image(to_integer(unsigned(d)))                             
                severity error;
                else    
                report "Test vector " & integer'image(i-propagation_delay) &
                                    " failed for input A = " & integer'image(to_integer(unsigned(a))) &
                                    "and b = " & integer'image(to_integer(unsigned(b))) &
                                    " and C = " & integer'image(to_integer(unsigned(c))) &
                                    "and D = " & integer'image(to_integer(unsigned(d)))                             
                severity error;
              end if; -- end report if
      end loop; -- end for loop
      wait;
   end process;

END; 

But I get a syntax error on the line

end if; -- end assert check if

I am trying to say if it is smaller then prop delay then check what is now, otherwise check i-prop.

Any ideas on how to work with this syntax or can you not split up the assert/report/severity?

Thanks for taking time to read guys!

Aucun commentaire:

Enregistrer un commentaire