Testing Verilog Code - Find Reason Output Not Displayed

  • Thread starter Thread starter polaris90
  • Start date Start date
  • Tags Tags
    Code Testing
Click For Summary

Discussion Overview

The discussion revolves around troubleshooting a Verilog code for an 8-bit counter, specifically focusing on why the output is not displayed correctly during simulation. Participants are exploring issues related to the testbench, reset conditions, and initialization of registers.

Discussion Character

  • Technical explanation
  • Debate/contested

Main Points Raised

  • One participant suggests that the counter may not be resetting properly, implying that the increment operation could be ineffective if the counter starts as an undefined value (X).
  • Another participant provides examples of synchronous and asynchronous reset structures, emphasizing the importance of resetting all elements in the block to avoid propagation of undefined values during simulation.
  • A participant questions the necessity of checking the reset condition at the edge, indicating confusion about the reset logic presented.
  • Further clarification is offered regarding the difference between synchronous and asynchronous resets, with a focus on how they should be structured for proper synthesis.
  • Concerns are raised about the initialization of the CLKCNTR register, with suggestions that without initialization, the reset condition may never be triggered.
  • One participant mentions that they tested the code on an FPGA successfully, which raises questions about the discrepancies between simulation and hardware behavior.
  • Another participant suggests initializing additional registers, like DSPCNTR, to ensure proper simulation behavior.
  • There is a proposal to modify the always block to include a reset condition that would handle both the counter and the reset logic more effectively.

Areas of Agreement / Disagreement

Participants express differing views on the handling of reset conditions and initialization of registers. There is no consensus on the exact cause of the output issue, as some participants believe it relates to initialization while others focus on the reset logic structure.

Contextual Notes

Participants note that simulation behavior may differ from actual hardware implementation, particularly regarding the handling of undefined values (X) in simulation environments. The discussion highlights the need for careful initialization and structuring of reset logic to avoid simulation artifacts.

Who May Find This Useful

This discussion may be useful for individuals working with Verilog code, particularly those involved in designing and testing digital circuits, as well as those interested in understanding the nuances of simulation versus hardware behavior.

polaris90
Messages
45
Reaction score
0
I have a verilog code for a simple 8-bit counter. I'm trying to build a testbench but for some reason it doesn't work. I'm using xilinx and when I run the simulation, the inputs work but the output doesn't work. It stays as XXX. Here is my verilog code and testbench.

Code:
module counter(enable, reset, clk, out, AN, style);

input style; //to count up or down
input clk;
input reset;
input enable;
output [6:0] out; //output to display

reg[3:0] first; //to hold the output for first seven-seg
reg[3:0] second;//to hold the outputfor second seven-seg
reg[24:0] CLKCNTR;  //clock counter
output [3:0] AN;//to indicate which seven-seg to use

	always @(posedge clk)begin//mak it count when the clock ticks
		
		CLKCNTR = CLKCNTR+1;    //increment the clock counter by one until 
		if (CLKCNTR==25000000) //it reaches 25000000
		begin
			CLKCNTR=0;	//reset the counter to loop
			if (reset)		//occurs only when reset is high
			begin
				first=0;		//reset seven segment displasy if 
				second=0;	//reset is high
			end
			
			else if (enable)	
			begin
				if (style)  //if counting up
				begin
					first = first+1;//increment first digit
				
					if(first==10) //if it reaches 10, reset and increment next digit
					begin
						first=0;
				
						second = second+1;	
				
						if(second==6) //if second digit reaches 6(one minute), reset
							second=0;
				
					end	
				end
				
				else if (!style)//if counting down
				begin
					if (first>0)//decrement the first digit unitl it reaches zero
						first=first-1;
					else
					begin
						first=9;
						if (second>0)
							second=second-1;
						else
							second=5;
					end
				end
			end
		 end
	end
	
	//instantiate the display module with the inputs and output
	display D1(.clk(clk), .out(out),.AN1(AN), .ones(first), .tens(second));
	
	
endmodule


module display(clk, out,AN1, ones, tens);


input clk;
output reg[6:0] out;
//output reg[6:0] out2;
input [3:0]ones; //first digit(seven segment display)
input [3:0]tens; //second digit(seven segment display)
output reg [3:0] AN1; //to tell which seven segment display is to be turned on
reg[20:0] DSPCNTR; //display counter

 initial begin
	AN1[3:0] =4'b1011;//initialize the seven-seg displays
	end
	always@(posedge clk) 
	begin
		DSPCNTR = DSPCNTR +1;//increment the counter of display counter until it reaches 25MHz
		if(DSPCNTR == 250000)//that way the seven-segs are refreshed and we are able to see them change
		begin
			DSPCNTR = 0; //reset counter
			
			AN1[2]=~AN1[2];
			AN1[1]=~AN1[1];
			if (AN1[1])
			begin
				case (ones)//case for first digit
						0: out=7'b1000000;
						1: out=7'b1111001;
						2: out=7'b0100100;
						3: out=7'b0110000;
						4: out=7'b0011001;
						5: out=7'b0010010;
						6: out=7'b0000010;
						7: out=7'b1111000;
						8: out=7'b0000000;
						9: out=7'b0010000;
					default: out=7'b1111111;
					endcase
			end
			
		  else if (AN1[2])//case for second digit
			begin
				case (tens)
						0: out=7'b1000000;
						1: out=7'b1111001;
						2: out=7'b0100100;
						3: out=7'b0110000;
						4: out=7'b0011001;
						5: out=7'b0010010;
						6: out=7'b0000010;
						7: out=7'b1111000;
						8: out=7'b0000000;
						9: out=7'b0010000;
					default: out=7'b1111111;
					
				endcase		
			end
		  
		end
	end
	
endmodule

testbench

Code:
module counter_tb;

	// Inputs
	reg enable;
	reg reset;
	reg clk;
	reg style;

	// Outputs
	wire [6:0] out;
	wire [3:0] AN;

	// Instantiate the Unit Under Test (UUT)
	counter uut (
		.enable(enable), 
		.reset(reset), 
		.clk(clk), 
		.out(out), 
		.AN(AN), 
		.style(style)
	);

	initial begin
		// Initialize Inputs
		enable = 0;
		reset = 0;
		clk = 0;
		style = 0;

		// Wait 100 ns for global reset to finish
		#100;
        
		// Add stimulus here
	#3 reset =1;
	#2reset = 0;
	#2 style = 1;
	#2 enable = 1;
	#100 enable = 0;
	#4 reset = 1;
	#4 reset = 0;
	end

always begin
	#1 clk = ~clk;	//clock toggles every strike
end

endmodule

I can't seem to find the reason why the output is no being displayed. I have tested someone else's code and the same happened. Could someone kindly give me a clue on what I'm doing wrong?
 
Last edited:
Engineering news on Phys.org
I think you are not resetting the counter. X + 1 = X

On another note, when you synthesize RTL flops, they should be of the form
// for sync reset
Code:
always @ (posedge clk) begin
   if (reset) begin
      counter <= 0;
      //always reset EVERYTHING in this block here ---- get in the habit
   end else begin
      if (enable) begin
         counter <= counter + 1;
      end
   end
end
//for async reset

Code:
always @ (posedge clk or posedge reset) begin
   if (reset) begin
      counter <= 0;
      //always reset EVERYTHING in this block here ---- get in the habit
   end else begin
      if (enable) begin
         counter <= counter + 1;
      end
   end
end

The separation of the reset block is important in some cases, expecially if you do gate level sims after synthesis. For "normal" synthesis tools you need to follow that structure. Again, get in the habit.
 
I don't think I'm following you completely. If there is a block describing the procedure to be done when reset happens, why do I have to check at the edge of reset?
 
Sorry, maybe I confused you. I showed two different examples, one for sync reset flops and one for async reset flops. In order to map (synthesize) to an async reset flop you need to follow the form of the second example.

The first example is good form for synchromous reset in clocked blocks, but is not mandatory. It is structured that way because reset should be the highest priority. This eliminates problems with X at the beginning of simulation (X propagation) that can happen in gate-level simulations. Sometimes thare are two resets. A power-on reset at the beginning of operation, and a soft-reset that can occur anytime. Sometimes you want them to do different things.

But there is another problem in your design. Simulations begin with all elements set to X.

CLKCNTR starts as X. When you add 1, it is still X. It will always be X. So reset will never be seen.
 
I don't see how the reset would never be seen. I tried initializing CLKCNTR but I get the same result. The compiler doesn't give me any warnings/errors about that. Also. I was able to test my code on an FPGA and it worked perfectly. I don't understand why it wouldn't work with the simulator. Here is a screenshot from the simulator.

I also tried initializing the outputs but they remain with that value all the way through.
 

Attachments

  • Capture.JPG
    Capture.JPG
    27.1 KB · Views: 976
The x problem is a simulation thing, since x doesn't exist in real life. Show the values for all the internal signals.

Try initializing DSPCNTR
 
to expand on what meBigGuy wrote, you never initialize CLKCNTR. It is defined as a register, but it's initial value is never given -- you start incrementing it right after the Always statement, without initializing it first. Your reset block is never seen because the counter never increments from X in the first place -and your if(reset) test only is seen if CLKCNTR==25000000. Like he said, you are better off always starting with an initialization clause within the Always blocks that resets all registers to their initial conditions (he showed two ways of doing this)

I would suggest the following:

always @ (posedge clk)
if (reset || (CLKCNTR==25000000) ) // synchronous reset under either condition...
begin
counter <= 0;
end
else if (reset)
begin
first <=0;
second <=0;
end
else if (enable)
begin
counter <= counter + 1;
end
end //always block
 
Last edited:

Similar threads

  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 1 ·
Replies
1
Views
3K
  • · Replies 1 ·
Replies
1
Views
8K
Replies
2
Views
7K
  • · Replies 1 ·
Replies
1
Views
2K
  • · Replies 1 ·
Replies
1
Views
28K
  • · Replies 1 ·
Replies
1
Views
2K
  • · Replies 3 ·
Replies
3
Views
5K
  • · Replies 13 ·
Replies
13
Views
3K
  • · Replies 6 ·
Replies
6
Views
3K