221 lines
7.5 KiB
VHDL
221 lines
7.5 KiB
VHDL
--*****************************************************************************
|
|
--*************************** VHDL Source Code ******************************
|
|
--********* Copyright 2010, Rochester Institute of Technology ***************
|
|
--*****************************************************************************
|
|
--
|
|
-- DESIGNER NAME: Jeanne
|
|
--
|
|
-- LAB NAME: Counters and Timers with VHDL 1
|
|
--
|
|
-- FILE NAME: timer_tb
|
|
--
|
|
-------------------------------------------------------------------------------
|
|
--
|
|
-- DESCRIPTION
|
|
--
|
|
-- This test bench will provide input to test the implemention of the
|
|
-- 4-digit counter. The pushbutton switch KEY0 is used to reset
|
|
-- the counter to 0. The contents of the counter are displayed on
|
|
-- the 7-segment displays, HEX2-0 which are verified via an assert statement.
|
|
-- The timer can be preset to any number from 000-999.
|
|
--
|
|
-- This testbench puts the timer in the test mode (100 ns) so the output
|
|
-- will change every 5 clock cycles. It is impossible to test the other modes
|
|
-- of operation due to the high number of clock pulses required to change the
|
|
-- output.
|
|
--
|
|
--
|
|
-------------------------------------------------------------------------------
|
|
--
|
|
-- REVISION HISTORY
|
|
--
|
|
-- _______________________________________________________________________
|
|
-- | DATE | USER | Ver | Description |
|
|
-- |==========+======+=====+================================================
|
|
-- | | | |
|
|
-- | 10/23/17 | JWC | 1.0 | Created
|
|
-- | | | |
|
|
----------------------------------------------------------------------------
|
|
-- | 10/23/19 | HLD | 1.1 | Updated TB to only use 3 HEX displays
|
|
-- | | | |
|
|
--*****************************************************************************
|
|
--*****************************************************************************
|
|
|
|
|
|
LIBRARY ieee;
|
|
USE ieee.std_logic_1164.ALL;
|
|
USE ieee.std_logic_unsigned.all;
|
|
USE ieee.numeric_std.ALL;
|
|
|
|
ENTITY timer_tb IS
|
|
END timer_tb;
|
|
|
|
|
|
ARCHITECTURE test OF timer_tb IS
|
|
|
|
-- Component Declaration for the Unit Under Test (UUT)
|
|
-- if you use a package with the component defined then you do not need this
|
|
COMPONENT timer IS
|
|
PORT(clk, reset_n, set_n : IN STD_LOGIC;
|
|
S : IN STD_LOGIC;
|
|
Pre_time : IN STD_LOGIC_vector(9 downto 0);
|
|
HEX0, HEX1, HEX2 : OUT STD_LOGIC_VECTOR(6 downto 0));
|
|
END COMPONENT;
|
|
|
|
-- define signals for component ports
|
|
-- Inputs
|
|
signal clk_tb : std_logic := '0';
|
|
signal reset_n_tb : std_logic := '0';
|
|
signal S_tb : std_logic := '0'; --put the system in test mode
|
|
signal set_n_tb : std_logic := '1';
|
|
signal pre_time_tb : std_logic_vector(9 downto 0) := "0000000000";
|
|
--
|
|
-- Outputs
|
|
signal hex0 : std_logic_vector(6 DOWNTO 0);
|
|
signal hex1 : std_logic_vector(6 DOWNTO 0);
|
|
signal hex2 : std_logic_vector(6 DOWNTO 0);
|
|
|
|
-- signals for test bench control
|
|
signal sim_done : boolean := false;
|
|
signal PERIOD_c : time := 20 ns; -- 50MHz
|
|
|
|
--signals for self-checking purposes
|
|
signal checksum : integer;
|
|
signal ones, tens, hundreds: integer;
|
|
|
|
BEGIN -- test
|
|
|
|
-- component instantiation
|
|
UUT : timer
|
|
PORT MAP (
|
|
clk => clk_tb,
|
|
reset_n => reset_n_tb,
|
|
set_n => set_n_tb,
|
|
S => S_tb,
|
|
Pre_time => pre_time_tb,
|
|
hex0 => hex0,
|
|
hex1 => hex1,
|
|
hex2 => hex2
|
|
);
|
|
|
|
-- This creates an clock_50 that will shut off at the end of the Simulation
|
|
-- this makes a clock_50 that you can shut off when you are done.
|
|
clk_tb <= NOT clk_tb AFTER PERIOD_C/2 WHEN (NOT sim_done) ELSE '0';
|
|
|
|
|
|
---------------------------------------------------------------------------
|
|
-- NAME: Stimulus
|
|
--
|
|
-- DESCRIPTION:
|
|
-- This process will apply stimulus to the UUT.
|
|
---------------------------------------------------------------------------
|
|
stimulus : PROCESS
|
|
|
|
BEGIN
|
|
-- de-assert all inputs except the reset which is asserted
|
|
reset_n_tb <= '0';
|
|
WAIT FOR 5 ns;
|
|
|
|
-- now lets sync the stimulus to the clock_50
|
|
-- move stimulus 1ns after clock edge
|
|
WAIT UNTIL clk_tb = '1';
|
|
|
|
-- de-assert reset
|
|
reset_n_tb <= '1';
|
|
-- allow the BCD counter to count to max value
|
|
-- convert the hex outputs back to BDC digits
|
|
--convert the BCD digits to an integer number
|
|
--compare the number against the loop counter
|
|
for i in 0 to 999 loop
|
|
wait for 5*PERIOD_C;
|
|
assert i = checksum
|
|
report "count is wrong. It should be " & integer'image(i) & CR
|
|
severity error;
|
|
end loop;
|
|
--count ten more
|
|
for i in 0 to 9 loop
|
|
wait for 5*PERIOD_C;
|
|
assert i = checksum
|
|
report "count is wrong. It should be " & integer'image(i) & CR
|
|
severity error;
|
|
end loop;
|
|
-- now load
|
|
pre_time_tb <= "0111110011";
|
|
set_n_tb <= '0';
|
|
wait for 5*PERIOD_C;
|
|
assert checksum = 499
|
|
report "count is wrong. It should be 499"
|
|
severity error;
|
|
set_n_tb <= '1';
|
|
-- count up
|
|
for i in 500 to 600 loop
|
|
wait for 5*PERIOD_C;
|
|
assert i = checksum
|
|
report "count is wrong. It should be " & integer'image(i) & CR
|
|
severity error;
|
|
end loop;
|
|
-- shutting down simulation
|
|
sim_done <= true;
|
|
WAIT FOR PERIOD_c*1;
|
|
report "Simulation Complete";
|
|
-----------------------------------------------------------------------
|
|
-- This Last WAIT statement needs to be here to prevent the PROCESS
|
|
-- sequence from re starting.
|
|
-----------------------------------------------------------------------
|
|
WAIT;
|
|
END PROCESS stimulus;
|
|
|
|
--------------------------------------------------------------------------
|
|
-- the following three processes take the seven segment display values that
|
|
-- the UUT output and converts them to the corresponding BCD digit (0-9)
|
|
-- the bcd digits are then converted to an integer value
|
|
--------------------------------------------------------------------------
|
|
checksum <= (hundreds * 100) + (10*tens) + ones;
|
|
|
|
process (hex2) is
|
|
begin
|
|
case(hex2) is
|
|
when "1000000" => hundreds <= 0;
|
|
when "1111001" => hundreds <= 1;
|
|
when "0100100" => hundreds <= 2;
|
|
when "0110000" => hundreds <= 3;
|
|
when "0011001" => hundreds <= 4;
|
|
when "0010010" => hundreds <= 5;
|
|
when "0000010" => hundreds <= 6;
|
|
when "1111000" => hundreds <= 7;
|
|
when "0000000" => hundreds <= 8;
|
|
when others => hundreds <= 9;
|
|
end case;
|
|
end process;
|
|
process (hex1) is
|
|
begin
|
|
case(hex1) is
|
|
when "1000000" => tens <= 0;
|
|
when "1111001" => tens <= 1;
|
|
when "0100100" => tens <= 2;
|
|
when "0110000" => tens <= 3;
|
|
when "0011001" => tens <= 4;
|
|
when "0010010" => tens <= 5;
|
|
when "0000010" => tens <= 6;
|
|
when "1111000" => tens <= 7;
|
|
when "0000000" => tens <= 8;
|
|
when others => tens <= 9;
|
|
end case;
|
|
end process;
|
|
process (hex0) is
|
|
begin
|
|
case(hex0) is
|
|
when "1000000" => ones <= 0;
|
|
when "1111001" => ones <= 1;
|
|
when "0100100" => ones <= 2;
|
|
when "0110000" => ones <= 3;
|
|
when "0011001" => ones <= 4;
|
|
when "0010010" => ones <= 5;
|
|
when "0000010" => ones <= 6;
|
|
when "1111000" => ones <= 7;
|
|
when "0000000" => ones <= 8;
|
|
when others => ones <= 9;
|
|
end case;
|
|
end process;
|
|
|
|
END test;
|