以下systemverilog中的代码失败:
module test_dly;
reg clk = 0;
wire w_clk_d;
always #1ns clk <= ~clk;
assign #1400ps w_clk_d = clk;
endmodule
Run Code Online (Sandbox Code Playgroud)
我预计w_clk_d将是clk的延迟版本,但事实并非如此.似乎#如果新事件在延迟到期之前到达,则#不工作.我编写了代码来处理这个问题,但有没有办法让#按预期工作?谢谢,
assign #1400ps w_clk_d = clk;充当延迟和过滤器.当clk更改等待1400ps然后应用当前值(不是原始值)w_clk_d.如果输入变化快于延迟恐吓值丢失.物理电路中的延迟单元也可以观察到类似的行为.
通过链接较小的延迟可以减少过滤; 物理延迟单元使用相同的策略.
wire #700ps clk_d = clk;
assign #700ps w_clk_d = clk_d;
Run Code Online (Sandbox Code Playgroud)
只有没有滤波的延迟可以通过传输延迟来实现,传输延迟clk对其切换时的值进行采样,然后将采样值应用于w_clk_d1400ps后者
logic w_clk_d;
always @* w_clk_d <= #1400ps clk;
Run Code Online (Sandbox Code Playgroud)
要将分配保留在调度程序活动区域中,则需要额外的代码
logic w_clk_d;
always @(clk) fork
begin
automatic logic sample_clk; // visible only locally with in the fork thread
sample_clk = clk; // local copy of clk
#1400ps;
w_clk_d = sample_clk;
end
join_none // non-blocking, allows detection of next @(clk)
Run Code Online (Sandbox Code Playgroud)
这里的问题是连续assign语句一次只能调度一个活动分配。如果分配的 RHS 变化比连续分配的惯性延迟更快,则 LHS 上的先前分配将被取消或过滤。
您想要的是所谓的传输延迟:RHS 上的每个更改都会传播到 LHS。您可以使用非阻塞赋值 (NBA) 运算符执行此操作。
module test_dly;
reg clk = 0;
wire w_clk_d;
always #1ns clk = ~clk;
always @clk w_clk_d <= #1400ps clk;
endmodule
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9888 次 |
| 最近记录: |