我們將以三個設計樣例,助力您提升設計開發效率。
對于FPGA應用開發來說,代碼是寫出來的,更是調試出來的。軟件仿真擁有最佳的信號可見性和調試靈活性,被大多數工程師熟練使用,能夠高效捕獲很多顯而易見的常見錯誤。
然而,由軟件實現的數字仿真過程運行速度有限,很難做到100%代碼覆蓋。導致那些隱藏的設計問題,將不可避免的逃逸,只能以FPGA 在線調試方式解決。換而言之,硬件在線調試將成為查找設計bug、解決設計潛在缺陷的最后防線。
如果對處于全速(at-speed)運行下的FPGA調試,在現有通用“能力技術”基礎上,再增加“硬件斷點”功能,那么也就對高速運行FPGA,擁有像調試軟件程序類似的完整的可控制能力:
- 凍結時鐘,FPGA“原地”保持靜止不動,獲取周期精確的信號數據;
- 釋放時鐘:就像松開了FPGA“剎車片”,繼續恢復至全速運行狀態。
以賽靈思FPGA為例,用戶已經能從硬件的運行特征出發,為設計增加兩類硬件斷點:
其中最基礎的是時鐘斷點(Clock-based Breakpoint),可視為“運行時鐘周期數觸發的中斷”,即FPGA設計在運行過程中,一旦遇到時鐘斷點,立即暫停執行,原地原位保持靜止狀態,用于獲取周期精確的信號數據。
- 用戶在設計階段,只需將下面的鐘斷點控制模塊(interruption logic),事先集成到待測DUT的頂層(hw_top),就可獲得這樣的在線調試能力。
本文是系列文章的第一篇,將以最基礎的 counter設計作為樣例,以按圖索驥的方式,詳細介紹在設計中集成時鐘斷點的實現過程,對原有設計的改動非常小,仍然保持優異的時序性能。
以下為正文
1.樣例簡要介紹
輸入時鐘為125 MHz,按秒計時輸出,由8個LED燈循環顯示當前讀秒計數。對應的頂層設計top.v如下:
//===========================================================================
// top.v
//===========================================================================
module top(input gclk,input reset, output [7:0] count_o
);wire [26:0] i_counter;// instantiate module countcount inst_count (.rst (reset),.clk (gclk),.count_out (count_o),.count (i_counter));
endmodule//===========================================================================
// count.v
//===========================================================================
module count (clk,rst,count_out,count
);input rst; // Active low resetinput clk; // 125MHz input clockoutput reg [7:0] count_out; // Output to LEDsoutput reg [26:0] count;//Counter to reduce speed of outputalways @(posedge clk)if (!rst) begincount <= 0;endelse begin count <= count + 1;endalways @(posedge clk)if (!rst)count_out <= 8'h00;else beginif (count == 27'h773_5940) begincount_out <= count_out + 1;endendendmodule
對應的約束文件:
#Arty A7-35T Pinout## Clock signal
create_clock -name gclk -period 8.000 [get_ports gclk]
set_property IOSTANDARD LVCMOS33 [get_ports { gclk }]
set_property PACKAGE_PIN E3 [get_ports { gclk }]#Counter 8-bit input and outputs - RST signal and LED indicators
## 4 LEDs
## Blue LEDs for another 4 led counting
set_property IOSTANDARD LVCMOS33 [get_ports {count_o[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {count_o[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {count_o[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {count_o[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {count_o[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {count_o[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {count_o[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {count_o[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports reset]set_property PACKAGE_PIN H5 [get_ports {count_o[0]}]
set_property PACKAGE_PIN J5 [get_ports {count_o[1]}]
set_property PACKAGE_PIN T9 [get_ports {count_o[2]}]
set_property PACKAGE_PIN T10 [get_ports {count_o[3]}]
set_property PACKAGE_PIN E1 [get_ports {count_o[4]}]
set_property PACKAGE_PIN G4 [get_ports {count_o[5]}]
set_property PACKAGE_PIN H4 [get_ports {count_o[6]}]
set_property PACKAGE_PIN K2 [get_ports {count_o[7]}]
set_property PACKAGE_PIN A8 [get_ports reset]
當您按照創建Vivado設計項目,導入以上約束文件時,請按照自己的硬件板卡定義進行修改。
2.? 時鐘斷點控制模塊
該模塊位于forgedaX軟件/breakpoint/controller/clock-based子目錄。
module interruption_logic((* dont_touch = "true" *) output reg [63:0] cycles,input sys_clk,input sys_reset,output task_clk
);wire clk_en;wire [63:0] breakpoint;reg [63:0] counter;reg break;il_vio_0 il_vio (.clk(sys_clk),.probe_in0(counter),.probe_in1(cycles),.probe_out0(breakpoint),.probe_out1(clk_en));always @(posedge sys_clk)beginif (!sys_reset)begincounter <= 0;break <= 0;endelse if (clk_en)beginif (counter == breakpoint)beginbreak <= 1'b1;endelsebegincounter <= counter + 1;break <= 1'b0;endendendBUFGCE inst_bufgce (.O(task_clk),.I(sys_clk),.CE(clk_en & ~break));always @(posedge task_clk)beginif (!sys_reset) begincycles <= 0;end elsebegincycles <= cycles + 1;endendendmodule
該模塊非常精簡,對您的原生設計的改動很小,所占用的硬件資源也非常少,應用設計在集成斷點后,仍然保持優異的時序性能。
在本樣例中,該斷點控制模塊僅使用了不到700個LUT,在7A35T芯片總計20800個LUT資源中,占比約為3.36%。
3.??將時鐘斷點模塊集成到設計中
時鐘斷點控制模塊與原有設計的融合集成,全程在Xilinx Vivado環境下完成,共有三個步驟。
Step 1. 導入斷點控制模塊
在Vivado Project Manager中,選擇“Add Source”
選擇“Add or create design Source”,單擊“Next”
選擇“Add Files”
選擇forgedaX軟件提供的時鐘斷點控制模塊interruption logic。
模塊代碼位于breakpoint/controller/clock-based/interruption_logic_v1.v,單擊“OK”。
單擊“Finish”,確認導入該模塊文件。
模塊成功導入,在Project Manager中顯示如下:
Step 2. 導入斷點控制模塊所使用的VIO IP核
在Vivado中,選擇“IP Catalog”,導入VIO IP核。
在IP Catalog搜索框中,直接輸入VIO,顯示如下:
在Customize IP核界面,對VIO IP進行參數設置:
設置兩個輸出端口的參數:
點擊“OK”,確認以上參數配置。
在IP生成對話框中,保持默認設置,點擊“Generate”,生成VIO IP核。
顯示“Generation of output products completed successfully”消息,表示IP核已成功導入。
在Project Manager窗口顯示如下:
Step 3. 在頂層設計中,對中斷控制模塊進行實例化,獲得受控的時鐘信號
對設計頂層(hw_top)的時鐘進行處理,對原有設計的改動非常少,就可實現對該時鐘控制模塊的融合集成,兩者的比對如下:
備注:在本樣例中,原始設計的頂層文件位于
<forgedaX軟件目錄>/demo/vivado_counter/counter/counter.srcs/sources_1/imports/Source/top.v
集成斷點控制模塊后的頂層文件,詳見:
<forgedaX軟件目錄>/demo/vivado_counter_clk_bp/counter-bp/counter-bp.srcs/sources_1/imports/Source/top.v
4.? 重新啟動Vivado編譯過程
啟動Vivado編譯,生成新的設計結果文件(.dcp), 得到的配置位流文件top.bit,以及調試支撐文件debug_nets.ltx。
5.? 用Hardware Manager驗證斷點的集成過程
您可直接在Vivado Hardware Manager中,驗證以上集成過程是否正確。
當對應的位流文件、調試支撐文件載入到FPGA之后,樣例設計暫停運行。打開VIO調試窗口,選擇Add Probes:
如下圖所示,斷點地址位于以上第2部分設置的初始值,即0xF。
繼續在VIO窗口,將斷點地址設置為FFFF_FFFF_FFFF_FFFF,清除斷點,樣例繼續全速運行,如下圖。
以上兩個操作正確完成,標志著時鐘斷點已成功集成到本樣例設計中。
后續將介紹事件斷點(Event-based Breakpoint)的集成和使用,持續更新中。
全文完,感謝您的耐心閱讀