Hassan
Hassan

Reputation: 21

Test bench and verification of code (VHDL)

I am new in VHDL. I wrote a code of decrement counter in which counter picks integer from the array and counts it down to zero and increments the check output. I want you guys to verify if the code is logically correct. If yes then how can i test it using the test bench.

entity counter is
   port(clk   : in bit;
        check : out integer);
end counter;     

architecture imp of counter is
   type my_array is array(natural range<>) of integer;
   constant set:my_array(1 to 5):= (2,4,6,8,10);--array of 5 integers
   signal count:integer:=set(1); --initiating count with integer at first location of array 
   signal t : integer;
begin
   process(clk)
      variable i : integer:= 1;--to be used to indicate the locations of array 
   begin
      if (clk='1' and clk'event) and (count>0) then
         count<=count-1;
      elsif (clk='1' and clk'event) and (i<5) then 
         i:=i+1;
         count<= set(i);
         t<=t+1;
      end if;
   end process;
   check<=t;
end imp;

Upvotes: 0

Views: 6813

Answers (2)

rick
rick

Reputation: 1646

Your code compiles correctly, but we would need a more detailed description of what it should do to make sure it is correct. As @tsukuyo said, you also need to assign an initial value to signal 't' in line #10.

After you've fixed that, here's a testbench that exercises your circuit and checks the output values automatically. It is important to check the output values in the testbench because this way you don't need to be staring at waveforms every time you make a change to your code. Since the testbench is self-checking, it automatically tells you when something is wrong:

use std.textio.all;                                                      
use std.env.all;                                                         

entity counter_tb is                                                     
end;                                                                     

architecture testbench of counter_tb is                                  
   signal clk: bit;                                                      
   signal check: integer;                                                

begin                                                                    
   -- instantiate the unit under test                                    
   uut: entity work.counter port map(clk => clk, check => check);

   -- generate a clock pulse with a 20 ns period                         
   clk <= not clk after 10 ns;                                           

   run_tests: process is                                                 
      -- declare an array with all expected output values                
      type integer_vector is array(natural range<>) of integer;          
      constant EXPECTED_RESULTS: integer_vector := (                     
         0, 0, 0,                                                        
         1, 1, 1, 1, 1,                                                  
         2, 2, 2, 2, 2, 2, 2,                                            
         3, 3, 3, 3, 3, 3, 3, 3, 3,                                      
         4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4                                 
      );                                                                 
      variable log_line: line;                                           

   begin                                                                 
      -- loop through all expected values and ensure that                
      -- they match the actual output value                              
      for i in EXPECTED_RESULTS'range loop                               
         wait until rising_edge(clk);                                    
         write(log_line,                                                 
            "i: " & to_string(i) &                                       
            ", check: " & to_string(check) &                             
            ", expected: " & to_string(EXPECTED_RESULTS(i))              
         );                                                              
         writeline(output, log_line);                                    
         assert check = EXPECTED_RESULTS(i);                             
      end loop;                                                          

      report "End of simulation. All tests passed.";                    
      finish;                                                            
   end process;                                                          

end;       

This is an example of the output it produces:

# Loading std.standard
# Loading std.textio(body)
# Loading std.env(body)
# Loading work.counter_tb(testbench)
# Loading work.counter(imp)
# run -all
# i: 0, check: 0, expected: 0
# i: 1, check: 0, expected: 0
# i: 2, check: 0, expected: 0
# i: 3, check: 1, expected: 1
# i: 4, check: 1, expected: 1
# i: 5, check: 1, expected: 1
# i: 6, check: 1, expected: 1
# i: 7, check: 1, expected: 1
# i: 8, check: 2, expected: 2
# i: 9, check: 2, expected: 2
# i: 10, check: 2, expected: 2
# i: 11, check: 2, expected: 2
# i: 12, check: 2, expected: 2
# i: 13, check: 2, expected: 2
# i: 14, check: 2, expected: 2
# i: 15, check: 3, expected: 3
# i: 16, check: 3, expected: 3
# i: 17, check: 3, expected: 3
# i: 18, check: 3, expected: 3
# i: 19, check: 3, expected: 3
# i: 20, check: 3, expected: 3
# i: 21, check: 3, expected: 3
# i: 22, check: 3, expected: 3
# i: 23, check: 3, expected: 3
# i: 24, check: 4, expected: 4
# i: 25, check: 4, expected: 4
# i: 26, check: 4, expected: 4
# i: 27, check: 4, expected: 4
# i: 28, check: 4, expected: 4
# i: 29, check: 4, expected: 4
# i: 30, check: 4, expected: 4
# i: 31, check: 4, expected: 4
# i: 32, check: 4, expected: 4
# i: 33, check: 4, expected: 4
# i: 34, check: 4, expected: 4
# ** Note:  End of simulation. All tests passed.
#    Time: 690 ns  Iteration: 0  Instance: /counter_tb                                                              

Note: to run the above simulation using Modelsim, type:

vlib work
vcom -2008 *.vhd
vsim -c counter_tb(testbench) -do "run -all; quit"

Upvotes: 1

user2778477
user2778477

Reputation:

The code is fine but you need to set an initialization value to t for simulation.

See Test Benches Overview to learn how to write a testbench using VHDL.

Here is a simple one:

entity counter_tb is
end;

architecture arch of counter_tb is

   component counter is
      port (clk   : in bit;
            check : out integer);
   end component;

   signal clk: bit;
   signal check: integer;
begin

   UUT: counter
      port map (clk => clk, check => check);

   clk_proc: process
   begin
      clk <= '0';
      wait for 50 ns;
      clk <= '1';
      wait for 50 ns;
   end process; 

end arch; 

Upvotes: 0

Related Questions