返回介绍

12.4.11 约束中的函数

发布于 2020-09-09 22:55:50 字数 1697 浏览 983 评论 0 收藏 0

某些特性很难或不可能在单一的表达式中表达。例如,在计算一个压缩数组中1的数目的时候,最普通的方法是使用一个循环语句:

function int count_ones (bit [9:0] w);
    for(count_ones=0; w!=0; w=w>>1)
        count_ones += w & 1'b1;
endfunction

这样的一个函数可以用来约束其它随机变量中1的数目:

constraint C1 {length == count_ones(v);}

如果没有调用函数的能力,那么这个约束需要将循环展开并将它表示成一个单独位的和:

constraint C2
{
    length == ((v>>9)&1) + ((v>>8)&1) + ((v>>7)&1) + ((v>>6)&1) + ((v>>5)&1) +
        ((v>>4)&1) + ((v>>3)&1) + ((v>>2)&1) + ((v>>1)&1) + ((v>>0)&1);
}

count_ones函数不同,一些更为复杂的特性需要使用临时状态或使用庞大的循环,因此它不可能转换成一个单独的表达式。因此,调用函数的能力增强了约束语言的表达能力并减少了出错的可能性。注意,上面的两个约束并不是完全等价的;C2是双向的(length可以约束v,反之亦然),而C1则不是。

为了处理这些基本情况,SystemVerilog允许约束表达式包含函数调用,但在语义上它强加了某些限制。

  • 出现在约束表达式中的函数不能包含output或ref参数(但允许使用const ref参数)。
  • 出现在约束表达式中的函数不应该是自动的(或者不应该没保存状态信息)并且不应该有边带效应。
  • 出现在约束表达式中的函数不能修改约束,例如调用rand_mode或constraint_mode方法。
  • 函数应该在约束被求解之前调用,并且它们的返回值应该被当作状态变量。
  • 作为函数参数使用的随机变量应该建立一个隐含的变量排序或优先级。仅包含具有较高优先级的变量会被首先求解,然后才是具有较低优先级的变量。被求解成一个较高优先级约束集合一部分的随机变量在余下的约束集合中变成状态变量。例如:
class B;
    rand int x, y;
    constraint C {x <= F(y);}
    constraint D {y inside {2, 4, 8};}
endclass

上面的例子强制yx之前求解。因此,约束D在约束C之前被独立地求解,而约束C使用yF(y)的值作为状态变量。注意:由函数参数隐含的变量排序的行为不同于使用“solve...before...”约束说明的变量排序;函数参数变量排序可以细分求解空间,因此也就会对它改变。由于较高优先级变量上的约束在求解的时候根本不考虑低优先级的约束,所以这种细分会导致整个约束失败。在每一个具有优先级的约束集合中,循环(randc)变量被首先求解。

  • 由隐含变量排序所产生的循环依赖性会导致一个错误。
  • 活跃约束中的函数调用执行的次数未被指定(至少一次),并且执行次序也是未指定的。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文