假设我们有一个协议,其中请求req
与req_id
断言,相应的rsp
将与rsp_id
断言。这些可能是乱序的。我想要涵盖具有相同ID的req
与特定req_id
和rsp
之间的clks数或延迟。我试过这样的事。这是正确的做法吗?还有其他有效的方法吗?
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 :(得分:2)
您尝试在序列中使用|->
运算符,该运算符只允许在属性中使用。
如果rsp
只能在req
后一个周期出现,那么此代码应该有效:
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
无法正确更新)。您应该拥有一个仅涵盖您在请求后看到匹配响应的属性:
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);
请注意,我已使用##1
将请求与响应分开。
答案 1 :(得分:0)
基本上你的想法是正确的,但看起来当条件为真时,序列的右侧将被评估一次,因此lat只会增加一次。
您需要一个循环机制来计算延迟。
以下是一个示例工作示例。您可以根据信号的生成距离更改[1:$],## 1等
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);
答案 2 :(得分: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个线程处于活动状态时才会触发上述属性。 如果需要,可以在函数中添加额外的检查,但是对于延迟计数,这应该没问题。
轶事:
Mentor AE - Dan发现了一个断言,它使我们的模拟速度降低了40%。写得不好的断言是我们块tb的一部分,它的影响在那里没有引起注意,因为我们的块级测试,运行时间有限。它然后潜入我们的顶级tb导致无法解决的运行时损失,直到一年后发现:)。 [猜测我们应该早点描述我们的模拟运行]
例如,如果上述协议在以后实现了中止,那么req-rsp线程将继续处理并等待(直到模拟结束)中止事务,尽管它不会影响功能,它将偷偷地继续占用处理器资源,做任何有用的回报。直到最后供应商AE介入以节省一天:)