16.1-16.4
1、断言的类别:并发断言(concurrent assertions)和立即断言(immediate assertions)两种。 立即断言与仿真一块使用;并发断言基于时钟语义并使用表达式的采样值。
一个断言能指定系统的行为。断言主要用于验证设计的行为,而且可用于提供功能覆盖,以及对用于验证不符合假设要求的输入激励(input stimulus)进行标记。
断言以要被执行验证函数的断言语句显示,语句会是以下几种:(1)断言(assert);(2)假设(assume);(3)覆盖(cover);(4)限制(restrict) 。
当语句从程序代码中提取出来,立即断言语句是被执行表达式的测试,这个表达式是非暂时的,其说明方法和程序中if语句条件下的表达式相同。如果表达式计算得到x,z,0,就会被认为是错误的,且断言描述会指向失败;否则表达式会被说明为对的,且断言描述通过(等价地,成功)。
2、立即断言有两个模式:简单立即断言(simple immediate assertions)和延时立即断言(deferred immediate assertions)。在简单立即断言中,成功/失败操作在断言计算后立即显示;在延时立即断言中,操作会延迟到时间步之后,为瞬态或“故障”值的意外多次执行提供一定程度的保护。
3、立即断言语句明确规定其表达式必须保持不变,立即断言语句的失败表明违反了要求,设计中有潜在错误。如果断言(assert)语句失败且未指定else分句,则该工具在默认情况下应调用$error,除非使用$assertcontrol with control_type 9(故障关闭)来抑制失败。
4、 立即假设语句(immediate assume statement)指定其表达式被假定为保持。例如,立即假设语句可以和形式验证工具一起使用,以指定设计输入假设,从而约束验证计算。在仿真中,立即假设可以作为立即断言来验证环境是否按照假设的方式运行。
5、立即断言和立即假设语句的动作块(action_block)指明断言成功或失败时采取的行动,和成功相关联的语句是第一个语句,这个语句叫做pass statement,且表达式计算为真则必须执行。pass statement能记录覆盖日志的成功数量,如果pass statement省略了,当立即断言或假定语句的断言表达式为true时,不会执行用户指定的操作。与else关联的语句叫fail statement,如果表达式计算为假(false),fail statement会执行,else语句可以省略。立即断言或假设语句的断言表达式计算后,动作块应立即执行,使用断言操作控制任务可以控制pass and fail statement的执行。
6、立即覆盖语句(immediate cover statement)指明,表达式的计算成功是覆盖目标。工具会收集覆盖信息,并在模拟(仿真)结束时或通过断言API按需报告结果。立即覆盖语句的结果应包含以下内容:(1)评估(计算)次数(Number of times evaluated);(2)成功次数(Number of times succeeded)
立即覆盖的pass and fail statement可以在statement_or_null指明,如果表达式计算为真,pass statement会被执行,立即覆盖表达式计算之后,pass statement应立即执行。
可选语句标签(标识符和冒号)围绕断言语句(或任何其他语句)创建命名块,并且可以使用%m格式规范显示作用域的层次名称。
7、 断言错误的信息可以用下列动作块中严重程度系统任务被打印出来:(1)$fatal;(2)$error;(3)$warning;(4)$info。
严重程度系统任务可用于断言通过或失败语句(pass or fail statement),在pass或fail语句中使用时,这些任务应打印相同的工具特定消息。例如:
assert_f: assert(f) $info("passed"); else $error("failed");
assume_inputs: assume(in_a || in_b) $info("assumption holds");
else $error("assumption does not hold");
cover_a_and_b: cover(in_a && in_b) $info("in_a && in_b==1 covered");
一个形式验证工具可以在assume表示in_a和in_b不同时为0的条件下证明assert_f,cover语句检测in_a和in_b是否同时为1。
如果这些系统任务中有一个以上包含在动作块中,则应按照规定执行每个任务。如果严重程度系统任务在即时断言或假设失败以外的时间执行,则可用编程方式记录立即断言或假设的实际失败时间。例如:
time t;
always@(posedge clk)
if (state==REQ)
assert(req1||req2)
else begin
t=$time;
#5 $error("assert failed at the time %0t",t);
end
如果立即断言在时间10处失败,错误信息应在时间15处被打印,但打印的用户定义字符串将是“在时间10处断言失败”。
失败语句和通过语句是一样的,是所有合法SystemVerilog程序语句,还可以用于向testbench的另一部分发出故障信号。
8、延时断言是立即断言的一种,可用于抑制由于立即断言中组合逻辑的噪声干扰活动导致的错误记录,延时断言和延时立即断言的简写。
延时断言有两种:观察延时立即断言(observed deferred immediate
assertions)和最终立即延时断言(final deferred immediate assertions)。
延时断言和简单立即断言相似,但又有以下主要区别:(1)语法:延时断言使用 #0(对于观察延时断言)或者 final(最终立即延时断言)在验证指令之后。(2)延时:延时记录而不是立即记录;(3)操作块限制:动作块只能包含一个子程序调用;(4)使用外部程序:延时断言可以用作module_common_item。
assert #0 (expression) action_block
assert final (expression) action_block
和所有立即断言一样,延时断言表达式在延时断言语句运行时计算,为了避免发生故障,记录或者动作块安排在当前时间步的稍后时间点。
如果延时断言的动作块中存在pass and fail statement,应由单个字程序调用,这个子程序可以是一个任务(task)、任务方法、void函数,void函数方法,或者系统函数。单个子程序调用要求没有begin-end块围绕pass or fail statement,begin不是子程序调用语句。在最终延时断言情况下,子程序可以在延迟区合法调用。子程序参数可以作为输入按值传递,也可以作为ref或const ref按引用传递,通过值传递的实际参数表达式(包括函数调用),应在延时断言表达式被计算时计算,把自动或动态变量作为实际值传递给ref或const ref会出错的。
观察和最终延迟断言动作块处理的不同点如下所示:(1)对于观察延时断言来说,子程序应被安排在反应区,按引用传递的实际参数表达式,使用或分配反应区基本变量的当前值。(2)对于最终延时断言来说,子程序应被安排在延时区,按引用传递的实际参数表达式,使用延时区基本变量的当前值。
除了延时断言语句,还有延时假设和覆盖语句,在函数中检查组合逻辑情况下,延时断言很有用,但是以一个假设而不是形式化工具使用;A deferred cover is useful to avoid crediting tests for covering a condition that is only met in passing by glitched values.(延时覆盖的,目前不重要,而且这句很拗口。。。。)
IEEE Standard for SystemVerilog—Unified Hardware Design, Specification, and Verification Language (IEEE Std 1800-2012)最近在看这本书,目前没找到比较好的翻译,我自己在百度的帮助下翻译了一部分,写在这里给我自己也给有需要的人参考一下。如有错误,可以在评论区指出!