簡體   English   中英

采樣和驅動信號的 SV/Verilog 時序

[英]SV/Verilog timing of sampling and driving signals

我有一個類驅動程序(用 UVM 編碼)和一個模塊 sampler_n_dummy_gnt 如下(為本問題的目的而簡化):

class driver extends uvm_driver #(bus_trans);
    ...
    task run_phase();
        forever begin
            seq_item_port.get_next_item(bus_trans_h);
            drive_item(bus_trans_h);
            ...
        end
    ...
    endtask

    task drive_item();
        vif.sel = 1;
        vif.req = 0;
        @(posedge vif.clk);
        vif.req = 1;
        // #1; // this delay needed to prolong req for 1 clock
        if (vif.gnt == 1)
            @(posedge vif.clk);
        else begin
            while (vif.gnt == 0)
                @(posedge vif.clk);
            end
        end
        vif.req = 0;
    endtask
endclass
module sampler_n_dummy_gnt;
    logic clk, rstn;
    int rdelay;

    bus_interface vif(clk, rstn);

    always #10ns clk = ~clk;

    always @(posedge vif.req) begin
        rdelay = $urandom_range(0,5);
        if (rdelay != 0) begin
          for (int i=0; i<rdelay; i=i+1) begin
            vif.gnt = 0;
            @(posedge vif.clk);
          end
        end
        vif.gnt = 1;
    end
endmodule

基本上,驅動程序模擬一個協議,該協議指定它應該在有新事務時斷言sel 一個周期后,它應該斷言req 然后它一直等到gnt為高電平,並且僅在一個周期后取消斷言req

采樣器等待req的斷言,並根據隨機生成的數字在斷言gnt之前等待一定數量的時鍾周期。 所以要么沒有延遲,要么有一些延遲,最多 5 個周期。

在我遇到第二筆交易之前,第一筆交易還可以。 在時鍾 7 的位置, gnt被取消斷言,因此req應該保持高電平,直到它在時鍾 8 看到gnt斷言。但是,從時鍾 7 開始,我再也沒有看到req斷言(即它保持為 0)。 我懷疑在時鍾 7 的位置,它看到gnt = 1但跳過了if-else條件並直接驅動req = 0 所以我必須添加我在上面評論過的那一行,以獲得預期的場景。 有人可以幫助解釋為什么需要延遲嗎?

                (Expected)                               (Actual)
        1   2   3   4   5   6   7   8          1   2   3   4   5   6   7   8
       _   _   _   _   _   _   _   _          _   _   _   _   _   _   _   _  
clk  _| |_| |_| |_| |_| |_| |_| |_| |_      _| |_| |_| |_| |_| |_| |_| |_| |_
       _______________     ___________        _______________     ___________
sel  _|               |___|                 _|               |___|
           ___________         _______            ___________         
req  _____|           |_______|             _____|           |_______________   
                   ___________     ___                    ___________     ___
gnt  _____________|           |___|         _____________|           |___|

我假設clkvif.clkvif.pclk實際上都是相同的信號。

您的代碼在處理同步信號方面存在許多問題。

  • 除非您正在處理異步邏輯,否則您應該只使用一個時鍾邊沿事件,而不是另一個信號的邊沿。
  • 對同步信號進行賦值時,始終使用非阻塞賦值<=
  • 確保對任務的第一次調用與時鍾沿同步

由於您沒有發布完整的代碼,我只能提出這個建議

class driver extends uvm_driver #(bus_trans);
    ...
    task run_phase();
       @(posedge vif.clk; // initial sync
       forever begin
            while (!seq_item_port.try_next_item(bus_trans_h)
               @(posedge vif.clk;
            drive_item(bus_trans_h);
            ...
        end
    ...
    endtask

    task drive_item();
        vif.sel <= 1;
        vif.req <= 0;
        @(posedge vif.clk);
        vif.req <= 1;
        @(posedge vif.clk iff vif.gnt);
        vif.req <= 0;
    endtask
endclass

從 SystemVerilog (SV) 類域采樣和驅動同步數據可能會出現問題。 在接口內部使用 SV 時鍾塊是標准解決方案。 使用時鍾模塊需要了解時鍾模塊、時鍾驅動分配和時鍾事件。 它還需要從界面的角度來理解輸入和輸出的感覺。 我列出的論文顯示了使用時鍾模塊時犯的一些經典錯誤(不要“繞過”CB。

為了幫助理解:

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM