我正在尝试在英特尔的 Quartus Prime 上编写一个简单的 Verilog 模块和测试平台,并在 Questa FPGA 模拟器上检查它的波形。
代码基本上有一个时钟和一个 4 位计数器。计数器应在时钟的每个正边沿递增,并在达到值 7 时回滚至 0。
模块:
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
测试台
`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
这是我得到的错误波形。
我尝试了不同的编写代码的方法:通过使用
cnt
块设置 initial
的初始值,这也没有帮助,并且在 cnt
变量中为我提供了具有未知值的相同波形。
我期望波形在时钟的每个正边沿显示从 0 到 7 的增量值,然后回绕到零并继续循环。
您将
cnt
声明为 reg
类型,并且该类型在时间 0 默认为未知值 (x
)。在第一个 posedge clk
,模拟器执行 cnt <= cnt + 4'd1
赋值,但是 cnt
保持在x
。这是预期的,因为将 1 添加到未知值会产生未知值。这就是为什么波形总是显示 x
代表 cnt
。
使用
cnt
块设置 initial
的初始值是有效的。这是一种方法:
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
这里有一个演示:EDA Playground
使用上述方法对于仿真来说是没问题的,甚至对于 FPGA 来说也可能没问题。另一种方法 是向您的 TFT_LCD_Driver
模块添加重置输入信号,并在
cnt
块中初始化 always
。