返回介绍

17.5 序列

发布于 2020-09-09 22:55:53 字数 5213 浏览 921 评论 0 收藏 0

sequence_expr ::=          // 引用自附录A.2.10
    cycle_delay_range sequence_expr {cycle_delay_range sequence_expr}
  | sequence_expr cycle_delay_range sequence_expr {cycle_delay_range sequence_expr}
  | expression_or_dist [boolean_abbrev]
  | (expression_or_dist {, sequence_match_item}) [boolean_abbrev]
  | sequence_instance [sequence_abbrev]
  | (sequence_expr {, sequence_match_item}) [sequence_abbrev]
  | sequence_expr and sequence_expr
  | sequence_expr intersect sequence_expr
  | sequence_expr or sequence_expr
  | first_match(sequence_expr {, sequence_match_item})
  | expression_or_dist throughout sequence_expr
  | sequence_expr within sequence_expr
  | clocking_event sequence_expr

cycle_delay_range ::=
    ## integral_number
  | ## identifier
  | ## (constant_expression)
  | ## [cycle_delay_const_range_expression]

sequence_match_item ::=
    operator_assignment
  | inc_or_dec_expression
  | subroutine_call

sequence_instance ::=
    ps_sequence_identifier [([actual_arg_list])]

actual_arg_list ::=
    actual_arg_expr {, actual_arg_expr}
  | .formal_identifier(actual_arg_expr) {, .formal_identifier(actual_arg_expr)}

actual_arg_expr ::=
    event_expression
  | $

boolean_abbrev ::=
    consecutive_repetition
  | non_consecutive_repetition
  | goto_repetition

sequence_abbrev ::= consecutive_repetition

consecutive_repetition ::= [* const_or_range_expression]

non_consecutive_repetition ::= [= const_or_range_expression]

goto_repetition ::= [-> const_or_range_expression]

const_or_range_expression ::=
    constant_expression
  | cycle_delay_const_range_expression

cycle_delay_const_range_expression ::=
    constant_expression : constant_expression
  | constant_expression : $
expression_or_dist ::= expression[dist{dist_list}]

语法17-2 — 序列语法(摘录自附录A)

特性经常由有序的行为构建。sequence功能提供了一种能力来构建和处理有序的行为。最简单的有序行为是线性的。一个线性序列是SystemVerilog布尔表达式的一个有限列表,这些表达式以一个线性增加的时间顺序排列。如果第一个布尔表达式在第一个时钟标记处被计算成“真”,第二个布尔表达式在第二个时钟标记处被计算成“真”,依此类推,直到并包括最后一个布尔表达式在最后一个时钟标记被计算成“真”,那么这个线性序列被说成在一个连续时钟标记的有限间隔上匹配。单个布尔表达式是一个简单线性序列的一个例子,并且它在单个时钟标记处匹配,只要在这个时钟标记处该布尔表达式被计算成“真”。

更为复杂的有序行为通过SystemVerilog序列来描述。一个序列是一个基于SystemVerilog布尔表达式的正则表达式,它简明地说明了一组零个、有限多或无限多的线性序列。如果这个集合中的线性序列中至少有一个匹配于一个连续时钟标记的有限间隔,那么序列就被认为在这个间隔上匹配。

一个特性可能包含一个或多个开始于不同时间的有序行为的检查。一个序列的计算是一次搜索起始始于一个特定时钟标记的序列匹配的过程。为了确定是否存在一个这样的匹配,在特定的时钟标记处开始计算合适的布尔表达式并在后续的时钟标记上持续直到找到一个匹配或者由于不存在匹配而中止。

类似于链表的串联,序列可以由串联组成。串联使用##指定了一个从第一个序列的结尾直到第二个序列的开始的延时。

下述为序列串联的语法:

sequence_expr ::=          // 引用自附录A.2.10
    cycle_delay_range sequence_expr {cycle_delay_range sequence_expr}
  | sequence_expr cycle_delay_range sequence_expr {cycle_delay_range sequence_expr}
  ...

cycle_delay_range ::=
    ## integral_number
  | ## identifier
  | ## (constant_expression)
  | ## [cycle_delay_const_range_expression]

cycle_delay_const_range_expression ::=
    constant_expression : constant_expression
  | constant_expression : $

语法17-3 — 序列串联语法(摘录自附录A)

在此语法中:

  • constant_expression在编译时计算并且必须产生一个整数值。
  • constant_expression只能是0或者更大。
  • $标记被用来指示仿真的结束。对于形式验证工具,$被用来指示一个有限的、 无边界的范围。
  • 当一个范围使用两个表达式说明的时候,第二个表达式必须大于或等于第一个表达式。

一个序列出现的语境决定了序列何时被计算。序列中的第一个表达式在触发序列计算的表达式的第一个时钟标记处被检查。序列中的每一个后续的元素(如果有的话)在后续的时钟被检查。

一个紧跟着一个数字或范围的##说明了从当前时钟标记到下一个序列开始的延时。延时##1指示后续序列在当前时钟标记之后的一个时钟标记开始。延时##0指示下一个序列开始于与当前时钟标记相同的时钟标记。

当作为两个序列的串联使用的时候,这个延时指的是从第一个序列的结尾到第二个序列的开始之间的延时。延时##1指示第二个序列的开始在第一个序列结束后的一个时钟标记。延时##0指示第二个序列的开始于第一个序列的结尾处于同一个时钟标记。

下面是几个延时表达式的例子,`true是一个布尔表达式,它总是被计算成“真”,这样它具有很好的直观性。它可以按如下方式定义:

`define true 1
##0 a     // means a
##1 a     // means ‘true ##1 a
##2 a     // means ‘true ##1 ‘true ##1 a
##[0:3]a  // means (a) or (`true ##1 a) or (`true ##1 `true ##1 a) or
          // (‘true ##1 ‘true ##1 ‘true ##1 a)
a ##2 b   // means a ##1 ‘true ##1 b

对于下面的序列:

req ##1 gnt ##1 !req

这个序列指出req在当前的时钟标记为真,gnt应该在第一个后续的时钟标记处为真,并且req应该在此之后的下一个时钟标记处为假。##1操作符说明了一个时钟标记的间隔。多于一个时钟标记的延时可以按下列方式说明:

req ##2 gnt

上面的例子指出,req应该在当前的时钟标记处为真,并且gnt应该在后续的第二个时钟标记处为真,如图17-2所示。

图17-2 — 序列的串联

下面的例子说明信号b应该在信号a之后的第N个时钟标记处为真:

a ##N b // 在第N个采样上检查b

为了说明一个交叠序列的串联(其中一个序列的结束点与下一个序列的起始点冲突),需要使用一个为0的值,如下例所示:

a ##1 b ##1 c // 第一个序列seq1
d ##1 e ##1 f // 第二个序列seq2
(a ##1 b ##1 c) ##0 (d ##1 e ##1 f) // 交叠的串联

在上面的例子中,c必须在序列seq1的结束点上为“真”,并且d必须在序列seq2的起始处为“真”。当使用0时钟标记延时串联的时候,cd必须在同一时刻为“真”,因此产生了一个等价于下面例子的串联的序列:

a ##1 b ##1 c&&d ##1 e ##1 f

同时需要注意的是:在序列之间没有其它形式的交叠能够使用串联操作进行表达。

在延时可以是一个范围内任意值的情况下,一个时间窗口可以使用下列形式指定:

req ##[4:32] gnt

在上面的例子中,信号req必须在当前的时钟标记为真,并且信号gnt必须在当前时钟标记之后的第4个和第32个时钟标记之间的某个时钟标记处为“真”。

通过使用$,这个时间窗口可以被扩展到一个有限的、但无边界的范围,如下面的例子所示。

req ##[4:$] gnt

通过与`true串联,一个序列可以被无条件地扩展。

a ##1 b ##1 c ##3 ‘true

当满足了信号c之后,序列长度被扩展了3个时钟标记。当通过较简单的序列来构建复杂序列的时候可以要求这样的在序列长度上的调整。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文