• 电力电子转战数字IC20220822day66——断言和序列


    目录

    assertion断言

    什么是assertion?

    assertion的作用是什么?

    assertion based verification ABV方法学定义assertion如何被使用,包括:

    assertion的分类有哪些?

    assertion如何编码实现?

    property和sequence的关系

    这里的seq和之前的seq的区别?

    sequence可以提供形式参数,提高复用性

    有两个操作符,第一个implication蕴含

    sequence序列

    ##周期延迟符号

    ##[min:max]范围内clk延迟

    $无穷大的周期

    [*]重复操作事件

    [=m]表示一个时间的连续性

    and表示两个seq需要保持匹配

    intersect要求匹配时刻在同一个clk

    or表示两个seq至少需要一个满足

    first_match表示从多次满足的序列中选择第一次满足的时刻,放弃其他时刻

    throughout检查一个信号或表达式在贯穿一个seq时是否满足要求

    within检查一个seq与另一个seq在部分clk长度上的重叠

    .ended检查序列的重点

    局部变量

    调用方法


    assertion断言

    什么是assertion?

    用来与设计功能和时序做比较的属性描述。???

    越短越好!

    assertion的作用是什么?

    • 检查设计的内容
    • 提高设计的可视度和调适能力
    • 检查设计特性在验证中是否被覆盖

    assertion based verification ABV方法学定义assertion如何被使用,包括:

    • 谁写?
    • 哪种语言可以写?
    • 写在哪里?
    • 可以使用哪些断言库Library?
    • 如何调试?
    • 如何使用形式验证工具?
    • 如何使用断言覆盖率?

    assertion的分类有哪些?

    • 立即断言immediate assertion
      • 非时序
      • 执行时如同过程语句
      • 可以在initial块、always块、task和function中使用
    • 并行断言concurrent assertion
      • 时序性的
      • 关键词property用来区分这两种断言
      • 与设计模块一同并行执行,所以称为并行断言

    assertion如何编码实现?

    1. [name:] assert(expression)[pass_statement][else fail_statement]
    2. time t;
    3. always @(posedge clk)
    4. if (state==REQ)
    5. assert (req1||req2)
    6. else begin
    7. t=$time;
    8. #5 $error("assert failed at time %0t", t);
    9. end
    10. //结合$fatal $error $warning $info
    11. assert (myfunc(a,b)) count1=count+1; else -> event1;
    12. assert (y==0) else flag=1;
    13. always @(state) assert (steate==$onehot) else $fatal;
    1. base_rule1: assert property (cont_prop(rst, in1, in2)) pass_stat else fail_stat;
    2. //req拉高,2个clk后grant拉高,1个clk后req拉低,1个clk后grant拉低
    3. property req_grant_prop
    4. @(posedge clk) req ## 2 gnt ##1 !req ## !gnt;
    5. endproperty

    并行断言只会在clk边沿激活,变量的值是采样到的值

    • 可以直接包含一个property,也可以独立声明。
    1. assert property (@(posedge clk)) disable iff(!reset) a | => b ##1 c);
    2. assert property(my_prop);
    3. property my_prop;
    4. @(posedge clk))
    5. disable iff(!reset) a | => b ##1 c;
    6. endproperty

    property和sequence的关系

    property块可以直接包含sequence

    复杂的property可以独立声明多个sequence

    sequence是property的基本构建模块,经过组合来描述复杂的功能属性

    这里的seq和之前的seq的区别?

    描述时序,不是做激励

    1. sequence s1;
    2. @(posedge clk) a ##1 b ##1 c;
    3. endsequence
    4. sequence s2;
    5. @(posedge clk) a ##1 c;
    6. endsequence
    7. property p1;
    8. @(posedge clk) disable iff(!reset)
    9. s1 |=>s2;//如果出现s1序列则马上跟着出现s2序列
    10. endproperty

    sequence可以在module interface program clocking package中声明

    1. sequence t2;
    2. (a ## [2:3] b) or (c ##[1:2] d);
    3. endsequence

    sequence可以提供形式参数,提高复用性

    1. sequence s20_1 (data, en);//参数为data和en
    2. (!frame && (data==data_bus)) ##1 (c_be[0:3] == en);
    3. endsequence

    有两个操作符,第一个implication蕴含

    表示:如果property中左边的先行算子成立,那么右边的后续算子才会被计算

    如果先行算子antecedent不成功,整个属性就默认被认为成功,这是空成功vacuous success

    只能在property中定义,不能在seq中定义

    分类

    • 交叠蕴含overlapped implication

      • 符号是|→
      • 如果条件满足,则评估后续算子序列;如果不满足,表现为空成功,不执行后续算子
      1. property p_req_ack;
      2. @(posedge clk) mem_en |-> (req ##2 ack);
      3. endproperty
    • 非交叠蕴含noi

      • 符号是|=→
      • 如果条件满足,则在下一周期评估后续算子序列;如果不满足则同上

    sequence序列

    ##周期延迟符号

    ##n表示在n个clk后

    ##0表示在当前周期,即交叠周期,相当于逻辑与&&

    1. sequence a_b
    2. @(posedge clk) a ##1 b;
    3. endsequence

    ##[min:max]范围内clk延迟

    min和max必须是非负数,seq会在从min到max时间窗口中最早的时间来匹配?

    在1个clk就出现b,则后面的clk就不会看了,最早的意思就是这样

    1. sequence a_b
    2. @(posedge clk) a ##[1:5] b;
    3. endsequence

    $无穷大的周期

    将max换成$,增大仿真评估序列的负担,不推荐

    [*]重复操作事件

    n非负数,不能为$

    表示b必须在两个连续的clk为真

    1. sequence a_b
    2. @(posedge clk) a ##1 b[*2];
    3. endsequence

    如果是[*2:5],表示b必须在2-5个连续clk为真(相当于逻辑或)

    a[*0]表示没有在任何正数clk内有效:如果a不满足,则忽略了,继续找b和c等其他事件

    a[*0:3] ##1 b表示:b、a ##1 b、a ##1 a ##1 b、a ##1 a ##1 a ##1 b

    [=m]表示一个时间的连续性

    需要重复发生m次,但不用在连续的clk发生

    例如在实战1中的burst read测试,期望读的data和ack信号在接下来的4个clk内返回,但是不需要连续4个clk

    [=m:n]表示从最小m到最大n的非连续clk

    and表示两个seq需要保持匹配

    SEQ1 and SEQ2

    • 两个seq的满足时间可以不同,SEQ1先满足,等待SEQ2满足时,and满足

    and左右可以是信号

    intersect要求匹配时刻在同一个clk

    和and类似,区别在于两个seq时序要在同一个clk内匹配

    or表示两个seq至少需要一个满足

    SEQ1 or SEQ2,逻辑或||

    • 两个seq在同一时刻触发,最终满足至少其中一个
    • 每个seq的结束时间可以不同,结束时间以晚结束的seq为准

     对于and和or的应用:如果burst write的长度为4,则写的长度可以为1、2或4

    1. property burstlengthvalid
    2. @(posedge clk) disable iff(!rst)
    3. ((burstlen==4) |-> (wrlen--1) or (wrlen==2) or (wrlen==4))
    4. endproperty
    5. assert property (bustlengthvalid)

    first_match表示从多次满足的序列中选择第一次满足的时刻,放弃其他时刻

    1. sequence t1;
    2. te1 ## [2:5] te2;//2-5次te2,共4种情况
    3. endsequence
    4. sequence ts1;
    5. first_match (te1 ## [2:5] te2);//上述4种情况中的第一次匹配的时刻
    6. endsequence
    7. sequence t2;
    8. (a ## [2:3] b) or (c ## [1:2] b);
    9. endsequence
    10. sequence ts2;
    11. first_match(t2);
    12. endsequence

    每一次PCI总线进入idle时状态机也应该返回idle,所以时序要求frame和irdy信号保持至少两个clk以上为高时系统状态为idle

    1. sequence checkbusidle
    2. (## [2:$] (frame && irdy));//宁可写成100也不要$
    3. endsequence
    4. property first_match_idle
    5. @(posedge clk) first_match (checkbusidle) |-> (state==busidle);
    6. endproperty

    throughout检查一个信号或表达式在贯穿一个seq时是否满足要求

    Sig1/Exp1 throughout Seq,左边和右边不一样

    在burst模式信号拉低后2个clk时,irdy/trdy要连续7个clk保持为低,同时burst模式信号在这连续的clk中也为低。(也就是burst模式信号至少比右边seq的时间还要长)

    1. sequence burst_rule1;
    2. @(posedge mclk)
    3. $fell (burst_mode) ##0//看做一个seq:burst_mode在这一拍拉低了
    4. (!burst_mode) throughout (##2 ((trdy==0) && (irdy==0)) [*7]);
    5. endsequence

      

    within检查一个seq与另一个seq在部分clk长度上的重叠

    SEQ1 within SEQ2,当seq1满足在seq2的一部分连续clk内成立,则表达式成立

    trdy需要再irday下拉的1个clk后保持7个clk为低,同时irday也将保持8个clk为低:

    !trdy[*7] within (($fell irdy) ##1 !irdy [*8])

    .ended检查序列的重点

    SEQ.ended

    在某一时刻序列抵达终点,则条件满足

    1. sequence e1;
    2. @(posedge sysclk) $rose(ready) ##1 proc1 ##1 proc2;
    3. endsequence
    4. //在inst为高的下一个clk,e1应该结束或者已经结束
    5. sequence rule;
    6. @(posedge sysclk) reset ##1 inst ##1 e1.ended ##1 branch_back;
    7. endsequence

     

     

    1. sequence arbseq (aFell, bRose);
    2. @(posedge clk) $fell(aFell) ##1
    3. $rose(bRose);
    4. endsequence
    5. property endcycle;
    6. @(posedge clk) $rose(c) |=> arbseq(a,b).ended;
    7. endproperty
    8. //这个property是不满足的,因为是在c拉高的时刻才开始这个property,a至少要在下个clk拉低
    9. $rose(c) && $fell(a) |=> $rose(b)

    局部变量

    可以在sequence或者property中使用,会伴随他们动态创建

    每一个sequence实例都会有它自己的变量拷贝

    1. sequence rs_cache_done
    2. ##[1:5] rdDone;
    3. endsequence
    4. //在cache rdDone拉高后读出的rdData会在2个clk后,在其基础上加1,并作为wrData写入
    5. sequence check_reg_wr_data;
    6. int local_data;//局部变量
    7. (rs_cache_done, local_data==cache_rd_data) ##2 (reg_wr_data == (local_data+1));
    8. endsequence
    1. property checkreadidack;
    2. int loc_id;
    3. //read拉高,伴随readid,下一次read必须在这一次read对应的readack返回之后才可以发起,用局部变量来存储
    4. ($rose(read), loc_id=readid) |=>//满足序列后执行逗号后的表达式
    5. not ($rose(read) && readid==loc_id) ##0 ($rose(readack) && readackid==loc_id);
    6. endproperty
    7. //先满足($rose(readack) && readackid==loc_id)
    8. //not ($rose(read) && readid==loc_id)没有相同readid的read发起
    9. //##0 表示逻辑与

    调用方法

    序列匹配时可以调用task,void function、系统函数

    1. sequence s1;
    2. logic v,w;
    3. (a, v=e) ##1 (b[->1], w=f, $display("b after a with v = %h, w = %h \\n", v,w));

    系统函数用来访问指定类型的变量采样:访问当前和上一个周期采样值,检测采样变量的变化

    1. $rose(expression[, clocking_event])
    2. $fell(expression[, clocking_event])
    3. //与上一个采样周期相比,变量最低位是否跳变为10,满足则返回1,否则返回0
    4. //clocking_event在sequence中不需要单独提供,一般会指定采样clk
    5. $stable(expression[, clocking_event])
    6. //表示在连续两个clk内表达式的值保持不变,满足则返回1,否则返回0
    7. $past(expr[, num_cycles][, gating_expr][, clocking_event])
    8. //访问在过去若干个采样周期前的数值,默认num_cycle为1,采样1个clk前的数值
    9. property reqcauseack;
    10. @(posedge clk) $rose(ack) |-> $past(req, 2);
    11. endproperty
    12. //在ack拉高时的前两个clkreq应该为高
    13. property cache_read_chk;
    14. @(posedge clk) (state==CACHE_READ) |-> ($past(state) != CACHE_MISS);
    15. endproperty
    16. //如果当前是CACHE_READ,则上一个状态不应该是miss

    $rose fell stable可以在过程块语句和连续赋值中使用

    1. always @(posedge clk)
    2. testdone<=stimulus_over & $rose(unit_done);
    3. always @(posedge clk) begin
    4. if($stable(my_sig)) begin $display(); end
    5. end
    6. assign intr_cleared=$fell(intr, @(posedge clk));//class里面能不能指定clk
    7. assign intr_set=$rose(intr, @posedge clk);

    系统函数也可以在seq,pro,assertion中使用

    $countbits(expression, control_bit)计算expression中匹配control_bit数值的位数

    $countones相当于$countbits(expression, ‘1)

    $onehot(expression)相当于$countbits(expression, ‘1)==1

    $isunknown(expression)相当于$countbits(expression, ‘x, ‘z)!=0

    $assertoff(level, [list of module, instance or assertion_identifier]);

    $assertkill(level, [list of module, instance or assertion_identifier]);

    $asserton(level, [list of module, instance or assertion_identifier]);

    level=0表示当前模块或者层次下所有assertion,level=n表示当前模块或层次下n层范围中的assertion

    identifier表示property的名字或者assertion的label

    1. module assert_control();
    2. initial begin
    3. @(negedge top_tb.reset_n) $display();
    4. $assertoff(0, top_tb.cpu_inst1);
    5. @(posedge top_tb.reset_n) $display();
    6. $asserton(0, top_tb.cpu_inst1);
    7. end
    8. endmodule
    9. //reset阶段停止所有assertion,复位之后开启
  • 相关阅读:
    php://filter协议在任意文件读取漏洞(附例题)
    【LeetCode】【剑指offer】【扑克牌中的顺子】
    tensorflow的GPU加速计算
    2 springMVC-处理器方法的返回值ModeVeiw,String,void,Object,List<Object>,String对象
    数字营销面试题库和答案(搜索引擎、网站 URL 、网站标题、关键字、关键词优化)
    Python接口自动化测试post请求和get请求,获取请求返回值
    使用控制台方式部署sentinel
    QT:使用自定义的信号与槽的方式
    Java的自动装箱与拆箱详细分析
    拦截浏览器从服务器后台加载的js 文件 替换为本地js文件 方便调试线上前端bug
  • 原文地址:https://blog.csdn.net/weixin_39668316/article/details/126479485