第4章 并发断言:基础(序列,属性,断言) 您所在的位置:网站首页 iff计算机 第4章 并发断言:基础(序列,属性,断言)

第4章 并发断言:基础(序列,属性,断言)

2024-01-14 16:50| 来源: 网络整理| 查看: 265

这些是时域断言,允许使用基于时钟(采样)边缘的语义创建复杂序列。这与完全组合逻辑的立即断言相反,并且不允许时域序列。

 并发断言是SVA语言的要旨。它们被称为并发,因为它们与其余的设计逻辑并行执行。让我们从基础开始,继续讨论并发断言的复杂概念。

 让我们先学习并发断言的基本语法,然后研究它的语义。

                                                 图4.1并发断言 - 基础

 在图4.1中,我们已经声明了一个属性'pr1',并用'reqGnt'标签声明它(标签是可选的,但是强烈推荐)。该图解释了并发断言的各个部分,包括一个属性;一个序列和属性的断言。

 'assert property(pr1)'语句触发属性'pr1'。 'pr1'反过来等待先行词'cStart'在(posedge clk)处为真,并且它是真意味着将(激发)一个叫做'sr1'的序列。 'sr1'检查发现'req'在被触发时为高,而2个'时钟'后'gnt'为真。如果这个时域条件满足,那么序列'sr1'将通过,属性'pr1'和'断言属性'也将成为PASS。让我们继续这个例子并研究其他关键语义。

                                     图4.2并发断言 - 采样边沿和动作块

 如图4.2所示,以下是断言的基本和必需部分。随着文章的继续,这些功能中的每一个都将被进一步解释和研究。

(1)'断言' - 你必须断言一个属性;即调用或触发它。

(2)有一个动作块与断言的通过或失败相关联。

(3)'property pr1'是在clk的上升沿边沿触发的(更多的是你必须有一个触发采样边缘的事实将在下面进一步解释)。

(4)'属性pr1'有一个前提,它是一个叫做cStart的信号,如果在posedge clk上被采样为高电平(在预定区域内),将暗示执行结果(序列sr1)。

(5)对序列sr1采样'req'并进行序列分析,以确定它是否在其触发时恰好为高(即,当由于重叠蕴涵运算符而触发序列时,在相同的clk上升沿),然后等待2个时钟并看'gnt'信号是否为高。

(6)注意,'cStart','req','gnt'中的每一个都是在属性中'clk'的posedge指定的边缘处采样的。换句话说,即使在序列中没有指定采样边沿,边沿将从属性pr1继承。

 还要注意的是,我们正在使用在posedge clk上取样值的概念,这意味着'posedge clk'是'采样边缘'。换句话说,采样边缘可以是任何东西(只要它是边缘而不是电平敏感的),这意味着它不一定必须是诸如时钟的同步边缘。它也可以是异步边缘。但是,要非常小心地使用异步边缘,除非您确定要实现的目标。我已经用了一个完整的例子来说明使用异步边沿作为采样边沿的缺陷。现在进入还为时尚早。这是并行断言中一个非常重要的概念,应该很好理解。但是,不要担心,随着我们的进一步发展,您将获得更多的洞察力。

 现在,让我们略微修改序列'sr1'以突出显示序列或属性中的布尔表达式,并研究并发断言的更多关键元素。

                                      图4.3并发断言 - 蕴含,前因和后果

 如图4.3所示,表达式的三个主要部分决定了断言何时触发,触发事件和触发事件与执行事件之间的持续时间。

 断言将被触发的条件称为“前因”,这是蕴涵算子的LHS。

一旦前面的匹配,断言的RHS被执行,称为“后果”。

'蕴涵'操作符决定了先行词和后续词之间的时间间隔。换句话说,蕴涵运算符以两种方式之一将先行词和后续词联系起来。它将它们与'重叠'蕴涵算子或'非重叠'蕴涵算子联系起来。 “理解”蕴含运算符的方式是“如果先行词匹配,结果将被执行。如果没有匹配,结果将不会触发,并且断言将继续等待先行词的匹配。

                                                 图4.4 带嵌入序列的属性

 图4.4进一步解释了先行词和结果。如图所示,您不必为了建模属性而创建序列。如果后续执行的逻辑足够简单,那么它可以直接在所示的结果中声明。但请注意,最好将属性分解成更小的序列以建模复杂的属性/序列。因此,考虑这个例子只是描述语言的语义。实践应该是分而治之。你会看到很多例子,这些例子看起来非常复杂,但是一旦你把它们分解成更小的逻辑块并且用更小的序列对它们进行建模,那么将所有这些结合在一起编写一个长的复杂断言序列会更容易。

 4.1 蕴涵运算符,前提和结果

                                            图4.5蕴涵运算符重叠和不重叠

 蕴涵运算符将先行词和后续词联系起来。如果先行词成立,则意味着结果应该成立。

 有两种类型的蕴涵算子,如图4.5所示。

 (1)重叠蕴涵运算符:参考图4.5,最上面的属性显示使用重叠运算符。 注意它的符号(|->),它不同于非重叠运算符(|=>)。 重叠意味着,当前提被发现是真实的,在'同一'时钟,后果将启动它的执行(评估)。 如图所示,当cStart在clk的posedge采样为High时,在相同的posedge clk时req需要为High。 这显示在与该属性相关的时序图中。  a. 那么,如果'req'在先行词之后的下一个posedge clk被抽样(以及之前的false),那么会发生什么? 重叠属性会通过吗? 

 (2)非重叠蕴涵运算符:相反,非重叠意味着当前提被发现是真的时,结果应该在一个时钟后启动它的执行。这显示在与该属性相关的时序图中。

   b. 那么,如果'req'在与先行词相同的posedge clk上被抽样(以及之后的False),会发生什么?非重叠属性会通过吗?

对1.a和2.a的答案是否定的。

                                 图4.6重叠和非重叠蕴涵算子的等价性

 图4.6 进一步显示了重叠运算符和非重叠运算符之间的等价关系。 '|=>'相当于'|-> ## 1'。请注意,## 1与Verilog的#1延迟不同。 ## 1表示一个时钟沿(采样沿)。因此'|-> ## 1'表示与'|=>'相同。

 建议:为了使调试更容易并且项目广泛统一,在断言中使用重叠操作符。原因?重叠是两类操作符的共同点。您始终可以建立从重叠到非重叠的模型,但反之亦然。这意味着在调试过程中,每个人都会知道所有属性都使用重叠进行建模,并且时钟数与属性中指定的完全相同。您不必添加或减少芯片规范中指定的时钟数量。更重要的是,如果每个人都使用他或她最喜欢的操作员,调试将是非常混乱,不知道哪个属性使用哪个操作符。

 4.2 时钟基础

                                                         图4.7时钟基础

 如前所述,并发断言​​仅在出现“边缘”时被评估,称为“采样边缘”。将“边缘”不断提及为“clk”的原因是因为最好让这个“边缘”与信号的posedge或negedge同步。你确实可以有一个异步边缘。但要非常小心。我已经使用了一个完整的例子来解释异步边沿的断言是如何工作的。它变得非常复杂,我极力阻止你写异步断言,除非你确定你知道你在做什么。在图4.7中,我们使用的是非重叠蕴涵运算符,这意味着在clk的上升沿处如果cStart为高,然后在一个时钟之后执行sr1。

 让我们重新讨论变量的“采样”。表达式变量cStart,req和gnt全部在posedge clk的预定区域中被采样。换句话说,如果(例如)cStart = 1并且posedge clk同时改变,则推定区域中的cStart的采样值将等于“零”而不是“1”。我们很快就会讨论仿真时间刻度中“预测区域”的真实含义,以及它如何影响断言的评估,特别是当采样时钟边沿和采样变量同时发生变化时。

 再次请注意,'sequence sr1'在其表达式中没有时钟。 'sequence sr1'的时钟是从'property pr1'继承的。接下来使用图4.8解释这一点。

                    图4.8“assert”,“property”和“sequence”中的时钟 - 时钟基础

 正如图4.8所解释的那样,'clk'作为边沿可以直接在assert语句中指定,也可以在属性中或序列中指定。无论它在哪里声明,它都会被整个断言(即断言,属性和序列块)继承。

 建议:如图4.8所示,我的建议是在属性中指定'clk'。原因是你可以保持序列没有采样边缘(即'clk'),因此使它们可重用。采样边沿可以在属性中改变,但序列(或级联序列)保持不变,并且可以改变其逻辑,而不用担心采样边沿。请注意,在属性中先行词的前面声明采样边沿'clk',也更具可读性。在clk的posedge,如果cStart为高,触发sr1。

 4.3采样边沿(时钟边沿)值:如何在仿真时间刻度中评估断言?

                                                 图4.9在模拟时间标记中断言可变采样和评估/执行

 所谓的采样边沿如何对属性或序列中的变量进行采样是设计断言时需要了解的最重要概念之一。如图4.9所示,需要注意的重要一点是,断言(属性/序列/表达式)中使用的变量在“预设”区域中进行采样。那是什么意思?它意味着(例如)如果采样变量与采样边沿(例如clk)同时发生变化,那么变量的值将成为它在时钟边缘之前保持的值。

 @(posedge clk)a | =>!a;

在上面的序列中,让我们假设变量'a'在采样边沿时钟变为posedge clk的同时变为'1'(并且假设'a'在变为'1'之前为'0')。会不会有先行者'a'的匹配?没有!由于在时钟到达posedge clk的同时'从'0'变为'1',因此按时钟采样的'a'的值将为'0'(预定区域)而不是'1'。这不会导致属性被触发,因为先行词没有被评估为真。这在调试过程中会让你感到困惑。你会期望'1'被采样并且属性触发了它。但是,你会得到相反的结果。

 这是一个非常重要的理解点,因为在仿真波形中(或者对于Verilog $monitor或$strobe),你会看到'a'上的'1'和posedge clk,并且不理解为什么该属性没有触发或为什么它失败(或通过)。务必记住,在采样边沿处,使用采样变量的“先前”值(即,在预定区域中的采样边沿之前的delta)。

 这里有一个完整的例子,包括测试平台和评论,解释了推定区域中变量的采样如何影响断言结果。

module assert1; reg A, B, C, D, clk; property ab; @ (posedge clk) !A |-[B; endproperty aba: assert property (ab) else $display($stime,,, 憫ab FAIL拻); abc: cover property (ab) $display($stime,,, 憫ab PASS拻); initial begin clk = 0; A = 0; B = 0; //Note: A and B are equal to ??at time 0. forever #10 clk = !clk; end initial begin `ifdef PASS

 / *以下一系列事件将导致属性'ab'通过,因为即使A = 0和B =1同时改变,他们也已经因为#1在posedge clk之前采样下来。因此当@(posedge clk)采样A,B; A = 0和B = 1被采样。属性先行词'!A'被评估为真,并且在同一时间(重叠运算符)B == 1。因此,属性通过* /

A = 0; B = 1; #1; @ (posedge clk) `else

 / *以下事件序列将导致属性'ab'失败。这是故事。 A = 0和B= 1与posedge clk同时改变。这导致B的采样值等于'0'而不等于'1',因为采样边沿(posedgeclk)对推定区域中的变量值进行采样并且在推定区域中B等于'0'。请注意,由于在上面的“初始”块中进行了初始化,所以在推定区域中A等于'0'。所以,现在你的'A'和'B'都是0,因为A是0,!A是真实的,并且属性评估发生。属性期望B == 1在同一时间(重叠运算符)!A是真实的。但是,'B的采样值是'0'并且属性失败。 */

@ (posedge clk) A = 0; B = 1; `endif @ (negedge clk) $finish(2); end endmodule  4.3.1 默认时钟模块

 对于文件中的长链属性和序列,您还可以使用默认时钟模块,如图4.10所示。这个图片可以用不同的方式来说明,在这些方式中可以声明时钟块以及它的有效范围。图中的顶部显示了'default clocking cb1'的声明,然后由后面的属性'checkReqGnt'和'checkBusGrant'继承。这个默认时钟模块将会有效,直到定义了另一个默认时钟模块。该图的底部部分很有趣。这里的属性直接嵌入到默认的时钟模块中。我不推荐这样做。时钟模块应该只包含时钟规格,这将保持模块化和可重用。在这些问题上明智地使用你的判断。

                                                            图4.10默认时钟模块

 图4.11在独立的Verilog模块中声明了两个时钟块,即'cb1'和'cb2',称为'design_clocks'。这是在一个模块中组织您的时钟策略的好方法。一旦定义好,就可以使用任何所需的时钟块,只需通过图中所示的分层实例名称引用它即可。

这是一些需要思考的方案。我概述了使用默认时钟模块的一些优缺点。这是最有利的,但有一些警告。

优点:对默认块的争论是可重用性。您可以更改默认块中的时钟关系,它将适用于以下所有块。您不必在每个属性中单独更改计时方案。这确实是一个真正的优势,如果您计划在默认块中更改时钟方案而不影响后续属性,请务必使用默认块。

                                             图4.11'时钟'和'默认时钟'

 缺点:可读性/可调性:当你看到一个没有采样边沿的属性时,你必须回滚到属性上方的'someplace'来查看正在使用的采样边沿。你必须找到先前的时钟块,不能只是去文件的顶部。我喜欢大多数采样边沿独立的属性。当然,这意外多敲几行代码,但更具可读性。

 4.3.2门控时钟

 图4.12显示了一个有趣的使用门控时钟作为属性采样边沿建模的应用。请注意,assign超出了断言的范围。但它的分配值'clkstart'确实可以用在属性中。一般来说,在定义属性/序列的给定范围内声明的任何变量都可用于断言。如果声明在模块外声明,但使用“绑定”方法绑定到模块,则适用相同的规则。更多关于'绑定'的声明即将推出。在这个例子中,采样边将是(clk和cGate)的posedge。在这个采样边的预定区域,属性和序列中的变量将被采样。

                                图4.12 门控时钟

 4.4并发断言是多线程的

 这是关于并发断言时需要掌握的最重要的概念。我们都知道SystemVerilog是一种并发语言,但它是多线程的(除了使用自动变量时)? SVA默认是并发和多线程的。

                                                 图4.13多线程并发断言

 在图4.13中,我们已经声明了与之前见过的相同的断言,即在posedge clk中,如果cStart采样为高电平,sr1将在相同的posedge clk触发,然后查找'req'为高电平时钟和'gnt'在两个时钟后被采样高电平。

 现在,让我们说cStart在clk的边沿被采样为高电平(S1),并且'req'也在同一个边沿被采样为高电平。在此posedge clk之后,序列将等待2个时钟,以查看'gnt'是否为高电平。

 但是在两个时钟结束之前,clk cStart在采样为高电平后恰好两个时钟变低,然后变为高电平(S2)。当我们的断言的第一个触发器将寻找gnt为高(S1)时,这也是相同的边沿。那么,这个断言会做什么?它是否会因为满足其先前条件而重新启动(S2),并忽略从第一个触发器(S1)等待的'gnt'?不,它不会忽略'gnt'。它将采样'gnt'为高(S1)并考虑第一个触发(cStart(S1))为PASS。那么,第二个触发器(cStart(S2))会发生什么?它会启动另一个线程。它会再等待2个时钟来检查'gnt'。到现在为止还挺好。我们看到一个SVA实例被线程化了。

但是生活变得更有趣了。

在S2之后,下一个时钟cStart再次被采样为高电平(S3)。 'req'也是高(req(S3))。现在断言会做什么?那么,S3将自己与S2线程。换句话说,现在有两个截然不同的触发器,等待在触发后的两个时钟采样'gnt'。这个图片完美的指出(!)在S2和S3之后,两个时钟'gnt'应当为高,并且所有3个相同断言都将被触发,且为PASS。

这在断言的设计和性能方面有很多含义。当我们讨论边沿触发的先行词时,我们将进一步讨论这一点。换句话说,我们例子中的属性编码的方式,它会拖累你的仿真器的性能,因为每当属性看到cStart在clk posedge处于高位时,它就会启动一个新线程。但是如果你只是想在cStart的第一次上升沿时评估这个属性,并且如果它保持高就忽略它(除非它再次变低并且再次变高),那么你必须使用边沿敏感先行词。更多关于这个的点将在Chap5阐述. 另外,多线程语言的概念变得更加有趣,你将在Sect. 6.2.1中看到。

 4.5形式参数

 断言的一个关键特征是它们可以被参数化。换句话说,断言可以用形式参数来设计,以保持它们的通用性,以便用于不同的实际参数。

图4.14是不言自明的。请注意,形式参数可以按照序列,属性以及assert语句进行指定。

这个应用在重用性方面显示了形式参数的优势。属性'noChangeSig'有3个形式参数,即pclk,refSig和Sig。该属性检查如果refSig在posedge pclk取样为高,那么Sig不是未知的。一旦这样的通用属性被写入,你可以用不同的clk,不同的refSig和Sig来调用它。 CheckRd是一个属性,它使用sysClk和OE_和RdData来检查未知条件,而CheckWr使用WE_和WrData来检查WrData是否未知。

                                                        图4.14形式和实际参数

 在任何项目中,都有可以通过传递不同的实际参数多次重用的通用属性。这不仅可以在同一个项目中重复使用,还可以在不同项目中重复使用。

有些公司已经创建了这样的属性池,可以根据项目的需要查找并重用。

如图4.15所示,属性可以是基于位置的以及以名字为基础得连接。我强烈建议使用基于名称的形式,以确保实际内容与正确的形式相关联,而不会含糊不清。该规则与我们用于Verilog端口连接的规则相同。

图4.16描述了以下几点

(1)可以将默认值分配给形式参数。

a. 如果实际和正式都指定了“默认”值,则实际值会覆盖默认值b. 如果形式具有默认值,您可以不通过实际的形式。请参考图4.16。

 

                        图4.15形式参数和实际参数 - 默认值和基于名称的连接

                     图4.16形式参数和实际参数 - 默认值和基于位置的连接

                                图4.17将事件控制传递给一个形参

 这是一个非常有趣的功能,对于可重用性非常有用。形参也可以用于事件控制。采样边沿可以作为实际参数传递给形参,并且实际可以用作属性中的采样边沿。我们通过'posedge clk'作为实际的'csig'。该属性使用@(csig),因为它是采样边沿。当'possclk'作为实际参数调用属性'pr1'时,'@(csig)'将变为'@(posedge clk)'。为了清楚起见,请参考图4.17。这些属性实际上可以成为一个共同的属性池中的一部分,单个项目可以通过自己的采样边沿规格重复使用。

 4.6禁用(属性)操作符:'disable iff’

'当然,您需要一种方法来在电路不稳定的条件下禁用属性(请考虑Reset)。这正是'disable iff'操作符所做的。它允许您在给定条件下显式禁用该属性。请注意,'disable iff'应当解释为'禁用当且仅当'。图4.18中的示例显示了如何在激活的复位期间禁用断言。您很有可能会在整个项目的所有属性中使用基于复位的禁用方法。注意下面的规则'disable iff'

 (1)'禁用iff'只能用于属性 - 而不是序列。 (2)'禁用iff'只能在声明先行条件之前使用。

 好的,如果一个属性开始执行并且在其执行过程中出现'disable iff'条件,会发生什么?

图4.18中的属性检查sdack_落入(即包含)在soe_中(不用担心,我们将在后面的章节中看到这些属性是如何工作的)。它也有'disable iff(!reset)'条件。如果复位信号被置位(低电平有效),则禁用该属性。

 让我们来看看仿真日志。

                                                          图4.16 ‘disable iff’操作符

 在LHS仿真日志中,复位从不被置位并且断言完成(并且在这种情况下通过)。

 在RHS模拟块中,复位在检查'sdack_中的soe'中间时被置位。猜猜看,整个断言都被丢弃了。你不会看到这个断言的通过/失败,因为它已被丢弃。如果disable iff条件发生在执行断言的中间,则整个断言将被禁用。有些人把这种丢弃视为失败,这是不正确的。

 一旦使用'disable iff'构造禁用了断言,只有'disable iff'条件不再成立后,它才会重新启动。

 正如我们将在Sect. 7.4中讨论的那样,仿真器会提供系统函数对断言执行进行全局控制。

 4.7严重级别(针对并发和立即断言)

                                     图4.19并发和即时断言的严重级别

 断言还允许具有不同严重级别的错误报告。 $fatal,$errot(默认),$warning和$info。图4.19解释了每一个的含义。

$error是默认,这意味着如果在assert语句中没有指定失败子句,$error将启动并提供仿真器生成错误消息。如果你已经为断言指定了一个标签(并且你应该有),那么(很可能)会显示在$error消息中。我说很可能是因为SystemVerilog LRM没有指定$ error的确切格式。它是仿真器供应商特定的。 $ warning和$ info是不言自明的,如图4.19所示。

 4.8绑定属性

 '绑定'允许我们将设计逻辑与断言逻辑分开。设计经理不喜欢在RTL中看到任何不能被综合的东西。 '绑定'有助于朝这个方向发展。

                                            图4.20 绑定属性

 图4.20中有三个模块。 'designModule'包含设计。 'propertyModule'包含对'designModule'中的逻辑进行操作的断言/属性。 'test_bindProperty'模块将propertyModule绑定到designModule。通过这样做,我们将'propertyModule'的属性与'designModule'分开。这就是'绑定'背后的想法。您不必将属性放置在与设计模块相同的模块中。如前所述,您应该让您的设计避免无法综合的所有语法结构。此外,将断言和设计保留在单独的模块中,可以使设计人员和DV工程师并行工作,而不受数据库管理系统的限制,其中一个文件不能同时由两名工程师修改。

为了使用'绑定'您必须在“绑定”语句中声明designModule的实例名称或模块名称。您需要设计模块/实例名称,属性模块名称和“绑定”实例名称才能使用。在我们的例子中,设计模块名称是designModule,它的实例名是'dM',属性模块名是propertyModule。

(未注释的)'bind'语句使用模块实例'dM'并将其绑定到属性模块'propertyModule '并给这个'绑定'一个实例名称'dpM'。它将propertyModule的端口与designModule的端口连接在一起。propertyModule中的'property rc1'将作用于连接的designModule端口。

注释的'bind'语句使用模块名'designModule'绑定到'propertyModule ''designModule'的所有实例都将绑定到'propertyModule'。

本质上,我们已经将设计的属性/断言和设计的逻辑分开。这是推荐的方法。通过将属性放置在与设计模块相同的模块中,您可以获得相同的结果,但这是高度非模块化和侵入式的方法。另外,如上所述,保持它们分离可使DV和设计工程师并行工作。

 4.8.1绑定属性(范围可见性)

 但是如果要将propertyModule的断言绑定到designModule的内部信号呢?这非常可行。

如图4.21所示,'rda'和'rdb'是designModule内部的信号。这些是您想要在'propertyModule'的断言中使用的信号。因此,您需要使'rda'和'rdb'对'propertyModule'可见。但是,您不想将'designModule'内部变量带到外部端口,以使其对'propertyModule'可见。你想保持'designModule'完全不变。为此,需要将输入端口添加到'propertyModule',并将其绑定到'designModule'的内部信号,如图4.21所示。请注意,在我们的示例中,我们将propertyModule端口的'pa'和'pb'绑定到designModule内部寄存器'rda'和'rdb'。换句话说,您可以在'绑定'期间直接引用designModule的内部信号。 'bind'具有对绑定模块'designModule'的完全可见范围。请注意,使用此方法,绑定到'propertyModule'输入端口时不必提供整个层次实例名称。

                         图4.21绑定属性到设计“模块”内部信号(范围可视性)

 4.8.2现有设计中的采用断言

 图4.22显示了如果你有一个现有的设计,你可以有效地使用'bind'结构在设计范围之外编写断言并绑定它们。如果您要在新的SoC中引入传统模块并希望确保传统模块在新设计中正常工作,这可能非常有用。这个图片展示的是方法论的一部分。在您的项目之前,确定您的“绑定”方法。看到所有的断言都在RTL之外,并且不是RTL中的一些混乱的混合,而是一些与外部属性文件绑定的混合。

                                                 图4.22绑定到现有设计的属性。断言在现有设计中的采用

 将断言保存在单独文件中的其他优点是可以独立验证它们,而无需控制RTL文件。当你想确保设计和验证同时进行时,这是一个很大的优势。

 4.9'序列'和'属性'之间的区别

 现在我们已经看到了使用序列和属性的断言,重新回顾并清楚地理解两者之间的差异是很好的。

 •“序列”

    - 序列是一个构建块。把它想象成一个宏或者一个子程序,你可以为给定的一组信号定义一个特定的关系。

    -  一个序列本身不会触发。它必须被断言。

    - 一个序列不允许蕴涵运算符。简单地允许信号之间的时域(或组合)关系。

    - 一个序列可以有可选的形式参数。

    - 一个时钟事件可以在一个序列中使用。

    - 一个序列可以声明在模块,接口,程序,时钟块,包(但不在'类'中)。

 •'属性'

    - 一个属性也不会自行触发,直到'assert'(或'cover')。

    - 属性蕴涵运算符,暗示先行词和后续词之间的关系。

    - 序列可以用作复杂属性的构建块。

    - 时钟事件可以应用在属性中,在序列中或者在两者中。

    - 一个属性可以声明在一个模块,一个接口,一个程序,一个时钟块,一个包(但不在'类'中)。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有