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

1.1 Verilog HDL用户自定义原语

本节描述了一种建模计数,通过设计和指定称为用户定义原语(User Defined Primitive,UDP)的新元素来扩充预定义的门原语集。这些新UDP的实例可以与门原语完全相同的方式使用,以表示正在建模的电路。

在UDP中可以表示以下两种类型的行为。

(1)组合:由组合UDP建模。

(2)时序:由时序UDP建模。

组合UDP使用其输入的值来确定其输出的下一个值。时序UDP使用其输入的值和输出的当前值来确定其输出的值。时序UDP提供了一种对诸如触发器和锁存器之类的时序电路进行建模的方法。时序UDP可以对电平敏感和边沿敏感行为进行建模。

每个UDP只有一个输出,可以处于三种状态之一:0、1或x。不支持三态值z。在时序UDP中,输出总是具有与内部状态相同的值。传递给UDP的z值应该与x值相同。

1.1.1 UDP定义

UDP定义独立于模块,它们与语法层次结构中的模块定义处于相同级别。它们可以出现在源文件文本中的任何位置,但不可出现在关键字module和endmodule之间。

实现可能会限制模型中UDP定义的最大数量,但允许至少256个。

UDP的语法格式如下:

其中,OutputName为输出端口名;UDP_name为UDP的标识符;List_of_inputs为用“,”分割的输入端口的名字;output_delaration为输出端口的类型声明;input_declarations为输入端口的类型声明;reg_declaration为输出寄存器类型数据的声明(可选);initial_statement为元件的初始状态声明(可选);table和endtable为关键字;list_of_table_entries为表项1到 n 的声明。

UDP的定义独立于模块定义。因此,UDP定义出现在模块定义以外。此外,也可以在单独的文本文件中定义UDP。

注: (1)UDP包含输入和输出端口声明。其中,输出端口声明以关键字ouput开头,后面跟随输出端口的名字;输入端口声明以关键字input开头,后面跟随输入端口的名字;时序UDP,包含用于输出端口的reg声明,可以在时序UDP的initial语句中指定输出端口的初始值;实现过程限制了UDP的输入端口个数,允许时序UDP可以至少有9个输入端口,组合UDP可以至少有10个输入端口。

(2)UDP的行为以列表的形式给出。以table关键字开始,以endtable关键字结束。

1.UDP头部

UDP定义具有两种形式。第一种形式,以关键字原语开头,后跟一个标识符,该标识符为UDP的名字。然后是一个逗号分隔的端口名字列表,该列表用括号括起来,后面跟着一个分号。UDP定义头部后面跟有端口声明和状态表。UDP定义以关键字endprimitive结束。

第二种形式,以关键字原语开头,后跟一个标识符,该标识符为UDP的名字。然后是一个逗号分隔的端口声明列表,该列表用括号括起来,后跟分号。UDP定义头部后面跟有一个状态表。UDP定义以关键字endprimitive结束。

UDP具有多个输入端口和一个输出端口。UDP上不允许双向inout端口。UDP的所有端口应为标量,不允许为矢量端口。注意,输出端口应为端口列表中的第一个端口。

2.UDP端口声明

UDP应包含输入和输出端口声明。输出端口声明以关键字output开头,后跟一个输出端口名字。输入端口声明以关键字input开头,后跟一个或多个输入端口名字。

当使用第一种形式的UDP头部声明UDP时,除输出声明外,时序UDP还应包含输出端口的reg声明,或者作为输出声明的一部分。组合UDP不能包含reg声明。输出端口的初值可以在时序UDP中的初始语句中指定。

实现可能会限制UDP的最大输入数量,但它们应允许时序UDP至少有9个输入,组合UDP至少有10个输入。

3.时序UDP初始化语句

时序UDP初始语句指定仿真开始时输出端口的值,该语句以关键字initial开头。下面的语句应该是一个赋值语句,它为输出端口分配一个单比特文字值。

4.状态表

状态表定义UDP的行为,它以关键字table开始,以关键字endtable结束。表中的每一行都以分号结尾,表中的每一行都使用各种字符创建,如表1.1所示。这些字符表示输入值和输出状态。支持三种状态,即0、1和x。在UDP中,明确排除z状态。表中定义了许多特殊字符来表示状态可能性的某些组合。

表1.1 UDP表中符号的含义

状态表每行的输入状态字段的顺序直接取决于UDP定义头部的端口列表,它与输入端口声明无关。

组合UDP的每个输入都有一个字段、输出有一个字段。输入字段与输出字段之间用冒号(:)分割。每一行定义输入值的特定组合的输出。

时序UDP在输入字段和输出字段之间插入了一个额外的字段。该额外字段表示UDP的当前状态,并考虑为当前输出值的等效。它由冒号分割。每一行都根据当前状态、输入值的特定组合以及最多一个输入跳变来定义输出。下面一行是非法的:

(01)(10)0:0:1;

如果所有输入值都指定为x,则输出状态应指定为x。

没有必要明确指定每个可能输入组合。未明确指定的输入值的所有组合都会导致默认输出状态x。

为不同的输出指定相同的输入组合(包括边沿)是非法的。

1.1.2 组合电路UDP

在组合UDP中,输出状态仅由当前输入状态的函数来确定。每当输入状态发生变化时,都会评估UDP,并将输出状态设置为状态表中与所有输入状态匹配的行所指示的值。未明确指定的输入的所有组合将驱动输出状态为未知值x。

【例1.1】 使用UDP定义mux2的Verilog HDL描述的例子,如代码清单1-1所示。

代码清单1-1 UDP定义mux2的Verilog HDL描述

1.1.3 电平敏感的时序UDP

电平敏感时序的时序行为和组合逻辑的行为表示方法相同,只是输出端口声明为reg类型,并且在每个表入口有一个额外的字段,用于表示UDP当前的状态。时序UDP的输出字段表示下一个状态。

【例1.2】 电平敏感UDP的Verilog HDL描述的例子,如代码清单1-2所示。

代码清单1-2 电平敏感UDP的Verilog HDL描述

该描述在两个方面不同于组合UDP模型。首先,输出标识符q由一个额外的reg声明,以指示存在内部状态q。UDP的输出值始终与内部状态相同。其次,添加了一个当前状态的字段,该字段与输入和输出用冒号(:)分割。

1.1.4 边沿敏感的时序UDP

在电平敏感行为中,输入值和当前状态足以确定输出值。边沿敏感行为的不同之处在于,输出的变化是由输入的特定跳变触发的。这使状态表成为一个跳变表。

每个表条目最多可以在一个输入上有一个跳变规范。转换由括号中的一对值(如01)或跳变符号(如r)指定。下面条目是非法的:

应明确规定所有不影响输出的跳变。否则,这种跳变会导致输出值变为x。所有未指定的跳变都默认为x。

如果UDP的行为对任何输入的边沿敏感,则应为所有输入的所有边沿指定所需的输出状态。

【例1.3】 边沿敏感UDP的Verilog HDL描述的例子,如代码清单1-3所示。

代码清单1-3 边沿敏感UDP的Verilog HDL描述

诸如01之类的术语表示输入值的跳变。具体地,(01)表示从0到1的跳变。前面UDP定义的表中的第一行解释如下:当时钟值从0跳变为1,数据等于0时,无论当前状态如何,输出都会变为0。

1.1.5 时序UDP的初始化

时序UDP的输出端口上的初始值可以通过提供过程分配的初始化语句指定。初始化语句是可选的。

与模块中的初始化语句一样,UDP中的初始化声明以关键字initial开头。UDP和模块中的初始化语句如表1.2所示。

表1.2 UDP和模块中的初始语句

【例1.4】 包含初始化时序UDP的Verilog HDL描述的例子,如代码清单1-4所示。

代码清单1-4 包含初始化时序UDP的Verilog HDL描述

输出q在仿真开始时具有初值1。实例化UDP上的延迟规范不会延迟将该初始值分配给输出的仿真时间。当仿真开始时,该值是状态表中的当前状态。UDP初始化语句中不允许出现延迟。

1.1.6 UDP实例

UDP实例在模块内以与门相同的方式指定。实例名字是可选的,与门相同。端口连接顺序与UDP定义中指定的顺序相同。由于UDP不支持z,因此只能指定两个延迟。可以为UDP实例的数组指定可选范围。

【例1.5】 例化UDP的Verilog HDL描述的例子,如代码清单1-5所示。

代码清单1-5 例化UDP的Verilog HDL描述

1.1.7 边沿和电平触发的混合行为

UDP定义允许在同一个表中混合电平敏感结构和边沿敏感结构。当输入发生变化时,首先处理边沿敏感的情况,然后处理电平敏感的情况。因此,当电平敏感和敏感情况指定不同的输出值时,结果由电平敏感情况指定。

【例1.6】 混合时序行为UDP的Verilog HDL描述的例子,如代码清单1-6所示。

代码清单1-6 混合行为时序UDB的Verilog HDL描述

在本例中,置位和清除逻辑是电平敏感的。每当置位和清除组合的值为“01”时,输出值为1。类似地,每当置位和清除组合的值为“10”时,输出值为0。

剩下的逻辑对时钟的边沿敏感。在正常的时钟情况下,触发器对时钟上升沿敏感,如这些条目中的时钟字段中的r所示。对于以f作为时钟值的条目,输出字段中的连字符(-)表示对时钟下降沿的不敏感。记住,应指定输入跳变所期望的输出,以避免输出中出现不需要的x值。最后两个条目表明,在稳定的低或高时钟上,j和k输入的跳变不会改变输出。 t7jOfUkNCqlUcqOhQ3WZCdwWqH14iPdUk/fZ6mi+Gpd0FJk5DIS0j5JqGPElP/xd

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

打开