Contact me for VHDL or Verilog projects and 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;

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.
count <= c;
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:

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.
         clk : IN  std_logic;
         count : OUT  std_logic_vector(3 downto 0);
         reset : IN  std_logic
   --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;
    -- 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
        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
        wait for 7 ns;
        reset <='1';
        wait for 3 ns;
        reset <='0';
        wait for 17 ns;
        reset <= '1';
        wait for 1 ns;
        reset <= '0';
  end process;


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.


  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)

  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.

  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?

  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):

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

    thanks in advance

  6. @Divya : The link is available in this post.

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

  7. I have been using the VHDL package linked below:,vhld_tb

    For 14+ years ...


  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

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

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

  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?

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

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

  14. hi... can u get me Viterbi decoder with register exchange and traceback method VHDL code? plzzzz
    replay me to

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

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

  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 .

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

  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.

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

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

  22. can anyone please help in vhdl code for array multilplier and test bench also. please mail me to

  23. can you give me an example of tenst bench for this code?
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use ieee.math_real.all;

    entity PID_Regler is
    data_width: integer := 14;
    intern_data_width: integer := 18

    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');

    Regler: process(clk_i)
    --Mappen der Eingeänge
    w <= data_w_i;
    x <= data_x_i;

    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');
    --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;

  24. how can i write a sawtooh code for Fs = 18khz in vhdl?

  25. how to Instantiate the Unit Under Test (UUT) for an output which is an array of 0 to 63 values ??

  26. Hi, 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

    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
    process (clk,A,EN)
    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;


    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;
    uut : decoder port map (
    clk => clk,
    A => A,
    X => X,
    EN => EN );
    clk_gen : process
    clk <= '0';
    wait for clock_period/2;
    clk <= '1';
    wait for clock_period/2;
    end process clk_gen;
    sdp : process
    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?

    1. Before begin I think you should write
      constant clk_period : time := 1 ns;


Related Posts with Thumbnails