Verilog HDL項目式教程 課件 項目3-5 結構化建模;行為建模;狀態機建模_第1頁
Verilog HDL項目式教程 課件 項目3-5 結構化建模;行為建模;狀態機建模_第2頁
Verilog HDL項目式教程 課件 項目3-5 結構化建模;行為建模;狀態機建模_第3頁
Verilog HDL項目式教程 課件 項目3-5 結構化建模;行為建模;狀態機建模_第4頁
Verilog HDL項目式教程 課件 項目3-5 結構化建模;行為建模;狀態機建模_第5頁
已閱讀5頁,還剩109頁未讀 繼續免費閱讀

下載本文檔

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

文檔簡介

任務3.1門級原語

任務3.2層次建模任務3.1門級原語任務3.1門級原語簡單的邏輯電路可以使用邏輯門來設計實現。基本的邏輯門分為兩類:與/或門類、緩沖/非門類。(1)與/或門類。與/或門類包括與門(and)、或門(or)、與非門(nand)、或非門(nor)、異或門(xor)、同或門(xnor)。與/或門類都具有一個標量輸出端和多個標量輸入端,門的端口列表中的第一個端口必定是輸出端口,其他均為輸入端口。當任意一個輸入端口的值發生變化時,輸出端口的值立即重新計算。例如:(2)緩沖/非門類。緩沖/非門類包括緩沖器(buf)、非門(not)、帶控制端的緩沖器/非門(bufif1、bufif0、notif1、notif0)。緩沖/非門類具有一個標量輸入端和多個標量輸出端,門的端口列表中的最后一個端口必定是輸入端口,其他均為輸出端口。例如:【例3-1】

利用雙輸入端的nand門,編寫自己的雙輸入端的與門(my_and)、或門(my_or)、非門(my_not)、異或門(my_xor)。上述電路設計涉及的知識點有門級原語例化和多輸出處理。下面對這些知識點進行說明。(1)門級原語例化。在門級原語實例引用的時候,可以不指定具體的實例名,這一點給需要實例引用幾百個甚至更多門的模塊提供了方便。但對于初學者,建議在調用門級原語時給出實例名。在以上示例中,調用門級原語時均沒有給出實例名。在實際應用中,與非門和或非門更為普遍,這是因為由這兩種門生成其他邏輯門容易實現。本例給出了使用與非門來設計其他基本邏輯門的方法。(2)多輸出處理。例3-1中有4個輸出y[0]~y[3],分別對應著與門、或門、非門、異或門。這4個輸出均是獨立的,在代碼中分別進行了單獨處理。在實踐中,建議針對每個輸出單獨進行分析設計,這樣做對于正確地實現電路邏輯是非常有效的。例3-1的測試代碼如例3-2所示。【例3-2】

門電路測試代碼。上述電路設計涉及的知識點是組合邏輯測試激勵的編寫方法。例3-2中將所有輸入變量通過位拼接運算符拼接成一個變量{bb,aa},然后進行循環加1處理,這樣就可以遍歷所有可能的組合,進而可以測試所有可能組合下的結果的正確性。與測試代碼對應的仿真圖如圖3-1所示。根據圖3-1可以看出,y對應的四路輸出均實現了相應門電路的功能,設計正確。邏輯門是最基本的電路單元,任何復雜的數字邏輯電路均可由邏輯門實現。但復雜電路的設計如果從邏輯門開始搭建,顯然是不現實的,這時必須采用其他建模方式,層次建模就是一種有效的方法。任務3.2?層

模首先通過一個典型的實例來介紹層次建模的概念。【例3-3】

實現一個1位全加器。使用QuartusⅡ軟件綜合的全加器的電路圖如圖3-2所示。由圖3-2可見,全加器是由兩個半加器和一個或門組成的。雙擊圖中的半加器,可以看出半加器又由與門、異或門和非門構成,如圖3-3所示。上述電路設計涉及的知識點有層次建模、模塊例化。下面對這些知識點進行說明。(1)層次建模。模塊是可以進行層次嵌套的,因此,可以將大型數字電路設計分割成不同的小模塊來實現特定的功能,最后通過頂層模塊調用子模塊來實現整體功能。在全加器模塊內部調用了半加器模塊和或門模塊,而在半加器模塊內部又調用了基本邏輯門原語。在層次建模中,不管是頂層模塊還是被調用模塊內部,其實現方式都可以使用多種方式,包括數據流建模、行為建模、結構化建模、狀態機建模等。例如,在例3-3中,或門模塊內部使用了數據流建模,使用了連續賦值語句assign。(2)模塊例化。在全加器模塊中有兩處調用了半加器:h_adderu0(ain,bin,d,e);?和h_adderu1(e,cin,f,sum);。每次調用均給出一個唯一的實例名,調用時端口列表名稱不同。在Verilog設計中,模塊調用時,可以按順序將模塊定義的端口與外部環境中的信號連接起來,這種方法稱為按順序連接。h_adderu0(ain,bin,d,e);?調用將ain、bin、d、e分別與模塊定義中的端口a、b、co、so連接;h_adderu1(e,cin,f,sum);?調用將e、cin、f、sum分別與模塊定義中的端口a、b、co、so連接。全加器的仿真波形如圖3-4所示。從仿真波形中可以看出,該設計完成了一位全加器的功能。與仿真波形相應的測試代碼如下:【例3-4】1位全加器測試模塊。上述仿真代碼涉及的知識點有模塊例化、輸入激勵。下面對這些知識點進行說明。(1)模塊例化。仿真代碼中的模塊例化與設計代碼中的模塊例化其方法完全相同。(2)輸入激勵。輸入激勵要簡潔,同時要保證輸入激勵全面且有代表性。對于3個輸入的組合邏輯電路來說,3個輸入的8種組合必須都測試,最簡單的方法就是?{cin,bin,ain}={cin,bin,ain}?+?1;?,這樣就可以保證3個輸入的所有可能組合都被測試到。鑒于大型電路設計越來越多,團隊合作分工越來越普遍,因此層次建模在實際應用中非常普遍。下面對層次建模、模塊實例化、端口關聯等進一步進行補充說明。(1)層次建模。數字電路設計中有兩種基本的設計方法:自底向上和自頂向下。在自頂向下設計方法中,首先定義頂層模塊,隨后將頂層模塊分解為多個必要的子模塊,然后進一步對各個子模塊進行分解,直到達到無法進一步分解的底層功能塊,如圖3-5所示。在自底向上設計方法中,首先對現有的功能塊進行分析,然后使用這些模塊來搭建規模大一些的功能塊,如此繼續,直到頂層模塊,如圖3-6所示。在典型的設計中,這兩種方法是混合使用的。為了說明層次建模的概念,下面結合全加器進行說明。根據全加器的電路圖,可以得出全加器的設計層次如圖3-7所示。使用自頂向下的方法進行設計,首先需要說明全加器的功能。在使用半加器和或門搭建頂層模塊之后,進一步使用與門、異或門和非門來實現半加器。這樣就可以將較大的功能塊分解為較小的功能塊,直到無法繼續分解。對于例3-4,我們可以認為基本門就是最小的功能塊,不可再分解。事實上,這些基本門是可以繼續分解的,這里就隱含著自底向上的設計方法。各種門級元件都是由MOS晶體管級開關元件構成的,都經過了優化設計,都可以用來搭建高層模塊。對于例3-4來說,自頂向下的設計方法和自底向上的設計方法按相反的方向獨立地進行,在門級會合。這樣電路設計者使用開關級原語創建了一個底層元件庫,而邏輯設計者通過使用自頂向下的方法將整個設計用由庫單元構成的結構來描述。(2)模塊實例化。在頂層模塊中,調用了2個半加器子模塊和一個或門子模塊。模塊的調用過程稱為模塊的實例化,調用模塊后創建的對象稱為實例。模塊實例化是實現自頂向下設計的一種重要途徑。模塊實例化可以是多層次的,一個調用了較低層次模塊的模塊,可以被更高層次的模塊調用。例如,例3-4中,可以先設計一個異或門模塊,這個模塊在半加器中被實例化,半加器模塊又在全加器模塊中被實例化。需要說明的是,模塊的調用(實例化)與C語言中的函數調用有著本質的區別。模塊被調用后會生成一個實例,這個實例可以使用實例名對其進行唯一標識。如果在某個模塊內出現了多次模塊調用,則各次調用所指定的實例名必須不相同,在同一模塊內不能出現兩個相同的實例名。同一個上級模塊可以對多個下級模塊進行調用,也可以對一個下級模塊進行多次調用。這樣就會在同一電路中生成多個一模一樣的電路結構單元,這些電路結構單元就是每次模塊調用后生成的模塊實例。所以,為了對這些相同的電路結構單元進行區分,為它們所取的模塊實例名應該是各不相同的。實例名和模塊名的區別是:模塊名標志著不同的模塊,用來區分電路單元的不同種類;而實例名則標志著不同的模塊實例,用來區別電路系統中的不同硬件電路單元。在測試模塊時,也需要對設計模塊進行例化,并對設計模塊的輸入信號增加激勵。(3)端口關聯。在模塊實例化中,端口起著非常重要的作用。端口是模塊與外界環境交互的接口,事實上,我們的模塊可以理解為一顆芯片,端口可理解為芯片的管腳。對于外部環境來說,模塊內部是不可見的,對模塊的實例化只能通過其端口進行。這種特點為設計者提供了很大的靈活性,只要端口保持不變,就可以對模塊內部的實現細節作任意修改。在模塊實例化中,可以使用兩種方法將模塊定義的端口與外部環境中的信號連接起來,即位置關聯法和名稱關聯法。①

位置關聯法。在位置關聯方法下,端口連接表的格式為(<端口1>,<端口2>,…,<端口n>)這些信號端口將與進行模塊定義時給出的“端口列表”中出現的各個模塊端口依次相連:端口連接表中的端口1與第1個模塊端口相連,端口連接表中的端口2與第2個模塊端口相連,以此類推。在全加器的Verilog描述中,采用了位置關聯的方法,即以下三條實例語句:h_adderu0(ain,bin,d,e);h_adderu1(e,cin,f,sum);or2au2(d,f,cout);②

名稱關聯法。在名稱關聯方法下,端口連接表的格式為(.<模塊端口1>(<端口1>),.<模塊端口2>(<端口2>),…,.<模塊端口n>(<端口n>))端口連接表內顯式地指明了與每個外部信號端口相連的模塊端口名,即模塊端口1所代表的端口將與端口1相連,依次類推。在全加器的Verilog描述中,若采用名稱關聯的方法,則需要用以下三條實例語句來替換相應的位置關聯語句。需要說明的是,不能在同一個端口連接表內混合使用名稱關聯和位置關聯。例如,下面這條語句是非法的:但對于不同的實例語句,則可以選擇不同的端口關聯方法。例如,下面的語句共存于同一個模塊中是合法的:另外,在端口名稱關聯方法下,模塊端口和信號端口的連接關系被顯式地說明,因此,端口連接表內各項的排列順序對端口連接關系是沒有影響的。例如,在全加器中對于半加器的實例化語句可寫成:這樣在大型設計中可以避免端口連接錯誤。任務4.1結構化過程語句always

任務4.2過程賦值語句

任務4.3選擇語句

任務4.4循環語句

任務4.5塊語句(begin/end)

任務4.6任務和函數語句

任務4.7流水線設計任務4.1結構化過程語句always

always語句是行為建模的基本語句,每個always語句代表一個獨立的執行過程,也稱為進程。與C語言不同,Verilog在本質上是并發的而非順序的,Verilog的各個always進程也是并發執行的,而不是順序執行的。always語句對應著實際的硬件電路。always@(*)通常對應組合邏輯電路。always@(posedgeclk)對應時序邏輯電路,相當于一個D觸發器和一個組合邏輯電路,其中組合邏輯電路的輸出直接連接D觸發器的數據輸入端。always語句包括的所有行為語句構成了一個always語句塊。每個always語句塊在滿足一定的條件后即執行其中的第一條語句,然后按順序執行隨后的語句,直到最后一條執行完成后,再次等待always語句塊的執行條件,等條件滿足后又從第一條語句開始執行,循環往復。因此,always語句通常用于對數字電路中一組反復執行的活動進行建模。【例4-1】

使用always語句描述D觸發器。例4-1的綜合結果如圖4-1所示。從綜合結果來看,例4-1實現了一個上升沿觸發的D觸發器。上述電路設計涉及的知識點有always語句、非阻塞賦值語句。下面對這些知識點進行說明。(1)?always語句。always語句是行為建模的典型特征。例4-1的程序在時鐘上升沿將數據d賦予觸發器輸出q,功能同D觸發器一樣。always語句由于其不斷重復執行的特性,只有和一定的時序控制結合在一起才有用。always@(posedgeclk)語句表示只有在clk上升沿才開始執行always語句塊,否則不執行。這種時序控制是always語句最常用的。always的時序控制可以是沿觸發的,也可以是電平觸發的,可以是單個信號或多個信號,中間需要用關鍵字or或“,”連接。例如:沿觸發的always塊常用來描述時序邏輯,如果符合可綜合風格要求,則可用綜合工具將其自動轉換為表示時序邏輯的寄存器組和門級邏輯;而電平觸發的always塊常用來描述組合邏輯和帶鎖存器的組合邏輯,如果符合可綜合風格要求,則可轉換為表示組合邏輯的門級邏輯或帶鎖存器的組合邏輯。一個模塊中可以有多個always塊,它們都是并行運行的。(2)always語句對應的電路。always@(*)通常對應組合邏輯電路。always@(posedgeclk)對應的是時序邏輯電路,相當于一個D觸發器和一個組合邏輯電路,其中組合邏輯電路的輸出直接連接D觸發器的數據輸入端。本書建議每個always語句塊通常都實現且僅實現一個輸出變量。這是因為一個D觸發器通常僅有一個輸出變量Q,這種實現方法與實際電路的對應關系清晰明了。(3)非阻塞賦值語句。q<=d;中使用的是非阻塞賦值語句。非阻塞賦值語句是過程賦值語句的一種類型。讀者應掌握阻塞賦值語句和非阻塞賦值語句的特征。任務4.2?過程賦值語句過程賦值語句的更新對象是寄存器、整數等。這些類型的變量在被賦值后,其值將保持不變,直到被其他過程賦值語句賦予新值。過程賦值語句與數據流建模中的連續賦值語句是不同的。首先,連續賦值語句總是處于活動狀態,任意一個操作數的變化都會導致表達式的重新計算以及重新賦值,但過程賦值語句只有在執行到的時候才會起作用。其次,更新對象不同,連續賦值語句的更新對象是線網,而過程賦值語句的更新對象是寄存器、整數等。最后,形式不同,過程賦值語句不使用assign。過程賦值語句與連續賦值語句又有相同之處,即兩者可以使用的運算符是完全相同的。連續賦值語句中使用的運算符在過程賦值語句中同樣適用,而且含義完全相同。Verilog包括兩種類型的過程賦值語句:阻塞賦值語句和非阻塞賦值語句。下面通過5個示例來說明兩種賦值方式的不同。這5個示例的設計目標都是實現3位移位寄存器,它們分別采用了阻塞賦值方式和非阻塞賦值方式。【例4-2】

采用阻塞賦值方式描述移位寄存器1。

綜合結果如圖4-2所示。【例4-3】

采用阻塞賦值方式描述移位寄存器2。

綜合結果如圖4-3所示。【例4-4】

阻塞賦值方式描述的移位寄存器3。

綜合結果如圖4-4所示。【例4-5】

采用非阻塞賦值方式描述移位寄存器1。

【例4-6】

采用非阻塞賦值方式描述移

位寄存器2。例4-5和例4-6的綜合結果與例4-2的完全一致,如圖4-2所示。例4-2~例4-6的電路設計涉及的知識點有過程賦值語句、阻塞賦值、非阻塞賦值。下面對這些知識點進行說明。(1)阻塞賦值。例4-2~例4-65個例題的設計目標均是實現3位移位寄存器,但從綜合結果可以看出,例4-3和例4-4沒有實現設計目標,這與這兩個設計中使用了阻塞賦值有關。Q2=Q1;這種賦值方式稱為阻塞賦值,Q2的值在賦值語句執行完成后立刻改變,而且隨后的語句必須在賦值語句執行完成后才能繼續執行。所以,例4-4中的三條語句Q0=D,Q1=Q0,Q2=Q1,執行完成后,Q0、Q1、Q2的值都變化為D的值。也就是說,D的值同時賦給了Q0、Q1、Q2,參照其綜合結果就能更清晰地看到這一點。例4-2和例4-3可通過同樣的分析得出與綜合結果一致的結論。(2)非阻塞賦值。Q2<=Q1;這種賦值方式稱為非阻塞賦值,Q2的值在賦值語句執行完成后并不會立刻改變,而是等到整個always語句塊結束后才完成賦值操作。所以,例4-6中的三條語句Q0<=D,Q2<=Q1,Q1<=Q0,執行完成后,Q0、Q1、Q2的值并沒有立刻更新,而是保持了原來的值,直到always語句塊結束后才同時進行賦值,因此Q0的值變為了D的值,Q2的值變為了原來Q1的值,Q1的值變為了原來Q0的值(而不是剛剛更新的Q0的值D),參照其綜合結果能更清晰地看到這一點。例4-5可通過同樣的分析得出與綜合結果一致的結論。(3)過程賦值語句總結。前三個例題采用的是阻塞賦值方式,可以看出阻塞賦值語句在always塊語句中的位置對其結果有影響;后兩個例題采用的是非阻塞賦值方式,可以看出非阻塞賦值語句在always塊語句中的位置對其結果沒有影響。因此,在使用賦值語句時要注意兩者的區別與聯系。在電路設計中,注意非阻塞賦值“<=”只能用于對寄存器類型變量進行賦值,因此只能用于“initial”塊和“always”塊中,不允許用于連續賦值語句“assign”;而阻塞賦值“=”既可以對線網類型變量賦值,也可以對寄存器類型變量進行賦值,因此既可以用于“initial”塊和“always”塊中,也可以用于連續賦值語句“assign”,但阻塞賦值通常用于連續賦值語句中。綜上所述,在選擇使用阻塞賦值和非阻塞賦值時,為了防止引起歧義或產生混亂,建議在實現組合邏輯時統一使用阻塞賦值,在實現時序邏輯時統一使用非阻塞賦值。任務4.3?選

句一、if條件語句if-else語句用來判定所給定的條件是否滿足,根據判定結果(真或假)決定執行給出的兩種操作之一。VerilogHDL語言提供了三種形式的if語句。(1)第1種if條件語句如下所示。(3)第3種if條件語句如下所示。(2)第2種if條件語句如下所示。

下面是一個使用if語句的例子。【例4-7】

使用always語句描述具有異步復位功能的D觸發器。

綜合結果如圖4-5所示。上述電路設計涉及的知識點有if條件語句和異步復位。下面對這些知識點進行說明。(1)異步復位。always@(posedgeclk,negedgerst)語句表示只有在clk上升沿或者rst下降沿才開始執行always語句塊,否則不執行。所以,D觸發器的復位為異步復位。這種帶有異步復位的時序邏輯電路的寫法可作為時序邏輯電路設計的模板。(2)?if條件語句。三種形式的if語句中,if后面都有“表達式”,一般為邏輯表達式或關系表達式。系統對表達式的值進行判斷,若為1,則按“真”處理;否則按“假”處理,執行指定的語句。三種形式的if語句中,語句后都有分號。這是由于分號是VerilogHDL語句中不可缺少的部分,這個分號是if語句中的內嵌套語句所要求的。但應注意,不要誤認為if和else是兩個語句,其實它們都屬于同一個if語句。else子句不能作為語句單獨使用,它必須是if語句的一部分,且與離它最近的if配對使用。例4-7中的程序使用了第2種if語句形式——if…else的條件語句,在時鐘上升沿的時刻,首先判斷復位信號rst是否有效,若有效則將D觸發器輸出置0,否則將數據d賦予D觸發器輸出。if(!rst)等同于if(rst==0),Verilog允許這些形式的表達式簡寫方式。在if和else后面可以包含一個語句,也可以有多個操作語句,此時用begin和end這兩個關鍵詞將幾個語句包含起來成為一個復合塊語句。例如:注意:end后不需要加分號。因為begin…end內是一個完整的復合語句,不需再附加分號。(3)?if語句的嵌套。在if語句中又包含一個或多個if語句,稱為if語句的嵌套。if語句嵌套的一般形式如下:進行電路設計時應注意if與else的配對關系,else總是與它上面距離最近的if配對。如果if與else的數目不一樣,則為了實現程序設計者的意圖,可以用begin…end塊語句來確定配對關系。例如:這時begin_end塊語句限定了內嵌if語句的范圍,因此else與第一個if配對。注意begin_end塊語句在if_else語句中的使用。二、case多路分支語句case語句是一種多分支選擇語句,基本的if語句只有兩個分支可供選擇,而實際設計中常常需要用到多分支選擇,Verilog語言提供的case語句可直接處理多分支選擇。case語句的一般形式如下:case(表達式) <case分支項> endcasecase分支項的一般格式如下:分支表達式: 語句;缺省項(default項): 語句;case后面()內的表達式稱為控制表達式,case分支項中的表達式稱為分支表達式。控制表達式通常表示為控制信號的某些位,分支表達式則用這些控制信號的具體狀態值來表示,因此,分支表達式又稱為常量表達式。當控制表達式的值與分支表達式的值相等時,就執行分支表達式后面的語句。如果所有的分支表達式的值都沒有與控制表達式的值相匹配,就執行default后面的語句。default項可有可無,一個case語句里只允許有一個default項。下面是一個簡單的使用case語句的例子。【例4-8】

使用case語句實現四功能的算術邏輯單元(ALU)設計,其輸入信號a、b均為4位,功能選擇信號sel為2位,輸出信號out為5位,具體關系如表4-1所示。例4-8的功能仿真結果如圖4-6所示。上述電路設計涉及的知識點有case語句和鎖存器。下面對這些知識點進行說明。(1)?case語句。在用case語句表達式進行比較的過程中,只有當信號的對應位的值能明確進行比較時,比較才能成功,因此應詳細說明case分項的分支表達式的值。case語句的所有表達式的值的位寬必須相等,只有這樣控制表達式和分支表達式才能進行對應位的比較。每一個case分項的分支表達式的值必須互不相同,否則就會出現矛盾現象(對表達式的同一個值有多種執行方案,對應到實際的電路,則會表現出電路不穩定)。執行完case分項后的語句后,跳出該case語句結構,終止case語句的執行。(2)鎖存器。如果條件語句或多路分支語句使用不當,則會在設計中生成原本沒有的鎖存器。對于多路選擇語句使用不當的示例如下:上述case語句的功能是:在某個信號sel取不同的值時,會給另一個信號q賦不同的值。always塊中說明:如果sel?=?0,q取a值;而當sel?=?2'b11,q取b的值。如果sel取2'b00和2'b11以外的值時,在always塊內,默認為q保持原值,這樣就自動生成了鎖存器。如果希望當sel取2'b00和2'b11以外的值時q賦為0,則default就必不可少了,如下例所示。程序中的case語句有default項,指明如果sel不取2'b00或2'b11時,編譯器或仿真器應賦給q的值。整個Verilog程序模塊綜合出來后,always塊對應的部分不會生成鎖存器。也就是說,在多路分支語句中使用default語句,可避免生成鎖存器。對于條件語句使用不當的示例如下:上述always語句塊中,if語句說明當a?=?1時,q取d的值。當a?=?0時,沒有定義q的取值。在always塊內,如果在給定的條件下變量沒有賦值,這個變量將保持原值,也就是說會生成一個鎖存器。如果希望當a?=?0時q的值為0,else項就必不可少,如下例所示。整個Verilog程序模塊綜合出來后,always塊對應的部分不會生成鎖存器。以上示例介紹了怎樣來避免偶然生成鎖存器的錯誤。如果使用if語句,應寫上else項;如果使用case語句,則應寫上default項。遵循上面兩條原則,就可以避免發生生成鎖存器的錯誤,使設計者更加明確設計目標,同時也增強了Verilog程序的可讀性。下面分別使用if-else語句和case語句來實現四選一多路選擇器,以使讀者體會兩種語句的差別與聯系。【例4-9】

四選一多路選擇器。綜合得出的電路圖如圖4-7所示。例4-9對應的測試代碼如例4-10所示。【例4-10】

四選一多路選擇器測試臺。仿真波形如圖4-8所示。從圖4-8的仿真波形可以看出,out_if和out_case在相同輸入激勵的情況下,輸出波形完全一致,這說明case語句與if/else語句是可以很容易地相互轉換。例4-10使用if-else語句實現out_if,使用case語句實現out_case。從綜合得到的電路圖來看,雖然電路結構差異較大,但實現的功能都是四選一多路選擇器,條件和輸出都一樣。上述電路設計和電路仿真中涉及的知識點是:if條件語句、case語句、選擇語句、鎖存器。三、選擇語句總結選擇語句包括if-else語句和case語句,是可綜合電路設計中最常使用的語句。選擇語句必須在initial和always語句塊中使用。在always語句塊內,如果在給定的條件下變量沒有賦值,這個變量將保持原值,也就是說會生成一個鎖存器。下面對選擇語句的使用作一些總結。(1)選擇語句。條件語句if和多路分支語句case只能用在always語句塊中,也就是只能用在行為建模中。if條件語句和case語句都屬于選擇語句。case語句與if…else語句可以很容易地相互轉換,但與case語句中的控制表達式和多分支表達式的結構相比,if…else結構中的條件表達式更為直觀一些。case語句經常用于實現基于真值表的組合邏輯電路設計和基于狀態機的時序邏輯電路設計。(2)鎖存器。前面在介紹case語句時已經介紹了鎖在器的知識點,下面對該知識點作一個總結。if-else和case這兩種分支語句經常會產生Latch。Latch就是鎖存器,是一種在異步電路系統中,對輸入信號電平敏感的單元,用來存儲信息。鎖存器在數據未鎖存時,輸出端的信號隨輸入信號變化,就像信號通過一個緩沖器,一旦鎖存信號有效,則數據被鎖存,輸入信號不起作用。可能產生Latch的幾種情況包括:①

組合邏輯中if-else條件分支語句缺少else語句。②

組合邏輯中case條件分支語句條件未完全列舉,且缺少default語句。③

組合邏輯中輸出變量賦值給自己。解決辦法如下:①if-else要涵蓋所有可能。②case語句列舉所有條件,如果不能列出所有條件,則應添加default語句。(3)選擇語句的使用原則。硬件電路設計過程中,對變量賦值應考慮各種情況,即針對各種情況變量的結果都要進行明確的說明。下面用兩段代碼完成同一功能的示例來進行說明。推薦的設計代碼如下:上面的示例中,兩段代碼都是正確的。但推薦的設計代碼說明了在各種情況下cnt的取值;而不推薦的設計代碼中沒有明確說明各種情況下cnt的取值,需要讀者進一步分析代碼,才能理解cnt的變化情況。任務4.4?循

句在VerilogHDL中常用的可綜合的循環語句有repeat和for,用來控制執行語句的執行次數。repeat用于將一條語句連續執行n次。for通過以下三個步驟來決定語句的循環執行:①

先給控制循環次數的變量賦初值。②

判定控制循環的表達式的值,如為假,則跳出循環語句;如為真,則執行指定的循環語句后,轉到第③步。③

執行一條賦值語句來修正控制循環變量次數的變量的值,然后返回第②步。下面對兩種循環語句進行詳細的介紹。一、for語句for語句的一般形式為for(表達式1;表達式2;表達式3)語句;它的執行過程如下:(1)求解表達式1。(2)求解表達式2,若其值為真(非0),則執行for語句中指定的內嵌語句,然后執行下面的第(3)步。若為假(0),則結束循環,轉到第(5)步。(3)若表達式為真,在執行指定的語句后,求解表達式3。(4)轉回上面的第(2)步,繼續執行。(5)執行for語句下面的語句。下面使用for循環語句實現由加法運算來完成乘法運算的功能。【例4-11】

使用for循環語句實現一個參數化的多位乘法器。綜合得到的電路圖如圖4-9所示。上述電路設計中涉及的知識點有for語句和begin/end順序塊。下面對這些知識點進行說明。(1)?for語句。for語句用于循環操作,例4-11就是采用了加法和移位這個循環操作來實現乘法的。在for語句中,循環變量的增值表達式可以不必是一般的常規加1或減1表達式。(2)?begin/end順序塊。begin/end塊語句相當于復合語句,可以看作一條語句。若在順序塊中定義變量,則需要給順序塊命名,如例4-11中的順序塊命名為mult。例4-11在命名順序塊中定義的變量j,一方面用作循環計數,另一方面也用作移位運算符的操作數。二、repeat語句repeat語句的格式如下:

下面的示例中使用repeat循環語句實現例4-11同樣的功能。【例4-12】使用repeat循環語句及加法和移位操作來實現一個參數化的多位乘法器。例4-12綜合得到的電路圖跟使用for循環中例4-11得到的電路圖完全一致。上述電路設計中涉及的知識點是repeat語句。下面對這些知識點進行說明。(1)例4-12使用repeat循環來代替for循環來實現乘法功能,二者的原理相同,但在實現形式上有所區別。(2)在repeat語句中,其表達式通常為常量表達式。repeat(size)中表達式size的值為常值4。下面使用for循環語句來實現8位移位寄存器。【例4-13】8位移位寄存器。程序說明如下:(1)例4-13使用兩種方法實現8位移位寄存器,其中q1使用普通方法實現,q2使用for語句實現。兩種方法原理相同,便于讀者理解for語句的功能。(2)例4-13使用了for語句,讀者可以很方便地使用repeat進行替換。(3)綜合得到的電路圖如圖4-10所示。(4)上述設計的測試代碼如例4-14所示。【例4-14】8位移位寄存器測試臺。

與仿真代碼相應的仿真波形如圖4-11所示。從圖4-11的仿真波形圖可以看出,移位寄存器設計正確。上述電路設計和電路仿真中涉及的知識點是循環語句、組合邏輯。下面對這些知識點進行說明。(1)循環語句。for語句、repeat語句都是可綜合的循環語句,都用于循環操作,并且在實際應用中兩者可以互相替換。(2)組合邏輯。循環語句實現的是組合邏輯電路,會耗用大量的硬件資源和時間。循環語句完成的功能越復雜,則該組合邏輯耗用的時間就越多,會大大降低系統的工作頻率。為了提高系統的工作頻率,讀者在設計中應盡量避免使用循環語句。三、循環語句總結VerilogHDL是一種硬件描述語言,如果期望在代碼中實現,則需要EDA工具將其翻譯成基本的門邏輯,而在硬件電路中并沒有循環電路的原型,因此,在使用循環語句時應時刻注意其可綜合性。循環語句包括可綜合的和不可綜合的。for語句、repeat語句都是可綜合的循環語句;while語句是不可綜合的循環語句。電路設計需要使用可綜合的循環語句,而使用最多的是for語句,其他可綜合的循環語句使用較少。因此,在可綜合的設計中,建議讀者僅使用for循環語句。對于硬件電路來說,循環語句屬于組合邏輯,會耗費大量的硬件資源。因此,在設計電路時應較少使用。設計電路時需考慮面積和速度這兩個因素,如果要提高電路的工作頻率,通常是將循環語句轉換成狀態機建模或者流水線建模來完成相應的功能。另外,對于不可綜合循環語句while,實現的功能也可以采用類似的處理辦法予以綜合實現。循環語句使用的指導原則是:雖然基于循環語句的VerilogHDL設計顯得相對簡單,且閱讀起來比較容易,但面向硬件和軟件設計的關注點是不一樣的,硬件設計并不追求代碼的短小,而是設計的時序、面積和性能等特征。在電路設計中應使用狀態機建模或者流水線建模來代替for循環。任務4.5?塊語句(begin/end)關鍵字begin和end用于將多條語句組成順序塊。順序塊的格式如下:其中,塊名即該塊的名字,是一個標識名。塊內聲明語句可以是參數聲明語句、reg型變量聲明語句、integer型變量聲明語句、real型變量聲明語句等。塊語句通常用來將兩條或多條語句組合在一起,使它們更像一條語句,類似于C語言中的復合語句。Verilog語言中可綜合的塊語句為順序塊,關鍵字begin和end用于將多條語句組成順序塊。順序塊具有以下特點:(1)順序塊中的語句是一條接一條按順序執行的,只有前面的語句執行完成之后才能執行后面的語句(非阻塞賦值語句除外)。(2)嵌套塊:塊可以嵌套使用。(3)命名塊:塊可以具有自己的名字,稱之為命名塊。在命名塊中可以聲明局部變量,命名塊是設計層次的一部分,命名塊中聲明的變量可以通過層次名引用進行訪問。下面是一個使用命名塊的示例,其功能是使用異或運算符對D完成縮位異或,并檢測D中1的個數。【例4-15】

完成使用異或運算符對D完成縮位異或運算和檢測D中1的個數這兩個功能。程序說明如下:(1)本例使用了for循環語句對D的各位進行運算。(2)本例使用了begin/end塊語句。塊語句相當于復合語句,可以看作一條語句。(3)本例定義了3個命名塊。其中,塊block1和塊xor_block、塊Count_block是嵌套關系。塊xor_block的功能是完成縮位異或,塊Count_block的功能是完成檢測D中1的個數。(4)在命名塊xor_block中聲明的局部變量I和在命名塊Count_block中聲明的局部變量J,都用于循環計數。需要說明的是,如果在塊中使用局部變量,則必須對該塊進行命名。任務4.6?任務和函數語句一、task語句task和function說明語句分別用來定義任務和函數。利用任務和函數可以把一個較大的程序模塊分解成多個較小的任務和函數,以便于理解和調試。輸入/輸出和總線信號的值可以傳入/傳出任務和函數。任務和函數往往是大的程序模塊中在不同地點多次用到的相同的程序段。學會使用task和function語句可以簡化程序的結構,使程序明白易懂,是讀者編寫較大型模塊的基本功。VerilogHDL函數和任務在綜合時被理解成具有獨立運算功能的電路,每調用一次函數和任務就相當于改變這部分電路的輸入,以得到相應的計算結果。下面分別通過任務和函數來實現對輸入數進行按位逆序后輸出。【例4-16】

用任務實現輸入數據按位逆序后輸出的功能。程序說明如下:(1)本例說明了怎樣定義任務和調用任務。開始于task而結束于endtask的部分定義了一個任務。定義的任務語法如下:這些聲明語句的語法與模塊定義中對應的聲明語句的語法是一致的。(2)reverse_bits(D,Q);的功能是調用任務并傳遞輸入/輸出變量給任務。調用任務并傳遞輸入/輸出變量的聲明語句的語法如下:<任務名>(端口1,端口2,…,端口n);本例中,任務調用變量(D,Q)和任務定義的I/O變量(data,result)之間是一一對應的。當任務啟動時,由D傳入的變量賦給了data,而當任務完成后的輸出又通過result賦給了Q。(3)如果傳給任務的變量值和任務完成后接收結果的變量已定義,則可以用一條語句啟動任務。任務完成以后,控制會傳回啟動過程。二、function語句使用任務完成的可綜合的模塊也可以由函數來實現。例4-17就是使用函數對例4-16進行了重新改寫。【例4-17】

用函數實現輸入數據位逆序后輸出的功能。程序說明如下:(1)本例說明了怎樣定義函數和調用函數。開始于function而結束于endfunction的部分定義了一個函數。定義的函數語法如下:注意:<返回值的類型或范圍>這一項是可選項,如缺省,則返回值為一位寄存器類型數據。這些聲明語句的語法與模塊定義中對應的聲明語句的語法是一致的。(2)?Q<=reverse_bits(D);的功能是調用函數并傳遞輸入變量給函數,函數的調用是通過將函數作為表達式中的操作數來實現的。在函數中,reverse_bits被賦予的值就是函數的返回值。函數的定義聲明了與函數同名的、函數內部的寄存器。如果在函數的聲明語句中<返回值的類型或范圍>為缺省,則這個寄存器是一位的,否則是與函數定義中<返回值的類型或范圍>一致的寄存器。函數的定義把函數返回值所賦值寄存器的名稱初始化為與函數同名的內部變量。調用函數并傳遞輸入/輸出變量的聲明語句的語法如下:<函數名>(<表達式><,<表達式>>*)其中,函數名作為確認符。本例中,函數調用變量(D,Q)和函數定義的I/O變量(data,reverse_bits)之間是一一對應的。當函數啟動時,由D傳入的變量賦給了data,而函數完成后的輸出又通過reverse_bits賦給了Q。(3)如果傳給函數的變量值和函數完成后接收結果的變量已定義,則可以用一條語句啟動函數。函數完成后,控制會傳回啟動過程。例4-16和例4-17兩個示例對應的仿真代碼如例4-18所示。【例4-18】

函數和任務的測試代碼。

仿真波形如圖4-12所示。從圖4-12的仿真波形可以看出,兩個示例均實現了位逆序的功能。上述電路設計和電路仿真中涉及的知識點有task語句、function語句。下面對這些知識點進行說明。(1)任務和函數的相同點。任務和函數在完成一些電路或者功能實現時是可以相互替換的(如例??4-18),使用時應注意兩者在輸入和輸出時的一些規則。(2)任務和函數的區別。①

任務能調用其他函數,而函數不能調用任務。②

函數只能與主模塊共用同一個仿真時間單位,而任務可以定義自己的仿真時間單位。③

函數至少要有一個輸入變量,而任務可以沒有或有多個任何類型的變量。④

任務可以啟動其他的任務,其他任務又可以啟動別的任務,可以啟動的任務數是沒有限制的。不管有多少任務啟動,只有當所有的啟動任務完成以后,控制才能傳回啟動過程。⑤

函數的目的是通過返回一個值來響應輸入信號的值。任務卻能支持多種目的,計算多個結果值,而這些結果值只能通過被調用的任務的輸出或總線端口輸出。⑥VerilogHDL模塊使用函數時是把它當作表達式中的操作符,這個操作符的結果值就是這個函數的返回值。也就是說,函數返回一個值,而任務則不返回值。例如,定義一個任務或函數,對一個16位的字進行操作讓高字節與低字節互換,把它變為另一個字(假定這個任務或函數名為switch_bytes)。任務返回的新字是通過輸出端口的變量,因此,16位字字節互換任務的調用方法為switch_bytes(old_word,new_word);。任務switch_bytes把輸入old_word的高、低字節互換放入new_word端口輸出。而函數返回的新字是通過函數本身的返回值,因此,16位字高、低字節互換函數的調用方法為new_word=switch_bytes(old_word);。與任務相比,函數的使用有較多的約束。例如,函數的定義不能包含任何的時間控制語句,即任何用#、@或wait來標識的語句;函數不能啟動任務;定義函數時至少要有一個輸入參量;在函數的定義中必須有一條賦值語句給函數中的一個內部變量賦以函數的結果值,該內部變量具有和函數名相同的名字。任務4.7?流水線設計數字系統的工作頻率要滿足以下公式:其中,Tco為發端寄存器Q時鐘到輸出時間;Tlogic為組合邏輯延遲;Trouting為兩級寄存器之間的布線延遲;Tsu為接收端寄存器建立時間;Tskew為兩級寄存器的時鐘歪斜,其值等于時鐘統一邊沿到達兩個寄存器時鐘端口的時間差;Tclk為系統所能達到的最小時鐘周期。該公式可結合圖4-13來理解。因此,要提升系統的工作頻率,就需要考慮降低不等式右邊的值。本任務所描述的流水線設計的主要目的就是降低組合邏輯延遲,從而提升整個數字系統的工作頻率。流水線工作原理可以用圖4-14進行說明。圖4-14中,組合邏輯運算(in+a)*b/c被拆分成3個運算。假設in?+?a的運算時間為t1,out1*b的運算時間為t2,out2/c的運算時間為t3,則運算(in+a)*b/c的運算時間為t1?+?t2?+?t3。顯然,max(t1,t2,t3)?<?t1?+?t2?+?t3,這樣就減少了寄存器間的組合邏輯延遲Tlogic,進而降低了系統所能達到的最小時鐘周期Tclk,也就是提升了系統的工作頻率。流水線通常將順序執行的阻塞賦值計算轉化為多周期完成的賦值,這樣就將單步順序計算拆分為多個并行計算,每步計算量減小,從而使所需要的時鐘周期減小,也就是提升了系統的工作頻率。下面用一個示例來說明流水線設計的實現方式和特點。【例4-19】

用普通循環語句實現1?+?2?+?3?+?…?+?9。下面對例4-19電路設計代碼作一些說明。(1)由于循環語句求和功能在一個時鐘周期內即可完成,因此,需要增加一個使能信號en,并且該信號的有效電平時間僅包含一個時鐘上升沿,該信號有效時才進行求和操作。(2)?for循環語句求和是組合邏輯電路,需要耗費的時間較長,因此,該設計的時鐘clk的工作頻率不能太高。(3)綜合得到的電路圖如圖4-15所示。從圖4-15中可以看出,組合邏輯是多個加法器的級聯,耗時是每個加法器的運算時間之和。【例4-20】

用流水線建模實現1?+?2?+?3?+?…?+?9。下面對上述電路設計代碼作一些說明。(1)使用流水線求和,也需要一個使能信號en,當該信號有效時即啟動求和操作。全部求和完成后,還需要一個結束標志flag。(2)?flag有效時,完成求和功能。flag有效的標志是當en有效時,flag無效的時候是加數超過9時。(3)流水線求和是時序邏輯電路,將原來組合邏輯電路求和的時間分散到10個周期內進行,因此,該設計的時鐘clk的工作頻率相對較高。(4)綜合得到的電路圖如圖4-16所示。從圖4-16中可以看出,每一級寄存器間的組合邏輯就是完成一次加法,但這需要多級寄存器。【例4-21】

測試代碼。仿真波形如圖4-17所示。循環語句實現的求和功能可以在一個時鐘周期內完成,而流水線設計則需要10個時鐘周期。上述電路設計和電路仿真中涉及的知識點有流水線、循環語句。下面對這些知識點進行說明。(1)流水線。本代碼將兩種實現方式在同一測試臺進行輸出結果對比。兩種實現方式輸入激勵完全相同,因此,放在一起測試不會添加任何工作量,只需要多一個例化語句即可。同時,輸出可以放在一起進行比較。由于采用循環語句求和在一個時鐘周期內完成,因此,使能信號en的有效電平時間包含一個時鐘上升沿即可。(2)流水線的效果。上述設計在沒添加任何約束的情況下,在QuartusⅡ

軟件上綜合實現后,可以查看到最大工作頻率。使用流水線的系統最大工作頻率如圖4-18所示。沒使用流水線的系統最大工作頻率如圖4-19所示由以上結果可知,使用流水線前后最大工作頻率相差3倍多。這種查看最大工作頻率的方法僅用于定性比較使用流水線前后的性能。不同的流水線,對系統性能的提升是不同的,需要單獨分析。若想得到更加準確的最大工作頻率,則需要進行精準的時序約束,包括系統時鐘頻率約束、輸入時序約束、輸出時序約束、管腳間時序約束等。讀者也可以使用Vivado得到最大工作頻率。在Vivado軟件中,要得到最大工作頻率,需要先進行時鐘約束,實現后即可查看最大工作頻率。感興趣的讀者可自行實驗,此處不再贅述。(3)流水線的優缺點。采用流水線既會增大資源的使用,也可降低寄存器間的傳播延時,保證系統維持高的系統時鐘速度。因此,在實際應用中,需要綜合考慮資源的使用和速度的要求,根據實際情況來選擇流水線的級數,以滿足設計需要。利用流水線式的設計方法可大大提高系統的工作速度。這種方法可廣泛應用于各種設計,特別是大型的、對速度要求較高的系統設計。(4)流水線和循環語句的關系。可綜合的循環語句在實現電路時會占用大量組合邏輯資源,因此,在面積緊張的情況下,可以考慮采用流水線來實現循環語句。雖然,while循環是不可綜合的,但算法中如果有使用while循環才能實現的功能,則這部分功能可以用流水線技術來實現。另外,從流水線的設計原理可以看出,使用C語言實現或驗證某種算法后,可以很容易地使用VerilogHDL語言轉換成硬件。通常情況下,使用C語言實現的軟件功能都可以使用硬件來實現。任務5.1同步有限狀態機引例

任務5.2狀態機的基本概念

任務5.3狀態機的編碼方法有限狀態機及其設計技術是實用數字系統設計的重要組成部分,也是實現高效率、高可靠性邏輯控制的重要途徑。有限狀態機廣泛應用于硬件控制電路設計,它把復雜的控制邏輯分解成有限個穩定狀態,在每個狀態上判斷并處理事件,變連續處理為離散數字處理。有限狀態機雖然僅有有限個狀態,但這并不意味著其只能進行有限次的處理,相反,有限狀態機是閉環系統,有限無窮,可以用有限的狀態處理復雜的事務。使用狀態機建模的電路有計數器、序列檢測器等。任務5.1?同步有限狀態機引例狀態機特別適合描述那些發生有先后順序或者有邏輯規律的事情。狀態機的本質就是對具有邏輯順序或時序規律事件的一種描述方法,邏輯順序和時序規律是狀態機所要描述的核心和強項。換言之,所有具有邏輯順序和時序規律的事情都適合用狀態機來描述。很多初學者不知道何時應用狀態機,這里介紹一種應用思路:從狀態變量入手。如果一個電路具有時序規律或者邏輯順序,則自然而然地可對這個電路規劃出狀態,從這些狀態入手,分析每個狀態的輸入、轉移和輸出,從而完成電路功能。使用狀態機的目的是控制某部分電路,完成某種具有邏輯順序或時序規律的電路設計。其實對于邏輯電路而言,小到一個簡單的時序邏輯,大到復雜的微處理器,都適合用狀態機的方法進行描述。由于狀態機不僅僅是一種電路描述工具,它更是一種思想方法,而且狀態機的HDL語言表達方式比較規范,有章可循,所以很多有經驗的設計者習慣用狀態機的思想進行邏輯設計,對各種復雜設計都套用狀態機的設計理念,從而提高設計的效率和穩定性。下面通過一個典型時序邏輯電路的設計實例來引入有限狀態機。【例5-1】

設計一個串行數據檢測器。電路的輸入信號A是與時鐘脈沖同步的串行數據,其時序關系如圖5-1所示。輸出信號為Y,要求電路在信號輸入A出現110序列時輸出信號Y為1,否則為0。這是一道典型的時序邏輯電路例題,其求解步驟如圖5-2所示。下面詳細介紹邏輯電路的設計步驟。(1)理解題意,由給定的邏輯功能建立原始狀態圖,如圖5-3所示。圖5-3中,S表示狀態;A/Y中斜杠左面的為輸入,斜杠右面的為輸出。(2)狀態化簡。合并等價狀態,消去多余狀態的過程稱為狀態化簡。所謂等價狀態,就是指在相同的輸入下有相同的輸出,并轉換到同一個次態的兩個狀態。顯然,圖5-3中的a和d是等價狀態,可以合并。化簡后的狀態圖如圖5-4所示。(3)狀態編碼。給每個狀態賦以二進制代碼的過程,稱為狀態編碼。對圖5-4的狀態進行某種編碼的結果如圖5-5所示。圖5-5所示狀態圖對應的狀態表如表5-1所示。(4)選擇觸發器的個數和類型。觸發器個數可根據狀態數確定,要求滿足2n-1<M≤2n。式中,M為狀態數,n為觸發器的個數。對于例5-1,已知M為3,所以可求出觸發器的個數為2。觸發器選擇D觸發器。(5)求出電路的激勵方程和輸出方程。根據表5-1可列出狀態轉換真值表及激勵信號,如表5-2所示。針對輸出和激勵信號,采用卡諾圖化簡,如圖5-6所示。利用多余狀態,卡諾圖化簡后的激勵方程和輸出方程為(6)畫出邏輯圖(見圖5-7)并檢查自啟動能力。經檢查,該電路具有自啟動能力。至此,該串行數據檢測器設計完畢。使用狀態機建模時,步驟(1)可理解為Moore狀態機;步驟(2)可理解為Mealy狀態機;步驟(3)為狀態編碼;步驟(4)~(6)不需要人工完成,由計算機來完成。針對步驟(1),可以使用HDL代碼實現Moore狀態機,如例5-2所示。【例5-2】

對應于例5-1中步驟(1)的同步狀態機。上述電路設計涉及的知識點有狀態轉移圖、狀態編碼、多進程狀態機、狀態機建模。下面對這些知識點進行說明。(1)狀態轉移圖。例5-2對應的狀態轉移圖如圖5-8所示。狀態圖的轉換條件如表5-3所示。(2)狀態編碼。parameters0=2'b00,s1=2'b01,s2=2'b10,s3=2'b11;?是狀態賦值語句,也就是狀態編碼。在VerilogHDL中,狀態必須明確賦值,通常使用參數(parameters)或宏定義(define)語句加上賦值語句來實現。例5-2就是采用參數加上賦值語句來實現的。當然也可以采用宏定義的方式來實現,如可定義為`defines02'b00則意味著s0的狀態碼是2'b00。在引用宏定義的狀態時,需要使用符號“`”。例如,程序中要使用狀態s0,則要寫成`s0。例5-2使用的狀態編碼方式為順序編碼,除了可使用這種編碼方式之外,還可以使用獨熱編碼、直接輸出型編碼、格雷編碼等。(3)多進程狀態機。例5-2實現的狀態機為單進程狀態機,除此之外,還有雙進程和多進程的實現方式。(4)狀態機建模。在進行電路設計時,通過數字電路的知識手工求解,難度稍大,也不能充分利用和體現EDA強大的功能;而使用狀態機建模來實現設計,只需要根據題意,得出狀態圖,然后直接使用硬件描述語言來描述狀態圖,無須利用過多的數字電路知識,充分利用了EDA強大的功能。任務5.2?狀態機的基本概念一、狀態機的基本描述方式在邏輯設計中,狀態機的基本描述方式有三種,分別是使用狀態轉移圖、狀態轉移列表、HDL語言描述狀態機。(1)使用狀態轉移圖描述狀態機。狀態轉移圖是描述狀態機的最自然的方式。狀態轉移圖經常用于在設計規劃階段定義邏輯功能,也可以用于分析代碼中的狀態機,通過圖形化的方式有助于理解設計意圖。(2)使用狀態轉移列表描述狀態機。使用狀態轉移列表描述狀態機是用列表的方式描述狀態機,是數字邏輯電路常用的描述方法之一。狀態轉移列表經常用于對狀態進行化簡。對于可編程邏輯設計,由于可用邏輯資源比較豐富,而且狀態編碼要考慮設計的穩定性、安全性等因素,所以并不經常使用狀態轉移列表優化狀態。(3)使用HDL語言描述狀態機。使用HDL語言描述狀態機是本章討論的重點,使用HDL語言描述狀態機既有章可循,又有一定的靈活性。通過一些規范的描述方法,可以使HDL語言描述的狀態機更安全、穩定、高效,易于維護。在VerilogHDL中可以用多種方法來描述有限狀態機,最常用的方法是用always塊和case語句。二、狀態機的基本要素及分類狀態機有三個基本要素,分別是狀態、輸出和輸入。(1)狀態:也叫狀態變量。在邏輯設計中,使用狀態劃分邏輯順序和時序規律。比如,在設計空調控制電路時,可以將環境溫度的不同作為狀態。(2)輸出:指在某一個狀態時特定發生的事件。例如,設計空調控制電路中,如果環境溫度高于設定溫度環境限值,則控制電機正轉進行降溫處理;如果環境溫度低于設定溫度環境限值,則控制電機反轉進行升溫處理。(3)輸入:指狀態機中進入每個狀態的條件。有的狀態機沒有輸入條件,其中的狀態轉移較為簡單;有的狀態機有輸入條件,當某個輸入條件存在時才能轉移到相應的狀態。根據狀態機的輸出是否與輸入條件相關,狀態機可分為兩類:Moore型狀態機和Mealy型狀態機。Mealy型狀態機的輸出是狀態向量和輸入的函數,其結構如圖5-9(a)所示。也就是說,Mealy型狀態機的輸出不僅依賴于當前狀態,而且取決于該狀態的輸入條件。Moore狀態機的輸出僅是狀態向量的函數,結構如圖5-9(b)所示。也就是說,Moore狀態機的輸出僅僅依賴于當前狀態,而與輸入條件無關。狀態機可以按是否有一個公共的時鐘控制(鐘控)分為同步狀態機和異步狀態機,如果具有鐘控則為同步狀態機,反之則為異步狀態機。根據狀態機的數量是否為有限個,可將狀態機分為有限狀態機和無限狀態機。三、單進程、雙進程和多進程狀態機描述狀態機時關鍵是要描述清楚狀態機的要素,即如何進行狀態轉移,每個狀態的輸出是什么,狀態轉移是否和輸入條件相關等。一個有限狀態機可以被分成次態譯碼、狀態寄存器、輸出譯碼三個模塊,也可以用五種不同的方式將這些模塊分配到進程語句中,以實現對狀態機的描述。(1)三個模塊用一個進程實現。也就是說,3個模塊均在1個always塊內,這種狀態機描述稱為單進程有限狀態機。在單進程狀態機中,既描述狀態轉移,又描述狀態的寄存和輸出。(2)每一個模塊分別用一個進程實現。也就是說,3個模塊對應著3個always塊,這種狀態機描述稱為三進程有限狀態機。在三進程狀態機中,一個always模塊采用同步時序描述狀態轉移,另一個模塊采用組合邏輯判斷狀態轉移條件,描述狀態轉移規律,第三個always模塊使用同步時序電路描述每個狀態的輸出。(3)次態譯碼、輸出譯碼分配在一個進程中,狀態寄存器用另一個進程描述。(4)次態譯碼、狀態寄存器分配在一個進程中,輸出譯碼用另一個進程描述。(5)次態譯碼用一個進程描述,狀態寄存器、輸出譯碼分配在另一個進程中。在后三種狀態機描述中,3個模塊對應著2個always塊,這種狀態機描述稱為雙進程有限狀態機。對于上面5種描述狀態機的方法,優先推薦采用第二種方法,其次推薦采用第四種方法,不推薦采用第一、三、五種方法。其原因是:FSM和其他設計一樣,最好采用同步時序方式設計,以提高設計的穩定性,消除毛刺。狀態機實現后,一般來說,狀態轉移部分是同步時序電路,而狀態的轉移條件的判斷是組合邏輯,第二種方法將同步時序和組合邏輯分別放到不同的always程序塊中實現,不僅便于閱讀、理解、維護,更重要的是有利于綜合器優化代碼,有利于用戶添加合適的時序約束條件,有利于布局布線器實現設計。第四種方法將同步時序和組合邏輯放在一個always程序塊中實現,代碼簡潔,同時可以達到與第二種相同的效果。而第一種方法描述不利于時序約束、功能更改、調試等,而且不能很好地表示Mealy

溫馨提示

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

評論

0/150

提交評論