Contact me for VHDL projects or assignments

Wednesday, March 3, 2010

How to write a testbench?

     Once you finish writing code for your design,you need to test whether it is working or not.One method of testing your design is by writing a testbench code.Without going much into the details I will give you an example.
     Below is a program for a basic 4 bit counter with reset input :

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity test is
port (clk : in std_logic;
      count : out std_logic_vector(3 downto 0);
      reset :in std_logic
     );
end test;

architecture Behavioral of test is
signal c : std_logic_vector(3 downto 0) :=(others => '0');  --initializing count to zero.
begin
count <= c;
process(clk,reset)
begin
if(clk'event and clk='1') then
-- when count reaches its maximum(that is 15) reset it to 0
if(c = "1111") then
c <="0000";
end if;
c <= c+'1';  --increment count at every positive edge of clk.
end if;
if(reset='1') then  --when reset equal to '1' make count equal to 0.
c <=(others => '0');  -- c ="0000"
end if;
end process;

end Behavioral;


Now I will give a sample test bench for the above code:

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.all;

-- entity declaration for your testbench.Dont declare any ports here
ENTITY test_tb IS
END test_tb;

ARCHITECTURE behavior OF test_tb IS
   -- Component Declaration for the Unit Under Test (UUT)
    COMPONENT test  --'test' is the name of the module needed to be tested.
--just copy and paste the input and output ports of your module as such.
    PORT(
         clk : IN  std_logic;
         count : OUT  std_logic_vector(3 downto 0);
         reset : IN  std_logic
        );
    END COMPONENT;
   --declare inputs and initialize them
   signal clk : std_logic := '0';
   signal reset : std_logic := '0';
   --declare outputs and initialize them
   signal count : std_logic_vector(3 downto 0);
   -- Clock period definitions
   constant clk_period : time := 1 ns;
BEGIN
    -- Instantiate the Unit Under Test (UUT)
   uut: test PORT MAP (
         clk => clk,
          count => count,
          reset => reset
        );      

   -- Clock process definitions( clock with 50% duty cycle is generated here.
   clk_process :process
   begin
        clk <= '0';
        wait for clk_period/2;  --for 0.5 ns signal is '0'.
        clk <= '1';
        wait for clk_period/2;  --for next 0.5 ns signal is '1'.
   end process;
   -- Stimulus process
  stim_proc: process
   begin        
        wait for 7 ns;
        reset <='1';
        wait for 3 ns;
        reset <='0';
        wait for 17 ns;
        reset <= '1';
        wait for 1 ns;
        reset <= '0';
        wait;
  end process;

END;

I think the code is self explanatory.I have given comments so that you can easily follow it. Now add these programs to your project and compile them.Once compilation is over click on "simulate Behavioral Model".You will get the following waveform.
    As you can see,whenever my reset=1,count value is zero.Otherwise count increments upto 15 and then get reset to zero.
Now a little more explanation about the test bench code:
    1) wait for 7 ns; means the simulator doesn't do anything for 7 nano second.If you want 7 ms delay instead of  7 ns then just replace ns with ms.
    2)The process named "clock_process" is  must in any test bench because it is used to generate clock for your module.Any main module always work with this clock.The period and duty cycle of the clock can be changed by editing this process.
    3)Your main module has to be given as a component in your test bench program inside "architecture".
    4)Your module has to be instantiated after the 'begin' statement.

21 comments:

  1. Inspecting the waveforms works for simple testbenchs, but it's easier to use VHDL asserts;
    You 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)

    ReplyDelete
  2. There's an insignificant type error in line 30, intead of " count => count; " is " count => count, ".

    By the way, what is "VHDL asserts"? I'm new here.

    Nice explanation.

    ReplyDelete
  3. In ModelSim, at least for me the "time := 1 ns;" doesn't work, but, with 10 ns is just fine.
    Which software did you use?

    ReplyDelete
  4. @Raphael : thanks for pointing out the mistake.I used xilinx ISE version 10.1.
    VHDL 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

    ReplyDelete
  5. hello can i get a link for the modified random number generator in open cores website.

    thanks in advance

    ReplyDelete
  6. @Divya : The link is available in this post.
    http://vhdlguru.blogspot.com/2010/08/random-number-generator-in-vhdlcont.html

    Just go to the project page and click on the download option.

    ReplyDelete
  7. I have been using the VHDL package linked below:
    http://opencores.org/project,vhld_tb

    For 14+ years ...

    Sckoarn

    ReplyDelete
  8. Hi

    I 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

    ReplyDelete
  9. How would you change this to be a 32 bit counter. I'm a beginner. Thanks.

    ReplyDelete
  10. hey can i get the code of a function that converts Boolean into integer .thanks in advance

    ReplyDelete
  11. @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?

    ReplyDelete
  12. hello can i get a vhdl code for 32 bit array???i am new in this field.

    ReplyDelete
  13. hi...can i get the vhdl code for frequency multiplier without using unisim library..

    ReplyDelete
  14. hi... can u get me Viterbi decoder with register exchange and traceback method VHDL code? plzzzz
    replay me to tabu.unnisa@gmail.com

    ReplyDelete
  15. What is resettable counter and what is the main objective of it? please answer Thanks.

    ReplyDelete
  16. can you give some examples for synthesizable and non-synthesizable code in vhdl..

    ReplyDelete
  17. In 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 .

    ReplyDelete
  18. thanks a lot,it was very helpful to do the sample example and know the model of executing it.

    ReplyDelete
  19. there is an error in the line c <= c + '1'; --increment count at every positive edge of clk.
    i m using xillinx 14.1
    any help.

    ReplyDelete
  20. can you give me an example of vhdl code subtractor of integer

    ReplyDelete
  21. can you give me an example of vhdl xilinx subtractor in integer

    ReplyDelete

Related Posts with Thumbnails

Download this article as PDF