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.
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.
I have been using the VHDL package linked below:
ReplyDeletehttp://opencores.org/project,vhld_tb
For 14+ years ...
Sckoarn
Hi
ReplyDeleteI have a general question about testing of VHDL-code...
Can anyone help me out on estimating the effort needed to specify and execute (formal) tests for VHDL?
I'm quite experienced in (software) testing & estimations but I do not have any metric's or key figures suitable for VHDL (like the number of I/O's, lines of code, state machines etc.)
A response in email will be appreciated: 4x4andmore @ gmail dot com
Regards, Patrick
How would you change this to be a 32 bit counter. I'm a beginner. Thanks.
ReplyDeletehey can i get the code of a function that converts Boolean into integer .thanks in advance
ReplyDelete@anubhav : A boolean has only two values TRUE and FALSE.So why do you want to convert it to a integer. What is your actual purpose?
ReplyDeletehello can i get a vhdl code for 32 bit array???i am new in this field.
ReplyDeletehi...can i get the vhdl code for frequency multiplier without using unisim library..
ReplyDeletehi... can u get me Viterbi decoder with register exchange and traceback method VHDL code? plzzzz
ReplyDeletereplay me to tabu.unnisa@gmail.com
What is resettable counter and what is the main objective of it? please answer Thanks.
ReplyDeletecan you give some examples for synthesizable and non-synthesizable code in vhdl..
ReplyDeleteIn your code you should use variable instead of a signal , multiple assignments inside a process are alright but it will be assigned the value only after exitin from the process .
ReplyDeletethanks a lot,it was very helpful to do the sample example and know the model of executing it.
ReplyDeletecan you give me an example of vhdl code subtractor of integer
ReplyDeletecan you give me an example of vhdl xilinx subtractor in integer
ReplyDeletecan anyone please help in vhdl code for array multilplier and test bench also. please mail me to alisasky22@gmail.com
ReplyDeletecan you give me an example of tenst bench for this code?
ReplyDeletelibrary IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use ieee.math_real.all;
entity PID_Regler is
generic(
data_width: integer := 14;
intern_data_width: integer := 18
);
port(
clk_i : in std_logic;
rst_i : in std_logic;
k_p : in std_logic_vector(intern_data_width-1 downto 0);
k_i : in std_logic_vector(intern_data_width-1 downto 0);
k_d : in std_logic_vector(intern_data_width-1 downto 0);
data_w_i : in std_logic_vector(data_width-1 downto 0);
data_x_i : in std_logic_vector(data_width-1 downto 0);
data_y_o : out std_logic_vector(data_width-1 downto 0)
);
end PID_Regler;
architecture Behavioral of PID_Regler is
signal w : std_logic_vector(data_width-1 downto 0);
signal x : std_logic_vector(data_width-1 downto 0);
signal e : std_logic_vector(data_width-1 downto 0);
signal y : std_logic_vector(data_width-1 downto 0);
signal yp: std_logic_vector(intern_data_width-1 downto 0) := (others => '0');
signal yi: std_logic_vector(intern_data_width-1 downto 0) := (others => '0');
signal yd: std_logic_vector(intern_data_width-1 downto 0) := (others => '0');
signal ealt : std_logic_vector(intern_data_width-1 downto 0) := (others => '0');
signal yi_alt : std_logic_vector(intern_data_width-1 downto 0) := (others => '0');
begin
Regler: process(clk_i)
begin
--Mappen der Eingeänge
w <= data_w_i;
x <= data_x_i;
--Regeldifferenz
e <= std_logic_vector(signed(w) - signed(x));
if rising_edge(clk_i) then
if rst_i = '1' then
yp <= (others => '0');
yi <= (others => '0');
yd <= (others => '0');
ealt <= (others => '0');
y <= (others => '0');
else
--e <= std_logic_vector(signed(w) - signed(x));
yp <= std_logic_vector(signed(k_p)*signed(e));
yi <= std_logic_vector(signed(yi_alt)+(signed(k_i)*signed(e)/10)); --yi_alt=yi
yd <= std_logic_vector(signed(k_d)*((signed(e)-signed(ealt))*10)); -- ealt=e
y <= std_logic_vector(signed(yp)+signed(yi)+signed(yd));
--y <= resize((yp + yi + yd));
ealt <= e;
yi_alt <= yi;
end if;
end if;
end process Regler;
data_y_o <= y;
end Behavioral;
how can i write a sawtooh code for Fs = 18khz in vhdl?
ReplyDeletehow to Instantiate the Unit Under Test (UUT) for an output which is an array of 0 to 63 values ??
ReplyDeleteHi, I have written a vhdl code for decoder and it is being synthesized well but couldnot simulate the test bench, here I am attaching my code for your reference
ReplyDeletedecoder.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity decoder is
Port ( clk : in std_logic;
A : in STD_LOGIC_VECTOR (1 downto 0);-- 2 bit input
X : out STD_LOGIC_VECTOR (3 downto 0);-- 4 bit input
EN : in STD_LOGIC); --enable input
end decoder;
architecture Behavioral of decoder is
begin
process (clk,A,EN)
begin
if(clk'event and clk= '1') then
X <= "1111";
if (EN = '1') then
case A is
when "00" => X(0) <= '0';
when "01" => X(1) <= '0';
when "10" => X(2) <= '0';
when "11" => X(3) <= '0';
when others => X <= "1111";
end case;
end if;
end if;
end process;
end Behavioral;
decoder_tb.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity decoder_tb is
-- Port ( );
end decoder_tb;
architecture Behavioral of decoder_tb is
component decoder is
Port ( clk : in std_logic;
A : in STD_LOGIC_VECTOR (1 downto 0);
X : out STD_LOGIC_VECTOR (3 downto 0);
EN : in STD_LOGIC);
end component decoder;
signal clk : std_logic;
signal A : std_logic_vector (1 downto 0);
signal X : std_logic_vector(3 downto 0);
signal EN : std_logic:= 0;
begin
uut : decoder port map (
clk => clk,
A => A,
X => X,
EN => EN );
clk_gen : process
begin
clk <= '0';
wait for clock_period/2;
clk <= '1';
wait for clock_period/2;
end process clk_gen;
sdp : process
begin
wait for 20 ns;
EN <= 1;
wait for 20 ns;
EN <= 0;
wait for 20 ns;
A <= "00";
wait for 20 ns;
A <= "01";
wait for 20 ns;
A <= "10";
wait for 20 ns;
A <= "11";
end process sdp;
end behavioral;
What is wrong in the above code?
Before begin I think you should write
Deleteconstant clk_period : time := 1 ns;
Hi I have written a vhdl code for decoder and i successfully synthesized it but couldnot simulate my test bench as it fails because of some errors. I am posting my decoder.vhd and decoder_tb.vhd here for your reference
ReplyDeletedecoder.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity decoder is
Port ( clk : in std_logic;
A : in STD_LOGIC_VECTOR (1 downto 0);-- 2 bit input
X : out STD_LOGIC_VECTOR (3 downto 0);-- 4 bit input
EN : in STD_LOGIC); --enable input
end decoder;
architecture Behavioral of decoder is
begin
process (clk,A,EN)
begin
if(clk'event and clk= '1') then
X <= "1111";
if (EN = '1') then
case A is
when "00" => X(0) <= '0';
when "01" => X(1) <= '0';
when "10" => X(2) <= '0';
when "11" => X(3) <= '0';
when others => X <= "1111";
end case;
end if;
end if;
end process;
end Behavioral;
decoder_tb.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity decoder_tb is
-- Port ( );
end decoder_tb;
architecture Behavioral of decoder_tb is
component decoder is
Port ( clk : in std_logic;
A : in STD_LOGIC_VECTOR (1 downto 0);
X : out STD_LOGIC_VECTOR (3 downto 0);
EN : in STD_LOGIC);
end component decoder;
signal clk : std_logic;
signal A : std_logic_vector (1 downto 0);
signal X : std_logic_vector(3 downto 0);
signal EN : std_logic:= 0;
begin
uut : decoder port map (
clk => clk,
A => A,
X => X,
EN => EN );
clk_gen : process
begin
clk <= '0';
wait for clock_period/2;
clk <= '1';
wait for clock_period/2;
end process clk_gen;
sdp : process
begin
wait for 20 ns;
EN <= 1;
wait for 20 ns;
EN <= 0;
wait for 20 ns;
A <= "00";
wait for 20 ns;
A <= "01";
wait for 20 ns;
A <= "10";
wait for 20 ns;
A <= "11";
end process sdp;
end behavioral;
Can you help me what is wrong in my test bench?
Clock_period is not defined
DeleteHi,
ReplyDeleteI was wondering about initializing the signals to a particular value during declaration. Would this bring any advantage to the testing?
In the counter code, it is not necessary to test when counter has reached 15
ReplyDelete