Xilinx AXI VIP使用教程

AXI接口虽然经常使用,很多同学可能并不清楚Vivado里面也集成了AXI的Verification IP,可以当做AXI的master、pass through和slave,本次内容我们看下AXI VIP当作master时如何使用。

  新建Vivado工程,并新建block design,命名为:axi_demo

6595724402f398842d721e549dea1808.png


新建axi vip,参数设置如下,第一个参数设置为Master,其他都保持默认,当然如果可以根据自己的实际需求作改动,比如id位宽,数据位宽等等。

1c60e0cbeeafcad5d82177e02e0102a8.png
image-20230726185112648

再添加AXI BRAM Controller和Block Memory Generator:

9464f0988907f7b0216de6ccefea1ca2.png


地址分配如下:0xc000_0000

d5cad1c157e4f59bad28c00d67a68a4c.png


生成ip的各种文件:

f521bb35adbacc20779d1257fc4fa2eb.png

新建仿真的tb_top文件,需要注意,文件类型是system verilog。

892c253521b1595aae59ea7c3bbd9ab3.png
image-20230726185756796

仿真代码放到文章末尾,代码中中导入的axi_demo_axi_vip_0_0_pkg,就是下面axi vip的component_name再加上后缀_pkg,后面的mst_agent也是component_name加上后缀 _mst_t

import axi_demo_axi_vip_0_0_pkg::*;
axi_demo_axi_vip_0_0_mst_t              mst_agent;
1627bbe2d5e3f73ef53845146e67110c.png
image-20230726190026270

运行仿真:

395f152e3ad739f4bb771ddc2f13936a.png
image-20230726190219346

将axi vip的M-AXI添加到波形窗口中:

6989363022c75c47f848cb13a1bd8f02.png
image-20230726190445127

可以看到,我们一开始向地址0xc0001000写入0x12345678,又发起一次读操作,可以将该数据读出。

d5993c3667ddcc60e01d8df0a72a124c.png
image-20230726190702883

有同学可能习惯用vcs来仿真,下篇文章我们再用vcs+verdi来仿真vivado的axi vip。

`timescale 1ns / 1ps

import axi_vip_pkg::*;
import axi_demo_axi_vip_0_0_pkg::*;

module tb_top();

bit clk;
bit aresetn;

//used in API and parital randomization for transaction generation and data read back from driver
axi_transaction                         wr_transaction;                // Write transaction
axi_transaction                         rd_transaction;                // Read transaction

xil_axi_uint                            mtestWID;                      // Write ID  
xil_axi_ulong                           mtestWADDR;                    // Write ADDR  
xil_axi_len_t                           mtestWBurstLength;             // Write Burst Length   
xil_axi_size_t                          mtestWDataSize;                // Write SIZE  
xil_axi_burst_t                         mtestWBurstType;               // Write Burst Type  
xil_axi_uint                            mtestRID;                      // Read ID  
xil_axi_ulong                           mtestRADDR;                    // Read ADDR  
xil_axi_len_t                           mtestRBurstLength;             // Read Burst Length   
xil_axi_size_t                          mtestRDataSize;                // Read SIZE  
xil_axi_burst_t                         mtestRBurstType;               // Read Burst Type  
xil_axi_lock_t                          mtestLOCK;                     // LOCK value for WRITE/READ_BURST transaction
xil_axi_cache_t                         mtestCacheType = 3;            // Cache Type value for WRITE/READ_BURST transaction
xil_axi_prot_t                          mtestProtectionType = 3'b000;  // Protection Type value for WRITE/READ_BURST transaction
xil_axi_region_t                        mtestRegion = 4'b000;          // Region value for WRITE/READ_BURST transaction
xil_axi_qos_t                           mtestQOS = 4'b000;             // QOS value for WRITE/READ_BURST transaction
xil_axi_data_beat                       dbeat;                         // Data beat value for WRITE/READ_BURST transaction
xil_axi_user_beat                       usrbeat;                       // User beat value for WRITE/READ_BURST transaction
xil_axi_data_beat [255:0]               mtestWUSER;                    // Wuser value for WRITE/READ_BURST transaction
xil_axi_data_beat                       mtestAWUSER = 'h0;             // Awuser value for WRITE/READ_BURST transaction
xil_axi_data_beat                       mtestARUSER = 0;               // Aruser value for WRITE/READ_BURST transaction
xil_axi_data_beat [255:0]               mtestRUSER;                    // Ruser value for WRITE/READ_BURST transaction
xil_axi_uint                            mtestBUSER = 0;                // Buser value for WRITE/READ_BURST transaction
xil_axi_resp_t                          mtestBresp;                    // Bresp value for WRITE/READ_BURST transaction
xil_axi_resp_t[255:0]                   mtestRresp;                    // Rresp value for WRITE/READ_BURST transaction

bit [63:0]                             mtestWData;                     // Write Data
bit[8*4096-1:0]                        Wdatablock;                     // Write data block
xil_axi_data_beat                      Wdatabeat[];                    // Write data beats

bit [63:0]                             mtestRData;                     // Read Data
bit[8*4096-1:0]                        Rdatablock;                     // Read data block
xil_axi_data_beat                      Rdatabeat[];                    // Read data beats


  initial begin
    aresetn = 1'b0;
    clk = 1'b0;
    #100ns;
    aresetn = 1'b1;
  end
   
  always #10 clk <= ~clk;

axi_demo u_dut(
    .aclk_0       (clk     ),
    .aresetn_0    (aresetn )
);

axi_demo_axi_vip_0_0_mst_t              mst_agent;

initial begin
    mst_agent = new("master vip agent",u_dut.axi_vip_0.inst.IF);
    mst_agent.start_master();               // mst_agent start to run
    mtestWID = $urandom_range(0,(1<<(0)-1)); 
    mtestWADDR = 'hc000_1000;//$urandom_range(0,(1<<(32)-1));
    mtestWBurstLength = 0;
    mtestWDataSize = xil_axi_size_t'(xil_clog2((32)/8));
    mtestWBurstType = XIL_AXI_BURST_TYPE_INCR;
    mtestWData = 'h12345678;//$urandom();
    $display("mtestWDataSize = %d", mtestWDataSize);
    //single write transaction filled in user inputs through API 
    single_write_transaction_api("single write with api",
                                 .id(mtestWID),
                                 .addr(mtestWADDR),
                                 .len(mtestWBurstLength), 
                                 .size(mtestWDataSize),
                                 .burst(mtestWBurstType),
                                 .wuser(mtestWUSER),
                                 .awuser(mtestAWUSER), 
                                 .data(mtestWData)
                                 );
                                  
    mtestRID = $urandom_range(0,(1<<(0)-1));
    mtestRADDR = mtestWADDR;
    mtestRBurstLength = 0;
    mtestRDataSize = xil_axi_size_t'(xil_clog2((32)/8)); 
    mtestRBurstType = XIL_AXI_BURST_TYPE_INCR;
    
    $display("mtestRDataSize = %d", mtestRDataSize);
    //single read transaction filled in user inputs through API 
    single_read_transaction_api("single read with api",
                                 .id(mtestRID),
                                 .addr(mtestRADDR),
                                 .len(mtestRBurstLength), 
                                 .size(mtestRDataSize),
                                 .burst(mtestRBurstType)
                                 );
end

  task automatic single_write_transaction_api ( 
                                input string                     name ="single_write",
                                input xil_axi_uint               id =0, 
                                input xil_axi_ulong              addr =0,
                                input xil_axi_len_t              len =0, 
                                input xil_axi_size_t             size =xil_axi_size_t'(xil_clog2((32)/8)),
                                input xil_axi_burst_t            burst =XIL_AXI_BURST_TYPE_INCR,
                                input xil_axi_lock_t             lock = XIL_AXI_ALOCK_NOLOCK,
                                input xil_axi_cache_t            cache =3,
                                input xil_axi_prot_t             prot =0,
                                input xil_axi_region_t           region =0,
                                input xil_axi_qos_t              qos =0,
                                input xil_axi_data_beat [255:0]  wuser =0, 
                                input xil_axi_data_beat          awuser =0,
                                input bit [63:0]              data =0
                                                );
    axi_transaction                               wr_trans;
    $display("single_write_transaction_api size = %d", size);
    wr_trans = mst_agent.wr_driver.create_transaction(name);
    wr_trans.set_write_cmd(addr,burst,id,len,size);
    wr_trans.set_prot(prot);
    wr_trans.set_lock(lock);
    wr_trans.set_cache(cache);
    wr_trans.set_region(region);
    wr_trans.set_qos(qos);
    wr_trans.set_data_block(data);
    mst_agent.wr_driver.send(wr_trans);   
  endtask  : single_write_transaction_api 
 
  task automatic single_read_transaction_api ( 
                                    input string                     name ="single_read",
                                    input xil_axi_uint               id =0, 
                                    input xil_axi_ulong              addr =0,
                                    input xil_axi_len_t              len =0, 
                                    input xil_axi_size_t             size =xil_axi_size_t'(xil_clog2((32)/8)),
                                    input xil_axi_burst_t            burst =XIL_AXI_BURST_TYPE_INCR,
                                    input xil_axi_lock_t             lock =XIL_AXI_ALOCK_NOLOCK ,
                                    input xil_axi_cache_t            cache =3,
                                    input xil_axi_prot_t             prot =0,
                                    input xil_axi_region_t           region =0,
                                    input xil_axi_qos_t              qos =0,
                                    input xil_axi_data_beat          aruser =0
                                                );
    axi_transaction                               rd_trans;
    $display("single_read_transaction_api size = %d", size);
    rd_trans = mst_agent.rd_driver.create_transaction(name);
    rd_trans.set_read_cmd(addr,burst,id,len,size);
    rd_trans.set_prot(prot);
    rd_trans.set_lock(lock);
    rd_trans.set_cache(cache);
    rd_trans.set_region(region);
    rd_trans.set_qos(qos);
    mst_agent.rd_driver.send(rd_trans);   
  endtask  : single_read_transaction_api

endmodule

猜你喜欢

转载自blog.csdn.net/Pieces_thinking/article/details/132332021