Once you finish writing code for your design, the next step would be to test it. One method of testing your design is by writing a testbench code. A testbench is used for testing the design and making sure it works as per your specified functionalities.
Using a testbench, we can pass inputs of our choice to the design to be tested. The outputs coming out of our design can be viewed on a simulation waveform or text file or even on console screen.
Lets see how this works with an example.
VHDL code for a 4 bit counter with reset:
The design above is a 4 bit UP counter with active high asynchronous reset. The design has 2 inputs - a clock and reset and one output which is the count value.
In order to write a good testbench we need to first understand the design. At least we should know, what kind of errors might be there and what kind of input combinations can bring out these errors. The design we have here is a very simple one, so it shouldn't be too complicated.
Let me show you a sample testbench for this design.
VHDL testbench for 4 bit UP counter:
The code is self explanatory with plenty of comments.
Using a testbench, we can pass inputs of our choice to the design to be tested. The outputs coming out of our design can be viewed on a simulation waveform or text file or even on console screen.
Lets see how this works with an example.
VHDL code for a 4 bit counter with reset:
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity adder is port (clk : in std_logic; reset :in std_logic; count : out unsigned(3 downto 0) --output of the design. 4 bit count value. ); end adder; architecture behavioral of adder is --initializing the count to zero. signal c : unsigned(3 downto 0) :=(others => '0'); begin count <= c; process(clk,reset) begin if(reset = '1') then --active high reset for the counter. c <= (others => '0'); elsif(rising_edge(clk)) then -- when count reaches its maximum(that is 15) reset it to 0 if(c = 15) then c <= (others => '0'); else c <= c + 1; --increment count at every positive edge of clk. end if; end if; end process; end behavioral;
The design above is a 4 bit UP counter with active high asynchronous reset. The design has 2 inputs - a clock and reset and one output which is the count value.
In order to write a good testbench we need to first understand the design. At least we should know, what kind of errors might be there and what kind of input combinations can bring out these errors. The design we have here is a very simple one, so it shouldn't be too complicated.
Let me show you a sample testbench for this design.
VHDL testbench for 4 bit UP counter:
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; -- entity declaration for your testbench. --Notice that the entity port list is empty here. entity tb_adder is end tb_adder; architecture behavior of tb_adder is -- component declaration for the unit under test (uut) component adder is port (clk : in std_logic; reset :in std_logic; count : out unsigned(3 downto 0) ); end component; --declare inputs and initialize them to zero. signal clk : std_logic := '0'; signal reset : std_logic := '0'; --declare outputs signal count : unsigned(3 downto 0); -- define the period of clock here. -- It's recommended to use CAPITAL letters to define constants. constant CLK_PERIOD : time := 10 ns; begin -- instantiate the unit under test (uut) uut : adder port map ( Clk => Clk, reset => reset, count => count ); -- Clock process definitions( clock with 50% duty cycle is generated here. Clk_process :process begin Clk <= '0'; wait for CLK_PERIOD/2; --for half of clock period clk stays at '0'. Clk <= '1'; wait for CLK_PERIOD/2; --for next half of clock period clk stays at '1'. end process; -- Stimulus process, Apply inputs here. stim_proc: process begin wait for CLK_PERIOD*10; --wait for 10 clock cycles. reset <='1'; --then apply reset for 2 clock cycles. wait for CLK_PERIOD*2; reset <='0'; --then pull down reset for 20 clock cycles. wait for CLK_PERIOD*20; reset <= '1'; --then apply reset for one clock cycle. wait for CLK_PERIOD; reset <= '0'; --pull down reset and let the counter run. wait; end process; end;
The code is self explanatory with plenty of comments.
When these codes were simulated in Xilinx ISE 14.6, I got the following waveform.
Simulation waveform:

I would summarize few points here,
I would summarize few points here,
- The entity port list of a testbench is always empty.
- All the designs which you want to test, declare them as components in the testbench code.
- The clock process part in the code, is only required for testing designs with a clock( sequential designs).
- Declare all the inputs and outputs in the design to be tested. Make sure you initialize all the inputs to zero ,in the system.
- Instantiate the design by any one of the Instantiation methods described available here. Note that this instantiation is written after the begin statement.
6 Comments
Inspecting the waveforms works for simple testbenchs, but it's easier to use VHDL asserts;
ReplyDeleteYou can put them at any given point in the test bench, to check whether the received values are as expected. This way you don't need to inspect waveforms (except when inspecting, when asserts tell you something is wrong)
This comment has been removed by a blog administrator.
ReplyDeleteIn ModelSim, at least for me the "time := 1 ns;" doesn't work, but, with 10 ns is just fine.
ReplyDeleteWhich software did you use?
@Raphael : thanks for pointing out the mistake.I used xilinx ISE version 10.1.
ReplyDeleteVHDL asserts are used to write intelligent testbenches. For these testbenches you need not see the waveform for seeing whether the code is working or not.They are used to alert the user of some condition inside the model. When the expression in the ASSERT statement evaluates to FALSE, the associated text message is displayed on the simulator console.Assertion statements can be used for complex designs where inputs and outputs have complex relation.
I will put a post on assertion statements in some time, for now see this link(under the E4 heading):
http://www.vhdl.org/comp.lang.vhdl/html3/gloss_example.html
hello can i get a link for the modified random number generator in open cores website.
ReplyDeletethanks in advance
@Divya : The link is available in this post.
ReplyDeletehttp://vhdlguru.blogspot.com/2010/08/random-number-generator-in-vhdlcont.html
Just go to the project page and click on the download option.