SVA假设/断言连续数据输入

时间:2016-07-22 07:18:02

标签: system-verilog assertions formal-verification system-verilog-assertions

我是一个基于断言的验证新手,试图了解它应该如何正确完成。我已经找到了很多关于systemverilog +断言的结构和技术细节的信息,但是我还没有找到一些" cookbook"关于事物在现实世界中如何真正完成的材料。

问题和限制:

  • Design具有带数据,有效 id 输入的数据输入总线
  • 一个数据"包"是3个样本
  • 在频道 n 之后,始终会有来自频道 n + 1 的数据
    • 通道ID将在发送最大ID后进行换行
  • 数据字节之间可以有任意数量的clk标记
  • 下面是一个简单且有希望正确的时序图,其中包含频道ID:

    enter image description here

那你怎么用最少量的代码来做这件事呢?很干净。以前我已经构建了虚拟verilog模块来驱动数据。但是肯定可以使用一些假设属性来限制通道ID,但是否则可以让正式工具自由地试图制动我的设计?

初学者的简单模板可能是:

data_in : assume property (
  <data with some ID>[=3]
  |=>
  <data with the next id after any clk tick>
);

我想问题是上面的假设/断言倾向于触发每个数据样本并创建在时间上重叠的并行线程。

4 个答案:

答案 0 :(得分:2)

相信你在谈论形式验证方法论。

  

对于形式验证,您无需构建任何驱动模块   刺激。但相反,刺激将由该工具驱动   本身,您可以使用假设属性来指导工具   产生法律刺激。

如果您不提供任何假设,那么工具可以驱动任何随机数据并评估断言,在这种情况下,您可能会得到错误的伪造。此方案称为“Under Constraint”

同样,如果您提供了太多假设,那么您可能会错过一些合法的输入组合。此方案称为“Over Constraint”

因此,提供准确的假设非常重要。

对于您的情况,您的假设可能有点像这样:

property channel_change;
  // To check the next consecutive ID, after data transfer
  @(posedge clk)
  (id) throughout (valid [=3]) |=> valid && (id == $past(id) + 1)
endproperty

assume property (channel_change);

有关形式验证方法的更多详细信息,请访问我的博客:What is Formal Verification? [1/2]&amp; What is Formal Verification? [2/2]

答案 1 :(得分:1)

您提供的示例不重叠。在具有相同ID的三个样本之后,一旦具有下一个ID的另一个数据样本到来,结果将匹配并且整个属性将保持。

重叠尝试无论如何都是生活中的事实。工具总是在每个时钟周期中评估(声明或假设)属性,以确定是否可以匹配。如果它确定它是,那么它开始一个新的尝试;如果没有,它继续前进。没有办法说“当它已经被尝试时,不要试图考虑这个断言”,因为你永远不知道一次尝试是否会在比赛中结束。

当看到像你画的那样的波浪时,很明显你不需要在三个样本中评估属性,但这仅仅是因为你可以看到整个画面。这类似于能够展望未来的工具。

继续讨论你的具体问题,你的约束并没有说明整个故事。它仅表明,一旦具有相同ID的3个样本到来,下一个样本的ID应该递增。这里没有任何说明样本必须包含3个包。你需要这样的东西:

assume property (
  sample_with_some_id_came |->
    came_out_of_reset_and_no_samples_were_sent.triggered or
      one_or_two_samples_with_same_id_sent_after_reset.triggered or
      three_samples_with_the_previous_id_sent.triggered
);

我也不确定你的假设是否会导致某种“无休止”的行为,因为你说在具有相同ID的3个样本之后必须总是有下一个样本。

答案 2 :(得分:1)

我将定义三个sequence以在下一个有效的same_id)上检测相同的ID;检测下一个有效(id)的change_id更改;并检测有效数据包(packet_id)。 然后我可以在四个valid内监控一个属性,只有三种可能的情况:即

case1: (id, id,   id,   id+1) OR 
case2: (id, id+1, id+1, id+1) OR
case3: (id, id,   id+1, id+1) 

请参阅下面的代码。我还没有测试过,这只是出于我的想法。希望它能奏效。 好的是property只能持续4个时钟滴答,而且在每个时钟滴答中,只有一个线程。所以我们可以避免线程爆炸。

// To detect same id within two non-consecutive valid,
// (a,a)
sequence same_id;
  int prev_id;
  @(posedge clk)
  valid, prev_id=id ##1 valid[=1] ##0 id==prev_id;
endsequence


// To detect valid packet
// (a,a,a)
sequence packet_id;
  int prev_id;
  @(posedge clk)
  same_id, prev_id=id ##1 valid[=1] ##0 id==prev_id;
endsequence   

// To detect any change of ID
// any (a,b)
sequence change_id;
  int prev_id;
  @(posedge clk)
  valid, prev_id=id ##1 valid[=1] ##0 id==prev_id+1;
endsequence

// Put all together, in any four non-consecutive valid, there are only three cases: a,b,b,b OR b,b,b,c OR a,a,b,b
property next_id;
  int prev_id;
  @(posedge clk)
  (change_id ##0 packet_id) or         // a,b,b,b
  (packet_id ##0 change_id) or         // b,b,b,c
  (same_id ##0 change_id ##0 same_id); // a,a,b,b
endproperty

答案 3 :(得分:0)

assume property (@ (posedge clk) disable iff (rst) ((valid[->2] ##0 id != $past(id,,valid)) or ($fell(rst) ##0 valid[->1])) |=> (valid[->1] ##0 id == $past(id,,valid))[*2] ##1 valid[->1] ##0 (id == $past(id,,valid) + 2'd1));

打破它: 隐含的先决条件是两次有效都发生了,并且当前id在时间段内有效完成两次变高([->]而不是[=]),与上一次有效变高的id不同:

((valid[->2] ##0 id != $past(id,,valid))

或有效值在第一笔交易后立即升高:

($fell(rst) ##0 valid[->1])

隐含的结果(在先行匹配| =>之后一个时钟开始)以有效的高电平两次匹配和id ==先前的id(有效有效)匹配开始。必须匹配两次[*]。

(valid[->1] ##0 id == $past(id,,valid))[*2]

并在下一个周期结束时,有效点在某个时候变高,并且当它这样做时,id必须等于先前的id(有效时为高)+1。

##1 valid[->1] ##0 (id == $past(id,,valid) + 2'd1))

这个假设允许id在有效值低时更改-但仍然要求id在3个有效高电平周期中都相同。

如果希望id在整个有效时间内保持稳定,则可以使用以下方法:

assume property (@ (posedge clk) disable iff (rst) ((valid[->2] ##0 id != $past(id,,valid)) or ($fell(rst) ##0 valid[->1])) |=> ($stable(id) throughout valid[->2]) ##1 valid[->1] ##0 (id == $past(id,,valid) + 2'd1));