【IC每日一题:SVA简介】

embedded/2024/11/18 6:22:10/

IC每日一题:SVA简介

  • 1 断言概念
    • 1.1 断言优势;
    • 1.2 断言类型
      • 1.2.1 立即断言
      • 1.2.2 并行断言
      • 1.2.3 并发断言Demo
  • 2 SVA语法
    • 2.1 蕴含操作符:|-> 和 ->
      • 2.1.1 蕴含操作符 |=>
      • 2.1.2 蕴含操作符|->
    • 2.2 延时操作符
      • 2.2.1 ##n 操作符
    • 2.3 重复操作符
      • 2.3.1 [*n]操作符
      • 2.3.2 [->n]操作符
      • 2.3.3 [=n]操作符
      • 2.3.4 [*]操作符
      • 2.3.5 [=0]操作符
      • 2.3.6 [->0]操作符
    • 2.4 匹配操作符
      • 2.4.1 intersect操作符
      • 2.4.2 within操作符
      • 2.4.3 throught操作符
      • 2.4.4 before操作符
      • 2.4.5 first_match操作符
      • 2.4.6 s_next 操作符
    • 2.5 内键函数
      • 2.5.1 $rose函数
      • 2.5.2 $fell
      • 2.5.3 $stable
      • 2.5.4 $past
      • 2.5.5 others
  • 3 FIFO空满断言

【博客首发于微信公众号《漫谈芯片与编程》,欢迎专注一下,多谢大家】

断言是对设计的属性的描述,用以检查设计是否按照预期执行。断言常用来验证总线时序或其他特定的时序逻辑,找出设计中的违例等。
断言主要用于验证设计的行为。断言是在仿真期间嵌入设计中或绑定到设计单元的检查。当特定条件或事件序列失败时,会生成警告或错误。设计人员可以在设计中嵌入断言立即报出error;验证人员编写断言用于验证及时设计错误和创建断言覆盖率;

1 断言概念

1.1 断言优势;

SVA 使用简洁的语法来描述复杂的时序和逻辑关系,使得断言易于阅读和维护;
相比于用verilog进行检查,SVA的优势在于:
1.SVA非常适合描述检查协议时序相关状况;
2.内部提供许多内嵌函数,方便直接调用;
3.可以创建断言覆盖率进行手机,定量检查;

1.2 断言类型

1.2.1 立即断言

立即断言:非时序,执行如过程语句,立即断言语句是在过程代码执行时对表达式进行的测试。如果表达式的值为X、Z或0,则解释为假,并且断言失败。否则,表达式解释为真,断言通过。可以在initial/always过程块中或者task/function中使用。立即断言可以结合 f a t a l , fatal, fatal,error, w a r n n i n g , warnning, warnning,info;

[name: ] assert(expression) [pass_statement][else fail_statement]

注意事项:

  • 如果表达式计算结果为真,则执行 pass 语句。
  • 与 else 关联的语句称为 fail 语句,如果表达式计算结果为假,则执行该语句。
  • pass 和 fail 语句都是可选的。
  • 由于断言是一种必须为真的声明,断言失败将具有相关的严重性。默认情况下,断言失败的严重性为错误。
  • 可以通过在 fail 语句中包含以下严重性系统任务之一来指定其他严重性级别:
  • $fatal - 生成运行时致命断言错误,终止仿真并返回错误代码。
  • $error - 是一个简单的 SystemVerilog 构造,发出错误严重性消息。
  • $warning - 是一个运行时警告,可以以工具特定的方式抑制。
  • $info - 表示断言失败没有特定的严重性。
  • 如果断言失败且未指定 else 子句,则工具默认调用 $error。

非常类似if-else表达四

1.2.2 并行断言

并行断言:时序性的、需要使用关键词proper,与设计模块并行执行,并行断言只会在时钟边沿激活,变量的值是采样得到的值。

  • 检查分布在多个时钟周期上的事件序列的断言称为并发断言。
  • 它们与其他 always 块并行执行,因此称为并发断言。
    与立即断言不同,同时断言仅在时钟节拍时进行评估。因此,它是一种基于时钟的评估模型,并且在并发断言中使用的表达式始终与时钟定义相关联。
    用于区分立即断言和并发断言的关键字是 “property”。

1.创建并发断言步骤


  • 序列:在任何设计模型中,功能由多个逻辑事件的组合表示;这些事件可以是在相同时钟边沿上计算的简单布尔表达式,也可以是在一段时间内涉及多个时钟周期的事件。关键字是"sequence".
sequence name_of_sequence;  <test expression> 
endsequence  
  • 属性:可以逻辑地或按顺序组合多个序列以创建更复杂的序列;关键字“property”.
property name_of_property;<test expression> or  <complex sequence expressions>
endproperty  
  • 断言:属性是在仿真期间验证的属性。必须断言该属性以在仿真期间生效; 关键字–assert;
assertion_ name: assert property( property_name );

** 对于较为简单的时序逻辑关系,可以不单独定义sequence,将sequence的内容直接写在property中;而对于时序关系较复杂的,或者为了提高复用性,可以将一些时序逻辑定义为单独的sequence,然后在property中调用。**

1.2.3 并发断言Demo

//----sequence----property---assertsequence seq;@(posedge clk) (A==1 && B==1);endsequenceproperty ppt;seq;endpropertyassert property (ppt) $display(" %0t, A=1 and B=1, assertion success",$time);else $display("%0t, A=%0b and B=%0b,assertion failure", $time,A,B);//---property--assert// 属性property req_ack_prop;@(posedge clk) req |-> ack;  // 当 req 为高时,下一个时钟周期 ack 也必须为高endpropertyproperty req_nack_prop;@(posedge clk) req |-> !ack;  // 当 req 为高时,下一个时钟周期 ack 不能为高endproperty// 断言assert property (req_ack_prop)else $error("Assertion failed: req_ack_prop");assert property (req_nack_prop)else $error("Assertion failed: req_nack_prop");//=====覆盖======//
// 覆盖cover property (req_ack_prop);

SVA_105">2 SVA语法

2.1 蕴含操作符:|-> 和 ->

蕴含操作符只能在property中使用;
如果我们希望仅在 “a” 高电平之后检查序列,可以通过使用蕴含运算符来实现。蕴含等价于一个 if-then 结构。
蕴含的左侧称为“前提”,右侧称为“结果”。
它只能用于属性定义,不能用于序列。

  • a |-> b:如果a成立,那么在当前时刻b必须成立;
  • a |=> b:如果a成立,那么在下一时刻b必须成立;

2.1.1 蕴含操作符 |=>

语法: A |=> B
含义: 如果 A 成立,则在下一个时钟周期 B 必须成立。
特点: |=> 是一个隐含的蕴含操作符,通常用于描述时序关系。它默认在时钟边沿处进行采样。

property req_ack;@(posedge clk) req |=> ack;  // 如果 req 在时钟上升沿成立,则在下一个时钟上升沿 ack 必须成立
endpropertyassert property (req_ack)else $error("Assertion failed: req_ack");//====带复位
property req_ack_with_reset;@(posedge clk) disable iff (!rst_n) req |=> ack;  // 如果 req 在时钟上升沿成立,则在下一个时钟上升沿 ack 必须成立,除非复位信号 rst_n 为低
endpropertyassert property (req_ack_with_reset)else $error("Assertion failed: req_ack_with_reset");//====带复位和组合逻辑
property complex_property;@(posedge clk) disable iff (!rst_n)(req && !ack) |=> (ack ##1 data_valid);  // 如果 req 成立且 ack 未成立,则在下一个时钟周期 ack 必须成立,并且在再下一个时钟周期 data_valid 必须成立
endpropertyassert property (complex_property)else $error("Assertion failed: complex_property");

2.1.2 蕴含操作符|->

如果前提匹配,则结果表达式将在 同一个时钟周期 中计算。

    property p;@(posedge clk) a |-> b;endproperty  a: assert property(p);  

2.2 延时操作符

2.2.1 ##n 操作符

语法: A ##n B
含义: A 发生后,经过 n 个时钟周期,B 必须发生。
特点: 用于描述信号之间的固定时钟周期延迟。


property req_ack_delay;@(posedge clk) req ##1 ack;  // 如果 req 在时钟上升沿成立,则在下一个时钟上升沿 ack 必须成立
endpropertyassert property (req_ack_delay)else $error("Assertion failed: req_ack_delay");property p;@(posedge clk) a |-> ##[1:4] b;//在当前时钟沿检查到a=1后,检测接下来的1~4个时钟周期内b=1
endproperty
a: assert property(p);property p;@(posedge clk) a |-> ##[0:4] b;//在当前时钟沿检查到a=1后,检测接下来的0~4个时钟周期内b=1,也就是在当前时钟沿b也必须为1
endproperty
a: assert property(p);property p;@(posedge clk) a |-> ##[1:$] b;//在当前时钟沿检查到a=1后,检测下一个时钟周期到仿真时间结束b=1
endproperty
a: assert property(p);

2.3 重复操作符

重复操作符用于描述信号或事件在一段时间内重复出现的模式

2.3.1 [*n]操作符

语法: A [*n]
含义: A 必须连续出现 n 次。
特点: 用于描述信号在连续的 n 个时钟周期内保持不变。

property req_stable_for_n_cycles;@(posedge clk) req [*3];  // req 必须在 3 个连续的时钟周期内保持不变
endpropertyassert property (req_stable_for_n_cycles)else $error("Assertion failed: req_stable_for_n_cycles");

2.3.2 [->n]操作符

语法: A [->n]
含义: A 必须至少出现 n 次。
特点: 用于描述信号在一段时间内至少出现 n 次。

property req_at_least_n_times;@(posedge clk) req [->3];  // req 必须至少出现 3 次
endpropertyassert property (req_at_least_n_times)else $error("Assertion failed: req_at_least_n_times");

2.3.3 [=n]操作符

语法: A [=n]
含义: A 必须恰好出现 n 次。
特点: 用于描述信号在一段时间内恰好出现 n 次。

property req_exactly_n_times;@(posedge clk) req [=3];  // req 必须恰好出现 3 次
endpropertyassert property (req_exactly_n_times)else $error("Assertion failed: req_exactly_n_times");

2.3.4 [*]操作符

语法: A [*]
含义: A 必须一直保持不变。
特点: 用于描述信号在无限长的时间内保持不变。

property req_always_stable;@(posedge clk) req [*];  // req 必须一直保持不变
endpropertyassert property (req_always_stable)else $error("Assertion failed: req_always_stable");

2.3.5 [=0]操作符

语法: A [=0]
含义: A 不得出现。
特点: 用于描述信号在一段时间内不得出现。

property req_never_occurs;@(posedge clk) req [=0];  // req 不得出现
endpropertyassert property (req_never_occurs)else $error("Assertion failed: req_never_occurs");

2.3.6 [->0]操作符

语法: A [->0]
含义: A 可以出现也可以不出现。
特点: 用于描述信号在一段时间内可以出现也可以不出现。

property req_optional_occurrence;@(posedge clk) req [->0];  // req 可以出现也可以不出现
endpropertyassert property (req_optional_occurrence)else $error("Assertion failed: req_optional_occurrence");

上述操作符总结:

module sva_example (input wire clk,input wire rst_n,input wire req,input wire ack
);// 1. req 在 3 个连续的时钟周期内保持不变property req_stable_for_n_cycles;@(posedge clk) req [*3];endpropertyassert property (req_stable_for_n_cycles)else $error("Assertion failed: req_stable_for_n_cycles");// 2. req 至少出现 3 次property req_at_least_n_times;@(posedge clk) req [->3];endpropertyassert property (req_at_least_n_times)else $error("Assertion failed: req_at_least_n_times");// 3. req 恰好出现 3 次property req_exactly_n_times;@(posedge clk) req [=3];endpropertyassert property (req_exactly_n_times)else $error("Assertion failed: req_exactly_n_times");// 4. req 在无限长的时间内保持不变property req_always_stable;@(posedge clk) req [*];endpropertyassert property (req_always_stable)else $error("Assertion failed: req_always_stable");// 5. req 在无限长的时间内不断出现property req_infinite_occurrences;@(posedge clk) req [->*];endpropertyassert property (req_infinite_occurrences)else $error("Assertion failed: req_infinite_occurrences");// 6. req 不得出现property req_never_occurs;@(posedge clk) req [=0];endpropertyassert property (req_never_occurs)else $error("Assertion failed: req_never_occurs");// 7. req 可以出现也可以不出现property req_optional_occurrence;@(posedge clk) req [->0];endpropertyassert property (req_optional_occurrence)else $error("Assertion failed: req_optional_occurrence");endmodule

2.4 匹配操作符

匹配操作符用于描述和检查信号之间的匹配关系;

2.4.1 intersect操作符

语法: A intersect B
含义: A 和 B 必须在同一时钟周期内同时发生。
特点: 用于描述两个序列或事件在同一时钟周期内同时满足;

sequence req;req;
endsequencesequence ack;ack;
endsequenceproperty req_ack_intersect;@(posedge clk) req intersect ack;  // req 和 ack 必须在同一时钟周期内同时发生
endpropertyassert property (req_ack_intersect)else $error("Assertion failed: req_ack_intersect");

2.4.2 within操作符

语法: A within B
含义: A 必须在 B 发生的时间范围内发生。
特点: 用于描述一个序列 A 必须在另一个序列 B 的时间范围内发生。

sequence start;start;
endsequencesequence end;end;
endsequenceproperty start_within_end;@(posedge clk) start within end;  // start 必须在 end 发生的时间范围内发生
endpropertyassert property (start_within_end)else $error("Assertion failed: start_within_end");

2.4.3 throught操作符

语法: A throughout B
含义: A 必须在整个 B 发生的时间范围内一直成立。
特点: 用于描述一个序列 A 在另一个序列 B 的整个持续时间内都必须成立;

sequence active;active;
endsequencesequence busy;busy;
endsequenceproperty active_throughout_busy;@(posedge clk) active throughout busy;  // active 必须在整个 busy 发生的时间范围内一直成立
endpropertyassert property (active_throughout_busy)else $error("Assertion failed: active_throughout_busy");

2.4.4 before操作符

语法: A before B
含义: A 必须在 B 之前发生。
特点: 用于描述一个序列 A 必须在另一个序列 B 之前发生。

sequence setup;setup;
endsequencesequence start;start;
endsequenceproperty setup_before_start;@(posedge clk) setup before start;  // setup 必须在 start 之前发生
endpropertyassert property (setup_before_start)else $error("Assertion failed: setup_before_start");

2.4.5 first_match操作符

语法: first_match (A, B)
含义: A 和 B 中的第一个匹配项。
特点: 用于描述多个序列或事件中的第一个匹配项。

sequence event1;event1;
endsequencesequence event2;event2;
endsequenceproperty first_event;@(posedge clk) first_match(event1, event2);  // event1 和 event2 中的第一个匹配项
endpropertyassert property (first_event)else $error("Assertion failed: first_event");

2.4.6 s_next 操作符

语法: s_next(A, B)
含义: A 发生后,下一个时钟周期 B 必须发生。
特点: 用于描述 A 和 B 之间的严格时序关系。

sequence req;req;
endsequencesequence ack;ack;
endsequenceproperty req_s_next_ack;@(posedge clk) s_next(req, ack);  // req 发生后,下一个时钟周期 ack 必须发生
endpropertyassert property (req_s_next_ack)else $error("Assertion failed: req_s_next_ack");

上述匹配操作符代码:

module sva_example (input wire clk,input wire rst_n,input wire req,input wire ack,input wire busy
);// 1. req 和 ack 必须在同一时钟周期内同时发生property req_ack_intersect;@(posedge clk) req intersect ack;endpropertyassert property (req_ack_intersect)else $error("Assertion failed: req_ack_intersect");// 2. req 必须在 busy 发生的时间范围内发生property req_within_busy;@(posedge clk) req within busy;endpropertyassert property (req_within_busy)else $error("Assertion failed: req_within_busy");// 3. busy 在整个 req 发生的时间范围内一直成立property busy_throughout_req;@(posedge clk) busy throughout req;endpropertyassert property (busy_throughout_req)else $error("Assertion failed: busy_throughout_req");// 4. req 必须在 busy 之前发生property req_before_busy;@(posedge clk) req before busy;endpropertyassert property (req_before_busy)else $error("Assertion failed: req_before_busy");// 5. req 和 ack 中的第一个匹配项property first_event;@(posedge clk) first_match(req, ack);endpropertyassert property (first_event)else $error("Assertion failed: first_event");// 6. req 发生后,下一个时钟周期 ack 必须发生property req_s_next_ack;@(posedge clk) s_next(req, ack);endpropertyassert property (req_s_next_ack)else $error("Assertion failed: req_s_next_ack");endmodule

2.5 内键函数

2.5.1 $rose函数

property rose_signal;@(posedge clk) $rose(req) |-> ack;  // 如果 req 从 0 变为 1,则在当前时钟周期 ack 必须成立
endpropertyassert property (rose_signal)else $error("Assertion failed: rose_signal");

2.5.2 $fell

property fell_signal;@(posedge clk) $fell(req) |-> ack;  // 如果 req 从 1 变为 0,则在当前时钟周期 ack 必须成立
endpropertyassert property (fell_signal)else $error("Assertion failed: fell_signal");

2.5.3 $stable

property stable_signal;@(posedge clk) $stable(req) |-> ack;  // 如果 req 在前一个时钟周期没有变化,则在当前时钟周期 ack 必须成立
endpropertyassert property (stable_signal)else $error("Assertion failed: stable_signal");

2.5.4 $past

property past_value;@(posedge clk) $past(req, 8) |-> ack;  // 如果 req 在 8 个时钟周期前成立,则在当前时钟周期 ack 必须成立
endpropertyassert property (past_value)else $error("Assertion failed: past_value");

2.5.5 others

$onehot(); $onehot0(); $conutones();

3 FIFO空满断言

证的是一个深度为32的FIFO,通过利用读写两个counter去记录目前为止。一旦满了,cnt=32,full应该立即拉高。一旦为空,cnt=0,empty应该立即拉高。

//counter
reg [15:0] w_cnt,r_cnt;
wire [15:0] cnt;
always@(posedge wif.clk)beginif(~wif.rstn)w_cnt<=16'b0;else if(wif.en)w_cnt<=w_cnt+1;
end
always@(posedge rif.clk)beginif(~rif.rstn)r_cnt<=16'b0;else if(rif.en)r_cnt<=r_cnt+1;
end
//check current counter
assign cnt=w_cnt-r_cnt;//check full
property full_chk;@(posedge wif.clk) disable iff(~wif.rstn)cnt==32 && $rose(cnt[5]) |-> $rose(wif.valid);
endpropertya_full_chk: assert property(full_chk) $display("check full pass");else $display("ERROR: check full fail");
c_full_chk: cover property(full_chk);//check empty
property empty_chk;@(posedge rif.clk) disable iff(~rif.rstn)cnt==0 && $fell(cnt[0]) |-> $rose(rif.valid);
endpropertya_empty_chk: assert property(empty_chk) $display("check empty pass");else $display("ERROR: check empty fail");
c_empty_chk: cover property(empty_chk);

[ref]
1.https://blog.csdn.net/qq_29325189/article/details/131058187


http://www.ppmy.cn/embedded/138457.html

相关文章

从0开始机器学习--Day28--PCA算法使用建议及初识异常检测

之前说到数据降维的方法是寻找到一个所有样本到其投影误差的投影平面&#xff0c;那么升维其实就是式子里的矩阵移到另一边即可&#xff1a; &#xff0c;注意这里没有用x表示是因为除非本身所有样本点的投影误差都很小&#xff0c;可以近似认为就在线上&#xff0c;因为这里的…

NVR录像机汇聚管理EasyNVR多品牌NVR管理工具视频汇聚技术在智慧安防监控中的应用与优势

随着信息技术的快速发展和数字化时代的到来&#xff0c;安防监控领域也在不断进行技术创新和突破。NVR管理平台EasyNVR作为视频汇聚技术的领先者&#xff0c;凭借其强大的视频处理、汇聚与融合能力&#xff0c;展现出了在安防监控领域巨大的应用潜力和价值。本文将详细介绍Easy…

小程序-基于java+SpringBoot+Vue的经济新闻资讯设计与实现

项目运行 1.运行环境&#xff1a;最好是java jdk 1.8&#xff0c;我们在这个平台上运行的。其他版本理论上也可以。 2.IDE环境&#xff1a;IDEA&#xff0c;Eclipse,Myeclipse都可以。推荐IDEA; 3.tomcat环境&#xff1a;Tomcat 7.x,8.x,9.x版本均可 4.硬件环境&#xff1a…

【Unity】ScriptableObject的应用:利用配方合成新物体

前一篇已经使用ScriptableObject(SO)类配置可放置物体&#xff0c;本篇探索更多的SO类应用场景。 需求分析 将若干指定物体放在工作台上&#xff0c;可以生成新的物体。 成果展示 Scene部分 准备工作台&#xff0c;放在工作台上的物体全部放在指定PlacedObjects空物体下。 …

Nginx 上安装 SSL 证书并启用 HTTPS 访问

本文将介绍如何在 Nginx 上为你的域名安装 SSL 证书&#xff0c;并配置 Nginx 使用 HTTPS 安全访问。我们将使用 Let’s Encrypt 免费的 SSL 证书&#xff0c;通过 Certbot 生成并管理证书&#xff0c;然后配置 Nginx 实现 HTTPS 加密访问。同时&#xff0c;我们将解决因 SSL 证…

智慧环保平台建设方案

1. 引言 随着环保意识的增强和技术的进步&#xff0c;智慧环保平台建设成为应对环境污染和生态退化的重要手段。本方案旨在通过大数据、云计算、物联网等先进技术&#xff0c;构建高效、智能的环保管理体系。 2. 环保现状与挑战 当前&#xff0c;我国面临大气污染、水体污染、…

ffmpeg 遇见错误

错误&#xff1a;Too many packets buffered for output stream 0:1. 解决&#xff1a;添加命令 -max_muxing_queue_size 1024 错误&#xff1a;"at least 3 arguments were expected, only 1 given in string" 解决: https://unix.stackexchange.com/questions/3…

在AndroidStudio中新建项目时遇到的Gradle下载慢问题,配置错的按我的来,镜像地址不知道哪个网页找的,最主要下载要快

android-studio-2024.2.1.11-windows Android 移动应用开发者工具 – Android 开发者 | Android Developers https://r4---sn-j5o76n7z.gvt1-cn.com/edgedl/android/studio/install/2024.2.1.11/android-studio-2024.2.1.11-windows.exe?cms_redirectyes&met1731775…