ise verilog多模块编译_如何使用ISE高效开发Verilog项目(新手)
高效開發VerilogHDL項目
V1.0@2014.11.22
作者:劉乾@北航計算機學院
免責聲明
這份文檔完全是依據作者在實際項目開發中總結出的經驗撰寫而成的。本文檔僅供參考。作者不對文檔中的任何錯誤負責。
引言:關于ISE的問題庫的使用說明
從ISE里進入的方式是:Help→?Xilinx?on?the?Web?→?Support?and?Services
一、?ISE常見問題
很多同學表示從來沒有用過這個幫助庫,這個庫是用來做什么的呢?
這個庫是用來search一些常見的系統錯誤的。下面是我利用ISE問題庫解決了的一些系統錯誤。
Q1:
錯誤提示:
ERROR:Simulator:904?–
Unable?to?remove?previous?simulation?file?A:/mips/mips_tb_isim_beh.exe.
Please?check?if?you?have?another?instance?of?this?simulation?running?on?your?system,?terminate?it?and?then?recompile?your?design.
System?Error?Message:?boost::filesystemremove:??ü??·??ê?£:?"A:\mips\mips_tb_isim_beh.exe"
A1:這種錯誤出現是由于同時開啟了對同一模塊的仿真,關閉上一次仿真后的界面即可,如果界面找不到了,請啟動任務管理器,從進程中關閉?isimgui.exe和mips_tb_isim_beh.exe后即可重新仿真
Q2:
錯誤提示:
FATAL?ERROR:?PrivateChannel:?Error?connecting?to?server?socket
ERROR:?The?simulation?failed?to?launch?for?the?following?reason:
Failed?to?communicate?with?child?process.
Please?shut?down?ISim?and?retry?the?simulation.?If?the?problem?persists,?please?contact?Xilinx?support.
Time?resolution?is?1?fs
No?active?Database
Unable?to?execute?live?simulation?command.
A2:這種錯誤一般是在高版本14.6中仿真時產生,并且是在win8里出現的。如果你是win8用戶,可以嘗試在win8開始的磁貼頁面找到應用程序里的ISE?Design?Suite?32?bit?(ISE的桌面快捷方式是默認為64bit的)
如果你無法使用32位版本的,只能使用64位版本的,使用如下教程可以使你在打開工程時不崩潰:
找到程序安裝路徑下的這兩個文件夾
X:\Xilinx\14.6\ISE_DS\ISE\lib\nt64X:\Xilinx\14.6\ISE_DS\common\lib\nt64
首先在第1個文件夾中,重命名libPortability.dll為libPortability.dll.orig,然后復制libPortabilityNOSH.dll的一個副本并重命名為libPortability.dll,這樣你就又有一個libPortability.dll文件了。然后在第2個文件夾,將之前得到的新的libPortability.dll覆蓋到這個文件夾中。
但此解決方案只能使你打開工程時不至于崩潰或閃退,仿真時有可能依舊出現bug。
最終解決的方案仍舊沒找到,只能是嘗試性的測試。希望有解決了的同學可以將解決方案email給我,以便我匯總在一起。
Q3:打不開Isim
A3:同樣可能是因為我們的版本的問題,請從32位版本快捷方式打開
還有一個解決方案如下:
打開ISE的目錄,找到14.6\ISE_DS\ISE\gnu?請從MINGW的官網下載最新版的MINGW覆蓋該文件
Q4:
錯誤提示:
WARNING:?File?"D:/ISE/P4/datapath.v"?Line?37.??For?instance?dp/dm/,?width?32?of?formal?port?A?is?not?equal?to?width?16?of?actual?signal?imm16.
A4:這是一個典型的位寬不匹配的錯誤,我們從中可以看到,在datapath.v文件里的dm模塊中模塊內部的定義變量A和外部傳入的變量imm16的位寬是不一致的,這個雖然是警告,但是有可能就是造成波形圖錯亂的關鍵原因之一,請記住,Behavioral?Check只能檢查出模塊內部的顯性的位寬不正確的錯誤,在模塊中實例化子模塊的時候的錯誤在仿真前有時候是檢查不出來的!
請一定要在仿真后看一下下面的提示信息并修改位寬。
另外注明一點,位寬的錯誤有可能是模塊參數的順序出錯導致的!請注意模塊順序,好的代碼風格應該是在實例化模塊時如下:
Mips?U_MIPS(.clk(clk),.reset(reset))
詳情可翻閱Verilog教程資料進行查詢。
二、?仿真調試技巧
以下是我調試的過程中總結的一些小技巧,如果你覺得還有一些需要補充的請發郵件給我,郵箱在文章最后會附上,謝謝!
1.如何把中間變量的值加入波形圖?
打開仿真界面后,我們可以看到三欄,最左側一欄下方有三個選項,分別是
Instances?and?Processes?,Memory,Source?Files
其中我們點到第一個選項,可以看到頂層目錄,點擊前面的+號,可以展開目錄,如果想添加某個中間變量的值入波形圖的話,請點擊中該變量,右鍵第一個選項可以將其加入波形圖中。
2.一個值出錯了,我該如何知道是在哪里出錯了呢?
我的思路是這樣的:
如果有一個值是非預期值(比如出現XXXX或者一些不是你想要的值),那么我們可以這樣推理,首先尋找到輸出為該變量(注意是直接輸出該變量)的器件,這里的器件包括多路選擇器,比如我有一個多路選擇器是根據MemtoReg信號的值選擇寫入GPR的數據,那么這時候如果我的WriteData是XXX,那么我們就考慮有以下三種情況:
1)DM的readdata值是XXX;
2)ALU的結果是XXX;
3)?控制信號MemtoReg是XXX
請通過小技巧1的方式將相關的變量值加入波形圖,點擊,或者通過菜單欄里的Simulation→Restart?再次仿真,然后注意觀察剛才出現錯誤的指令的相應位置的值哪個是錯誤的,如果我們觀察到ALU的結果是XXX,那我們繼續考慮是否是ALU的輸入或者控制信號有錯誤,溯源以后可以發現源頭的錯誤值是在哪里產生的。
源頭錯誤的產生原因往往有以下幾點:
1)?未能成功傳參。請檢查在你的頂層模塊實例化模塊的模塊參數變量名是否全部寫對?請尤其注意錯別字母和大小寫的區分!如果要查找某一變量名所在位置的話,可以使用快捷鍵ctrl+F進行查找。
2)?位寬不匹配。確實存在一種情況是在仿真和check時都不會報錯的位寬檢查,比如我定義了一個?wire?[31:0]?aluout當其要傳入一個模塊時,該模塊本來相應位置的位寬應該為32位,但是我們如下定義ALU?my_alu(XX…,aluout[31:2],XXX)?本來alu的輸出就應該是32位的,我們定義也是32位的,但在使用時錯誤地使用了aluout的31:2?位作為變量參數,這時候我們的ISE不會報錯!?在我電腦上是不報錯的,其他電腦測過兩臺,也是不會報錯的,所以請格外注意!
3)?未定義該變量。請注意檢查你的變量是否在模塊的開始定義過,如果定義過,請檢查是否存在語法錯誤,常見的初級語法錯誤將在后面進行說明。
3.合理設置仿真時間
請多使用該符號而不要使用,第一個代表的是執行一個你的runtime,runtime默認是1us,可在仿真時進行調整,請注意把testbench里的clk保持不變的延遲時間和runtime維持比例不要過小!否則將一次跳完很多指令或一次,不利于檢查你的錯誤!
三、?調試過程中常見問題
1.clk的值為xx,線為黃色,無波形圖
這種狀態很多情況下都有可能會導致,請嘗試以下方法進行改進看是否解決你的問題:
1)觀察你是否使用了assign連續賦值了reg定義的變量
請記住:wire對應于連續賦值,如assign?;?reg對應于過程賦值,如always,initial
2)觀察是否在組合邏輯電路中使用了always@(posedge?clk)類似的描述,為了確保不是該問題導致的原因,建議所有的組合邏輯建模過程都使用assign!(高老板也強調過這一點)
實際上我使用always@(*)也可以描述組合邏輯,但是會有一些風險,如果不使用*的話請注意要把賦值表達式右端的變量全部加入敏感列表內!
關于風險的問題我自己的一點想法:
這個問題涉及到一個always@(*)和assign表示組合邏輯電路時的不定態問題。舉個例子:
wire?a;
reg?b;
assign?a?=?1'b0;
always@(*)
b?=?1'b0;
在這種情況下,做仿真時a將會正常為0,但是b卻是不定態。這是為什么?verilog規定,always@(*)中的*是指該always塊內的所有輸入信號的變化為敏感列表,也就是仿真時只有當always@(*)塊內的輸入信號產生變化,該塊內描述的信號才會產生變化,而像
always@(*)?b?=?1'b0?;
這種寫法由于1'b0一直沒有變化,所以b的信號狀態一直沒有改變,由于b是組合邏輯輸出,所以復位時沒有明確的值(不定態),而又因為always@(*)塊內沒有敏感信號變化,因此b的信號狀態一直保持為不定態。
3)是否是因為是初始態的原因,沒有進行run(如果run之后clk發生變化就是該原因)
2.在ISE仿真時我的pc始終為XXXXXX?或?instruction?始終為XXXXXXX
A2:最有可能的情況是?PC未進行初始化,建議在測試文件里reset一下或者可以在pc模塊中對pc的值進行初始化。
如果你在你的pc模塊中發現如此定義且reset后還是不可以,那么請注意你是否有如下類似語句:
assign?PC?=?______?或者
PC?<=?_____
如果賦值給PC不是一個input變量而是中間變量,那么需要對這些中間變量進行初始化!
完成以上內容,一般PC的初始值會變成0,即仿真的第一步完成了。
3.如果我在PC值為0時下一步我的PC值沒有像正常的PC+1?而是變成了不定值?
A3:對于這種問題?請注意在頂層設計模塊中你是否有傳往PC的NPC的控制信號是否進行了初始化?(一般初始化控制信號可以解決這個問題)
4.我的控制信號是對的,輸入也是對的,case語句寫的也是對的,為什么最后結果不對?
A4:遇到這種情況,請檢查下列是否出錯:
1)?語句的==后面的常量值是否寫清楚了位數?如果是類似于if(memtoreg==01)的語句,請將它改成if(memtoreg==2’b01)的格式以確保正確。
2)?請檢查多個if條件判斷是否會出現矛盾。
四、?VerilogHDL代碼編寫建議
以下是關于編寫VerilogHDL代碼的建議。
1.避免引入鎖存器!
當你用always建模組合邏輯時,為了避免引入鎖存器,必須做到:
s?每一個if描述語句都有對應的else語句。
s?每一個case語句都對應一個default語句。
2.在always塊中是順序執行的,所以請注意賦值順序!
3.在“always”塊內被賦值的每一個信號都必須定義成reg型。
4.always語句由于其不斷重復執行的特性,只有和一定的時序控制結合在一起才有用。如果一個always語句沒有時序控制,則這個always語句將會發成一個仿真死鎖。見下例:
always?areg?=?~areg;
這個always語句將會生成一個0延遲的無限循環跳變過程,這時會發生仿真死鎖。
所以請注意,請一定不要單獨使用always!
5.請注意一個模塊的輸入不可以為reg類型!
6.輸入端口可以由wire/reg驅動,但輸入端口只能是wire;輸出端口可以是wire/reg類型,輸出端口只能驅動wire。
項塔蘭?致
總結
以上是生活随笔為你收集整理的ise verilog多模块编译_如何使用ISE高效开发Verilog项目(新手)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MSSQL SERVER 2005 数学
- 下一篇: shell中修改=后的值