SystemVerilog——Axi4Lite_To_Localbus

摘要:用SystemVerilog对Axi4转localbus进行编写与仿真

如果需要从PS端对PL进行寄存器的读写操作,从znyq M_AXI_HPM_FPD出来,经过axi_interconnect 模块分出多个通道(不同的地址),经过一个axi_slave模块,再传到本地的寄存器内。

1. axi_slave

module jb_axi_slave #(
    parameter   AXI_ADDR_WIDTH  = 13,
    parameter   AXI_DATA_WIDTH  = 32

) (
    input                       clk,
    input                       srst,
    jb_axi4_lite_if.slave       IFP_axi4_lite,
    jb_axi_regs_if.master       IFP_axi_rw
);

    localparam  ADDR_LSB = (AXI_DATA_WIDTH/32) + 1;


   // AXI4LITE signals
   logic [AXI_ADDR_WIDTH-1 : 0]           axi_awaddr   ='h0   ;
   logic 					              axi_awready  ='h0   ;
   logic 					              axi_wready   ='h0   ;
   logic [1 : 0] 				          axi_bresp    ='h0   ;
   logic 					              axi_bvalid   ='h0   ;
   logic [AXI_ADDR_WIDTH-1 : 0] 		  axi_araddr   ='h0   ;
   logic 					              axi_arready  ='h0   ;
   logic [AXI_DATA_WIDTH-1 : 0] 		  axi_rdata    ='h0   ;
   logic [1 : 0] 				          axi_rresp    ='h0   ;
   logic 					              axi_rvalid   ='h0   ;
   logic [AXI_DATA_WIDTH-1 : 0] 		  reg_data_out    ;

  
   logic                    aw_en = 'h0;
  
   
   // I/O Connections assignments

   assign IFP_axi4_lite.awready	= axi_awready;
   assign IFP_axi4_lite.wready	= axi_wready;
   assign IFP_axi4_lite.bresp	= axi_bresp;
   assign IFP_axi4_lite.bvalid	= axi_bvalid;
   assign IFP_axi4_lite.arready	= axi_arready;
   assign IFP_axi4_lite.rdata	= axi_rdata;
   assign IFP_axi4_lite.rresp	= axi_rresp;
   assign IFP_axi4_lite.rvalid	= axi_rvalid;


   // Assert axi_awready  when awvalid & wvalid is high

   always @( posedge clk ) begin
      if ( srst == 1'b1 ) begin
	 axi_awready <= 1'b0;
	 aw_en <= 1'b1;
      end 
      else begin    
	 if (~axi_awready && IFP_axi4_lite.awvalid && IFP_axi4_lite.wvalid && aw_en) begin
	    // Assumption no outstanding transaction
	    axi_awready <= 1'b1;
	    aw_en <= 1'b0;
	 end
	 else if ( IFP_axi4_lite.bready && axi_bvalid) begin
	    aw_en <= 1'b1;
	    axi_awready <= 1'b0;
	 end
	 else begin
	    axi_awready <= 1'b0;
	 end
      end 
   end      

   //Latch the address based on valid
   always @( posedge clk )  begin
	if ( srst == 1'b1 )  begin
	     axi_awaddr <= 0;
	  end 
	else begin    
	   if (~axi_awready && IFP_axi4_lite.awvalid && IFP_axi4_lite.wvalid && aw_en) begin
	      // Write Address latching 
	      axi_awaddr <= IFP_axi4_lite.awaddr;
	   end
	end 
   end       
   
   //Assert wreaddy for a clock cycle when awvalid and wvalid is asserted aw_en is set
   always @( posedge clk ) begin
      if ( srst == 1'b1 )  begin
	 axi_wready <= 1'b0;
      end 
      else begin    
	 if (~axi_wready && IFP_axi4_lite.awvalid && IFP_axi4_lite.wvalid && aw_en ) begin
	    // 
	    axi_wready <= 1'b1;
	 end
	 else begin
	    axi_wready <= 1'b0;
	 end
      end 
   end       


   assign IFP_axi_rw.wren = axi_wready &&  IFP_axi4_lite.awvalid && IFP_axi4_lite.wvalid && axi_awready;


   //BVALID AND BRESP SETTINGS
   always @( posedge clk ) begin								  
      if ( srst == 1'b1 )  begin
	 axi_bvalid  <= 0;
	 axi_bresp   <= 2'b0;
      end 
      else begin    
	 if (axi_awready && IFP_axi4_lite.awvalid  && ~axi_bvalid && axi_wready && IFP_axi4_lite.wvalid)  begin
	    // indicates a valid write response is available
	    axi_bvalid <= 1'b1;
	    axi_bresp  <= 2'b0; // 'OKAY' response 
	 end                   // work error responses in future
	 else begin
	    if (IFP_axi4_lite.bready && axi_bvalid) begin 
	       //check if bready is asserted while bvalid is high) 
	       //(there is a possibility that bready is always asserted high)
	       axi_bvalid <= 1'b0; 
	    end  
	 end
      end
   end 

  
  // READ LOGIC /
  
   always @( posedge clk ) begin 
      if ( srst == 1'b1 ) begin
	 axi_arready <= 1'b0;
	 axi_araddr  <= 32'b0;
      end 
      else begin 
	 if (~axi_arready && IFP_axi4_lite.arvalid) begin
	    // indicates that the slave has acceped the valid read address
	    axi_arready <= 1'b1;
	    // Latch Read address
	    axi_araddr  <= IFP_axi4_lite.araddr;
	 end
	 else begin
	    axi_arready <= 1'b0;
	 end
      end 
   end 


   //Latch the address based on valid
   always @( posedge clk ) begin
      if ( srst == 1'b1 ) begin
	 axi_rvalid <= 0;
	 axi_rresp  <= 0;
      end 
      else begin    
	 if (axi_arready && IFP_axi4_lite.arvalid && ~axi_rvalid) begin
	    // Valid read data is available at the read data bus
	    axi_rvalid <= 1'b1;
	    axi_rresp  <= 2'b0; // 'OKAY' response
	 end   
	 else if (axi_rvalid && IFP_axi4_lite.rready)   begin
	    // Read data is accepted by the master
	    axi_rvalid <= 1'b0;
	 end                
      end
   end 

   assign IFP_axi_rw.rden = axi_arready & IFP_axi4_lite.arvalid & ~axi_rvalid;   


   // Output register or memory read data
   //Latch the address based on valid
   always @( posedge clk ) begin
      if ( srst == 1'b1 ) begin
	 axi_rdata  <= 0;
      end 
      else begin    
	 if (IFP_axi_rw.rden)  begin
	    axi_rdata <= reg_data_out;     // register read data
	 end   
      end
   end 

  assign reg_data_out = IFP_axi_rw.rdata;	  
   
 


///WRITE LOGIC 
  assign IFP_axi_rw.wr_offset = axi_awaddr[AXI_ADDR_WIDTH-1:ADDR_LSB];
//  assign IFP_axi_rw.wr_offset = axi_awaddr;

///READ LOGIC 
  assign IFP_axi_rw.rd_offset = axi_araddr[AXI_ADDR_WIDTH-1:ADDR_LSB];
//  assign IFP_axi_rw.rd_offset = axi_araddr;


  assign IFP_axi_rw.wdata = IFP_axi4_lite.wdata;





endmodule
   


这段代码的核心就是对axi_lite进行握手操作,同时得到:

IFP_axi_rw.rden、IFP_axi_rw.rdata、IFP_axi_rw.wren、IFP_axi_rw.wdata、IFP_axi_rw.wr_offset、IFP_axi_rw.rd_offset

用这些信号将数据送入寄存器中或者从寄存器中读出数据。

2. regs


module jb_helpchip_regs ( 
    input                           clk, 
    input                           srst,  
    jb_axi_regs_if.slave            IFP_axi_rw, 
    jb_helpchip_ctrl_if.ctrl         IFP_helpchip_ctrl
);

    `include "jb_db_HC_params.svh"



Register Field Declarations//

   logic  [15:0]              HC_VERSION_REGISTER_hc_revision_num;
  // Revision number
   logic  [7:0]              HC_VERSION_REGISTER_hc_minor_version;
  // minor version
   logic  [7:0]              HC_VERSION_REGISTER_hc_major_version;
  // major version
   logic  [31:0]              HC_DEBUG_REVISION_hc_debug_revision;
  // Debug build version. Should be 0 for official builds. 
   logic  [31:0]              HC_DEBUG_RW_0_hc_debug_rw_0;
  // debug ethernet loopback
   logic  [31:0]              HC_DEBUG_RW_1_hc_debug_rw_1;
  // debug ethernet restart_tx_rx
   logic  [31:0]              HC_DEBUG_RW_2_hc_debug_rw_2;
  // debug ethernet sys_reset
   logic  [31:0]              HC_DEBUG_RW_3_hc_debug_rw_3;
  // 
   logic  [31:0]              HC_DEBUG_RW_4_hc_debug_rw_4;
  // 
   logic  [31:0]              HC_DEBUG_RW_5_hc_debug_rw_5;
  // 
   logic  [31:0]              HC_DEBUG_RW_6_hc_debug_rw_6;
  // 
   logic  [31:0]              HC_DEBUG_RW_7_hc_debug_rw_7;
  // 
   logic  [31:0]              HC_DEBUG_RW_8_hc_debug_rw_8;
  // 
   logic  [31:0]              HC_DEBUG_RW_9_hc_debug_rw_9;
  // 
   logic  [31:0]              HC_DEBUG_RW_10_hc_debug_rw_10;
  // 
   logic  [31:0]              HC_DEBUG_RW_11_hc_debug_rw_11;
  // 
   logic  [31:0]              HC_DEBUG_RW_12_hc_debug_rw_12;
  // 
   logic  [31:0]              HC_DEBUG_RW_13_hc_debug_rw_13;
  // 
   logic  [31:0]              HC_DEBUG_RW_14_hc_debug_rw_14;
  // 
   logic  [31:0]              HC_DEBUG_RW_15_hc_debug_rw_15;
  // 
   logic  [31:0]              HC_DEBUG_RW_16_hc_debug_rw_16;
  // 
   logic  [31:0]              HC_DEBUG_RW_17_hc_debug_rw_17;
  // 
   logic  [31:0]              HC_DEBUG_RW_18_hc_debug_rw_18;
  // 
   logic  [31:0]              HC_DEBUG_RW_19_hc_debug_rw_19;
  // 
   logic  [31:0]              HC_DEBUG_RW_20_hc_debug_rw_20;
  // 
   logic  [31:0]              HC_DEBUG_RW_21_hc_debug_rw_21;
  // 
   logic  [31:0]              HC_DEBUG_RW_22_hc_debug_rw_22;
  // 
   logic  [31:0]              HC_DEBUG_RW_23_hc_debug_rw_23;
  //  
   logic  [31:0]              HC_DEBUG_RW_24_hc_debug_rw_24;
  //  
   logic  [31:0]              HC_DEBUG_RW_25_hc_debug_rw_25;
  //  
   logic  [31:0]              HC_DEBUG_RW_26_hc_debug_rw_26;
  //  
   logic  [31:0]              HC_DEBUG_RW_27_hc_debug_rw_27;
  //  
   logic  [31:0]              HC_DEBUG_RW_28_hc_debug_rw_28;
  //  
   logic  [31:0]              HC_DEBUG_RW_29_hc_debug_rw_29;
  //  
   logic  [31:0]              HC_DEBUG_RW_30_hc_debug_rw_30;
  // 
   logic  [31:0]              HC_DBG_SCRATCH_hc_dbg_scratch;
  //  








ASSIGN PARAMETERS//

   assign  HC_VERSION_REGISTER_hc_revision_num =  HC_REVISION_NUM;
   assign  HC_VERSION_REGISTER_hc_minor_version =  HC_MINOR_VERSION;
   assign  HC_VERSION_REGISTER_hc_major_version =  HC_MAJOR_VERSION;
   assign  HC_DEBUG_REVISION_hc_debug_revision =  HC_DEBUG_REVISION;




ASSIGN CONTROL RW INTF FIELDS//

   assign  IFP_helpchip_ctrl.debug_rw[0] =  HC_DEBUG_RW_0_hc_debug_rw_0;
   assign  IFP_helpchip_ctrl.debug_rw[1] =  HC_DEBUG_RW_1_hc_debug_rw_1;
   assign  IFP_helpchip_ctrl.debug_rw[2] =  HC_DEBUG_RW_2_hc_debug_rw_2;
   assign  IFP_helpchip_ctrl.debug_rw[3] =  HC_DEBUG_RW_3_hc_debug_rw_3;
   assign  IFP_helpchip_ctrl.debug_rw[4] =  HC_DEBUG_RW_4_hc_debug_rw_4;
   assign  IFP_helpchip_ctrl.debug_rw[5] =  HC_DEBUG_RW_5_hc_debug_rw_5;
   assign  IFP_helpchip_ctrl.debug_rw[6] =  HC_DEBUG_RW_6_hc_debug_rw_6;
   assign  IFP_helpchip_ctrl.debug_rw[7] =  HC_DEBUG_RW_7_hc_debug_rw_7;
   assign  IFP_helpchip_ctrl.debug_rw[8] =  HC_DEBUG_RW_8_hc_debug_rw_8;
   assign  IFP_helpchip_ctrl.debug_rw[9] =  HC_DEBUG_RW_9_hc_debug_rw_9;
   assign  IFP_helpchip_ctrl.debug_rw[10] =  HC_DEBUG_RW_10_hc_debug_rw_10;
   assign  IFP_helpchip_ctrl.debug_rw[11] =  HC_DEBUG_RW_11_hc_debug_rw_11;
   assign  IFP_helpchip_ctrl.debug_rw[12] =  HC_DEBUG_RW_12_hc_debug_rw_12;
   assign  IFP_helpchip_ctrl.debug_rw[13] =  HC_DEBUG_RW_13_hc_debug_rw_13;
   assign  IFP_helpchip_ctrl.debug_rw[14] =  HC_DEBUG_RW_14_hc_debug_rw_14;
   assign  IFP_helpchip_ctrl.debug_rw[15] =  HC_DEBUG_RW_15_hc_debug_rw_15;
   assign  IFP_helpchip_ctrl.debug_rw[16] =  HC_DEBUG_RW_16_hc_debug_rw_16;
   assign  IFP_helpchip_ctrl.debug_rw[17] =  HC_DEBUG_RW_17_hc_debug_rw_17;
   assign  IFP_helpchip_ctrl.debug_rw[18] =  HC_DEBUG_RW_18_hc_debug_rw_18;
   assign  IFP_helpchip_ctrl.debug_rw[19] =  HC_DEBUG_RW_19_hc_debug_rw_19;
   assign  IFP_helpchip_ctrl.debug_rw[20] =  HC_DEBUG_RW_20_hc_debug_rw_20;
   assign  IFP_helpchip_ctrl.debug_rw[21] =  HC_DEBUG_RW_21_hc_debug_rw_21;
   assign  IFP_helpchip_ctrl.debug_rw[22] =  HC_DEBUG_RW_22_hc_debug_rw_22;
   assign  IFP_helpchip_ctrl.debug_rw[23] =  HC_DEBUG_RW_23_hc_debug_rw_23;
   assign  IFP_helpchip_ctrl.debug_rw[24] =  HC_DEBUG_RW_24_hc_debug_rw_24;
   assign  IFP_helpchip_ctrl.debug_rw[25] =  HC_DEBUG_RW_25_hc_debug_rw_25;
   assign  IFP_helpchip_ctrl.debug_rw[26] =  HC_DEBUG_RW_26_hc_debug_rw_26;
   assign  IFP_helpchip_ctrl.debug_rw[27] =  HC_DEBUG_RW_27_hc_debug_rw_27;
   assign  IFP_helpchip_ctrl.debug_rw[28] =  HC_DEBUG_RW_28_hc_debug_rw_28;
   assign  IFP_helpchip_ctrl.debug_rw[29] =  HC_DEBUG_RW_29_hc_debug_rw_29;
   assign  IFP_helpchip_ctrl.debug_rw[30] =  HC_DEBUG_RW_30_hc_debug_rw_30;




ASSIGN STATUS RO INTF FIELDS//





///WRITE LOGIC 
  always @(posedge clk) begin
    if (srst) begin
                  HC_DEBUG_RW_0_hc_debug_rw_0 <= 'h0;  // debug ethernet loopback
                  HC_DEBUG_RW_1_hc_debug_rw_1 <= 'h1;  // debug ethernet restart_tx_rx
                  HC_DEBUG_RW_2_hc_debug_rw_2 <= 'h1;  // debug ethernet sys_reset
                  HC_DEBUG_RW_3_hc_debug_rw_3 <= 'h0;  // 
                  HC_DEBUG_RW_4_hc_debug_rw_4 <= 'h0;  // 
                  HC_DEBUG_RW_5_hc_debug_rw_5 <= 'h0;  // 
                  HC_DEBUG_RW_6_hc_debug_rw_6 <= 'h0;  // 
                  HC_DEBUG_RW_7_hc_debug_rw_7 <= 'h0;  // 
                  HC_DEBUG_RW_8_hc_debug_rw_8 <= 'h0;  // 
                  HC_DEBUG_RW_9_hc_debug_rw_9 <= 'h0;  // 
                  HC_DEBUG_RW_10_hc_debug_rw_10 <= 'h0;  // 
                  HC_DEBUG_RW_11_hc_debug_rw_11 <= 'h0;  // 
                  HC_DEBUG_RW_12_hc_debug_rw_12 <= 'h0;  // 
                  HC_DEBUG_RW_13_hc_debug_rw_13 <= 'h0;  // 
                  HC_DEBUG_RW_14_hc_debug_rw_14 <= 'h0;  // 
                  HC_DEBUG_RW_15_hc_debug_rw_15 <= 'h0;  // 
                  HC_DEBUG_RW_16_hc_debug_rw_16 <= 'h0;  // 
                  HC_DEBUG_RW_17_hc_debug_rw_17 <= 'h0;  // 
                  HC_DEBUG_RW_18_hc_debug_rw_18 <= 'h0;  // 
                  HC_DEBUG_RW_19_hc_debug_rw_19 <= 'h0;  // 
                  HC_DEBUG_RW_20_hc_debug_rw_20 <= 'h0;  // 
                  HC_DEBUG_RW_21_hc_debug_rw_21 <= 'h0;  // 
                  HC_DEBUG_RW_22_hc_debug_rw_22 <= 'h0;  // 
                  HC_DEBUG_RW_23_hc_debug_rw_23 <= 'h0;  //  
                  HC_DEBUG_RW_24_hc_debug_rw_24 <= 'h0;  //  
                  HC_DEBUG_RW_25_hc_debug_rw_25 <= 'h0;  //  
                  HC_DEBUG_RW_26_hc_debug_rw_26 <= 'h0;  //  
                  HC_DEBUG_RW_27_hc_debug_rw_27 <= 'h0;  //  
                  HC_DEBUG_RW_28_hc_debug_rw_28 <= 'h0;  //  
                  HC_DEBUG_RW_29_hc_debug_rw_29 <= 'h0;  //  
                  HC_DEBUG_RW_30_hc_debug_rw_30 <= 'h0;  // 
                  HC_DBG_SCRATCH_hc_dbg_scratch <= 'h3333_cccc;  //  
    end
    else if (IFP_axi_rw.wren) begin
      case(IFP_axi_rw.wr_offset)
      15'h7c0  : begin //'h1F00
                  HC_DEBUG_RW_0_hc_debug_rw_0 <= IFP_axi_rw.wdata[31:0];  // debug ethernet loopback
             end
      15'h7c1  : begin //'h1F04
                  HC_DEBUG_RW_1_hc_debug_rw_1 <= IFP_axi_rw.wdata[31:0];  // debug ethernet restart_tx_rx
             end
      15'h7c2  : begin //'h1F08
                  HC_DEBUG_RW_2_hc_debug_rw_2 <= IFP_axi_rw.wdata[31:0];  // debug ethernet sys_reset
             end
      15'h7c3  : begin //'h1F0C
                  HC_DEBUG_RW_3_hc_debug_rw_3 <= IFP_axi_rw.wdata[31:0];  // 
             end
      11'h7c4  : begin //'h1F10
                  HC_DEBUG_RW_4_hc_debug_rw_4 <= IFP_axi_rw.wdata[31:0];  // 
             end
      11'h7c5  : begin //'h1F14
                  HC_DEBUG_RW_5_hc_debug_rw_5 <= IFP_axi_rw.wdata[31:0];  // 
             end
      11'h7c6  : begin //'h1F18
                  HC_DEBUG_RW_6_hc_debug_rw_6 <= IFP_axi_rw.wdata[31:0];  // 
             end
      11'h7c7  : begin //'h1F1C
                  HC_DEBUG_RW_7_hc_debug_rw_7 <= IFP_axi_rw.wdata[31:0];  // 
             end
      11'h7c8  : begin //'h1F20
                  HC_DEBUG_RW_8_hc_debug_rw_8 <= IFP_axi_rw.wdata[31:0];  // 
             end
      11'h7c9  : begin //'h1F24
                  HC_DEBUG_RW_9_hc_debug_rw_9 <= IFP_axi_rw.wdata[31:0];  // 
             end
      11'h7ca  : begin //'h1F28
                  HC_DEBUG_RW_10_hc_debug_rw_10 <= IFP_axi_rw.wdata[31:0];  // 
             end
      11'h7cb  : begin //'h1F2C
                  HC_DEBUG_RW_11_hc_debug_rw_11 <= IFP_axi_rw.wdata[31:0];  // 
             end
      11'h7cc  : begin //'h1F30
                  HC_DEBUG_RW_12_hc_debug_rw_12 <= IFP_axi_rw.wdata[31:0];  // 
             end
      11'h7cd  : begin //'h1F34
                  HC_DEBUG_RW_13_hc_debug_rw_13 <= IFP_axi_rw.wdata[31:0];  // 
             end
      11'h7ce  : begin //'h1F38
                  HC_DEBUG_RW_14_hc_debug_rw_14 <= IFP_axi_rw.wdata[31:0];  // 
             end
      11'h7cf  : begin //'h1F3C
                  HC_DEBUG_RW_15_hc_debug_rw_15 <= IFP_axi_rw.wdata[31:0];  // 
             end
      11'h7d0  : begin //'h1F40
                  HC_DEBUG_RW_16_hc_debug_rw_16 <= IFP_axi_rw.wdata[31:0];  // 
             end
      11'h7d1  : begin //'h1F44
                  HC_DEBUG_RW_17_hc_debug_rw_17 <= IFP_axi_rw.wdata[31:0];  // 
             end
      11'h7d2  : begin //'h1F48
                  HC_DEBUG_RW_18_hc_debug_rw_18 <= IFP_axi_rw.wdata[31:0];  // 
             end
      11'h7d3  : begin //'h1F4C
                  HC_DEBUG_RW_19_hc_debug_rw_19 <= IFP_axi_rw.wdata[31:0];  // 
             end
      11'h7d4  : begin //'h1F50
                  HC_DEBUG_RW_20_hc_debug_rw_20 <= IFP_axi_rw.wdata[31:0];  // 
             end
      11'h7d5  : begin //'h1F54
                  HC_DEBUG_RW_21_hc_debug_rw_21 <= IFP_axi_rw.wdata[31:0];  // 
             end
      11'h7d6  : begin //'h1F58
                  HC_DEBUG_RW_22_hc_debug_rw_22 <= IFP_axi_rw.wdata[31:0];  // 
             end
      11'h7d7  : begin //'h1F5C
                  HC_DEBUG_RW_23_hc_debug_rw_23 <= IFP_axi_rw.wdata[31:0];  //  
             end
      11'h7d8  : begin //'h1F60
                  HC_DEBUG_RW_24_hc_debug_rw_24 <= IFP_axi_rw.wdata[31:0];  //  
             end
      11'h7d9  : begin //'h1F64
                  HC_DEBUG_RW_25_hc_debug_rw_25 <= IFP_axi_rw.wdata[31:0];  //  
             end
      11'h7da  : begin //'h1F68
                  HC_DEBUG_RW_26_hc_debug_rw_26 <= IFP_axi_rw.wdata[31:0];  //  
             end
      11'h7db  : begin //'h1F6C
                  HC_DEBUG_RW_27_hc_debug_rw_27 <= IFP_axi_rw.wdata[31:0];  //  
             end
      11'h7dc  : begin //'h1F70
                  HC_DEBUG_RW_28_hc_debug_rw_28 <= IFP_axi_rw.wdata[31:0];  //  
             end
      11'h7dd  : begin //'h1F74
                  HC_DEBUG_RW_29_hc_debug_rw_29 <= IFP_axi_rw.wdata[31:0];  //  
             end
      11'h7de  : begin //'h1F78
                  HC_DEBUG_RW_30_hc_debug_rw_30 <= IFP_axi_rw.wdata[31:0];  // 
             end
      11'h7ff  : begin //'h1FFC
                  HC_DBG_SCRATCH_hc_dbg_scratch <= IFP_axi_rw.wdata[31:0];  //  
               end
      endcase
    end
  end
///



///READ LOGIC 
  always @(*) begin
    IFP_axi_rw.rdata = 0;
    if (IFP_axi_rw.rden) begin
       case(IFP_axi_rw.rd_offset)
      15'h0  : begin//'h0
                   IFP_axi_rw.rdata[15:0] = HC_VERSION_REGISTER_hc_revision_num;  // Revision number
                   IFP_axi_rw.rdata[23:16] = HC_VERSION_REGISTER_hc_minor_version;  // minor version
                   IFP_axi_rw.rdata[31:24] = HC_VERSION_REGISTER_hc_major_version;  // major version
             end
      15'h1  : begin//'h4
                   IFP_axi_rw.rdata[31:0] = HC_DEBUG_REVISION_hc_debug_revision;  // Debug build version. Should be 0 for official builds. 
             end
      15'h7c0  : begin//'h1F00
                   IFP_axi_rw.rdata[31:0] = HC_DEBUG_RW_0_hc_debug_rw_0;  // debug ethernet loopback
             end
      15'h7c1  : begin//'h1F04
                   IFP_axi_rw.rdata[31:0] = HC_DEBUG_RW_1_hc_debug_rw_1;  // debug ethernet restart_tx_rx
             end
      15'h7c2  : begin//'h1F08
                   IFP_axi_rw.rdata[31:0] = HC_DEBUG_RW_2_hc_debug_rw_2;  // debug ethernet sys_reset
             end
      11'h7c3  : begin//'h1F0C
                   IFP_axi_rw.rdata[31:0] = HC_DEBUG_RW_3_hc_debug_rw_3;  // 
             end
      11'h7c4  : begin//'h1F10
                   IFP_axi_rw.rdata[31:0] = HC_DEBUG_RW_4_hc_debug_rw_4;  // 
             end
      11'h7c5  : begin//'h1F14
                   IFP_axi_rw.rdata[31:0] = HC_DEBUG_RW_5_hc_debug_rw_5;  // 
             end
      11'h7c6  : begin//'h1F18
                   IFP_axi_rw.rdata[31:0] = HC_DEBUG_RW_6_hc_debug_rw_6;  // 
             end
      11'h7c7  : begin//'h1F1C
                   IFP_axi_rw.rdata[31:0] = HC_DEBUG_RW_7_hc_debug_rw_7;  // 
             end
      11'h7c8  : begin//'h1F20
                   IFP_axi_rw.rdata[31:0] = HC_DEBUG_RW_8_hc_debug_rw_8;  // 
             end
      11'h7c9  : begin//'h1F24
                   IFP_axi_rw.rdata[31:0] = HC_DEBUG_RW_9_hc_debug_rw_9;  // 
             end
      11'h7ca  : begin//'h1F28
                   IFP_axi_rw.rdata[31:0] = HC_DEBUG_RW_10_hc_debug_rw_10;  // 
             end
      11'h7cb  : begin//'h1F2C
                   IFP_axi_rw.rdata[31:0] = HC_DEBUG_RW_11_hc_debug_rw_11;  // 
             end
      11'h7cc  : begin//'h1F30
                   IFP_axi_rw.rdata[31:0] = HC_DEBUG_RW_12_hc_debug_rw_12;  // 
             end
      11'h7cd  : begin//'h1F34
                   IFP_axi_rw.rdata[31:0] = HC_DEBUG_RW_13_hc_debug_rw_13;  // 
             end
      11'h7ce  : begin//'h1F38
                   IFP_axi_rw.rdata[31:0] = HC_DEBUG_RW_14_hc_debug_rw_14;  // 
             end
      11'h7cf  : begin//'h1F3C
                   IFP_axi_rw.rdata[31:0] = HC_DEBUG_RW_15_hc_debug_rw_15;  // 
             end
      11'h7d0  : begin//'h1F40
                   IFP_axi_rw.rdata[31:0] = HC_DEBUG_RW_16_hc_debug_rw_16;  // 
             end
      11'h7d1  : begin//'h1F44
                   IFP_axi_rw.rdata[31:0] = HC_DEBUG_RW_17_hc_debug_rw_17;  // 
             end
      11'h7d2  : begin//'h1F48
                   IFP_axi_rw.rdata[31:0] = HC_DEBUG_RW_18_hc_debug_rw_18;  // 
             end
      11'h7d3  : begin//'h1F4C
                   IFP_axi_rw.rdata[31:0] = HC_DEBUG_RW_19_hc_debug_rw_19;  // 
             end
      11'h7d4  : begin//'h1F50
                   IFP_axi_rw.rdata[31:0] = HC_DEBUG_RW_20_hc_debug_rw_20;  // 
             end
      11'h7d5  : begin//'h1F54
                   IFP_axi_rw.rdata[31:0] = HC_DEBUG_RW_21_hc_debug_rw_21;  // 
             end
      11'h7d6  : begin//'h1F58
                   IFP_axi_rw.rdata[31:0] = HC_DEBUG_RW_22_hc_debug_rw_22;  // 
             end
      11'h7d7  : begin//'h1F5C
                   IFP_axi_rw.rdata[31:0] = HC_DEBUG_RW_23_hc_debug_rw_23;  //  
             end
      11'h7d8  : begin//'h1F60
                   IFP_axi_rw.rdata[31:0] = HC_DEBUG_RW_24_hc_debug_rw_24;  //  
             end
      11'h7d9  : begin//'h1F64
                   IFP_axi_rw.rdata[31:0] = HC_DEBUG_RW_25_hc_debug_rw_25;  //  
             end
      11'h7da  : begin//'h1F68
                   IFP_axi_rw.rdata[31:0] = HC_DEBUG_RW_26_hc_debug_rw_26;  //  
             end
      11'h7db  : begin//'h1F6C
                   IFP_axi_rw.rdata[31:0] = HC_DEBUG_RW_27_hc_debug_rw_27;  //  
             end
      11'h7dc  : begin//'h1F70
                   IFP_axi_rw.rdata[31:0] = HC_DEBUG_RW_28_hc_debug_rw_28;  //  
             end
      11'h7dd  : begin//'h1F74
                   IFP_axi_rw.rdata[31:0] = HC_DEBUG_RW_29_hc_debug_rw_29;  //  
             end
      11'h7de  : begin//'h1F78
                   IFP_axi_rw.rdata[31:0] = HC_DEBUG_RW_30_hc_debug_rw_30;  // 
             end
      11'h7ff  : begin//'h1FFC
                   IFP_axi_rw.rdata[31:0] = HC_DBG_SCRATCH_hc_dbg_scratch;  //  
               end
       endcase
   end
 end
///



endmodule///

利用wren和ren对寄存器进行读写操作。

3.仿真

我的task时序是按照这张图来的,除开response返回值

SystemVerilog——Axi4Lite_To_Localbus_第1张图片

`timescale 1ns / 1ps
//
// 
// Create Date: 02/16/2023 09:43:30 AM
// Design Name: Jade
// Module Name: tb_top_ctrl_helpchip
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module tb_top_ctrl_helpchip();

typedef struct packed{
    logic [31:0]  awaddr;
    logic         awvalid;
    logic         awready;
    logic [31:0]  wdata;
    logic [3:0]   wstrb;
    logic         wvalid;
    logic         wready;
    logic [1:0]   bresp;
    logic         bvalid;
    logic         bready;
    logic [31:0]  araddr;
    logic         arvalid;
    logic         arready;
    logic [31:0]  rdata;
    logic [1:0]   rresp;
    logic         rvalid;
    logic         rready;
    } axi4_lite_t;

logic 	                ptp_clk				   ;
logic                   ptp_reset			   ;


logic 	                clk					   ;	//491.52MHz		2.017
logic 	                reset				   ;
axi4_lite_t             axi4_lite           = 0;



always	#1		ptp_clk = ~ptp_clk;
always	#1.017	clk 	= ~clk;

    jb_axi4_lite_if     #(.ADDR_WIDTH(16), .DATA_WIDTH(32))  IFP_axi_lite_helpchip_out();
    jb_helpchip_ctrl_if         IFP_helpchip_ctrl();

jb_top_ctrl_helpchip #(
        .AXI_ADDR_WIDTH             (16),
        .AXI_DATA_WIDTH             (32)
    )u_jb_top_ctrl_helpchip(
    .clk                (clk),
    .srst               (reset),
    .IFP_axi4_lite      (IFP_axi_lite_helpchip_out),
    .IFP_helpchip_ctrl  (IFP_helpchip_ctrl)
);

initial begin
		ptp_clk		<= 0;
		ptp_reset	<= 1;
		clk 		<= 0;
		reset 		<= 1;
				
/* ----------------------------------------------- */		
        #20
        ptp_reset	<= 0;
        reset 		<= 0;
        
        #20;
		
		axi4_write(32'hA0291F00, 32'h12345678);
		axi4_write(32'hA0291F04, 32'hFF);
		axi4_write(32'hA0291F08, 32'h6);
		axi4_write(32'hA0291F0C, 32'h0);
		
		#20
		axi4_read(32'hA0290000);
		//axi4_read(32'hA0291F00);
		//axi4_read(32'hA0291F04);
		//axi4_read(32'hA0291F08);
		//axi4_read(32'hA0291F0C);
		
		#15	$stop;
end

always @ (posedge clk) begin
    if(reset) begin
        IFP_axi_lite_helpchip_out.awaddr    <= 'h0;
        IFP_axi_lite_helpchip_out.awvalid   <= 'h0;
        IFP_axi_lite_helpchip_out.awready   <= 'h0;
        IFP_axi_lite_helpchip_out.wdata     <= 'h0;
        IFP_axi_lite_helpchip_out.wstrb     <= 'h0;
        IFP_axi_lite_helpchip_out.wvalid    <= 'h0;
        IFP_axi_lite_helpchip_out.wready    <= 'h0;
        IFP_axi_lite_helpchip_out.bresp     <= 'h0;
        IFP_axi_lite_helpchip_out.bvalid    <= 'h0;
        IFP_axi_lite_helpchip_out.bready    <= 'h0;
        IFP_axi_lite_helpchip_out.araddr    <= 'h0;
        IFP_axi_lite_helpchip_out.arvalid   <= 'h0;
        IFP_axi_lite_helpchip_out.arready   <= 'h0;
        IFP_axi_lite_helpchip_out.rdata     <= 'h0;
        IFP_axi_lite_helpchip_out.rresp     <= 'h0;
        IFP_axi_lite_helpchip_out.rvalid    <= 'h0;
        IFP_axi_lite_helpchip_out.rready    <= 'h0;
        
    end
    else begin
        IFP_axi_lite_helpchip_out.awaddr    <= axi4_lite.awaddr ;
        IFP_axi_lite_helpchip_out.awvalid   <= axi4_lite.awvalid;
        IFP_axi_lite_helpchip_out.awready   <= axi4_lite.awready;
        IFP_axi_lite_helpchip_out.wdata     <= axi4_lite.wdata  ;
        IFP_axi_lite_helpchip_out.wstrb     <= axi4_lite.wstrb  ;
        IFP_axi_lite_helpchip_out.wvalid    <= axi4_lite.wvalid ;
        IFP_axi_lite_helpchip_out.wready    <= axi4_lite.wready ;
        IFP_axi_lite_helpchip_out.bresp     <= axi4_lite.bresp  ;
        IFP_axi_lite_helpchip_out.bvalid    <= axi4_lite.bvalid ;
        IFP_axi_lite_helpchip_out.bready    <= axi4_lite.bready ;
        IFP_axi_lite_helpchip_out.araddr    <= axi4_lite.araddr ;
        IFP_axi_lite_helpchip_out.arvalid   <= axi4_lite.arvalid;
        IFP_axi_lite_helpchip_out.arready   <= axi4_lite.arready;
        IFP_axi_lite_helpchip_out.rdata     <= axi4_lite.rdata  ;
        IFP_axi_lite_helpchip_out.rresp     <= axi4_lite.rresp  ;
        IFP_axi_lite_helpchip_out.rvalid    <= axi4_lite.rvalid ;
        IFP_axi_lite_helpchip_out.rready    <= axi4_lite.rready ;
    end
end

task automatic axi4_read(int addr);
    begin
      axi4_lite.rready  <= 1'd0;
      @(posedge clk);
      axi4_lite.araddr  <= addr[31:0];
      axi4_lite.arvalid <= 1'd1;
      @(posedge clk);
      @(posedge clk);
      
      while (axi4_lite.arready)
        @(posedge clk);
      axi4_lite.arvalid <= 1'd0;
      
      while(axi4_lite.rvalid)
        @(posedge clk);
      axi4_lite.rready  <= 1'd1;
      if (axi4_lite.rresp == 2'd0)
        $display("Read ok, Raddr - %x, Rdata - %x", axi4_lite.araddr, axi4_lite.rdata);
      else
        $display("Read failed, Raddr - %x, Rresp - %x", axi4_lite.araddr, axi4_lite.rresp);
      @(posedge clk);
      axi4_lite.rready  <= 1'd0;
    end
  endtask
  
task automatic axi4_write(int addr, data);
    begin
      axi4_lite.bready  <= 1'd0;
      @(posedge clk);
      axi4_lite.awaddr  <= addr[31:0];
      axi4_lite.awvalid <= 1'd1;
      axi4_lite.wdata   <= data[31:0];
      axi4_lite.wvalid  <= 1'd1;
      axi4_lite.wstrb   <= 4'd15;
      
      @(posedge clk);
      while (axi4_lite.awready)
        @(posedge clk);
        @(posedge clk);
      axi4_lite.awvalid <= 1'd0;
      

      while (axi4_lite.wready)
        @(posedge clk);
      axi4_lite.wvalid  <= 1'd0;
      
      
      while (axi4_lite.bvalid)
        @(posedge clk);
      axi4_lite.bready  <= 1'd1;
      @(posedge clk);
      axi4_lite.bready  <= 1'd0;
      if (axi4_lite.bresp != 2'b00)
        $display("Write failure...%d", axi4_lite.bresp);
    end
  endtask


endmodule

熟悉了一下systemverilog的一些用法,以及systemverilog写测试激励。

SystemVerilog——Axi4Lite_To_Localbus_第2张图片

总结

当时需要从zu67传一个128k(0xA0280000、0xA0290000)的地址到ku3p,但是这个代码里面需要修改两处,才能保证一切正确:

需要非常注意偏移地址

///WRITE LOGIC
  assign IFP_axi_rw.wr_offset = axi_awaddr[AXI_ADDR_WIDTH-2:ADDR_LSB];

///READ LOGIC
  assign IFP_axi_rw.rd_offset = axi_araddr[AXI_ADDR_WIDTH-2:ADDR_LSB];

把parameter AXI_ADDR_WIDTH改成17就可以了

工程代码:

https://download.csdn.net/download/Y__Yshans/87454767

参考文章:

AXI总线之AXI-LITE总线分析与实现_bibogo的博客-CSDN博客_axi-lite

你可能感兴趣的:(SystemVerilog,fpga开发)