------------------------------------------------------------
-- Copyright: 2011 George Mason University, Virginia USA
--            http://www.iis.ee.ethz.ch/~sha3
------------------------------------------------------------
-------------------------------------------------------------------------------
-- Title      : Testbench for Groestl
-- Project    : Shabziger
-------------------------------------------------------------------------------
-- File       : gmu_groestl_tb.vhd
-- Author     : Frank K. Guerkaynak  
-- Company    : Integrated Systems Laboratory, ETH Zurich
-- Created    : 2011-08-22
-- Last update: 2011-08-25
-- Platform   : ModelSim (simulation), Synopsys (synthesis)
-- Standard   : VHDL'87
-------------------------------------------------------------------------------
-- Description: Standard testbench
-------------------------------------------------------------------------------
-- Copyright (c) 2011 Integrated Systems Laboratory, ETH Zurich
-------------------------------------------------------------------------------
-- Revisions  :
-- Date        Version  Author  Description
-- 2011-08-22  1.0      kgf	Created
-------------------------------------------------------------------------------



library ieee;
use ieee.std_logic_1164.all;
use work.simulstuff.all;
use std.textio.all;

-------------------------------------------------------------------------------

entity gmu_groestl_tb is

end gmu_groestl_tb;

-------------------------------------------------------------------------------

architecture test of gmu_groestl_tb is

  component gmu_groestl_top
    port (
      ClkxCI         : in  std_logic;
      RstxRBI        : in  std_logic;
      ScanInxTI      : in  std_logic;
      ScanOutxTO     : out std_logic;
      ScanEnxTI      : in  std_logic;
      InEnxSI        : in  std_logic;
      FinBlockxSI    : in  std_logic;
      DataxDI        : in  std_logic_vector(511 downto 0);
      OutEnxSO       : out std_logic;
      PenUltCyclexSO : out std_logic;
      DataxDO        : out std_logic_vector(255 downto 0));
  end component;

  -- component ports
  signal ClkxC         : std_logic;
  signal RstxRB        : std_logic;
  signal FinBlockxS    : std_logic;
  signal InWrEnxS      : std_logic;
  signal OutWrEnxS     : std_logic;
  signal PenUltCyclexS : std_logic;
  signal DataInxD      : std_logic_vector(511 downto 0);
  signal DigestxD      : std_logic_vector(255 downto 0);
  signal ExpRespxD     : std_logic_vector(255 downto 0);
  -- clock
  signal Clk : std_logic := '1';
  signal ScanInxT : std_logic := '0';   -- No scan for this version
  signal ScanEnxT : std_logic := '0';   -- No scan for this version
  signal ScanOutxT: std_logic;



   type stimulirecordtype is record
      DataInxD  : std_logic_vector(511 downto 0);
      FinBlockxS: std_logic;
      DigestxD  : std_logic_vector(255 downto 0);
   end record;

   signal STIMULI: stimulirecordtype;    -- record of stimuli
   -- declarations of signals that do help coordinate testbench processes
   signal SIMPROGRESS : ResolveTrafficLight trafficlight := orange;
   -- timing of clock and simulation events
   constant clkphasehigh: time:= 10 ns;
   constant clkphaselow: time:= 10 ns;
   constant responseacquisitiontime: time:= 15 ns;
   constant stimulusapplicationtime: time:= 5 ns;
   constant resetactivetime:         time:= 5 ns;

  
   -- declaration of stimuli, expected responses, and simulation report files
   file stimulifile  : text;
   constant stimulifilename : string := "../simvectors/testvectors.txt";


  ---- declaration of non-universal i.e. MUT-dependent subprograms
  
   -- purpose: get one record worth of stimuli from file.
   impure function GetStimuliRecord
      (file stimulifile : text)
      return stimulirecordtype
   is
      variable read_ok : boolean;
      variable in_line, in_line_tmp : line;
      -- stimuli to default to unknown in case no value is obtained from file
      variable stimulirecord : stimulirecordtype :=
            ( DataInxD     => (others => '0'),
              FinBlockxS   => '0',
              DigestxD     => (others => '-')
            );
   begin      
      -- read a line from the stimuli file
      -- skipping any empty and comment lines encountered
      loop
         readline(stimulifile,in_line);
         -- copy line read to enable meaningful error messages later
         in_line_tmp := new string'(in_line(in_line'low to in_line'high));
         if in_line_tmp'length >= 1 then
            exit when in_line_tmp(1) /= '%';
         end if;
         deallocate(in_line_tmp);
      end loop;
      -- extract all values of a record of stimuli
         GetFileEntry
            (stimulirecord.DataInxD,in_line,in_line_tmp,stimulifilename);
         GetFileEntry
            (stimulirecord.FinBlockxS,in_line,in_line_tmp,stimulifilename);
         GetFileEntry
            (stimulirecord.DigestxD,in_line,in_line_tmp,stimulifilename);
      -- deallocate line copy now that all entries have been read
      deallocate(in_line_tmp);
      return stimulirecord;
   end GetStimuliRecord;

   -- purpose: compose a failure message line and write it to the report file.
   procedure PutSimulationReportFailure
      (ActualDigestxD   : in std_logic_vector(255 downto 0);
       ExpectedDigestxD : in std_logic_vector(255 downto 0);
       respmatch : in respmatchtype)
   is
      variable out_line : line;      
   begin
      report "Error Encountered "   severity warning;
      write(out_line,string'("ERROR at "));
      write(out_line,now);
      writeline(output,out_line);         
      -- add expected responses
      write(out_line,string'("   Received = "));
      vector2hex(out_line,ActualDigestxD);
      writeline(output,out_line);         
      write(out_line,string'("   Expected = "));
      vector2hex(out_line,ExpectedDigestxD);
      writeline(output,out_line);
   end PutSimulationReportFailure;

  
begin  -- test

  -- component instantiation
  DUT: gmu_groestl_top
    port map (
      ClkxCI         => ClkxC,
      RstxRBI        => RstxRB,
      ScanEnxTI      => ScanEnxT,
      ScanInxTI      => ScanInxT,
      ScanOutxTO     => ScanOutxT,
      InEnxSI        => InWrEnxS,
      FinBlockxSI    => FinBlockxS,
      DataxDI        => DataInxD,
      OutEnxSO       => OutWrEnxS,
      PenUltCyclexSO => PenUltCyclexS,
      DataxDO        => DigestxD);

  -- clock generation
   Tb_clkgen : process
   begin
      case SIMPROGRESS is
         -- if orange then wait for start sign
         when orange => wait until SIMPROGRESS=green;
         -- if green then proceed with yet another clock period
         when green => null;
         when green2 => null;
         -- if yellow (neither red nor any other color should occur here) 
         -- then terminate
         when others => SIMPROGRESS <= red; wait; -- forever
      end case;
      CLKxC <= '1';
      wait for clkphasehigh;
      CLKxC <= '0';
      wait for clkphaselow;
   end process Tb_clkgen;



   -- launch and terminate simulation run
   ----------------------------------------------------------------------------
   Tb_launchterm : process
      variable status: file_open_status;
   begin
      -- open files for stimuli, config, and simulation report
      file_open(status,stimulifile,stimulifilename,read_mode);
      assert status=open_ok
         report FileOpenMessage(stimulifilename,status) severity failure;      
      -- give start sign to other processes
      SIMPROGRESS <= green;
      -- suspend until clock generator shuts down
      wait until SIMPROGRESS=red;
      report "Simulation run completed, all stimuli processed."
         severity note;
      -- close files
      file_close(stimulifile);

      wait; -- forever to starve event queue
   end process Tb_launchterm;




   -- obtain stimulus and apply it to MUT
   ----------------------------------------------------------------------------

   Tb_stimappli : process
      -- variables for accounting of mismatching responses
      variable respmatch : respmatchtype;
      variable respaccount : respaccounttype := (0,0,0,0,0);
      variable exprespavail : boolean := true;

   begin
      -- wait for start sign
      wait until SIMPROGRESS=green;

      -- default values
        RstxRB      <= '0';               -- Resets Active
        FinBlockxS  <= '0';             
        InWrEnxS    <= '0';               -- No enable yet
        DataInxD    <= ( others => '0');  -- all zeroes per default
');  -- initially no expectation
        wait for resetactivetime;       -- Wait until reset is over
        RstxRB <= '1';                  -- take reset back
-------------------------------------------------------------------------------
-- Initial Vector
-------------------------------------------------------------------------------

      wait until CLKxC'event and CLKxC='1';
        STIMULI <= GetStimuliRecord(stimulifile);

        wait for stimulusapplicationtime;  -- wait until the right time
        InWrEnxS   <= '1';                 
        DataInxD   <= STIMULI.DataInxD;
        FinBlockxS <= STIMULI.FinBlockxS;  -- delay no more needed.. 
        wait until ClkxC'event and ClkxC='1';  -- make sure data is clocked in
-------------------------------------------------------------------------------
-- Start Loop
-------------------------------------------------------------------------------
     -- process until we run out of stimuli
      appli_loop : while not (endfile(stimulifile)) loop
        wait for stimulusapplicationtime;
        InWrEnxS   <= '0';                 -- no longer needed
        FinBlockxS <= '0';                 -- should be sampled
        ExpRespxD  <= STIMULI.DigestxD;    -- we need a slight delay here 

     -- wait the cycles until the PenUltCyclexS arrives
     -- This is the penultimate cycle. Everything will be clear after this
        done_loop : while PenUltCyclexS = '0' loop
          wait until ClkxC'event and ClkxC='1';
          wait for responseacquisitiontime;
        end loop done_loop;
        
     -- now we have donexS
        STIMULI <= GetStimuliRecord(stimulifile);  -- read a new value
        
        wait until ClkxC'event and ClkxC='1';
        wait for stimulusapplicationtime;
        InWrEnxS <= '1';                -- new data is here
        DataInxD <= STIMULI.DataInxD;   -- apply new data;
        FinBlockxS <= STIMULI.FinBlockxS;  -- apply new FinBlockxS
        -- note that the expected response and FinBlockxS will be updated in the
        -- next cycle. The last values are still used in this cycle

        wait until CLKxC'event and CLKxC='1';
        -- loop until all stimuli have been processed
      end loop appli_loop;
-------------------------------------------------------------------------------
-- Final Vector We applied the last vector, let us wait for the result 
-------------------------------------------------------------------------------
-- read the last one as well
      wait for stimulusapplicationtime;
      InWrEnxS <= '0';                   -- no longer needed
      FinBlockxS <= '0';                 -- should be sampled
      ExpRespxD  <= STIMULI.DigestxD;    -- we need a slight delay here 

     -- wait the cycles until the PenUltCyclexS arrives
     -- This is the penultimate cycle. Everything will be clear after this
        last_loop : while PenUltCyclexS = '0' loop
          wait until ClkxC'event and ClkxC='1';
          wait for responseacquisitiontime;
        end loop last_loop;

       wait until CLKxC'event and CLKxC='1';

-- now we are done 
-------------------------------------------------------------------------------
      
     SIMPROGRESS <= red;
     wait;
   end process Tb_stimappli;


-------------------------------------------------------------------------------
-- Check for output responses only
-------------------------------------------------------------------------------
  
   tb_respcheck: process
      -- variables for accounting of mismatching responses
      variable respmatch : respmatchtype;
      variable respaccount : respaccounttype := (0,0,0,0,0);
      variable out_line : line;      
      
   begin  -- process tb_respcheck
    -- wait for start sign
    wait until SIMPROGRESS=green;
    
    while SIMPROGRESS = green loop 
      wait until CLKxC'event and CLKxC='1';
      wait for responseacquisitiontime;

      if OutWrEnxS = '1' then           -- we have a comparison value
             CheckResponse(DigestxD,ExpRespxD,respmatch,respaccount);
             if respmatch /= mok then   -- is there a mismatch ?? 
                   PutSimulationReportFailure(DigestxD,ExpRespxD,respmatch);
             else
                   write(out_line,string'("  -> Matching result at "));
                   write(out_line,now);
                   writeline(output,out_line);         
             end if;
       end if;
    end loop;                           -- sim green
    PutSimulationReportSummary(respaccount);


    wait;                               -- kill the queue
     
   end process tb_respcheck;



  
end test;


Generated on Tue Nov 22 15:16:34 CET 2011
Home