IEEE Standard for SystemVerilog Unified Hardware Design 断言翻译笔记(1)

430 阅读5分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路!

16.1-16.4

断言的类别:

并发断言(concurrent assertions)和立即断言(immediate assertions)两大类。

立即断言与仿真一块使用;并发断言基于时钟语义并使用表达式的采样值。

断言主要用于验证设计的行为,且可用于提供功能覆盖,以及对用于验证不符合假设要求的输入激励(input stimulus)进行标记。

断言以要被执行验证函数的断言语句显示,语句会是以下几种:断言(assert)、假设(assume)、覆盖(cover)、限制(restrict) 。

立即断言语句是被执行表达式的测试,这个表达式是非暂时的,和程序中if语句条件下的表达式相同。
如果表达式计算得到x,z,0,则被认为是错误的,且断言描述指向失败;如果表达式计算得到1,则是对的,且断言描述通过(成功)。

立即断言的两个模式

简单立即断言(simple immediate assertions)和延时立即断言(deferred immediate assertions)。

简单立即断言中,成功/失败操作在断言计算后立即显示; 延时立即断言中,操作会延迟到时间步之后,为瞬态或“故障”值的意外多次执行提供一定程度的保护。

  • 立即断言语句规定其表达式必须保持不变,立即断言语句的失败表明违反了要求,设计中有潜在错误。如果断言语句失败且未指定else分句,则该工具在默认情况下应调用error,除非使用error,除非使用assertcontrol with control_type (故障关闭)来抑制失败。
  • 立即假设语句(immediate assume statement)是指定其表达式被假定为保持。立即假设语句可以和形式验证工具一起使用,以指定设计输入假设,从而约束验证计算。在仿真中,立即假设可以作为立即断言来验证环境是否按照假设的方式运行。

立即断言和立即假设语句的动作块(action_block)指明断言成功或失败时采取的行动,和成功相关联的语句是第一个语句,这个语句叫做pass statement,且表达式计算为真则必须执行。

pass statement 能记录覆盖日志的成功数量,如果pass statement 省略了,立即断言或假定语句的断言表达式为true时,不会执行用户指定的操作;与else 关联的语句叫fail statement,如果表达式计算为false,fail statement 会执行,else语句也可以省略。立即断言或假设语句的断言表达式计算后,动作块应立即执行,使用断言操作控制任务可以控制pass statement和fail statement 的执行。

  • 立即覆盖语句(immediate cover statement),表达式的计算成功是覆盖目标。工具会收集覆盖信息,并在模拟结束时或通过断言API按需报告结果。立即覆盖语句的结果应包含以下内容:评估(计算)次数(Number of times evaluated);成功次数(Number of times succeeded)。

立即覆盖的pass statement和fail statement 可以在statement_or_null指明,如果表达式计算为真,pass statement 会被执行,立即覆盖表达式计算之后,pass statement 应立即执行。

严重程度( fatal,fatal,error,warning,warning,info)系统任务可用于断言通过或失败语句(pass or fail statement),在passfail语句中使用时,这些任务应打印相同的工具特定消息。如:

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_ain_b不同时为0的条件下证明assert_fcover语句检测in_ain_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处断言失败”。

延时断言两种类别

观察延时立即断言(observed deferred immediate assertions)和最终立即延时断言(final deferred immediate assertions)。

延时断言和简单立即断言相似,但又有以下主要区别:语法:延时断言使用 #0(对于观察延时断言)或者 final(最终立即延时断言)在验证指令之后;延时:延时记录而不是立即记录;操作块限制:动作块只能包含一个子程序调用;使用外部程序:延时断言可以用作module_common_item

assert #0 (expression) action_block
assert final (expression) action_block

立即断言一样,延时断言表达式在延时断言语句运行时计算,为了避免发生故障,记录或者动作块安排在当前时间步的稍后时间点。

如果延时断言的动作块中存在pass statementfail statement ,应由单个子程序调用,这个子程序可以是一个任务(task)、任务方法、void函数,void函数方法,或者系统函数。

单个子程序调用要求没有begin-end块围绕pass or fail statement,*begin *不是子程序调用语句。在最终延时断言情况下,子程序可以在延迟区合法调用。

子程序参数可以作为输入按值传递,也可以作为refconst ref按引用传递,通过值传递的实际参数表达式(包括函数调用),在延时断言表达式被计算时计算,把自动或动态变量作为实际值传递给refconst ref会出错的。

观察和最终延迟断言动作块处理的不同点如下所示:
(1)对于观察延时断言来说,子程序应被安排在反应区,按引用传递的实际参数表达式,使用或分配反应区基本变量的当前值。
(2)对于最终延时断言来说,子程序应被安排在延时区,按引用传递的实际参数表达式,使用延时区基本变量的当前值。