往下看之前华匾,推薦大家先看一下這個:
度娘找到的一個我覺得寫的還不錯的教程渺鹦,做實驗之前看一下腐巢,哪怕剛開始看不懂也不要緊肴盏,到后面幫助很大的灸叼。
還有一個稍微高級一些的遵馆,涉及到一些設計規(guī)范蜡塌。如果只是為了完成課程設計的話完全可以不看這個,好奇的同學可以看看:
http://www.360doc.com/content/15/0111/23/20647836_440011821.shtml
我主要說一下我認為比較容易被大家忽視的地方适室。凡是綜合的時候會報error的東西我就不寫了嫡意,那種錯誤軟件會給出特別明確的提示,照著提示直接修改就行捣辆,總不至于連這個都改不對
所以我下面我就不說那些編譯器會報錯的東西了鹅很,主要還是一些我認為比較重要的注意事項以及大家開始的時候可能注意不到的東西。
開始用Verilog的時候需要有一個意識罪帖,雖然Verilog因為語法和C語言相似促煮,也被稱為類C語言,但是它和C有著本質(zhì)的不同整袁。C語言屬于軟件型語言菠齿,而Verilog屬于硬件編程語言。C語言最后形成的是二進制代碼坐昙,執(zhí)行的時候是順序執(zhí)行的绳匀,而且一般情況下,程序是嚴格按照語句的設計來運行炸客。而Verilog則是根據(jù)Verilog語句生成電路疾棵,最后由生成的電路完成設計者的功能。而生成的電路在某些情況下痹仙,并不能像C語言一樣完成程序設計者的所有要求是尔,在將程序語言綜合成電路的過程中,如果程序的設計沒有嚴格按照某些規(guī)范开仰,最后生成的電路可能會有意想不到的邏輯產(chǎn)生拟枚,導致“明明程序的邏輯設計正確,但是電路不能正常工作”的現(xiàn)象众弓。此外恩溅,設計出來的電路屬于并發(fā)式執(zhí)行而非順序執(zhí)行,所以在剛開始進行設計的時候谓娃,需要改變自己在C語言設計過程中產(chǎn)生的順序性思維脚乡。
就我個人的體驗來說,剛開始的時候最容易犯得錯誤就是在條件判斷語句中沒有將所有的條件都列出來滨达,導致綜合軟件綜合處多余的鎖存器產(chǎn)生的錯誤奶稠。
說人話就是case語句之后沒有default,if/else if語句的最后沒有跟一個else將所有其它可能的條件都封鎖到一個行為上弦悉。尤其是在用always語句寫組合邏輯的時候更容易出現(xiàn)類似的錯誤窒典。
如果出現(xiàn)了程序能正常通過軟件的檢查蟆炊,變量的名稱沒有錯誤同時程序的邏輯看似正確但是電路不能正常工作的情況時稽莉,推薦優(yōu)先檢查該問題。開始編寫代碼的時候也推薦養(yǎng)成所有的case語句后面都有default涩搓,所有的if/else if 語句后面都有else的好習慣污秆。
上面說過了劈猪,Verilog生成的電路是并發(fā)式執(zhí)行命令的,但是這并不代表Verilog語句執(zhí)行任務沒有順序良拼。
在if/else if語句就存在執(zhí)行順序的問題战得,和C語言一樣,靠前的判斷條件如果先執(zhí)行庸推,那么后面的判斷條件就不會進行判斷常侦。當多分支判斷語句只有一個條件成立的時候,書寫順序?qū)τ趫?zhí)行結(jié)果沒有影響贬媒,但是如果有兩個以上條件成立聋亡,那么只有最靠前的那個會執(zhí)行,所以設計的時候要讓自己希望執(zhí)行的部分靠前际乘,不希望執(zhí)行的靠后坡倔,或者充分利用其他的條件,使每種情況下都只有一個判斷條件成立脖含。
進行圖形化設計的時候罪塔,可能會需要一些引腳恒為0或者恒為1。需要恒為1接vcc养葵,需要恒為0接gnd征堪。
關(guān)于如何找Vcc和gnd:
雙擊quartus的圖形設計界面的空白位置:
彈出一個器件選擇窗口,在圖中所示的文本框中輸入vcc或者gnd即可直接出現(xiàn)vcc关拒、gnd器件请契。同理也可用該方法查找其它器件(用),也可以在上面的libraries中查找需要的器件:
自己設計封裝的元器件也可以在這個界面調(diào)用夏醉,點擊那個瀏覽按鈕:
然后找到你想使用的bsf文件:
然后直接添加到電路中即可爽锥。需要注意的是和你添加的bsf相關(guān)的電路文件也是要一起復制到你的工程的目錄下的,不然不能使用畔柔。
關(guān)于圖形化設計界面的接線方式氯夷,除了直接進行連接之外,quartus會自動將所有同名的線連接在一起靶擦。所以只需要從接口上引出一根線腮考,然后雙擊連接線,將需要連接的接口的線命名為一個名字就可以了玄捕,如圖所示踩蔚,兩根分離的線都被命名為CPMAR:
對于一組線的情況,命名方式如下:
線名[高位..低位]
如
bus[15..0]
中間是兩個英文的句號枚粘。
想要連接其中的幾根線的方式也很簡單馅闽,比如連接一根線:
bus[7]
連接多根線
bus[9..2]
此外, 多根線需要用bus line來連接的,就是圖中粗的那個:
如果想把洗的node line編程粗的bus line福也,只要選擇對應的線局骤,右鍵,選擇bus line即可
之前說到了如何調(diào)用自己封裝的模塊暴凑,那么下面就說一下如何封裝你的模塊峦甩。
選中你要封裝的模塊(圖形化設計或者Verilog設計都可以),選擇file->Create/Update->Create Symbol Files for Current File:
然后在彈出的窗口中直接保存即可现喳,可以修改文件名:
如果需要修改生成的bsf文件的外觀凯傲,可以在工程目錄下找到生成的bsf文件,雙擊打開嗦篱,即可修改外觀:
另外如果只是在Verilog語言中調(diào)用模塊的話泣洞,不需要封裝,直接調(diào)用就可以默色。
用Verilog語言調(diào)用模塊的時候球凰,調(diào)用方式很簡單只要按照:
被調(diào)用模塊名 部件名(.接口1(線1), .接口2(線2).......)
比如被調(diào)用的模塊定義為:
module example(a, b, c);
.......
....
endmodule
那么調(diào)用這個模塊的時候語法就是:
example example_0(.a(wire1), .b(wire2), .c(wire3));
還有一種調(diào)用方式,就是省掉 . +接口名部分腿宰,直接按照順序在調(diào)用模塊的括號中寫所有對應的wire呕诉,如:
example example_0(wire1, wire2, wire3);
這樣也是可以的,但是缺點在于當接口比較多的時候吃度,會出現(xiàn)自己分不清那個接口對應的是哪一根線的情況甩挫,而且這個方式中,哪一個接口和哪一根線對應完全依賴于順序椿每,更容易出錯伊者。所以推薦使用第一種方法。
寄存器組在Verilog中是這樣的:
reg [15:0]regfile[31:0]
表示每一個寄存器的位數(shù)為16位(150共16個)间护,總共有32個這樣的寄存器(310共32個)亦渗。
如果想要調(diào)用第25個寄存器,調(diào)用方式為
regfile[25]
如果想要調(diào)用第25個寄存器的某幾位汁尺,調(diào)用方式為:
regfile[25][14:7]
wire型變量法精。剛開始的時候可能有的人不清楚wire型變量到底是個啥,其實wire型變量就想到于圖形化設計電路的時候的那一根根連線痴突,使用wire型變量既可以在模塊調(diào)用的時候直接使用搂蜓,也可以使用
assign wire名稱=wire名稱/寄存器
的方式調(diào)用
用assign語句書寫條件分支語句。說到條件判斷辽装,我們最容易想到的是用if/else或者case語句來實現(xiàn)帮碰。其實很多時候我們可以用assign實現(xiàn)分支條件語句的書寫,相比于使用需要always塊的if/else和case相比拾积,更不容易出錯殉挽。
方式如下:
assign 變量值=判斷條件1?事件1:
判斷條件2?事件2:
判斷條件3?事件3:
事件4;
當然用更多的判斷條件實現(xiàn)更多的時間丰涉。
這個方式其實就是
assign 變量值=判斷條件?事件1:事件2;
語句的一種應用。在C語言中也存在相同的語句可以使用此再。
reg,wire類型變量的數(shù)量和位數(shù)對應關(guān)系玲销。如果定義一個8位的reg變量输拇,我們有無數(shù)種定義方式:
[7:0]寄存器名
[8:1]寄存器名
[16:9]寄存器名
具體用哪一種,一來要根據(jù)情況而定贤斜,二來要考慮到自己的使用習慣策吠。如果對于沒有特殊要求的寄存器,最好養(yǎng)成把最低位定義成統(tǒng)一的數(shù)的習慣(比如0或者1)瘩绒。對于有特殊要求的寄存器猴抹,比如要保存某[15:0]寄存器中數(shù)據(jù)的高8位,定義的時候也不要定義成[7:0]锁荔,最好按照[15:0]寄存器中的格式定義為[15:8]蟀给,這樣調(diào)用的時候邏輯更加清晰。
善用parameter阳堕。parameter就相當于C語言中的宏定義跋理。比如在大二下學期計算機組成原理課設中需要用到的狀態(tài)機中,狀態(tài)的定義方式:
parameter s0=4'b0000,s1=4'b0001,s2=4'b0010,s3=4'b0011,s4=4'b0100,s5=4'b0101,s6=4'b0110,s7=4'b0111;
parameter s8=4'b1000,s9=4'b1001,s10=4'b1010,s11=4'b1011,s12=4'b1100,s13=4'b1101,s14=4'b1110;
之后調(diào)用的時候就可以直接使用s0恬总,s1來進行操作前普,修改的時候也分方便。體驗過C語言宏定義好處的人壹堰,應該就不用我多說在后期修改的時候這種定義方式有多方便了吧拭卿。
對于多層嵌套的begin,end語句贱纠,可以再開始的時候?qū)γ恳粭lbegin峻厚,end加注釋,通過注釋實現(xiàn)每一條begin谆焊,end的對應目木。
比如:
always @(xxxx)
begin //always begin
if(條件1)
begin //if(條件1) begin
if(條件2)
begin //if(條件2) begin
end //if(條件2) end
end //if(條件1) end
end //always end
通過這種方式,begin和end的對應關(guān)系就不會亂了懊渡。
如何設置頂層文件刽射。當工程涉及到多個模塊時,可能會出現(xiàn)工程的頂層文件(即仿真以及下載的時候真正需要進行操作的那個文件)和我們設想的不一樣剃执。比如在這個工程中誓禁,這個是我現(xiàn)在的頂層文件:
可是我需要的頂層文件實際上是這個:
那么那么首先我們要在files里面找到這個文件,然后右鍵肾档,選擇Set as Top-Level Entity即可:
同樣的摹恰,如果你想要單獨測試這個工程里某一個子模塊的功能辫继,只要將那個子模塊設置成top-level就可以直接對這個模塊進行測試了。
進行仿真的時候可能會涉及到多個仿真文件需要切換俗慈,這時候就需要我們手動選擇仿真文件姑宽。選擇processing-simulator tools
然后會出現(xiàn)這個窗口,找到你想要使用的仿真文件闺阱,然后點擊start即可進行仿真炮车。如果start之后發(fā)現(xiàn)仿真的窗口沒有出現(xiàn),那就點擊start旁邊的open即可打開仿真結(jié)果窗口:
有的時候我們會希望多位信號直接等于某一個數(shù)酣溃,操作如下瘦穆。選中你想要修改的信號區(qū)域,然后雙擊赊豌,會彈出一個修改窗口
在Radix中選擇數(shù)據(jù)格式扛或,比如十進制,十六進制碘饼,ASCII碼等等熙兔,然后在下方輸入數(shù)值。
點擊OK之后就會看到變化:
添加重復度高的元器件艾恼。有的時候可能會遇到這樣的模塊:
這是只有兩個重復的情況黔姜,實際設計中可能還會出現(xiàn)更多的情況。對于這種的蒂萎,其實完全沒有必要一個一個去連接秆吵,用一些批量修改的方法可以讓工作量減小特別多。就拿這個舉例五慈,開始的時候先添加這個74244芯片纳寂,然后在一個接口上添加一根線,命名為dataregout[]:
然后將這根線復制4跟泻拦,然后再將四根一起復制到下面四個端口上(按住ctrl拖動可直接復制)毙芜。對于另一邊進行同樣的操作,同時將其他單獨的線也接好争拐,如圖:
連接好了之后可以拖動一下元器件腋粥,看看連接線有沒有跟著一起移動,如果沒有跟著一起移動說明沒接上架曹,一起移動了就說明連接成功隘冲。然后,需要幾個重復的器件绑雄,就將整個器件和所有的連接線都選中展辞,然后按住ctrl+鼠標左鍵拖動到你想要的位置。
然后雙擊第一個線名万牺,按方向鍵左鍵一次罗珍,即可將輸入光標移動到方括號中洽腺,直接輸入對應的數(shù)字,然后回車覆旱,會自動跳到下一條線的名字上蘸朋,繼續(xù)進行同樣的操作直到所有的線命名完畢:
然后對所有的部件進行同樣的操作即可。
不但速度快扣唱,而且錯誤率低藕坯,視覺效果更整齊。