VerilogHDL基本語法綜述_第1頁
VerilogHDL基本語法綜述_第2頁
VerilogHDL基本語法綜述_第3頁
VerilogHDL基本語法綜述_第4頁
VerilogHDL基本語法綜述_第5頁
已閱讀5頁,還剩128頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、Verilog HDL 基本語法 語匯代碼的編寫標準 常量、變量及數據類型 關鍵字和標示符 運算符 語句 綜合代碼的編寫標準 規(guī)定了文本布局、命名和注釋的約定,以提高源代碼的可讀性和可維護性。n每個Verilog HDL源文件中只準編寫一個頂層模塊,也不能把一個頂層模塊分成幾部分寫在幾個源文件中。n源文件名字應與文件內容有關,最好與頂層模塊同名!源文件名字的第一個字符必須是字母或下劃線,不能是數字或$符號!n每行只寫一個聲明語句或說明。n源代碼用層層縮進的格式來寫。語匯代碼的編寫標準2n定義變量名的大小寫應自始至終保持一致(如變量名第一個字母均大寫)。n變量名應該有意義,而且含有一定的有關信息

2、。局部變量名(如循環(huán)變量)應簡單扼要。n通過注釋對源代碼做必要的說明,尤其對接口(如模塊參數、端口、任務、函數變量)做必要的注釋很重要。語匯代碼的編寫標準3n常量盡可能多地使用參數定義和宏定義,而不要在語句中直接使用字母、數字和字符串。參數定義(用一個標識符來代表一個常量)的格式:u parameter 參數名1=表達式,參數名2=表達式,;宏定義(用一個簡單的宏名來代替一個復雜的表達式)的格式:u define 標志符(即宏名)字符串(即宏內容)語匯代碼的編寫標準4常量整型數:5表表 達達 方方 式式說說 明明 舉舉 例例+/- 完整的表達方式8b11000101或8 hc5 缺省位寬,則位

3、寬由機器系統(tǒng)決定,至少32位hc5 缺省進制為十進制,位寬默認為32位197v注:這里位寬指對應二進制數的寬度。常量n x表示不定值,z表示高阻值;n “?”是z的另一種表示符號,建議在case語句中使用?表示高阻態(tài)zn 為提高可讀性,在較長的數字之間可用下劃線_隔開!但不可以用在和之間。n 當常量未指明位寬時,默認為32位。6n 17 /位寬, 基數符號不寫會采用default值 (32bit十進制)n 8d32 /8-bit十進制值為32n 8h1A 8o37n 8b0001_1100 n 32bx / ”x”表unknownn 4b0? / ”?”表示高阻常量7常量實數n 十進制計數法,

4、科學計數法7.2 1.8e-4/1.8*10-4 9.5E6字符串與字符變量n 字符串為兩個雙引號“ ”之間的字符,不許跨行“This is a string!”; /共17個字符8常量參數(符號常量)參數(符號常量)參數是一個常量,經常用于定義時延和變量的寬度。parameter byte_size=8; /定義一個常數參數parameter, byte_msb=byte_size-1; /用數表達式賦值parameter average_delay = (r+f)/2; /用常數表達式賦值9變量變量即在程序運行過程中其值可以改變的量Verilog HDL中共有19種數據類型;其中3個最基本

5、的數據類型為:n 網絡型(nets type)n 寄存器型(register type )n 數組型(memory type)10變量線網類型:nets type表示Verilog結構化元件間的物理連線物理連線。它的值由驅動元件的值決定;如如果沒有驅動元件連接到線網,線網的缺省值為果沒有驅動元件連接到線網,線網的缺省值為z z。寄存器類型:register type表示一個抽象的數據存儲單元,它只能在只能在alwaysalways語句和語句和initialinitial語句中語句中被賦值被賦值,并且它的值從一個賦值到另一個賦值被保存下來。寄存器類型的變量具有x的缺省值。11wire型變量型變量

6、n它它是最常用的netsnets型變量型變量,常用來表示以assign語句賦值的組合邏輯信號。n模塊中的輸入/輸出信號類型缺省為wire型。n可用做任何方程式的輸入,或“assign”語句和實例元件的輸出。變量12wire 數據名1,數據名2, ,數據名n;wiren-1:0 數據名1,數據名2, ,數據名m;或 wiren:1 數據名1,數據名2, ,數據名m;每條總線位寬為n共有m條總線wire型向量(總線)變量13變量14register類型類型:在程序塊中作變量用,對信號賦值需要用該數據類型,賦值時用關鍵字賦值時用關鍵字initial或或always開始。開始。常用register變量

7、 reg:是最常見的數據類型,常代表觸發(fā)器. integer: 32位帶符號整數型變量,可以作為普通寄存器 使用,典型應用為高層次行為建模。 time類型:無符號時間變量。 real和realtime類型:實數寄存器(或實數時間寄存器)變量registerregister型變量與型變量與netsnets型變量的根本區(qū)別是:型變量的根本區(qū)別是: vregister型變量需要被明確地賦值,并且在被重新賦值前一直保持原值。vregister型變量必須通過過程賦值語句賦值!不能通過assign語句賦值!v在過程塊內被賦值的每個信號必須定義成register型!15reg型變量n 定義在過程塊中被賦值的

8、信號,往往代表觸發(fā)器,但不一定就是觸發(fā)器(也可以是組合邏輯信號)!reg 數據名1,數據名2, ,數據名n;變量16regn-1:0 數據名1,數據名2, ,數據名m;或 regn:1 數據名1,數據名2, ,數據名m;每個向量位寬為n共有m個reg型向量例 reg4:1 regc,regd; /regc,regd為4位寬的reg型向量reg型向量(總線)變量17用reg型變量生成組合邏輯舉例:module rw1( a, b, out1, out2 ) ; input a, b; output out1, out2; reg out1; wire out2; assign out2 = a

9、; always (b) out1 = b;endmoduleaout2bINVout1過程賦值語句連續(xù)賦值語句電平觸發(fā)Verilog中reg與wire的區(qū)別reg型變量既可生成觸發(fā)器,也可生成組合邏輯; wire型變量只能生成組合邏輯。變量18用reg型變量生成觸發(fā)器舉例:module rw2( clk, d, out1, out2 ); input clk, d; output out1, out2; reg out1; wire out2; assign out2 = d & out1 ; always (posedge clk) begin out1 3 = 4b0001; 4b100

10、14 = 4b0000 4b10011 = 5b10010; 4b10012 = 6b100100; 16 = 32b100000036運算符條件運算符?:EX:tri_data=en? data_out:32bz;/三態(tài)37類類 別別運運 算算 符符優(yōu)先級優(yōu)先級邏輯、位運算符! 高低算術運算符* / % 移位運算符關系運算符 =等式運算符= = ! = = !=縮減、位運算符& & | |邏輯運算符&|條件運算符?:運算符的優(yōu)先級為提高程序的可讀性,建議使用括號來控制運算的優(yōu)先級!例(ab)&(bc) (a= =b)|(x= = y) (!a)|(ab)運算符38語句39賦值語句賦值語句連續(xù)

11、賦值語句過程賦值語句塊語句塊語句begin_end語句fork_join語句條件語句條件語句if_else語句case語句循環(huán)語句循環(huán)語句forever語句while語句repeat語句for語句結構說明語句結構說明語句initial語句always語句task語句function語句編譯預處理語句編譯預處理語句define語句timescale語句include語句語句40賦值語句分為兩類:n 連續(xù)賦值語句assign語句,用于對wire型變量賦值,是描述組合邏輯最常用的方法之一 例 assign c=a&b; /a、b、c均為wire型變量n 過程賦值語句用于對reg型變量賦值,有兩種方式

12、:非阻塞(non-blocking)賦值方式: 賦值符號為=,如 b = a ; 阻塞(blocking)賦值方式: 賦值符號為=,如 b = a ; 非阻塞賦值方式 clkDFFcD QD QabDFF非阻塞賦值在塊結束時才完成賦值操作!注:c的值比b的值落后一個時鐘周期!語句41阻塞賦值方式 阻塞賦值在該語句結束時就完成賦值操作!clkDFFcD Qab注:在一個塊語句中,如果有多條阻塞賦值語句,在前面的賦值語句沒有完成之前,后面的語句就不能被執(zhí)行,就像被阻塞了一樣,因此稱為阻塞賦值方式。 這里c的值與b的值一樣 !語句42n 非阻塞(non-blocking)賦值方式 ( b= a):o

13、 b的值被賦成新值a的操作, 并不是立刻完成的,而是在塊結束時才完成;o 塊內的多條賦值語句在塊結束時同時賦值;o 硬件有對應的電路。n 阻塞(blocking)賦值方式 ( b = a):o b的值立刻被賦成新值a;o 完成該賦值語句后才能執(zhí)行下一句的操作;o 硬件沒有對應的電路,因而綜合結果未知。v建議在初學時只使用一種方式,不要混用!v建議在可綜合風格的模塊中使用非阻塞賦值!語句43塊語句用來將兩條或多條語句組合在一起,使其在格式上更像一條語句,以增加程序的可讀性。塊語句有兩種:n begin_end語句標識順序執(zhí)行的語句n fork_join語句標識并行執(zhí)行的語句語句44順序塊n 塊內

14、的語句是順序執(zhí)行的;n 每條語句的延遲時間是相對于前一條語句的仿真時間而言的;n 直到最后一條語句執(zhí)行完,程序流程控制才跳出該順序塊。語句45begin 語句1; 語句2; 語句n;endbegin:塊名 塊內聲明語句; 語句1; 語句2; 語句n;end注:塊內聲明語句可以是參數聲明、reg型變量聲明、integer型變量聲明、real型變量聲明語句?;蛘Z句46例 例 #10注:這里標識符“#”表示延遲; 在模塊調用中“#”表示參數的傳遞語句47 例用順序塊和延遲控制組合產生一個時序波形。 parameter d = 50;注:每條語句的延遲時間d是相對于前一條語句的仿真時間而言的!語句48

15、用fork_join標識的塊語句并行塊塊內的語句是同時執(zhí)行的;塊內每條語句的延遲時間是相對于程序流程控制進入到塊內時的仿真時間而言的;延遲時間用于給賦值語句提供時序;當按時間排序在最后的語句執(zhí)行完或一個disable語句執(zhí)行時,程序流程控制跳出該并行塊。49fork 語句1; 語句2; 語句n;joinfork:塊名 塊內聲明語句; 語句1; 語句2; 語句n;join或注:塊內聲明語句可以是參數聲明、reg型變量聲明、integer型變量聲明、real型變量聲明語句、 time型變量聲明語句和事件(event)說明語句。語句50 例4用并行塊和延遲控制組合產生一個時序波形。 波形同例3注:在

16、fork_join塊內,各條語句不必按順序給出!但為增加可讀性,最好按被執(zhí)行的順序書寫!語句51語句if-else 條件語句條件語句case 語句語句for循環(huán)語句循環(huán)語句52if (條件表達式條件表達式) 塊語句塊語句1else if (條件表達式條件表達式2) 塊語句塊語句2else if (條件表達式條件表達式n) 塊語句塊語句nelse 塊語句塊語句n+1case (敏感表達式敏感表達式) 值值1: 塊語句塊語句1 值值2: 塊語句塊語句2 值值n: 塊語句塊語句n default:塊語句:塊語句n+1endcasefor (表達式表達式1;表達式;表達式2;表達式;表達式3)塊語句)

17、塊語句 若if與else的數目不一樣,注意用“begin_end”語句來確定if與else的配對關系!if(表達式1) if(表達式2)語句1; else 語句2;else if(表達式3)語句3; else 語句4;if(表達式1) begin if(表達式2)語句1; endelse 語句2;當if與else的數目不一樣時,最好用“begin_end”語句將單獨的if語句括起來:if語句的嵌套:語句53語句casecase語句與語句與if-elseif-else語句區(qū)別語句區(qū)別n if-elseif-else語句語句適于對不同的條件,執(zhí)行不同的語句;對于每個判定只有兩兩個分支。n case

18、case語句語句適于對同一個控制信號取不同的值時,輸出取不同的值!它是多多分支語句。n 當控制信號只有一個時,最好采用case語句,比較簡潔!54是case語句的兩種變體語句case casez casexcase casez casex的區(qū)別的區(qū)別n 在在casecase語句中,分支表達式每一位的值都是確定的語句中,分支表達式每一位的值都是確定的(或者為(或者為0 0,或者為,或者為1 1););n 在在casezcasez語句中,若分支表達式某些位的值為高阻值語句中,若分支表達式某些位的值為高阻值z z,則不考慮對這些位的比較;,則不考慮對這些位的比較;n 在在casexcasex語句中,

19、若分支表達式某些位的值為語句中,若分支表達式某些位的值為z z或不或不定值定值x x,則不考慮對這些位的比較。,則不考慮對這些位的比較。n 在分支表達式中,可用在分支表達式中,可用“?”來標識來標識x x或或z z55module mux_z(out,a,b,c,d,select); output out; input a,b,c,d; input3:0 select; reg out; /必須聲明 always (select3:0 or a or b or c or d) begin casez (select) 4b?1: out = a; 4b?1? : out = b; 4b? 1?

20、 : out = c; 4b 1? : out = d; endcase endendmodule例 用casez描述的數據選擇器這里“?”表示高阻態(tài)語句56使用條件語句注意事項應注意列出所有條件分支,否則當條件不滿足時,編譯器會生成一個鎖存器保持原值!這一點可用于設計時序電路,如計數器:條件滿足時加1,否則保持原值不變。而在組合電路設計中,應避免生成隱含鎖存器!有效的方法是在if語句最后寫上else項;在case語句最后寫上default項。語句57如何正確使用if語句?生成了不想要的鎖存器:不會生成鎖存器:always (al or d) begin if(al) q=d; enddDFF

21、D Qalq例 設計一個數據選擇器always (al or d) begin if(al) q=d; else q=0; end0dalqmultiplexer當al為0時,q保持原值!當al為0時,q等于0!語句58always (sel1:0 or a or b) case(sel1:0) 2b00: q=a; 2b11: q=b; endcase生成了不想要的鎖存器:例 設計一個數據選擇器always (sel1:0 or a or b) case(sel1:0) 2b00: q=a; 2b11: q=b; default: q=b0; endcase不會生成鎖存器:如何正確使用cas

22、e語句?當sel為00或11以外的值時,q保持原值!v避免生成鎖存器的原則:n如果用到if語句,最好寫上else項;n如果用到case語句,最好寫上default項。語句59循環(huán)語句nfor語句通過3個步驟來決定語句的循環(huán)執(zhí)行:o(1)給控制循環(huán)次數的變量賦初值。o(2)判定循環(huán)執(zhí)行條件,若為假則跳出循環(huán);若為真,則執(zhí)行指定的語句后,轉到第(3)步。o(3)修改循環(huán)變量的值,返回第(2)步。nrepeat語句連續(xù)執(zhí)行一條語句n次nwhile語句執(zhí)行一條語句,直到循環(huán)執(zhí)行條件不滿足;若一開始條件即不滿足,則該語句一次也不能被執(zhí)行!nforever語句無限連續(xù)地執(zhí)行語句,可用disable語句中斷

23、!語句60for語句for (表達式1;表達式2;表達式3)語句for(循環(huán)變量賦初值;循環(huán)執(zhí)行條件;循環(huán)變量增值) 執(zhí)行語句8條語句 相當于采用while語句建立的循環(huán)結構:begin 循環(huán)變量賦初值; while(循環(huán)執(zhí)行條件) begin 循環(huán)變量增值; endendfor語句比while語句簡潔!語句61repeat語句連續(xù)執(zhí)行一條或多條語句n次。repeat (循環(huán)次數表達式)語句repeat (循環(huán)次數表達式) begin end執(zhí)行語句為多條語句或語句62例 兩個8位二進制數乘法注:不如采用for語句簡單!語句631.while語句有條件地執(zhí)行一條或多條語句。n 首先判斷循環(huán)執(zhí)行

24、條件表達式是否為真。若為真,則執(zhí)行后面的語句或語句塊;然后再回頭判斷循環(huán)執(zhí)行條件表達式是否為真,若為真,再執(zhí)行一次后面的語句;如此不斷,直到條件表達式不為真。while (循環(huán)執(zhí)行條件表達式)語句while (循環(huán)執(zhí)行條件表達式) begin end或語句 while64module count1s_while ( count,rega,clk ); output3:0 count; input 7:0 rega; input clk; reg3:0 count; always (posedge clk) begin:count1 reg7:0 tempreg; /用作循環(huán)執(zhí)行條件表達式 co

25、unt = 0; / count初值為0 tempreg = rega; / tempreg 初值為rega while(tempreg) / 若tempreg非0,則執(zhí)行以下語句 begin if(tempreg0) count = count+1; /只要tempreg最低位為1,則 count加1 tempreg = tempreg 1; /右移1位 end endendmodule例 對一個8位二進制數中值為1的位進行計數。改變循環(huán)執(zhí)行條件表達式的值如何用for語句改寫此程序呢?語句65無條件連續(xù)執(zhí)行forever后面的語句或語句塊。forever 語句forever begin en

26、d或v常用在測試模塊中產生周期性的波形,作為仿真激勵信號。v常用disable語句跳出循環(huán)!注:不同于always語句,不能獨立寫在程序中, 一般用在initial語句塊中!initial begin : Clocking clk = 0; #10 forever #10 clk = !clk; endinitial begin : Stimulus disable Clocking; / 停止時鐘 end 語句 forever語句66initial說明語句 只執(zhí)行一次always說明語句不斷重復執(zhí)行,直到仿真 結束task說明語句 可在程序模塊中的一處或 多處調用function說明語句可在

27、程序模塊中的一處 或多處調用語句 67always塊語句 包含一個或一個以上的聲明語句(如:過程賦值語句、任務調用、條件語句和循環(huán)語句等),在仿真運行的全過程中,在定時控制下被反復執(zhí)行。語句 在always塊中被賦值的只能是register型變量(如reg,integer,real,time)。每個always塊在仿真一開始便開始執(zhí)行,當執(zhí)行完塊中最后一個語句,繼續(xù)從always塊的開頭執(zhí)行。68always 注1:如果always塊中包含一個以上的語句,則這些語句必須放在begin_end或fork_join塊中!always (posedge clk or negedge clear) b

28、egin if(!clear) qout = 0; /異步清零 else qout = 1; end 語句6970例生成一個0延遲的無限循環(huán)跳變過程形成仿真死鎖 always areg = areg;例在測試文件中,用于生成一個無限延續(xù)的信號波形時鐘信號注2:always語句必須與一定的時序控制結合在一起才有用! 如果沒有時序控制,則易形成仿真死鎖!define half_period 50 module half_clk_top; reg reset, clk; / 輸入信號 wire clk_out; / 輸出信號 always #half_period clk = clk; endmod

29、ule語句70always () begin / 過程賦值語句 / if語句 / case語句 / while,repeat,for循環(huán) / task,function調用 end一般為輸入敏感信號表達式又稱事件表達式或敏感表,當其值改變時,則執(zhí)行一遍塊內語句;在敏感信號表達式中應列出影響塊內取值的所有信號! 敏感信號可以為單個信號,也可為多個信號,中間需用關鍵字or連接!敏感信號不要為x或z,否則會阻擋進程!always塊語句一個變量不能在多個always塊中被賦值!語句71always的時間控制可以為沿觸發(fā),也可為電平觸發(fā)。關鍵字posedge表示上升沿;negedge表示下降沿。alwa

30、ys (posedge clock or posedge reset) begin endalways (a or b or c) begin end由兩個沿觸發(fā)的always 塊由多個電平觸發(fā)的always 塊語句7273always塊語句是用于綜合過程的最有用的語句之一,但又常常是不可綜合的。為得到最好的綜合結果, always塊程序應嚴格按以下模板來編寫:always (Inputs) /所有輸入信號必須列出,用or隔開 begin /組合邏輯關系 end always (Inputs) /所有輸入信號必須列出,用or隔開 if (Enable) begin /鎖存動作 end 語句73

31、always (posedge Clock) / Clock only begin / 同步動作 end always (posedge Clock or negedge Reset)/ Clock and Reset only begin if (! Reset) / 測試異步復位電平是否有效 / 異步動作 else / 同步動作 end / 可產生觸發(fā)器和組合邏輯語句74當always塊有多個敏感信號時,一定要采用if - else if語句,而不能采用并列的if語句!否則易造成一個寄存器有多個時鐘驅動,將出現編譯錯誤。always posedge min_clk or negedge r

32、eset) begin if (reset) min=0; else if (min=8h59) /當reset無效且min=8h59時 begin min=0;h_clk=1; end end 通常采用異步清零!只有在時鐘周期很小或清零信號為電平信號時采用同步清零。千萬別寫成if哦!語句75initial begin 語句1; 語句2; 語句n; end 例 利用initial語句生成激勵波形。 initial begin inputs = b000000; #10 inputs = b011001; #10 inputs = b011011; #10 inputs = b011000; #

33、10 inputs = b001000; end在仿真的初始狀態(tài)對各變量進行初始化;在測試文件中生成激勵波形作為電路的仿真信號。語句 initial語句76parameter size=16;reg3:0 addr;reg reg1;reg7:0 memory0:15;initial begin reg1 = 0; for(addr=0;addrsize;addr=addr+1); memoryaddr=0; end例 對各變量進行初始化。語句77除module以外,Verilog還提供了任務(task)和函數(function)n 可重復調用n 定義和調用都包含在module內部語句78ta

34、sk和function語句分別用來由用戶定義任務和函數。任務和函數往往是大的程序模塊中在不同地點多次用到的相同的程序段。利用任務和函數可將一個很大的程序模塊分解為許多較小的任務和函數,便于理解和調試。輸入、輸出和總線信號的值可以傳入、傳出任務和函數。語句 task和function語句79task 任務名;/無需定義端口名列表端口與類型說明;/調用時按順序和類型列出局部變量說明;塊語句endtaskn 當希望能夠對一些信號進行一些運算并輸出多個結果(即有多個輸出變量)時,宜采用任務結構。n 常常利用任務來幫助實現結構化的模塊設計,將批量的操作以任務的形式獨立出來,使設計簡單明了。語句(端口1,

35、端口2,); 80.always (posedge sys_clk) begin if(read_request = 1) begin read_mem(IR,PC); /Event and function calls end endtask read_mem; output 15:0 data_in; input 15:0 addr; always (posedge read_grant) beginADDRESS = addr;#15 data_in = data; endendtask.語句注1:任務的定義與調用必須在一個module模塊內!注2:任務被調用時,需列出端口名列表,且必須

36、與任務定義中的I/O變量一一對應!注3:一個任務可以調用其他任務和函數。81例 通過任務調用完成4個4位二進制輸入數據的冒泡排序。 任務的定義任務的調用82functionn 函數的目的是通過返回一個用于某表達式的值,來響應輸入信號。適于對不同變量采取同一運算的操作。n 函數在模塊內部定義,通常在本模塊中調用,也能根據按模塊層次分級命名的函數名從其他模塊調用。而任務只能在同一模塊內定義與調用! 語句83語句Functionfunction 函數名;輸入端口與類型說明;局部變量說明;塊語句endfiction注意:1.函數不能調用任務,任務可調用任何其他函數和任務 2.函數只有輸入變量且至少一個

37、 3.函數定義的塊語句不許出現定時控制 4.函數通過函數名返回一個值缺省則返回1位reg型數據( )與函數定義中的輸入變量對應!84always (posedge sys_clk) begin . IR = swap_bits(IR); . endfunction 15:0 swap_bits; input 15:0 in_vec; reg 15:0 temp_reg; integer i; begin for (I = 15; I = 0; I = I-1) temp_reg15-i = in_veci; swap_bits = temp_reg; endendfunctioin語句85語句

38、注1:函數的調用是通過將函數作為調用函數的表達式中的操作數來實現的!注2:函數在綜合時被理解成具有獨立運算功能的電路,每調用一次函數,相當于改變此電路的輸入,以得到相應的計算結果。86函數的使用規(guī)則函數的定義不能包含任何時間控制語句用延遲#、事件控制或等待wait標識的語句。函數不能啟動(即調用)任務!定義函數時至少要有一個輸入參量!且不能有任何輸出或輸入/輸出雙向變量。在函數的定義中必須有一條賦值語句,給函數中的一個內部寄存器賦以函數的結果值,該內部寄存器與函數同名。語句87例 利用函數對一個8位二進制數中為0的位進行計數。只有輸入變量內部寄存器對應函數的輸入變量語句88任務(任務(task

39、 )函數(函數(function)目的或用途目的或用途可計算多個多個結果值通過返回一個一個值,來響應輸入信號輸入與輸出輸入與輸出可為各種類型(包括inout型)至少有一個輸入變量,但不能有任何output或inout型變量被調用被調用只可在過程過程賦值語句中調用,不能在連續(xù)賦值語句中調用可作為表達式中的一個操作數來調用,在過程過程賦值和連續(xù)連續(xù)賦值語句中均可調用調用其他任務調用其他任務和函數和函數任務可調用其他任務任務和函數函數函數可調用其他函數,但不可調用其他任務返回值返回值不向表達式返回值向調用它的表達式返回一個值任務與函數的區(qū)別語句89語句“編譯預處理”是Verilog HDL編譯系統(tǒng)的

40、一個組成部分。編譯預處理語句以西文符號“ ”開頭注意,不是單引號“”!在編譯時,編譯系統(tǒng)先對編譯預處理語句進行預處理,然后將處理結果和源程序一起進行編譯。90 define語句宏定義語句用一個指定的標志符(即宏名)來代表一個字符串(即宏內容)。宏定義的作用:以一個簡單的名字代替一個長的字符串或復雜表達式;以一個有含義的名字代替沒有含義的數字和符號。define 標志符(即宏名)字符串(即宏內容) 例 define IN ina+inb+inc+ind 宏展開在編譯預處理時將宏名替換為字符串的過程。語句91宏名可以用大寫字母,也可用小寫字母表示;但建議用大寫字母,以與變量名相區(qū)別。 define

41、語句可以寫在模塊定義的外面或里面。宏名的有效范圍為定義命令之后到源文件結束。在引用已定義的宏名時,必須在其前面加上符號“ ” !使用宏名代替一個字符串,可簡化書寫,便于記憶,易于修改。語句92預處理時只是將程序中的宏名替換為字符串,不管含義是否正確。只有在編譯宏展開后的源程序時才報錯。宏名和宏內容必須在同一行中進行聲明!宏定義不是Verilog HDL語句,不必在行末加分號!如果加了分號,會連分號一起置換!語句93例 module test; reg a,b,c,d,e,out; define expression a + b + c + d; assign out = expression

42、+ e; 經過宏展開后,assign語句為: assign out = a + b + c + d; + e; /出現語法錯誤!錯誤!語句94例 module test; reg a,b,c; wire out; define aa a + b define cc c + aa /引用已定義的宏名 aa 來定義宏cc assign out = cc; 經過宏展開后, assign語句為: assign out = c + a + b;語句在進行宏定義時,可引用已定義的宏名,實現層層置換。95文件包含語句一個源文件可將另一個源文件的全部內容包含進來。include “文件名”預處理后includ

43、e “file2.v”Afile1.vBfile2.vABfile1.v將file2.v中全部內容復制插入到include “file2.v”命令出現的地方語句 include語句96避免程序設計人員的重復勞動!不必將源代碼復制到自己的另一源文件中,使源文件顯得簡潔。(1)可以將一些常用的宏定義命令或任務(task)組成一個文件,然后用include語句將該文件包含到自己的另一源文件中,相當于將工業(yè)上的標準元件拿來使用。(2)當某幾個源文件經常需要被其他源文件調用時,則在其他源文件中用include語句將所需源文件包含進來。語句97例 用include語句設計16位加法器adder模塊位拼接改

44、變被引用模塊adder中的參數size為my_size98一個 include語句只能指定一個被包含的文件;若要包含n個文件,需用n個 include語句。include語句可出現在源程序的任何地方。被包含的文件若與包含文件不在同一子目錄下,必須指明其路徑!include “aaa.v” “bbb.v” /非法!include “parts/count.v” /合法!include “aaa.v” include “bbb.v” /合法!語句99可將多個include語句寫在一行;在該行中,只可出現空格和注釋行。文件包含允許嵌套。include “aaa.v” include “bbb.v”

45、/合法!include “file2.v”file1.vinclude “file3.v”file2.v(不包含include 命令)file3.v語句100時間尺度語句用于定義跟在該命令后模塊的時間單位和時間精度。timescale / 時間單位用于定義模塊中仿真時間和延遲時間的基準單位;時間精度用來聲明該模塊的仿真時間和延遲時間的精確程度。在同一程序設計里,可以包含采用不同時間單位的模塊。此時用最小的時間精度值決定仿真的時間單位。語句 timescale語句101 timescale 1ps / 1ns / 非法! timescale 1ns / 1ps / 合法!時間精度至少要和時間單位

46、一樣精確,時間精度值不能大于時間單位值!在 timescale語句中,用來說明時間單位和時間精度參量值的數字必須是整數。其有效數字為1、10、100;單位為秒(s)、毫秒(ms)、微秒(us)、納秒(ns)、皮秒(ps)、毫皮秒(fs)。語句102例 timescale語句應用舉例。 timescale 10ns / 1ns /時間單位為10ns,時間精度為1nsreg sel; initial begin #10 sel = 0; / 在10ns10時刻,sel變量被賦值為0 #10 sel = 1; / 在10ns20時刻,sel變量被賦值為1 end 語句103語句的順序執(zhí)行:(1)在

47、“always”模塊內,邏輯按書寫的順序執(zhí)行。(2)順序語句“always”模塊內的語句。(3)在“always”模塊內,若隨意顛倒賦值語句的書寫順序,可能導致不同的結果!(見 例3.11.1、 例3.11.2) 。(4)注意阻塞賦值語句當本語句結束時即完成賦值操作!語句104105例順序執(zhí)行模塊1。module serial1(q,a,clk); output q,a; input clk; reg q,a; always (posedge clk) begin q=q; /阻塞賦值語句 a=q; endendmodule例順序執(zhí)行模塊2。module serial2(q,a,clk); o

48、utput q,a; input clk; reg q,a; always (posedge clk) begin a=q; q=q; endendmodule對前一時刻的q值取反對當前時刻的q值取反對前一時刻的q值取反對前一時刻的q值取反a和q的波形反相!a和q的波形完全相同!語句105語句的并行執(zhí)行:(1)“always”模塊、“assign”語句、實例元件都是同時(即并行)執(zhí)行的?。?)它們在程序中的先后順序對結果并沒有影響。(3)將兩條賦值語句分別放在兩個“always”模塊中,盡管兩個“always”模塊順序相反,但仿真波形完全相同。語句106例并行執(zhí)行模塊1。module para

49、ll1(q,a,clk); output q,a; input clk; reg q,a; always (posedge clk) begin q=q; end always (posedge clk) begin a=q; endendmodule例并行執(zhí)行模塊2。module parall2(q,a,clk); output q,a; input clk; reg q,a; always (posedge clk) begin a=q; end always (posedge clk) begin q=q; endendmodule語句107(1)把設計分割成較小的功能塊,每塊用行為風格

50、設計。除設計中對速度響應要求比較臨界的部分外,都應避免門級描述。(2)建立一個好的時鐘策略(如單時鐘、多相位時鐘,經過門產生的時鐘、多時鐘域等)。保證源代碼中時鐘和復位信號是干凈的(即不是由組合邏輯或沒有考慮到的門產生的)。綜合代碼的編寫標準v綜合:將用HDL語言或圖形方式描述的電路設計轉換為實際門級電路(如觸發(fā)器、邏輯門等),得到一個網表文件,用于進行適配(在實際器件中進行布局和布線)。108(3)建立一個好的測試策略,使所有觸發(fā)器都是可復位的,使測試能通過外部管腳進行,又沒有冗余的功能。(4)所有源代碼都必須遵守并符合在always塊語句的4種可綜合標準模板之一。(5)描述組合和鎖存邏輯的

51、always塊,必須在always塊開頭的控制事件列表中列出所有的輸入信號。綜合代碼的編寫標準109(6)描述組合邏輯的always塊,一定不能有不完全賦值,即所有輸出變量必須被各輸入值的組合值賦值,不能有例外。(7)描述組合和鎖存邏輯的always塊一定不能包含反饋,即在always塊中已被定義為輸出的寄存器變量絕對不能再在該always塊中讀進來作為輸入信號。綜合代碼的編寫標準110(8)時鐘沿觸發(fā)的always塊必須是單時鐘的,且任何異步控制輸入(通常是復位或置位信號)必須在控制事件列表中列出。 例:always (posedge clk or negedge set or negedg

52、e reset)(9)避免生成不想要的鎖存器。在無時鐘的always塊中,若有的輸出變量被賦了某個信號變量值,而該信號變量并未在該always塊的電平敏感控制事件中列出,則會在綜合中生成不想要的鎖存器。綜合代碼的編寫標準111(10)避免生成不想要的觸發(fā)器。n 在時鐘沿觸發(fā)的always塊中,如果用非阻塞賦值語句對reg型變量賦值;或者當reg型變量經過多次循環(huán)其值仍保持不變,則會在綜合中生成觸發(fā)器。n用reg型變量生成觸發(fā)器舉例: module rw2( clk, d, out1); input clk, d; output out1; reg out1; always (posedge c

53、lk) /沿觸發(fā) out1 = d ; endmodule非阻塞賦值語句dclkout1D QDFF綜合代碼的編寫標準112若不想生成觸發(fā)器,而是希望用reg型變量生成組合邏輯,則應使用電平觸發(fā): module rw2( clk, d, out1); input clk, d; output out1; reg out1; always (d) /電平觸發(fā) out1 = d ; endmoduledout1BUFF綜合代碼的編寫標準113(11)所有內部狀態(tài)寄存器必須是可復位的,這是為了使RTL級和門級描述能夠被復位成同一個已知的狀態(tài),以便進行門級邏輯驗證。(12)對存在無效狀態(tài)的有限狀態(tài)機和

54、其他時序電路(如4位十進制計數器有6個無效狀態(tài)),必須明確描述所有的2的N次冪種狀態(tài)下的行為(包括無效狀態(tài)),才能綜合出安全可靠的狀態(tài)機。綜合代碼的編寫標準114(13)一般地,在賦值語句中不能使用延遲,否則是不可綜合的。(14)不要使用integer型和time型寄存器,否則將分別綜合成32位和64位的總線。(15)仔細檢查代碼中使用動態(tài)指針(如用指針或地址變量檢索的位選擇或存儲單元)、循環(huán)聲明或算術運算部分,因為這類代碼在綜合后會生成大量的門,且難以優(yōu)化。綜合代碼的編寫標準115Verilog不同抽象級別一個復雜電路的完整Verilog HDL模型由若干個Verilog HDL模塊構成,每

55、個模塊由若干的子模塊構成可分別用不同抽象級別的Verilog HDL描述。116Verilog不同抽象級別在同一個Verilog HDL模塊中可有多種級別的描述。n 系統(tǒng)級(system level): 用高級語言結構(如case語句)實現的設計模塊外部性能的模型;n 算法級(algorithmic level): 用高級語言結構實現的設計算法模型(寫出邏輯表達式);n RTL級(register transfer level): 描述數據在寄存器之間流動和如何處理這些數據的模型;n 門級(gate level): 描述邏輯門(如與門、非門、或門、與非門、三態(tài)門等)以及邏輯門之間連接的模型;n

56、 開關級(switch level): 描述器件中三極管和儲存節(jié)點及其之間連接的模型。117Verilog不同抽象級別電路描述n 行為級描述:側重對模塊行為功能的抽象描述n 結構級描述:側重對模塊內部結構實現的具體描述行為級模塊描述n 由多個并行運行的過程塊組成n 過程塊由過程語句(initial與always)和塊語句(串行塊begin-end與并行塊fork-join)組成n 塊語句由過程賦值語句和高級程序語句構成o 過程賦值語句:阻塞與非阻塞式賦值o 高級程序語句:if-else、case、while、wait包括系統(tǒng)級,算法級,RTL級1181. 邏輯功能描述算法級注:首先必須根據邏輯

57、功能寫出邏輯表達式!例 用邏輯表達式實現4選1數據選擇器module mux4_1(out,in1,in2,in3,in4,cntrl1,cntrl2); output out; input in1,in2,in3,in4,cntrl1,cntrl2; assign out=(in1 & cntrl1 & cntrl2) | (in2 & cntrl1 & cntrl2) | (in3 & cntrl1 & cntrl2) | (in4 & cntrl1 & cntrl2) ;endmoduleVerilog不同抽象級別1192. case語句描述系統(tǒng)級 只需知道輸入與輸出間的真值表!比調用門

58、原語和采用邏輯功能描述都簡潔!例 用case語句描述4選1數據選擇器module mux4_1(out,in1,in2,in3,in4,cntrl1,cntrl2); output out; input in1,in2,in3,in4,cntrl1,cntrl2; reg out; always (in1 or in2 or in3 or in4 or cntrl1 or cntrl2) case (cntrl1,cntrl2) 2b00:out=in1; 2b01:out=in2; 2b10:out=in3; 2b11:out=in4; default :out=1bx; endcaseen

59、dmodulecase語句應放在always塊內!Verilog不同抽象級別1203.條件運算符描述算法級 只需知道輸入與輸出間的真值表!注:比調用門原語,采用邏輯表達式或 case語句描述代碼更簡單!但也更抽象!且耗用器件資源更多!例 用條件運算符描述4選1數據選擇器module mux4_1(out,in1,in2,in3,in4,cntrl1,cntrl2); output out; input in1,in2,in3,in4,cntrl1,cntrl2; assign out= cntrl1? (cntrl2? in4 :in3) : (cntrl2? in2 :in1) ;endmodule當cntrl1=1時執(zhí)行當cntrl1=0時執(zhí)行Verilog不同抽象級別121Verilog結構級描述門級描述:對由基本邏輯門(and、or)互連而成的具有一定功能的電路模塊的描述結構級描述:將上述邏輯門用一個個功能模塊替換,就拓展到一般意義的結構級描述結構級描述側重對模塊內部結構實現的具體描述122Verilog HDL的門級描述門級描述即直接調用門原語進行邏輯的結構描述。 以門級為基礎的結構描述

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論