• ZYNQ搭建HP总线从DDR进行PL与PS交互


    一,在XIINX FPGA中有支持三种AXI总线,有三种AXI协议接口,全局时钟,复位低有效分别是
    AXI4:面向高性能地址映射通信需求,是面向地址映射的接口,最大允许256次的数据突发传输;
    AXI4-Lite:是一个轻量级的地址映射单次传输接口,占用很少的逻辑单元。
    AXI4-Stream:面向高速流数据传输;去掉了地址项,允许无限制的数据突发传输规模。

    1,写地址通道信号

     2,写数据和写响应信号

     3,读地址通道号

    4,读数据通道号

    二,AXI4-Lite搭建hp接口

    1,单击菜单栏 Tools->Create and Package New IP,开始创建一个AXI4-Lite接口总线IP

    2,使用vivado自带的AXI总线模板创建一个AXI4-Lite接口IP,并命名

    3,模板支持三种协议,lite/full/stream,总线包括Master和Slave两种接口模式,这里根据自己的搭建目标选择Master模式或Slave模式。

    这里选择axi_lite_master,搭建HP接口。

    4,编辑接口进行用户代码添加

    5,在module pl_to_ps_hp_v1_0 #模块中,第20行,// Users to add ports here地方,添加输入和输出接口。这里input是留给PL直接输入数据的地方。

            input wire pl_to_ps_wr_valid,
            input wire [63:0]wr_pl_to_ps_hp_data,
            output wire ps_to_pl_rd_valid,
            output wire [63:0]rd_ps_to_pl_hp_data,

            input wire wr_base_addr_valid,
            input wire [31:0]wr_base_addr,
            input wire rd_base_addr_valid,
            input wire [31:0]rd_base_addr,
            input wire [15:0]rd_length,
     

    6,在module pl_to_ps_hp_v1_0 #模块中,在// Instantiation of Axi Bus Interface M00_AXI注释下面的pl_to_ps_hp_v1_0_M00_AXI #中的例化末尾加入例化的接口,具体例化对象就是上面的输入输出信号,具体如下:

    1. pl_to_ps_hp_v1_0_M00_AXI # (
    2. .C_M_START_DATA_VALUE(C_M00_AXI_START_DATA_VALUE),
    3. .C_M_TARGET_SLAVE_BASE_ADDR(C_M00_AXI_TARGET_SLAVE_BASE_ADDR),
    4. .C_M_AXI_ADDR_WIDTH(C_M00_AXI_ADDR_WIDTH),
    5. .C_M_AXI_DATA_WIDTH(C_M00_AXI_DATA_WIDTH),
    6. .C_M_TRANSACTIONS_NUM(C_M00_AXI_TRANSACTIONS_NUM)
    7. ) pl_to_ps_hp_v1_0_M00_AXI_inst (
    8. .INIT_AXI_TXN(m00_axi_init_axi_txn),
    9. .ERROR(m00_axi_error),
    10. .TXN_DONE(m00_axi_txn_done),
    11. .M_AXI_ACLK(m00_axi_aclk),
    12. .M_AXI_ARESETN(m00_axi_aresetn),
    13. .M_AXI_AWADDR(m00_axi_awaddr),
    14. .M_AXI_AWPROT(m00_axi_awprot),
    15. .M_AXI_AWVALID(m00_axi_awvalid),
    16. .M_AXI_AWREADY(m00_axi_awready),
    17. .M_AXI_WDATA(m00_axi_wdata),
    18. .M_AXI_WSTRB(m00_axi_wstrb),
    19. .M_AXI_WVALID(m00_axi_wvalid),
    20. .M_AXI_WREADY(m00_axi_wready),
    21. .M_AXI_BRESP(m00_axi_bresp),
    22. .M_AXI_BVALID(m00_axi_bvalid),
    23. .M_AXI_BREADY(m00_axi_bready),
    24. .M_AXI_ARADDR(m00_axi_araddr),
    25. .M_AXI_ARPROT(m00_axi_arprot),
    26. .M_AXI_ARVALID(m00_axi_arvalid),
    27. .M_AXI_ARREADY(m00_axi_arready),
    28. .M_AXI_RDATA(m00_axi_rdata),
    29. .M_AXI_RRESP(m00_axi_rresp),
    30. .M_AXI_RVALID(m00_axi_rvalid),
    31. .M_AXI_RREADY(m00_axi_rready),
    32. .wr_base_addr_valid(wr_base_addr_valid),
    33. .wr_base_addr(wr_base_addr),
    34. .rd_base_addr_valid(rd_base_addr_valid),
    35. .rd_base_addr(rd_base_addr),
    36. .rd_length(rd_length),
    37. .pl_to_ps_wr_valid(pl_to_ps_wr_valid),
    38. .wr_pl_to_ps_hp_data(wr_pl_to_ps_hp_data),
    39. .rd_ps_to_pl_hp_data(rd_ps_to_pl_hp_data),
    40. .rd_ps_to_pl_hp_data(rd_ps_to_pl_hp_data)
    41. );

    7,在module pl_to_ps_hp_v1_0_M00_AXI #模块中,输入输出接口的地方,第30行加入输入输出信号,都是从它的顶层文件引入进来的。

    1. module pl_to_ps_hp_v1_0_M00_AXI #
    2. (
    3. // Users to add parameters here
    4. // User parameters ends
    5. // Do not modify the parameters beyond this line
    6. // The master will start generating data from the C_M_START_DATA_VALUE value
    7. parameter C_M_START_DATA_VALUE = 32'hAA000000,
    8. // The master requires a target slave base address.
    9. // The master will initiate read and write transactions on the slave with base address specified here as a parameter.
    10. parameter C_M_TARGET_SLAVE_BASE_ADDR = 32'h40000000,
    11. // Width of M_AXI address bus.
    12. // The master generates the read and write addresses of width specified as C_M_AXI_ADDR_WIDTH.
    13. parameter integer C_M_AXI_ADDR_WIDTH = 32,
    14. // Width of M_AXI data bus.
    15. // The master issues write data and accept read data where the width of the data bus is C_M_AXI_DATA_WIDTH
    16. parameter integer C_M_AXI_DATA_WIDTH = 32,
    17. // Transaction number is the number of write
    18. // and read transactions the master will perform as a part of this example memory test.
    19. parameter integer C_M_TRANSACTIONS_NUM = 4
    20. )
    21. (
    22. // Users to add ports here
    23. // User ports ends
    24. input wire wr_base_addr_valid,
    25. input wire [31:0]wr_base_addr,
    26. input wire rd_base_addr_valid,
    27. input wire [31:0]rd_base_addr,
    28. input wire [15:0]rd_length,
    29. input wire pl_to_ps_wr_valid,
    30. input wire [63:0]wr_pl_to_ps_hp_data,
    31. output reg ps_to_pl_rd_valid,
    32. output reg [63:0]rd_ps_to_pl_hp_data,
    33. // Do not modify the ports beyond this line
    34. // Initiate AXI transactions
    35. input wire INIT_AXI_TXN,
    36. // Asserts when ERROR is detected
    37. output reg ERROR,
    38. // Asserts when AXI transactions is complete
    39. output wire TXN_DONE,
    40. // AXI clock signal
    41. input wire M_AXI_ACLK,
    42. // AXI active low reset signal
    43. input wire M_AXI_ARESETN,
    44. // Master Interface Write Address Channel ports. Write address (issued by master)
    45. output wire [C_M_AXI_ADDR_WIDTH-1 : 0] M_AXI_AWADDR,
    46. // Write channel Protection type.
    47. // This signal indicates the privilege and security level of the transaction,
    48. // and whether the transaction is a data access or an instruction access.
    49. output wire [2 : 0] M_AXI_AWPROT,
    50. // Write address valid.
    51. // This signal indicates that the master signaling valid write address and control information.
    52. output wire M_AXI_AWVALID,
    53. // Write address ready.
    54. // This signal indicates that the slave is ready to accept an address and associated control signals.
    55. input wire M_AXI_AWREADY,
    56. // Master Interface Write Data Channel ports. Write data (issued by master)
    57. output wire [C_M_AXI_DATA_WIDTH-1 : 0] M_AXI_WDATA,
    58. // Write strobes.
    59. // This signal indicates which byte lanes hold valid data.
    60. // There is one write strobe bit for each eight bits of the write data bus.
    61. output wire [C_M_AXI_DATA_WIDTH/8-1 : 0] M_AXI_WSTRB,
    62. // Write valid. This signal indicates that valid write data and strobes are available.
    63. output wire M_AXI_WVALID,
    64. // Write ready. This signal indicates that the slave can accept the write data.
    65. input wire M_AXI_WREADY,
    66. // Master Interface Write Response Channel ports.
    67. // This signal indicates the status of the write transaction.
    68. input wire [1 : 0] M_AXI_BRESP,
    69. // Write response valid.
    70. // This signal indicates that the channel is signaling a valid write response
    71. input wire M_AXI_BVALID,
    72. // Response ready. This signal indicates that the master can accept a write response.
    73. output wire M_AXI_BREADY,
    74. // Master Interface Read Address Channel ports. Read address (issued by master)
    75. output wire [C_M_AXI_ADDR_WIDTH-1 : 0] M_AXI_ARADDR,
    76. // Protection type.
    77. // This signal indicates the privilege and security level of the transaction,
    78. // and whether the transaction is a data access or an instruction access.
    79. output wire [2 : 0] M_AXI_ARPROT,
    80. // Read address valid.
    81. // This signal indicates that the channel is signaling valid read address and control information.
    82. output wire M_AXI_ARVALID,
    83. // Read address ready.
    84. // This signal indicates that the slave is ready to accept an address and associated control signals.
    85. input wire M_AXI_ARREADY,
    86. // Master Interface Read Data Channel ports. Read data (issued by slave)
    87. input wire [C_M_AXI_DATA_WIDTH-1 : 0] M_AXI_RDATA,
    88. // Read response. This signal indicates the status of the read transfer.
    89. input wire [1 : 0] M_AXI_RRESP,
    90. // Read valid. This signal indicates that the channel is signaling the required read data.
    91. input wire M_AXI_RVALID,
    92. // Read ready. This signal indicates that the master can accept the read data and response information.
    93. output wire M_AXI_RREADY
    94. );

    8,在module pl_to_ps_hp_v1_0_M00_AXI #模块中,把下面引入数据的内容都换成具体的有效信号,地址信号或者数据信号。官方生成的接口传的是固定地址32'h40000000和固定数据32'hAA000000。修改为:

    1. reg axi_awvalid; //write address valid
    2. reg axi_wvalid; //write data valid
    3. reg axi_arvalid; //read address valid
    4. reg axi_bready=1'b0; //write response acceptance
    5. reg [C_M_AXI_ADDR_WIDTH-1 : 0] axi_awaddr; //write address
    6. reg [C_M_AXI_DATA_WIDTH-1 : 0] axi_wdata; //write data
    7. reg [C_M_AXI_ADDR_WIDTH-1 : 0] axi_araddr; //read addresss
    8. reg [15 : 0]read_index;
    9. assign M_AXI_AWADDR = axi_awaddr;
    10. assign M_AXI_WDATA = axi_wdata;
    11. assign M_AXI_AWPROT = 3'b000;
    12. assign M_AXI_AWVALID = axi_awvalid;
    13. assign M_AXI_WVALID = axi_wvalid;
    14. assign M_AXI_WSTRB = 8'b11111111;
    15. assign M_AXI_BREADY = axi_bready;
    16. assign M_AXI_ARADDR = axi_araddr;
    17. assign M_AXI_ARVALID= axi_arvalid;
    18. assign M_AXI_ARPROT = 3'b001;
    19. assign M_AXI_RREADY = ps_to_pl_rd_valid;
    20. //--------------------------------
    21. //用户的编辑思路
    22. //--------------------------------
    23. reg [31:0]axi_awaddr_r=32'd0;
    24. always @(posedge M_AXI_ACLK)
    25. begin
    26. if(wr_base_addr_valid)
    27. begin //锁存写数据基地址
    28. axi_awaddr_r <= wr_base_addr;
    29. end
    30. else if(M_AXI_AWREADY&&M_AXI_WREADY&& pl_to_ps_wr_valid)
    31. begin //PL TO PS HP写数据过程
    32. axi_awvalid <= 1'b1;
    33. axi_awaddr <= axi_awaddr_r;
    34. axi_awaddr_r <= axi_awaddr_r + 32'h00000008;
    35. axi_wvalid <= 1'b1;
    36. axi_wdata <= wr_pl_to_ps_hp_data;
    37. end
    38. else
    39. begin
    40. axi_awvalid <= 1'b0;
    41. axi_wvalid <= 1'b0;
    42. end
    43. end
    44. always @(posedge M_AXI_ACLK) //产生回应信号
    45. begin
    46. if(M_AXI_BVALID&&(!axi_bready))
    47. begin
    48. axi_bready <= 1'b1;
    49. end
    50. else if(axi_bready)begin
    51. axi_bready <= 1'b0;
    52. end
    53. else
    54. begin
    55. axi_bready <= axi_bready;
    56. end
    57. end
    58. reg [1:0]rd_state;
    59. reg [31:0]axi_araddr_r;
    60. always @(posedge M_AXI_ACLK)
    61. begin
    62. if(M_AXI_ARESETN == 0)
    63. begin
    64. rd_state <= 2'd0;
    65. read_index <= 16'd0;
    66. axi_araddr <= 32'd0;
    67. axi_araddr_r <= 32'd0;
    68. axi_arvalid <= 1'b0;
    69. ps_to_pl_rd_valid <= 1'b0;
    70. rd_ps_to_pl_hp_data <= 64'h0;
    71. end
    72. else begin
    73. case(rd_state)
    74. 2'd0:
    75. begin
    76. if(rd_base_addr_valid)begin
    77. axi_araddr_r <= rd_base_addr;
    78. read_index <= 16'd0;
    79. rd_state <= rd_state + 1'b1;
    80. end
    81. else
    82. begin
    83. rd_state <= rd_state;
    84. end
    85. end
    86. 2'd1:begin
    87. if(M_AXI_ARREADY)
    88. begin
    89. axi_arvalid <= 1'b1;
    90. axi_araddr <= axi_araddr_r;
    91. axi_araddr_r <= axi_araddr_r + 32'h00000008;
    92. read_index <= read_index + 1;
    93. rd_state <= rd_state + 1'b1;
    94. end
    95. else
    96. begin
    97. axi_arvalid <= 1'b0;
    98. end
    99. end
    100. 2'd2:begin
    101. axi_arvalid <= 1'b0;
    102. if(M_AXI_RVALID)
    103. begin
    104. ps_to_pl_rd_valid <= 1'b1;
    105. rd_ps_to_pl_hp_data <= M_AXI_RDATA;
    106. rd_state <= rd_state + 1'b1;
    107. end
    108. else begin
    109. rd_state <= rd_state;
    110. end
    111. end
    112. 2'd3:
    113. begin
    114. ps_to_pl_rd_valid <= 1'b0;
    115. if(read_index==rd_length)begin
    116. rd_state <= 2'd0;
    117. end
    118. else begin
    119. rd_state <= 2'd1;
    120. end
    121. end
    122. endcase
    123. end
    124. end

    9,生成bit流就可以正式使用了

    三,搭建hp接口的block design

    四,zynq sdk读写HP DDR验证

    五,选择Verify Peripheral IP using AXI4 VIP可以自行对AXI4-lite快速验证

     单击完成后vivado自动产生demo,单击Block Design的工程,可以看到如下 2 个 IP。其中 maxi_lite_0就是我自定义的IP,另外一个slave_0是用来验证 maxi_lite_0正确性。

    采用默认地址分配0x44A0_0000

    axi_lite_master代码解析:

    1. `timescale 1 ns / 1 ps
    2. module maxi_lite_v1_0_M00_AXI #
    3. (
    4. // Users to add parameters here
    5. // User parameters ends
    6. // Do not modify the parameters beyond this line
    7. // The master will start generating data from the C_M_START_DATA_VALUE value
    8. parameter C_M_START_DATA_VALUE = 32'hAA000000,
    9. // The master requires a target slave base address.
    10. // The master will initiate read and write transactions on the slave with base address specified here as a parameter.
    11. parameter C_M_TARGET_SLAVE_BASE_ADDR = 32'h40000000,
    12. // Width of M_AXI address bus.
    13. // The master generates the read and write addresses of width specified as C_M_AXI_ADDR_WIDTH.
    14. parameter integer C_M_AXI_ADDR_WIDTH = 32,
    15. // Width of M_AXI data bus.
    16. // The master issues write data and accept read data where the width of the data bus is C_M_AXI_DATA_WIDTH
    17. parameter integer C_M_AXI_DATA_WIDTH = 32,
    18. // Transaction number is the number of write
    19. // and read transactions the master will perform as a part of this example memory test.
    20. parameter integer C_M_TRANSACTIONS_NUM = 4
    21. )
    22. (
    23. // Users to add ports here
    24. // User ports ends
    25. // Do not modify the ports beyond this line
    26. // Initiate AXI transactions
    27. input wire INIT_AXI_TXN,
    28. // Asserts when ERROR is detected
    29. output reg ERROR,
    30. // Asserts when AXI transactions is complete
    31. output wire TXN_DONE,
    32. // AXI clock signal
    33. input wire M_AXI_ACLK,
    34. // AXI active low reset signal
    35. input wire M_AXI_ARESETN,
    36. // Master Interface Write Address Channel ports. Write address (issued by master)
    37. output wire [C_M_AXI_ADDR_WIDTH-1 : 0] M_AXI_AWADDR,
    38. // Write channel Protection type.
    39. // This signal indicates the privilege and security level of the transaction,
    40. // and whether the transaction is a data access or an instruction access.
    41. output wire [2 : 0] M_AXI_AWPROT,
    42. // Write address valid.
    43. // This signal indicates that the master signaling valid write address and control information.
    44. output wire M_AXI_AWVALID,
    45. // Write address ready.
    46. // This signal indicates that the slave is ready to accept an address and associated control signals.
    47. input wire M_AXI_AWREADY,
    48. // Master Interface Write Data Channel ports. Write data (issued by master)
    49. output wire [C_M_AXI_DATA_WIDTH-1 : 0] M_AXI_WDATA,
    50. // Write strobes.
    51. // This signal indicates which byte lanes hold valid data.
    52. // There is one write strobe bit for each eight bits of the write data bus.
    53. output wire [C_M_AXI_DATA_WIDTH/8-1 : 0] M_AXI_WSTRB,
    54. // Write valid. This signal indicates that valid write data and strobes are available.
    55. output wire M_AXI_WVALID,
    56. // Write ready. This signal indicates that the slave can accept the write data.
    57. input wire M_AXI_WREADY,
    58. // Master Interface Write Response Channel ports.
    59. // This signal indicates the status of the write transaction.
    60. input wire [1 : 0] M_AXI_BRESP,
    61. // Write response valid.
    62. // This signal indicates that the channel is signaling a valid write response
    63. input wire M_AXI_BVALID,
    64. // Response ready. This signal indicates that the master can accept a write response.
    65. output wire M_AXI_BREADY,
    66. // Master Interface Read Address Channel ports. Read address (issued by master)
    67. output wire [C_M_AXI_ADDR_WIDTH-1 : 0] M_AXI_ARADDR,
    68. // Protection type.
    69. // This signal indicates the privilege and security level of the transaction,
    70. // and whether the transaction is a data access or an instruction access.
    71. output wire [2 : 0] M_AXI_ARPROT,
    72. // Read address valid.
    73. // This signal indicates that the channel is signaling valid read address and control information.
    74. output wire M_AXI_ARVALID,
    75. // Read address ready.
    76. // This signal indicates that the slave is ready to accept an address and associated control signals.
    77. input wire M_AXI_ARREADY,
    78. // Master Interface Read Data Channel ports. Read data (issued by slave)
    79. input wire [C_M_AXI_DATA_WIDTH-1 : 0] M_AXI_RDATA,
    80. // Read response. This signal indicates the status of the read transfer.
    81. input wire [1 : 0] M_AXI_RRESP,
    82. // Read valid. This signal indicates that the channel is signaling the required read data.
    83. input wire M_AXI_RVALID,
    84. // Read ready. This signal indicates that the master can accept the read data and response information.
    85. output wire M_AXI_RREADY
    86. );
    87. // function called clogb2 that returns an integer which has the
    88. // value of the ceiling of the log base 2
    89. function integer clogb2 (input integer bit_depth);
    90. begin
    91. for(clogb2=0; bit_depth>0; clogb2=clogb2+1)
    92. bit_depth = bit_depth >> 1;
    93. end
    94. endfunction
    95. // TRANS_NUM_BITS is the width of the index counter for
    96. // number of write or read transaction.
    97. localparam integer TRANS_NUM_BITS = clogb2(C_M_TRANSACTIONS_NUM-1);
    98. // Example State machine to initialize counter, initialize write transactions,
    99. // initialize read transactions and comparison of read data with the
    100. // written data words.
    101. parameter [1:0] IDLE = 2'b00, // This state initiates AXI4Lite transaction
    102. // after the state machine changes state to INIT_WRITE
    103. // when there is 0 to 1 transition on INIT_AXI_TXN
    104. INIT_WRITE = 2'b01, // This state initializes write transaction,
    105. // once writes are done, the state machine
    106. // changes state to INIT_READ
    107. INIT_READ = 2'b10, // This state initializes read transaction
    108. // once reads are done, the state machine
    109. // changes state to INIT_COMPARE
    110. INIT_COMPARE = 2'b11; // This state issues the status of comparison
    111. // of the written data with the read data
    112. reg [1:0] mst_exec_state;
    113. // AXI4LITE signals
    114. //write address valid
    115. reg axi_awvalid;
    116. //write data valid
    117. reg axi_wvalid;
    118. //read address valid
    119. reg axi_arvalid;
    120. //read data acceptance
    121. reg axi_rready;
    122. //write response acceptance
    123. reg axi_bready;
    124. //write address
    125. reg [C_M_AXI_ADDR_WIDTH-1 : 0] axi_awaddr;
    126. //write data
    127. reg [C_M_AXI_DATA_WIDTH-1 : 0] axi_wdata;
    128. //read addresss
    129. reg [C_M_AXI_ADDR_WIDTH-1 : 0] axi_araddr;
    130. //Asserts when there is a write response error
    131. wire write_resp_error;
    132. //Asserts when there is a read response error
    133. wire read_resp_error;
    134. //A pulse to initiate a write transaction
    135. reg start_single_write;
    136. //A pulse to initiate a read transaction
    137. reg start_single_read;
    138. //Asserts when a single beat write transaction is issued and remains asserted till the completion of write trasaction.
    139. reg write_issued;
    140. //Asserts when a single beat read transaction is issued and remains asserted till the completion of read trasaction.
    141. reg read_issued;
    142. //flag that marks the completion of write trasactions. The number of write transaction is user selected by the parameter C_M_TRANSACTIONS_NUM.
    143. reg writes_done;
    144. //flag that marks the completion of read trasactions. The number of read transaction is user selected by the parameter C_M_TRANSACTIONS_NUM
    145. reg reads_done;
    146. //The error register is asserted when any of the write response error, read response error or the data mismatch flags are asserted.
    147. reg error_reg;
    148. //index counter to track the number of write transaction issued
    149. reg [TRANS_NUM_BITS : 0] write_index;
    150. //index counter to track the number of read transaction issued
    151. reg [TRANS_NUM_BITS : 0] read_index;
    152. //Expected read data used to compare with the read data.
    153. reg [C_M_AXI_DATA_WIDTH-1 : 0] expected_rdata;
    154. //Flag marks the completion of comparison of the read data with the expected read data
    155. reg compare_done;
    156. //This flag is asserted when there is a mismatch of the read data with the expected read data.
    157. reg read_mismatch;
    158. //Flag is asserted when the write index reaches the last write transction number
    159. reg last_write;
    160. //Flag is asserted when the read index reaches the last read transction number
    161. reg last_read;
    162. reg init_txn_ff;
    163. reg init_txn_ff2;
    164. reg init_txn_edge;
    165. wire init_txn_pulse;
    166. // I/O Connections assignments
    167. //Adding the offset address to the base addr of the slave
    168. assign M_AXI_AWADDR = C_M_TARGET_SLAVE_BASE_ADDR + axi_awaddr;
    169. //AXI 4 write data
    170. assign M_AXI_WDATA = axi_wdata;
    171. assign M_AXI_AWPROT = 3'b000;
    172. assign M_AXI_AWVALID = axi_awvalid;
    173. //Write Data(W)
    174. assign M_AXI_WVALID = axi_wvalid;
    175. //Set all byte strobes in this example
    176. assign M_AXI_WSTRB = 4'b1111;
    177. //Write Response (B)
    178. assign M_AXI_BREADY = axi_bready;
    179. //Read Address (AR)
    180. assign M_AXI_ARADDR = C_M_TARGET_SLAVE_BASE_ADDR + axi_araddr;
    181. assign M_AXI_ARVALID = axi_arvalid;
    182. assign M_AXI_ARPROT = 3'b001;
    183. //Read and Read Response (R)
    184. assign M_AXI_RREADY = axi_rready;
    185. //Example design I/O
    186. assign TXN_DONE = compare_done;
    187. assign init_txn_pulse = (!init_txn_ff2) && init_txn_ff;
    188. //Generate a pulse to initiate AXI transaction.
    189. always @(posedge M_AXI_ACLK)
    190. begin
    191. // Initiates AXI transaction delay
    192. if (M_AXI_ARESETN == 0 )
    193. begin
    194. init_txn_ff <= 1'b0;
    195. init_txn_ff2 <= 1'b0;
    196. end
    197. else
    198. begin
    199. init_txn_ff <= INIT_AXI_TXN;
    200. init_txn_ff2 <= init_txn_ff;
    201. end
    202. end
    203. //--------------------
    204. //Write Address Channel
    205. //--------------------
    206. // The purpose of the write address channel is to request the address and
    207. // command information for the entire transaction. It is a single beat
    208. // of information.
    209. // Note for this example the axi_awvalid/axi_wvalid are asserted at the same
    210. // time, and then each is deasserted independent from each other.
    211. // This is a lower-performance, but simplier control scheme.
    212. // AXI VALID signals must be held active until accepted by the partner.
    213. // A data transfer is accepted by the slave when a master has
    214. // VALID data and the slave acknoledges it is also READY. While the master
    215. // is allowed to generated multiple, back-to-back requests by not
    216. // deasserting VALID, this design will add rest cycle for
    217. // simplicity.
    218. // Since only one outstanding transaction is issued by the user design,
    219. // there will not be a collision between a new request and an accepted
    220. // request on the same clock cycle.
    221. always @(posedge M_AXI_ACLK)
    222. begin
    223. //Only VALID signals must be deasserted during reset per AXI spec
    224. //Consider inverting then registering active-low reset for higher fmax
    225. if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)
    226. begin
    227. axi_awvalid <= 1'b0;
    228. end
    229. //Signal a new address/data command is available by user logic
    230. else
    231. begin
    232. if (start_single_write)
    233. begin
    234. axi_awvalid <= 1'b1;
    235. end
    236. //Address accepted by interconnect/slave (issue of M_AXI_AWREADY by slave)
    237. else if (M_AXI_AWREADY && axi_awvalid)
    238. begin
    239. axi_awvalid <= 1'b0;
    240. end
    241. end
    242. end
    243. // start_single_write triggers a new write
    244. // transaction. write_index is a counter to
    245. // keep track with number of write transaction
    246. // issued/initiated
    247. always @(posedge M_AXI_ACLK)
    248. begin
    249. if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)
    250. begin
    251. write_index <= 0;
    252. end
    253. // Signals a new write address/ write data is
    254. // available by user logic
    255. else if (start_single_write)
    256. begin
    257. write_index <= write_index + 1;
    258. end
    259. end
    260. //--------------------
    261. //Write Data Channel
    262. //--------------------
    263. //The write data channel is for transfering the actual data.
    264. //The data generation is speific to the example design, and
    265. //so only the WVALID/WREADY handshake is shown here
    266. always @(posedge M_AXI_ACLK)
    267. begin
    268. if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)
    269. begin
    270. axi_wvalid <= 1'b0;
    271. end
    272. //Signal a new address/data command is available by user logic
    273. else if (start_single_write)
    274. begin
    275. axi_wvalid <= 1'b1;
    276. end
    277. //Data accepted by interconnect/slave (issue of M_AXI_WREADY by slave)
    278. else if (M_AXI_WREADY && axi_wvalid)
    279. begin
    280. axi_wvalid <= 1'b0;
    281. end
    282. end
    283. //----------------------------
    284. //Write Response (B) Channel
    285. //----------------------------
    286. //The write response channel provides feedback that the write has committed
    287. //to memory. BREADY will occur after both the data and the write address
    288. //has arrived and been accepted by the slave, and can guarantee that no
    289. //other accesses launched afterwards will be able to be reordered before it.
    290. //The BRESP bit [1] is used indicate any errors from the interconnect or
    291. //slave for the entire write burst. This example will capture the error.
    292. //While not necessary per spec, it is advisable to reset READY signals in
    293. //case of differing reset latencies between master/slave.
    294. always @(posedge M_AXI_ACLK)
    295. begin
    296. if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)
    297. begin
    298. axi_bready <= 1'b0;
    299. end
    300. // accept/acknowledge bresp with axi_bready by the master
    301. // when M_AXI_BVALID is asserted by slave
    302. else if (M_AXI_BVALID && ~axi_bready)
    303. begin
    304. axi_bready <= 1'b1;
    305. end
    306. // deassert after one clock cycle
    307. else if (axi_bready)
    308. begin
    309. axi_bready <= 1'b0;
    310. end
    311. // retain the previous value
    312. else
    313. axi_bready <= axi_bready;
    314. end
    315. //Flag write errors
    316. assign write_resp_error = (axi_bready & M_AXI_BVALID & M_AXI_BRESP[1]);
    317. //----------------------------
    318. //Read Address Channel
    319. //----------------------------
    320. //start_single_read triggers a new read transaction. read_index is a counter to
    321. //keep track with number of read transaction issued/initiated
    322. always @(posedge M_AXI_ACLK)
    323. begin
    324. if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)
    325. begin
    326. read_index <= 0;
    327. end
    328. // Signals a new read address is
    329. // available by user logic
    330. else if (start_single_read)
    331. begin
    332. read_index <= read_index + 1;
    333. end
    334. end
    335. // A new axi_arvalid is asserted when there is a valid read address
    336. // available by the master. start_single_read triggers a new read
    337. // transaction
    338. always @(posedge M_AXI_ACLK)
    339. begin
    340. if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)
    341. begin
    342. axi_arvalid <= 1'b0;
    343. end
    344. //Signal a new read address command is available by user logic
    345. else if (start_single_read)
    346. begin
    347. axi_arvalid <= 1'b1;
    348. end
    349. //RAddress accepted by interconnect/slave (issue of M_AXI_ARREADY by slave)
    350. else if (M_AXI_ARREADY && axi_arvalid)
    351. begin
    352. axi_arvalid <= 1'b0;
    353. end
    354. // retain the previous value
    355. end
    356. //--------------------------------
    357. //Read Data (and Response) Channel
    358. //--------------------------------
    359. //The Read Data channel returns the results of the read request
    360. //The master will accept the read data by asserting axi_rready
    361. //when there is a valid read data available.
    362. //While not necessary per spec, it is advisable to reset READY signals in
    363. //case of differing reset latencies between master/slave.
    364. always @(posedge M_AXI_ACLK)
    365. begin
    366. if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)
    367. begin
    368. axi_rready <= 1'b0;
    369. end
    370. // accept/acknowledge rdata/rresp with axi_rready by the master
    371. // when M_AXI_RVALID is asserted by slave
    372. else if (M_AXI_RVALID && ~axi_rready)
    373. begin
    374. axi_rready <= 1'b1;
    375. end
    376. // deassert after one clock cycle
    377. else if (axi_rready)
    378. begin
    379. axi_rready <= 1'b0;
    380. end
    381. // retain the previous value
    382. end
    383. //Flag write errors
    384. assign read_resp_error = (axi_rready & M_AXI_RVALID & M_AXI_RRESP[1]);
    385. //--------------------------------
    386. //User Logic
    387. //--------------------------------
    388. //Address/Data Stimulus
    389. //Address/data pairs for this example. The read and write values should
    390. //match.
    391. //Modify these as desired for different address patterns.
    392. //Write Addresses
    393. always @(posedge M_AXI_ACLK)
    394. begin
    395. if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)
    396. begin
    397. axi_awaddr <= 0;
    398. end
    399. // Signals a new write address/ write data is
    400. // available by user logic
    401. else if (M_AXI_AWREADY && axi_awvalid)
    402. begin
    403. axi_awaddr <= axi_awaddr + 32'h00000004;
    404. end
    405. end
    406. // Write data generation
    407. always @(posedge M_AXI_ACLK)
    408. begin
    409. if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1 )
    410. begin
    411. axi_wdata <= C_M_START_DATA_VALUE;
    412. end
    413. // Signals a new write address/ write data is
    414. // available by user logic
    415. else if (M_AXI_WREADY && axi_wvalid)
    416. begin
    417. axi_wdata <= C_M_START_DATA_VALUE + write_index;
    418. end
    419. end
    420. //Read Addresses
    421. always @(posedge M_AXI_ACLK)
    422. begin
    423. if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)
    424. begin
    425. axi_araddr <= 0;
    426. end
    427. // Signals a new write address/ write data is
    428. // available by user logic
    429. else if (M_AXI_ARREADY && axi_arvalid)
    430. begin
    431. axi_araddr <= axi_araddr + 32'h00000004;
    432. end
    433. end
    434. always @(posedge M_AXI_ACLK)
    435. begin
    436. if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)
    437. begin
    438. expected_rdata <= C_M_START_DATA_VALUE;
    439. end
    440. // Signals a new write address/ write data is
    441. // available by user logic
    442. else if (M_AXI_RVALID && axi_rready)
    443. begin
    444. expected_rdata <= C_M_START_DATA_VALUE + read_index;
    445. end
    446. end
    447. //implement master command interface state machine
    448. always @ ( posedge M_AXI_ACLK)
    449. begin
    450. if (M_AXI_ARESETN == 1'b0)
    451. begin
    452. // reset condition
    453. // All the signals are assigned default values under reset condition
    454. mst_exec_state <= IDLE;
    455. start_single_write <= 1'b0;
    456. write_issued <= 1'b0;
    457. start_single_read <= 1'b0;
    458. read_issued <= 1'b0;
    459. compare_done <= 1'b0;
    460. ERROR <= 1'b0;
    461. end
    462. else
    463. begin
    464. // state transition
    465. case (mst_exec_state)
    466. IDLE:
    467. // This state is responsible to initiate
    468. // AXI transaction when init_txn_pulse is asserted
    469. if ( init_txn_pulse == 1'b1 )
    470. begin
    471. mst_exec_state <= INIT_WRITE;
    472. ERROR <= 1'b0;
    473. compare_done <= 1'b0;
    474. end
    475. else
    476. begin
    477. mst_exec_state <= IDLE;
    478. end
    479. INIT_WRITE:
    480. // This state is responsible to issue start_single_write pulse to
    481. // initiate a write transaction. Write transactions will be
    482. // issued until last_write signal is asserted.
    483. // write controller
    484. if (writes_done)
    485. begin
    486. mst_exec_state <= INIT_READ;//
    487. end
    488. else
    489. begin
    490. mst_exec_state <= INIT_WRITE;
    491. if (~axi_awvalid && ~axi_wvalid && ~M_AXI_BVALID && ~last_write && ~start_single_write && ~write_issued)
    492. begin
    493. start_single_write <= 1'b1;
    494. write_issued <= 1'b1;
    495. end
    496. else if (axi_bready)
    497. begin
    498. write_issued <= 1'b0;
    499. end
    500. else
    501. begin
    502. start_single_write <= 1'b0; //Negate to generate a pulse
    503. end
    504. end
    505. INIT_READ:
    506. // This state is responsible to issue start_single_read pulse to
    507. // initiate a read transaction. Read transactions will be
    508. // issued until last_read signal is asserted.
    509. // read controller
    510. if (reads_done)
    511. begin
    512. mst_exec_state <= INIT_COMPARE;
    513. end
    514. else
    515. begin
    516. mst_exec_state <= INIT_READ;
    517. if (~axi_arvalid && ~M_AXI_RVALID && ~last_read && ~start_single_read && ~read_issued)
    518. begin
    519. start_single_read <= 1'b1;
    520. read_issued <= 1'b1;
    521. end
    522. else if (axi_rready)
    523. begin
    524. read_issued <= 1'b0;
    525. end
    526. else
    527. begin
    528. start_single_read <= 1'b0; //Negate to generate a pulse
    529. end
    530. end
    531. INIT_COMPARE:
    532. begin
    533. // This state is responsible to issue the state of comparison
    534. // of written data with the read data. If no error flags are set,
    535. // compare_done signal will be asseted to indicate success.
    536. ERROR <= error_reg;
    537. mst_exec_state <= IDLE;
    538. compare_done <= 1'b1;
    539. end
    540. default :
    541. begin
    542. mst_exec_state <= IDLE;
    543. end
    544. endcase
    545. end
    546. end //MASTER_EXECUTION_PROC
    547. //Terminal write count
    548. always @(posedge M_AXI_ACLK)
    549. begin
    550. if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)
    551. last_write <= 1'b0;
    552. //The last write should be associated with a write address ready response
    553. else if ((write_index == C_M_TRANSACTIONS_NUM) && M_AXI_AWREADY)
    554. last_write <= 1'b1;
    555. else
    556. last_write <= last_write;
    557. end
    558. //Check for last write completion.
    559. //This logic is to qualify the last write count with the final write
    560. //response. This demonstrates how to confirm that a write has been
    561. //committed.
    562. always @(posedge M_AXI_ACLK)
    563. begin
    564. if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)
    565. writes_done <= 1'b0;
    566. //The writes_done should be associated with a bready response
    567. else if (last_write && M_AXI_BVALID && axi_bready)
    568. writes_done <= 1'b1;
    569. else
    570. writes_done <= writes_done;
    571. end
    572. //------------------
    573. //Read example
    574. //------------------
    575. //Terminal Read Count
    576. always @(posedge M_AXI_ACLK)
    577. begin
    578. if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)
    579. last_read <= 1'b0;
    580. //The last read should be associated with a read address ready response
    581. else if ((read_index == C_M_TRANSACTIONS_NUM) && (M_AXI_ARREADY) )
    582. last_read <= 1'b1;
    583. else
    584. last_read <= last_read;
    585. end
    586. /*
    587. Check for last read completion.
    588. This logic is to qualify the last read count with the final read
    589. response/data.
    590. */
    591. always @(posedge M_AXI_ACLK)
    592. begin
    593. if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)
    594. reads_done <= 1'b0;
    595. //The reads_done should be associated with a read ready response
    596. else if (last_read && M_AXI_RVALID && axi_rready)
    597. reads_done <= 1'b1;
    598. else
    599. reads_done <= reads_done;
    600. end
    601. //-----------------------------
    602. //Example design error register
    603. //-----------------------------
    604. //Data Comparison
    605. always @(posedge M_AXI_ACLK)
    606. begin
    607. if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)
    608. read_mismatch <= 1'b0;
    609. //The read data when available (on axi_rready) is compared with the expected data
    610. else if ((M_AXI_RVALID && axi_rready) && (M_AXI_RDATA != expected_rdata))
    611. read_mismatch <= 1'b1;
    612. else
    613. read_mismatch <= read_mismatch;
    614. end
    615. // Register and hold any data mismatches, or read/write interface errors
    616. always @(posedge M_AXI_ACLK)
    617. begin
    618. if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)
    619. error_reg <= 1'b0;
    620. //Capture any error types
    621. else if (read_mismatch || write_resp_error || read_resp_error)
    622. error_reg <= 1'b1;
    623. else
    624. error_reg <= error_reg;
    625. end
    626. // Add user logic here
    627. // User logic ends
    628. endmodule

      axi_lite_master代码测试结果:

  • 相关阅读:
    AI&Cloud 分论坛 07-AI原生数据库与RAG【文档管理】
    发明专利加急程序
    MySQL常见问题汇总
    Centos脚本编程一例,程序运行提示菜单、自动查杀进程和后台运行
    L57.linux命令每日一练 -- 第九章 Linux进程管理命令 -- ps和pstree
    Springboot 集成 Ehcache操作数据库显示SQL语句设置
    【前端】零基础快速搞定JavaScript核心知识点
    Web Worker:JS多线程的伪解药?
    【LeetCode】221. 最大正方形
    【buildroot】buildroot使用笔记-02 | 对/dev的四种管理机制
  • 原文地址:https://blog.csdn.net/wangjie36/article/details/126317934