Verilog硬件描述語言行為建模_第1頁
Verilog硬件描述語言行為建模_第2頁
Verilog硬件描述語言行為建模_第3頁
Verilog硬件描述語言行為建模_第4頁
Verilog硬件描述語言行為建模_第5頁
已閱讀5頁,還剩65頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

西安郵電大學微電子系第四章行為建模隨著電路設計復雜度的不斷提升,我們需要從整體結構和算法層次上對硬件電路進行抽象和描述。這種描述是比數(shù)據(jù)流描述更高層級的描述,稱為行為級或算法級建模。行為級建模:4.1結構化過程語句

initial和always是verilog中用于行為級建模的兩種基本語句,其他所有的行為語句只能出現(xiàn)在這兩種過程語句中。

每個initial和always語句代表一個獨立的(并發(fā))執(zhí)行過程。每個執(zhí)行過程從仿真時間0開始,并且這兩種語句不能嵌套使用。1、initial語句//initial語句的格式如下:initialbegin語句1;語句2;......語句n;end所有在initial語句內(nèi)的語句構成了一個initial塊,initial塊從仿真0時刻開始執(zhí)行,在整個仿真過程中只執(zhí)行一次。如果模塊中包含多個initial塊,則這些initial塊各自獨立并發(fā)執(zhí)行。[例1]:initialbeginareg=0; //初始化寄存器aregmemory[index]=0;end在這個例子中用initial語句在仿真開始時對各變量進行初始化。[例2]:initialbegininputs='b000000; //初始時刻為0#10inputs='b011001; #10inputs='b011011; #10inputs='b011000; #10inputs='b001000; end[例3]:

modulestimulus;

regx,y,a,b,m;initialm=1’b0;initialbegin#5a=1’b1;

#25b=1’b0;endinitialbegin#10x=1’b0;#25y=1’b1;endendmoduleinitial塊常用于測試文件和虛擬模塊的編寫,用來產(chǎn)生仿真測試信號和設置信號記錄等仿真環(huán)境。

2、always語句:其聲明格式如下:always<時序控制><語句>always語句包括的所有行為語句構成了一個always塊。該塊從仿真0時刻開始順序執(zhí)行其中的語句。在仿真過程中不斷重復執(zhí)行的。

always語句由于其不斷重復執(zhí)行的特性,只有和一定的時序控制結合在一起才有用。如果一個always語句沒有時序控制,則這個always語句將會成為一個仿真死鎖。[例]:alwaysareg=~areg;

這個always語句將會生成一個0延遲的無限循環(huán)跳變過程,這時會發(fā)生仿真死鎖。

如果加上時序控制,則這個always語句將變?yōu)橐粭l非常有用的描述語句。見下例:

[例]:always#half_periodareg=~areg;這個例子生成了一個周期為:period(=2*half_period)的無限延續(xù)的信號波形,常用這種方法來描述時鐘信號,作為激勵信號來測試所設計的電路。

Verilog提供三種時序控制方法:基于延遲的時序控制、基于事件的時序控制和電平敏感的時序控制。[例]:reg[7:0]counter;regtick;always@(posedgeareg)begintick<=~tick;counter<=counter+1;end這個例子中,每當areg信號的上升沿出現(xiàn)時把tick信號反相,并且把counter增加1。這種時間控制是always語句最常用的。always的時序控制可以是沿觸發(fā)也可以是電平觸發(fā)的,可以單個信號也可以多個信號,中間需要用關鍵字or連接,如:

always@(posedgeclockorposedgereset)//由兩個沿觸發(fā)的always塊

begin

……endalways@(aorborc)//由多個電平觸發(fā)的always塊

begin

……end沿觸發(fā)的always塊常常描述時序邏輯,如果符合可綜合風格要求可用綜合工具自動轉換為表示時序邏輯的寄存器組和門級邏輯,而電平觸發(fā)的always塊常常用來描述組合邏輯和鎖存器,如果符合可綜合風格要求可轉換為表示組合邏輯的門級邏輯或鎖存器。一個模塊中可以有多個always塊,它們都是并行運行的。

4.2賦值語句和塊語句1、過程賦值語句:過程賦值語句可以給寄存器、整數(shù)、時間變量賦值。連續(xù)賦值語句總是處于活動狀態(tài),而過程賦值語句只有在執(zhí)行到的時候才會起作用。在VerilogHDL語言中,信號有兩種賦值方式:(1).非阻塞(Non_Blocking)賦值方式(如b<=a;)

1)它不會阻塞位于同一個順序塊中其后語句的執(zhí)行。同一順序塊中的語句并發(fā)執(zhí)行。2)

b的值并不是立刻就改變的,塊結束后才完成賦值操作。(2).阻塞(Blocking)賦值方式(如b=a;)1)順序塊中的阻塞賦值語句按順序執(zhí)行,它不會阻塞其后并行塊中語句的執(zhí)行。語句執(zhí)行完后,塊才結束。

2)b的值在賦值語句執(zhí)行完后立刻就改變。

非阻塞賦值方式和阻塞賦值方式的區(qū)別常給設計人員帶來問題。問題主要是給“always”塊內(nèi)的reg型信號的賦值方式不易把握。一般情況下,如果用一個always塊來描述時序電路,這個的“always”模塊內(nèi)的reg型信號都是采用下面的非阻塞賦值方式:b<=a;[例1]:always@(posedgeclk)beginb<=a;c<=b;end

[例1]中的"always"塊中用了非阻塞賦值方式,定義了兩個reg型信號b和c,clk信號的上升沿到來時,b就等于a,c就等于b,這里應該用到了兩個觸發(fā)器。請注意:賦值是在"always"塊結束后執(zhí)行的,c應為原來b的值。這個"always"塊實際描述的電路功能如下圖所示:

[例2]:always@(posedgeclk)beginb=a;c=b;end[例2]中的"always"塊用了阻塞賦值方式。clk信號的上升沿到來時,將發(fā)生如下的變化:b馬上取a的值,c馬上取b的值(即等于a),生成的電路圖如下所示只用了一個觸發(fā)器來寄存器a的值,又輸出給b和c。這大概不是設計者的初衷,如果采用[例1]所示的非阻塞賦值方式就可以避免這種錯誤。

DCLKQabcclk2、塊語句:

塊語句通常用來將兩條或多條語句組合在一起,使其在格式上看更象一條語句。塊語句有兩種,一種是begin_end語句,通常用來標識順序執(zhí)行的語句,用它來標識的塊稱為順序塊。一種是fork_join語句,通常用來標識并行執(zhí)行的語句,用它來標識的塊稱為并行塊。下面進行詳細的介紹。順序塊順序塊有以下特點:1)塊內(nèi)的語句是按順序執(zhí)行的,即只有上面一條語句執(zhí)行完后下面的語句才能執(zhí)行。2)每條語句的延遲時間是相對于前一條語句的仿真時間而言的。3)直到最后一條語句執(zhí)行完,程序流程控制才跳出該語句塊。順序塊的格式如下:begin語句1;語句2;......語句n;end或begin:塊名塊內(nèi)聲明語句 語句1;語句2;......語句n;end

其中:塊名即該塊的名字,一個標識名。塊內(nèi)聲明語句可以是參數(shù)聲明語句、reg型變量聲明語句、integer型變量聲明語句、real型變量聲明語句。

下面舉例說明:[例1]:beginareg=breg;creg=areg;//creg的值為breg的值。end

從該例可以看出,第一條賦值語句先執(zhí)行,areg的值更新為breg的值,然后程序流程控制轉到第二條賦值語句,creg的值更新為areg的值。因為這兩條賦值語句之間沒有任何延遲時間,creg的值實為breg的值。當然可以在順序塊里延遲控制時間來分開兩個賦值語句的執(zhí)行時間,見[例2]:

[例2]:beginareg=breg;#10creg=areg;//在兩條賦值語句間延遲10個時間單位。end

[例3]:parameterd=50;//聲明d是一個參數(shù)reg[7:0]r;//聲明r是一個8位的寄存器變量begin//由一系列延遲產(chǎn)生的波形#dr='h35;#dr='hE2;#dr='h00;#dr='hF7;end

并行塊并行塊有以下四個特點:塊內(nèi)語句是同時執(zhí)行的,即程序流程控制一進入到該并行塊,塊內(nèi)語句則開始同時并行地執(zhí)行。塊內(nèi)每條語句的延遲時間是相對于程序流程控制進入到塊內(nèi)時的仿真時間的。延遲時間是用來給賦值語句提供執(zhí)行時序的。當按時間時序排序在最后的語句執(zhí)行完后,程序流程控制跳出該程序塊。

并行塊的格式如下:fork語句1;語句2;.......語句n;joinfork:塊名塊內(nèi)聲明語句 語句1;語句2;......語句n;join其中:

塊名即標識該塊的一個名字,相當于一個標識符。塊內(nèi)說明語句可以是參數(shù)說明語句、reg型變量聲明語句、integer型變量聲明語句、real型變量聲明語句、time型變量聲明語句、事件(event)說明語句。下面舉例說明:

[例4]:fork#50r='h35;#100r='hE2;#150r='h00;#200r='hF7;join

在這個例子中用并行塊來替代了前面例子中的順序塊來產(chǎn)生波形,用這兩種方法生成的波形是一樣的。起始時間和結束時間在并行塊和順序塊中都有一個起始時間和結束時間的概念。對于順序塊,起始時間就是第一條語句開始被執(zhí)行的時間,結束時間就是最后一條語句執(zhí)行完的時間。而對于并行塊來說,起始時間對于塊內(nèi)所有的語句是相同的,即程序流程控制進入該塊的時間,其結束時間是按時間排序在最后的語句執(zhí)行完的時間。

在fork_join塊內(nèi),各條語句不必按順序給出,因此在并行塊里,各條語句在前還是在后是無關緊要的。[例5]:fork#200r='hF7;#150r='h00;#100r='hE2;#50r='h35;join

在這個例子中,各條語句并不是按被執(zhí)行的先后順序給出的,但同樣可以生成前面例子中的波形。

4.3條件語句1.if_else語句if語句是用來判定所給定的條件是否滿足,根據(jù)判定的結果(真或假)決定執(zhí)行給出的兩種操作之一。VerilogHDL語言提供了三種形式的if語句。(1).if(表達式)語句例如:if(a>b)out1<=int1;

(2).if(表達式)語句1else 語句2例如: if(a>b)out1<=int1;elseout1<=int2;(3).if(表達式1)語句1;elseif(表達式2)語句2;elseif(表達式3)語句3;........elseif(表達式m)語句m;else語句n;

例如:if(a>b)out1<=int1;elseif(a==b)out1<=int2;elseout1<=int3;五點說明:(1).

三種形式的if語句中在if后面都有“表達式”,一般為邏輯表達式或關系表達式。系統(tǒng)對表達式的值進行判斷,若為0,x,z,按“假”處理,若為1,按“真”處理,執(zhí)行指定的語句。

(2).第二、第三種形式的if語句中,在每個else前面有一分號,整個語句結束處有一分號。例如:

這是由于分號是VerilogHDL語句中不可缺少的部分,這個分號是if語句中的內(nèi)嵌套語句所要求的。如果無此分號,則出現(xiàn)語法錯誤。但應注意,不要誤認為上面是兩個語句(if語句和else語句)。它們都屬于同一個if語句。else子句不能作為語句單獨使用,它必須是if語句的一部分,與if配對使用。(3).在if和else后面可以包含一個內(nèi)嵌的操作語句,也可以有多個操作語句,此時用begin和end這兩個關鍵詞將幾個語句包含起來成為一個復合塊語句。如:if(a>b)beginout1<=int1;out2<=int2;endelsebeginout1<=int2;out2<=int1;end注意在end后不需要再加分號。因為begin_end內(nèi)是一個完整的復合語句,不需再附加分號。(4).允許一定形式的表達式簡寫方式。如下面的例子:if(expression)等同if(expression==1)if(!expression)

等同if(expression!=1)(5).if語句的嵌套在if語句中又包含一個或多個if語句稱為if語句的嵌套。一般形式如下:if(expression1)if(expression2)語句1 (內(nèi)嵌if)else語句2elseif(expression3)語句3 (內(nèi)嵌if)else語句4應當注意if與else的配對關系,else總是與它上面的最近的if配對。如果if與else的數(shù)目不一樣,為了確保實現(xiàn)程序設計者的企圖和增強程序可讀性,可以用begin_end塊語句來確定配對關系。

例如:if( )begin if( )語句1 (內(nèi)嵌if)endelse語句2這時begin_end塊語句限定了內(nèi)嵌if語句的范圍,因此else與第一個if配對。if(index>0)for(scani=0;scani<index;scani=scani+1)if(memory[scani]>0)beginmemory[scani]=0;endelse /*WRONG*/$display("error-indexiszero");盡管程序設計者把else寫在與第一個if(外層if)同一列上,希望與第一個if對應,但實際上else是與第二個if對應,因為它們相距最近。正確的寫法應當是這樣的:if(index>0)beginfor(scani=0;scani<index;scani=scani+1)if(memory[scani]>0)beginmemory[scani]=0;endend

else/*WRONG*/ $display("error-indexiszero");2.case語句

case語句是一種多分支選擇語句,if語句只有兩個分支可供選擇,Verilog語言提供的case語句直接處理多分支選擇。case語句通常用于微處理器的指令譯碼,它的一般形式如下:case(表達式) <case分支項> endcasecasez(表達式) <case分支項> endcasecasex(表達式) <case分支項> endcasecase分支項的一般格式如下:分支表達式: 語句缺省項(default項): 語句reg[15:0]rega;reg[9:0]result;case(rega)16'd0:result=10'b0111111111;16'd1:result=10'b1011111111;16'd2:result=10'b1101111111;16'd3:result=10'b1110111111;16'd4:result=10'b1111011111;16'd5:result=10'b1111101111;16'd6:result=10'b1111110111;16'd7:result=10'b1111111011;16'd8:result=10'b1111111101;16'd9:result=10'b1111111110;default:result='bx;endcase

每一個case分項的分支表達式的值必須互不相同,否則就會出現(xiàn)矛盾現(xiàn)象(對表達式的同一個值,有多種執(zhí)行方案)。執(zhí)行完case分項后的語句,則跳出該case語句結構,終止case語句的執(zhí)行。在用case語句表達式進行比較的過程中,只有當信號的對應位的值能明確進行比較時,比較才能成功。因此要注意詳細說明case分項的分支表達式的值。case語句的所有表達式的值的位寬必須相等,只有這樣控制表達式和分支表達式才能進行對應位的比較。一個經(jīng)常犯的錯誤是用'bx,'bz來替代n'bx,n'bz,這樣寫是不對的,因為信號x,z的缺省寬度是機器的字節(jié)寬度,通常是32位(此處n是case控制表達式的位寬)。

case語句與if_else_if語句的區(qū)別主要有兩點:與case語句中的控制表達式和多分支表達式這種比較結構相比,if_else_if結構中的條件表達式更為直觀一些。對于那些分支表達式中存在不定值x和高阻值z位時,case語句提供了處理這種情況的手段。下面的兩個例子介紹了處理x,z值位的case語句。[例1]:case(select[1:2])2'b00:result=0;2'b01:result=flaga;2'b0x,2'b0z:result=flaga?'bx:0;2'b10:result=flagb;2'bx0,2'bz0:result=flagb?'bx:0;default:result='bx;endcase[例2]:case(sig)1'bz:$display("signalisfloating");1'bx:$display("signalisunknown");default:$display("signalis%b",sig);endcaseVerilogHDL針對電路的特性提供了case語句的其它兩種形式用來處理case語句比較過程中的不必考慮的情況(don‘tcarecondition)。其中casez語句用來處理不考慮高阻值z的比較過程,casex語句則將高阻值z和不定值都視為不必關心的情況。所謂不必關心的情況,即在表達式進行比較時,不將條件表達式或分支表達式中的該位的狀態(tài)考慮在內(nèi)。這樣在case語句表達式進行比較時,就可以靈活地設置以對信號的某些位進行比較。

[例3]:reg[7:0]ir;casez(ir)8'b1???????:instruction1(ir);8'b01??????:instruction2(ir);8'b00010???:instruction3(ir);8'b000001??:instruction4(ir);endcase[例4]:reg[7:0]r,mask;mask=8'bx0x0x0x0;casex(r^mask)8'b001100xx:stat1;8'b1100xx00:stat2;8'b00xx0011:stat3;8'bxx001100:stat4;endcase3.由于使用條件語句不當在設計中生成了原本沒想到有的鎖存器VerilogHDL設計中容易犯的一個通病是由于不正確使用語言,生成了并不想要的鎖存器。下面我們給出了一個在“always"塊中不正確使用if語句,造成這種錯誤的例子。

檢查一下左邊的"always"塊,if語句保證了只有當al=1時,q才取d的值。這段程序沒有寫出al=0時的結果,那么當al=0時會怎么樣呢?在"always"塊內(nèi),如果在給定的條件下變量沒有賦值,這個變量將保持原值,也就是說會生成一個鎖存器!如果設計人員希望當al=0時q的值為0,else項就必不可少了,請注意看右邊的"always"塊,整個Verilog程序模塊綜合出來后,"always"塊對應的部分不會生成鎖存器。

VerilogHDL程序另一種偶然生成鎖存器是在使用case語句時缺少default項的情況下發(fā)生的。

case語句的功能是:在某個信號(本例中的sel)取不同的值時,給另一個信號(本例中的q)賦不同的值。注意看下圖左邊的例子,如果sel=0,q取a值,而sel=11,q取b的值。這個例子中不清楚的是:如果sel取00和11以外的值時q將被賦予什么值?在下面左邊的這個例子中,程序是用VerilogHDL寫的,即默認為q保持原值,這就會自動生成鎖存器。

右邊的例子很明確,程序中的case語句有default項,指明了如果sel不取00或11時,編譯器或仿真器應賦給q的值。程序所示情況下,q賦為0,因此不需要鎖存器。

以上就是怎樣來避免偶然生成鎖存器的錯誤。如果用到if語句,最好寫上else項。如果用case語句,最好寫上default項。遵循上面兩條原則,就可以避免發(fā)生這種錯誤,使設計者更加明確設計目標,同時也增強了Verilog程序的可讀性。4.4循環(huán)語句

在VerilogHDL中存在著四種類型的循環(huán)語句,用來控制執(zhí)行語句的執(zhí)行次數(shù)。1)

forever 連續(xù)的執(zhí)行語句。2)

repeat 連續(xù)執(zhí)行一條語句n次。3)

while 執(zhí)行一條語句直到某個條件不滿足。如果一開始條件即不滿足(為假),則語句一次也不能被執(zhí)行。4)

for通過三個步驟來決定語句的循環(huán)執(zhí)行。注意:循環(huán)語句只能在always或initial塊中使用。

1.forever語句forever語句的格式如下:forever 語句;或forever begin 多條語句end

forever循環(huán)語句不包含任何條件表達式,只執(zhí)行無限循環(huán),直到遇到系統(tǒng)任務$finish為止。常用于產(chǎn)生周期性的波形,用來作為仿真測試信號。它與always語句不同處在于不能獨立寫在程序中,而必須寫在initial塊中。

例:

regclock;

initialbeginclock=1’b0;

forever#10clock=~clock;

end2.repeat語句repeat語句的格式如下:

repeat(表達式)語句;或repeat(表達式)begin多條語句end

在repeat語句中,其表達式通常為常量表達式。

例:

integercount;

initialbegincount=0;

repeat(128)begin$display(“count=%d”,count);

count=count+1;

endend3.while語句while語句的格式如下:

while(表達式)語句或用如下格式:while(表達式)begin多條語句 end

例1:

integercount;initialbegincount=0;while(count<128)count=count+1;end例2:用while循環(huán)語句對rega這個八位二進制數(shù)中值為1的位進行計數(shù)。begin: count1sreg[7:0]tempreg;count=0;tempreg=

溫馨提示

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

評論

0/150

提交評論