Verilog語言可以有多種方式來描述硬件,同時,使用這些描述方式,又可以在多個抽象層次上設計硬件,這是Verilog語言的重要特征。
在Verilog語言中,有以下3種最基本的描述方式:
-
- 數據流描述:采用assign連續賦值語句
- 行為描述:使用always語句或initial語句塊中的過程賦值語句(推薦掌握)
- 結構化描述:實例化已有的功能模塊或原語
以一個4位全加器為例:
|
|
|
|
module Full_Add_4b_1( A, B, Cin, Sum, Cout ); input[3:0] A; input[3:0] B; input Cin; output[3:0] Sum; output Cout; assign {Cout, Sum} = A + B + Cin; endmodule |
module Full_Add_4b_2( A, B, Cin, Sum, Cout ); input[3:0] A; input[3:0] B; input Cin; output[3:0] Sum; output Cout; reg [3:0] Sum; reg Cout; always @(A or B or Cin) begin {Cout, Sum} <= A + B + Cin; end endmodule |
`include "Full_Add_4b_1.v" module Full_Add_4b_3( A, B, Cin, Sum, Cout ); input[3:0] A; input[3:0] B; input Cin; output[3:0] Sum; output Cout; //實例化全加器 Full_Add_4b_1 FA0( A, B, Cin, Sum, Cout ); endmodule |
|
||
下面逐一對這些描述方式進行介紹:
數據流描述
在數字電路中,信號經過組合邏輯時會類似於數據流動,即信號從輸入流向輸出,並不會在其中存儲。當輸入發生變化時,總會在一定時間以后體現在輸出端。同樣,我們可以模擬數字電路的這一特性,對其進行建模,這種建模方式通常被稱為數據流建模。數據流描述中最基本的語句是assign連續賦值語句。
圖中的模型可以用如下語句來描述:
asssign #1 A_xor_wire = eq0 ^ eq1;
在任意一個時刻,A_xor_wire線網的值都是由eq0和eq1決定的,也可以說是由它們驅動的。
下面對連續賦值語句的特點進行說明:
一、連續驅動
連續賦值語句是連續驅動的,也就是說只要輸入發生變化,都會導致該語句的重新計算。
二、只有線網類型的變量才能在assign語句中被賦值
由於連續賦值語句中被賦值的變量在仿真器中不會存儲其值,因此該變量是線網類型(Net)的,而不是寄存器類型的。
另外,線網類型的變量可以被多重驅動,也就是說可以在多個連續賦值語句中驅動同一個線網。
但是寄存器變量就不同了,它不能被不同的行為進程(例如always語句塊)驅動。
三、使用assign對組合邏輯建模
建議使用assign對組合邏輯建模,這是因為assign語句的連續驅動特點與組合邏輯的行為非常相似,而且在assign語句中加延時可以非常精確地模擬組合邏輯的慣性延時。
四、並行性
assign語句與行為語句塊(always和initial)、其它連續賦值語句、門級模型之間是並行的。一個連續賦值語句是一個獨立的進程,進程之間是並發的,同時也是交織的。
五、實例
這是一個半加器,使用連續賦值語句描述這個電路。
|
|
|
module Half_Add( X, Y, Sum, C_out ); //半加器 input X; input Y; output Sum; output C_out; assign Sum = X ^ Y, C_out = X & Y; endmodule |
|
|
|
|
行為描述
行為方式的建模是指采用對信號行為級的描述(不是結構級的描述)的方法來建模。在表示方面,類似數據流的建模方式,但一般是把用initial 塊語句或always 塊語句描述的歸為行為建模方式。行為建模方式通常需要借助一些行為級的運算符如加法運算符(+),減法運算符(-)等。
例: 一位全加器的行為建模
module Full_Add_1b_2( A, B, Cin, Sum, Cout );
input A;
input B;
input Cin;
output Sum;
output Cout;
reg Sum;
reg Cout;
always @(A or B or Cin)
begin {Cout, Sum} <= A + B + Cin;
end endmodule
需要先建立以下概念:
1、只有寄存器類型的信號才可以在always和initial 語句中進行賦值,類型定義通過reg語句實現。
2、always 語句是一直重復執行,由敏感表(always 語句括號內的變量)中的變量觸發。
3、always 語句從0 時刻開始。
4、在begin 和end 之間的語句是順序執行,屬於串行語句。
結構化描述
結構化描述就是說在設計中實例化已有的功能模塊,這些功能模塊包括門原語、用戶自定義原語(UDP)和其他模塊(module)。以下是結構化描述的3種實例類型:
-
- 實例化其他模塊
- 實例化門(如與門and、異或門xor等)
- 實例化UDP
結構化的描述方式反映了一個設計的層次結構。
例[1]:一位全加器
|
|
|
module Full_Add_1b_3( A, B, Cin, Sum, Cout ); input A; input B; input Cin; output Sum; output Cout; wire S1, T1, T2, T3; // -- statements -- // xor x1 (S1, A, B); xor x2 (Sum, S1, Cin); and A1 (T3, A, B ); and A2 (T2, B, Cin); and A3 (T1, A, Cin); or O1 (Cout, T1, T2, T3 ); endmodule |
|
該實例顯示了一個全加器由兩個異或門、三個與門、一個或門構成。S1、T1、T2、T3則是門與門之間的連線。代碼顯示了用純結構的建模方式,其中xor 、and、or 是Verilog HDL 內置的門器件。
以 xor x1 (S1, A, B) 該例化語句為例:
xor 表明調用一個內置的異或門,器件名稱xor ,代碼實例化名x1(類似原理圖輸入方式)。括號內的S1,A,B 表明該器件管腳的實際連接線(信號)的名稱 ,其中 A、B是輸入,S1是輸出。其他同。
例[2]:兩位全加器
兩位的全加器可通過調用兩個一位的全加器來實現。該設計的結構圖如下:
`include "Full_Add_1b_3.v" module Full_Add_2b_3( FA, FB, FCin, FSum, FCout ) ; parameter SIZE = 2; input [SIZE:1] FA; input [SIZE:1] FB; input FCin; output [SIZE:1] FSum; output FCout; wire FTemp; Full_Add_1b_3 FA1( .A (FA[1]), .B (FB[1]), .Cin (FCin) , .Sum (FSum[1]), .Cout (FTemp) ); Full_Add_1b_3 FA2( .A (FA[2]), .B (FB[2]), .Cin (FTemp) , .Sum (FSum[2]), .Cout (FCout) ); endmodule
該實例用結構化建模方式進行一個兩位的全加器的設計,頂層模塊Full_Add_2b_3 調用了兩個一位的全加器 Full_Add_1b_3。在這里,以前的設計模塊Full_Add_1b_3 對頂層而言是一個現成的器件,頂層模塊只要進行例化就可以了。
注意這里的例化中,端口映射(管腳的連線)采用名字關聯,如 .A (FA[2]) ,其中.A 表示調用器件的管腳A,括號中的信號表示接到該管腳A的電路中的具體信號。 wire 保留字表明信號FTemp 是屬線網類型。
另外,在設計中,盡量考慮參數化的問題
RTL級,register transfer level,指的是用寄存器這一級別的描述方式來描述電路的數據流方式;而Behavior級指的是僅僅描述電路的功能而可以采用任何verilog語法的描述方式。鑒於這個區別,RTL級描述的目標就是可綜合,而行為級描述的目標就是實現特定的功能而沒有可綜合的限制。
行為級是RTL的上一層,行為級是最符合人類邏輯思維方式的描述角度,一般基於算法,用C/C++來描述。從行為級到RTL級的轉換,一般都是由IC設計人員手工翻譯。
這個過程繁瑣,工作量很大,特別是隨着數字系統的復雜性提升,這樣的純手工"翻譯"過程容易出錯,且使得開發周期變長。一批高級綜合工具應運而生。如Menter Graphics的高層次綜合工具Catapult C Synthesis。能夠將數字系統的行為級描述映射為RTL設計,並滿足給定的目標限制。從層次由上到下,數字系統的設計過程為:
Idea->行為級描述->rtl描述->門級網標->物理版圖
行為級的描述更多的是采取直接賦值的形式,只能看出結果,看不出數據流的實際處理過程。其中又大量采用算術運算,延遲等一些無法綜合的語句。常常只用於驗證仿真。
RTL級的描述就會更詳細一些,並且從寄存器的角度,把數據的處理過程表達出來。可以容易地被綜合工具綜合成電路的形式。
行為級描述可是說是RTL的上層描述,比RTL更抽象。行為描述不關心電路的具體結構,只關注算法。
有行為綜合工具,可以直接將行為級的描述綜合為RTL級的,比如Behavioral Compiler。
在硬件設計中有一句著名的話:thinking of hardware。RTL在很大程度上是對流水線原理圖的描述。哪里是組合邏輯,哪里是寄存器,設計者應該了然於胸。組合邏輯到底如何實現,取決於綜合器和限制條件。
rtl級可以理解為,可以直接給綜合工具生成你要的網表的代碼,而行為級則不行。比如real可以用於行為級,而不能用於rtl級!
行為級 is for testbench for modelling.
RTL is for synthesis
語法塊如果可以被綜合到gate level,就是RTL的。否則就是behavior level的。
同樣是for語句,如果循環條件是常數,就是RTL的,如果是變量,就是behavior的。
行為級不考慮電路的實現,不考慮綜合
RTL級描述數據在寄存器層次的流動模型。
always 屬於行為級模型,是最基本的行為模型,是可以綜合的。
綜合與RTL或者行為級沒有必然聯系,雖然大多數行為模型不能綜合
從網上copy
目的區別:
行為級描述目的是加快仿真速度,做法是盡量減少一個always塊中要執行的語句數量,其結果不是為了綜合,只關注算法。有行為綜合工具,可以直接將行為級的描述綜合為RTL級的,比如Behavioral Compiler。
形式區別:
RTL級描述是為了綜合工具能夠正確的識別而編寫的代碼,verilog中有一個可綜合的子集,不同的綜合工具支持的也有所不同, RTL級的描述就會更詳細一些,並且從寄存器的角度,把數據的處理過程表達出來。可以容易地被綜合工具綜合成電路的形式。可以采用任何verilog語法 的描述方式。鑒於這個區別,RTL級描述的目標就是可綜合,
行為級的描述更多的是采取直接賦值的形式,只能看出結果,看不出數據流的實際處理過程。其中又大量采用算術運算,延遲等一些無法綜合的語句。常常只用於驗證仿真。
電路區別:
RTL級,register transfer level,指的是用寄存器這一級別的描述方式來描述電路的數據流方式;RTL在很大程度上是對流水線原理圖的描述。哪里是組合邏輯,哪里是寄存器,設計 者應該了然於胸。組合邏輯到底如何實現,取決於綜合器和限制條件。 RTL是晶體管傳輸級,描述硬件的相互聯接關系,一般都可以綜合;
而Behavior級指的是僅僅描述電路的功能而在硬件設計中有一句著名的話:thinking of hardware。簡單說,rtl就是用寄存器和組合邏輯組成,不能再用其他construct;behavior就是指定輸入和輸出之間的關系。
混亂點: 有時感覺RTL級是行為級與數據流級的混合應用。
樂點: 同樣是for語句,如果循環條件是常數,就是RTL的,如果是變量,就是behavior的。
轉:https://blog.csdn.net/a8039974/article/details/43635257
