Variable does not update in module

I'm trying to write a simple Verilog module and a testbench for it on intel's Quartus Prime and checkout it's waveform on Questa FPGA simulator.

The code basically has a clock and a 4-bit counter. The counter should increment at every positive edge of the clock and wrap back to 0 when it reaches the value of 7.

Module:

module TFT_LCD_Driver(  
    input clk,
    output reg [3:0] cnt    
);


always @(posedge clk) begin
        if (cnt == 4'd7)
            cnt <= 0;
        else
        cnt <= cnt + 4'd1;
end

endmodule

Testbench

`define clk_period 20

module TFT_LCD_Driver_tb();

    reg clk;
    wire [3:0] cnt;
    
    TFT_LCD_Driver tft(
        .clk(clk),
        .cnt(cnt)
    );
    
    
    initial begin
        clk = 1'b1;
    end
    
    always #(`clk_period/2) clk = ~clk;

endmodule

This is the wrong wave form that I am getting.

Wrong wave form

I tried different ways of writing the code: by setting the initial value of cnt using an initial block that also did not help and gave me the same waveform with unknown values in the cnt variable.

I am expecting the waveform to show incremental values from 0 to 7 at each positive edge of the clock and then wrap back to zero and continue the cycle.

Upvotes: 1

Views: 62

Answers (1)

toolic
toolic

Reputation: 62105

You declared cnt as a reg type, and that type defaults to the unknown value (x) at time 0. At the 1st posedge clk, the simulator executes the cnt <= cnt + 4'd1 assignment, but cnt remains at x. This is expected since adding 1 to an unknown value results in an unknown value. This is why the waveforms always show x for cnt.

Setting the initial value of cnt using an initial block works. Here is one way to do it:

module TFT_LCD_Driver(  
    input clk,
    output reg [3:0] cnt    
);

initial cnt = 0;

always @(posedge clk) begin
        if (cnt == 4'd7)
            cnt <= 0;
        else
        cnt <= cnt + 4'd1;
end
endmodule

enter image description here

Here is a demonstration on: EDA Playground


Using the above approach is fine for simulation, and it may even be fine for an FPGA. Another approach is to add a reset input signal to your TFT_LCD_Driver module and initialize cnt in the always block.

Upvotes: 0

Related Questions