XtremeDV 2018-04-19 17:42:06
分类专栏: SVA system verilog SystemVerilog Assertions
一个断言是一个检查你设计的规范,你要确保永不违反。如果规范被违反,您希望看到失败。
下面给出一个简单的例子。每当FRAME_无效(即变为高)时,最后数据相位(LDP_)必须被置位(即变为低)。这种检查对于纠正给定接口的功能是必不可少的。 SVA语言被精确设计来处理这种时域情况。正如我们将在Sect中看到的那样。 SVA建模比Verilog容易得多。还要注意,断言在时间域中起作用(我们将在后面介绍更多),并行以及多线程。这些属性使得SVA语言非常适合写时域检查。
图2.1简单的总线协议设计及其SVA属性
图2.1显示了这个简单总线协议的断言。我们将讨论如何阅读这段代码,以及这段代码如何与紧接着的Sect2.2.1中的Verilog进行比较。
正如我们在介绍部分所讨论的那样,我们需要提高设计/调试/仿真/覆盖循环的生产力。断言完全有助于这些领域。正如我们将看到的,与Verilog或SystemVerilog中编写的相同声明相比,它们比标准Verilog或SystemVerilog更容易编写(从而提高设计生产力),更易于调试(从而提高调试生产力),提供功能覆盖和模拟速度更快。让我们逐一看到这些优势。
参考图2.1中的时序图,让我们看看SVA如何缩短开发时间。 SVA代码非常明了。有一个属性'ldpcheck'表示''在posedge时钟,如果FRAME_上升,这意味着在接下来的2个时钟内LDP_下降''。这几乎就像用英文书写检查器一样。然后,我们'声明'这个属性,它将检查在每个posedge clk满足的必要条件。我们也'覆盖'这个属性,看看我们确实行使了所需的条件。但我们正在超越自己。所有这些将在接下来的章节中详细解释。现在,只需理解SV断言很容易编写,易于阅读并且易于调试。
现在检查相同check的Verilog代码(图2.2)。有很多方法可以对此进行编码。显示了行为层面的一种方式。在这里你可以分解出两个程序块。一个监视LDP和另一个等待2个时钟。然后在两个程序块中的任何一个完成时禁用整个块('ldpcheck')。正如你所看到的,检查器不仅非常难以阅读/解释,而且很容易出错。您最终可能花费更多时间来调试您的检查程序,而不是验证逻辑。
图2.2简单总线协议的Verilog代码
图2.3断言提高可观测性
断言的一个最重要的优点是它们解决了问题的根源。正如我们在接下来的章节中将会看到的那样,断言在你的设计中位于当地时间条件下。换句话说,您不必从主输出一直追溯到错误发生地,即设计内部的某个错误。断言是这样编写的,它们接近逻辑(例如@(posedge clk)state0 |->Read。这样的断言接近状态机的描述,如果断言失败,我们知道当状态机处于状态0时,Read没有发生。一些最有用的放置断言的地方是FIFO,计数器,块到块接口,块到IO接口,状态机等。这些RTL逻辑中的结构是许多错误产生的地方。当本地条件失败时,放置一个检查本地条件的断言将被触发,从而直接指向错误的来源(图2.3)。
传统的验证可以称为Black Box验证,具有Black Box可观察性,这意味着,您可以在“模块”的主要输入处应用向量/事务,而不必关心模块中的内容(黑盒验证),并且通过主要输出观察模块的行为(黑盒可观测性)。另一方面,断言允许你进行黑盒验证时,用白盒进行观测(在模块内部写一些断言)。
图2.4 SystemVerilog声明提供时域功能覆盖
断言不仅可以帮助你发现bug,还可以帮助你确定你是否覆盖(即检查)了设计逻辑,主要是时间域条件。它们在发现您的测试平台的时域覆盖方面非常有用。这就是为什么这么重要的原因(图2.4)。
让我们说,你一直在运行回归24 * 7,并且已经停止了在你的设计中发现错误。这是否意味着你完成了验证?不发现错误可能意味着两件事之一。 (1)设计中确实没有任何问题,或者(2)您没有行使(或覆盖)设计的所有必需功能。你可能会不断碰到同样的逻辑,其中没有进一步的错误。换句话说,你可能会得出一个错误的结论,即所有的错误都已经找到。
简而言之,覆盖范围包括三个组成部分(我们将在第19章详细讨论)。 (1)代码覆盖率(结构性),需要100%; (2)需要设计覆盖整个设计的功能覆盖描述,并且必须完全覆盖; (3)需要仔细设计的时域覆盖(使用SVA'cover'特征),以完全覆盖设计的所有所需时域条件。
好的,让我们回到我们在上一节中看到的简单总线协议断言。让我们看看该SVA声明中的'cover'声明是如何工作的。代码在这里重复以提高可读性。
在这段代码中,你会看到有一个'cover'声明。它告诉你的是“你是否检查了这种条件”或“你是否覆盖了这个属性”。换句话说,正如上面所讨论的,如果断言永远不会失败,那可能是由于两个原因。(1)你没有错误或(2)你从未检查过条件开始!在cover声明中,如果条件得到执行但不失败,则通过与“cover”声明关联的$display操作块获得PASS指示。由于我们尚未详细讨论这些断言,因此您可能无法完全理解这一概念,但确定您的设计的时域覆盖是验证非常重要的一个方面,并且必须将其作为验证计划的一部分。
重申一下,SVA支持'cover'结构,告诉你该断言是否已被执行(覆盖)。没有这个指示,如果没有失败,你不知道你是否确实行使了所需的条件。在我们的例子中,如果FRAME_从不上升,断言将不会被启动,显然也不会有任何错误报告。所以,在仿真结束时,如果你没有看到错误,或者你甚至没有看到''ldpcheck PASS''显示,你就知道断言永远不会发生。换句话说,您必须看到执行的“cover property”声明,以便知道该条件已得到行使。我们将在接下来的章节中进一步讨论。作为您的验证方法的一部分,请尽量使用'cover'。
呵呵!这是什么意思?这个例子,我从现实生活经验中学到了。在我们的项目中,在完成了有向和有约束的随机验证之后,我们总是进行完全随机的并行验证(即设计文件的所有发起者同时对设计的所有目标进行验证)。这背后的想法是在设计中发现任何死锁(或者活锁)。大多数启动器测试都是精心设计的(即它们不会破坏对方的地址空间),但具有如此大的随机性,您的目标模型可能无法预测对随机事务的响应。在所有这些情况下,最好禁用目标模型中的积分板(除非积分板完全证明它们可以在事务的总体随机性中存活),但保持断言存活。现在,对于并发的随机事务,目标模型将尽其所能地做出最好的响应,但是如果存在问题(例如模拟挂起(死锁)或简单地保持时钟而不提前发挥功能(活锁)),则断言将指出问题。
换句话说,断言总是存在并且不管事务流(随机或定向),只要检测到不正确的条件,它们就会立即触发。
•示例:问题定义:
- 您的设计具有以太网接收和视频作为输入,也是一个PCI目标。
- 它还具有向PCI目标,SDRAM,以太网传输和视频输出等输出事务的内部启动器。
- 在您完成受限制的随机验证后,您现在需要模拟最终的大规模随机验证,从所有输入接口爆炸事务,并从内部主设备(DMA,Video Engine,嵌入式处理器)到设计的所有输出接口进行事务处理。
- 但是很有可能你的参考模型,自检测试,记分板可能无法预测这种庞大的随机性下设计的正确行为。
•解决方案:
- 关闭所有检查(参考模型,记分板等),除非它们被充分证明在大量的随机传输下有效。
- 但保持断言活着。
- 以庞大的随机性来测试设计(保持每个启动器的地址空间清洁)。
- 如果有任何断言发生,你已经发现了深藏在角落里的错误。
这是我们在设计中遇到的一个经典案例,在tape-out之前幸运地发现了这个错误。如果没有断言的帮助,我们不会发现错误,并且必须有一个复杂的软件解决方法。我会让下面的例子来解释这种情况。
•规格:
- 在存储地址错误时,在与检测到错误相同的周期,下一个地址寄存器(NAR)中的地址应该冻结。
• 错误:
- 对于存储地址错误,控制NAR寄存器的状态机实际上冻结了下一个时钟的地址(而不是存储地址错误发生时同一时钟的当前地址)。换句话说,一个不正确的地址被存储在NAR中。
• 那么,为什么测试通过这个bug呢?
- 触发此错误的测试使用相同的地址。换句话说,即使在NAR中捕捉到错误的'next'地址,由于'next'和'previous'地址是相同的,所以逻辑似乎表现正确。
- 断言:增加了一个断言来检查当一个存储地址错误被声明时,状态机不应该移动到指向流水线中的下一个地址。由于这个缺陷,状态机实际上确实进入了下一阶段。断言被触发和错误被捕获。
•SVA语言支持多时钟域交叉(CDC)逻辑
- 可以写入从一个时钟域到另一个时钟域的SVA属性。非常适合跨越时钟域的数据完整性检查。
•断言是可读的:非常适合记录和传达设计意图。
- 非常适合创建可执行的规格。
- 写断言的过程来指定设计要求&&进行交叉审查设计一致性
错误,不一致,遗漏,模糊
- 用它来进行设计验证(测试计划)评审。
•未来设计的可重用性
- 参数化的断言(例如16位总线接口)在未来的设计中(使用32位总线接口)更容易部署。
- 断言可以在RTL之外建模,并且容易绑定(使用'绑定')到RTL,使设计和DV逻辑分离并易于维护。
•断言始终开启
- 断言永远不会进入睡眠状态(直到您特别关闭它们)。
- 换句话说,主动断言充分利用每个新的测试/激励配置,通过监控设计行为来抵抗新的激励。
•使用断言进行加速/仿真
- 长时间延迟和大规模随机测试需要加速/仿真工具。 这些工具开始支持断言。断言对长时间/随机测试的快速调试有很大的帮助。我们将在接下来的章节中进一步讨论。
•全局严重性级别($Error,$Fatal等)
- 帮助在仿真中保持统一的错误报告结构。
•全局打开/关闭断言(如$dumpon / $dumpoff)
- 更简单的代码管理(无需将每个断言打开/关闭)。
•形式验证取决于断言
- 用于设计的“相同”断言也可以直接由形式验证工具使用。静态形式验证工具应用其算法来确保'assert'ion永不失败。
-“assume”允许对正确设计约束,这对形式验证非常重要。
•一种语言,多种用法
- 检查设计和形式验证的“assert”
- 检查时域覆盖的“cover”
- 形式验证的“assume”设计约束。
本节将指出,断言不仅在基于软件的仿真中有用,而且在基于硬件的仿真中也是如此。你可以使用断言来直接在硬件中使用的原因是因为断言是可综合的(至少是简单的)。尽管断言综合有很多方法可行,但综合中已经包含了足够的子集,并且足以在硬件中部署断言。
在图2.5中显示了一个通用仿真系统。可综合的断言是设计的一部分,它们被综合并被分区到模拟器硬件。在仿真过程中,如果设计逻辑有错误,可综合的断言将会启动并触发停止/跟踪寄存器来停止仿真,并直接指出故障原因。
任何使用模拟作为其验证策略一部分的人都非常清楚,尽管模拟器可能需要几秒钟才能“模拟”设计,但调试失败后需要数小时。断言将是调试工作的一大福音。许多商业供应商现在支持可综合的断言。
图2.5用于硬件仿真的断言
在同一思路上,断言也可以在硅片中合成。在硅后验证期间,可以编写一个功能错误并且硬件寄存器可以记录失败。该寄存器可以反映在芯片的GPIO上,或者可以使用JTAG边界扫描来扫描寄存器。输出可以被解码以确定哪个断言是红色的,哪个部分的硅导致了失败。 没有这种设施,需要数小时的调试时间来查明硅故障的原因。这项技术现在正在被广泛使用。与芯片的整体面积相比,可综合断言逻辑的“面积”开销可以忽略不计,但调试变得简单具有巨大的价值。请注意,这样的断言也可以更容易地调试现场的硅故障。
图2.6正式(静态功能)和仿真中的断言和假设
您为设计验证编写的相同断言可以用于静态功能验证或静态功能加仿真算法的所谓混合验证。图2.6显示(在LHS上)SVA假设和(在RHS /中心)SVA断言。正如你所看到的,假设对于静态形式验证(又称形式化)最有用(即使假设也可以用于模拟中,我们将在后面的章节中看到),而SVA断言在形式化和模拟中都有用。
那么什么是静态功能验证(也称为静态形式验证)?简单的英语中,静态形式是一种方法,静态形式化算法应用输入的所有可能的组合和时间域可能性来行使给定逻辑块的所有可能的“逻辑锥”并且看断言没有被违反。这消除了对测试台的需求,并且确保逻辑在任何情况下都不会失败。这为验证逻辑提供了100%全面性。所以作为一个侧面说明,为什么我们需要写一个测试台!静态形式(截至撰写本文时)受逻辑块大小(即,门等效RTL)的限制,特别是如果运动输入的时域很大时。这种限制的原因是算法必须创建不同的逻辑锥以尝试证明属性成立。随着更大的逻辑块,这些所谓的逻辑锥爆炸。这也被称为“状态空间爆炸”。为了解决这个问题,仿真专家提出了混合仿真技术。在这种技术中,仿真部署到'接近'断言逻辑,然后使用静态功能验证算法在断言检查下的逻辑。这减少了逻辑锥的数量和它们的大小,并且您可能会看到该属性成功。由于静态功能或混合功能超出了本书的范围,因此我们将到此为止。
图2.7用于不同用途的断言和OVL
图2.7显示了断言的优越性。写一次断言,但是很多EDA工具都可以使用此断言。
我们已经在高层讨论了在仿真,形式验证,覆盖率分析和仿真中使用断言。但是,您如何将它们用于测试台生成/检查器以及什么是OVL断言库?
测试台生成/检查器:随着逻辑设计的日益复杂,测试台也变得越来越复杂。断言如何帮助设计测试台逻辑?让我们假设您需要在特定条件下将某个traffic驱动到DUT输入。您可以设计一个断言来检查这种情况,并在检测到FAIL动作块触发后,可以用它来驱动DUT的traffic。使用断言语言比单独使用SystemVerilog检查条件要容易得多。第二个好处是对验证逻辑本身做出断言。由于验证逻辑(在某些情况下)比设计逻辑更加复杂,因此使用断言来检查测试台逻辑也是有意义的。
OVL库:打开验证库。这个预定义的检查库是在PSL和SVA成为主流之前用Verilog编写的。目前该库还包含基于SVA(和PSL)的断言。断言检查器的OVL库旨在供设计,集成和验证工程师用来检查仿真,模拟和形式验证中的良好/不良行为。 OVL包含流行的断言,如FIFO断言等。 OVL仍在使用中,您可以从Accellera网站下载整个标准库:http://www.accellera.org/downloads/standards/ovl。
我们不会涉及OVL的细节,因为网络上有大量可用的OVL信息。 OVL代码本身很容易理解。一旦你更好地理解了断言语义,它也是一个很好的地方,可以看到如何为'流行'检查(例如FIFO)写出断言。
也许这种范式现在已经发生了变化,但在撰写本文时,在整体验证方法中采用SVA仍存在许多犹豫。这里有一些受欢迎的反对意见。
•我没有时间添加断言。我甚至没有时间来完成我的设计。我在哪里还有时间添加断言?
- 这取决于你对“完成我的设计”的定义。如果定义是简单地在设计中添加所有没有验证/调试功能的RTL代码,然后将设计放在 墙上进行验证,那么最终的“工作设计”将花费相当长的时间。
- 在设计过程中,您已经在考虑并假设许多条件(状态转换假设,块间协议假设等)。只需在设计时将您的假设转换为断言。即 使使用简单的测试台,他们也会很快找到这些角落里的错误。
•我没有时间添加断言。我正在调试已经违反我设计的bug。
- 呃,实际上你可以在更短的时间内调试你的设计,如果你在设计时添加了断言(或者至少现在添加断言),那么如果失败的测 试能够触发断言,那么你的调试时间将会非常短。
- 断言指向错误的根源,并在验证模块块级和芯片级设计时显着减少调试时间。
- 换句话说,这有点鸡和鸡蛋问题。你没有时间写断言,但没有这些断言,你会花更多的时间来调试你的设计!
•学断言不是验证工程师的工作吗?
- 不完全的。设计验证(DV)工程师没有深入了解微架构级RTL细节。但真正的答案是,BOTH Design和DV工程师需要添加断 言。我们将在即将到来的部分详细讨论。
•DV工程师说:我是断言的新手,并且比调试设计花费更多的时间来调试我的断言。
- 那么,你不花时间调试你的测试台逻辑吗?你的参考模型?调试断言有什么区别?如果有的话,断言已被证明在查找错误和 减少调试时间方面非常有效。
- 根据我个人的经验(在过去的许多SoC和处理器项目中),项目报告的总错误中约有25%是DV错误。在你的测试平台上添加 断言有很大的好处,这比调试它们的时间要重要得多。
•设计师也不能成为验证者。不要求设计师添加断言违反此规则吗?
- 正如我们将在下面的章节中讨论的,添加断言来检查设计的“意图”并验证你自己的假设。你没有写断言来复制你的RTL。下 面的例子清楚地表明设计者确实需要添加断言。
- 例如,
对于发给下一个模块的每一个'req',我确实会得到'ack',并且对于每个'req'我只会得到1'ack'。这是一个交叉模块假设,与 您设计RTL的方式无关。您不会在声明中复制您的RTL。
我的状态机不应该停留在任何“状态”(除了“空闲”状态)超过10个时钟。
设计和验证工程师都需要添加断言......
•设计工程师:
- 微型架构级决策/假设对于DV工程师是不可见的。因此,设计人员最适合保证超级逻辑的正确性。
- 每个假设都是一个断言。如果你认为你发送到另一个模块的'请求'将总是在2个时钟内得到'ack';这是一个假设。所以,为它 设计一个断言。
- 在设计逻辑时添加断言,而不是事后的再添加。
•DV工程师:
- 添加断言来检查宏功能和芯片/ SoC级功能。
一旦数据包处理完L4层,它确实会显示在DMA队列中。
机器检查异常确实将PC设置为异常处理程序地址。
- 添加断言来检查接口IO逻辑
复位失效后,所有信号都不会变为'X'。
如果处理器处于等待模式,并且没有待处理的指令,它必须在100个时钟内断言一个SleepReq到内存子系统。
在紧急中断时,外部时钟/控制逻辑块必须在10个时钟内声明CPU_wakeup。
让我们考虑一下PCI Read的一个简单例子。根据图2.8的规范,设计团队会添加哪种类型的断言以及验证团队将添加什么类型断言?下表描述了这些差异。我只给出了几个可以写出来的断言。验证和设计工程师需要写更多的断言。但是,这个例子是作为区分的基础。
设计人员在微架构级别添加断言,而验证工程师专注于系统级别,特别是本例中的接口级别。
我们将在LAB6练习下面的书中为这个PCI协议建立模型。在现阶段不知道基础知识的情况下跳入书面断言还为时过早。
PCI协议用于简单的读取。使用FRAME_断言,AD地址和C_BE_具有有效值。然后IRDY_被断言,表示主机已准备好接收数据。目标以间歇等待状态传输数据。在FRAME_无效后,最后一次数据传输发生在一个时钟。
让我们看看设计和验证工程师需要写什么类型的断言(表2.1和2.2)。
图2.8一个简单的PCI读协议
请注意,表中有两列。(1)property是否失败? (2)property是否被覆盖?没有列PASS属性。这是因为,只有在跑property被触发但不失败的情况下,断言中的“cover”才会触发;换句话说,它通过。因此,不需要PASS列。这个'cover'一栏告诉你,你确实覆盖(触发)了断言,并没有失败。当断言失败时,它会告诉你断言已被执行(covered),并且在执行过程中失败。
理解和规划需要添加的断言类型非常重要。这是做好你的验证计划的一部分。它还将帮助您在团队中分配工作。
请注意'性能含义'断言。很多人错过这一点。从处理器背景来看,我已经看到这些断言成为一些最有用的断言。这些断言会让我们知道(例如)缓存读取延迟,并允许我们有足够的时间进行架构更改。
•RTL断言(设计意图)
- 输入模块;
非法的状态转变; 死锁; 活锁; FIFOs,onehot等
•模块接口断言(设计接口意图)
- 模块间协议验证;非法组合(如果req为'0',ack不能为'1');稳定状态要求(当从设备声明write_queue_full时,主设备不能 声明write_req);
•芯片功能断言(芯片/ SoC功能意图)
- 导致目标重试的PCI事务最终将在重试队列中结束。
•芯片接口断言(芯片接口意图)
- 商业上可用的标准总线断言VIP可用于全面检查您的设计是否符合标准协议,如PCIX,AXI等。
- 每个关于IO功能的设计假设都是一个断言。
•性能含义断言(性能意图)
- 读取的缓存延迟; 数据包处理延迟; 在太迟之前捕获性能问题。这一说法与其他任何方式一样。例如,如果'Read Cache Latency'大于2个时钟,则请求断言。这是一个很容易写出断言,而且非常有用。
•不要复制RTL
- 白盒可观察性并不意味着为每行RTL代码添加断言。这是一个非常重要的观点,因为如果RTL表示'req'的意思是'授予',不要写 一个说同样的东西的断言!请继续阅读。
- 捕捉意图
例如,在读取之前总是允许在请求队列中跟随读取到同一地址的写入完成。这是设计的目的。设计师如何实施重新排序逻辑并 不是很有意思。所以,从验证的角度来看,您需要编写验证芯片规范的断言。
这里需要注意的是,以上并不意味着你不会添加低级断言。这里的经典示例是FIFO断言。为您的设计中的所有FIFO写入FIFO 断言。 FIFO是低级逻辑,但许多重要的错误都是围绕着FIFO逻辑,并且添加这些断言将为您的验证提供最大限度的提升。
•在整个RTL设计过程中添加断言
- 他们很难作为后续思考添加。
- 即使使用简单的模块级测试平台,也能帮助您发现错误。
•如果断言没有发现失败。
- 如果测试失败并且没有任何断言提示,请查看是否存在需要添加的可用于失败情况的断言。
- 新添加的断言现在可用于任何其他可能触发它的测试。
注意:如果添加了足够多的断言,这一点对于做出决定非常重要。换句话说,如果测试失败并且没有任何断言提示,那么很可 能 还有更多的断言要添加。
•可重用性
- 使用可以通过'实际'参数实例化(重用)的形式来创建通用属性库。我们将在书中进一步介绍这一点。
- 下一个项目重用。
•这是“测试计划,测试计划,测试计划......”
- 根据设计规格审查并重新审查您的测试计划。
- 确保你为每个必须保证工作的“关键”功能添加了断言。
•如果测试保持失败,但断言无法解决,则说明没有足够的断言。
换句话说,如果您必须从主要输出(模块或SoC)中追踪缺少任何断言的错误,这意味着您没有提供足够的断言来覆盖该路径。
•“形式”(又名静态形式功能验证)工具处理断言的能力
- 这意味着如果你没有足够的“断言密度”(意思是说,如果一个寄存器值不会在3到5个时钟内传播到一个断言 - 导致设计中稀疏的断言),形式分析工具可能会给处理状态/空间爆炸问题。换句话说,一个静态函数形式工具可能无法处理一个大的时间域。如果断言密度很高,则该工具必须处理较小的逻辑锥。如果断言密度稀疏,则该工具必须在时间和空间组合中处理更大的逻辑锥,并且可能会遇到麻烦。
•为规则使用断言(属性/序列)
- DV(设计验证)团队:
尽可能多地将您的测试计划中的“响应检查”部分记录为可行的,直接写入可执行属性中。
用它来验证计划审查和更新
- 设计团队:
将微结构级断言直接记录到可执行属性中。
用它来进行设计评审。
•断言交叉评审
- 评审
DV团队与设计团队一起审查宏,芯片,接口级别的断言。
- 交叉评审
模块A设计者审查模块B的接口断言
模块B设计者评论模块A的接口断言
- 错误的假设,错误的沟通在早期被发现。
SVA支持三种断言。简而言之,这是他们的描述。我们将在本书中详细讨论它们。
•立即断言
•并发断言
•延迟断言(在IEEE 1800-2009中引入)
立即断言
•简单的非时间域断言,像程序块中的语句一样执行,
•与程序性'if'陈述条件中的表达式的解释方式相同
•只有在规定程序性说明的情况下才能指定。
并发断言
•这些是时域断言,允许使用基于时钟(采样边缘)的语义创建复杂序列。
•它们对边缘敏感并且不对电平敏感。换句话说,它们必须有一个“采样边缘”,它可以对序列或属性中使用的变量值进行采样。
延迟断言(在IEEE 1800-2009中引入)
•延迟断言是一种立即断言。请注意,立即断言立即进行评估,无需等待其组合表达式中的变量稳定下来。这也意味着当组合表达式稳定下来并且可能多次执行时,立即断言很容易出现小故障。另一方面,延迟断言不会评估它们的序列表达式,直到所有值已经定下来(或在时间戳的反应区域中)时为止。
如果其中一些不太合理,那也没关系。这就是本书其余部分将解释的内容。让我们从立即断言开始并理解它的语义。然后,我们继续讨论并发断言和最后的延迟断言。本书侧重于并发断言,因为这实际上是SystemVerilog断言语言的主要依据。
表2.3本书中使用的约定
LEVEL SENSITIVE HIGH:此符号表示在时序图中记录的时钟边沿检测到信号为高电平(电平敏感)。它可能是前一时钟的高电平或低电平,并可能在时钟沿后保持高电平或低电平。然而,这并不意味着在指定时钟边缘的这个信号上会出现“posedge”。
LEVEL SENSITIVE LOW:此符号表示在时序图中记录的时钟边沿检测到信号为低电平(电平敏感)。它可能是前一时钟的高电平或低电平,并可能在时钟沿后保持高电平或低电平。然而,这并不意味着在该时钟边缘的信号上会出现'negedge'。
EDGE SENSITIVE HIGH:这个符号意味着这个信号是一个上升沿。
EDGE SENSITIVE LOW:这个符号意味着这个信号是一个下降沿。
PROPERTY PASSES:此符号表示在此处检测到序列/属性匹配(即序列/属性PASSes)。
PROPERTY FAILs:这个符号表示一个序列/属性在这里不匹配(即序列/属性FAILs)。
请注意,信号的电平敏感属性显示为“胖”高位和低位符号。我可以画出正常的时序图,但看到它们看起来非常麻烦并且不容易传达这一点。因此,我选择了胖箭头来表达,当胖箭头高时,信号在时钟之前是高的;在时钟和时钟之后。这同样适用于胖低箭头。
对于边缘敏感的断言,我选择了常规的时序图来区分它们与电平敏感的符号。
高(细)箭头用于PASS,低(细)箭头用于FAIL(表2.3)。
转载https://blog.csdn.net/zhajio/article/details/80007604