1. 程式人生 > 其它 >基於Axi4_lite協議的自定義IP模擬平臺的搭建

基於Axi4_lite協議的自定義IP模擬平臺的搭建

  做FPGA開發離不開模擬,模擬對於FPGA的除錯開發起到了很好的輔助作用。對於新手而言模擬就更加重要了,老練的FPGA開發者時序瞭然於胸,對於簡單的IP核開發是可以省略模擬的步驟,但是對於絕大多數的情況而言,模擬不僅能提高工作效率,而且能夠提高開發者的時序分析能力。模擬是驗證最常用的手段,雖說現在很多FPGA裡頭集成了邏輯分析,但是直接上板除錯還是會損耗不少的時間,一方面是跑綜合需要足夠的時間,另一方面板上除錯的資源有限,很多的錯誤並不能合理的排查。以此在寫完程式碼後最好是先做模擬,模擬沒問題了再上板除錯。

  正常情況下模擬都會用到模擬工具,我一般用的模擬工具是modelsim,vivavo雖說也有自帶的模擬,但是使用起來不僅麻煩,而且時序會跟modelsim的有些偏差。

  下面的模擬平臺的搭建就是基於前面所講的axi4_lite協議,對自定義IP核GPIO進行模擬。模擬程式碼主要是用system Verilog語言來完成,學過C或C++的應該能比較容易看懂,會Verilog語言的看SV語言應該難度也不大。

  一般封裝好的IP會在一個資料夾下:

  資料夾下會放doc檔案及ip檔案,doc用來存放IP核的暫存器說明及操作文件,ip則用來放IP核的相關程式碼。

  ip檔案下存放if,rtl,sim檔案,if放封裝時可能需自定義的介面,rtl放IP核原始碼,sim放模擬程式碼。

  rtl:

 

  sim:

  使用的時候直接雙擊run.bat檔案即可,modelsim自動開啟並模擬。

  run.bat程式碼:

1 modelsim -do sim.do

  sim.do程式碼:

 1 #刪除work工作目錄
 2 file delete -force work
 3     
 4 #設定uvm環境變數,指定uvm的dpi位置
 5 set UVM_DPI_HOME D:/modeltech64_10.5/uvm-1.1d/win64
 6 
 7 #建立work工作目錄
 8 vlib work
 9 
10 #vlog表示編譯 *.sv表示do檔案同級路徑下所有.sv檔案 -L表示新增庫檔案
11 vlog -L mtiAvm -L mtiOvm -L mtiUvm -L mtiUPF *.sv
12 13 #編譯原始檔,包含覆蓋率測試 14 vlog -cover sbctf -coveropt 3 ../rtl/*.v 15 16 #執行模擬,開啟覆蓋率視窗,不使能優化,呼叫uvm庫uvm_dpi,利用UVM_TEST_NAME從命令列中尋找測試用例的名字,建立它的例項並執行 17 vsim -coverage -novopt -c -sv_lib $UVM_DPI_HOME/uvm_dpi work.Gpio_sim +UVM_TESTNAME=case0 18 19 #觀察DUT的訊號波形 20 add wave -position insertpoint sim:/Gpio_sim/u_Axi4_Gpio/* 21 22 run 10ms

  頂層模擬檔案Gpio_sim.sv:

  1 //**************************************************************************
  2 // *** file name      : Gpio_sim.sv
  3 // *** version        : 1.0
  4 // *** Description    : Gpio IP core testbech
  5 // *** Blogs          : https://www.cnblogs.com/WenGalois123/
  6 // *** Author         : Galois_V
  7 // *** Date           : 2022.4.7        
  8 // *** Changes        :       
  9 //**************************************************************************
 10 `timescale 1ns/1ps
 11 `define GPIO_NUM 32
 12 
 13 module Gpio_sim();
 14     
 15 /******************************************************************************\   
 16 Define AXI4-lite interface port
 17 \******************************************************************************/        
 18     wire                w_axi_aclk       ;
 19     wire                w_axi_aresetn    ;
 20     
 21     wire    [31:0]      w_axi_awaddr     ;
 22     wire                w_axi_awvalid    ;
 23     wire                w_axi_awready    ;
 24     
 25     wire    [31:0]      w_axi_wdata      ;
 26     wire    [3:0]       w_axi_wstrb      ;
 27     wire                w_axi_wvalid     ;
 28     wire                w_axi_wready     ;
 29     
 30     wire    [1:0]       w_axi_bresp      ;
 31     wire                w_axi_bvalid     ;
 32     wire                w_axi_bready     ;
 33     
 34     wire    [31:0]      w_axi_araddr     ;
 35     wire                w_axi_arvalid    ;
 36     wire                w_axi_arready    ;
 37     
 38     wire    [31:0]      w_axi_rdata      ;
 39     wire    [1:0]       w_axi_rresp      ;
 40     wire                w_axi_rvalid     ;
 41     wire                w_axi_rready     ;
 42     
 43 /******************************************************************************\   
 44 Instantiate AXI4-lite master module
 45 \******************************************************************************/
 46     m_axi4_lite_if u_m_axi4_lite_if
 47     (
 48         .o_sys_clk                 (w_axi_aclk                ),
 49         .o_sys_rstn                (w_axi_aresetn             ),
 50         .o_m_axi_awaddr            (w_axi_awaddr              ),
 51         .o_m_axi_awvalid           (w_axi_awvalid             ),
 52         .i_m_axi_awready           (w_axi_awready             ),
 53         .o_m_axi_wdata             (w_axi_wdata               ),
 54         .o_m_axi_wstrb             (w_axi_wstrb               ),
 55         .o_m_axi_wvalid            (w_axi_wvalid              ),
 56         .i_m_axi_wready            (w_axi_wready              ),
 57         .i_m_axi_bresp             (w_axi_bresp               ),
 58         .i_m_axi_bvalid            (w_axi_bvalid              ),
 59         .o_m_axi_bready            (w_axi_bready              ),
 60         .o_m_axi_araddr            (w_axi_araddr              ),
 61         .o_m_axi_arvalid           (w_axi_arvalid             ),
 62         .i_m_axi_arready           (w_axi_arready             ),
 63         .i_m_axi_rdata             (w_axi_rdata               ),
 64         .i_m_axi_rresp             (w_axi_rresp               ),
 65         .i_m_axi_rvalid            (w_axi_rvalid              ),
 66         .o_m_axi_rready            (w_axi_rready              )
 67     );
 68     
 69 /******************************************************************************\   
 70 Instantiate AXI4-lite slave IP core
 71 \******************************************************************************/
 72     reg        [31:0]        w_gpio_i;
 73     Axi4_Gpio    
 74     #( 
 75         .IO_NUM    (`GPIO_NUM)                
 76     )    
 77     u_Axi4_Gpio
 78     (
 79         .i_s_axi_aclk              (w_axi_aclk                ),    
 80         .i_s_axi_aresetn           (w_axi_aresetn             ),   
 81         .i_s_axi_awaddr            (w_axi_awaddr              ),     
 82         .i_s_axi_awprot            ('d0                       ),     
 83         .i_s_axi_awvalid           (w_axi_awvalid             ),  
 84         .o_s_axi_awready           (w_axi_awready             ),  
 85         .i_s_axi_wdata             (w_axi_wdata               ),    
 86         .i_s_axi_wstrb             (w_axi_wstrb               ),    
 87         .i_s_axi_wvalid            (w_axi_wvalid              ),     
 88         .o_s_axi_wready            (w_axi_wready              ),     
 89         .o_s_axi_bresp             (w_axi_bresp               ),    
 90         .o_s_axi_bvalid            (w_axi_bvalid              ),     
 91         .i_s_axi_bready            (w_axi_bready              ),     
 92         .i_s_axi_araddr            (w_axi_araddr              ),     
 93         .i_s_axi_arprot            ('d0                       ),     
 94         .i_s_axi_arvalid        (w_axi_arvalid             ),  
 95         .o_s_axi_arready           (w_axi_arready             ),  
 96         .o_s_axi_rdata             (w_axi_rdata               ),    
 97         .o_s_axi_rresp             (w_axi_rresp               ),    
 98         .o_s_axi_rvalid            (w_axi_rvalid              ),     
 99         .i_s_axi_rready            (w_axi_rready              ),      
100         
101         .i_gpio_if_i               (w_gpio_i                  ),
102         .o_gpio_if_o               (                          ),
103         .o_gpio_if_t               (                          )  
104     ); 
105     
106 
107     
108 /******************************************************************************\   
109 Perform the steps of IP core in sequence
110 \******************************************************************************/    
111     reg  [31:0] r_cpu_rd_data;
112     initial r_cpu_rd_data = 0;
113 
114 
115     initial
116     begin  
117         $display("start"); 
118         #2000;
119         u_m_axi4_lite_if.arm_write_data(32'h00000000,32'h5aa5a55a,4'hf);
120         #200;
121         u_m_axi4_lite_if.arm_write_data(32'h00000004,32'h5a00005a,4'hf);
122         #200;
123         u_m_axi4_lite_if.arm_read_data(32'h00000000,r_cpu_rd_data);
124         #200;
125         u_m_axi4_lite_if.arm_read_data(32'h00000004,r_cpu_rd_data);
126         #200;
127         w_gpio_i = 32'h1234567;
128         u_m_axi4_lite_if.arm_read_data(32'h00000008,r_cpu_rd_data);
129         $display("sim complete"); 
130     end
131 
132 endmodule

     產生激勵模組m_axi4_lite_if.sv:

  1 //**************************************************************************
  2 // *** file name      : m_axi4_lite_if.sv
  3 // *** version        : 1.0
  4 // *** Description    : axi4_lite_if master
  5 // *** Blogs          : https://www.cnblogs.com/WenGalois123/
  6 // *** Author         : Galois_V
  7 // *** Date           : 2022.4.7        
  8 // *** Changes        :       
  9 //**************************************************************************
 10 `timescale 1ns/1ps
 11 
 12 module m_axi4_lite_if
 13 (
 14     output    reg                    o_sys_clk,
 15     output    reg                    o_sys_rstn,
 16     
 17     output    reg    [31:0]          o_m_axi_awaddr,
 18     output    reg                    o_m_axi_awvalid,
 19     input                            i_m_axi_awready,
 20     
 21     output    reg    [31:0]          o_m_axi_wdata,
 22     output    reg    [3:0]           o_m_axi_wstrb,
 23     output    reg                    o_m_axi_wvalid,
 24     input                            i_m_axi_wready,
 25     
 26     input        [1:0]               i_m_axi_bresp,
 27     input                            i_m_axi_bvalid,
 28     output    reg                    o_m_axi_bready,
 29     
 30     output    reg    [31:0]          o_m_axi_araddr,
 31     output    reg                    o_m_axi_arvalid,
 32     input                            i_m_axi_arready,
 33     
 34     input        [31:0]              i_m_axi_rdata,
 35     input        [1:0]               i_m_axi_rresp,
 36     input                            i_m_axi_rvalid,
 37     output    reg                    o_m_axi_rready
 38 );
 39 
 40     parameter               SYS_CLK = 100_000_000  ,
 41                             TIME_1S = 1000_000_000 ;
 42     
 43     
 44     real clk_cnt = TIME_1S/SYS_CLK;
 45 /******************************************************************************\   
 46 產生模擬環境需要的時鐘與復位訊號,這裡的時鐘訊號為125MHz                                                      
 47 \******************************************************************************/    
 48     initial//所有的initial模組都是並行的,initial模組的語句是按順序執行的。
 49     begin 
 50         o_sys_clk = 0;
 51         o_sys_rstn = 0;
 52         #1000;
 53         o_sys_rstn = 1;
 54     end
 55     
 56     always #(clk_cnt/2) o_sys_clk = ~o_sys_clk;
 57 
 58 /******************************************************************************\   
 59 先初始化axi4-lite的輸出量訊號                                                      
 60 \******************************************************************************/    
 61     initial
 62     begin 
 63         o_m_axi_awaddr         = 'd0;
 64         o_m_axi_awvalid     = 'd0;
 65         o_m_axi_wdata         = 'd0;
 66         o_m_axi_wstrb         = 'd0;
 67         o_m_axi_wvalid        = 'd0;
 68         o_m_axi_bready        = 'd0;
 69         o_m_axi_araddr        = 'd0;
 70         o_m_axi_arvalid        = 'd0;
 71         o_m_axi_rready         = 'd0;
 72     end
 73 /******************************************************************************\   
 74 通過axi4-lite匯流排寫資料,寫task                                                     
 75 \******************************************************************************/        
 76     task arm_write_data
 77     ( 
 78         input    [31:0]    i_addr , 
 79         input    [31:0]    i_data ,
 80         input    [3:0]    i_byte_en
 81     );
 82     begin
 83         @(posedge o_sys_clk)
 84         begin 
 85             o_m_axi_awaddr = i_addr;
 86             o_m_axi_awvalid = 1'b1;
 87             o_m_axi_wdata = i_data;
 88             o_m_axi_wstrb = i_byte_en;
 89             o_m_axi_wvalid = 1'b1;
 90             o_m_axi_bready = 1'b1;
 91         end
 92         @(posedge o_sys_clk); 
 93         begin
 94             while(~(i_m_axi_awready & i_m_axi_wready))    //
 95             begin
 96                 @(posedge o_sys_clk)
 97                 begin
 98                     o_m_axi_awvalid = 1'b0;
 99                     o_m_axi_wvalid = 1'b0;
100                 end
101             end
102         end
103         
104         @(posedge o_sys_clk)
105         begin
106             while(~i_m_axi_bvalid)
107             begin
108                 @(posedge o_sys_clk)
109                 begin
110                     if(i_m_axi_bresp != 2'b00)
111                     begin
112                         $display("write fail");
113                     end
114                 end
115             end
116         end
117         
118         o_m_axi_bready = 1'b0;
119     end
120     endtask
121 
122 
123 /******************************************************************************\   
124 通過axi4-lite匯流排讀資料,讀task                                                  
125 \******************************************************************************/    
126     task arm_read_data
127     ( 
128         input    [31:0]    i_addr,
129         output    [31:0]    o_rdata
130     );
131     begin
132         @(posedge o_sys_clk)
133         begin
134             o_m_axi_araddr = i_addr;
135             o_m_axi_arvalid = 1'b1;
136             o_m_axi_rready = 1'b1;
137         end
138         
139         @(posedge o_sys_clk)
140         begin
141             while(~i_m_axi_arready)
142             begin
143                 @(posedge o_sys_clk)
144                 begin
145                     o_m_axi_arvalid = 1'b0;
146                 end
147             end
148         end
149         @(posedge o_sys_clk)
150         begin
151             o_rdata = i_m_axi_rdata;
152             while(~i_m_axi_rvalid)
153             begin
154                 if(i_m_axi_rresp!=2'b00)
155                 $display("read fail");
156             end
157         end
158         
159         o_m_axi_rready = 1'b0;
160     end
161     endtask
162 
163 endmodule

  以上便是整個axi4_lite 的模擬平臺搭建,可以根據實際需要增加新的介面功能,比如axi4_stream介面這些。

  模擬的結果如下圖: