【问题标题】:Unexpected result of verilog dflipflop codeverilog d'flip flop 代码的意外结果
【发布时间】:2018-07-14 13:19:44
【问题描述】:

对于下面的 verilog dff 示例输出最后显示(仅显示前两行)。我无法理解为什么总是在零时间执行块,而我已经写了 always@(posedge clk)。 posedge clk 没有在零时间发生。你能帮我理解输出吗?

module main;
reg d,clk;
wire q;

always #5 clk++;
always #10 d++;

dff dff(d,clk,q);  

initial 
begin
d = 1;
clk = 1;
$monitor("time = %d d = %d clk = %d q = %d",$time,d,clk,q);
#50 $finish ;
end
endmodule

module dff(input wire d,clk, output reg q);
always @(posedge clk)
begin
q = d;
$display("time = %d inside module dff",$time);
end
endmodule

Output is
time =                    0 inside module dff
time =                    0 d = 1 clk = 1 q = 1
...

【问题讨论】:

    标签: verilog


    【解决方案1】:

    在编写顺序逻辑时使用非阻塞分配 (q<=d;)。非阻塞分配将分配 NBA 区域的 LHS,我们可以观察到 LHS 和 RHS 之间的时钟延迟。

    有关非阻塞分配用法的更多信息,请参阅this paper

    always 块在时间0 执行而言,有一个clk 在时间0 时从x1 的转换(来自initial 块)。结果,模拟器将其视为上升沿。注意reg的默认值是x

    我们可以根据需要在 Verilog/SV 中制作不同类型的时钟发生器。有关不同类型时钟发生器的示例,请参阅Cummings paper

    【讨论】:

    • 即使我使用非阻塞赋值,我也会得到相同的输出。在我的模拟器中,reg 的默认值为 x。将 x -> 1 转换视为 posedge 是否有效?
    • 如果有效,您可以讨论同意或不同意,但这是标准行为。
    • @Ranju,在initial 块中设置clk=0; 以避免time-0 事件。此外,根据 Verilog/SV 标准,posedge 应在从 0 到 x、z 或 1 以及从 x 或 z 到 1 的转换时检测到
    猜你喜欢
    • 1970-01-01
    • 2016-06-14
    • 2015-10-31
    • 1970-01-01
    • 2017-10-17
    • 2016-08-13
    • 2013-10-15
    • 1970-01-01
    • 2012-04-20
    相关资源
    最近更新 更多