两种类型的HDL结构经常用于描述结构化模型的延迟,如专用集成电路(Application Specific Integrated Circuit,ASIC)的逻辑单元。包括:
(1)分布式延迟。指定事件通过模块内的门和网络传播所需要的时间。
(2)模块路径延迟。描述从源端(input端口或inout端口)事件传播到目的端(output端口或inout端口)所需要的时间。
指定块语句用于说明源端和目的端的路径并为这些路径分配延迟。指定块的语法格式为
指定块以关键字specify和endspecify为界,并且应该出现在模块声明中。指定块可以执行以下任务:
(1)描述模块中的不同路径;
(2)为模块中的路径分配延迟;
(3)执行时序检查,以确保模块输入端所产生的事件满足模块所描述器件的时序约束。
指定块描述的路径称为模块路径,将信号源与目的配对。源可以是单向(input端口)或双向(inout端口)的。类似地,目的可以是单向(output端口)或双向(inout端口)的,并将其称为模块路径的目的。
【例1.7】 指定块Verilog HDL描述的例子,如代码清单1-7所示。
代码清单1-7 指定块的Verilog HDL描述
跟在关键字specify后面的前两行声明指定参数。指定参数声明后面的行描述了模块路径,并为该模块路径分配延迟。指定参数确定分配给模块路径的延迟。
在指定块中设置路径延迟需要两个步骤:
(1)描述模块路径;
(2)为这些路径分配延迟。
模块路径可以描述为简单路径、边沿敏感路径或状态依赖路径。模块路径应该在指定块内定义为源信号和目的信号之间的连接。模块路径可以连接向量和标量的任何组合。
图1.1给出了模块路径延迟。从图中可知,从不同源端口(A、B、C和D)到同一个目的端口(Q)存在不同路径延迟,因此可以为每个输入到输出的路径指定不同的延迟。
图1.1 模块路径延迟
1.模块路径限制
模块路径有以下限制:
(1)模块路径源应为连接到模块input端口或inout端口的网络;
(2)模块路径目的应为连接到模块output端口或inout端口的网络或变量。
(3)在模块内,模块路径目的只能有一个驱动器。
2.简单模块路径
简单路径可以使用以下其中一种方法声明:
(1)源*>目的;
(2)源=>目的。
符号*>和=>分别表示模块路径源和模块路径目的之间不同类型的连接。操作符“*”在源和目的之间建立完全连接。操作符“=>”在源和目标之间建立并行连接。
【例1.8】 简单模块路径声明Verilog HDL描述的例子,如代码清单1-8所示。
代码清单1-8 简单模块路径声明的Verilog HDL描述
3.边沿敏感路径
如果在描述一个模块路径时,在源端使用了一个边沿跳变,此时该路径称为边沿敏感路径。边沿敏感路径结构用于对输入到输出的延迟的时序建模,其只在源端信号出现指定的边沿时发生。边沿敏感路径的语法格式为
或
edge_identifier可以是与输入终端描述符相关联的关键词posedge或negedge,specify_input_terminal_descriptor可以是任何input端口或inout端口。如果指定向量端口作为specify_input_terminal_descriptor,则应在最低有效位上检测边沿跳变。如果未指定边沿跳变,则应将路径看作输入端任何跳变的有效路径。
可以使用完全连接(*>)或并行连接(=>)指定边沿敏感路径。对于并行连接(=>),目的应为任何标量output或inout端口,或向量output或inout端口的位选择。对于全连接(*>),目的应为向量或标量output和inout端口中的一个或多个列表,以及向量output和inout端口中的位选择或部分选择。
data_source_expression是任意表达式,用作到路径目的的数据流描述。这种任意的数据路径描述不影响数据或事件通过模型的实际传播;数据路径源处的事件如何传播到目的取决于模块的内部逻辑。polarity_operator描述数据路径是同方向还是反方向。
【例1.9】 带有正极性操作符边沿敏感路径声明的Verilog HDL描述的例子。
在该例子中,在clock的正边沿,模块使用10的上升延迟和8的下降延迟从clock扩展到out。数据路径是从in到out。
【例1.10】 带有负极性操作符边沿敏感路径声明的Verilog HDL描述的例子。
在该例子中,在clock[0]的负边沿,模块路径使用10的上升延迟和8的下降延迟从clock[0]扩展到out。数据路径是从in到out,并且in在传播到输出时取反。
【例1.11】 没有边沿标识符的边沿敏感路径声明的Verilog HDL描述的例子。
在该例子中,clock的任何变化,模块路径将从clcok扩展到out。
4.状态依赖路径
一个依赖状态的路径是指,当一个指定条件为真时,可以为一个模块路径分配延迟,它影响通过该路径的信号传播延迟。语法格式为
从上面的语法格式可知,一个状态依赖路径描述包括以下条目:
(1)一个条件表达式,当计算结果为“真”时,使能模块路径;
(2)模块路径描述;
(3)应用于模块路径的表达式。
1)条件表达式
条件表达式中的操作数应由以下内容构成:
(1)标量或向量模块input端口或inout端口或它们位选择或部分选择;
(2)本地定义的变量或网络或它们的位选择或部分选择;
(3)编译时间常数(常数和指定参数)。
在条件表达式中可用的有效操作符如表1.3所示。
表1.3 在条件表达式中可用的有效操作符
2)简单状态依赖路径
如果状态依赖路径的路径描述是简单路径,则称为简单状态依赖路径。
【例1.12】 使用状态依赖路径描述XOR门时序Verilog HDL描述的例子,如代码清单1-9所示
代码清单1-9 使用状态依赖路径描述XOR门时序的Verilog HDL描述
在该例子中,前两个状态依赖路径描述了当XOR门(x1)对输入变化取反时的一对输出上升和下降延迟时间。最后两个状态依赖路径描述了当XOR门缓冲变化输入的另一对输出上升和下降延迟时间。
【例1.13】 对部分ALU建模。状态依赖路径为不同ALU操作指定不同延迟的Verilog HDL描述的例子,如代码清单1-10所示
代码清单1-10 使用状态依赖路径为不同ALU操作指定不同延迟的Verilog HDL描述
在该例子中,前三个路径声明声明了从操作数输入i1和i2延伸到o1输出的路径。根据操作码上输入所指定的操作,将这些路径上的延迟分配给操作。最后一个路径声明声明了从操作码输入到o1输出的路径。
3)边沿敏感状态依赖路径
如果状态依赖路径的路径描述描述了边沿敏感路径,则该状态依赖路径称为边沿敏感状态依赖路径。只要满足以下标准,就可以将不同的延迟分配给相同的边沿敏感路径:
(1)边沿、条件或两者都使每个声明唯一;
(2)端口在所有路径声明中以相同的方式引用(整个端口、位选择或部分选择)。
【例1.14】 边沿敏感状态依赖路径Verilog HDL描述的例子1。
在该例子中,当复位和清除为低时发生时钟的上升沿,模块路径使用10的上升和8的下降延迟从clock扩展到out。
【例1.15】 两个对边沿敏感路径声明Verilog HDL描述的例子,如代码清单1-11所示。
在该例子中,每个声明都有一个唯一的边沿。
代码清单1-11 两个对边沿敏感路径声明的Verilog HDL描述
【例1.16】 边沿敏感状态依赖路径Verilog HDL描述的例子2,如代码清单1-12所示。
代码清单1-12 边沿敏感状态依赖路径的Verilog HDL描述
【例1.17】 边沿敏感状态依赖路径Verilog HDL非法描述的例子,如代码清单1-13所示。
代码清单1-13 边沿敏感状态依赖路径的Verilog HDL非法描述
该例子给出的两个状态依赖路径声明是非法的,因为即使它们有不同的条件,目的也没有以相同的方式指定,即第一个目标是部分选择,第二个是位选择。
4)ifnone条件
ifnone条件用于当用于路径的其他条件都不成立时,指定一个默认的状态依赖路径延迟。ifnone条件将指定和状态依赖模块路径相同的模块路径源端和目的端。需要遵守下面的规则:
(1)只能描述简单模块路径;
(2)对应于ifnone路径的状态依赖路径可以是简单模块路径或边沿敏感路径;
(3)如果没有到ifnone模块路径的对应状态依赖路径,则将ifnone模块路径看作一个无条件的简单模块路径;
(4)为模块路径指定ifnone条件和为同一模块路径指定无条件简单路径是非法的。
【例1.18】 有效状态依赖路径组合Verilog HDL描述的例子,如代码清单1-14所示。
代码清单1-14 有效状态依赖路径组合的Verilog HDL描述
【例1.19】 模块路径组合Verilog HDL非法描述的例子,如代码清单1-15所示。
代码清单1-15 模块路径组合的Verilog HDL非法描述
该例子中的模块路径描述组合是非法的,因为它使用ifnone条件将状态依赖路径与同一模块路径的无条件路径组合在一起。
5.全连接和并行连接路径
操作符*>应用于在源和目的之间建立完全连接。在完全连接中,源中的每个位都应连接到目的中的每一位。模块路径源不需要具有与模块路径目的相同的位数。
由于没有限制源信号和目的信号的位宽或数量,完全连接可以处理大多数类型的模块路径。下面的条件要求使用完全连接:
(1)一个向量和一个标量之间的一个模块路径;
(2)不同位宽向量之间的一个模块路径;
(3)在一个语句中,描述有多个源或多个目的的模块路径。
操作符“=>”用于在源和目的之间建立一个并行连接。在并行连接中,源端口的每一位将连接到目的端口的每一位。只能在包含相同位数的源和目的之间创建并行模块路径。
并行连接比全连接更加严格。它们只能是一个源和一个目的之间的连接,并且每个信号包含相同的位数。因此,一个并行连接只能用于描述两个相同位宽向量之间的一个模块路径。由于标量是一个位,所以“*>”或者“=>”都可以用于建立两个标量比特位之间的连接。
在两个4位向量之间使用全连接和并行连接的区别,如图1.2所示。
图1.2 充分连接和并行连接之间的区别不同
【例1.20】 宽度为8位的2:1多路复用器Verilog HDL描述的例子,如代码清单1-16所示。
代码清单1-16 宽度为8位的2:1多路复用器的Verilog HDL描述
从s到q的模块路径使用完全连接(*>),因为它将标量源(1位选择线)连接到向量目的(8位输出总线)。从输入线in1和in2到q的模块路径使用并行连接(=>),因为它们在两条8位总线之间建立了并行连接。
6.在单个语句中声明多个模块路径
通过使用符号*>将逗号分隔的源列表连接到逗号分隔的目的列表,可以在一条语句中描述多个模块路径。当在一个语句中描述多个模块路径时,源和目的列表可能包含任意宽度的标量和向量的混合。多模块路径声明中的连接始终是完全连接。
【例1.21】 多个路径全连接Verilog HDL描述的例子1。
等效为:
7.模块路径极性
模块路径的极性指示信号跳变的方向在从输入端传播到输出端时是否取反。这种任意极性描述不影响数据或事件通过模型的实际传播;源处的上升或下降如何传播到目的地取决于模块的内部逻辑。模块路径可以指定三种极性中的任意一种,即未知极性、正极性和负极性。
1)未知极性
默认情况下,模块路径应具有未知极性;也就是说,路径源处的条件可能以不可预测的方式传播到目的地,如下所示:
(1)源处的上升可能导致目的处的上升跳变、下降跳变或无跳变。
(2)源处的下降可能导致目的处的上升跳变、下降跳变或无跳变。
指定为全连接或并联连接,但没有极性运算符+或-的模块路径应看作极性未知的模块路径。
【例1.22】 未知极性模块路径Verilog HDL描述的例子。
2)正极性
对于具有正极性的模块路径,源处的任何跳变都可能导致目的处的相同跳变,如下所示:
(1)在源处的上升可能导致目的处的上升跳变或无跳变。
(2)在源处的下降可能导致目的处的下降跳变或无跳变。
正极性的模块路径应通过将正极性运算符指定为“=>”或“*>”的前缀。
【例1.23】 正极性模块路径Verilog HDL描述的例子。
3)负极性
对于具有负极性的模块路径,源处的任何跳变都可能导致目的处的相反跳变,如下所示:
(1)源处的上升可能导致目的处的下降跳变或无跳变。
(2)源处的下降可能导致目的处的上升跳变或无跳变。
负极性的模块路径应通过将负极性运算符指定为“=>”或“*>”的前缀。
【例1.24】 负极性模块路径Verilog HDL描述的例子。
在路径终止的模块输出处发生的延迟应通过为模块路径描述分配延迟值来指定。
在模块路径延迟分配中,左侧指定模块路径描述,右侧指定一个或多个延迟值。可以选择性地将延迟值括在一对括号中。可能有1个、2个、3个、6个或12个延迟值分配给模块路径。延迟值应为包含文字或规范参数的常量表达式,并且可能存在形式为min:type:max的延迟表达式。
【例1.25】 为路径分配延迟Verilog HDL描述的例子,如代码清单1-17所示。
代码清单1-17 为路径分配延迟的Veriog HDL描述
在该例子中,在specparam关键字后面声明的指定参数指定模块路径延迟的值。模块路径分配将这些模块路径延迟分配给模块路径。
1.指定在模块路径上的跳变延迟
每个路径延迟表达式可以是一个表示典型延迟的单个值,也可以是三个值的冒号分隔列表,按顺序表示最小、典型和最大延迟。如果路径延迟表达式导致负值,则应将其视为零。表1.4描述了不同的路径延迟值应如何与各种跳变关联。
表1.4 将不同路径延迟值与不同的跳变关联的方法
【例1.26】 延迟格式表达式路径分配Verilog HDL描述的例子,如代码清单1-18所示。
代码清单1-18 延迟格式表达式路径分配的Verilog HDL描述
2.指定x跳变延迟
如果没有明确地指出x跳变延迟,则基于下面两个规则计算x跳变的延迟值:
(1)从一个已知状态跳变到x将尽可能快地发生,即跳变到x使用尽量短的延迟。
(2)从x到一个已知状态的跳变延迟尽可能长,即为从x的任何一个跳变使用尽量长的延迟。
表1.5给出了用于x跳变的延迟值的通用算法以及具体例子。表中,表示了以下两组x跳变。
表1.5 用于x跳变的计算延迟
(1)从已知状态s跳变到x:s->x
(2)从x跳变到已知状态s:x->s
3.延迟选择
当指定路径输出必须调度到跳变时,仿真器需要确定所使用的正确延迟。在这个过程中,可能指定了连接到输出路径的多个输入,此时仿真器必须确定使用哪个指定的路径。
仿真器首先要确定所指定的到输出的活动路径。活动的指定路径是指在最近的时间内输入经常跳变的路径,它们要么是无条件的,要么是条件为真。在同时出现输入跳变的情况下,可能有很多从输入到输出的指定路径都处于活动状态。
一旦识别出活动的指定路径,就必须从中选择一个延迟。这是通过比较从每个指定路径调度的特定跳变的正确延迟并选择最小延迟来完成的。
【例1.27】 延迟分配Verilog HDL描述的例子1。
对于Y从0到1的跳变,如果近期A的跳变比B更加频繁,则选择延迟6;否则,选择延迟5。如果最近它们都同时发生跳变,则选择它们两个上升延迟中最小的一个,即从B中选择上升延迟5。如果Y从1到0跳变,则从A中选择下降延迟9。
【例1.28】 延迟分配Verilog HDL描述的例子2。
根据MODE的值,这些指定路径中从0到5的任何位置都可能处于活动状态。当MODE=2时,前面3个指定路径是活动的。上升沿时,将选择4,因为这是前三个中最小的上升延迟;下降沿时,将选择5,因为这是前三个中最小的下降延迟。
如果模块包含模块路径延迟和分布式延迟(模块内原语实例的延迟),将选择每个路径内两个延迟中较大的一个。
【例1.29】 混合模块路径延迟和分布式延迟例子1。
图1.3给出了利用分布式延迟和路径延迟组合建模的简单电路(仅示出了D输入到Q输出路径)。这里,从输入D到输出Q的模块路径上的延迟是22,而分布式延迟的总和是0+1=1。因此,由D上的跳变引起的Q上的跳变将在D上的跳变后22个时间单位发生。
图1.3 模块延迟比分布式延迟要长
【例1.30】 混合模块路径延迟和分布式延迟例子2。
在图1.4中,从D到Q的模块路径上的延迟为22,但沿着该模块路径的分布式延迟现在加起来为10+20=30。因此,由D上的事件引起的Q上的事件将在D上事件发生30个时间单位后发生。
图1.4 模块延迟比分布式延迟要短
在模块内,模块路径的输出网络不超过一个驱动器。因此,在模块路径输出时,不允许线逻辑。
图1.5给出了出现布线输出规则的冲突,以及避免规则冲突的一个方法。如图1.5(a)所示,由于一个路径由两个逻辑门的输出驱动器,因此所有连接到网络S的模块路径都是非法的。如图1.5(b)所示,假设信号S 是“线与”的,通过放置包含门逻辑的布线逻辑来创建连到输出的一个驱动器,就能规避这个限制。
图1.5 非法和合法模块路径
图1.6(a)的模块路径描述是非法的,当把Q和R连接到一起时,则产生规则冲突条件。尽管在相同的模块内禁止多个输出驱动器连接到一个路径目的端,但是在模块外是允许的。图1.6(b)给出的模块路径描述是合法的。
图1.6 非法和合法模块路径
在时间上,将比模块路径延迟更接近的两个连续调度的跳变看作脉冲。默认,拒绝模块路径的输出脉冲。连续的跳变不能比模块输出延迟还要靠近,称为脉冲传播的惯性延迟模型。
脉冲宽度范围控制如何处理模块路径输出的脉冲,包括:
(1)应拒绝脉冲宽度的范围;
(2)允许脉冲传播到路径目的的脉冲宽度范围;
(3)脉冲应在路径目的处生成逻辑x的脉冲宽度范围。
两个脉冲限制值定义了与每个模块路径跳变延迟相关的脉冲宽度范围,这两个脉冲限制值为错误限制值和拒绝限制值。错误限制值应该至少和拒绝限制值一样大。不会过滤掉大于或等于错误限制值的脉冲(通过)。小于错误限制值但大于或等于拒绝限制值的脉冲过滤为x。拒绝小于拒绝限制值的脉冲。默认,将错误限制值和拒绝限制值设置成与延迟相等。这些默认值产生完整的惯性脉冲行为,拒绝所有小于延迟的脉冲。
如图1.7所示,从输入A到输出Y的上升延迟为7、下降延迟为9。默认情况下,上升延迟的错误限制值和拒绝限制值都是7。下降延迟的错误限制值和拒绝限制值都是9。与形成脉冲的后沿延迟相关联的脉冲极限确定是否以及如何对脉冲进行滤波。波形Y’显示了无脉冲过滤产生的波形。脉冲宽度为2,小于上升延迟7的拒绝限制值;因此如波形Y所示对脉冲进行滤波。
图1.7 由于脉冲宽度小于模块路径延迟,因此过滤掉脉冲
有三种方法可以从默认值修改脉冲限制值。首先,Verilog语言提供PATHPULSE$ specparam来修改默认值的脉冲限制值。其次,调用选项可以指定应用于所有模块路径延迟的百分比,以形成相应的错误限制值和拒绝限制值。第三,SDF注解可以单独注解每个模块路径跳变延迟的错误极限和拒绝极限。
1.指定块控制脉冲限制值
可以使用PATHPULSE$ specparam从指定块内设置脉冲极限值。使用PATHPULSE$指定拒绝限制值和错误限制值的语法格式为
其中,reject_limit_value为拒绝限制值;error_limit_value为错误限制值;specify_input_terminal _descriptor为输入终端描述符;specify_output_terminal_descriptor为输出终端描述符。
如果只指定了拒绝限制值,则应同时适用于拒绝限制值和错误限制值。
可以针对特定模块路径指定拒绝限制值和错误限制值。当没有指定模块路径时,拒绝限制值和错误限制值应适用于模块中定义的所有模块路径。如果路径特定的PATHPULSE$指定参数和非路径特定的PATHPULSE$指定参数出现在同一模块中,则路径特定的参数应优先于指定的路径。
模块路径输入终端和输出终端应符合模块路径输入和输出的规则,但有以下限制,即终端不能是向量的位选择或部分选择。
当模块路径声明声明多个路径时,PATHPULSE$ 指定参数应仅指定给第一个路径输入终端和第一个路径输出终端。指定的拒绝限制值和错误限制值应适用于多路径声明中的所有其他路径。应忽略指定除第一路径输入和路径输出终端以外的任何内容的PATHPULSE$指定参数。
【例1.31】 PATHPULSE$修改脉冲限制值Verilog HDL描述的例子,如代码清单1-19所示。
代码清单1-19 PATHPULSE$修改脉冲限制值的Verilog HDL描述
在该例子中,通过第一个PATHPULSE$,路径clk=>q获取的拒绝限制值为2、错误限制值为9,如第一个PATHPULSE$声明所定义。路径(clk*>q)和(pre*>q)接收第二个PATHPULSE$声明的拒绝限制值0和错误限制值4。路径data=>q没有使用PATHPULSE$明确的说明,因此它获得的拒绝限制值和错误限制值为3,正如第三个PATHPULSE$声明所定义的那样。
2.全局控制脉冲限制值
两个调用选项可以指定全局应用于所有模块路径跳变延迟的百分比。错误限制调用选项指定用于其错误限制值的每个模块路径跳变延迟的百分比。拒绝限制调用选项指定用于其拒绝限制值的每个模块路径跳变延迟的百分比。百分比值为0~100之间的整数。
拒绝和错误限制调用选项的默认值都是100%。当两个选项都不存在时,则每个模块跳变延迟的100%用作拒绝和误差限制。
如果错误限制百分比小于拒绝限制百分比,则为错误。在这种情况下,错误限制百分比设置为等于拒绝限制百分比。
当同时存在PATHPULSE$和全局脉冲限制调用选项时,应优先考虑PATHPULES$值。
3.脉冲限值的SDF注解
SDF注解可用于指定模块路径跳变延迟的脉冲限制值。当存在PATHPULSE$、全局脉冲限制调用选项和脉冲限制值的SDF注解时,SDF注解值优先。
4.详细的脉冲控制能力
脉冲过滤行为的默认类型有两个缺点。首先,对x状态的脉冲过滤可能不够“悲观”,x状态的持续时间太短而不起作用。第二,不相等的延迟可以导致脉冲拒绝,只要后沿在前沿之前,就不会留下脉冲被拒绝的指示。
1)基于事件/基于检测脉冲过滤
当一个输出脉冲必须过滤到x时,如果模块路径输出立即跳变到x(基于检测),而不是在脉冲的前沿已经调度的跳变时间上(基于事件),则表达出更大的悲观情绪。
默认,基于事件脉冲过滤到x。当输出脉冲必须过滤到x时,脉冲的前沿变成到x的跳变,且后沿变成从x的跳变。边沿的跳变时间不变。
如图1.8所示,使用了非对称上升/下降时间的简单缓冲区,图中的拒绝限制值和错误限制值都为0,图中给出了基于时间和基于检测的输出波形。
图1.8 基于事件和基于检测
有两种不同的方法用于选择基于检测或者基于事件行为。
(1)通过使用基于检测或者基于事件调用选项,全局处理所有模块路径输出;
(2)通过使用本地指定块脉冲类型声明,其语法格式为:
如果模块路径输出在已经出现在模块路径声明中之后出现在脉冲类型声明中,则为错误。脉冲类型调用选项优先于脉冲类型指定块声明。
2)负脉冲检测
当一个模块路径的输出延迟不相等时,可能调度一个脉冲的后沿时间要早于调度一个脉冲的前沿时间,导致产生一个负脉冲宽度。在正常条件下,如果调度一个脉冲的后沿时间要早于调度一个脉冲的前沿时间,则取消前沿。当脉冲的初始状态和最终状态相同时,不会出现跳变,因此未指示曾经出现一个调度。
通过使用行为的showcancelled类型,可以指示一个x状态的负脉冲。当一个脉冲的后沿比前沿先调度时,这个类型使前沿调度变成x、后沿从x调度。基于事件脉冲类型,用调度到x来代替前沿调度。基于检测脉冲类型,在检测到负脉冲上立即调度到x。
通过两种不同的方法,使能showcancelled行为。
(1)使用showcancelled和noshowcancelled调用选项。
(2)使用指定块showcancelled的声明,其语法格式为
图1.9给出了showcancelled行为描述,图中给出了一个输入到一个带有不等上升/下降延迟缓冲区的窄脉冲,这将导致调度脉冲的后沿早于前沿。输入脉冲的前沿在6个单位之后调度(由A点标记的输出事件)。脉冲后沿在一个时间单位后出现,其调度输出事件出现在4个单位之后(由B标记的点)。第2个输出调度用于一个时间,该时间先于已经存在的用于前面的输出脉冲边沿的调度,图中给出了3种不同工作模式的输出波形。第一个波形给出了默认行为(未使能showcancelled的行为和默认的基于时间的类型),第二个波形给出了与基于事件结合的showcancelled行为,最后一个波形给出了与基于检测结合的showcancelled行为。
图1.9 当前事件消除问题和矫正
相同的情况也可能出现在几乎同时的输入跳变中,如图1.10所示,图中给出了两输入与非门的输入波形,开始时A为逻辑高、B为逻辑低。在第10个时刻,B跳变,即0->1,导致在第24个时刻的输出调度为1->0。A在第12个时刻,1->0,因此在第22个时刻调度为0->1。图中箭头用于标记由输入A和B跳变引起的输出跳变。图中给出了3种不同操作模式的输出波形。第一个波形显示了未使能showcancelled行为的默认行为以及默认的基于事件类型。第二个波形将showcancelled行为与基于事件一起显示。第三个波形将showcancelled行为和基于检测一起显示。
图1.10 NAND门几乎同时跳变的输入,其中一个事件在另一个事件尚未成熟之前调度
带有showcancelled行为基于事件类型的缺点是输出脉冲边沿靠得太近,导致x状态的时间持续太短,图1.11给出了基于检测类型解决这个问题的方法。
图1.11 NAND门的同步输入切换,输出事件在相同时刻调度
【例1.32】 指定块中没有脉冲类型或showcancelled声明的Verilog HDL描述的例子。
【例1.33】 指定块中带有showcancelled声明的Verilog HD描述的例子。
此showcancelled声明出错,因为它遵循了模块路径声明中out的使用。如果out从输入a中不显示已取消的行为,但从输入b中显示已取消行为,这将是矛盾的。
【例1.34】 带有showcancelled和脉冲类型语句Verilog HDL描述的例子,如代码清单1-20所示。
代码清单1-20 带有showcancelled和脉冲类型语句的Verilog HDL描述
在该例子中,这两个指定块都会产生相同的结果。输出out和out_b都被声明为showcancelled和pulsestyle_ondetect。