|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
Verilog语法中最基本的数据类型有 线网(wire),寄存器(reg)和整数(integer)三种类型,这三种数据类型是可综合的数据类型,在Verilog 程序设计中被广泛使用。其它还有可以用于仿真的数据类型如 timer,real,字符串等变量都可以看作reg类型的扩展。wire,reg ,integer,timer,real是声明变量类型的关键字。变量必须先声明后使用,声明后变量的数据类型也就确定了。变量声明是模块(module)内惟一的,不能在同一个模块或函数内重复声明。* ]" K# R2 A: ~3 F8 E. y& M
- 线网(wire):0 ]9 B, ]# }) L* _; z4 U% y) e
线网(wire)类型表示逻辑单元或实例之间的连线,一般由逻辑单元的输出驱动。没有连接驱动的wire型变量的值为高阻’z’。3 S; L$ e) {! @' w# i" w$ d0 n
- wire类型变量的使用:
- wire型变量的声明与赋值
4 y; r' X6 N+ B5 uwire类型的变量只能由assign语句赋值,或在声明时赋初值。而且赋值的机会只有一次。
4 O+ O. E4 [; c* N, e/ ~; p- J# P 变量声明实例:
: N2 j/ ^( ] H7 iwire a, b; % ?! G( i: r0 F6 W
wire c = 0;# Y- T% _$ f- d8 G8 U3 x: r% l
wire d = 1'b1;2 f. T$ R1 L3 X, V" p u8 r7 O& D
assign a = c;+ s4 T# Z6 G, Y W) h
声明a, b为线网类型,并将c的值赋给a, 此时a的为0;而且a只有这一次赋值机会。, x% l' r, e5 f( J
变量c在声明的时候赋初值为0,此后c就一直保留该值,不能再给c赋值,也不能再次声明。/ T9 ^! {. j' R8 M! J- W
注意:wire类型的变量不能重复赋值。
4 J7 K# p4 a {4 x S0 a* \. H- 桥接
8 @' \, B# M( b' p+ J0 a7 C Wire 型变量作为中间变量可以实现桥接的作用。在下面的例子中可以看出,wire型变量起到变量之间值传递的作用。7 h+ }! P, Y8 f) s( [+ [6 \
实例1:! y& ~! [' F9 i0 k. \8 {
module wire_bridge+ C% g9 X. w9 o( a3 F6 {& i6 S
(
% H. I( ^, W0 Q. h2 Z$ j) \input a,b,ci,
; V5 N" g! I8 _8 houtput y,co# b3 [, Z, E. b) C
);! q- _0 @1 k. A% m9 l4 L, }
wire d, e, f;( f+ m3 E7 J- p: l2 _: x& a
assign d = a ^ b;& _9 W& z. D/ J. y
assign e = a & b; _+ z; H- I# t: J
assign f = ci & d;& T1 n$ r4 Q2 p# G/ P( G0 o ?
assign y = d ^ ci;
. \! B7 I/ e% I; e5 lassign co = e | f; , t0 S0 G! O; i% L6 c6 _
endmodule
) X1 u: s+ G0 _" E5 o9 rwire变量在逻辑电路中的对应关系,简单的说就是起到连线的作用。
7 [, O( N* N, n5 H; k" ]$ H在例化模块之间传递变量。5 S2 F; N. m# ]+ C
实例2:7 }; o, @5 M [
module fadder49 R/ ^, h- }& b( Z# N! ? H$ M7 @
(
8 @' l* r" L, ]8 ]1 dinput ci, L3 `+ @$ T, X( a. |- }1 `' f
input [3:0] a,
* y9 O" M* @$ p F7 Einput [3:0] b,
. v9 ]+ u5 C8 G2 l$ A' E* `0 o( o/ e
output [3:0] y,
9 T# o$ Y5 T0 Noutput co1 n( l: w3 ~$ d, ]% Y: u( M5 J
);
6 u1 n7 H8 v7 A8 W: W! Rwire co1,co2,co3;- l+ g$ N& u. h, T! b1 ]" b
// 例化 一位全加器,并重复使用4次+ \9 L& {7 J4 l
fadder1 fadder1_inst1
6 L9 W( l5 ^. h1 _/ \. A" [7 h% f(
$ g; o$ C0 M: `9 t.ci (ci),2 C# R% q/ f; ^* ~- n% m
.a (a[0]),
" f. h2 Y9 [: r.b (b[0]),
; z0 c: t6 N3 k) c2 ?.y (y[0]),: ?1 F, V5 n. Z4 R5 {- A) c( N
.co (co1)
# Q3 c. t# O2 r- v' @8 P$ e! g);
1 }" l# C/ o7 q- m3 U$ vfadder1 fadder1_inst2; M4 l; w( b, {1 y* l
(4 D% u% m6 V0 W9 I, ]
.ci (co1),
0 Y. G$ K L- ?, {, Q5 F! @* C& m.a (a[1]),
9 R5 A+ V4 b4 w) K/ J.b (b[1]),4 C. q3 C; C# x0 B3 ~8 U
.y (y[1]),: ~8 f: e. Z/ r- ~: L* @
.co (co2)
: L! O% H# L- Y- k. v);
' j4 \ e; _3 J* n. j* u
7 Y S% {$ `% i* hfadder1 fadder1_inst3
% r% {! `6 b- Z8 M(3 i. g" D( R# F5 Q, B
.ci (co2),
0 \( B6 D9 g- Y/ {" Y.a (a[2]),
! w8 R8 ? \' k- I- `.b (b[2]),
& b9 [- @8 I( }8 D, j% K.y (y[2]),
+ a& P0 |# p: F% `.co (co3)
! m. c. j y! C4 p+ `);7 e$ n# ] a+ t6 @
' ?' }0 e4 `8 c, i* S" {fadder1 fadder1_inst4
- V8 c( a9 n. o% P. G. Z( [(( e! @$ c) W- I# z$ h' x! s
.ci (co3),9 k: N. O8 V: i9 R
.a (a[3]),5 O$ Q" z8 m, u! V, R' g
.b (b[3]),
3 m7 f. L6 Y, r% H.y (y[3]),
* Y1 |: M) P: Q" {4 Y9 s.co (co)
5 R8 V* Z' B9 E4 G);
" k& M% Q: K* l% \" C* y C: Tendmodule" D& h; ?* v+ P5 o; b& m
wire型变量只能在并发语句或例化模块中被赋值,如实例1中的 d,e,f和实例2中co1,co2,co3; 但wire型变量可以根据需要在并发语句或顺序语句中赋值给其他变量。
# H1 \7 L2 [' f% A3 r对wire型变量的变量赋值,只能采用并发语句赋值。变量定义时初始化时赋值和例化模块的输出赋值,wire型变量不能在顺序语句中被赋值。( n; S* H. s( L) v5 r
寄存器(reg )类型:
5 D6 y9 S/ O% y! A8 e3 ^( Y# u寄存器(reg)是一种具有记忆功能的数据类型。用来表示存储单元,它会保持数据原有的值,直到被改写。一般分为锁存器和触发器两种。但无论哪一种建模,它们都只能在顺序语句中被赋值,而不能在并发语句中赋值。5 }2 B) {$ |( G# m& Q6 v% x0 \( { @
例:
Z# E' K6 ? W* |. W0 |: }reg a;reg b;always@(*)begin a <= 1’b1; b <= 1’b0;end
' z7 W; U* L9 L) w而 assign a = 1’b1; 就是错误的;因为a是reg型变量。1 O7 F5 \. l2 ]
与wire类型变量不同的时,在reg型变量声明时可以赋初值,而后续的顺序语句可以对该变量继续赋值,从而修改原值。而wire型变量只有一次赋值机会。
/ i+ _5 j( J ^' f) M9 F( u注意:在同一个顺序过程语句中可以对reg型变量多次赋值,后面的赋值会替代前面的赋值,充分利用这一特点,可以是程序更简洁。但不允许在多个顺序过程语句中对同一个reg型变量都赋值。
1 `* L: G8 C" c( j' e6 H. V. mmodule reg_assign( input clk, input a, input b, input sel, output c);reg ma;//顺序过程语句1always @(posedge clk)begin if(sel) ma <= a;end//顺序过程语句2always @(posedge clk)begin if(!sel) ma <= b;endassign c = ma;endmodule
( u* C9 y7 b# [7 d* ~# H+ W上面的例子红色部分是有问题的,虽然reg 型变量允许被多次赋值,但不能在不同的顺序过程中多次赋值。上面的代码可以修改如下:7 ~3 j: o Q) Z( Y. s$ q2 w
module reg_assign
+ G: ^/ ~6 z4 C9 x(
% V# Y2 q8 G( { `5 D; K& X8 C4 Ginput clk,
6 \" q3 P% z0 @input a,
$ S5 e( J4 l: c. Q6 p) k% D7 Qinput b,' w1 N. W5 ]8 @ C; P8 m
input sel,9 k: h6 G5 I1 S$ a( y
output c3 a0 |0 [* W; u# z) w2 R6 j
);
4 J3 P6 W6 [" ^8 S1 _) }reg ma;- o6 v; K) U/ G3 M
//顺序过程语句1
8 V8 x: C7 M3 halways @(posedge clk)# `7 B. }3 V8 ^
begin q7 K' o# j# |; {7 M) y
if(sel)7 x# C: H/ Y- ~( n) k0 B( k
ma <= a;
$ D/ p- l k9 \, K6 Yelse
6 I6 |9 f- T' N9 b. Kma <= b;1 P; c( O+ x" Y; t( F
end. j) Z' n" Q! J3 l8 a+ t, @! V
% N0 o( V6 S! l9 C4 ?1 l6 T
assign c = ma;& U& F% Z" E+ \/ d1 Z
% A4 z& D, ]. G3 i3 Pendmodule- N, y0 _- c/ p) } S
wire型变量与reg型变量都可以使用向量(vector)进行声明;
- a% S/ `0 e5 I7 N6 P$ j9 j$ D
3 P0 |4 R* J/ u0 `如 : wire [3:0] a, b;% z9 I! w& m) u) ?: C% g' |
+ `/ o; V2 n: e F# K% f* Qreg [3:0] c, d;
9 s% ~; _) N$ g( Q0 G
8 F: p# j! z5 ^4 `向量的运算遵循运算符的规则,细节参见verilog 运算符。
) I) n/ y, n6 h9 ~' a |
|