本文首發於微信公眾號「花螞蟻」,想要學習FPGA及Verilog的同學可以關注一下。

變數即在程序運行過程中其值可以改變的量,在Verilog HDL中變數的數據類型有很多種,這裡只對常用的幾種進行介紹。

網路數據類型表示結構實體(例如門)之間的物理連接。網路類型的變數不能儲存值,而且它必需受到驅動器(例如門或連續賦值語句,assign)的驅動。

如果沒有驅動器連接到網路類型的變數上,則該變數就是高阻

的,即其值為z常用的網路數據類型包括wire型和tri型。這兩種變數都是用於連接器件單元,它們具有相同的語法格式和功能。

之所以提供這兩種名字來表達相同的概念是為了與模型中所使用的變數的實際情況相一致。wire型變數通常是用來表示單個門驅動或連續賦值語句驅動的網路型數據,tri型變數則用來表示多驅動器驅動的網路型數據。

如果wire型或tri型變數沒有定義邏輯強度(logic strength),在多驅動源的情況下,邏輯值會發生衝突從而產生不確定值。下表為wire型和tri型變數的真值表。

一. wire型

wire型數據常用來表示用於以assign關鍵字指定的組合邏輯信號。Verilog程序模塊中輸入輸出信號類型預設時自動定義為wire型。wire型信號可以用作任何方程式的輸入,也可以用作「assign」語句或實例元件的輸出。

wire型信號的格式同reg型信號的很類似。其格式如下:

wire [n-1:0] 數據名1,數據名2,…數據名i; //共有i條匯流排,每條匯流排內有n條線路

wire [n:1] 數據名1,數據名2,…數據名i;

wire是wire型數據的確認符,[n-1:0]和[n:1]代表該數據的位寬,即該數據有幾位。最後跟著的是數據的名字。如果一次定義多個數據,數據名之間用逗號隔開。聲明語句的最後要用分號表示語句結束。看下面的幾個例子。

wire a; //定義了一個一位的wire型數據
wire [7:0] b; //定義了一個八位的wire型數據
wire [4:1] c, d; //定義了二個四位的wire型數據

二. reg型

寄存器是數據儲存單元的抽象。寄存器數據類型的關鍵字是reg。通過賦值語句可以改變寄存器儲存的值,其作用與改變觸發器儲存的值相當。

Verilog HDL語言提供了功能強大的結構語句使設計者能有效地控制是否執行這些賦值語句。這些控制結構用來描述硬體觸發條件,例如時鐘的上升沿和多路器的選通信號。reg類型數據的預設初始值為不定值,x。

reg型數據常用來表示用於「always」模塊內的指定信號,常代表觸發器。通常,在設計中要由「always」塊通過使用行為描述語句來表達邏輯關係。在「always」塊內被賦值的每一個信號都必須定義成reg型。

reg型數據的格式如下:

reg [n-1:0] 數據名1,數據名2, 數據名i;

reg [n:1] 數據名1,數據名2, 數據名i;

reg是reg型數據的確認標識符,[n-1:0]和[n:1]代表該數據的位寬,即該數據有幾位(bit)。最後跟著的是數據的名字。如果一次定義多個數據,數據名之間用逗號隔開。聲明語句的最後要用分號表示語句結束。看下面的幾個例子:

reg rega; //定義了一個一位的名為rega的reg型數據
reg [3:0] regb; //定義了一個四位的名為regb的reg型數據
reg [4:1] regc, regd; //定義了兩個四位的名為regc和regd的reg型數據

對於reg型數據,其賦值語句的作用就象改變一組觸發器的存儲單元的值

在Verilog中有許多構造(construct)用來控制何時或是否執行這些賦值語句。這些控制構造可用來描述硬體觸發器的各種具體情況,如觸發條件用時鐘的上升沿等,或用來描述具體判斷邏輯的細節,如各種多路選擇器。

reg型數據的預設初始值是不定值x。reg型數據可以賦正值,也可以賦負值。但當一個reg型數據是一個表達式中的操作數時,它的值被當作是無符號值,即正值。例如:當一個四位的寄存器用作表達式中的操作數時,如果開始寄存器被賦以值-1,則在表達式中進行運算時,其值被認為是+15。

注意:

reg型只表示被定義的信號將用在「always」塊內,理解這一點很重要。並不是說reg型信號一定是寄存器或觸發器的輸出。雖然reg型信號常常是寄存器或觸發器的輸出,但並不一定總是這樣。

初學者往往會對wire和reg的用法混淆,下面是對wire和reg用法的總結:

wire用法總結

1.wire可以在Verilog中表示任意寬度的單線/匯流排

2.wire可以用於模塊的輸入和輸出埠以及一些其他元素並在實際模塊聲明中

3.wire不能存儲值(無狀態),並且不能在always @塊內賦值(=或<=)左側使用。

4. wire是assign語句左側唯一的合法類型

5.wire只能用於組合邏輯

reg用法總結

1. 類似於電線,但可以存儲信息(有內存,有狀態)允許連接到模塊的輸入埠,但不能連接到實例化的輸出

2. 在模塊聲明中,reg可以用作輸出,但不能用作輸入

3. 在always@(......)語句塊內,= 或者 <= 賦值語句的左邊必須是是reg變數

在initial語句塊內,= 賦值語句的左邊必須是是reg變數

4. Reg不能用於assign賦值語句的左側

5. 當與@(posedge clock)塊一起使用時,reg可用於創建寄存器

6. reg可用於組合邏輯和時序邏輯

構建一個模塊module時

input必須是wire

output可以是wire也可以是reg

inout必須是wire

例化模塊時

外部連接input埠的可以是wire也可以是reg

外部連接output埠的必須是wire

外部連接inout埠的必須是wire

三. memory型

Verilog HDL通過對reg型變數建立數組來對存儲器建模,可以描述RAM型存儲器,ROM存儲器和reg文件。數組中的每一個單元通過一個數組索引進行定址。在Verilog語言中沒有多維數組存在。 memory型數據是通過擴展reg型數據的地址範圍來生成的。其格式如下:

reg [n-1:0] 存儲器名[m-1:0]

在這裡,reg[n-1:0]定義了存儲器中每一個存儲單元的大小,即該存儲單元是一個n位的寄存器。存儲器名後的[m-1:0]或[m:1]則定義了該存儲器中有多少個這樣的寄存器。最後用分號結束定義語句。下面舉例說明:

reg [7:0] mema[255:0];

這個例子定義了一個名為mema的存儲器,該存儲器有256個8位的存儲器。該存儲器的地址範圍是0到255。注意:對存儲器進行地址索引的表達式必須是常數表達式。

另外,在同一個數據類型聲明語句里,可以同時定義存儲器型數據和reg型數據。見下例:

parameter wordsize=16, //定義二個參數。
memsize=256;
reg [wordsize-1:0] mem[memsize-1:0],writereg, readreg;

儘管memory型數據和reg型數據的定義格式很相似,但要注意其不同之處。如一個由n個1位寄存器構成的存儲器組是不同於一個n位的寄存器的。見下例:

reg [n-1:0] rega; //一個n位的寄存器
reg mema [n-1:0]; //一個由n個1位寄存器構成的存儲器組

一個n位的寄存器可以在一條賦值語句里進行賦值,而一個完整的存儲器則不行。見下例:

rega =0; //合法賦值語句
mema =0; //非法賦值語句

如果想對memory中的存儲單元進行讀寫操作,必須指定該單元在存儲器中的地址。下面的寫法是正確的。

mema[3]=0; //給memory中的第3個存儲單元賦值為0。

進行定址的地址索引可以是表達式,這樣就可以對存儲器中的不同單元進行操作。表達式的值可以取決於電路中其它的寄存器的值。例如可以用一個加法計數器來做RAM的地址索引。

本文首發於微信公眾號「花螞蟻」,想要學習FPGA及Verilog的同學可以關注一下。


推薦閱讀:
相关文章