【发布时间】:2022-01-21 16:40:59
【问题描述】:
我用预设功能实现了一个非常简单的计数器(代码复制如下)。
module counter
#(
parameter mod = 4
) (
input wire clk,
input wire rst,
input wire pst,
input wire en,
input wire [mod - 1:0] data,
output reg [mod - 1:0] out,
output reg rco
);
parameter max = (2 ** mod) - 1;
always @* begin
if(out == max) begin
rco = 1;
end else begin
rco = 0;
end
end
always @(posedge clk) begin
if(rst) begin
out <= 0;
end else if(pst) begin
out <= data;
end else if(en) begin
out <= out + 1;
end else begin
out <= out;
end
end
endmodule
我无法理解以下模拟结果。在时钟上升沿断言pst 且data 设置为7 时,计数器的out 设置为data,正如预期的那样(下面的第一张图片。out 是最后一个信号,data 是信号就在上面,上面是pst.)。在下一个上升沿,我保持预设置位并将data 设置为0。但是,out 这次没有跟随data。这种行为的原因是什么?
我的想法
在我将data 设置为0 的时钟上升沿,我注意到out 保持在7,并且不会增加到8。所以我相信计数器正在预设,但值为7,不是 0。如果我及时将 data 转换从 7 移动到 0,out 会按预期设置为 0(下图)。我遇到了竞态条件吗?
测试台
我生成第一张图片的初始测试台代码如下所示。我以 cmets 的形式展示了我为获得连贯结果所做的更改。
parameter mod = 4;
// ...
reg pst;
reg [mod - 1:0] data;
// ...
@(posedge clk); // ==> @(negedge clk)
data = 7;
pst = 1;
@(posedge clk); // ==> @(negedge clk)
data 0;
pst = 1;
@(posedge clk); // ==> @(negedge clk)
pst = 0;
@(posedge clk);
// ...
【问题讨论】:
-
显然在第二个时钟沿
data仍然是 7 并且仅在 时钟沿之后变为 0。 -
@mkrieger1 看起来确实如此。但是,为什么第一个预设周期在时钟上升沿看到
data为 7 而不是 0(在那之前data为 0)? -
因为在第一个时钟边沿
data显然已经是 7。 -
@mkrieger1 我试图理解为什么从一个时钟沿到下一个时钟沿的行为不同。在我的测试平台中,我只是这样做:
data = 7; @(posedge clk); data = 0; @(posedge clk)来获取第一张图片。 -
好的。我不知道它为什么会这样。
标签: verilog