本章介紹Verilog HDL的基本要素,包括標識符、注釋、數值、編譯程序指令、系統任務和系統函數。另外,本章還介紹了 Ve r i l o g硬體描述語言中的兩種數據類型。
3.1 標識符
Verilog HDL中的標識符( i d e n t i f i e r )可以是任意一組字母、數字、$符號和_(下劃線)符號的組合,但標識符的第一個字符必須是字母或者下劃線。另外,標識符是區分大小寫的。以下是標識符的幾個例子:
C o u n t
COUNT / / 與C o u n t不同。
_ R 1 _ D 2
R 5 6 _ 6 8
F I V E $
轉義標識符(escaped identifier )可以在一條標識符中包含任何可列印字符。轉義標識符以 \(反斜線)符號開頭,以空白結尾(空白可以是一個空格、一個制表字符或換行符)。下面例舉了幾個轉義標識符:
\ 7 4 0 0
\ . * .$
\ { * * * * * * }
\ ~Q
\O u t G a t e 與O u t G a t e相同。
最後這個例子解釋了在一條轉義標識符中,反斜線和結束空格並不是轉義標識符的一部分。也就是說,標識符\ O u t G a t e 和標識符O u t G a t e恆等Verilog HDL定義了一系列保留字,叫做關鍵詞,它僅用於某些上下文中。附錄A列出了語言中的所有保留字。注意只有小寫的關鍵詞才是保留字。例如,標識符 a l w a y s (這是個關鍵詞)與標識符A LWAY S(非關鍵詞)是不同的。另外,轉義標識符與關鍵詞並不完全相同。標識符 \initial 與標識符i n i t i a l(這是個關鍵詞)不同。注意這一約定與那些轉義標識符不同。
3.2 注釋
在Verilog HDL中有兩種形式的注釋。
/ *第一種形式:可以擴展至
多行 * /
/ /第二種形式:在本行結束。
3.3 格式
Verilog HDL區分大小寫。也就是說大小寫不同的標識符是不同的。此外, Verilog HDL是
自由格式的,即結構可以跨越多行編寫,也可以在一行內編寫。白空(新行、制表符和空格)
沒有特殊意義。下面通過實例解釋說明。
initial beginT o p = 3' b001; #2 T o p = 3' b011; e n d
和下面的指令一樣:
i n i t i a l
begin
T o p = 3' b001;
#2 T o p = 3' b 0 1 1 ;
e n d
3.4 系統任務和函數
以$字符開始的標識符表示系統任務或系統函數。任務提供了一種封裝行為的機制。這種機制可在設計的不同部分被調用。任務可以返回 0個或多個值。函數除只能返回一個值以外與任務相同。此外,函數在0時刻執行,即不允許延遲,而任務可以帶有延遲。
$d i s p l a y ("Hi, you have reached LT today");
/* $d i s p l a y 系統任務在新的一行中顯示。* /
$t i m e
/ /該系統任務返回當前的模擬時間。
3.5 編譯指令
以`(反引號)開始的某些標識符是編譯器指令。在 Verilog 語言編譯時,特定的編譯器指令在整個編譯過程中有效(編譯過程可跨越多個文件),直到遇到其它的不同編譯程序指令。
完整的標準編譯器指令如下:
• `define, `undef
• `ifdef, `else, `endif
• `default_nettype
• `include
• `resetall
• `timescale
• `unconnected_drive, `nounconnected_drive
• `celldefine, `endcelldefine
3.5.1 `define 和`undef
` d e f i n e指令用於文本替換,它很像C語言中的#define 指令,如:
` d e f i n e M A X _ B U S _ S I Z E 3 2
. . .
r e g [ `M A X _ B U S _ S I Z E - 1:0 ] A d d R e g;
一旦` d e f i n e 指令被編譯,其在整個編譯過程中都有效。例如,通過另一個文件中的
` d e f i n e指令,M A X_B U S_S I Z E 能被多個文件使用。
`undef 指令取消前面定義的宏。例如:
` d e f i n e W O R D 16 //建立一個文本宏替代。
. . .
w i r e [ `W O R D : 1] Bus;
. . .
` u n d e f W O R D
// 在` u n d e f編譯指令後, W O R D的宏定義不再有效.
3.5.2 `ifdef、`else 和`endif
這些編譯指令用於條件編譯,如下所示:
` i f d e f W I N D O W S
p a r a m e t e r WORD_SIZE = 16
` e l s e
p a r a m e t e r W O R D _ S I Z E = 32
` e n d i f
在編譯過程中,如果已定義了名字為 W I N D O W S的文本宏,就選擇第一種參數聲明,否則
選擇第二種參數說明。
` e l s e 程序指令對於`ifdef 指令是可選的。
3.5.3 `default_nettype
該指令用於為隱式線網指定線網類型。也就是將那些沒有被說明的連線定義線網類型。
`default_nettype wand
該實例定義的預設的線網為線與類型。因此,如果在此指令後面的任何模塊中沒有說明的連
線,那麼該線網被假定為線與類型。
3.5.4 `include
` i n c l u d e 編譯器指令用於嵌入內嵌文件的內容。文件既可以用相對路徑名定義,也可以用
全路徑名定義, 例如:
` i n c l u d e " . . / . . /primitives.v "
編譯時,這一行由文件「. . / . . / p r i m i t i v e s . v」 的內容替代。
3.5.5 `resetall
該編譯器指令將所有的編譯指令重新設置為預設值。
` r e s e t a l l
例如,該指令使得預設連線類型為線網類型。
3.5.6 `timescale
在Verilog HDL 模型中,所有時延都用單位時間表述。使用 ` t i m e s c a l e編譯器指令將時間
單位與實際時間相關聯。該指令用於定義時延的單位和時延精度。 ` t i m e s c a l e編譯器指令格式
為:
` t i m e s c a l e t i m e _ u n i t / t i m e _ p r e c i s i o n
t i m e _ u n i t 和t i m e _ p re c i s i o n 由值1、1 0、和1 0 0以及單位s、m s、u s、n s、p s和f s組成。例如:
` t i m e s c a l e 1 n s / 1 0 0 p s
表示時延單位為1ns, 時延精度為1 0 0 p s。`timescale 編譯器指令在模塊說明外部出現, 並且影響
後面所有的時延值。例如:
` t i m e s c a l e 1ns/ 100ps
m o d u l e A n d F u n c (Z, A, B) ;
o u t p u t Z;
i n p u t A, B;
a n d # (5.22, 6.17 ) A l (Z, A, B);
/ /規定了上升及下降時延值。
e n d m o d u l e
編譯器指令定義時延以 n s為單位,並且時延精度為 1/10 ns(100 ps)。因此,時延值5 . 2 2對應
5.2 ns, 時延6 . 1 7對應6.2 ns。如果用如下的` t i m e s c a l e程序指令代替上例中的編譯器指令 ,
` t i m e s c a l e 1 0 n s / 1 n s
那麼5 . 2 2對應52ns, 6.17對應6 2 n s。
在編譯過程中,` t i m e s c a l e指令影響這一編譯器指令後面所有模塊中的時延值,直至遇到
另一個` t i m e s c a l e指令或` r e s e t a l l指令。當一個設計中的多個模塊帶有自身的 ` t i m e s c a l e編譯指
令時將發生什麼?在這種情況下,模擬器總是定位在所有模塊的最小時延精度上,並且所有
時延都相應地換算為最小時延精度。例如,
` t i m e s c a l e 1ns/ 100ps
m o d u l e A n d F u n c (Z, A, B) ;
o u t p u t Z;
i n p u t A, B;
a n d # (5.22, 6.17 ) A l (Z, A, B) ;
e n d m o d u l e
` t i m e s c a l e 10ns/ 1ns
m o d u l e T B;
r e g PutA, PutB;
w i r e G e t O;
i n i t i a l
b e g i n
P u tA = 0;
P u t B = 0;
#5.21 P u t B = 1;
#10.4 P u t A = 1;
#15 P u t B = 0;
e n d
A n d F u n c A F 1(GetO, PutA, PutB ) ;
e n d m o d u l e
在這個例子中,每個模塊都有自身的 ` t i m e s c a l e編譯器指令。` t i m e s c a l e編譯器指令第一次應用於時延。因此,在第一個模塊中, 5 . 2 2對應5.2 ns, 6.17對應6.2 ns; 在第二個模塊中5 . 2 1對應52 ns, 10.4對應104 ns, 15對應150 ns。如果仿真模塊T B,設計中的所有模塊最小時間精度為100 ps。因此,所有延遲(特別是模塊 T B中的延遲)將換算成精度為 100 ps。延遲52 ns現在對應5 2 0 * 100 ps,1 0 4對應1 0 4 0 * 100 ps,1 5 0對應1 5 0 0 * 100 ps。更重要的是,仿真使用100 ps為時間精度。如果仿真模塊 A n d F u n c,由於模塊T B不是模塊A d d F u n c的子模塊,模塊T B中的` t i m e s c a l e程序指令將不再有效。
3.5.7 `unconnected_drive和`nounconnected_drive
在模塊實例化中,出現在這兩個編譯器指令間的任何未連接的輸入埠或者為正偏電路
狀態或者為反偏電路狀態。
` u n c o n n e c t e d _ d r i v e p u l l 1
. . .
/ *在這兩個程序指令間的所有未連接的輸入埠為正偏電路狀態(連接到高電平) * /
` n o u n c o n n e c t e d _ d r i v e
`unconnected_drive pull0
. . .
/ *在這兩個程序指令間的所有未連接的輸入埠為反偏電路狀態(連接到低電平) * /
` n o u n c o n n e c t e d _ d r i v e
3.5.8 `celldefine 和 `endcelldefine
這兩個程序指令用於將模塊標記為單元模塊。它們表示包含模塊定義,如下例所示。
` c e l l d e f i n e
m o d u l e F D 1 S 3 A X (D, CK, Z) ;
. . .
e n d m o d u l e
` e n d c e l l d e f i n e
某些P L I例程使用單元模塊。
3.6 值集合
Verilog HDL有下列四種基本的值:
1) 0:邏輯0或「假」
2) 1:邏輯1或「真」
3) x:未知
4) z:高阻
注意這四種值的解釋都內置於語言中。如一個為 z的值總是意味著高阻抗,一個為 0的值
通常是指邏輯0。
在門的輸入或一個表達式中的為「 z」的值通常解釋成「x」。此外,x值和z值都是不分大
小寫的,也就是說,值0 x 1 z與值0 X 1 Z相同。Verilog HDL中的常量是由以上這四類基本值組成的。
Verilog HDL中有三類常量:
1) 整型
2) 實數型
3) 字符串型
下劃線符號(_)可以隨意用在整數或實數中,它們就數量本身沒有意義。它們能用來提
高易讀性;唯一的限制是下劃線符號不能用作為首字符。
3.6.1 整型數
整型數可以按如下兩種方式書寫:
1) 簡單的十進位數格式
2) 基數格式
1. 簡單的十進位格式
這種形式的整數定義為帶有一個可選的 「+」(一元)或 「-」(一元)操作符的數字序
列。下面是這種簡易十進位形式整數的例子。
32 十進位數3 2
-15 十進位數-1 5
這種形式的整數值代表一個有符號的數。負數可使用兩種補碼形式表示。因此 3 2在5位的
二進位形式中為1 0 0 0 0,在6位二進位形式中為11 0 0 0 1;-1 5在5位二進位形式中為1 0 0 0 1,在6
位二進位形式中為11 0 0 0 1。
2. 基數表示法
這種形式的整數格式為:
[s i z e ] 'base value
s i z e 定義以位計的常量的位長; b a s e為o或O(表示八進位),b或B(表示二進位),d或D(表示十進位),h或H(表示十六進位)之一; v a l u e是基於b a s e的值的數字序列。值 x和z以及十六進位中的a到f不區分大小寫。
下面是一些具體實例:
5'O37 5 位八進位數
4'D2 4 位十進位數
4'B1x_01 4 位二進位數
7'Hx 7 位x(擴展的x), 即x x x x x x x
4'hZ 4 位z(擴展的z) , 即z z z z
4'd-4 非法:數值不能為負
8'h 2 A 在位長和字符之間,以及基數和數值之間允許出現空格
3'b001 非法: ` 和基數b之間不允許出現空格
(2+3)'b10 非法:位長不能夠為表達式
注意,x(或z)在十六進位值中代表4位x(或 z ),在八進位中代表3位x(或 z ),在二進
制中代表1位x(或z)。基數格式計數形式的數通常為無符號數。這種形式的整型數的長度定義是可選的。如果沒有定義一個整數型的長度,數的長度為相應值中定義的位數。下面是兩個例子:
'o721 9 位八進位數
'hAF 8 位十六進位數
如果定義的長度比為常量指定的長度長,通常在左邊填 0補位。但是如果數最左邊一位為
x或z,就相應地用x或z在左邊補位。例如:
10'b10 左邊添0佔位, 0000000010
10'bx0x1 左邊添x佔位, x x x x x x x 0 x 1
如果長度定義得更小,那麼最左邊的位相應地被截斷。例如:
3 ' b 1 0 0 1 _ 0 0 1 1與3'b011 相等
5'H0FFF 與5'H1F 相等
?字符在數中可以代替值z在值z被解釋為不分大小寫的情況下提高可讀性
3.6.2 實數
實數可以用下列兩種形式定義:
1) 十進位計數法;例如
2 . 0
5 . 6 7 8
1 1 5 7 2 . 1 2
0 . 1
2. // 非法:小數點兩側必須有1位數字
2) 科學計數法; 這種形式的實數舉例如下:
23_5.1e2 其值為23510.0; 忽略下劃線
3.6E2 360.0 ( e與E相同)
5 E-4 0 . 0 0 0 5
Ve r i l o g語言定義了實數如何隱式地轉換為整數。實數通過四捨五入被轉換為最相近的整
數。
4 2 . 4 4 6, 42.45 轉換為整數4 2
92.5, 92.699 轉換為整數9 3
-15.62 轉換為整數-1 6
-26.22 轉換為整數-2 6
3.6.3 字符串
字符串是雙引號內的字符序列。字符串不能分成多行書寫。例如 :
"INTERNAL ERROR"
" R E A C H E D-> H E R E "
用8位A S C I I值表示的字符可看作是無符號整數。因此字符串是 8位A S C I I值的序列。為存
儲字符串「INTERNAL ERROR」,變量需要8 * 1 4位。
r e g [1 : 8*14] M e s s a g e;
. . .
M e s s a g e = "INTERNAL ERROR"
反斜線 (\ ) 用於對確定的特殊字符轉義。
\n 換行符
\t 制表符
\\ 字符\本身
\" 字符"
\206 八進位數2 0 6對應的字符
3.7 數據類型
Verilog HDL 有兩大類數據類型。
1) 線網類型。net type 表示Ve r i l o g結構化元件間的物理連線。它的值由驅動元件的值決定,例如連續賦值或門的輸出。如果沒有驅動元件連接到線網,線網的預設值為 z。
2) 寄存器類型。register type表示一個抽象的數據存儲單元,它只能在 a l w a y s語句和i n i t i a l語句中被賦值,並且它的值從一個賦值到另一個賦值被保存下來。寄存器類型的變量具有 x的預設值。
3.7.1 線網類型
線網數據類型包含下述不同種類的線網子類型。
• wire
• tri
• wor
• trior
• wand
• triand
• trireg
• tri1
• tri0
• supply0
• supply1
簡單的線網類型說明語法為:
n e t _ k i n d [m s b:l s b] net1, net2, . . . , n e t N;
n e t _ k i n d 是上述線網類型的一種。 m s b和l s b 是用於定義線網範圍的常量表達式;範圍定義是可選的;如果沒有定義範圍,預設的線網類型為 1位。下面是線網類型說明實例。
w i r e Rdy, Start; //2個1位的連線。
w a n d [2:0] A d d r; //A d d r是3位線與。
當一個線網有多個驅動器時,即對一個線網有多個賦值時,不同的線網產生不同的行為。
例如,
w o r R d e;
. . .
a s s i g n R d e = B l t & W y l;
. . .
a s s i g n Rde = K b l | K i p;
本例中,R d e有兩個驅動源,分別來自於兩個連續賦值語句。由於它是線或線網, R d e的有
效值由使用驅動源的值(右邊表達式的值)的線或(wor)表(參見後面線或網的有關章節)決定。
1. wire和t r i線網
用於連接單元的連線是最常見的線網類型。連線與三態線 ( t r i )網語法和語義一致;三態線
可以用於描述多個驅動源驅動同一根線的線網類型;並且沒有其他特殊的意義。
w i r e R e s e t;
w i r e [3:2] Cla, Pla, Sla ;
t r i [ M S B-1 : L S B +1] A r t;
如果多個驅動源驅動一個連線(或三態線網),線網的有效值由下表決定。
wire (或 t r i ) 0 1 x z
0 0 x x 0
1 x 1 x 1
x x x x x
z 0 1 x z
下面是一個具體實例:
a s s i g n C l a = P l a & S l a;
. . .
a s s i g n Cla = P l a ^ S l a;
在這個實例中, C l a有兩個驅動源。兩個驅動源的值(右側表達式的值)用於在上表中索引,以便決定C l a的有效值。由於C l a是一個向量,每位的計算是相關的。例如,如果第一個右側
表達式的值為0 1 x, 並且第二個右測表達式的值為11 z,那麼C l a 的有效值是x 1 x (第一位0和1在表中索引到x, 第二位1和1在表中索引到1,第三位x 和z在表中索引到x)。
2. wor和t r i o r線網
線或指如果某個驅動源為 1,那麼線網的值也為1。線或和三態線或( t r i o r )在語法和功能上
是一致的。
w o r [M S B:L S B] A r t;
t r i o r [M A X-1: M I N-1] Rdx, Sdx, Bdx ;
如果多個驅動源驅動這類網,網的有效值由下表決定。
wor (或 t r i o r ) 0 1 x z
0 0 1 x 0
1 1 1 1 1
x x 1 x x
z 0 1 x z
3. wand和t r i a n d線網
線與( w a n d )網指如果某個驅動源為 0,那麼線網的值為 0。線與和三態線與 ( t r i a n d )網在語法和功能上是一致的。
w a n d [-7 : 0] D b u s;
t r i a n d Reset, Clk;
如果這類線網存在多個驅動源,線網的有效值由下表決定。
wand (或 t r i a n d ) 0 1 x z
0 0 0 0 0
1 0 1 x 1
x 0 x x x
z 0 1 x z
4. trireg線網
此線網存儲數值(類似於寄存器),並且用於電容節點的建模。當三態寄存器 ( t r i r e g )的所有驅動源都處於高阻態,也就是說,值為 z時,三態寄存器線網保存作用在線網上的最後一個值。此外,三態寄存器線網的預設初始值為 x。
t r i r e g [1:8] Dbus, Abus;
5. tri0和t r i 1線網
這類線網可用於線邏輯的建模,即線網有多於一個驅動源。 t r i 0(t r i 1)線網的特徵是,
若無驅動源驅動,它的值為0(t r i 1的值為1)。
t r i 0 [-3:3] G n d B u s;
t r i 1 [ 0 :-5] OtBus, ItBus;
下表顯示在多個驅動源情況下t r i 0或t r i 1網的有效值。
tri0 (tri1) 0 1 x z
0 0 x x 0
1 x 1 x 1
x x x x x
z 0 1 x 0 ( 1 )
6. supply0和s u p p l y 1線網
s u p p l y 0用於對「地」建模,即低電平 0;s u p p l y 1網用於對電源建模,即高電平 1;例如:
s u p p l y 0 Gnd, ClkGnd;
s u p p l y 1 [2:0] Vcc;
3.7.2 未說明的線網
在Verilog HDL中,有可能不必聲明某種線網類型。在這樣的情況下,預設線網類型為 1
位線網。可以使用` d e f a u l t _ n e t t y p e編譯器指令改變這一隱式線網說明方式。使用方法如下:
` d e f a u l t _ n e t t y p e n e t _ k i n d
例如,帶有下列編譯器指令:
`default_nettype wand
任何未被說明的網預設為1位線與網。
3.7.3 向量和標量線網
在定義向量線網時可選用關鍵詞s c a l a re d 或v e c t o re d。如果一個線網定義時使用了關鍵詞v e c t o re d, 那麼就不允許位選擇和部分選擇該線網。換句話說,必須對線網整體賦值(位選擇和部分選擇在下一章中講解)。例如:
wire vectored[3:1] G r b;
/ /不允許位選擇G r b[ 2 ]和部分選擇G r b [ 3 : 2 ]
wor scalared [4:0] B e s t;
/ /與w o r [4:0] B e s t相同,允許位選擇B e s t [ 2 ]和部分選擇B e s t [ 3 : 1 ]。
如果沒有定義關鍵詞,預設值為標量。
3.7.4 寄存器類型
有5種不同的寄存器類型。
• reg
• integer
• time
• real
• realtime
1. reg寄存器類型
寄存器數據類型r e g是最常見的數據類型。r e g類型使用保留字re g加以說明,形式如下:
r e g [ m s b: l s b] reg1, reg2, . . . r e g N;
m s b和l s b 定義了範圍,並且均為常數值表達式。範圍定義是可選的;如果沒有定義範圍,缺
省值為1位寄存器。例如:
r e g [3:0] S a t; // S a t為4 位寄存器。
r e g C n t; //1 位寄存器。
r e g [1:32] Kisp, Pisp, Lisp ;
寄存器可以取任意長度。寄存器中的值通常被解釋為無符號數 , 例如:
r e g [1:4] C o m b;. . .
C o m b = -2; //C o m b 的值為1 4(1 1 1 0),1 1 1 0是2的補碼。
C o m b = 5; //C o m b的值為1 5(0 1 0 1)。
2. 存儲器
存儲器是一個寄存器數組。存儲器使用如下方式說明:
r e g [ m s b: 1 s b] m e m o r y 1 [ u p p e r 1: l o w e r 1] ,
m e m o r y 2 [u p p e r 2: l o w e r 2] ,. . . ;
例如:
r e g [0:3 ] M y M e m [ 0 : 6 3 ]
/ /M y M e m為6 4個4位寄存器的數組。
r e g B o g [ 1 : 5 ]
/ /B o g為5個1位寄存器的數組。
M y M e m和B o g都是存儲器。數組的維數不能大於 2。注意存儲器屬於寄存器數組類型。線網數
據類型沒有相應的存儲器類型。
單個寄存器說明既能夠用於說明寄存器類型,也可以用於說明存儲器類型。
p a r a m e t e r A D D R _ S I Z E = 16 , W O R D _ S I Z E = 8;
r e g [1: W O R D _ S I Z E] R a m P a r [ A D D R _ S I Z E-1 : 0], D a t a R e g;
R a m P a r是存儲器,是1 6個8位寄存器數組,而D a t a R e g是8位寄存器。
在賦值語句中需要注意如下區別:存儲器賦值不能在一條賦值語句中完成,但是寄存器
可以。因此在存儲器被賦值時,需要定義一個索引。下例說明它們之間的不同。
r e g [1:5] D i g; //D i g為5位寄存器。
. . .
D i g = 5'b11011;
上述賦值都是正確的, 但下述賦值不正確:
r e g B O g[1:5]; //B o g為5個1位寄存器的存儲器。
. . .
B o g = 5'b11011;
有一種存儲器賦值的方法是分別對存儲器中的每個字賦值。例如:
r e g [0:3] X r o m [ 1 : 4 ]
. . .
X r o m[1] = 4'hA;
X r o m[2] = 4'h8;
X r o m[3] = 4'hF;
X r o m[4] = 4'h2;
為存儲器賦值的另一種方法是使用系統任務:
1) $re a d m e m b (加載二進位值)
2) $re a d m e m b (加載十六進位值)
這些系統任務從指定的文本文件中讀取數據並加載到存儲器。文本文件必須包含相應的二進
制或者十六進位數。例如:
r e g [1:4] RomB [7:1] ;
$ r e a d m e m b ("ram.patt", RomB);
R o m b是存儲器。文件「 r a m . p a t t」必須包含二進位值。文件也可以包含空白空間和注釋。下面是文件中可能內容的實例。
1 1 0 1
1 1 1 0
1 0 0 0
0 1 1 1
0 0 0 0
1 0 0 1
0 0 1 1
系統任務$ r e a d m e m b促使從索引7即R o m b最左邊的字索引,開始讀取值。如果只加載存儲
器的一部分,值域可以在$ r e a d m e m b方法中顯式定義。例如:
$r e a d m e m b ("ram.patt", R o m B, 5, 3);
在這種情況下只有 R o m b[ 5 ] ,R o m b[ 4 ]和R o m b[ 3 ]這些字從文件頭開始被讀取。被讀取的值為
11 0 1、11 0 0和1 0 0 0。
文件可以包含顯式的地址形式。
@hex_address value
如下實例:
@5 11001
@2 11010
在這種情況下,值被讀入存儲器指定的地址。
當只定義開始值時,連續讀取直至到達存儲器右端索引邊界。例如:
$r e a d m e m b ("rom.patt", R o m B, 6);
/ /從地址6開始,並且持續到1。
$r e a d m e m b ( "rom.patt",R o m B, 6, 4);
/ /從地址6讀到地址4。
3. Integer寄存器類型
整數寄存器包含整數值。整數寄存器可以作為普通寄存器使用,典型應用為高層次行為
建模。使用整數型說明形式如下:
i n t e g e r integer1, integer2 ,. . . intergerN [m s b:1 s b] ;
m s b和l s b是定義整數數組界限的常量表達式,數組界限的定義是可選的。注意容許無位界
限的情況。一個整數最少容納 3 2位。但是具體實現可提供更多的位。下面是整數說明的實
例。
i n t e g e r A, B, C; //三個整數型寄存器。
i n t e g e r Hist [3:6]; //一組四個寄存器。
一個整數型寄存器可存儲有符號數,並且算術操作符提供 2的補碼運算結果。
整數不能作為位向量訪問。例如,對於上面的整數 B的說明,B[ 6 ]和B[ 2 0:1 0 ]是非法的。
一種截取位值的方法是將整數賦值給一般的 r e g類型變量,然後從中選取相應的位,如下所
示:
r e g [31:0] B r e g;
i n t e g e r B i n t;
. . .
/ /B i n t[ 6 ]和B i n t[ 2 0 : 1 0 ]是不允許的。
. . .
B r e g = B i n t;
/ * 現在,B r e g[ 6 ]和B r e g[ 2 0 : 1 0 ]是允許的,並且從整數B i n t獲取相應的位值。 * /
上例說明了如何通過簡單的賦值將整數轉換為位向量。類型轉換自動完成,不必使用特
定的函數。從位向量到整數的轉換也可以通過賦值完成。例如 :
i n t e g e r J;
r e g [3:0] B c q;
J = 6; // J的值為3 2 ' b 0 0 0 0 . . . 0 0 1 1 0。
B c q = J; // B c q的值為4 ' b 0 1 1 0。
B c q = 4'b0101.
J = B c q; //J的值為3 2 ' b 0 0 0 0 . . . 0 0 1 0 1。
J = -6; // J 的值為 3 2 ' b 1 1 1 1 . . . 1 1 0 1 0。
B c q = J; //B c q的值為4 ' b 1 0 1 0。
注意賦值總是從最右端的位向最左邊的位進行;任何多餘的位被截斷。如果你能夠回憶
起整數是作為2的補碼位向量表示的,就很容易理解類型轉換。
4. time類型
t i m e類型的寄存器用於存儲和處理時間。 t i m e類型的寄存器使用下述方式加以說明。
t i m e time_id1, time_id2 , . . . , t i m e _ i d N [ m s b:1 s b] ;
m s b和l s b是表明範圍界限的常量表達式。如果未定義界限,每個標識符存儲一個至少 6 4位的
時間值。時間類型的寄存器只存儲無符號數。例如 :
t i m e E v e n t s [0:31]; //時間值數組。
t i m e C u r r T i m e; //C u r r T i m e 存儲一個時間值。
5. real和r e a l t i m e類型
實數寄存器(或實數時間寄存器)使用如下方式說明:
/ /實數說明:
r e a l r e a l _ r e g 1, r e a l _ r e g 2, . . ., r e a l _ r e g N;
/ /實數時間說明:
r e a l t i m e r e a l t i m e _ r e g 1, r e a l t i m e _ r e g 2, . . . , r e a l t i m e _ r e g N;
r e a l t i m e與r e a l類型完全相同。例如:
r e a l Swing, Top;
r e a l t i m e C u r r T i m e;
r e a l說明的變量的預設值為0。不允許對r e a l聲明值域、位界限或字節界限。
當將值x和z賦予r e a l類型寄存器時,這些值作0處理。
r e a l R a m C n t;
. . .
R a m C n t = 'b01x1Z;
R a m C n t在賦值後的值為' b 0 1 0 1 0。
3.8 參數
參數是一個常量。參數經常用於定義時延和變量的寬度。使用參數說明的參數只被賦值
一次。參數說明形式如下:
p a r a m e t e r p a r a m 1 = c o n s t _ e x p r 1, param2 = c o n s t _ e x p r 2, . . . ,
p a r a m N = c o n s t _ e x p r N;
下面為具體實例:
p a r a m e t e r L I N E L E N G T H = 132, A L L _ X _ S = 16'bx;
p a r a m e t e r B I T = 1, B Y T E = 8, P I = 3.14;
p a r a m e t e r S T R O B E _ D E L A Y = ( B Y T E + B I T) / 2;
p a r a m e t e r T Q _ F I L E = " /h o m e/b h a s k e r/T E S T/ a d d . t q " ;
參數值也可以在編譯時被改變。改變參數值可以使用參數定義語句或通過在模塊初始化語句中定義參數值
歡迎關注FPGA設計論壇,實時獲取更多FPGA相關資訊