Testing Verilog Code - Find Reason Output Not Displayed

In summary, the conversation discusses a verilog code for a simple 8-bit counter and a testbench. The code uses xilinx and has inputs for style, enable, reset, and clk. The output is a 7-bit number displayed on two seven-segment displays. The conversation also mentions an issue with the output not being displayed and suggests initializing the counter and other internal signals.
  • #1
polaris90
45
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
  • #2
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.
 
  • #3
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?
 
  • #4
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.
 
  • #5
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: 915
  • #6
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
 
  • #7
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:

FAQ: Testing Verilog Code - Find Reason Output Not Displayed

Why is my Verilog code not displaying the expected output?

There could be several reasons for this. One possibility is that there is an error in your code that is causing it to not function properly. Another possibility is that the inputs or stimuli being used in your testbench are not correct. It is also possible that there is an issue with your simulation tool. It is important to carefully check your code and testbench, and also make sure you are using the correct version of your simulation tool.

How do I troubleshoot my Verilog code to find the reason for the output not being displayed?

The first step is to carefully review your code and make sure there are no syntax errors or logical errors that could be causing the issue. You can also use debugging tools provided by your simulation tool to step through your code and see where the problem may be occurring. Additionally, it can be helpful to use print statements in your code to track the values of different signals and variables throughout the simulation.

Is there a specific method or process for testing Verilog code?

While there is no one set method for testing Verilog code, there are some common practices that can help ensure your code is thoroughly tested. These include writing testbenches with a variety of input values, using print statements for debugging, and using assertions to check for expected outputs. It is also important to simulate your code with different simulation tools to ensure it functions correctly in different environments.

Can I use automated tools for testing my Verilog code?

Yes, there are several automated tools available for testing Verilog code. These tools can help with tasks such as generating testbenches, checking for code coverage, and identifying errors in code. However, it is still important to manually review and test your code to ensure it is functioning as expected.

How can I improve the testing process for my Verilog code?

There are a few ways to improve the testing process for Verilog code. One is to use a test-driven development approach, where tests are written before the code is written. This can help identify any potential issues early on. Additionally, using code coverage tools can help ensure that all parts of your code are being tested. Finally, regularly reviewing and updating your testbenches and test cases can help catch any errors that may have been missed previously.

Similar threads

Replies
2
Views
2K
Replies
1
Views
8K
Replies
1
Views
1K
Replies
2
Views
27K
Replies
1
Views
2K
Replies
1
Views
4K
Replies
3
Views
4K
Replies
13
Views
1K
Back
Top