下载第 9章 结 构 建 模本章讲述 Verilog HDL中的结构建模方式。结构建模方式用以下三种实例语句描述:
Gate实例语句
UDP实例语句
Module实例语句第 5章和第 6章已经讨论了门级建模方式和 U D P建模方式,本章讲述模块实例语句。
9.1 模块
Verilog HDL中,基本单元定义成模块形式,如下所示,
m o d u l e m o d u l e _ n a m e(p o r t _ l i s t) ;
D e c l a r a t i o n s _ a n d _ S t a t e m e n t s
e n d m o d u l e
端口队列 p o rt _ l i s t列出了该模块通过哪些端口与外部模块通信。
9.2 端口模块的端口可以是输入端口、输出端口或双向端口。缺省的端口类型为线网类型(即
w i r e类型) 。但是,端口可被显式地指定为线网。输出或输入输出端口能够被重新声明为 r e g型寄存器。无论是在线网说明还是寄存器说明中,线网或寄存器必须与端口说明中指定的长度相同。下面是一些端口说明实例。
m o d u l e M i c r o (PC,Instr,NextAddr);
/ /端口说明
i n p u t [3:1] P C;
o u t p u t [1:8] I n s t r;
i n o u t [16:1] N e x t A d d r;
/ /重新说明端口类型:
w i r e [16:1] N e x t A d d r; //该说明是可选的,但如果指定了,就必须与它的端口说明保持相同长度。
r e g [1:8] I n s t r;
/ /I n s t r已被重新说明为 r e g类型,因此它能在 always 语句或在 i n i t i a l语句中赋值。
.,,
e n d m o d u l e
9.3 模块实例语句一个模块能够在另外一个模块中被引用,这样就建立了描述的层次。模块实例语句形式如下:
module_name instance_name(p o r t _ a s s o c i a t i o n s) ;
信号端口可以通过位置或名称关联;但是关联方式不能够混合使用。端口关联形式如下:
p o r t _ e x p r / /通过位置。
.P o r t N a m e (p o r t _ e x p r) / /通过名称。
p o rt _ e x p r可以是以下的任何类型:
1) 标识符( r e g或 n e t)
2) 位选择
3) 部分选择
4) 上述类型的合并
5) 表达式(只适用于输入端口)
在位置关联中,端口表达式按指定的顺序与模块中的端口关联。在通过名称实现的关联中,模块端口和端口表达式的关联被显式地指定,因此端口的关联顺序并不重要。下例使用两个半加器模块构造全加器;逻辑图如图 9 - 1所示。
m o d u l e H A(A,B,S,C);
i n p u t A,B;
o u t p u t S,C;
p a r a m e t e r A N D _ D E L A Y = 1,X O R _ D E L A Y = 2;
a s s i g n #X O R _ D E L A Y S = A ^ B;
a s s i g n #A N D _ D E L A Y C = A & B;
e n d m o d u l e
m o d u l e F A(P,Q,Cin,Sum,Cout) ;
i n p u t P,Q,Cin;
o u t p u t Sum,Cout;
p a r a m e t e r O R _ D E L A Y = 1;
w i r e S1,C1,C2;
/ /两个模块实例语句
HA h1 (P,Q,S1,C1); //通过位置关联。
HA h2 (,A(C i n),.S(S u m),.B(S 1),.C(C 2)); //通过端口与信号的名字关联。
/ /门实例语句:
or #O R _ D E L A Y O1 (Cout,C1,C2) ;
e n d m o d u l e
在第一个模块实例语句中,H A是模块的名字,h 1是实例名称,并且端口按位置关联,即信号 P与模块( H A)的端口 A连接,信号 Q与端口 B连接,S 1与 S连接,C 1与模块端口 C连接。
在第二个实例中,端口按名称关联,即模块( H A)和端口表达式间的连接是显示地定义的。
下例是使用不同端口表达式形式的模块实例语句。
Micro M1 (U d I n[3:0],{WrN,RdN},S t a t u s[0],S t a t u s[ 1 ],
& U d O u t [0:7],T x D a t a) ;
这个实例语句表示端口表达式可以是标识符( T x D a t a),位选择( S t a t u s[ 0 ]),部分位选择( U d I n[ 3,0 ]),合并( {Wr N,R d N})或一个表达式( & u d O u t[ 0,7 ]);表达式只能够连接到输入端口。
9.3.1 悬空端口在实例语句中,悬空端口可通过将端口表达式表示为空白来指定为悬空端口,例如:
84 Verilog HDL 硬件描述语言 下载图 9-1 使用两个半加器模块构造的全加器
DFF d1 (,Q(Q S),.Q b a r(),.D a t a( D ),
.P r e s e t(),.C l o c k(CK)); //名称对应方式。
DFF d2 (QS,,D,,CK) ; / /位置对应方式。
/ /输出端口 Q b a r悬空。
/ /输入端口 P r e s e t打开,其值设定为 z。
在这两个实例语句中,端口 Q b a r和 P re s e t悬空。
模块的输入端悬空,值为高阻态 z。模块的输出端口悬空,表示该输出端口废弃不用。
9.3.2 不同的端口长度当端口和局部端口表达式的长度不同时,端口通过无符号数的右对齐或截断方式进行匹配。例如:
m o d u l e C h i l d(Pba,Ppy) ;
i n p u t [5:0] P b a;
o u t p u t [2:0] P p y;
.,,
e n d m o d u l e
m o d u l e T o p;
w i r e [1:2] B d l;
w i r e [2:6] M p r;
Child C1(Bdl,Mpr) ;
e n d m o d u l e
在对 C h i l d模块的实例中,B d l[ 2 ]连接到 P b a[ 0 ],B d l[1] 连接到 P b a[ 1 ],余下的输入端口
P b a[ 5 ],P b a[ 4 ]和 P b a[ 3 ]悬空,因此为高阻态 z。与之相似,M p r[ 6 ]连接到 P p y[ 0 ],M p r[ 5 ]连接到 P p y[ 1 ],M p r[4] 连接到 P p y[ 2 ]。参见图 9 - 2。
图 9-2 端口匹配
9.3.3 模块参数值当某个模块在另一个模块内被引用时,高层模块能够改变低层模块的参数值。模块参数值的改变可采用下述两种方式:
1) 参数定义语句( d e f p a r a m);
2) 带参数值的模块引用。
1,参数定义语句参数定义语句形式如下:
d e f p a r a m hier_path_name1 = v a l u e 1,
hier_path_name2 = v a l u e 2,...;
较低层模块中的层次路径名参数可以使用如下语句显式定义(层次路径名在下一章中讲第 9章 结 构 建 模 85下载述) 。下面是一个例。模块 FA和 H A已在本节前面描述过。
m o d u l e TOP (N e w A,N e w B,N e w S,N e w C) ;
i n p u t N e w A,N e w B;
o u t p u t N e w S,N e w C;
d e f p a r a m H a 1,X O R _ D E L A Y = 5,
/ /实例 H a 1中的参数 X O R _ D E L A Y。
H a 1,A N D _ D E L A Y = 2;
/ /实例 H a 1中参数的 A N D _ D E L A Y。
HA Hal (NewA,NewB,NewS,NewC) ;
e n d m o d u l e
m o d u l e T O P 2 (NewP,NewQ,NewCin,NewSum,NewCout) ;
i n p u t NewP,NewQ,NewCin;
o u t p u t N e w S u m,N e w C o u t;
d e f p a r a m F a 1,h 1,X O R _ D E L A Y = 2,
/ /实例 F a 1的实例 h 1中的参数 X O R _ D E L A Y。
F a 1,h 1,A N D _ D E L A Y = 3,
/ /实例 F a 1的实例 h 1中的参数 A N D _ D E L A Y。
F a 1,O R _ D E L A Y = 3;
/ /实例 F a 1中的参数 O R _ D E L A Y)
FA Fa1 (NewP,NewQ,NewCin,NewSum,NewCout) ;
e n d m o d u l e
2,带参数值的模块引用在这种方法中,模块实例语句自身包含有新的参数值。下面的例子在前几节中也出现过,
本例中采用带参数的模块引用方式。
m o d u l e T O P 3 (N e w A,N e w B,N e w S,N e w C) ;
i n p u t N e w A,N e w B;
o u t p u t N e w S,N e w C;
H A #(5,2) H a 1(N e w A,N e w B,N e w S,N e w C) ;
/ /第 1个值 5赋给参数 A N D_D E L A Y,该参数在模块 H A中说明。
/ /第 2个值 2赋给参数 X O R_D E L A Y,该参数在模块 H A中说明。
e n d m o d u l e
m o d u l e T O P 4(N e w P,N e w Q,N e w C i n,N e w C o u t) ;
i n p u t N e w P,N e w Q,N e w C i n;
o u t p u t N e w S u m,N e w C o u n t;
d e f p a r a m F a 1,h 1,X O R _ D E L A Y = 2,//实例 F a 1中实例 h 1的参数 X O R _ D E L A Y。
F a 1,h 1,A N D _ D E L A Y = 3; //实例 F a 1中实例 h 1的参数 A N D _ D E L A Y。
F A #(3) F a 1(N e w P,N e w Q,N e w C i n,N e w C o u t) ;
/ /值 3是参数 O R _ D E L A Y的新值。
e n d m o d u l e
模块实例语句中参数值的顺序必须与较低层被引用的模块中说明的参数顺序匹配。在模块 TO P 3中,A N D _ D E L AY已被设置为 5,X O R _ D E L AY已被设置为 2。
模块 TO P 3和 TO P 4解释说明了带参数的模块引用只能用于将参数值向下传递一个层次(例如,O R _ D E L AY),但是参数定义语句能够用于替换层次中任意一层的参数值。
应注意到:在带参数的模块引用中,参数的指定方式与门级实例语句中时延的定义方式
86 Verilog HDL 硬件描述语言 下载相似;但由于对复杂模块的引用时,其实例语句不能像对门实例语句那样指定时延,故此处不会导致混淆。
参数值还可以表示长度。下面是通用的 M× N乘法器建模的实例。
m o d u l e M u l t i p l i e r(O p d _ 1,O p d _ 2,R e s u l t) ;
p a r a m e t e r E M = 4,E N = 2; //默认值
i n p u t [E M:1] O p d_ 1 ;
i n p u t [E N:1] O p d_ 2 ;
o u t p u t [E M+E N:1] R e s u l t;
a s s i g n R e s u l t = O p d _ 1 * O p d _ 2;
e n d m o d u l e
这个带参数的乘法器可在另一个设计中使用,下面是 8× 6乘法器模块的带参数引用方式:
w i r e [1:8] P i p e _ R e g;
w i r e [1:6] D b u s;
w i r e [1:14] A d d r _ C o u n t e r;
.,,
M u l t i p l i e r #(8,6) M 1(P i p e_R e g,D b u s,A d d r_C o u n t e r) ;
第 1个值 8指定了参数 E M的新值,第 2个值 6指定了参数 E N的新值。
9.4 外部端口在迄今为止所见到的模块定义中,端口表列举出了模块外部可见的端口。例如,
m o d u l e S c r a m _ A(A r b,C t r l,M e m _ B l k,B y t e) ;
i n p u t[0:3] A r b;
i n p u t C t r l;
i n p u t [8:0] M e m _ B l k;
o u t p u t [0:3] B y t e;
.,,
e n d m o d u l e
A r b,C t r l,M e m _ B l k和 B y t e为模块端口。这些端口同时也是外部端口,即在实例中,当采用名称关联方式时,外部端口名称用于指定相互连接。下面是模块 S c r a m _ A的实例。
Scram_A SX(,B y t e(B 1),.M e m _ B l k(M 1),.C t r l(C 1),.A r b(A 1) ) ;
在模块 S c r a m _ A中,外部端口名称隐式地指定。 Verilog HDL中提供显式方式指定外部端口名称。这可以通过按如下形式指定一个端口来完成:
.e x t e r n a l _ p o r t _ n a m e(i n t e r n a l _ p o r t _ n a m e)
下面是同一个例子,只不过是显式地指定外部端口。
m o d u l e S c r a m _ B (,D a t a(A r b),.C o n t r o l(C t r l),
.M e m _ W o r d(M e m _ B l k),.A d d r(B y t e) ) ;
i n p u t [0:3] A r b;
i n p u t C t r l;
i n p u t [ 8,0 ]M e m _ B l k;
o u t p u t [0:3] B y t e;
.,,
e n d m o d u l e
模块 S c r a m _ B在此实例中指定的外部端口是 D a t a,C o n t ro l,M e m _ Wo rd和 A d d r。端口表显式地表明了外部端口和内部端口之间的连接。注意外部端口无需声明,但是模块的内部端口第 9章 结 构 建 模 87下载却必须声明。外部端口在模块内不可见,但是却要在模块实例语句中使用,而内部端口因为在模块中可见,所以必须在模块中说明。在模块实例语句中,外部端口的使用如下所示:
Scram_B S1(,A d d r(A 1),.D a t a(D 1),.C o n t r o l(C 1),
.M e m _ W o r d(M 1) ) ;
在模块定义的端口表中,这两种概念不能混淆,即在模块定义中所有端口必须指定显式的端口名称,或者没有一个端口带有显式的端口名称。
如果模块端口通过位置连接,则模块实例语句中不能使用外部端口名称。
内部端口名称可以是标识符,也可以是下述类型的表达式:
位选择;
部分选择;
位选择、部分选择和标识符的合并。
例如,
m o d u l e S c r a m _ C (A r b[ 0,2 ],C t r l,
{ M e m _ B l k[ 0 ],M e m _ B l k[ 1 ] },B y t e[ 3 ] ) ;
i n p u t [0:3] A r b;
i n p u t C t r l;
i n p u t [8:0] M e m _ B l k;
o u t p u t [0:3] B y t e;
.,,
e n d m o d u l e
在 S c r a m _ C的模块定义中,端口表包括部分选择( A r b[ 0,2 ]),标识符( C t r l),合并
( {M e m _ B l k[ 0 ],M e m _ B l k[ 1 ] } )和位选择( B y t e[ 3 ]) 。在内部端口是位选择、部分选择或合并的情况下,没有隐式地指定外部端口名。因此,在这样的模块实例语句中,模块端口必须通过位置关联相互连接。例如,
Scram_C SYA (L 1[ 4,6 ],C L,M M Y[ 1,0 ],B T) ;
在这个实例语句中,端口通过位置关联相连接,因此 L 1[ 4∶ 6 ]连接到 A r b[ 0∶ 2 ],C L连接到 C t r l,M M Y[ 1 ]连接到 M e m _ B l k[ 0 ],M M Y[ 0 ]连接到 M e m _ B l k[ 1 ],B T连接到 B y t e[ 3 ]。
若使用端口名称关联(即当内部端口不是标识符时),必须对模块中的端口指定外部端口名。如下面的 S c r a m _ D模块定义所示。
m o d u l e S c r a m _ D (,D a t a(A r b[ 0,2 ] ),.C o n t r o l(C t r l),
.M e m _ W o r d( {M e m _ B l k[ 0 ],M e m _ B l k[ 1 ] } ),
.A d d r(B y t e[ 3 ] ) ) ;
i n p u t [0:3] A r b;
i n p u t C t r l;
i n p u t [8:0] M e m _ B l k;
o u t p u t [0:3] B y t e;
.,,
e n d m o d u l e
在 S c r a m _ D模块实例语句中,端口既能够使用位置连接,也能够使用名称连接,但是不能混合使用。下例的模块实例语句端口通过名称连接。
Scram_D SZ (,D a t a(L 1[ 4,6 ],.C o n t r o l(C L),
.M e m _ W o r d(M M Y[ 1,0 ],.A d d r(B T) ) ;
模块中可以只有外部端口而没有内部端口。即模块在引用中其外部端口可以悬空,不与内部信号相连。例如:
88 Verilog HDL 硬件描述语言 下载
m o d u l e Scram_E (,D a t a(),.C o n t r o l (C t r l),
.M e m _ W o r d ({ M e m _ B l k[0],M e m _ B l k [ 1 ] } ),
.A d d r( ) ) ;
i n p u t C t r l;
i n p u t [8:0] M e m _ B l k;
.,,
e n d m o d u l e
模块 S c r a m _ E 有两个外部端口 D a t a和 A d d r,这两个端口在使用时被悬空。
一个内部端口是否能与多个外部端口连接? Verilog HDL允许这样连接。例如,
m o d u l e F a n O u t (,A(C t r l I n),.B(C o n d O u t),.C(C o n d O u t) ) ;
i n p u t C t r l I n;
o u t p u t C o n d O u t;
a s s i g n CondOut = C t r l I n;
e n d m o d u l e
内部端口 C o n d O u t 与两个外部端口 B和 C连接,所以 C o n d O u t的值在 B和 C上都出现。
9.5 举例下例采用结构模型描述十进制计数器。十进制计数器的逻辑图如图 9 - 3所示。
图 9-3 十进制计数器
m o d u l e D e c a d e _ C t r (C l o c k,Z) ;
i n p u t C l o c k;
o u t p u t [0:3] Z;
w i r e S 1,S 2;
a n d A 1 (S 1,Z[ 2 ],Z[1]); //基本门实例语句。
// 4个模块实例语句:
JK_FF JK1(,J( 1 ' b 1 ),.K( 1 ' b 1 ),.C K(C l o c k),.Q(Z[ 0 ] ),.N Q( ) ),
J K 2(,J(S 2),.K( 1 ' b 1 ),.C K(Z[ 0 ] ),.Q(Z[ 1 ] ),.N Q( ) ),
J K 3(,J( 1 ' b 1 ),,K ( 1 ' b 1 ),,C K (Z[ 1 ] ),,Q (Z[ 2 ] ),.N Q( ) ),
J K 4(,J(S 1),.K( 1 ' b 1 ),.C K(Z[ 0 ] ),.Q(Z[ 3 ] ),.N Q(S 2) ) ;
e n d m o d u l e
注意常数作为输入端口信号的用法,以及悬空端口。
下面是另一个例子,3位可逆计数器的逻辑结构如图 9 - 4所示,其结构描述如下:
m o d u l e U p _ D o w n(C l k,C n t _ U p,C n t _ D o w n,Q) ;
i n p u t C l k,C n t _ U p,C n t _ D o w n;
o u t p u t [0:2] Q;
第 9章 结 构 建 模 89下载
w i r e S 1,S 2,S 3,S 4,S 5,S 6,S 7,S 8
JK_FF JK1( 1 ' b 1,1 ' b 1,C l k,Q[ 0 ],S 1),
J K 2( 1 ' b 1,1 ' b 1,S 4,Q[ 1 ],S 5),
J K 3( 1 ' b 1,1 ' b 1,S 8,Q[ 2 ],) ;
a n d A 1(S 2,C n t _ U p,Q[ 0 ] ),
A 2(S 3,S 1,C n t _ D o w n),
A 3(S 7,Q[ 1 ],C n t _ U p),
A 4(S 6,S 5,C n t _ D o w n) ;
o r O 1(S 4,S 2,S 3),
O 2(S 8,S 7,S 6) ;
endmodule
图 9-4 位可逆计数器习题
1,模块实例语句与门实例语句的区别是什么?
2,当端口悬空时,即端口没有被连接时,端口的值是什么?
3,对于 9,3节中的模块 FA,O R _ D E L AY值为 4,X O R _ D E L AY值为 7,A N D _ D E L AY值为 5,写出其结构描述形式。
4,用本章讲述的模块 FA编写执行加法和减法的 4位 A L U的结构模型。
5,用 5,11节中描述的 M U X 4 x 1模块编写 1 6 - 1多路选择器的结构化模型。
6,用异步低电平复位描述通用 N位计数器。将通用计数器在实例语句中用作 5位计数器用测试验证程序验证这个 5位计数器。
90 Verilog HDL 硬件描述语言 下载所有触发器的 J,K输入端口与高电平相连
Gate实例语句
UDP实例语句
Module实例语句第 5章和第 6章已经讨论了门级建模方式和 U D P建模方式,本章讲述模块实例语句。
9.1 模块
Verilog HDL中,基本单元定义成模块形式,如下所示,
m o d u l e m o d u l e _ n a m e(p o r t _ l i s t) ;
D e c l a r a t i o n s _ a n d _ S t a t e m e n t s
e n d m o d u l e
端口队列 p o rt _ l i s t列出了该模块通过哪些端口与外部模块通信。
9.2 端口模块的端口可以是输入端口、输出端口或双向端口。缺省的端口类型为线网类型(即
w i r e类型) 。但是,端口可被显式地指定为线网。输出或输入输出端口能够被重新声明为 r e g型寄存器。无论是在线网说明还是寄存器说明中,线网或寄存器必须与端口说明中指定的长度相同。下面是一些端口说明实例。
m o d u l e M i c r o (PC,Instr,NextAddr);
/ /端口说明
i n p u t [3:1] P C;
o u t p u t [1:8] I n s t r;
i n o u t [16:1] N e x t A d d r;
/ /重新说明端口类型:
w i r e [16:1] N e x t A d d r; //该说明是可选的,但如果指定了,就必须与它的端口说明保持相同长度。
r e g [1:8] I n s t r;
/ /I n s t r已被重新说明为 r e g类型,因此它能在 always 语句或在 i n i t i a l语句中赋值。
.,,
e n d m o d u l e
9.3 模块实例语句一个模块能够在另外一个模块中被引用,这样就建立了描述的层次。模块实例语句形式如下:
module_name instance_name(p o r t _ a s s o c i a t i o n s) ;
信号端口可以通过位置或名称关联;但是关联方式不能够混合使用。端口关联形式如下:
p o r t _ e x p r / /通过位置。
.P o r t N a m e (p o r t _ e x p r) / /通过名称。
p o rt _ e x p r可以是以下的任何类型:
1) 标识符( r e g或 n e t)
2) 位选择
3) 部分选择
4) 上述类型的合并
5) 表达式(只适用于输入端口)
在位置关联中,端口表达式按指定的顺序与模块中的端口关联。在通过名称实现的关联中,模块端口和端口表达式的关联被显式地指定,因此端口的关联顺序并不重要。下例使用两个半加器模块构造全加器;逻辑图如图 9 - 1所示。
m o d u l e H A(A,B,S,C);
i n p u t A,B;
o u t p u t S,C;
p a r a m e t e r A N D _ D E L A Y = 1,X O R _ D E L A Y = 2;
a s s i g n #X O R _ D E L A Y S = A ^ B;
a s s i g n #A N D _ D E L A Y C = A & B;
e n d m o d u l e
m o d u l e F A(P,Q,Cin,Sum,Cout) ;
i n p u t P,Q,Cin;
o u t p u t Sum,Cout;
p a r a m e t e r O R _ D E L A Y = 1;
w i r e S1,C1,C2;
/ /两个模块实例语句
HA h1 (P,Q,S1,C1); //通过位置关联。
HA h2 (,A(C i n),.S(S u m),.B(S 1),.C(C 2)); //通过端口与信号的名字关联。
/ /门实例语句:
or #O R _ D E L A Y O1 (Cout,C1,C2) ;
e n d m o d u l e
在第一个模块实例语句中,H A是模块的名字,h 1是实例名称,并且端口按位置关联,即信号 P与模块( H A)的端口 A连接,信号 Q与端口 B连接,S 1与 S连接,C 1与模块端口 C连接。
在第二个实例中,端口按名称关联,即模块( H A)和端口表达式间的连接是显示地定义的。
下例是使用不同端口表达式形式的模块实例语句。
Micro M1 (U d I n[3:0],{WrN,RdN},S t a t u s[0],S t a t u s[ 1 ],
& U d O u t [0:7],T x D a t a) ;
这个实例语句表示端口表达式可以是标识符( T x D a t a),位选择( S t a t u s[ 0 ]),部分位选择( U d I n[ 3,0 ]),合并( {Wr N,R d N})或一个表达式( & u d O u t[ 0,7 ]);表达式只能够连接到输入端口。
9.3.1 悬空端口在实例语句中,悬空端口可通过将端口表达式表示为空白来指定为悬空端口,例如:
84 Verilog HDL 硬件描述语言 下载图 9-1 使用两个半加器模块构造的全加器
DFF d1 (,Q(Q S),.Q b a r(),.D a t a( D ),
.P r e s e t(),.C l o c k(CK)); //名称对应方式。
DFF d2 (QS,,D,,CK) ; / /位置对应方式。
/ /输出端口 Q b a r悬空。
/ /输入端口 P r e s e t打开,其值设定为 z。
在这两个实例语句中,端口 Q b a r和 P re s e t悬空。
模块的输入端悬空,值为高阻态 z。模块的输出端口悬空,表示该输出端口废弃不用。
9.3.2 不同的端口长度当端口和局部端口表达式的长度不同时,端口通过无符号数的右对齐或截断方式进行匹配。例如:
m o d u l e C h i l d(Pba,Ppy) ;
i n p u t [5:0] P b a;
o u t p u t [2:0] P p y;
.,,
e n d m o d u l e
m o d u l e T o p;
w i r e [1:2] B d l;
w i r e [2:6] M p r;
Child C1(Bdl,Mpr) ;
e n d m o d u l e
在对 C h i l d模块的实例中,B d l[ 2 ]连接到 P b a[ 0 ],B d l[1] 连接到 P b a[ 1 ],余下的输入端口
P b a[ 5 ],P b a[ 4 ]和 P b a[ 3 ]悬空,因此为高阻态 z。与之相似,M p r[ 6 ]连接到 P p y[ 0 ],M p r[ 5 ]连接到 P p y[ 1 ],M p r[4] 连接到 P p y[ 2 ]。参见图 9 - 2。
图 9-2 端口匹配
9.3.3 模块参数值当某个模块在另一个模块内被引用时,高层模块能够改变低层模块的参数值。模块参数值的改变可采用下述两种方式:
1) 参数定义语句( d e f p a r a m);
2) 带参数值的模块引用。
1,参数定义语句参数定义语句形式如下:
d e f p a r a m hier_path_name1 = v a l u e 1,
hier_path_name2 = v a l u e 2,...;
较低层模块中的层次路径名参数可以使用如下语句显式定义(层次路径名在下一章中讲第 9章 结 构 建 模 85下载述) 。下面是一个例。模块 FA和 H A已在本节前面描述过。
m o d u l e TOP (N e w A,N e w B,N e w S,N e w C) ;
i n p u t N e w A,N e w B;
o u t p u t N e w S,N e w C;
d e f p a r a m H a 1,X O R _ D E L A Y = 5,
/ /实例 H a 1中的参数 X O R _ D E L A Y。
H a 1,A N D _ D E L A Y = 2;
/ /实例 H a 1中参数的 A N D _ D E L A Y。
HA Hal (NewA,NewB,NewS,NewC) ;
e n d m o d u l e
m o d u l e T O P 2 (NewP,NewQ,NewCin,NewSum,NewCout) ;
i n p u t NewP,NewQ,NewCin;
o u t p u t N e w S u m,N e w C o u t;
d e f p a r a m F a 1,h 1,X O R _ D E L A Y = 2,
/ /实例 F a 1的实例 h 1中的参数 X O R _ D E L A Y。
F a 1,h 1,A N D _ D E L A Y = 3,
/ /实例 F a 1的实例 h 1中的参数 A N D _ D E L A Y。
F a 1,O R _ D E L A Y = 3;
/ /实例 F a 1中的参数 O R _ D E L A Y)
FA Fa1 (NewP,NewQ,NewCin,NewSum,NewCout) ;
e n d m o d u l e
2,带参数值的模块引用在这种方法中,模块实例语句自身包含有新的参数值。下面的例子在前几节中也出现过,
本例中采用带参数的模块引用方式。
m o d u l e T O P 3 (N e w A,N e w B,N e w S,N e w C) ;
i n p u t N e w A,N e w B;
o u t p u t N e w S,N e w C;
H A #(5,2) H a 1(N e w A,N e w B,N e w S,N e w C) ;
/ /第 1个值 5赋给参数 A N D_D E L A Y,该参数在模块 H A中说明。
/ /第 2个值 2赋给参数 X O R_D E L A Y,该参数在模块 H A中说明。
e n d m o d u l e
m o d u l e T O P 4(N e w P,N e w Q,N e w C i n,N e w C o u t) ;
i n p u t N e w P,N e w Q,N e w C i n;
o u t p u t N e w S u m,N e w C o u n t;
d e f p a r a m F a 1,h 1,X O R _ D E L A Y = 2,//实例 F a 1中实例 h 1的参数 X O R _ D E L A Y。
F a 1,h 1,A N D _ D E L A Y = 3; //实例 F a 1中实例 h 1的参数 A N D _ D E L A Y。
F A #(3) F a 1(N e w P,N e w Q,N e w C i n,N e w C o u t) ;
/ /值 3是参数 O R _ D E L A Y的新值。
e n d m o d u l e
模块实例语句中参数值的顺序必须与较低层被引用的模块中说明的参数顺序匹配。在模块 TO P 3中,A N D _ D E L AY已被设置为 5,X O R _ D E L AY已被设置为 2。
模块 TO P 3和 TO P 4解释说明了带参数的模块引用只能用于将参数值向下传递一个层次(例如,O R _ D E L AY),但是参数定义语句能够用于替换层次中任意一层的参数值。
应注意到:在带参数的模块引用中,参数的指定方式与门级实例语句中时延的定义方式
86 Verilog HDL 硬件描述语言 下载相似;但由于对复杂模块的引用时,其实例语句不能像对门实例语句那样指定时延,故此处不会导致混淆。
参数值还可以表示长度。下面是通用的 M× N乘法器建模的实例。
m o d u l e M u l t i p l i e r(O p d _ 1,O p d _ 2,R e s u l t) ;
p a r a m e t e r E M = 4,E N = 2; //默认值
i n p u t [E M:1] O p d_ 1 ;
i n p u t [E N:1] O p d_ 2 ;
o u t p u t [E M+E N:1] R e s u l t;
a s s i g n R e s u l t = O p d _ 1 * O p d _ 2;
e n d m o d u l e
这个带参数的乘法器可在另一个设计中使用,下面是 8× 6乘法器模块的带参数引用方式:
w i r e [1:8] P i p e _ R e g;
w i r e [1:6] D b u s;
w i r e [1:14] A d d r _ C o u n t e r;
.,,
M u l t i p l i e r #(8,6) M 1(P i p e_R e g,D b u s,A d d r_C o u n t e r) ;
第 1个值 8指定了参数 E M的新值,第 2个值 6指定了参数 E N的新值。
9.4 外部端口在迄今为止所见到的模块定义中,端口表列举出了模块外部可见的端口。例如,
m o d u l e S c r a m _ A(A r b,C t r l,M e m _ B l k,B y t e) ;
i n p u t[0:3] A r b;
i n p u t C t r l;
i n p u t [8:0] M e m _ B l k;
o u t p u t [0:3] B y t e;
.,,
e n d m o d u l e
A r b,C t r l,M e m _ B l k和 B y t e为模块端口。这些端口同时也是外部端口,即在实例中,当采用名称关联方式时,外部端口名称用于指定相互连接。下面是模块 S c r a m _ A的实例。
Scram_A SX(,B y t e(B 1),.M e m _ B l k(M 1),.C t r l(C 1),.A r b(A 1) ) ;
在模块 S c r a m _ A中,外部端口名称隐式地指定。 Verilog HDL中提供显式方式指定外部端口名称。这可以通过按如下形式指定一个端口来完成:
.e x t e r n a l _ p o r t _ n a m e(i n t e r n a l _ p o r t _ n a m e)
下面是同一个例子,只不过是显式地指定外部端口。
m o d u l e S c r a m _ B (,D a t a(A r b),.C o n t r o l(C t r l),
.M e m _ W o r d(M e m _ B l k),.A d d r(B y t e) ) ;
i n p u t [0:3] A r b;
i n p u t C t r l;
i n p u t [ 8,0 ]M e m _ B l k;
o u t p u t [0:3] B y t e;
.,,
e n d m o d u l e
模块 S c r a m _ B在此实例中指定的外部端口是 D a t a,C o n t ro l,M e m _ Wo rd和 A d d r。端口表显式地表明了外部端口和内部端口之间的连接。注意外部端口无需声明,但是模块的内部端口第 9章 结 构 建 模 87下载却必须声明。外部端口在模块内不可见,但是却要在模块实例语句中使用,而内部端口因为在模块中可见,所以必须在模块中说明。在模块实例语句中,外部端口的使用如下所示:
Scram_B S1(,A d d r(A 1),.D a t a(D 1),.C o n t r o l(C 1),
.M e m _ W o r d(M 1) ) ;
在模块定义的端口表中,这两种概念不能混淆,即在模块定义中所有端口必须指定显式的端口名称,或者没有一个端口带有显式的端口名称。
如果模块端口通过位置连接,则模块实例语句中不能使用外部端口名称。
内部端口名称可以是标识符,也可以是下述类型的表达式:
位选择;
部分选择;
位选择、部分选择和标识符的合并。
例如,
m o d u l e S c r a m _ C (A r b[ 0,2 ],C t r l,
{ M e m _ B l k[ 0 ],M e m _ B l k[ 1 ] },B y t e[ 3 ] ) ;
i n p u t [0:3] A r b;
i n p u t C t r l;
i n p u t [8:0] M e m _ B l k;
o u t p u t [0:3] B y t e;
.,,
e n d m o d u l e
在 S c r a m _ C的模块定义中,端口表包括部分选择( A r b[ 0,2 ]),标识符( C t r l),合并
( {M e m _ B l k[ 0 ],M e m _ B l k[ 1 ] } )和位选择( B y t e[ 3 ]) 。在内部端口是位选择、部分选择或合并的情况下,没有隐式地指定外部端口名。因此,在这样的模块实例语句中,模块端口必须通过位置关联相互连接。例如,
Scram_C SYA (L 1[ 4,6 ],C L,M M Y[ 1,0 ],B T) ;
在这个实例语句中,端口通过位置关联相连接,因此 L 1[ 4∶ 6 ]连接到 A r b[ 0∶ 2 ],C L连接到 C t r l,M M Y[ 1 ]连接到 M e m _ B l k[ 0 ],M M Y[ 0 ]连接到 M e m _ B l k[ 1 ],B T连接到 B y t e[ 3 ]。
若使用端口名称关联(即当内部端口不是标识符时),必须对模块中的端口指定外部端口名。如下面的 S c r a m _ D模块定义所示。
m o d u l e S c r a m _ D (,D a t a(A r b[ 0,2 ] ),.C o n t r o l(C t r l),
.M e m _ W o r d( {M e m _ B l k[ 0 ],M e m _ B l k[ 1 ] } ),
.A d d r(B y t e[ 3 ] ) ) ;
i n p u t [0:3] A r b;
i n p u t C t r l;
i n p u t [8:0] M e m _ B l k;
o u t p u t [0:3] B y t e;
.,,
e n d m o d u l e
在 S c r a m _ D模块实例语句中,端口既能够使用位置连接,也能够使用名称连接,但是不能混合使用。下例的模块实例语句端口通过名称连接。
Scram_D SZ (,D a t a(L 1[ 4,6 ],.C o n t r o l(C L),
.M e m _ W o r d(M M Y[ 1,0 ],.A d d r(B T) ) ;
模块中可以只有外部端口而没有内部端口。即模块在引用中其外部端口可以悬空,不与内部信号相连。例如:
88 Verilog HDL 硬件描述语言 下载
m o d u l e Scram_E (,D a t a(),.C o n t r o l (C t r l),
.M e m _ W o r d ({ M e m _ B l k[0],M e m _ B l k [ 1 ] } ),
.A d d r( ) ) ;
i n p u t C t r l;
i n p u t [8:0] M e m _ B l k;
.,,
e n d m o d u l e
模块 S c r a m _ E 有两个外部端口 D a t a和 A d d r,这两个端口在使用时被悬空。
一个内部端口是否能与多个外部端口连接? Verilog HDL允许这样连接。例如,
m o d u l e F a n O u t (,A(C t r l I n),.B(C o n d O u t),.C(C o n d O u t) ) ;
i n p u t C t r l I n;
o u t p u t C o n d O u t;
a s s i g n CondOut = C t r l I n;
e n d m o d u l e
内部端口 C o n d O u t 与两个外部端口 B和 C连接,所以 C o n d O u t的值在 B和 C上都出现。
9.5 举例下例采用结构模型描述十进制计数器。十进制计数器的逻辑图如图 9 - 3所示。
图 9-3 十进制计数器
m o d u l e D e c a d e _ C t r (C l o c k,Z) ;
i n p u t C l o c k;
o u t p u t [0:3] Z;
w i r e S 1,S 2;
a n d A 1 (S 1,Z[ 2 ],Z[1]); //基本门实例语句。
// 4个模块实例语句:
JK_FF JK1(,J( 1 ' b 1 ),.K( 1 ' b 1 ),.C K(C l o c k),.Q(Z[ 0 ] ),.N Q( ) ),
J K 2(,J(S 2),.K( 1 ' b 1 ),.C K(Z[ 0 ] ),.Q(Z[ 1 ] ),.N Q( ) ),
J K 3(,J( 1 ' b 1 ),,K ( 1 ' b 1 ),,C K (Z[ 1 ] ),,Q (Z[ 2 ] ),.N Q( ) ),
J K 4(,J(S 1),.K( 1 ' b 1 ),.C K(Z[ 0 ] ),.Q(Z[ 3 ] ),.N Q(S 2) ) ;
e n d m o d u l e
注意常数作为输入端口信号的用法,以及悬空端口。
下面是另一个例子,3位可逆计数器的逻辑结构如图 9 - 4所示,其结构描述如下:
m o d u l e U p _ D o w n(C l k,C n t _ U p,C n t _ D o w n,Q) ;
i n p u t C l k,C n t _ U p,C n t _ D o w n;
o u t p u t [0:2] Q;
第 9章 结 构 建 模 89下载
w i r e S 1,S 2,S 3,S 4,S 5,S 6,S 7,S 8
JK_FF JK1( 1 ' b 1,1 ' b 1,C l k,Q[ 0 ],S 1),
J K 2( 1 ' b 1,1 ' b 1,S 4,Q[ 1 ],S 5),
J K 3( 1 ' b 1,1 ' b 1,S 8,Q[ 2 ],) ;
a n d A 1(S 2,C n t _ U p,Q[ 0 ] ),
A 2(S 3,S 1,C n t _ D o w n),
A 3(S 7,Q[ 1 ],C n t _ U p),
A 4(S 6,S 5,C n t _ D o w n) ;
o r O 1(S 4,S 2,S 3),
O 2(S 8,S 7,S 6) ;
endmodule
图 9-4 位可逆计数器习题
1,模块实例语句与门实例语句的区别是什么?
2,当端口悬空时,即端口没有被连接时,端口的值是什么?
3,对于 9,3节中的模块 FA,O R _ D E L AY值为 4,X O R _ D E L AY值为 7,A N D _ D E L AY值为 5,写出其结构描述形式。
4,用本章讲述的模块 FA编写执行加法和减法的 4位 A L U的结构模型。
5,用 5,11节中描述的 M U X 4 x 1模块编写 1 6 - 1多路选择器的结构化模型。
6,用异步低电平复位描述通用 N位计数器。将通用计数器在实例语句中用作 5位计数器用测试验证程序验证这个 5位计数器。
90 Verilog HDL 硬件描述语言 下载所有触发器的 J,K输入端口与高电平相连