2016-06-25 82 views
2

假設我們有一個協議,其中請求req被認定爲req_id並且對應的rsp將被認定爲rsp_id。這些可能無序。我想覆蓋req與特定req_idrsp之間的時間間隔或等待時間的數目與相同的ID。我嘗試過這樣的事情。這是正確的做法嗎?有沒有其他有效的方法?如何覆蓋請求和響應之間的延遲

covergroup cg with function sample(int a); 
    coverpoint a { 
    a1: bins short_latency = {[0:10]}; 
    a2: bins med_latency = {[11:100]}; 
    a3: bins long_latency = {[101:1000]}; 
    } 
endgroup 
// Somewhere in code 
cg cg_inst = new(); 

sequence s; 
    int lat; 
    int id; 
    @(posedge clk) disable iff (~rst) 
    (req, id = req_id, lat = 0) |-> ##[1:$] ((1'b1, lat++) and (rsp && rsp_id == id, cg_inst.sample(lat))); 
endsequence 
+0

**沒有工作**意味着什麼?編譯器錯誤?沒有覆蓋?請提供一個測試用例。 –

+0

我很抱歉。我想知道這是否是正確的做法?這會覆蓋我的延遲嗎? – user1978273

回答

1

你試圖使用|->操作的順序,這是隻允許一個屬性內裏:[$ 1],## 1等可以改變。

如果rspreq後只能得出一個週期,那麼這段代碼應該工作:

property trans; 
    int lat, id; 

    (req, id = req_id, lat = 0) |=> (1, lat++) [*0:$] ##1 rsp && rsp_id == id 
     ##0 (1, $display("lat = %0d", lat)); 
endproperty 

##0後的元素是存在的調試。您可以在生產代碼中省略它。

但是,我不會混合這樣的斷言和覆蓋,因爲我已經看到蘊含運算符可能導致變量流問題(即lat不會得到正確更新)。你應該有,只是覆蓋了你見過請求後匹配響應特性是:我用##1分離從響應請求

property cov_trans; 
    int lat, id; 

    (req, id = req_id, lat = 0) ##1 (1, lat++) [*0:$] ##1 rsp && rsp_id == id 
     ##0 (1, $display("cov_lat = %0d", lat)); 
endproperty 

cover property (cov_trans); 

通知。

0

基本上你的想法是正確的,不過貌似序列的右側,當條件爲真,因此LAT將僅遞增一次,將評估一次。

您將需要一個循環機制來計算延遲。

下面是一個示例工作示例。基於這些信號是如何產生的近

property ps; 
    int lat; 
    int id; 
    @(posedge clk) 
    disable iff (~rst) 
     (req, id = req_id, lat = 0) |=> (1'b1, lat++)[*1:$] ##1 (rsp && rsp_id == id, cg_inst.sample(lat)); 
endproperty 

assert property (ps); 
+0

@RahulMnenon您的代碼將錯過響應請求後立即響應(即零延遲)的情況,因爲您至少需要一個增量循環。 –

0

或者......

財產/序列,雖然它們看起來是小碼,在這種情況下,每REQ(還未收到RSP)有自己的櫃檯一個單獨的進程分叉。這導致許多計數器做了非常類似的工作。如果有很多req在飛行中(和/或屬性或序列的許多實例),它將開始添加到模擬運行時間[儘管這只是一小塊代碼]

所以另一種方法是保持觸發器更簡單,我們嘗試保持處理線性。

int counter=0; // you can use a larger variablesize to avoid the roll-over issue 
int arr1[int] ; // can use array[MAX_SIZE] if you know the max request id is small 
always @(posedge clk) counter <= counter + 1 ; // simple counter 


function int latency (int type_set_get , int a) ; 
    if (type_set_get == 0) arr1[a] = counter; // set 
           //DEBUG $display(" req id %d latency %d",a,counter-arr1[a]); 
           // for roll-over - if (arr1[a] > counter) return (MAX_VAL_SIZE - arr1[a] + counter) ; 
    return (counter - arr1[a]); //return the difference between captured clock and current clock . 
endfunction 

property ps(); 
    @(posedge clk) 
    disable iff (~rst) 
     ##[0:$]((req,latency(0,req_id)) or (rsp,cg_inst.sample(latency(1,rsp_id)))); 
endproperty 

assert property (ps); 

上述屬性僅在看到req/rsp時觸發,只有1個線程處於活動狀態才能查找。 如果需要額外的檢查可以添加到該功能,但對於延遲計數這應該沒問題。

軼事:

導師AE - 旦發現這是由高達40%減緩我們的模擬斷言。寫得不好的斷言是我們塊tb的一部分,其影響在那裏未被注意到,因爲我們的塊級測試,運行時間有限。然後它潛入我們的頂級tb中,造成無數的運行時間損失,直到它在一年後被發現爲止。 [猜猜我們應該早些時候描述我們的模擬運行]

例如,如果上述協議在稍後實施中止,則req-rsp線程將繼續處理並等待(直到模擬結束)異常終止的事務雖然不會影響功能,但它會偷偷地繼續處理處理器資源,無用回報。直到最後一個供應商AE步驟保存一天:)