Verilog HDL數(shù)字系統(tǒng)設(shè)計及其應用-05行為描述(一):模塊基本結(jié)構(gòu)_第1頁
Verilog HDL數(shù)字系統(tǒng)設(shè)計及其應用-05行為描述(一):模塊基本結(jié)構(gòu)_第2頁
Verilog HDL數(shù)字系統(tǒng)設(shè)計及其應用-05行為描述(一):模塊基本結(jié)構(gòu)_第3頁
Verilog HDL數(shù)字系統(tǒng)設(shè)計及其應用-05行為描述(一):模塊基本結(jié)構(gòu)_第4頁
Verilog HDL數(shù)字系統(tǒng)設(shè)計及其應用-05行為描述(一):模塊基本結(jié)構(gòu)_第5頁
已閱讀5頁,還剩55頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第5章行為描述(一):模塊基本結(jié)構(gòu)5.1行為描述的結(jié)構(gòu)5.2語句塊5.1行為描述的結(jié)構(gòu)模塊采用行為描述方式時的基本語法格式如下:module

<模塊名>(<端口列表>)模塊端口說明參數(shù)定義(可選)數(shù)據(jù)類型說明過程塊(initial過程塊或always過程塊,可有一個或多個)連續(xù)賦值語句;任務定義(task)(可選)函數(shù)定義(function)(可選)endmodule其中:端口列表中可以有單個或多個輸入、輸出或雙向端口;這些端口類型要在“模塊端口說明”部分進行類型說明。參數(shù)定義用關(guān)鍵詞parameter實現(xiàn),如果模塊定義了參數(shù),那么該模塊的每個實例可以對該參數(shù)進行重新定義,使得該參數(shù)值對每一個具體實例是惟一的。數(shù)據(jù)類型說明用來對模塊中用到的各類變量類型進行說明,如果某個變量沒有進行數(shù)據(jù)類型說明,則它的類型缺省為連線類型(wire)。過程塊是由過程語句initial或always開頭的一個語句塊,根據(jù)這兩個不同的關(guān)鍵詞,過程塊可以被分為“initial過程塊”和“always過程塊”兩種類型。過程塊中包含一條或多條行為語句,過程塊是行為描述的主要組成部分。連續(xù)賦值語句是由關(guān)鍵詞assign來標識的一種賦值語句,它只能對連線型類型(net類型)變量進行驅(qū)動,它和語句塊一樣也是一種行為描述語句。在下一章討論過程賦值語句時我們將對連續(xù)賦值語句一并進行討論。任務定義和函數(shù)定義部分都是可選的,它們引入的目的是為了描述模塊中被多次執(zhí)行的部分以及為了增強代碼的易讀性。上面列出的各個模塊組成項可以以任意次序出現(xiàn),但是端口說明和數(shù)據(jù)類型說明必須出現(xiàn)在這些端口和數(shù)據(jù)被引用之前。與第2章中描述的模塊的一般格式定義相比,我們可以看出:在進行行為描述時,模塊內(nèi)不能出現(xiàn)模塊實例和原語實例語句(包括用戶自定義原語實例),模塊內(nèi)只能存在過程塊(initial過程塊和always過程塊)、連續(xù)賦值語句、任務定義(task)和函數(shù)定義(function)這四種結(jié)構(gòu)成分。對電路進行行為描述主要是通過過程塊和連續(xù)賦值語句來進行的,任務和函數(shù)的使用也需要在過程塊或連續(xù)賦值語句中進行調(diào)用。本章以及第6、7章將對這幾種結(jié)構(gòu)成分進行介紹。一個行為描述模塊中可以同時包含多個過程塊和多個連續(xù)賦值語句,這些組成成分將以并行方式各自獨立地執(zhí)行;行為描述模塊也可以只包含過程塊或者只包含連續(xù)賦值語句。5.1.1過程塊每個過程塊是由“過程語句(initial或always)”和語句塊所組成的,而語句塊主要是由過程性賦值語句(包括“過程賦值語句”和“過程連續(xù)賦值語句”)和高級程序語句(包括“條件分支語句”和“循環(huán)控制語句”)這兩種行為語句構(gòu)成的。過程塊具有如下特點:

(1)在行為描述模塊中出現(xiàn)的每個過程塊(always過程塊或initial過程塊)都代表一個獨立的進程。

(2)在進行仿真時,所有initial過程塊和always過程塊的執(zhí)行都是從0時刻開始并行地進行的。

(3)每一個過程塊內(nèi)部的多條語句的執(zhí)行方式可以是順序執(zhí)行的(當塊定義語句為begin-end時的情況),也可以是并行執(zhí)行的(塊定義語句為fork-join時的情況)。

(4)?always過程塊和initial過程塊都是不能嵌套使用的。比如下例5-1就是錯誤的。

【例5-1】錯例:嵌套的過程塊。modulenested_procedural_block(a,b,c);inputa,b;outputc;reg

a,b,c;initial//initial過程塊1beginc=a;initial//嵌套在initial過程塊1內(nèi)部的initial過程塊2beginc=b;endendendmodule5.1.2intial過程塊

initial過程塊是由過程語句“initial”和語句塊組成的,它的格式為:initial語句塊而“語句塊”的格式為:<塊定義語句1>:<塊名>塊內(nèi)局部變量說明;時間控制1行為語句1;……時間控制n

行為語句n;<塊定義語句2>在如上所示的格式中:

(1)過程語句關(guān)鍵詞initial表明了該過程塊是一個“initial過程塊”。

(2)<塊定義語句1>和<塊定義語句2>構(gòu)成了一組塊定義語句,它們可以是“begin,end”語句組或“fork,join”語句組。這兩條塊定義語句將它們之間的多條行為語句組合在一起,使之構(gòu)成一個語句塊,并使其在格式上更像一條語句。當語句塊中只包含一條行為語句并且不需要定義塊名和塊內(nèi)局部變量時,這兩條塊定義語句可以缺省。

(3)<塊名>為可選項,塊名可以為語句塊創(chuàng)建一個局部作用域。定義了塊名的過程塊稱為“有名塊”,在有名塊中可以定義局部變量,有名塊內(nèi)部語句的執(zhí)行可以被disable語句中斷。

(4)塊內(nèi)局部變量說明也是可選項,只有在有名塊中才能定義局部變量,并且塊內(nèi)局部變量只能是寄存器類數(shù)據(jù)類型。

(5)時間控制用來對過程塊內(nèi)各條語句的執(zhí)行時間進行控制。它可以是任何一種時間控制方式。關(guān)于時間控制我們將在第6章進行詳細討論。

(6)行為語句可以是如下語句中的一種:

?過程賦值語句(阻塞型或非阻塞型過程賦值語句)。

?過程連續(xù)賦值語句(assign/deassign或force/release語句組)。

if條件分支語句。

case條件分支語句。

?循環(huán)控制語句(forever,repeat,while,for循環(huán)控制語句)。

wait等待語句。

disable中斷語句。

?事件觸發(fā)語句(event_trigger)。

?任務調(diào)用語句(用戶自定義的任務或系統(tǒng)任務)我們可以將上面的這些行為語句分成三類:過程性賦值語句、高級程序語句和時間控制語句。其中過程性賦值語句和高級程序語句是過程塊的基本組成部分。要注意上面列出的行為語句只能對寄存器類數(shù)據(jù)變量進行賦值(除force/release過程連續(xù)賦值語句以外)。在進行仿真時,一個initial過程塊從模擬0時刻開始執(zhí)行,它在仿真過程中只執(zhí)行一次,在執(zhí)行完一次后該initial過程塊就被掛起,不再執(zhí)行。如果一個模塊中存在多個initial過程塊,則每個initial過程塊都是同時從0時刻開始并行執(zhí)行的。initial過程塊內(nèi)的多條行為語句可以是順序執(zhí)行(語句塊是begin-end串行塊時)的,也可以是并行執(zhí)行(語句塊是fork-join并行塊時)的。

initial過程塊的使用主要是面向功能模擬的,它通常不具有可綜合性。initial過程塊通常用來描述測試模塊的初始化、監(jiān)視、波形生成等功能行為;而在對硬件功能模塊的行為描述中,initial過程塊常常用來對只需執(zhí)行一次的進程進行描述,例如它可以用來為寄存器變量賦初值。

【例5-2】initial過程塊用于對變量和存儲器進行初始化。moduleregister_initialize(memory);inout

areg;inoutmemory;parameterSIZE=1024;parameterBYTESIZE=8;reg[BYTESIZE-1:0]memory[SIZE-1:0];initial//initial過程語句begin:SEQ_BLK_A//塊定義語句,SEQ_BLK_A為塊名integer:index

;//計數(shù)變量,為塊中的一個局部變量for(index=0;index<SIZE;index=index+1)memory[index]=0;//對存儲器memory進行初始化areg=0;//對寄存器areg進行初始化end//塊結(jié)束標志endmodule這個例子的作用是用initial語句在仿真的開始時刻對寄存器變量和存儲器進行賦零值操作,從而實現(xiàn)各個變量的初始化。例5-2中的串行塊被定義了一個塊名“SEQ_BLK_A”,這是由于為了循環(huán)計數(shù)需要定義局部變量index,而只有當串行語句塊為有名塊時才能在塊中定義局部變量,所以上例中的塊名定義不能缺省。initial過程塊中包含了一個begin-end串行語句塊。所以對存儲器的賦值操作將先于對寄存器的賦值操作進行。這個initial過程塊在0ns時開始執(zhí)行,并且由于串行塊中for循環(huán)控制語句和過程賦值語句都沒有指定時延,所以對存儲器和寄存器的賦值操作都是在0時刻開始和完成的。在完成對寄存器的賦值操作后,initial過程塊中所有的語句都已執(zhí)行完畢,所以initial過程塊將結(jié)束執(zhí)行,并且將被永遠掛起不再重新執(zhí)行。

【例5-3】initial過程塊用于為電路仿真生成激勵波形。initialbegininputs=‘b000000; //初始時刻為0#10inputs=‘b011001; //10個時間單位后取值改變#20inputs=‘b011011; //20個時間單位后取值改變#5inputs=‘b011000; //5個時間單位后取值改變#10inputs=‘b001000; //20個時間單位后取值改變end在例5-3中,我們用initial過程塊來生成特定的電路仿真激勵信號,和例5-2中的情況一樣,initial語句包含了一個串行塊。但是在此例中begin-end串行塊內(nèi)的語句是帶有時延的,假定initial語句從t=0時刻開始執(zhí)行,那么首先執(zhí)行第一條賦值語句,在t=0時刻input的值變?yōu)?b000000;由于第二條賦值語句帶有延時控制,所以第二條語句的執(zhí)行是在第一條語句執(zhí)行結(jié)束10個單位時間后(即在t=10時刻)開始的,在t=10時刻input的值變?yōu)?b011001;然后再等待20個單位時間后開始第三條賦值語句的執(zhí)行,依次類推可以知道input取值的變化情況將如表5.1所示。當?shù)谖鍡l賦值語句執(zhí)行完畢后(t=45時刻),initial過程塊中所有語句已全部執(zhí)行完,仿真進程跳出initial過程塊,initial語句被永遠掛起。5.1.3always過程塊

always過程塊是由“always”過程語句和語句塊組成的,它的格式為:always@(敏感事件列表)語句塊其中“語句塊”的格式為:<塊定義語句1>:<塊名>塊內(nèi)局部變量說明;時間控制1行為語句1;……時間控制n

行為語句n;<塊定義語句2>

(1)關(guān)鍵詞always表明了該過程塊是一個“always過程塊”。

(2)?@(敏感事件列表)是可選項,帶有敏感事件列表的語句塊被稱為“由事件控制的語句塊”,它的執(zhí)行要受敏感事件的控制。(敏感事件列表)的形式為:(event-expression[orevent-expression*])敏感事件列表是由一個或多個事件表達式(event-expression)構(gòu)成的,當存在多個事件表達式時要用or將它們組合起來。or用來說明:只要發(fā)生了敏感事件列表所列出的多個事件中的任何一個,就將啟動后面語句塊的執(zhí)行。敏感事件列表實際上代表了一個事件控制類型的時間控制。我們將在第6章進一步討論時間控制、事件控制和敏感事件列表。

(3)?always過程塊中關(guān)于<塊定義語句>的規(guī)定和initial過程塊中的情況一樣,它們可以是“begin-end”語句組或“fork-join”語句組,由這兩組語句組組合成的語句塊分別稱為串行塊和并行塊。當過程塊中只包含一條語句且不需定義塊名與塊內(nèi)局部變量時,塊定義語句可以缺省。

(4)?<塊名>為可選項,對它的規(guī)定與initial過程塊中的情況一樣。定義了塊名的過程塊稱為有名塊。

(5)塊內(nèi)局部變量是可選項,對它的規(guī)定與initial過程塊中的情況一樣。只有在有名塊中才能定義局部變量,塊內(nèi)局部變量只能是寄存器類數(shù)據(jù)類型;

(6)時間控制用來對過程塊內(nèi)各條語句的執(zhí)行時間進行控制。其作用與initial過程塊中的“時間控制”部分的作用是相同的。

(7)對“行為語句”的規(guī)定與上一小節(jié)中initial過程塊中的情況相同。從上面的格式定義可以看出,always過程塊和initial過程塊在格式上的區(qū)別主要在于:always過程語句后面可以有一個敏感事件列表,該敏感事件列表的作用是用來激活always過程語句的執(zhí)行,而initial過程語句的后面則不允許有敏感事件列表。在進行仿真時,和initial過程塊一樣,always過程塊是從模擬0時刻開始執(zhí)行的。但是always語句在仿真過程中是不斷重復執(zhí)行的,而不像initial過程塊中的語句那樣在執(zhí)行一次后就被掛起,不會再次被執(zhí)行。并且always過程塊內(nèi)各條語句的真正執(zhí)行必須由敏感事件列表中列出的事件進行觸發(fā)才能啟動。如果always過程塊中的敏感事件列表缺省,則認為觸發(fā)條件始終被滿足,always過程塊將無條件地循環(huán)執(zhí)行下去,直到遇到$finish或$stop系統(tǒng)任務為止。敏感事件列表由一個或多個“事件表達式(event-expression)”構(gòu)成,事件表達式說明了啟動塊內(nèi)語句執(zhí)行時的觸發(fā)條件。當存在多個事件表達式時要用關(guān)鍵詞or將多個觸發(fā)條件組合起來。Verilog規(guī)定:只要這些事件表達式所代表的多個觸發(fā)條件中有一個成立,就啟動塊內(nèi)語句的執(zhí)行。例如,在語句:always@(aorborc);begin……end中,always過程塊的多個事件表達式分別是信號a,b和c,它們代表的觸發(fā)條件分別是信號a,b,c發(fā)生變化,這三個事件表達式之間以關(guān)鍵詞or分隔,這時只要其中一個觸發(fā)條件被滿足,也就是只要信號a,b,c中有一個的值發(fā)生變化,begin-end語句塊的執(zhí)行就被觸發(fā)。而如果信號a,b,c的值都沒有發(fā)生變化,則任何一個觸發(fā)條件都沒有被滿足,begin-end語句塊中的語句不被執(zhí)行;此時由于always過程語句的重復執(zhí)行的特點,仿真進程將不斷地對觸發(fā)條件進行監(jiān)測,等待a,b,c信號發(fā)生變化。

always過程塊的使用主要是對硬件功能模塊的行為進行描述,它也可以在測試模塊中用來對時鐘進行描述。利用always過程塊可以實現(xiàn)鎖存器和觸發(fā)器,它也可以用來實現(xiàn)組合邏輯。在用always過程塊實現(xiàn)組合邏輯時要注意將所有的輸入信號都列入敏感事件列表中,而在用always過程塊實現(xiàn)時序邏輯時卻不一定要將所有的輸入信號都列入敏感事件列表。敏感事件列表中未包含所有輸入信號的情況稱為“不完整事件說明(IncompleteEventSpecification)”?!安煌暾录f明”情況在仿真時可能會引起模擬器的誤解。我們可以通過如下兩個例子來說明這個問題。

【例5-4】敏感事件列表中未包含所有輸入信號的情況。modulethree_input_and(f,a,b,c);outputf;inputa,b,c;regf;always@(aorb)beginf=a&b&c;endendmodule例5-4描述了一個3輸入與門,由于輸入c沒有出現(xiàn)在敏感事件列表中,所以仿真時當輸入信號c發(fā)生變化時不會重新計算f值。所以仿真得到的功能并不是一個3輸入與門的功能行為,而正確實現(xiàn)3輸入與門應該采用例5-5所示的描述方式。

【例5-5】敏感事件列表中包含了所有的輸入信號。modulethree_input_and(f,a,b,c);outputf;inputa,b,c;regf;always@(aorborc)beginf=a&b&c;endendmodule在使用always過程塊時還要注意避免引起仿真死鎖狀態(tài)的發(fā)生。因為always語句有重復循環(huán)執(zhí)行的特性,所以當敏感事件列表缺省時,語句塊將一直循環(huán)執(zhí)行下去,這就有可能在仿真時產(chǎn)生仿真死鎖情況,如例5-6給出的語句所示。

【例5-6】不恰當使用always語句而產(chǎn)生仿真死鎖情況的例子。alwaysbeginclk=~clk;end上例中的always語句不帶有敏感事件列表,所以begin-end語句塊的執(zhí)行是無條件循環(huán)進行的,這樣當仿真進程進行到該always過程塊后(假設(shè)為t0時刻),將開始重復執(zhí)行塊中語句“clk=~clk;”,由于該語句沒有時間控制部分,該語句每次執(zhí)行都不需要時延,這樣仿真進程將停留在t0時刻不斷地循環(huán)執(zhí)行這條語句。這時,仿真就不能往下一時刻繼續(xù)進行,這就進入了一種仿真死鎖狀態(tài)。如果例5-6中的語句能加上延時控制,則該always語句將變?yōu)橐粭l非常有用的描述語句(見例5-7)。

【例5-7】對例5-6的改進。alwaysbegin#50clk=~clk;end例5-7中的賦值語句帶有50個單位時間的時延,這樣每一次該賦值語句被執(zhí)行的時刻是不同的,彼此間隔50個單位時間。所以循環(huán)就不是停留在t0時刻,而是往前推進的。例5-7可以生成一個周期為100的無限延續(xù)的信號波形。5.2語句塊語句塊就是在“initial過程塊”或“always過程塊”中位于過程語句(initial語句或always語句)后面的,由“塊定義語句1”和“塊定義語句2”所界定的一組行為語句?!皦K定義語句1”和“塊定義語句2”構(gòu)成了一對“塊定義語句”。塊定義語句分成兩種:

一種是“begin-end”語句組,它們用來組合需要順序執(zhí)行的語句,由“begin-end”語句組標識的語句塊稱為“串行塊”。

另一種是“fork-join”語句組,它們用來組合需要并行執(zhí)行的語句。由“fork-join”語句組標識的語句塊稱為“并行塊”?!皦K定義語句1”(begin或fork語句)標識了語句塊的開始,“塊定義語句2”(end或join語句)則標識著語句塊的結(jié)束。當語句塊內(nèi)只包含一條語句時塊定義語句可以缺省。如果在定義語句塊的同時還引入了一個塊名,則該語句塊可以由這個塊名惟一標識,該語句塊被稱為一個“有名塊”。在有名塊內(nèi)可以定義內(nèi)部寄存器變量,并且可以用“disable”中斷語句來中斷有名塊內(nèi)語句的執(zhí)行。同時語句塊的塊名還提供了惟一標識寄存器的一種方法。語句塊只能出現(xiàn)在行為描述模塊中,但它不必非得出現(xiàn)在與過程語句initial或always的結(jié)合中,后面我們可以看到:在高級程序語句中以及任務和函數(shù)中都可以出現(xiàn)語句塊結(jié)構(gòu)。5.2.1串行塊(begin-end塊)串行塊的塊定義語句為“begin,end”,串行塊中的各條語句按串行方式順序執(zhí)行。串行塊的格式如下:begin

:<塊名>塊內(nèi)局部變量說明時間控制1行為語句1……時間控制n

行為語句nend其中,“塊內(nèi)局部變量說明”可以是reg型變量聲明語句、integer型變量聲明語句及real型變量聲明語句。串行塊執(zhí)行時的特點如下:

(1)串行塊內(nèi)的各條語句是按它們在塊內(nèi)出現(xiàn)的次序逐條順序執(zhí)行的,當前面一條語句執(zhí)行完畢后下一條語句才能開始執(zhí)行。

(2)塊中每條語句中的延時控制都是相對于前一條語句結(jié)束時刻的延時控制。

(3)在進行仿真時,當遇到串行塊時,塊中第一條語句隨即就開始執(zhí)行;當串行塊中最后一條語句執(zhí)行完畢時,程序流程控制就跳出串行塊,串行塊結(jié)束執(zhí)行。整個串行塊的執(zhí)行時間等于其內(nèi)部各條語句執(zhí)行時間的總和。下面給出串行語句塊的幾個例子。

【例5-8】一個時鐘上升沿控制的三位移位寄存器。moduleThree_bit_shift_register(clk,d_in,d_out);inputclk;inputd_in;outputd_out;reg

reg_a,reg_b,d_out;always@(posedge

clk)begind_out=reg_b;reg_b=reg_a;reg_a=d_in;endendmodule在例5-8的代碼內(nèi)包含了一個begin-end串行塊,它屬于always過程塊的一部分。時鐘的上升沿跳變將觸發(fā)串行塊的執(zhí)行:第一條賦值語句首先執(zhí)行,將reg_b的值賦給寄存器d_out;執(zhí)行完第一條語句后,程序流程控制轉(zhuǎn)到第二條語句,開始執(zhí)行第二條語句,將reg_a的值賦給reg_b;然后執(zhí)行第三條語句,將輸入d_in值賦給reg_a;在執(zhí)行完第三條語句(串行塊中的最后一條語句)后,程序流程跳出串行塊,串行塊結(jié)束執(zhí)行。下面是一個塊內(nèi)語句帶有延時的情況。

【例5-9】由帶有延時控制的語句組成的串行塊,用于產(chǎn)生時序波形。modulesequential_signal_gen(d_out);outputd_out;reg

d_out;initialbegind_out=0;#1d_out=1;#2d_out=0;#3d_out=1;#4d_out=0;endendmodule例5-9中的begin-end串行塊屬于initial過程塊的一部分。塊中語句執(zhí)行過程如下:

(1)在仿真開始后(t=0時刻)串行塊就開始執(zhí)行,首先執(zhí)行第一條語句,第一條語句執(zhí)行完時也就是在0時刻d_out值變?yōu)?。

(2)然后開始執(zhí)行第二條語句,由于第二條賦值語句帶有1個單位時間的延時,所以直到第一條語句結(jié)束1個單位時間后(t=1時刻),第二條賦值語句才開始執(zhí)行,d_out的值變?yōu)?。

(3)同樣,第三條賦值語句是在第二條語句結(jié)束2個單位時間后(t=3時刻)開始執(zhí)行,d_out的值變?yōu)?。

(4)第四條賦值語句是在第三條語句結(jié)束3個單位時間后(t=6時刻)開始執(zhí)行,d_out的值變?yōu)?。

(5)第五條賦值語句是在第四條語句結(jié)束4個單位時間后(t=10時刻)開始執(zhí)行,d_out的值變?yōu)?。

(6)第五條賦值語句結(jié)束后,串行塊結(jié)束執(zhí)行。上例中串行語句塊執(zhí)行過程所產(chǎn)生的波形如圖5.1所示。圖5.1例5-9的執(zhí)行產(chǎn)生的波形5.2.2并行塊(fork-join塊)并行塊的塊定義語句為“fork,join”,并行塊中的多條語句是并行執(zhí)行的。并行塊的格式如下:fork:<塊名>塊內(nèi)局部變量說明時間控制1行為語句1;……時間控制n

行為語句n;join其中,“塊內(nèi)局部變量說明”可以是reg型變量聲明語句、integer型變量聲明語句、real型變量聲明語句、time型變量聲明語句及事件(event)聲明語句。并行塊執(zhí)行時的特點如下:

(1)并行塊內(nèi)各條語句是同時并行地執(zhí)行的,也就是說當程序流程控制進入并行塊后,塊內(nèi)各條語句都各自獨立地同時開始執(zhí)行。各條語句的起始執(zhí)行時間都等于程序流程控制進入該并行塊的時間。

(2)塊內(nèi)各條語句中指定的延時控制都是相對于程序流程控制進入并行塊的時刻的延時,也就是相對于并行塊開始執(zhí)行時刻的延時。

(3)當并行塊內(nèi)所有的語句都已經(jīng)執(zhí)行完畢后,也就是當執(zhí)行時間最長的那一條塊內(nèi)語句結(jié)束執(zhí)行后,程序流程控制才跳出并行塊,結(jié)束并行塊的執(zhí)行。整個并行塊的執(zhí)行時間等于執(zhí)行時間最長的那條語句所需的執(zhí)行時間。下面給出并行塊的幾個例子。

【例5-10】用并行塊來產(chǎn)生時序波形。modulesequential_signal_gen(d_out);outputd_out;reg

d_out;initialforkd_out=0;#1d_out=1;#2d_out=0;#3d_out=1;#4d_out=0;joinendmodule從例5-10與例5-9的比較中可以看出,它們兩者惟一的差別就是把塊定義語句由原來的串行塊定義語句“begin-end”改為這里的并行塊定義語句“fork-join”。但這一改變將導致語句塊的執(zhí)行過程與執(zhí)行結(jié)果都發(fā)生變化。在仿真開始后(t=0時刻)initial過程語句隨即被執(zhí)行,并行塊隨后也開始執(zhí)行(t=0時刻),塊內(nèi)所有語句的執(zhí)行被同時啟動:由于第一條賦值語句沒有時延,所以第一條語句的賦值操作也是在0時刻同時進行的,使d_out取值變?yōu)?。由于第二條賦值語句帶有1個單位時間的延時,所以在并行塊開始執(zhí)行1個單位時間后(t=1時刻),第二條賦值語句對應的賦值操作才真正得到執(zhí)行,將d_out的取值改變?yōu)?。同樣,第三條賦值語句對應的賦值操作是在并行塊開始執(zhí)行2個單位時間后(t=2時刻)才進行的,將d_out取值變?yōu)?;第四條賦值語句對應的賦值操作是在并行塊開始執(zhí)行3個單位時間后(t=3時刻)才進行的,將d_out取值變?yōu)?;第五條賦值語句對應的賦值操作是在并行塊開始執(zhí)行4個單位時間后(t=4時刻)進行的,使d_out的值變?yōu)?。由于并行塊中的五條語句的執(zhí)行所需時間分別是0,1,2,3,4個單位時間,其中第五條賦值語句所需時間最長,所以在第五條語句執(zhí)行完畢后(t=4時刻),并行塊結(jié)束執(zhí)行。該并行語句塊執(zhí)行過程產(chǎn)生的波形如圖5.2所示,它和上一小節(jié)中用串行塊實現(xiàn)的圖5.1所示的波形是不同的。要注意例5-10并行塊內(nèi)各條賦值語句出現(xiàn)的次序可以是不同的,比如其中各條語句的次序可以是例5-11所示的情況。圖5.2例5-10的執(zhí)行產(chǎn)生的波形

【例5-11】并行塊內(nèi)語句的不同次序。initialfork#3d_out=1;#2d_out=0;#4d_out=0;#1d_out=1;d_out=0;join在例5-11中,并行塊內(nèi)的各條語句并不是按它們被執(zhí)行的先后順序給出的,但例5-11同樣可以生成與例5-10相同的波形。5.2.3串行塊和并行塊的混合使用在分別對串行塊和并行塊進行了介紹之后,我們還必須討論一下串行塊和并行塊的混合使用。它可以分為如下兩種情況。

(1)當串行塊和并行塊屬于不同的過程塊(initial或always過程塊)時,串行塊和并行塊是并行執(zhí)行的。

【例5-12】串行塊和并行塊屬于不同過程塊時的情況。modulebelong_to_different_pro_block(a,b);outputa,b;rega,b;initial //第一個initial過程塊begin //串行塊a=0; //語句S1#20a=0; //語句S2b=1; //語句S3#40a=0; //語句S4b=0; //語句S5endinitial //第二個initial過程塊fork //并行塊b=1; //語句P1#10a=1; //語句P2#10b=0; //語句P3#30a=1; //語句P4#50a=1; //語句P5joinendmodule例5-12中出現(xiàn)了兩個initial過程塊,這兩個過程塊是并行執(zhí)行的,所以它們內(nèi)部所包含的begin-end串行語句塊和fork-join并行語句塊也是并行執(zhí)行的。而在串行塊內(nèi)部,各條語句按順序方式執(zhí)行;在并行塊內(nèi)部,各條語句按并行方式執(zhí)行。例5-12中各條語句的執(zhí)行時序如表5.2所示。

(2)當串行塊和并行塊嵌套使用在同一過程塊內(nèi)時,內(nèi)層語句塊可以看作是外層語句塊中的一條普通語句,內(nèi)層語句塊在什么時刻得到執(zhí)行是由外層語句塊的規(guī)則所決定的;而在內(nèi)層語句塊開始執(zhí)行后,其內(nèi)部各條語句的執(zhí)行要遵守內(nèi)層語句塊的規(guī)則。

【例5-13】嵌套使用的串行塊和并行塊。modulepara_bloc_nested_in_seri_bloc(a,b);outputa,b;rega,b;initial //?initial

溫馨提示

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

評論

0/150

提交評論