cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Highlighted
Newbie
Newbie
267 Views
Registered: ‎07-24-2020

Why is my testbench clk not advancing?

Hi, 

All my testbench is trying to do is verify whether or not the LED signal went high, but on Modelsim when I try and simulate it, the clock doesn't even start and nothing initializes. What am I doing wrong?

`timescale 1ns/100ps
 
module fir_filter_tb();
 reg clk, reset_n;
 reg led;

top top_level (
	.clk(clk),
	.reset_n(reset_n),
	.led(led)
	);
	
    initial
	 begin
	 $display($time, " << Starting the Simulation >>");
	 clk = 1'b0; // at time 0
	 reset_n = 0; // reset is active
	 led = 0; // output is low
	 #10 reset_n = 1'b1; // at time 20 release reset
	 end
    
    always #10 clk = ~clk;
    always
	begin
	     if (led ==  1'b1) begin
	         $write($time, "Filter Successful");
	     end else begin
		 $write($time, "bleh you suck");
	end end
endmodule : fir_filter_tb

 

 

0 Kudos
2 Replies
Highlighted
Guide
Guide
231 Views
Registered: ‎01-23-2009

The problem is your last always block...

Verilog simulation is event driven; events are processed at a given simulated time. Only after all the events for a given simulation time are executed is the time advanced to the next time that has events to process. Your last block is preventing that from happening.

Your last block is an 'always' block that executes some functional code, but with no time control statements in it. At time 0, it starts, does a loop (printing a message) and then ends. But since it is an always block, it restarts right away. It does this loop forever in time unit 0. Since there is always this event running or scheduled, time cannot advance past time unit 0.

Simply adding a time control statement to it will make it (at least potentially) advance. Time control statements are

  • #(value)
  • wait(expression)
  • @(event)

So if you modify the last loop to be

always
begin
   if (led ==  1'b1) begin
         $write($time, "Filter Successful");
   end else begin
	 $write($time, "bleh you suck");
   end
   #1; 
end

Now just before the end of your loop, the process pauses for one time unit - scheduled to restart at the next time unit (for the first iteration, at time unit 1). Eventually all other events for time 0 will complete, and the simulated time will advance. In time unit 1, this will run again, and then pause until time unit 2.

So now, this will run once in each time unit, as opposed to before where it ran infinitely at time unit 0.

Avrum

0 Kudos
Highlighted
Xilinx Employee
Xilinx Employee
168 Views
Registered: ‎06-10-2020

Hello,

The verilog coding of always block is causing this issue to occur.

If same code you run using Vivado 2020.1 , below warning will be displayed for the testcase.

WARNING: [VRFC 10-1771] potential always loop found at line 23 at tb.v

Here the loop control with always block in not associated. This causes the always block to exexute continously at time 0 and simulation time not advancing.

Please rewrite the code using any of event control.

Like: always @ (posedge clk) or wait (expression)

Also use $finish statement to come out of simulation exceution.

-------------------------------------------------------------------------------------------------------------------------

If this reply is useful, please don't forget to mark the post as "Kudos" or "Accepted solution"

--------------------------------------------------------------------------------------------------------------------------

 

0 Kudos