Vivado進行FPGA調試「犯罪現場」,在仿真環境中重現方法

在FPGA調試過程中,經常遇到這樣的情況:出現BUG時,想採用仿真環境把FPGA調試中遇到的BUG給重現出來,但無論怎樣改變仿真環境中的激勵,都無法重現FPGA上的出現BUG的情況。此時,如果有一種方法,能夠把FPGA正在運行時產生BUG前所有的輸入變量狀態給捕獲下來,然後作為激勵,添加到仿真環境中去,這樣以來,就能夠重現FPGA運行時出現的BUG,就可以在仿真環境中去解決這個BUG,調試的複雜度瞬間降低很多,也能大大的提高FPGA調試的效率。

本文介紹一種利用Vivado進行FPGA調試時,如何把FPGA調試中的數據給“捕獲”出來,並保存為文件,轉換到仿真環境中進行仿真,“重現”FPGA調試運行場景的方法。

Vivado進行FPGA調試“犯罪現場”,在仿真環境中重現方法

1、背景

從一個RTL代碼描述的電路到FPGA樣機的過程可以分為兩個階段,第一階段為仿真驗證,第二階段為FPGA驗證。仿真驗證是激勵數據源常常由自己編寫,往往與板級驗證數據源(如TestCenter等網絡測試儀產生的以太網數據包)存在較大區別,因此在這裡介紹一種將板級驗證數據導入仿真Testbench中的方法。使用這種方法,可以使仿真驗證數據源最大限度地接近板級數據源,可以輔助排除絕大部分的邏輯錯誤。

Vivado進行FPGA調試“犯罪現場”,在仿真環境中重現方法

2、操作流程

這裡我們還以Zedboard Debug數據導出到Testbench為例,對具體實施流程進行介紹,如圖1所示,該流程可以分為3個步驟:

(1) Zedboard,抓取感興趣的數據,並通過jtag線傳輸到上位機;

(2) 在上位機Vivado軟件的Tcl Console中輸入命令,將抓取的數據另存為wave.csv文件;

(3) 將wave.csv文件中的數據導入Testbench中,最終輸出波形。

Vivado進行FPGA調試“犯罪現場”,在仿真環境中重現方法

圖1 操作流程

3、 操作實例

下面給出一個實例,針對圖1的三個步驟,對操作流程進行詳細介紹。

(1) 抓取感興趣的數據,如圖2所示。

Vivado進行FPGA調試“犯罪現場”,在仿真環境中重現方法

圖2 抓取感興趣的數據

(2) 如圖3所示,在tclconsole中輸入命令,將抓取的數據轉存為wave,csv,轉存後的文件如圖4所示。

Vivado進行FPGA調試“犯罪現場”,在仿真環境中重現方法

圖3 tcl console輸入命令

Vivado進行FPGA調試“犯罪現場”,在仿真環境中重現方法

圖4 wave.csv文件

(3)將圖4中的數據存入RAM中,並在Testbench中循環讀取,獲得波形數據,如圖5所示。

Vivado進行FPGA調試“犯罪現場”,在仿真環境中重現方法

圖5 波形數據

通過這樣的方法,就可以把FPGA運行時的輸入激勵數據捕獲到文件中,進而轉換到仿真環境中進行調試。

按照慣例,我們給出上述過程的源碼。

FPGA工程源代碼

1`timescale 1ns/1ps

2

3module CAPTURE_TOP (

4 input clk

5 ) ;

6

7//REGS

8reg [30:0] cnt ;

9//WIRES

10 wire rst ;

11 wire [31:0] cnt_capture ;

12

13//INSTANTCE MODULE

14vio_rst u_vio_rst (

15 .clk(clk), // input wire clk

16 .probe_out0(rst) // output wire [0 : 0] probe_out0

17 );

18

19ila_0 u_ila_0 (

20 .clk(clk), // input wire clk

21 .probe0(cnt_capture) // input wire [31:0] probe0

22 );

23

24//MAIN CORE

25

26always @(posedge clk or posedge rst) begin

27 if (rst == 1'b1) begin

28 cnt <= 'd0 ;

29 end

30 else begin

31 cnt <= cnt+'d3 ;

32 end

33end

34

35assign cnt_capture = {1'b1, cnt} ;

36

37endmodule

38

Zedboard開發板約束文件

1set_property PACKAGE_PIN Y9 [get_ports clk]

2set_property IOSTANDARD LVCMOS33 [get_ports clk]

仿真環境TESTBENCH文件

1`timescale 1ns/1ps

2 module CAPTURE_TEST_TOP ;

3//REGS

4 reg clk ;

5 reg rst ;

6 reg [9:0] addra ;

7

8//WIRES

9 wire [30:0] dout ;

10 wire [31:0] douta ;

11

12ROM_32_1024 your_instance_name (

13 .clka(clk), // input wire clka

14 .ena(1'b1), // input wire ena

15 .addra(addra), // input wire [9 : 0] addra

16 .douta(douta) // output wire [31 : 0] douta

17);

18

19 always @(posedge clk or posedge rst) begin

20 if (rst == 1'b1) begin

21 addra <= 'd0 ;

22 end

23 else

begin

24 addra <= addra + 1'b1 ;

25 end

26 end

27

28 assign dout = douta[30:0] ;

29

30//MAIN CORE

31initial begin

32 clk = 1'b0 ;

33 rst = 1'b1 ;

34 # 100

35 rst = 1'b0 ;

36 end

37 always # 10 clk = ~clk ;

38

39endmodule

注:上述文件中ROM模塊(data_1024.coe)數據來自圖4所示的數據。


分享到:


相關文章: