2016-07-27 55 views
4

下面的代碼的SystemVerilog失敗失敗:在Systemverilog#延遲時,信號的速度比延遲

module test_dly; 
    reg clk = 0; 
    wire w_clk_d; 

    always #1ns clk <= ~clk; 
    assign #1400ps w_clk_d = clk; 
endmodule 

我預計w_clk_d將被推遲CLK的版本,但事實並非如此。 似乎#如果新事件在延遲過期之前到達,則#不工作。 我寫了代碼來處理這個問題,但有沒有辦法讓#工作正常? 謝謝,

回答

4

assign #1400ps w_clk_d = clk;充當延遲和過濾器。當clk更改等待1400ps然後將當前值(非原始值)應用於w_clk_d。如果輸入變化比延遲威脅值丟失更快。物理電路中的延遲單元也可以觀察到類似的行爲。

通過鏈接較小的延遲可以減少過濾;物理延遲單元使用相同的策略。

wire #700ps clk_d = clk; 
assign #700ps w_clk_d = clk_d; 

只未經過濾的延遲可以與傳輸延遲,這樣的clk值時,它切換,則該採樣值適用於w_clk_d 1400ps後者

logic w_clk_d; 
always @* w_clk_d <= #1400ps clk; 

爲了保持分配來實現在調度程序活動區域,則需要額外的代碼

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) 
+0

非常感謝,我不知道過濾。我實現類似於你的示例代碼的延遲,但是你的示例代碼更友好,我將使用它。 –

0

這裏的問題在於連續的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