Following code in systemverilog fails:
module test_dly;
reg clk = 0;
wire w_clk_d;
always #1ns clk <= ~clk;
assign #1400ps w_clk_d = clk;
endmodule
I expected that w_clk_d will be delayed version of clk, but it is not. Seems that # not working if new event arrived before delay expired. I wrote code to deal with this, but is there way to make # work as expected? Thanks,
assign #1400ps w_clk_d = clk;
acts as a delay and filter. When clk
changes wait 1400ps then then apply the current value (not original value) to w_clk_d
. If the input changes faster than the delay intimidated values are lost. A similar behavior can also be observed with delay cells in physical circuits.
Filtering can be reduced by chaining smaller delays; the same strategy is used with physical delay cells.
wire #700ps clk_d = clk;
assign #700ps w_clk_d = clk_d;
A delay only without filtering can be achieved with a transport delay, which samples the value of clk
when it toggles, then applies the sampled value to w_clk_d
1400ps latter
logic w_clk_d;
always @* w_clk_d <= #1400ps clk;
To keep the assignment in the schedulers active region then extra code is needed
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With