购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

1.3 Verilog HDL时序检查

本节将介绍在指定块中如何使用时序检查来确定信号是否遵守时序约束。

1.3.1 时序检查概述

时序检查可以放在指定块中,通过确保关键事件在给定的时间限制内发生来验证设计的时序性能。为了方便起见,将时序检查分成两组。第一组时序检查是根据稳定性时间窗口描述的:

第二组中的定时检查检查时钟和控制信号,并根据两个事件之间的时间差进行描述($nochange检查涉及三个事件):

尽管它们以$开头,但是时序检查不是系统任务。由于历史原因,出现前导“$”,定时检查不应该与系统任务混淆。特别是指定块中不能出现任何系统任务,在过程代码中也不能出现任何时序检查。

一些时序检查能接受负限制值。所有时序检查都有一个参考事件和一个数据事件,并且布尔条件可以与每个事件相关联。有些检查有两个信号自变量,其中一个是引用事件,另一个是数据事件。其他检查只有一个信号自变量,参考事件和数据事件都是从中得出的。只有当相关条件为真时,才能通过时序检查检测到参考事件和数据事件。

时序检查评估基于两个事件的时间,这两个事件分别称为时间戳事件和时间检查事件。时间戳事件信号上的跳变使仿真器记录(标记)跳变时间,以供将来在评估时序检查时使用。时间检查事件信号上的跳变导致仿真器实际评估时序检查以确定是否发生了冲突。

对于某些检查,参考事件总是时间戳事件,数据事件总是时间检查事件;而对于其他检查,情况正好相反。对于其他检查,关于哪个是时间戳事件、哪个是时间检查事件的决定是基于下面更详细讨论的因素。

每个时序检查都可以包括一个可选的通知程序,每当时序检查检测到违规时,该通知程序就会切换。该模型可以使用通知程序使行为成为时序检查违规的函数。

与模块路径延迟表达式一样,时序检查限制值是常数表达式,可以包括指定参数。

1.3.2 使用稳定窗口的时序检查

使用稳定窗口的时序检查接受两个信号,即参考事件和数据事件,并定义一个信号的时间窗口,同时检查另一信号相对于该窗口的跳变时间。通常,它们都执行以下步骤:

(1)使用指定的一个或多个限制来定义关于参考信号的时间窗口;

(2)检查数据信号相对于时间窗口的跳变时间;

(3)如果数据信号在时间窗口内跳变,则报告时序冲突。

1.$setup

语法格式为

其中,data_event为时间戳事件;reference_event为时间检查事件;limit为非负常数表达式;notifier(可选)为Reg。

此外,数据(时间戳)事件通常是一个数据信号,而参考事件(时间检查事件)通常是一个时钟信号。时间窗口的终点由下式确定:

在下面情况下,$setup时序检查报告时序冲突,即

图1.12更清楚地说明以上公式给出的约束条件。从图中可知允许的建立时间窗口宽度由limit决定。对于数据信号(时间戳事件)来说,它应该在窗口的起点以外就应该有效。如果数据信号的有效时间落在了时间窗口内,就表示时间戳事件没有为参考事件(clk信号)提供足够的建立时间,也就是不满足建立时间要求,这就会产生建立时间的冲突。

图1.12 $setup时序检查的概念

2.$hold

语法格式为

其中,reference_event为时间戳事件;data_event为时间检查事件;limit为非负常数表达式;notifier(可选)为reg;

此外,数据事件(时间检查事件)通常是一个数据信号,而参考事件(时间戳事件)通常是一个时钟信号。时间窗口的起点和终点由下式确定:

在下面情况下,$hold时序检查报告时序冲突,即

图1.13更清楚地说明以上公式给出的约束条件。从图中可知允许的保持时间窗口宽度由limit决定。对于数据信号(时间检查事件)来说,它应该在窗口的起点开始一直到窗口终点一直有效。如果数据信号(时间检查事件)的有效时间落在了时间窗口内,就表示时间检查事件没有为时间戳事件(clk信号)提供足够的保持时间,也就是不满足保持时间要求,这就会产生保持时间的冲突。

图1.13 $hold时序检查的概念

3.$setuphold

语法格式为

其中,reference_event表示当建立限制条件的值是正数的时候,为时间检查事件或者时间戳事件;当建立限制条件的值是负数的时候,为时间戳事件。data_event表示当保持限制条件的值是正数的时候,为时间检查事件或者时间戳事件;当保持限制条件值是负数时,为时间戳事件。setup_limit为常数表达式;hold_limit为常数表达式;notifier(可选)为Reg;timestamp_cond(可选)为用于负的时序检查的时间戳条件;timecheck_cond(可选)为用于负的时序检查的时间检查条件;delayed_reference(可选)为用于负的时序检查延迟的参考信号;delayed_data(可选)为用于负的时序检查延迟的数据信号。$setuphold时序检查可以接受限制值为负数的条件。此处,数据事件通常是一个数据信号,而参考事件通常是一个时钟信号。当建立限制和保持限制的值均为正数时,参考事件或数据事件可作为时间检查事件,这将取决在仿真时首先发生的事件。

如果建立限制或保持限制的值其中有一个为负数时,限制条件变成如下表达式:

$setuphold时序检查将$setup和$hold时序检查功能组合为一个时序检查。

因此,下面的调用:

等效于下面的功能(如果tSU和tHLD都不是负数时):

当建立约束和保持约束为正,数据事件首先发生时,时间窗口的起点和终点由下式确定:

在下面的情况下,$setuphold时序检查报告一个时序冲突,即

当建立约束和保持约束为正,数据事件第二个发生时,时间窗口的起点和终点由下式确定:

在下面的情况下,$setuphold时序检查报告一个时序冲突,即

4.$removal

语法格式为

其中,data_event为时间戳事件;reference_event为时间检查事件;limit为非负常数表达式;notifier(可选)为Reg。

此处,参考事件(时间检查事件)通常是一个控制信号,如清除(clear)、复位(reset)或置位(set),而数据事件(时间戳事件)通常是一个时钟信号。时间窗口的起点和终点由下式确定:

在下面的情况下,$removal时序检查报告一个时序冲突,即

时间窗口的端点不是冲突区域的一部分。当限制值为零时,$removal检查将不发出冲突。

图1.14更清楚地说明以上公式给出的约束条件。从图中可知允许的去除时间窗口宽度由limit决定。对于参考事件(时间检查事件)来说,它应该在窗口的起点开始一直到窗口终点为止一直有效。如果参考事件(时间检查事件)的有效时间落在了时间窗口内,就表示时间检查事件没有为时间戳事件(clk信号)提供足够的去除时间,也就是不满足去除时间要求,这就会产生去除时间冲突。

图1.14 $removal时序检查的概念

5.$recovery

语法格式为

其中,data_event为时间检查事件;reference_event为时间戳事件;limit为非负常数表达式;notifier(可选)为Reg。

此处,参考事件(时间戳事件)通常是一个控制信号,如清除(clear)、复位(reset)或者置位(set),而数据事件(时间检查事件)通常是一个时钟信号。时间窗口的起点和终点由下式确定:

下面的情况下,$removal时序检查报告一个时序冲突,即

对于包含有异步复位的一个寄存器来说,恢复时间是指将异步复位信号切换到不活动状态后,下一个活动时钟沿之前的最小时间。这个时间用于安全地锁存一个新的数据。

图1.15更清楚地说明以上公式给出的约束条件。从图中可知允许的恢复时间窗口宽度由limit决定。对于参考事件(时间戳事件)来说,它应该先于窗口起点有效。如果参考事件(时间戳事件)的有效时间落在了时间窗口内,就表示时间戳事件没有为时间检查事件(clk信号)提供足够的恢复时间,也就是不满足恢复时间要求,这就会产生恢复时间冲突。

图1.15 $recovery时序检查的概念

6.$recrem

语法格式为

其中,reference_event表示当去除限制值是正数时,为时间检查事件或者时间戳事件;当去除限制值是负数时,为时间戳事件。data_event表示当恢复限制值是正数时,为时间检查事件或者时间戳事件;当恢复限制值是负数时,为时间戳事件。recovery_limit为常数表达式;removal_ limit为常数表达式;notifier(可选)为Reg;timestamp_cond(可选)表示用于负的时序检查的时间戳条件;timecheck_cond(可选)表示用于负的时序检查的时间检查条件;delayed_ reference(可选)表示用于负的时序检查延迟的参考信号;delayed_data(可选)表示用于负的时序检查延迟的数据信号。

当去除限制值和恢复限制值均为正数时,参考事件或数据事件均可作为时间检查事件,这取决于仿真中最先出现的事件。

当去除限制值或恢复限制值为负时,约束变成下面的公式:

$recrem时序检查将$removal和$recovery时序检查的功能组合为一个时序检查,因此,下面的调用:

等效为下面的功能(tREC和tREM的值不为负数):

当去除限制值和恢复限制值均为正数,并且数据事件首先发生时,时间窗口的起点和终点由下式确定:

在下面的情况下,$recrem时序检查报告一个时序冲突:

当去除限制值和恢复限制值均为正数,且数据事件第二个发生时,时间窗口的起点和终点由下式确定:

在下面的情况下,$recrem时序检查将报告一个时序冲突,即

1.3.3 时钟和控制信号的时序检查

时钟和控制信号的时序检查接受一个或者两个信号,并且验证它们的跳变永远不会被多个限制分割。对于只指定一个信号的检查,从该信号得到参考事件和数据事件。通常,这些检查执行下面的步骤:

(1)确定两个事件之间经过的时间;

(2)将经过的时间和指定的限制进行比较;

(3)如果经过时间和指定的限制冲突,则报告时序冲突。

偏斜(skew)检查有两个不同的冲突检测机制,即基于事件和基于定时器。

(1)基于事件的偏斜检查,只有在信号跳变时执行检查。

(2)基于定时器的偏斜检查,只要仿真时间等于经过的偏斜限制值时,就执行检查。

$nochange检查包含三个事件,而不是两个。

1.$skew

语法格式为

其中,reference_event为时间戳事件;data_event为时间检查事件;limit为非负常数表达式;notifier(可选)为Reg。

在下面情况下,$skew时序检查报告一个冲突,即

参考信号和数据信号的同时跳变不会引起$skew报告冲突,甚至抖动限制值为0的时候。

$skew时序检查是基于事件的,只有在一个数据事件后,才进行评估。如果没有一个数据事件(如数据事件无限延迟),将不会评估$skew时序检查,且不会报告时序冲突。相反,$timeskew和$fullskew默认基于定时器,如果绝对要求冲突报告且数据事件很晚出现或甚至于完全不出现时,就会使用它们。

一旦检测到参考事件,$skew将无限等待一个数据事件。在没有发生数据事件以前,不会报告时序冲突。第二个连续的参考事件将取消前面所等待的数据事件,开始新的数据事件。

在一个参考事件后,$skew时序检查不会停止对用于一个时序冲突的数据事件进行检查。当一个发生在参考事件后的数据事件超过了限制,则$skew报告时序冲突。

2.$timeskew

语法格式为

其中,data_event为时间检查事件;reference_event为时间戳事件;limit为非负常数表达式;notifier(可选)为Reg;event_based_flag(可选)为常数表达式;remain_active_flag(可选)为常数表达式。

在出现下面情况时,$timeskew时序检查报告一个时序冲突:

参考信号和数据信号的同时跳变不会引起 $timeskew 报告冲突,甚至抖动限制值为0。如果一个新的时间戳事件准确地发生在时间限制超时时,$timeskew也不会报告一个冲突。

$timeskew的默认行为是基于定时器的。在一个参考事件后经过的时间等于限制值时,立即报告一个冲突,且检查将变成静止的,不会报告更多的冲突(甚至是响应数据事件),直到下一个参考事件为止。然而,如果在限制内发生了一个数据事件,则不会报告一个冲突,检查将立即变成静止的。当它的条件为假并且没有设置remain_active_flag时,如果检测到一个有条件的参考事件时,该检查也将变成静止的。

使用event_based_flag可以将基于时间的行为改为基于事件的行为。当同时设置event_based_flag和remain_active_flag时,它的行为像$skew检查。当只设置event_based_flag时,它的行为像$skew,下面情况例外:

(1)当报告第一个冲突后,变成静态的;

(2)当它的条件为假时,检测到一个有条件的参考事件。

【例1.35】 $timeskew检查的Verilog HDL描述的例子。

图1.16给出采样$timeskew的波形。图中:

(1)没有设置event_based_flag和remain_active_flag。

CP上的第一个参考事件(A点标记)后,在50个时间单位后,在B点报告一个冲突。将$timeskew检查改为静止的,并且不会报告更多的冲突。

(2)设置event_based_flag,但未设置remain_active_flag。

CP上第一个参考事件(A点标记)后,在CPN有一个负跳变(C点标记)时将产生一个时序冲突,将$timeskew检查改为静止的,且不会报告更多的冲突。当MODE为假时,在CP上产生第二个参考事件(F点标记),因此$timeskew检查保持静止。

(3)设置event_based_flag和remain_active_flag。

CP上第一个参考事件(A点标记)后,在CPN上若有3个负跳变(用C、D和E点标记),则将产生时序冲突。当MODE为假时,在CP上产生第二个参考事件(F点标记),但由于设置了remain_active_flag,$timeskew保持活动。因此,在CPN上的G、H、I和J点报告额外的冲突。换句话说,CPN上的所有负跳变将产生冲突,与$skew行为相同。

(4)没有设置event_based_flag,但设置remain_active_flag。

对于图1.16给出的波形,$timeskew在情况(4)下,与情况(1)有相同的行为。两个情况的不同之处如图1.17所示。

图1.16 采样$timeskew

图1.17 设置remain_active_flag时采样 $timeskew

尽管MODE的条件为假,在CP产生参考事件(以F点标记),但由于设置了remain_active_ flag,所以$timeskew检查不会变为静止。因此,在B点报告冲突。然而对于情况(1),由于没有设置remain_active_flag,在F点,$timeskew检查将变为静止,且不会报告冲突。

3.$fullskew

语法格式为

其中,data_event为时间戳或时间检查事件;reference_event为时间戳或时间检查事件;limit 1为非负常数表达式;limit 2为非负常数表达式;notifier(可选)为Reg;event_based_flag(可选)为常数表达式;remain_active_flag(可选)为常数表达式。

除参考事件和数据事件可以以任何顺序跳变外,$fullskew类似于$timeskew。第一个限制是数据事件跟随参考事件的最大时间;第二个限制是参考事件跟随数据事件的最大时间。

当参考事件在数据事件之前时,参考事件是时间戳事件,数据事件是时间检查事件;当数据事件在参考事件之前时,数据事件是时间戳事件,参考事件是时间检查事件。

在下面情况下,$fullskew时序检查报告一个冲突。此处,当参考事件先出现跳变时,将限制设置为limit 1;当数据事件先出现跳变时,将限制设置为limit 2。

在参考信号和数据信号出现同时跳变时不会引起$fullskew报告一个时序冲突,甚至于抖动限制值为0时。如果一个新的时间戳事件准确发生在到达时间限制时,$fullskew也不会报告一个冲突。

$fullskew默认的行为是基于定时器(没有设置event_based_flag)。在一个时间戳时间后,如果一个时间检查事件没有出现在到达时间限制时,将立即报告一个冲突,且时序检查将变成静止的。然而,如果在时间限制内发生了一个时间检查事件,则不会报告冲突,且时序检查立即变成静止的。

一个参考事件或数据事件是一个时间戳事件,并且启动一个新的时序窗口。如果在前面的一个时间戳时间后,在时间限制范围内发生了一个时间检查事件,则时序检查将变成静止的,和上面描述的相同。

在基于定时器的模式下,在一个时间限制范围内发生的第二个时间戳事件将启动一个新的时序窗口用于取代第一个窗口,除非第二个时间戳事件有一个关联条件,该条件的值为假,在这种情况下,$fullskew的行为取决于remain_active_flag。如果设置该标志,则将简单地忽略第二个时间戳事件。如果没有设置该标志,且时间检查是活动的,则时序检查将转为静止的。

通过event_based_flag,可以将$fullskew检查所默认的行为从基于定时器改为基于事件。在这个模式下,$fullskew类似于$skew,这是因为它不是在时间戳事件后到达时间限制时报告冲突(基于定时器模式),而是在时间限制值后发生时间检查事件才报告冲突。这样一个事件将结束第一个时序窗口,并且立即启动一个新的时序窗口,它充当新窗口的时间戳事件。在限制值范围内的一个时间检查事件将结束时序窗口,时序检查将变为静止的,且不报告时序冲突。

在基于事件的模式下,发生在时间检查事件之前的第二个时间戳事件将开启一个新的时序窗口来取代第一个时序窗口,除非第二个时间戳时间所关联的条件值为假。在这种情况下,$fullskew的行为取决于remain_active_flag。如果设置标志,则简单忽略第二个时间戳事件;如果没有设置标志,且时间检查是活动的,则时序检查变为静止的。

在基于定时器和基于事件的模式中,如果时间戳事件没有条件或具有“真”条件,并且如果时序检查处于休眠状态,则激活时序检查。

【例1.36】 $fullskew Verilog HDL描述的例子。

图1.18给出采样$fullskew的波形。

图1.18 采样$fullskew

(1)没有设置event_based_flag。

在CP跳变(A点标记)同时MODE为真时,开始等待CPN上的负跳变。在到达50个时间单位时(B点标记),报告冲突。这将检查复位,并且等待下一个活动的跳变。

CPN产生一个负跳变(C点标记),同时MODE为真时,在CP上等待一个正的跳变,在D点,时间过去了70个时间单位,同时MODE为真,但CP没有出现正的跳变,因此报告一个冲突,复位检查,等待下一个活动的跳变。

CPN的一个跳变(E点标记),也导致一个时序冲突,在F点也是这样,这是因为即使CP跳变,但是MODE不再为真。G和H点的跳变也导致时序冲突,但是I点没有,这是因为该点后CP出现跳变时,同时MODE为真。

(2)设置event_based_flag。

在CP跳变(A点标记)同时MODE为真时,开始等待CPN上的负跳变。CPN在C点报告一个时序冲突,这是因为超过了50个时间单位的限制。当MODE为真时,在C点的跳变开始等待70个时间单位,用于CP上的正跳变。但是,对于CPN在C~H点的跳变且MODE为真时,CP没有正的跳变。因此,不会报告时序冲突。在CPN上I点的跳变,开始等待70个时间单位,且当MODE为真时,CP在J点的正跳变满足条件。

尽管在这个例子给出的波形中没有显示remain_active_flag的角色,但是应该承认在确定$fullskew在时序检查中的行为时,该标志非常重要,正如在$timeskew时序检查中的那样。

4.$width

语法格式为

其中,data_event(隐含)为时间检查边沿触发事件;reference_event为时间戳边沿触发事件;timing_check_limit为非负常数表达式;notifier(可选)为Reg;threshold(可选)为非负常数表达式。

通过测量从时间戳事件到时间检查事件的时间,$width时间检查监视信号脉冲的宽度。由于一个数据事件没有传递到$width,所以它从参考事件中得到:

数据事件=带有相反边沿的参考事件信号

由于采用这种方法获取用于$width的数据事件,因此必须传递一个边沿触发的事件作为参考事件。如果一个参考事件没有边沿说明,则出现编译器错误。

由于根据时间窗口定义$width时序检查,因此类似于将其表示为时间检查和时间戳之间的时间差。

在下面情况下,$width时序检查报告一个冲突,即

脉冲宽度必须大于或等于限制值,以避免一个时序冲突。但是,对于小于门限(threshold)的毛刺来说,没有报告冲突。

如果要求一个notifier参数时,需要包含门限参数。允许可以不指定这两个参数,此时门限的默认值为0。如果出现notifier,则应该有非空的门限值。

【例1.37】$width 合法和不合法Verilog HDL描述的例子。

5.$period

语法格式为

其中,隐含的data_event为时间戳边沿触发事件;reference_event为时间戳边沿触发事件;timing_ check_limit为非负常数表达式;notifier(可选)为Reg。

由于一个数据事件没有传递参数到$period,所以它从参考事件中得到:

数据事件 = 带有相同边沿的参考事件信号

由于采用这种方法获取用于$period的数据事件,因此必须传递一个边沿触发的事件作为参考事件。如果一个参考事件没有边沿说明,则出现编译器错误。

由于根据时间窗口定义$period时序检查,因此类似于将其表示为时间检查和时间戳之间的时间差。在下面情况下,$period时序检查报告冲突:

6.$nochange

语法格式为

其中,data_event为时间戳事件或时间检查事件;reference_event为边沿触发的时间戳事件和/或时间检查事件;start_edge_offset为常数表达式;end_edge_offset为常数表达式;notifier(可选)为Reg。

如果在一个控制信号(参考事件)指定的电平期间发生了一个数据事件,则$nochange时序检查报告一个时序错误。参考事件可以使用posedge或negedge关键字说明,但不能使用边沿控制的标识符。

起始边沿和结束边沿能扩展或者缩小时序冲突的区域,它是由边沿之后的参考事件的间隔定义的。如果参考事件是一个上升沿,则间隔是一个参考信号为高电平的周期。一个用于起始边沿的正偏移通过更早的启动时序冲突区域而扩展了区域;用于起始边沿的负偏移通过更晚的启动时序冲突区域缩短了区域。类似地,用于结束边沿的正偏移通过更晚结束而扩展了时序冲突区域,而用于结束边沿的负偏移通过较早结束而缩小了时序冲突区域。如果所有的偏移都为0,将不会改变区域的大小。

不像其他时序检查,$nochan ge 涉及三个跳变,而不是两个跳变。参考事件的前沿定义了时间窗口的开始,参考事件的后沿定义了时间窗口的结束。如果在时间窗口的任何时间内发生了数据事件,则导致冲突。

时间窗口的起点和终点由下面公式确定:

在下面情况下,$nochange时序检查将报告时序冲突,即

【例1.38】$nochange Verilog HDL描述的例子。

在该例子中,如果clk为高时,改变data信号则报告一个冲突。如果clk上升沿和data跳变同时发生,则没有冲突。

1.3.4 边沿控制标识符

在时序检查中,基于在0、1和x之间的特定沿跳变,边沿控制标识符可用于控制事件。

边沿控制标识符包含关键字edge,后面跟着包含1对到6对边沿跳变(0、1和x)的一个方括号列表,即

(1)01,表示从0跳变到1;

(2)0x,表示从0跳变到x;

(3)10,表示从1跳变到0;

(4)1x,表示从1跳变到x;

(5)x0,表示到从x跳变到0;

(6)x1,表示从x跳变到1。

在边沿跳变中涉及z时,与在边沿跳变中涉及x时相同对待。

posedge和negedge关键字可以用于某个边沿控制的描述符,如posedge clr等效于edge[01, 0x, x1] clr。

类似地,negedge clr等效于edge[10, x0, 1x] clr

1.3.5 提示符:用户定义对时序冲突的响应

时序检查提示符检可以用于打印描述冲突或者在器件输出端出现x的错误信息。

提示符是一个reg,在需要调用时序检查任务的模块中声明,它作为系统时序检查的最后一个参数。只要发生时序冲突,时序检查就更新提示符的值。

对所有的系统时序检查来说,提示符是一个可选的参数,可以从时序检查中去掉该参数而不会对时序检查产生不利的影响。

表1.6给出了提示符值对时序冲突的响应。

表1.6 提示符值对时序冲突的响应

【例1.39】 带提示符时序检查Verilog HDL描述的例子。

【例1.40】 在行为模型中使用提示符Verilog HDL描述的例子。

注: 这个模块只应用到边敏感的UDP;对于电平敏感的模型,生成一个用于x传播的额外模型。

1.精确仿真的要求

为了对负值时序检查准确建模,应满足下面的要求。

(1)如果信号在冲突窗口中(不包括结束点)发生改变,将触发时序冲突。小于两个单位仿真精度的冲突窗口,将不产生时序冲突。

(2)在冲突窗口内(除去结束点),锁存数据应该是一个稳定的值。

为了便于这些建模要求,在时序检查中,产生数据和参考信号的延迟复制版本。在运行时,用于内部时序检查评估。调整内部所使用的建立和保持时间,以移动冲突窗口,使它和参考信号重叠。

在时序检查中,声明延迟数据和参考信号。这样,可以在模型的功能实现中使用它们,以保证精确的仿真。如果在时序检查中,没有延迟信号,并且出现负的建立时间和保持时间,则创建隐含的延迟信号。由于在定义的模块行为中不能使用隐含的延迟信号,这样的一个模型可能有不正确的行为。

【例1.41】 隐含延迟信号Verilog HDL描述的例子1。

为CLK和DATA创建隐含延迟信号,但是不可能访问它们。 $setuphold 检查将正确地评估。但是,功能行为不总是正确的。如果在CLK的上升沿和10个时间单位后,DATA跳变,则时钟不正确地获取前面的DATA数据。

【例1.42】 隐含延迟信号Verilog HDL描述的例子2。

为CLK、DATA1和DATA2创建隐含延迟信号,即使在两个不同的时序检查中都引用CLK,仍然只创建一个隐含的延迟信号,并且用于所有的时序检查。

【例1.43】 隐含延迟信号Verilog HDL描述的例子3。

为CLK和DATA1创建明确的延迟信号del_CLK和del_DATA1,而为DATA2创建了隐含的延迟信号。换句话说,CLK只创建了一个延迟信号del_CLK,而不是为每个时序检查都创建一个延迟信号。

信号的延迟版本,不管是隐含的还是明确的,可以用在$setup、$hold、$setuphold,、$recovery、$removal、$recrem、$width、$period和$nochange时序检查中。这些检查将相应地调整其限制。这将保证在正确的时刻切换提示符。如果调整后的限制小于或等于0,则将限制设置为0,仿真器将产生一个警告。

信号的延迟版本不可以用于$skew、$fullskew和$timeskew时序检查。因为它可能导致信号跳变顺序的逆转,导致模型剩余部分在错误时间切换用于时序检查的提示符,导致在取消一个时序检查冲突时跳变到x。这个问题可以通过为每个检查使用单独的提示符来解决。

对负的时序检查值,可以会出现相互之间的不一致,并且对于延迟信号的延迟值没有解决的方法。在这些情况下,仿真器将产生警告信息。可以将最小的负限制值改为0,并且重新计算延迟信号的延迟,并且通过反复计算直到找到一个解决方案为止。这样,可以解决不一致的问题。因为在最坏情况下,所有负的限制值都变为0,不需要延迟信号。所以,这个过程总是可以找到一个解决方案。

当出现负限制值的时候,延迟时序检查信号才真正地被延迟。如果一个时序检查信号被多个该信号到输出的传播延迟所延迟,将花费比它传播延迟更长的时间来改变输出。它将在相同的时间(被延迟的时序检查信号发生变化的时间)取代跳变。这样,输出的行为就好像它的指定路径延迟等于应用到时序检查信号的延迟。只有为数据信号的每个边沿给出唯一的建立/保持或去除/恢复时间时,才产生这种情况。

【例1.44】 隐含延迟信号Verilog HDL描述的例子4。

建立时间是−7(−3和−7中,较大的绝对值),为dCLK创建延迟7。因此,在CLK的上升沿之后的7个时间单位输出Q才发生变化,而不是在指定路径中给出的6个时间单位。

2.负时序检查的条件

通过使用“&&&”操作符,可以使条件与参考信号和数据信号相关。但是,当建立或保持时间为负时,条件需要以更灵活的方式与参考信号和数据信号配对。

下面的$setup和$hold检查将一起工作以提供和单个$setuphold相同的检查:

在$setup检查中,clk是时间检查事件;而在$hold检查中,data是时间检查事件。不能用一个$setuphold表示。因此,提供额外的参数,使得用一个$setuphold表示成为可能。这些参数是timestamp_cond和timecheck_cond。下面的$setuphold等效于分开的$setup和$hold:

在该例子中,timestamp_cond参数为空,而timecheck_cond参数是cond1。

timestamp_cond和timecheck_cond参数与参考信号或数据信号关联,这基于这些信号的延迟版本发生的前后顺序。timestamp_cond与最先跳变的延迟信号关联,而timecheck_cond与第二个跳变的延迟信号关联。

延迟信号只创建用于参考信号和数据信号,不能用于任何和它们相关的条件信号。因此,仿真器不能隐含延迟timestamp_cond和timecheck_cond。通过构造延迟信号的函数,实现用于timestamp_cond和timecheck_cond域延迟的条件信号。

【例1.45】 条件延迟控制Verilog HDL描述的例子,如代码清单1-21所示。

代码清单1-21 条件延迟控制的Verilog HDL描述

分配语句创建条件信号,它是延迟信号的函数。创建延迟的条件与参考信号和数据信号的延迟版本是同步的,用于执行检查。

第一个$setuphold有负的建立时间。因此,时间检查条件TE_cond_D与数据信号D相关;第二个$setuphold有负的保持时间。因此,时间检查条件TE_cond_TI和参考信号CP相关;第三个$setuphold有负的建立时间。因此,时间检查条件DXTI_cond和数据信号TE相关。

图1.19给出了该例子的冲突窗口。

图1.19 时序检查冲突窗口

一下是用于延迟信号所计算的延迟值:

用延迟的信号为timestamp_cond和timecheck_cond参数创建信号不是必要的,但通常更接近于真实的器件行为。

3.负时序检查的提示符

由于在内部对参考信号和数据信号延迟,因此将时序冲突的检测延迟。在负时序检查中,当时序检查检测到一个时序冲突时,将切换负时序检查中的提示符reg。时序冲突发生在被调整的时序检查值所测量的延迟信号出现冲突时,而不是在未延迟信号在模型输入被冲突内的原始时序检查值所测量时。

4.选项行为

如前所述,应通过调用选项,使能Verilog仿真器处理$setuphold和$recrem时序检查中负值的能力。在不使能此调用选项的情况下,可能会运行为接受具有延迟引用和/或延迟数据信号的负时序检查值而编写的模型。在这种情况下,延迟的参考信号和数据信号成为原始参考信号和数字信号的副本。如果使用了关闭所有定时检查的调用选项,也会发生同样的情况。

1.3.6 使能带有条件的时序检查

一种称为条件事件的结构将时序检查的发生与条件信号的值联系起来。

在条件中使用比较可能是确定的(如===和!==),或无操作,或不确定的(如==或!=)。当比较是确定的,在条件信号中的值x不会使能时序检查。对于不确定的比较,条件信号中的值x将使能条件检查。

作为条件的信号应该是一个标量网络,如果使用有多位的矢量网络或表达式,则使用矢量网络或表达式的LSB。

如果有条件时序检查要求多个有条件信号时,在指定块外通过逻辑组合成一个信号,它可用于有条件信号。

【例1.46】 无条件时序检查Verilog HDL描述的例子。

此处,在信号clk的每个上升沿到来时,执行建立时序检查。如果只有在clr为高时,在信号clk的每个上升沿到来时执行时序检查,将上面的命令重新写为

【例1.47】 条件时序检查Verilog HDL描述的例子。

该例子给出了触发相同时序检查的两种方法。第一种方法,只有clr为低时,在clk上升沿到来时,才执行建立时序检查;第二种方法,使用===运算符,这使得条件的比较结果是确定的。

1.3.7 时序检查中的矢量信号

在时序检查中,信号可以部分或全部都是向量。这将被理解成单个时序检查,将其中一位或多位的跳变看作该向量的单个跳变。

【例1.48】 向量信号时序检查Verilog HDL描述的例子,如代码清单1-22所示。

代码清单1-22 向量信号时序检查的Verilog HDL描述

如果在第100个时刻,DAT从’b00101110跳变到’b01010011。在第105个时刻,CLK从0跳变到1,则 $setup 时序检查也只报告一个时序冲突。

仿真器可以提供一个选项,使时序检查中的向量创建多个单比特位的时序检查。对于只有单个信号的时序检查,如$period或$width, N 位宽度的向量导致 N 个不同的时序检查。对于两个信号的时序检查,如$setup、$hold、$setuphold、$skew、$timeskew、$fullskew、$recovery、$removal、$recrem和$nochange, M N 是两个信号的宽度,结果是 M * N 个时序检查。如果有一个提示符,则所有的时序检查将触发该提示符。

使能该选项,上面的例子产生6个时序冲突,这是因为DAT中的6位发生跳变。

1.3.8 负时序检查

当使能负时序检查选项时,可以接受$setuphold和$recrem时序检查。这两个时序检查的行为和对应的负值是相同的。本小节将介绍$setuphold时序检查,但是也同样应用于$recrem时序检查。

建立和保持时序检查值定义了一个关于参考信号边沿时序冲突窗口,在这个窗口内,数据保持不变。任何在指定窗口内的数据变化,将引起时序冲突。报告时序冲突,通过提示符reg,在模型中将发生其他行为,如当检测到一个时序冲突时,强制一个触发器输出x。

如图1.20所示,对于建立和保持时间都为正值时,暗示这个冲突窗口跨越参考信号。

图1.20 数据约束间隔,正的建立/保持

一个负的建立或保持时间,意味着冲突窗口移动到参考信号的前面或后面。在真实器件的内部,由于内部时钟和数据信号路径的不同,可能发生这种情况。从图1.21可知,这些延迟的显著差异会导致出现负的建立或保持值。

图1.21 数据约束间隔,负的建立/保持 MhsJTXPqmvQ0597v+zv+7NBOVq0Wuq70yB0qpmY8b77t2m+NWPw1BzRPYcdmuHCK

点击中间区域
呼出菜单
上一章
目录
下一章
×