General Structure for Simulation
a) UUT: Test Component Instantiation
b) Signals to generate stimulus
c) assert statements
1. A simple template for stimulus generation in VHDL is:
Here is a simple stimulus which would test a 2x2 multiplierNotice that in the process below, there is no sensitivity list and it uses wait statements.
---------- Stimulus to DUT-----
stim:process
begin
A <= "00";
B <= "00";
wait for 10 ns;
A<= "01";
B<= "01";
wait for 10 ns;
A <= "10";
B <= "10";
wait for 10 ns;
A <= "11";
B <= "11";
wait;
end process stim;
Note: "Wait;" is an important statement at the end. If not for this, stimulus will be generated repeatedly and will enter into infinite loop. This might be OK if it is exactly what you want.
I will update the post to have more advanced stimulus generation styles in future such as reading stimulus for text file, using python to generate stimulus.
1a. Improvement# 1
A little bit better approach to above stimulus generation is shown below. We declare a constant which is called "period" with default value of 10 ns.---------- Stimulus to DUT-----
stim:process
constant period: time := 10 ns;
begin
A <= "00";
B <= "00";
wait for period;
A<= "01";
B<= "01";
wait for period;
A <= "10";
B <= "10";
wait for period;
A <= "11";
B <= "11";
wait;
end process stim;
2. Improvement #2
While the above example 1a shows how to create stimulus, it lacks code check the response from the dut and ensure that it is indeed working as expected. How do we check correctness of the response?One approach is to use assert statements
assert (dut response = expected response); If dut response is not equal to expected response, assert will throw an error.
e.g., for stimulus wait for 10 ns;
A<= "01";
B<= "01";
We expect the output to be 0001. So, we would write the statement as
assert (P = "0001") report "TEST FAILED";
An example code is shown below:---------- Stimulus to DUT-----
stim:process
constant period: time := 10 ns;
constant update: time := 1 ns;
begin
-- Case#1:
wait for period;
A <= "00";
B <= "00";
wait for update;
assert (P = "0000")report "TEST FAILED" severity error;
-- Case#2:
wait for period;
A<= "01";
B<= "01";
wait for update;
assert (P = "0001")report "TEST FAILED" severity error;
-- Case#3:
wait for period;
A <= "10";
B <= "10";
wait for update;
assert (P = "0010") report "TEST FAILED" severity error;
-- Case#4:
wait for period;
A <= "11";
B <= "11";
wait for update;
assert (P = "1001") report "TEST FAILED" severity error;
wait;
end process stim;
3. Improvement#3
While the above approach is nicely structured, it is cumbersome to write all the statements every time. Also, there is a regularity in the stimulus vector. A better approach would be to store all the stimulus elements in a vetcor/array and read the stimulus from vector/array using a for loop
---------- Stimulus to DUT-----
stim:process
constant period: time := 10 ns;
constant update: time := 1 ns;
begin
--- Apply Stimulus recursively
for i in 0 to 3 loop
wait for period;
A <= CONV_STD_LOGIC_VECTOR(i,2);
B <= CONV_STD_LOGIC_VECTOR(i,2);
wait for update;
assert (P = i*i)report "TEST FAILED" severity error;
end loop;
wait;
end process stim;
In this case I have shown how you could create stimulus on the fly using for loop and apply to the DUT. However, there will be situations where you want to precalculate the stimulus through some other code and store in file.
Note: For some debugging purposes, you want to print out the input values when a test case fails. Often times, the input value is a std_logic_vector. To convert std_logic_vector use "integer'image(CONV_INTEGER(unsigned(a)))"
4. Improvement# 4: Make a Simpkg, printing objects in VHDL
Start adding all the utility functions for testbenches such as vec2str, std2str into a package so that it can be reused. To print variable i of integer type use, integer'image(i);
Tutorial: Printing Objects in VHDL
http://www-ee.uta.edu/Online/Zhu/spring_2007/tutorial/how_to_print_objexts.txt
5. Improvement# 5: Assert in multiple lines
Assert statement in VHDL by default only allows one line. To break it into multiple lines use concatenate (&) operator
e.g., assert (y= remainder(0))
report "Test Failed" &
"dut y =" & std2str(y) & " expected y =" & std2str(remainder(0))
severity error;
5. Random Value Stimulus in VHDL Testbenches
The IEEE "math_real" VHDL package supplies a function called "UNIFORM" which returns a pseudo-random number (of type REAL) in the range 0 to 1.0.
No comments:
Post a Comment