第8章 仿真 联系客服

发布时间 : 星期五 文章第8章 仿真更新完毕开始阅读89dde9240722192e4536f6cb

input cin, a, b ; output cout ; ’

table

//cin a b : cout //真值表

? 0 0 : 0; //只要有两个输入为0,则进位输出肯定为0 0 ? 0 : 0; 0 0 ? : 0;

? 1 1 : 1; //只要有两个输入为1,则进位输出肯定为1

1 ? 1 : 1; 1 1 ? : 1; endtable endprimitive

可以看出,简缩符“?”使表达式的书写更简练,增强了程序的可读性。下面是一个采用简缩符“?”来表述的3选1多路选择器UDP元件的例子。 例8-15 3选1多路选择器UDP元件

primitive mux31(Y,in0, inl, in2,s2,s1);

input in0,inl,in2,s2,s1; output Y; table

//in0 inl in2 s2 s1 : Y

0 ? ? 0 0 : 0; //当s2s1=00时,Y=in0 1 ? ? 0 0 : 1;

? 0 ? 0 1 : 0; //当s2s1=01时,Y=inl ? 1 ? 0 1 : 1;

? ? 0 1 ? : 0; //当s2s1=1?时,Y=in2 ? ? 1 l ? : 1; 0 0 ? 0 ? : 0; 1 1 ? 0 ? : 1; 0 ? 0 ? 0 : 0; 1 ? 1 ? 0 : 1; ? 0 0 ? 1 : 0;

? 1 1 ? 1 : 1; endtable eadprimitive

8.3.2 时序逻辑UDP元件

与组合逻辑电路相比,时序逻辑电路元件的输出除了与当前的输入状态有关,还与时序元件本身的内

13

部状态有关。

对时序逻辑电路UDP进行定义时的table表项格式为:

输入1逻辑值 输入2逻辑值 …. 输入n逻辑值 :内部状态 :输出逻辑值

与组合逻辑电路UDP的定义一样,时序逻辑电路UDP定义模块中各个输入端口在table表项中的排列顺序必须与它们在“primitive”语句中端口表项内的排列顺序保持严格一致;在表项中要用空格分隔开不同的输入逻辑值。

时序逻辑电路UDP定义时的table表项格式与组合逻辑电路UDP的表项格式的不同之处在于: (1)表项中多了关于元件内部状态的描述。

(2)要用两个冒号“:”分别将输入逻辑值部分与元件内部状态,元件内部状态与输出逻辑值部分分隔开。

(3)在够建table表项时要把元件内部状态对输出的影响考虑进去。

时序逻辑电路元件可根据触发方式分为电平触发与边沿触发两类。它们对应的table表项格式虽然都是上面给出的格式,但是table表项中输入输出信号可取的状态在两种电路类别下是不同的。

1、初始化状态寄存器

因为时序逻辑电路元件有自己的内部状态,所以必须有一个寄存器变量来保持其内部状态。在时序逻辑电路UDP的定义模块中必须将输出端口定义为寄存器类型。

在有些情况下必须对上电时刻(即0时刻)元件的初始状态值加以指定。所以在时序逻辑电路UDP的定义模块中还可以增加“元件初始状态说明”,这一项通过“initial”过程语句来指定元件上电时刻的初始状态(0、1或x)。如果该说明项(initial语句)缺省,则元件的初始状态被默认为不定态“x”。

2、电平触发时序电路UDP

电平触发时序电路UDP的特点是其内部状态改变是由某一输入信号电平触发的。 例8-16 电平敏感的1位数据锁存器UDP元件 primitive latch(Q,clk,reset,D); input clk, reset, D; output Q; reg Q;

initial Q=1'b1; //初始化 table

//clk reset D : State: Q

? 1 ? : ? : 0; //reset=1,则不管其他端口为什么值,输出都为0 0 0 0 : ? : 0; //clk=0,锁存器把D端的输入值输出 0 0 1 : ? : 1;

1 0 ? : ? : -; //clk=1,锁存器的输出保持原值,用符号“-”表示 endtable

14

endprimitive

数据锁存器UDP与前面的组合电路元件相比,多了一列对元件内部状态(state)的描述,内部状态两边用冒号与输入、输出隔开。同时,增加了新的符号“-”,表示保持原值的意思。

3、边沿触发时序电路UDP

边沿触发时序电路UDP的特点是内部状态的改变是由输入时钟的有效沿(上升沿或下降沿)触发的,而与时钟信号稳定时的输入状况无关。所以对边沿触发时序逻辑元件的描述中就需要对输入信号的变化和变化方式加以考虑。模拟器只有在检测到输入信号发生跳变时才会搜索table表得到新的内部状态值和输出逻辑值。这样table表项中的输入逻辑值部分需要列出输入逻辑值变化情况即跳变情况。在Verilog中用一对括号括起来的二个数字“(vw)”的形式来表示从一个状态到另一个状态的转化,其中v、w可以是0、1、x、?之一,因而(01)代表的就是由0往1的上升沿正跳变,(10)则代表下降沿负跳变,(1x)代表了由1往不定态的跳变,(??)代表在0、1、x三状态间的任意跳变……。必须注意Verilog规定在每条table表项中最多只允许一个输入信号处于跳变状态,例如:

// clk data : state : next_state (01) (10) : 0 : 0 ;

表示的这条table表项就是不允许的,因为其中有两个输入信号clk和data同时发生了跳变。

例8-17 上升沿触发的D触发器UDP元件 primitive DFF(Q,D,clk); output Q; input D, clk; reg Q; table

//clk D :state : Q

(01) 0 : ? : 0; //上升沿到来,输出Q:D (01) 1 : ? : 1; (0X) 1 : 1 : 1; (0X) 0 : 0 : 0;

(?0) ? : ? : -; //没有上升沿到来,输出Q保持原值

? (??) : ? : -; //时钟不变,输出也不变

endtable endprimitive

在上面的例子中,括号内的两个数字表示状态间的转变,也就是不同的边沿,(01)表示上升沿;(10)表示下降沿;(?0)表示从任何状态(0、1、x)到0的跳变,即排除了上升沿的可能性。

上例中table列表第3、4行的意思是:当时钟从0状态变化到不确定状态(x)时,如输入数据与当前状态(state)一致,则输出也是定态。

table列表中最后一行的意思是:如果时钟处于某一确定状态(这里的“?”表示是0或者是1,不包括x),则不管输入数据有什么变化((??)表示任何可能的变化),D触发器的输出都将保持原值不变(用符号“—”

15

表示)。

8.3.3 UDP元件缩记符

为便于描述、增强可读性,VerilogHDL在UDP元件的定义中引入了很多缩记符号,前面已经介绍了一些,表8.3进一步对这些缩记符做了总结。

表8.3 UDP定义时的缩记符号 缩记符 0 1 x ? B或b - (vy) * R或r F或f P或p N或n 定义 逻辑0 逻辑1 不定状态 0、1或x(任意态) 0或1 输出状态保持不变 代表(01)(10)(0x)(1x)(x1)(x0)(?1) 等 同(??),表示输入端的任意变化 同(01),表示输入的上跳变沿 同(10) ,表示输入的下跳变沿 (01) (0x) 或 (x1) (10) (1x) 或 (x0) 说明 能用来描述输入、输出信号 能用来描述输入、输出信号 能用来描述输入、输出信号 只能表示输入,不能用来对输出进行描述 只能表示输入,不能用来对输出进行描述 只用于时序元件的输出 从逻辑v到y的转变 表示输入有任何变化,不能用来对输出进行描述 表示上升沿 表示下降沿 包含x的上升沿跳变 包含x的下升沿跳变 例8-18是采用了上述缩记符表示的一个带有异步置1和异步清零的上升沿触发的D触发器的UDP元件的例子。

例8-18 带异步置1和异步清零的上升沿触发的D触发器UDP元件

primitive DFF_UDP(Q,D,clk,clr,set); output Q; input D,clk,clr,set; reg Q; table

// clk D clr set : state : Q (01) 1 0 0 (01) 1 0 x ? ? 0 x (01) 0 0 0 (01) 0 x 0 ? ? x 0 (x1) 1 0 0 (x1) 0 0 0 (0x) 1 0 0 (0x) 0 0 0

: ? : 0; : ? : 0; : 0 : 0; : ? : 1; : ? : 1; : 1 : 1; : 0 : 0; : 1 : 1; : 0 : : 1 :

0; 1;

? ? 1 ? : ? : 1; ? ? 0 1 : ? : 0;

16