------------------------------------------------------------
-- Copyright: 2011 Integrated Sytems Laboratory, ETH Zurich
-- http://www.iis.ee.ethz.ch/~sha3
------------------------------------------------------------
-------------------------------------------------------------------------------
-- Title : Testbench for design "shabziger"
-- Project : Shabziger
-------------------------------------------------------------------------------
-- File : shabziger_tb.vhd
-- Author : Frank K. Guerkaynak
-- Company : Integrated Systems Laboratory, ETH Zurich
-- Created : 2011-08-29
-- Last update: 2011-09-09
-- Platform : ModelSim (simulation), Synopsys (synthesis)
-- Standard : VHDL'87
-------------------------------------------------------------------------------
-- Description: Simpleset test
-------------------------------------------------------------------------------
-- Copyright (c) 2011 Integrated Systems Laboratory, ETH Zurich
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2011-08-29 1.0 kgf Created
-- 2011-09-01 1.1 kgf Now reads integers from the config file
-- Also initializes the LFSR from the testbench
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- To DO
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.shabzigerpkg.all;
use work.simulstuff.all;
use std.textio.all;
use ieee.numeric_std.all;
-------------------------------------------------------------------------------
entity shabziger_tb is
end shabziger_tb;
-------------------------------------------------------------------------------
architecture test of shabziger_tb is
component shabziger
port (
AlgSelxSI : in std_logic_vector(3 downto 0);
OutSelxSI : in std_logic_vector(3 downto 0);
DataOutxDO : out std_logic_vector(15 downto 0);
FinBlockxSI : in std_logic;
OutWrEnxSO : out std_logic;
InWrEnxSO : out std_logic;
PenUltCyclexSO : out std_logic;
MemWrEnxSBI : in std_logic;
PadOutEnxSI : in std_logic;
PadDrive1xSI : in std_logic;
PadDrive2xSI : in std_logic;
PadSlewxSI : in std_logic;
FuncScanEnxTI : in std_logic;
FuncScanInxTI : in std_logic;
CoreScanEnxTI : in std_logic;
CoreScanInxTI : in std_logic;
ClkxCI : in std_logic;
ClkDxCI : in std_logic;
RstxRBI : in std_logic);
end component;
-- The configuration file
file configfile : text;
constant configfilename : string := "../simvectors/config.txt";
-- These signals willbe overwritten by the values read from the
-- configfile .
-- how many input blocks will be processed in the simulation
signal NUMBLOCKS : integer := 256;
-- 1/PROBABILITY will generate a FinBlockxSI signal
signal PROBABILITY : integer := 10;
-- 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;
-- component ports
signal AlgSelxS : std_logic_vector(3 downto 0);
signal OutSelxS : std_logic_vector(3 downto 0);
signal DataOutxD : std_logic_vector(15 downto 0);
signal FinBlockxS : std_logic;
signal OutWrEnxS : std_logic;
signal InWrEnxS : std_logic;
signal PenUltCyclexS : std_logic;
signal MemWrEnxSB : std_logic;
signal PadOutEnxS : std_logic;
signal PadDrive1xS : std_logic;
signal PadDrive2xS : std_logic;
signal PadSlewxS : std_logic;
signal FuncScanEnxT : std_logic;
signal FuncScanInxT : std_logic;
signal FuncScanOutxT : std_logic;
signal CoreScanEnxT : std_logic;
signal CoreScanInxT : std_logic;
signal RstxRB : std_logic;
-- clock
signal ClkxC : std_logic := '1';
signal ClkDxC : std_logic := '0'; -- wll be set to zero
begin -- test
-- component instantiation
DUT : shabziger
port map (
AlgSelxSI => AlgSelxS,
OutSelxSI => OutSelxS,
DataOutxDO => DataOutxD,
FinBlockxSI => FinBlockxS,
OutWrEnxSO => OutWrEnxS,
InWrEnxSO => InWrEnxS,
PenUltCyclexSO => PenUltCyclexS,
MemWrEnxSBI => MemWrEnxSB,
PadOutEnxSI => PadOutEnxS,
PadDrive1xSI => PadDrive1xS,
PadDrive2xSI => PadDrive2xS,
PadSlewxSI => PadSlewxS,
FuncScanEnxTI => FuncScanEnxT,
FuncScanInxTI => FuncScanInxT,
CoreScanEnxTI => CoreScanEnxT,
CoreScanInxTI => CoreScanInxT,
ClkxCI => ClkxC,
ClkDxCI => ClkDxC,
RstxRBI => RstxRB);
-- 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;
-- waveform generation
WaveGen_Proc : process
variable rand : integer; -- random variable
variable state1, state2 : integer := 77; -- stolen from luethi
variable in_line, in_line_tmp : line;
variable status : file_open_status;
variable f_alg : std_logic_vector(3 downto 0) := "0000";
variable f_blocks : integer;
variable f_prob : integer;
variable f_lfsrinit : std_logic_vector(LFSRLEN downto 0) := (others => '1');
begin
-------------------------------------------------------------------------------
-- Configure the system
-------------------------------------------------------------------------------
-- open files for config
file_open(status,configfile,configfilename,read_mode);
assert status=open_ok
report FileOpenMessage(configfilename,status) severity failure;
loop
readline(configfile,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
-- these are std_logic_vector because I was lazy to add integer
-- versions in the simulstuff
GetFileEntry(f_alg,in_line,in_line_tmp,configfilename);
GetFileEntryInt(f_blocks,in_line,in_line_tmp,configfilename);
GetFileEntryInt(f_prob,in_line,in_line_tmp,configfilename);
GetFileEntry(f_lfsrinit,in_line,in_line_tmp,configfilename);
-- deallocate line copy now that all entries have been read
deallocate(in_line_tmp);
-- convert the variables to the actual signals used
AlgSelxS <= f_alg;
-- NUMBLOCKS <= to_integer(unsigned(f_blocks));
-- PROBABILITY <= to_integer(unsigned(f_prob));
NUMBLOCKS <= f_blocks;
PROBABILITY <= f_prob;
file_close(configfile);
-------------------------------------------------------------------------------
-- INITIAL values
-------------------------------------------------------------------------------
-- give start sign to other processes
SIMPROGRESS <= green;
-- insert signal assignments here
ClkDxC <= '0'; -- permenantly zero
OutSelxS <= "0000";
-- these will remain the same throughout this test
FinBlockxS <= '1';
MemWrEnxSB <= '1';
PadOutEnxS <= '0';
PadDrive1xS <= '0';
PadDrive2xS <= '0';
PadSlewxS <= '0';
FuncScanInxT <= '0';
FuncScanEnxT <= '1'; -- prevent glitches
CoreScanInxT <= '0';
CoreScanEnxT <= '0';
RstxRB <= '0';
------------------------------------------------------------------------------
-- RESET
------------------------------------------------------------------------------
wait until ClkxC'event and ClkxC ='1';
wait for resetactivetime;
RstxRB <= '1';
-------------------------------------------------------------------------------
-- SCAN IN THE LFSR
-------------------------------------------------------------------------------
FuncScanEnxT <= '1'; -- configure the cores to scan
wait until ClkxC'event and ClkxC ='1'; -- wait for clk
lfsr_loop: for i in 0 to LFSRLEN loop -- LFSRLEN times
wait for stimulusapplicationtime;
FuncScanInxT <= f_lfsrinit(i);
wait until ClkxC'event and ClkxC ='1';
end loop lfsr_loop;
wait for stimulusapplicationtime;
FuncScanEnxT <= '0'; -- Disable func scan
wait for responseacquisitiontime; -- we should be ready
-------------------------------------------------------------------------------
-- START OF STIMULI
-------------------------------------------------------------------------------
-- we want to catch a few cases
cnt_loop: for i in 1 to NUMBLOCKS loop
done_loop : while PenUltCyclexS = '0' loop
wait until ClkxC'event and ClkxC='1';
wait for responseacquisitiontime;
end loop done_loop;
-- Due to I/O requirements, the PenUltCyclexS signal is
-- registered in shabziger. This means that the moment we see
-- the signal, the core is already in the cycle where it samples the value
-- of FinBlockxS. As a result, the Change here will not effect the current
-- block but the next one that we will be issuing
-- next cycle
wait until ClkxC'event and ClkxC='1';
wait for stimulusapplicationtime;
-- let us have a 1/PROBABILITY chance of making the next blockthe last block
GenerateRandomInteger(1, PROBABILITY, state1, state2, rand);
if rand /= 1 then
FinBlockxS <= '0';
else
FinBlockxS <= '1';
end if;
end loop cnt_loop; --i
-------------------------------------------------------------------------------
-- END OF STIMULI
-------------------------------------------------------------------------------
SIMPROGRESS <= red; -- stop other processes
wait; -- wait for ever
end process WaveGen_Proc;
end test;