摘要:用SystemVerilog对Axi4转localbus进行编写与仿真
如果需要从PS端对PL进行寄存器的读写操作,从znyq M_AXI_HPM_FPD出来,经过axi_interconnect 模块分出多个通道(不同的地址),经过一个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
用这些信号将数据送入寄存器中或者从寄存器中读出数据。
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对寄存器进行读写操作。
我的task时序是按照这张图来的,除开response返回值
`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写测试激励。
当时需要从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