Reputation: 55
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.
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
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
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