最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

1.3VERILOG-明德?lián)P至簡設(shè)計法原理與應(yīng)用

2022-12-21 10:24 作者:明德?lián)P易老師  | 我要投稿


第三章 ?VERILOG

4?Verilog HDL基本語句

4.1?順序塊語句

語句塊塊提供將兩條或更多條語句組合成語法結(jié)構(gòu)上相當(dāng)于一條語句的機(jī)制。這里主要講Verilog HDL的順序語句塊(begin . . . end):語句塊中的語句按給定次序順序執(zhí)行。順序語句塊中的語句按順序方式執(zhí)行。每條語句中的時延值與其前面的語句執(zhí)行的模擬時間相關(guān)。一旦順序語句塊執(zhí)行結(jié)束,跟隨順序語句塊過程的下一條語句繼續(xù)執(zhí)行。順序語句塊的語法如下:



假定順序語句塊在第10個時間單位開始執(zhí)行。兩個時間單位后第1條語句執(zhí)行,即第12個時間單位。此執(zhí)行完成后,下1條語句在第17個時間單位執(zhí)行(延遲5個時間單位)。然后下1條語句在第20個時間單位執(zhí)行,以此類推。該順序語句塊執(zhí)行過程中產(chǎn)生的波形如圖:



圖?33


4.2?連續(xù)賦值語句

數(shù)據(jù)流的描述是采用連續(xù)賦值語句(assign)語句來實現(xiàn)的。語法如下:

assign ???net_type ??=?表達(dá)式;

連續(xù)賦值語句用于組合邏輯的建模。等式左邊是wire類型的變量。等式右邊可以是常量、由運算符如邏輯運算符、算術(shù)運算符參與的表達(dá)。如下幾個實例:

注意如下幾個方面:
1、連續(xù)賦值語句的執(zhí)行是:只要右邊表達(dá)式任一個變量有變化,表達(dá)式立即被計算,計算的結(jié)果立即賦給左邊信號。


2、連續(xù)賦值語句之間是并行語句,因此與位置順序無關(guān)。

4.3?條件語句

4.3.1?條件語句?if

語句的語法如下:

如果對condition_1?條件滿足,不管condition_2是否滿足,都執(zhí)行procedural_statement_1,procedural_statement_2和procedural_statement_3都不執(zhí)行。

如果condition_1不滿足而condition_2滿足,則執(zhí)行procedural_statement_2,procedural_statement_1和procedural_statement_3都不執(zhí)行。

如果condition_1不滿足并且condition_2也不滿足時,執(zhí)行procedural_statement_3,procedural_statement_1和procedural_statement_2都不執(zhí)行。

以下是一個例子。

注意條件表達(dá)式必須總是被括起來,如果使用if - if - else?格式,那么可能會有二義性,如下例所示:

問題是最后一個else?屬于哪一個if??它是屬于第一個if?的條件(Clk)還是屬于第二個if的條件?(Reset)??這在Verilog HDL?中已通過將else?與最近的沒有else?的if?相關(guān)聯(lián)來解決。在這個例子中,?else?與內(nèi)層if?語句相關(guān)聯(lián)。以下是另一些if?語句的例子。


書寫建議:

1、條件表達(dá)式需用括號括起來。

2、若為if - if?語句,請使用塊語句?begin --- end?:


以上兩點建議是為了使代碼更加清晰,防止出錯。





4.3.2?條件語句?case



case語句首先對條件表達(dá)式case_expr?求值,然后依次對各分支項求值并進(jìn)行比較,第一個與條件表達(dá)式值相匹配的分支中的語句被執(zhí)行。可以在1?個分支中定義多個分支項;這些值不需要互斥。缺省分支覆蓋所有沒有被分支表達(dá)式覆蓋的其他分支。例:



書寫建議:?case?的缺省項必須寫,防止產(chǎn)生鎖存器。


4.4?過程語句

Verilog HDL中提供兩種過程賦值語句initial和always語句,用這兩種語句來實現(xiàn)行為的建模。這兩種語句之間的執(zhí)行是并行的,即語句的執(zhí)行與位置順序無關(guān)。這兩種語句通常與語句塊(begin ....end)相結(jié)合,則語句塊中的執(zhí)行是按順序執(zhí)行的。


4.4.1?initial?語句

initial語句只執(zhí)行一次,即在設(shè)計被開始模擬執(zhí)行時開始(0時刻)。通常只用在對設(shè)計進(jìn)行仿真的測試文件中,用于對一些信號進(jìn)行初始化和產(chǎn)生特定的信號波形。語法如下:(大家只要先有個概念就可以)




事例如上產(chǎn)生一個信號波形:

再次強(qiáng)調(diào),initial語句只用于仿真測試,一般不會用到設(shè)計代碼中。





4.4.2?always?語句

需要看對應(yīng)的視頻,請點擊視頻編號::001100000068

1、本節(jié)介紹時序邏輯代碼(即always語句),分位同步復(fù)位的時序邏輯和異步復(fù)位的時序邏輯,本教學(xué)統(tǒng)一采用異步時鐘邏輯。
2、這是ALTERA和VIVADO文檔

always語句與initial語句相反,是被重復(fù)執(zhí)行,執(zhí)行機(jī)制是通過對一個稱為敏感變量表的事件驅(qū)動來實現(xiàn)的,下面會具體講到。




always是“一直、總是”的意思,@后面跟著事件。整個always的意思是:當(dāng)敏感事件的條件滿足時,就執(zhí)行一次“程序語句”。每敏感事件每滿足一次,就執(zhí)行“程序語句”一次。


這段程序的意思是,當(dāng)信號a或者信號b或者信號d發(fā)生變化時,就執(zhí)行一次下面語句。在執(zhí)行該段語句時,首先判斷信號sel是否為0,如果為0,則執(zhí)行第783行代碼;如果sel不為0,則執(zhí)行第785行代碼。需要強(qiáng)調(diào)的是,a、b、c任意一個發(fā)生變化一次,782行至785行也只執(zhí)行一次,不會執(zhí)行第二次的。

注意到的是,sel這個信號變化時,是不會執(zhí)行第782行到785行代碼的。通常這不符合設(shè)計者的想法。例如,一般想法是當(dāng)sel為0時,c的結(jié)果是a+b;當(dāng)sel不為0時,c的結(jié)果是a+d。但如果sel由0變1之后,c的結(jié)果a+b。總之,這不是一個規(guī)范的設(shè)計思維。

一般設(shè)計者的想法是:當(dāng)信號a或者信號b或者信號d或者信號sel執(zhí)行變化時,就執(zhí)行782行至785行。這樣就確保,當(dāng)sel為0時,c的結(jié)果一定為a+b;當(dāng)sel不為0時,c的結(jié)果一定是a+d。所以要在敏感列表中加上sel,如下面代碼。


當(dāng)敏感信號非常多時,很容易就會把敏感信號遺漏,為避免這種情況,可以用“*”來代替。這個“*”是指“程序語句”中所有的條件信號,也就是a、b、d、sel(不包括c)發(fā)生變化。明德?lián)P也推薦這種寫法。



這種條件信號變化,結(jié)果立即變化的always,我們稱之為“組合邏輯”。


這段代碼敏感列表是“posedge clk”,其中posedge表示上升沿。也就是說,當(dāng)clk由0變成1的瞬間,執(zhí)行一次程序代碼:第806至809行。其他時候,c的值保持不變。要特別強(qiáng)調(diào)的是,如果clk沒有由0變成1,那么即使a、b、d、sel發(fā)生變化,c的值也是不變的。


這段代碼的敏感列表是“negedge clk”,其中negedg表示下降沿。也就是說,當(dāng)clk由1變成0的瞬間,執(zhí)行一次程序代碼:第806至809行。其他時候,c的值保持不變。要特別強(qiáng)調(diào)的是,如果clk沒有由1變成0,那么即使a、b、d、sel發(fā)生變化,c的值也是不變的。


這段代碼的敏感列表是“posedge clk or negedge rst_n”,也就是說,當(dāng)clk由0變成1的瞬間,或者rst_n由1變化0的瞬間,執(zhí)行一次程序代碼:第814至820行。其他時候,c的值保持不變。

我們把這種信號邊沿觸發(fā),即信號上升沿或者下降沿才變化的always,稱之為“時序邏輯”。而那個信號clk是時鐘。注意,識別是不是時鐘,不是看名稱,而是看這個信號放在哪里。如放在敏感列表并且是邊沿觸發(fā)的,才是時鐘。而信號rst_n是復(fù)位信號,也不是看名字,而是它放在敏感列表里,并且也是邊沿觸發(fā),更關(guān)鍵的是“程序語句”首先判斷了rst_n的值,也就是優(yōu)先級最高,一般都是用于復(fù)位使用的。

注意以下幾點:

1、對組合邏輯的always?語句,敏感變量必須寫全,或者用“*”代替。

2、對組合邏輯器件的賦值采用阻塞賦值“=;時序邏輯器件的賦值語句采用非阻塞賦值“<=”;具體原因請看“阻塞賦值和非阻塞賦值”一節(jié)內(nèi)容。


4.5?阻塞賦值和非阻塞賦值

需要看對應(yīng)的視頻,請點擊視頻編號:001100000072

1、本節(jié)介紹在always語句塊中,verilog語言支持的兩種類型的賦值:阻塞賦值(=)和非阻塞賦值(<=),前者表示順序執(zhí)行,后者表示并行執(zhí)行。
2、這是ALTERA和VIVADO文檔

在always語句塊中,verilog語言支持兩種類型的賦值:阻塞賦值和非阻塞賦值。阻塞賦值使用“=”語句;非阻塞賦值使用“<=”語句。

阻塞賦值:在一個begin end的多行賦值語句,是先執(zhí)行當(dāng)前行的賦值語句,再執(zhí)行下一行的賦值語句。

非阻塞賦值:在一個begin end的多行賦值語句,在同一時間同時賦值。


例如上面兩個例子中,1到4行這一段是阻塞賦值,程序會先執(zhí)行825行,得到結(jié)果后再執(zhí)行826行。829至832行這一段是非阻塞賦值,830行和831行的賦值語句是同時執(zhí)行的。

假設(shè)當(dāng)前c的值為0,d的值為0,a的新值為1。

阻塞賦值的執(zhí)行過程和結(jié)果:程序會先執(zhí)行第825行,此時c的值將更新為1,然后再執(zhí)行826行,此時c+a也就是相當(dāng)于1+1=2,也就是d的值為2。

非阻塞賦值的執(zhí)行過程和結(jié)果:程序會同時執(zhí)行第830行和831行。特別注意是,在執(zhí)行831行的時候,830行是還沒有執(zhí)行的,也就是意味著c的值還沒變化,即此時c的值為0。同時執(zhí)行的結(jié)果是,c的值為1,d的值為1。

明德?lián)P的規(guī)范要求,組合邏輯使用阻塞賦值“=”,時序邏輯使用非阻塞賦值“<=”。讀者可以把這個規(guī)則記下來,絕對不會出錯。

制定這個規(guī)范的原因,不是語法上的原因,而是為了正確描述硬件的原因。


5? D觸發(fā)器

需要看對應(yīng)的視頻,請點擊視頻編號:001100000069

1、本節(jié)主要介紹了在FPGA中使用最簡單的觸發(fā)器——D觸發(fā)器,介紹了它的結(jié)構(gòu)、波形,以及如何看FPGA波形。
2、這是ALTERA和VIVADO文檔


5.1?D觸發(fā)器

數(shù)字電路介紹了多種觸發(fā)器:JK觸發(fā)器、D觸發(fā)器、RS觸發(fā)器、T觸發(fā)器等。在FPGA中,我們使用的是最簡單的觸發(fā)器---D觸發(fā)器。


5.1.1?D觸發(fā)器結(jié)構(gòu)



圖?34

圖?34是D觸發(fā)器的結(jié)構(gòu)圖,讀者可以把它看成一個芯片。該芯片擁有4個管腳,其中3個是輸入管腳:時鐘clk、復(fù)位rst_n、信號d;1個是輸出管腳:q。

該芯片的功能是這樣的:當(dāng)給管腳rst_n給低電平,也就是賦值為0時,輸出管腳q就處于低電平狀態(tài)。如果管腳rst_n為高電平,然后再看管腳clk,在clk由0變1即上升沿的時候,將現(xiàn)在d的值賦給q,d是低電平,q也是低電平,d是高電平,q也是高電平。


5.1.2?D觸發(fā)器波形



圖?35

圖 35是D觸發(fā)器的功能波形圖。該波形圖反映了D觸發(fā)器各個信號的變化情況,從左到右表示時間的走勢。時鐘信號有規(guī)律地高低變化。波形圖從左開始往右看。




5.1.3?D觸發(fā)器代碼

我們看下面這段時序邏輯的代碼。


我們從語法上,分析該段代碼的功能。該段代碼總是在“時鐘clk上升沿或者復(fù)位rst_n下降沿”的時候執(zhí)行一次。怎樣執(zhí)行呢?

1.?如果復(fù)位rst_n=0,則q的值為0;

2.?如果復(fù)位rst_n=1,則將d的值賦給q(注意,前提條件是時鐘上升沿的時候)。

上面的功能,與這個功能是相同的:當(dāng)給管腳rst_n給低電平,也就是賦值為0時,輸出管腳q就處于低電平狀態(tài)。如果管腳rst_n為高電平,然后再看管腳clk,在clk由0變1即上升沿的時候,將現(xiàn)在d的值賦給q,d是低電平,q也是低電平,d是高電平,q也是高電平。

沒錯,上面代碼功能,與D觸發(fā)器的功能是一樣的。這份代碼,其實就是在描述一個D觸發(fā)器,這就是D觸發(fā)器的代碼。

前面已經(jīng)講過,在FPGA設(shè)計中,你可以用原理圖的形式來設(shè)計,也可以用硬件描述語言。當(dāng)用原理圖來設(shè)計時,幾個D觸發(fā)器還可以忍受,但如果是幾千幾萬個D觸發(fā)器呢,那必定是頭暈眼花了。用硬件描述語言verilog,則沒有這問題。


5.1.4?怎么看FPGA波形

我們再來討論一下波形。先請讀者思考,在第4個時鐘上升沿的時刻,在此時此刻看到的信號q的值是多少?是0還是1?還是說看到q的上升沿?



圖?36

我們的verilog代碼對應(yīng)的是硬件,我們應(yīng)該從硬件來分析這個問題。我們想一下代碼的因果關(guān)系。是先有時鐘上升沿,這個是因。然后將d的值賦給q,這個是結(jié)果。這個因果是有先后關(guān)系的,對于硬件來說,這個“先后”無論是多么地快,也是占有一定時間的,所以q的變化會稍后于clk的上升沿。例如下圖就是硬件的實際變化情況。



圖?37

圖中就很容易看出,第4個時鐘上升沿時刻,看到的q值為0,也就是變化前的值。上面的波形雖然更將近于實際,但這樣畫圖實在是沒累了,而且也沒有完成必要。我們只需掌握這種看波形規(guī)則:時鐘上升沿看信號,是看到變化之前的值。



圖?38

所以第4個時鐘上升沿時,看到q值為0;在第6個時鐘上升沿時,看到q值為1;在第7個時鐘上升沿時,看到q值為0;在第8個時鐘上升沿時,看到q值為1;在第10個時鐘上升沿時,看到q值為0。

注意一下,復(fù)位信號是在系統(tǒng)開始時刻或者出現(xiàn)異常時才使用,一般上電后就不會再次復(fù)位了,可以認(rèn)為復(fù)位是特殊的情況。

我們考慮正常使用的情況。我們無論是從功能上,還是波形上,都可以看到信號q只在時鐘上升沿才變化,它絕對不會在中間變化。在一般的數(shù)字系統(tǒng)中,大部分信號之間的傳遞,都是在同一個時鐘傳遞的,即大部分都是同步電路??鐣r鐘的電路占比非常小,屬于特殊的異步電路。在本教材中,所有的案例、練習(xí),如果沒有提前說明,默認(rèn)都是同步電路。

既然是同步電路,那么輸入信號d也是另一個D觸發(fā)器產(chǎn)生的,并且是同一個時鐘clk產(chǎn)生的,如下圖。

這就意味著信號d也只會在時鐘上升沿變化,理想波形中,它不會在時鐘的中間變化的,所以修正下波形圖,下圖就是理想的、正確的波形圖。



圖?39






5.2?時序邏輯實現(xiàn)的加法器

我們分析下面這段代碼


我們?nèi)匀粡恼Z法上,分析該段代碼的功能。該段代碼總是在“時鐘clk上升沿或者復(fù)位rst_n下降沿”的時候執(zhí)行一次。怎樣執(zhí)行呢?

1.?如果復(fù)位rst_n=0,則q的值為0;

2.?如果復(fù)位rst_n=1,則將(a+d)的結(jié)果賦給q(注意,前提條件是時鐘上升沿的時候)。

假設(shè)用信號c表示a+d的結(jié)果,則第2點可改為:如果復(fù)位rst_n=1,則將c的值賦給q(注意,前提條件是時鐘上升沿的時候)。這很明顯就是一個D觸發(fā)器,輸入信號為d,輸出為q,時鐘為clk,復(fù)位為rst_n。



圖?40

c是怎么來的?c是a+d的結(jié)果,自然是一個加法器,所以可以畫出上面代碼所對應(yīng)的電路結(jié)構(gòu)圖,可以看出在D觸發(fā)器的基礎(chǔ)上增加了一個加法器。



圖?41

很容易分析出上面電路的功能:信號a和信號b相加得到c,c連到D觸發(fā)器的輸入端。當(dāng)clk出現(xiàn)上升沿時,將c的值傳給q。這與代碼功能是一致的。

下面是代碼和硬件所對應(yīng)的波形圖。



圖?42

先看信號c的波形,c的產(chǎn)生只有與a和b有關(guān),與rst_n和clk無關(guān)。c是a+d的結(jié)果,按照二進(jìn)制加法:0+0=0,0+1=1,1+1=0。就可以畫出c的波形。

再看信號q的波形。q是D觸發(fā)器的輸出,它只在rst_n的下降沿或者clk的上升沿才變化,其他時候不變化,也就是a、b、c有變化時,q都不會立刻變。



圖?43





讀者有沒有發(fā)現(xiàn),在討論時序邏輯的加法器時,我們是分開討論加法器的輸出c和D觸發(fā)器的輸出q,這就像兩塊獨立的電路。那我們Verilog代碼,是否也可以分開來寫呢?當(dāng)然是可以的。

我們可以先將下面的硬件電路用Verilog描述出來。



圖?44

該電路對應(yīng)的電路,可以寫成:

也可以寫成


面的兩段代碼,都是描述同一硬件電路,并且是加法器。

其次,我們再用Verilog描述一下觸發(fā)器。



圖?45

其代碼的寫法如下:


最后,我們可以看到,兩段代碼都有信號c,說明這兩個是相連的,因此硬件連接起來,變成下面電路。



圖?46

由此可見,下面兩段代碼所對應(yīng)的硬件電路是一模一樣的。


這兩種代碼哪種比較好?答案是一樣好。因為它們的硬件是相同的,這就是評估verilog代碼好不好的最基本標(biāo)準(zhǔn),不是看代碼行數(shù),而是看硬件。


6?時鐘的重要性

需要看對應(yīng)的視頻,請點擊視頻編號:001100000070

1、本節(jié)主要介紹了數(shù)字電路中非常重要的概念——時鐘,以及時鐘頻率和時鐘周期的換算方法。
2、這是ALTERA和VIVADO視頻

時鐘信號是每隔固定時間上下變化的信號。本次上升沿和上次上升沿占用的時間,就是時鐘周期,它的倒數(shù)就是時鐘頻率。高電平占整個時鐘周期的時間,稱之為占空比。 FPGA中的時鐘,占空比一般是50%,即高電平時間和低電平時間一樣。其實占空比在FPGA內(nèi)部沒有太大的意義,因為我們使用的是時鐘上升沿來觸發(fā),更加關(guān)心的是時鐘頻率。

如果時鐘的上升沿每秒出現(xiàn)一次,說明時鐘的時鐘周期為1秒,時鐘頻率為1Hz。如果時鐘的上升沿每1毫秒出現(xiàn)一次,說明時鐘的時鐘周期為1毫秒,時鐘頻率為1000Hz,或?qū)懗?kHz。

現(xiàn)在普通的FPGA器件,所支持的時鐘頻率范圍一般不超過150M,高端器件可能不超過700M(經(jīng)驗值,實際能跑多愉,取決于器件、設(shè)計的電路有相當(dāng)大的關(guān)系)。反對應(yīng)的時鐘周期在納秒級范圍。所以本教材里,所有案例的時鐘頻率一般都是幾十到一百多M。

下面列出本教材常用到的時鐘頻率以及所對應(yīng)的時鐘周期,方便讀者進(jìn)行換算。


時鐘是FPGA最重要的信號,所有的其他信號在時鐘的上升沿統(tǒng)一變化,這就像軍隊里的令旗,所有軍隊在看到令旗到來的時刻,執(zhí)行已經(jīng)設(shè)定好的命令。

時鐘這塊令旗影響著整體電路的穩(wěn)定。首先,時鐘要非常地穩(wěn)定跳動。就如軍隊令旗,時快時慢,就會讓人無所適從,容易出錯。而如果令旗非常穩(wěn)定,每個人都知道令旗什么時候過來,在令旗到來前能不能完成任務(wù),不能就通知改正(修改代碼),避免系統(tǒng)出錯。

其次,一個高效的軍隊,令旗越少越好,不同部隊看不同的令旗,那么部隊協(xié)作就容易出現(xiàn)問題,整個軍隊必定做不到高效,或者容易出錯。同樣道理,F(xiàn)PGA系統(tǒng)的時鐘,必定是越少越好,最好就是一個時鐘。這也是要求讀者,不要把信號放在時序邏輯敏感列表的原因。


7?模塊

7.1?模塊結(jié)構(gòu)

需要看對應(yīng)的視頻,請點擊視頻編號:001100000051

1、本節(jié)主要介紹模塊結(jié)構(gòu),模塊(module)是verilog的基本描述單位,是用于描述某個設(shè)計功能或結(jié)構(gòu)及與其他模塊通信的外部端口,有5個主要部分:端口定義、參數(shù)定義(可選)、I/O說明、內(nèi)部信號聲明、功能定義。? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

2、2、這是ALTERA和VIVADO文檔
模塊(module)是Verilog?的基本描述單位,用于描述某個設(shè)計的功能或結(jié)構(gòu)及與其他模塊通信的外部端口。

?模塊在概念上可等同一個器件就如我們調(diào)用通用器件(與門、三態(tài)門等)或通用宏單元(計數(shù)器、ALU、CPU)等,因此,一個模塊可在另一個模塊中調(diào)用。一個電路設(shè)計可由多個模塊組合而成,因此一個模塊的設(shè)計只是一個系統(tǒng)設(shè)計中的某個層次設(shè)計,模塊設(shè)計可采用多種建模方式。

每個模塊實現(xiàn)特定的功能,模塊可進(jìn)行層次的嵌套,因此可以將大型的數(shù)字電路設(shè)計分割成大小不一的小模塊來實現(xiàn)特定的功能,最后通過由頂層模塊調(diào)用子模塊來實現(xiàn)整體功能,這就是Top-Down的設(shè)計思想,

??Verilog 的基本設(shè)計單元是“模塊”。采用模塊化的設(shè)計使系統(tǒng)看起來更有條理也便于仿真和測試,那么整個項目的設(shè)計思想就是模塊套模塊,自頂向下依次展開。

本書主要以verilog硬件描述語言為主,模塊是Verilog的基本描述單位,用于描述每個設(shè)計的功能和結(jié)構(gòu),以及其他模塊通信的外部接口。

模塊有五個主要部分:端口定義、參數(shù)定義(可選)、?I/O說明、內(nèi)部信號聲明、功能定義。且模塊總是以關(guān)鍵詞module開始,以關(guān)鍵詞endmodule結(jié)尾。它的一般語法結(jié)構(gòu)如下所示:



下面我們來詳細(xì)分析一下這段代碼:



7.2?模塊的端口定義

第1至5行聲明了模塊的名字和輸入輸出口。其格式如下:

module?模塊名(端口?1,端口?2,端口?3,……);

其中模塊是以module開始,以endmodule結(jié)束。模塊名是模塊唯一的標(biāo)識符,我們建議模塊名盡量用能夠描述其功能的名字來命名,并且模塊名和文件名相同。

模塊的端口表示的是模塊的輸入和輸出口名,也就是它與別的模塊聯(lián)系端口的標(biāo)識。


7.3?參數(shù)定義

第7行參數(shù)定義是將常量用符號代替,以增加代碼可讀性和可修改性,是一個可選擇的語句,用不到可以省略,參數(shù)定義一般格式如下:

parameter ?DATA_W = x;


7.4?I/O?說明




7.5?信號類型
需要看對應(yīng)的視頻,請點擊視頻編號:001100000052

1、本節(jié)主要介紹,Verilog HDL的信號類型,主要包括兩種數(shù)據(jù)類型:線網(wǎng)類型(net type)和寄存器類型(reg type),在進(jìn)行工程設(shè)計中也只會使用到這兩個類型的信號;信號位寬,定義信號類型的同時,必須定義好信號的位寬,取決于該信號要表示的最大值,例如a信號的最大值為1000,那么信號a的位寬必須大于或等于10位;線網(wǎng)類型wire,用于對結(jié)構(gòu)化器件之間的物理連接的建模,代表的是物理連接線,不存儲其邏輯值,通常用assign進(jìn)行賦值;寄存器類型reg,通常用于對存儲單元的描述,如D型觸發(fā)器、ROM等。必須注意的是:reg類型的變量不一定是存儲單元,如在always語句中進(jìn)行描述的必須是用reg類型的變量;wire和reg的區(qū)別,本書總結(jié)出一套解決方法:在本模塊中使用always設(shè)計的信號都定義為reg型,其他都定義為wire型。? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

2、這是ALTERA和VIVADO文檔

第16至18行定義了信號的類型。在模塊內(nèi)用到的和與端口有關(guān)的?wire?和?reg?類型變量的聲明。如:

reg [width-1 : 0] R?變量?1,?R?變量?2 ……;

wire [width-1 : 0] W?變量?1,W?變量?2……;

如果不寫,默認(rèn)是wire型,并且信號位寬為1。


7.6?功能描述

第21至31行是功能描述部分。模塊中最重要的部分是邏輯功能定義部分。有三種方法可在模塊中產(chǎn)生邏輯。

1.?用“assign”聲明語句,如描述一個兩輸入與門:assign ?a = b & c。

2.?用“always”塊。即前面介紹的時序邏輯和組合邏輯。

3.?模塊例化。


7.6.1?例化

對一個數(shù)字系統(tǒng)的設(shè)計,我們采用的是自頂向下的設(shè)計方式??砂严到y(tǒng)劃分成幾個功能模塊,每個功能模塊再劃分成下一層的子模塊。每個模塊的設(shè)計對應(yīng)一個module?,一個module?設(shè)計成一個verilog HDL?程序文件。因此,對一個系統(tǒng)的頂層模塊,我們采用結(jié)構(gòu)化的設(shè)計,即頂層模塊分別調(diào)用了各個功能模塊。

一個模塊能夠在另外一個模塊中被引用,這樣就建立了描述的層次。模塊實例化語句形式如下:

module_name instance_name(port_associations) ;

信號端口可以通過位置或名稱關(guān)聯(lián);但是關(guān)聯(lián)方式不能夠混合使用。端口關(guān)聯(lián)形式如下:

port_expr / /通過位置。.PortName (port_expr) / /通過名稱。


建議:在例化的端口映射中請采用名字關(guān)聯(lián),這樣,當(dāng)被調(diào)用的模塊管腳改變時不易出錯。

在我們的實例化中,可能有些管腳沒用到,可在映射中采用空白處理,如:




對輸入管腳懸空的,則該管腳輸入為高阻 Z,輸出管腳被懸空的,該輸出管腳廢棄不用。

下面以一個實例(一個頻率計數(shù)器系統(tǒng))說明如何用HDL進(jìn)行系統(tǒng)設(shè)計。

在該系統(tǒng)中,我們劃分成如下三個部分:2輸入與門模塊,LED顯示模塊,4位計數(shù)器模塊。系統(tǒng)的層次描述如下:


圖?47

頂層模塊CNT_BCD,文件名CNT_BCD.v,該模塊調(diào)用了低層模塊?AND2、CNT_4b和?HEX2LED?。系統(tǒng)的電路結(jié)構(gòu)圖如下:



圖?48

頂層模塊CNT_BCD對應(yīng)的設(shè)計文件 CNT_BCD.v 內(nèi)容為:


注意:這里的AND2是為了舉例說明,在實際設(shè)計中,對門級不要重新設(shè)計成一個模塊,同時對涉及保留字的(不管大小寫)相類似的標(biāo)識符最好不用。


7.7?模塊案例

下面先介紹幾個簡單的Verilog HDL程序。

例[1]?加法器


該例描述一個3位加法器,從例子可看出整個模塊是以module 開始,endmodule 結(jié)束。

例[2] ??比較器


該例描述一個比較器,從上可看到,/* ?.... */ 和 // ... 表示注釋部分。注釋只是為了方便設(shè)計者讀懂代碼,對編譯并不起作用。

例[3] ?三態(tài)驅(qū)動器

該例描述了一個三態(tài)驅(qū)動器。其中三態(tài)驅(qū)動門在模塊 mytri 中描述,而在模塊trist 中調(diào)用了模塊mytri 。模塊mytri 對trist 而言相當(dāng)于一個已存在的器件,在trist 模塊中對該器件進(jìn)行實例化,實例化名 u_mytri 。


8?可綜合設(shè)計

需要看對應(yīng)的視頻,請點擊視頻編號:001000000049

1、本節(jié)主要介紹使用綜合器對Verilog代碼進(jìn)行解釋并將代碼轉(zhuǎn)化成實際電路來表示,最終產(chǎn)生實際電路(網(wǎng)表),即綜合;為了避免在編寫好代碼、綜合成電路、燒寫到FPGA后才發(fā)現(xiàn)問題,此時再去定位問題就會非常的地困難,所以,在綜合前,設(shè)計師可以通過仿真軟件對代碼進(jìn)行仿真測試,檢測出BUG并將其解決,最后再將程序燒寫進(jìn)FPGA,即仿真;在Veriglog語言中,有些語法結(jié)構(gòu)只是以仿真測試為目的,是不能與實際硬件電路對應(yīng)起來的,也稱之為不可綜合語法,

2、本節(jié)整理了不可綜合或者不推薦使用的代碼。? ? ? ?

3、ALTERA和VIVADO文檔


Verilog硬件描述語言有很完整的語法結(jié)構(gòu)和系統(tǒng),類似高級語言,這些語法結(jié)構(gòu)的應(yīng)用給我們的設(shè)計描述帶來很多方便。但是,Verilog是描述硬件電路的,它是建立在硬件電路的基礎(chǔ)上的。有些語法結(jié)構(gòu)只是為了仿真測試目的,是不能與實際硬件電路對應(yīng)起來的,也就是說我們在把一個語言描述的程序映射成實際硬件電路中的結(jié)構(gòu)時是不能實現(xiàn)的。

綜合就是把你寫的rtl代碼轉(zhuǎn)換成對應(yīng)的實際電路。

比如你寫代碼assign a=b&c;

EDA綜合工具就會去元件庫里拿一個二輸入與門出來,然后輸入端分別接上b和c,輸出端接上a

假如你寫了很多這樣的語句

綜合工具就會像搭積木一樣的把你這些“邏輯”電路用一些“門”電路來搭起來。當(dāng)然,工具會對必要的地方做一些優(yōu)化,比如你寫一個電路assing a=b&~b,這樣工具就吧a恒接為0了,而不會去給你找一個與門來搭這個電路。



所以,“綜合”要做的事情有:編譯rtl代碼,從庫里選擇用到的門器件,把這些器件按照“邏輯”搭建成“門”電路。

不可綜合,是指找不到對應(yīng)的“門”器件來實現(xiàn)相應(yīng)的代碼。比如#100之類的延時功能,簡單的門器件是無法實現(xiàn)延時100個單元的。還有打印語句等,也是門器件無法實現(xiàn)的。

我們在設(shè)計的時候,要確保所寫的代碼是可以綜合的,這一個是依賴于設(shè)計者的能力,知道什么是可綜合的代碼,什么是不可綜合的代碼。對于初學(xué)者來說,最好是先記住規(guī)則,遵守規(guī)則,先按規(guī)則來設(shè)計電路。在這一過程中,逐漸理解,這是一個最好的學(xué)習(xí)路徑。

下面表格,列出了不可綜合或者不推薦使用的代碼。

表不可綜合或不推薦使用的代碼

下表是明德?lián)P推薦使用的設(shè)計。

表明德?lián)P規(guī)范推薦使用的代碼及其說明


8.1?組合邏輯及其Verilog設(shè)計


表門級邏輯及其verilog設(shè)計



表選擇器和比較器及其verilog設(shè)計


表選擇器和比較器及其verilog設(shè)計

表運算邏輯及其verilog設(shè)計



8.2?時序邏輯verilog設(shè)計方法


時序邏輯的代碼一般有兩種,同步復(fù)位的時序邏輯和異步復(fù)位的時序邏輯。同步復(fù)位的時序邏輯,即復(fù)位不是立即有效,而在時鐘上升沿時復(fù)位才有效。代碼結(jié)構(gòu)如下:




異步復(fù)位的時序邏輯,復(fù)位立即有效,與時鐘無關(guān)。代碼結(jié)構(gòu)如下:




對于時序邏輯verilog設(shè)計明德?lián)P提出以下建議:

為了教學(xué)的方便,明德?lián)P的代碼統(tǒng)一采用異步時鐘邏輯,建議同學(xué)們都采用此結(jié)構(gòu),這樣設(shè)計時只需考慮是用時序邏輯還是組合邏輯結(jié)構(gòu)來寫代碼即可;實際工作,請遵從公司規(guī)范。

在明德?lián)P提供的gVim版本軟件中打開代碼后,輸入“Zuhe”命令(回車后)可得到組合邏輯的代碼結(jié)構(gòu);輸入“Shixu”命令(回車后)可得到時序邏輯的代碼結(jié)構(gòu);

時序邏輯沒有復(fù)位信號是不規(guī)范的代碼,建議不要這樣使用。



1.3VERILOG-明德?lián)P至簡設(shè)計法原理與應(yīng)用的評論 (共 條)

分享到微博請遵守國家法律
郸城县| 田阳县| 昔阳县| 东海县| 平果县| 苏尼特左旗| 平原县| 石门县| 谢通门县| 榆树市| 桂东县| 顺平县| 高安市| 永顺县| 峡江县| 焦作市| 新野县| 营口市| 怀宁县| 寿宁县| 阳谷县| 冕宁县| 无锡市| 盱眙县| 宜城市| 五寨县| 武川县| 黔西| 株洲县| 集安市| 阳曲县| 永吉县| 静安区| 卓资县| 柯坪县| 云霄县| 大宁县| 丰原市| 安徽省| 南投县| 泗洪县|