例項九— 除法器設計
4.3 例項九 除法器設計(Robei工具)
4.3.1. 本章導讀
要求掌握除法器原理,並根據原理設計除法器模組以及設計對應的測試模組,最後在 Robei視覺化模擬軟體經行功能實現和模擬驗證。
設計原理
這個除法器的設計為傳統除法器,因此十分簡單,易懂:
(1)先取除數和被除數的正負關係,然後正值化被除數,由於需要遞減的除數,所以除數應取負值和補碼形式。
(2)被除數每一次遞減,商數遞增。
(3)直到被除數小於除數,遞減過程剩下的是餘數。
(4)輸出的結果根據除數和被除數的正負關係。
下圖4-3-1顯示除法器模組的設計:
4.3.2. 設計流程
1. divider模型設計
(1)新建一個模型命名為divider,型別為module,同時具備5輸入3輸出,每個引腳的屬性和名稱參照下圖4-3-2經行對應的修改。
(2)新增程式碼。點選模型下方的 Code新增程式碼。
程式碼:
reg[3:0] i;
reg[7:0] dsor;
reg[7:0] rd;
reg[7:0] dend;
reg[7:0] qent;
reg isneg;
reg isdone;
always @(posedge clk or negedge rst_n)
if(!rst_n)
begin
i<=4’d0;
dend<=8’d0;
dsor<=8’d0;
rd<=8’d0;
qent<=8’d0;
isneg<=1’b0;
isdone<=1’b0;
end
else if(start_sig)
case(i)
0: begin
dend<=dividend[7]?~dividend+1:dividend;
dsor<=divisor[7]?~divisor+1:divisor;
rd<=divisor[7]?divisor:(~divisor+1);
isneg<=dividend[7]^divisor[7];
qent<=8’d0;
i<=i+1;
end
1: begin
if(dend<dsor)
begin
qent<=isneg?(~qent+1):qent;
i<=i+1;
end
else
begin
dend<=dend+rd;
qent<=qent+1;
end
end
2:begin
isdone<=1’b1;
i<=i+1;
end
3:begin
isdone<=1’b0;
i<=4’d0;
end
endcase
assign done_sig=isdone;
assign quotient=qent;
assign remainder=dend;
(3)儲存模型到一個資料夾(資料夾路徑不能有空格和中文)中,執行並檢查有無錯誤。
2. divider_test測試檔案的設計
(1)新建一個5輸入3輸出的divider_test測試檔案,將Module Type設定為“testbench”,各個引腳配置如圖4-3-4所示。
(2)另存為測試檔案。將測試檔案儲存到上面建立的模型所在的資料夾下。
(3)加入模型。在Toolbox工具箱的Current欄裡,會出現模型,單擊該模型並在divider _test上新增,並連線引腳,如下圖4-3-5所示:
(4)輸入激勵。點選測試模組下方的“Code”,輸入激勵演算法。激勵程式碼在結束的時候要用$finish 結束。
測試程式碼:
initial
begin
clk=1’b0;
rst_n=1’b0;
#10 rst_n=1’b1;
#1000 $finish;
end
always #5 clk=~clk;
reg[3:0] i;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
dividend<=8’d0;
divisor<=8’d0;
start_sig<=1’b0;
i<=1’b0;
end
else
begin
case(i)
0:if(done_sig)
begin
start_sig<=1’b0;
i<=i+1;
end
else
begin
dividend<=8’d9;
divisor<=8’d3;
start_sig<=1’b1;
end
1:if(done_sig)
begin
start_sig<=1’b0;
i<=i+1;
end
else
begin
dividend<=8’d3;
divisor<=8’d9;
start_sig<=1’b1;
end
2:if(done_sig)
begin
start_sig<=1’b0;
i<=i+1;
end
else
begin
dividend<=8’d8;
divisor<=8’d2;
start_sig<=1’b1;
end
3:if(done_sig)
begin
start_sig<=1’b0;
i<=i+1;
end
else
begin
dividend<=8’d8;
divisor<=8’d4;
start_sig<=1’b1;
end
4:if(done_sig)
begin
start_sig<=1’b0;
i<=i+1;
end
else
begin
dividend<=8’d8;
divisor<=8’d3;
start_sig<=1’b1;
end
5:i<=4’d5;
endcase
end
end
(5)執行模擬並檢視波形。檢視輸出資訊。檢查沒有錯誤之後檢視波形。
點選右側 Workspace 中的訊號,進行新增並檢視分析模擬結果。如圖4-3-6所示:
3. divider_constrain約束檔案的設計
由於開發板硬體資源限制,我們在後端設計中把除法器的dividend和divisor由8位改為4位,以達到更直觀的驗證效果。
(1)新建一個模組,命名為divider_constrain,具備11個輸入和9個輸出。
(2)把約束模組儲存到和設計的divider模組同一個目錄下,先開啟divider模組把dividend,divisor,quotient,remainder資料長度都改成4位,儲存並執行,之後通過滑鼠左鍵單擊把divider模組新增進約束模組。
(3)連線:分別把divider模組的clk,rst_n,start_sig和約束模組的一個輸入端相連;把divider模組的dividend,divisor分別和約束模組的四個輸入端相連;然後把divider模組的輸出done_sig和約束模組的一個輸出端相連,把quotient,remainder和約束模組的4個輸出端相連。
(4)修改約束模組的埠名稱和連線名稱。約束模組的埠名稱即分配到開發板上的硬體引腳。本次設計中使用的引腳如下:
clk對應開發板開關G15;
rst_n對應開發板開關P15;
start_sig對應開發板開關W13;
dividend[0],dividend[1],dividend[2],dividend[3]分別對應V13,U17,T17,Y17;
divisor[0],divisor[1],divisor[2],divisor[3]分別對應V12,W16,J15,H15;
done_sig對應開發板LED燈M14;
quotient[0],quotient[1],quotient[2],quotient[3]分別對應U14,U15,V17,V18;
remainder[0],remainder[1],remainder[2],remainder[3]分別對應T14,T15,P14,R14;
修改完埠名稱後,記得修改對應divident,divisor,quotient,remainder的連線名稱分別為0,1,2,3。完成修改後的模組圖如圖4-3-7所示。
(5)儲存並執行,如果看到顯示“Generate constrain file complete”字樣,說明約束檔案已經成功生成,同樣也可以點選View->CodeView來檢視程式碼。
4.3.3. 板級驗證
為了測試所設計divider的工作特性,需選擇搭載XILINX公司的Z-7010晶片的開發板,所以選用VIVADO設計平臺進行Synthesis、Implementation和Generate Bitstream,最終將生成的資料流檔案下載到開發板內,並進行驗證。
1. VIVADO設計平臺進行後端設計
1.1啟動Vivado軟體並選擇裝置XC7Z010CLG400-1作為硬體物件,設計語言選用Verilog,建立新的工程,新增通過Robei設計的檔案divider.v。
(1)開啟Vivado,選擇開始>所有程式>Xilinx Design Tools> Vivado2013.4> Vivado2013.4;
(2)單擊建立新專案Create New Project啟動向導。你將看到建立一個新的Vivado專案對話方塊,單擊Next;
(3)在彈出的對話方塊中輸入工程名divider及工程儲存的位置,並確保Create project subdirectory核取方塊被選中,單擊Next;
(4)選擇專案型別表單的RTL Project選項,不要勾選Do not specify sources at this time核取方塊,然後單擊Next;
(5)使用下拉按鈕,選中Verilog作為目標檔案和模擬語言;
(6)點選新增Add Files按鈕,瀏覽到剛剛我們Robei專案的目錄下開啟Verilog資料夾,選擇divider.v,單擊Open,然後單擊Next去新增現有的IP模型;
(7)由於我們沒有任何的IP新增,跳過這一步,單擊Next去新增約束形成;
(8)點選新增Add Files按鈕,瀏覽到剛剛設計的目錄下找到constrain資料夾,選擇其中的divider_constrain.xdc檔案,單擊open完成新增;
(9)在預設視窗中,按照圖4-3-13所示設定Filer中的選項,然後在Parts中選擇XC7Z010CLG400-1,單擊Next;
(10)單擊Finish,本Vivado專案建立成功。
1.2開啟divider_constrain.xdc檔案,可以檢視引腳約束原始碼。
(1)在資源視窗sources中,展開約束資料夾,然後雙擊開啟divider_constrain.xdc進入文字編輯模式;
(2)Xilinx設計約束檔案分配FPGA位於主機板上的開關和指示燈的物理IO地址,這些資訊可以通過主機板的原理圖或電路板的使用者手冊來獲得。
本次設計的約束檔案程式碼是通過Robei軟體自動生成,但是,Robei軟體目前生成的約束程式碼只有對輸入輸出埠的分配,在這個設計中,我們使用了一個通過開關控制的模擬時鐘clk,而非系統時鐘,這種電路在綜合的時候一般都會報錯,所以,在約束檔案最後,我們需要手動新增一句命令:
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets clk_IBUF]
來保證流程中不會出錯。
完整的約束程式碼如下:
#This file is generated by Robei!
#Pin Assignment for Xilinx FPGA with Software Vivado.
set_property PACKAGE_PIN G15 [get_ports clk]
set_property IOSTANDARD LVCMOS33 [get_ports clk]
set_property PACKAGE_PIN P15 [get_ports rst_n]
set_property IOSTANDARD LVCMOS33 [get_ports rst_n]
set_property PACKAGE_PIN M14 [get_ports done_sig]
set_property IOSTANDARD LVCMOS33 [get_ports done_sig]
set_property PACKAGE_PIN V12 [get_ports divisor[0]]
set_property IOSTANDARD LVCMOS33 [get_ports divisor[0]]
set_property PACKAGE_PIN W16 [get_ports divisor[1]]
set_property IOSTANDARD LVCMOS33 [get_ports divisor[1]]
set_property PACKAGE_PIN J15 [get_ports divisor[2]]
set_property IOSTANDARD LVCMOS33 [get_ports divisor[2]]
set_property PACKAGE_PIN H15 [get_ports divisor[3]]
set_property IOSTANDARD LVCMOS33 [get_ports divisor[3]]
set_property PACKAGE_PIN V13 [get_ports dividend[0]]
set_property IOSTANDARD LVCMOS33 [get_ports dividend[0]]
set_property PACKAGE_PIN U17 [get_ports dividend[1]]
set_property IOSTANDARD LVCMOS33 [get_ports dividend[1]]
set_property PACKAGE_PIN T17 [get_ports dividend[2]]
set_property IOSTANDARD LVCMOS33 [get_ports dividend[2]]
set_property PACKAGE_PIN Y17 [get_ports dividend[3]]
set_property IOSTANDARD LVCMOS33 [get_ports dividend[3]]
set_property PACKAGE_PIN T14 [get_ports {remainder[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports remainder[0]]
set_property PACKAGE_PIN T15 [get_ports remainder[1]]
set_property IOSTANDARD LVCMOS33 [get_ports remainder[1]]
set_property PACKAGE_PIN P14 [get_ports remainder[2]]
set_property IOSTANDARD LVCMOS33 [get_ports remainder[2]]
set_property PACKAGE_PIN R14 [get_ports remainder[3]]
set_property IOSTANDARD LVCMOS33 [get_ports remainder[3]]
set_property PACKAGE_PIN U14 [get_ports quotient[0]]
set_property IOSTANDARD LVCMOS33 [get_ports quotient[0]]
set_property PACKAGE_PIN U15 [get_ports quotient[1]]
set_property IOSTANDARD LVCMOS33 [get_ports quotient[1]]
set_property PACKAGE_PIN V17 [get_ports quotient[2]]
set_property IOSTANDARD LVCMOS33 [get_ports quotient[2]]
set_property PACKAGE_PIN V18 [get_ports quotient[3]]
set_property IOSTANDARD LVCMOS33 [get_ports quotient[3]]
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets clk_IBUF]
(3)點選File—>Save File儲存檔案。
1.3使用Vivado綜合工具來綜合設計,並進行Implementation任務實現。
(1)單擊綜合任務下拉選單中的Run Synthesis,綜合過程將會在divider.v檔案以及所有分層檔案中執行。當綜合過程完成了,且沒有錯誤資訊,將會彈出帶有三個選項的完成對話方塊;
(2)如果有錯誤,根據錯誤資訊提示修改,直至綜合沒有錯誤。然後選擇Run Implementation選項,執行任務實現,然後單擊OK;
(3)任務實現過程將在綜合後的設計上執行。當這個過程完成,且沒有錯誤資訊,將會彈出帶有三個選項的任務實現完成對話方塊;
(4)如果有錯誤,根據錯誤資訊提示修改,直至綜合沒有錯誤。
1.4將開發板上的電源開關撥到ON,生成位元流並開啟硬體會話,對FPGA進行程式設計。
(1)確保微型USB電纜連線到PROG UART介面(在電源開關的旁邊);
(2)確保JP7設定為USB提供電源;
(3)接通電源板上的開關;
(4)點選任務實現完成彈出的對話方塊中Generate Bitstream或者點選導航視窗中程式設計和除錯任務中的Generate Bitstream。位元流生成過程將在任務實現設計後執行。當完成位元流生成後會彈出有三個選項的完成對話方塊;
(5)這一過程將已經生成的divider.bit檔案放在divider.runs目錄下的impl_1目錄下;
(6)選擇開啟硬體管理器Open Hardware Manager選項,然後單擊確定。硬體管理器視窗將開啟並顯示“未連線”狀態;
(7)點選Open a new hardware target。如果之前已經配置過開發板你也可以點選最近開啟目標連結Open recent target;
(8)單擊Next看Vivado自定義搜尋引擎伺服器名稱的形式;
(9)單擊Next以選擇本地主機埠;
(10)單擊兩次Next,然後單擊Finish。未連線硬體會話狀態更改為伺服器名稱並且器件被高亮顯示,如圖4-3-19所示。還要注意,該狀態表明它還沒有被程式設計;
(11)在器件上單擊滑鼠右鍵,選擇Program device或單擊視窗上方彈出的Program device-> XC7z010_1連結到目標FPGA器件進行程式設計;
(12)單擊確定對FPGA進行程式設計。開發板上Done指示燈亮時,器件程式設計結束;
(13)通過控制撥動和按鍵開關的開閉來觀察LED(請參考前面的邏輯圖)驗證輸出結果。
2. 開發板驗證
首先,將rst_n(SW1)復位開關撥之低電平,再來回撥動1至2次clk(BTNC)按鍵,進行復位操作,之後將rst_n撥至高電平;
然後,設定被除數和除數值,這裡選擇被除數為6,除數為2進行驗證;
除數SW74,被除數SW30,商LD30,餘數LD74。
最後,每次按一下clk時鐘鍵,給一個上升沿,程式進行一次運算。第一次上升沿後,quotient為0,reminder為6,故LD7~0的顯示為00000110;第二次上升沿後,quotient為1,reminder為4,故LD7~0的顯示為00010100;第三次上升沿後,quotient為2,reminder為2,故LD7~0的顯示為00100010;第四次上升沿後,quotient為3,reminder為0,故LD7~0的顯示為00110000,此時計算結束,done_sig亮起,經驗證該除法器本次運算無誤。
重複以上步驟,設定不同的被除數和除數值進行多方位驗證,通過驗證結果證明該除法器符合設計的要求。
4.3.4. 問題與思考
挑戰題:讀者們可能發現以上設計的除法器每一次運算消耗的時鐘不一致,當除數的數量越大,它消耗的時鐘的就越大,所以下面請讀者們上網搜尋迴圈式除法器的資料,並以迴圈式除法器的演算法設計一個運算過程消耗時鐘一致的迴圈式除法器。
相關文章
- 設計模式例項程式碼設計模式
- Jmeter beanshell程式設計例項JMeterBean程式設計
- KafKa Java程式設計例項KafkaJava程式設計
- 數字IC設計 FPGA——再談乘法器設計(使用Verilog 原語 LUT 進行四位乘法器設計)FPGA
- 解析JavaScript設計模型Iterator例項JavaScript模型
- Verilog設計技巧例項及實現
- 基於Verilog的陣列乘法器設計陣列
- 設計模式:命令模式(Command Pattern)及例項設計模式
- MySQL與MongoDB設計例項對比QYMySqlMongoDB
- 設計模式 - 原則及例項講解設計模式
- 設計模式例項講解 - 里氏替換設計模式
- 設計模式例項講解 - 介面隔離設計模式
- 設計模式例項講解 - 依賴倒置設計模式
- C++設計模式+例項視訊教程C++設計模式
- DophinScheduler 如何定期刪除日誌例項?
- 設計模式使用例項(5)——建造者模式例項之資料庫連線管理設計模式資料庫
- 設計模式例項講解 - 開放封閉設計模式
- shell script程式設計小結——附帶例項程式設計
- Dreamweaver網頁製作教程:表格設計例項網頁
- Spark程式設計環境搭建及WordCount例項Spark程式設計
- JavaScript刪除元素節點程式碼例項JavaScript
- C++學習隨筆——簡單的單例設計模式例項C++單例設計模式
- Python - 物件導向程式設計 - 類變數、例項變數/類屬性、例項屬性Python物件程式設計變數
- [翻譯]返回導向程式設計例項入門程式設計
- VC++視覺化程式設計第一個程式設計例項出錯C++視覺化程式設計
- 例項七— 8位移位暫存器的設計
- LINUX Shell指令碼程式設計例項詳解(一)上Linux指令碼程式設計
- 微控制器C程式設計例項指導pdfC程式程式設計
- makefile--偽目標語法與程式設計例項程式設計
- 10個最新互動式Web設計例項欣賞Web
- 基於FPGA的乘法器原理介紹及設計實現FPGA
- PHP+Ajax微信手機端九宮格抽獎例項PHP
- k8s透過api介面刪除例項K8SAPI
- 基於SEH的靜態反除錯(例項分析)除錯
- 刪除所有正在執行和退出的docker例項Docker
- 刪除字串中的html標籤程式碼例項字串HTML
- 詳解Python物件導向程式設計之類、例項、方法Python物件程式設計
- 最新SS園設計模式例項剖析與深入解讀教程設計模式