📄 00071.html
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN">
<html>
<head>
<title>12.4.12 约束守卫者</title>
<meta http-equiv="Content-Type" content="text/html; charset=GB2312" />
<meta name="generator" content="Doc-O-Matic" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<link rel="STYLESHEET" href="default.css" type="text/css" />
<script type="text/javascript" src="scripts.js"></script>
</head>
<body class="Element700" onload="onBodyLoadEx('systemverilog31a.html', 'topic', '00071.html');" onmousedown="onBodyMouseDown();">
<!-- Begin Popups -->
<div class="Element801" id="popup00233">
<div class="Element800">
<div class="Element14">
链接</div>
<div class="Element11">
<div class="Element10">
<a href="00067.html" target="topic">12.4 约束块</a></div>
</div>
</div>
</div>
<!-- End Popups -->
<!-- Begin Page Header -->
<div class="Element710" id="areafixed">
<div class="Element92">
<table width="100%" cellspacing="0" cellpadding="0">
<tr><td width="33%">
<div class="Element1">
<a href="#" onmousedown="showPopup(this, 'popup00233');"><img src="seealsolink.png" border="0" alt="" title=""></a> SystemVerilog 3.1a语言参考手册</div>
</td><td width="34%">
<div class="Element2">
</div>
</td><td width="33%">
<div class="Element90">
<a href="00070.html" target="topic"><img src="btn_prev_lightblue.gif" border="0" alt="Previous" title="Previous" onmouseover="switchImage(this, 'btn_prev_lightblue_hover.gif');" onmouseout="switchImage(this, 'btn_prev_lightblue.gif');"></a><a href="00067.html" target="topic"><img src="btn_up_lightblue.gif" border="0" alt="Up" title="Up" onmouseover="switchImage(this, 'btn_up_lightblue_hover.gif');" onmouseout="switchImage(this, 'btn_up_lightblue.gif');"></a><a href="00080.html" target="topic"><img src="btn_next_lightblue.gif" border="0" alt="Next" title="Next" onmouseover="switchImage(this, 'btn_next_lightblue_hover.gif');" onmouseout="switchImage(this, 'btn_next_lightblue.gif');"></a></div>
</td></tr></table><div class="Element5">
12.4.12 约束守卫者</div>
</div>
</div>
<!-- End Page Header -->
<!-- Begin Client Area -->
<div class="Element720" id="areascroll">
<div class="Element721">
<!-- Begin Page Content -->
<div class="Element58">
<a name="描述"></a><div class="Element11">
<div class="Element10">
<p class="Element10">
约束守卫者是一些判决表达式,它的作用并不是为了求解约束需要满足的逻辑关系,而是作为产生约束的守卫者。这些判决表达式在约束被求解之前计算,并且只能调用下列条目:</p>
<ul class="Element630">
<li class="Element600">常量</li>
<li class="Element600">状态变量</li>
<li class="Element600">对象句柄比较(两个句柄之间比较或者在句柄与常量<span style="color: #FF0000">null</span>之间比较)</li>
</ul><p class="Element10">
除了上面描述的条目外,迭代约束(参见<a href="00077.html" target="topic">12.4.7节</a>)还会将循环变量以及正在被迭代的数组的尺寸当作状态变量。 </p>
<p class="Element10">
</p>
<p class="Element10">
将这些判决表达式作为约束守卫者能够在某些表面上看起来正确的约束上失败,因此也就可以防止求解器产生计算错误。这就使得用户能够编写约束来防止由于无效句柄或越界的数组索引导致的错误。例如,下面的例子实现了一个singlylinked链表(名字为<i>SList</i>),使用它的<i>sort</i>约束能够赋值一个按降序排列的数字随机序列。然而,对于最后一个元素,<i>next<span style="color: #800080">.</span>n</i>会由于无效句柄产生一个计算错误,因此约束表达式会在最后一个元素失败。 </p><div class="Element170">
<a href="#" onclick="CopyElementToClipboard('code00432');">Copy Code</a></div>
<div class="Element13"><div class="Element12" id="code00432"><pre class="Element12"><span style="color: #0000FF">class</span> SList<span style="color: #800080">;</span>
<span style="color: #0000FF">rand int</span> n<span style="color: #800080">;</span>
<span style="color: #0000FF">rand</span> Slist next<span style="color: #800080">;</span>
<span style="color: #0000FF">constraint</span> sort <span style="color: #800080">{</span>n <span style="color: #800080"><</span> next<span style="color: #800080">.</span>n<span style="color: #800080">;}</span>
<span style="color: #0000FF">endclass</span></pre></div></div>
<p class="Element10">
</p>
<p class="Element10">
上面例子中的错误条件可以通过编写一个守卫这个条件的判决表达式来避免: </p><div class="Element170">
<a href="#" onclick="CopyElementToClipboard('code00433');">Copy Code</a></div>
<div class="Element13"><div class="Element12" id="code00433"><pre class="Element12"><span style="color: #0000FF">constraint</span> sort <span style="color: #800080">{</span><span style="color: #0000FF">if</span><span style="color: #800080">(</span>next <span style="color: #800080">!= </span><span style="color: #FF0000">null</span><span style="color: #800080">)</span> n <span style="color: #800080"><</span> next<span style="color: #800080">.</span>n<span style="color: #800080">;}</span></pre></div></div>
<p class="Element10">
</p>
<p class="Element10">
在上面例子中的<i>sort</i>约束中,<span style="color: #0000FF">if</span>会防止在<i>next<span style="color: #800080"></i>==</span><span style="color: #FF0000">null</span>的时候产生一个约束,因此,在这种情况下可以避免访问一个无效对象。无论是蕴含(<span style="color: #800080">-></span>)还是<span style="color: #0000FF">if</span>...<span style="color: #0000FF">else</span>都可以用作约束守卫者。 </p>
<p class="Element10">
</p>
<p class="Element10">
守卫表达式本身可以包含会引起计算错误的子表达式(例如空引用),并且它们还被守卫以免产生错误。通过使用下列的四态表示来计算判决子表达式可以完成这个逻辑转移:</p>
<ul class="Element630">
<li class="Element600">0 FALSE子表达式计算成FALSE</li>
<li class="Element600">1 TRUE子表达式计算成TRUE</li>
<li class="Element600">E ERROR子表达式引起一个计算错误</li>
<li class="Element600">R RANDOM表达式包含随机变量并且不能被计算</li>
</ul><p class="Element10">
判决表达式内的每一个子表达式都会被计算以便产生上述四个值中的一个。子表达式以任意顺序计算,并且计算结果加上逻辑操作以四态表示形式定义了结果。子表达式的联合(<span style="color: #800080">&&</span>)、分离(<span style="color: #800080">||</span>)或非(<span style="color: #800080">!</span>)可以包含某些(或许所有)守卫子表达式。下列规则说明了守卫的结果值:</p>
<ul class="Element630">
<li class="Element600">联合(<span style="color: #800080">&&</span>):如果任意一个子表达式计算成FALSE,那么守卫会被计算成FALSE。另外,如果任意一个子表达式计算成ERROR,那么守卫计算成ERROR,否则计算成TRUE。
<ul class="Element631">
<li class="Element601">如果守卫计算成FALSE,那么约束会被消除。</li>
<li class="Element601">如果守卫计算成TRUE,那么会产生一个约束(可能是有条件的)。</li>
<li class="Element601">如果守卫计算成ERROR,那么会产生一个错误并且随机化会失败。</li>
</ul></li>
<li class="Element600">分离(<span style="color: #800080">||</span>):如果任何一个子表达式计算成TRUE,那么守卫会被计算成TRUE。另外,如果任意个子表达式计算成ERROR的话,那么守卫会被计算成ERROR,否则守卫计算成FALSE。
<ul class="Element631">
<li class="Element601">如果守卫计算成FALSE,那么会产生一个约束(可能是有条件的)。</li>
<li class="Element601">如果守卫计算成TRUE,那么会产生一个无条件的约束。</li>
<li class="Element601">如果守卫计算成ERROR,那么会产生一个错误并且随机化会失败。</li>
</ul></li>
<li class="Element600">非(<span style="color: #800080">!</span>):如果子表达式计算成ERROR,那么守卫计算成ERROR。另外,如果子表达式计算成TRUE或FALSE,那么守卫会被分别计算成FALSE或TRUE。</li>
</ul><p class="Element10">
这些规则可以使用下列的真值表表示: </p>
<p class="Element10">
<img src="12_4_12.png" border="0" alt="" title=""> </p>
<p class="Element10">
</p>
<p class="Element10">
上述规则会被递归地应用直到所有的子表达式被计算。判决表达式的最终值按下列规则确定结果:</p>
<ul class="Element630">
<li class="Element600">如果结果为TRUE,那么会产生一个无条件约束。</li>
<li class="Element600">如果结果为FALSE,那么约束会被消除并且不会产生错误。</li>
<li class="Element600">如果结果为ERROR,那么会产生一个无条件错误并且约束会失败。</li>
<li class="Element600">如果最终的计算结果为RANDOM,那么会产生一个有条件约束。</li>
</ul><p class="Element10">
当最终结果是RANDOM的时候,需要遍历判决表达式树以便收集计算成RANDOM的所有有条件守卫。当最终结果为ERROR的时候,不需要遍历后续的表达式树,这就使得实现时只发布一个错误。 </p>
<p class="Element10">
</p>
<p class="Element10">
例子1: </p><div class="Element170">
<a href="#" onclick="CopyElementToClipboard('code00434');">Copy Code</a></div>
<div class="Element13"><div class="Element12" id="code00434"><pre class="Element12"><span style="color: #0000FF">class</span> D<span style="color: #800080">;</span>
<span style="color: #0000FF">int</span> x<span style="color: #800080">;</span>
<span style="color: #0000FF">endclass</span>
<span style="color: #0000FF">class</span> C<span style="color: #800080">;</span>
<span style="color: #0000FF">rand int</span> x<span style="color: #800080">, </span>y<span style="color: #800080">;</span>
D a<span style="color: #800080">,</span> b<span style="color: #800080">;</span>
<span style="color: #0000FF">constraint</span> c1 <span style="color: #800080">{(</span>x<span style="color: #800080"> < </span>y<span style="color: #800080"> || </span>a<span style="color: #800080">.</span>x<span style="color: #800080"> > </span>b<span style="color: #800080">.</span>x<span style="color: #800080"> || </span>a<span style="color: #800080">.</span>x<span style="color: #800080"> == </span><span style="color: #FF0000">5</span><span style="color: #800080">) -> </span>x<span style="color: #800080">+</span>y<span style="color: #800080"> == </span><span style="color: #FF0000">10</span><span style="color: #800080">;}</span>
<span style="color: #0000FF">endclass</span></pre></div></div>
<p class="Element10">
</p>
<p class="Element10">
在上面的例子中,判决表达式为(x<span style="color: #800080"> < </span>y)、(a<span style="color: #800080">.</span>x<span style="color: #800080"> > </span>b<span style="color: #800080">.</span>x)、以及(a<span style="color: #800080">.</span>x<span style="color: #800080"> == </span><span style="color: #FF0000">5</span>),它们被分离(<span style="color: #800080">||</span>)连接起来。一些可能的情况有:</p>
<ul class="Element630">
<li class="Element600">情况1:a为非空,b为<span style="color: #FF0000">null</span>,a.x为5。</li>
</ul><p class="Element10">
因为(a<span style="color: #800080">.</span>x<span style="color: #800080"> == </span><span style="color: #FF0000">5</span>)为真,所以b.x产生错误的事实不会导致一个错误。 </p>
<p class="Element10">
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -