第10章 递归属性

 

                                             图10.1递归属性-基础

 递归属性只是表明一个条件成立。该属性使用正确的非重叠蕴涵运算符调用它自己,并纠正左侧表达式和右侧表达式关系。如图10.1(顶部属性rc1)所示,如果ra为真,并且在下一个时钟rc1(ra)为真,则rc1应该在其自身上重现。请注意,rc1中的先行词(|=>左边表达式)是1'b1,这意味着先行词总是真。这允许一个容易和正确的‘and’表达先行/后果的含义。还要注意,您必须在递归属性中使用非重叠的运算符。

图10.1中的最顶层的例子(baseP:assert property(@(posedge clk)$ fell(rst_)|  - > rc1(bStrap))else gotoFail;)指定$ fall(rst_)为true时,调用后续的rc1(bStrap)。‘rc1’属性将bStrap作为输入,并将输入和(1'b1 | => rc1(ra))执行‘and’。这意味着暗示1'b1总是正确的,并且rc1(ra)将在clk的每个posedge上被调用以自身重复出现。该属性将继续进入自身循环,直到bStrap采样为0.在这种情况下,‘and’将失败,属性也会失败。换句话说,我们已经检查过在$fell(rst_)之后,‘bStrap’(bootstrap信号)不会被取消断言(即变为低)。

注意:如果使用重叠运算符,属性将会重新出现本身在零时间内,基本上将仿真器陷入零延迟循环,导致仿真挂起。

但是,图10.1中的属性真的有什么用处吗?它会检查信号永久保存。你如何将这样的模型应用于现实世界?你真正需要检查的是一个条件成立,直到另一个条件成立。如果发生这种情况,该属性通过,否则失败。现在更实际了。让我们用下面的例子来理解这一点。

 10.1 应用程序:递归属性

 如图10.2所示,对于或条件,递归属性变得有用。规范说,我们需要确保intr为真,直到iack被声明。让我们看看这是如何工作的。属性rc1表示iack为真或者intr为真,该属性递归地调用rc1。现在,如果中断到达之前和之后,(intr和(true | => rc1(intr,iack)))将失败,因为这里有一个intr的‘and’。另一方面,如果首先到达,则‘iack或...’条件将通过,因为这是一个OR。换句话说,我们是递归的‘intr’,看看它在iack到达之前是否成立。

在仿真日志中的时刻55,iack = 1和intr = 0。由于intr等于前一个钟的1,所以它一直保持直到iack到达。因此,该属性通过。另一方面,在105时刻,在iack变为1之前,intr变为0。换句话说,在iack到达并且属性失败之前,intr没有保持自己。图10.3显示了另一个有趣的应用。

 

                                                图10.2 递归属性 - 应用

 

                                                   图10.3递归属性 - 应用

 该属性的规范读取missAlloc的检测结果,可以看到wdataH一直保持到readC为true。在图10.3中,属性s_rc1检查是否看到misAlloc是真的,然后触发rc1。属性rc1反过来保持为真(即递归)直到readC为真。如果在readC变为高电平之前wdataH变为低电平,则属性(以及整个断言)将失败(因为wdataH是序列rc1中‘与’条件的LHS),如果readC在wdataH之前到达,则序列rc1中的or条件通过,断言会通过。

这样我们确保了wdataH一直保持到readC完成,如果这一点起初不是很明显,请参考图10.2来理解‘property rc1’如何工作。

注意我们正在通过传递整个序列missAlloc作为一个实际的属性s_rc1的形参genericSeq,这是一个非常有用的方法,用一个序列作为一个实际的序列来形式化。

进一步的细微差别在图10.4中用注释来描述。

 

                                     图10.4递归属性 - 进一步细微化I

 图10.5显示递归属性中禁用‘disable iff’。然而,这个问题有一个简单的解决方案,它在图的底部显示。分开‘disable iff’的要求和两个属性中属性的递归性质。递归属性不包含‘disable iff’,属性rillegal在‘disable iff’条件时禁用rLegal。

 

                                        图10.5递归属性 - 进一步的细微差别II

 

                                            图10.6递归属性 - 相互递归

 图10.6显示了两个递归属性确实可以相互递归。 cPhase2调用cPhase1和cPhase1依次调用cPhase2。为什么这不会在零延迟循环中结束?首先,由于两个属性中的非重叠运算符有1个时钟等待。其次,每个属性都有先行词(|->左侧表达式),属性只有在先行词为真的情况下才会执行。所以,如果cPhase2调用cPhase1,那么cPhase1将首先等待c为true,然后触发属性的递归部分。当cPhase1调用cPhase2时会发生同样的情况。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值