首页 > 学院 > 开发设计 > 正文

如何实现axi_lite的双向传递

2019-11-06 08:53:01
字体:
来源:转载
供稿:网友

最近,由于项目。需要通过axi_lite实现PS与PL之间的双向信息传输。在网上找了好久,PS到PL单向传输的例子很多,比如http://www.eetop.cn/blog/html/70/1149070-51989.html这篇博文描述的这样。

而双向传输的例子却很难找到,通过阅读生成的自定义ip代码。发现PS有写寄存器的能力,也有读寄存器的能力。这就使得PL向PS传输信息可以实现。

本文后面贴出的代码,用最简单的方法来实现PL向PS的信息传输。将生成的代码中分配的四个寄存器中的最后一个寄存器PS写的能力禁止,只保存PS读的能力,而通过PL写这个寄存器(PS可读)来实现PL向PS传输信息。

接下来贴出修改部分代码: 首先,禁止PS对于最后一个寄存器写的能力。首先,要找到write logic部分,可通过查看生成代码注释找到。此部分代码如下所示(不同vivado版本可能有一定差异),对slv_reg3进行操作部分删除,本文代码采用注释方法方便比较,共三处,分别用(1)、(2)、(3)标记:

// Implement memory mapped register select and write logic generation // The write data is accepted and written to memory mapped registers when // axi_awready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted. Write strobes are used to // select byte enables of slave registers while writing. // These registers are cleared when reset (active low) is applied. // Slave register write enable is asserted when valid address and data are available // and the slave is ready to accept the write address and write data. assign slv_reg_wren = axi_wready && S_AXI_WVALID && axi_awready && S_AXI_AWVALID;

always @( posedge S_AXI_ACLK )begin if ( S_AXI_ARESETN == 1'b0 ) begin slv_reg0 <= 0; slv_reg1 <= 0; slv_reg2 <= 0; //(1)// slv_reg3 <= 0; end else begin if (slv_reg_wren) begin case ( axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] ) 2'h0: for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 ) if ( S_AXI_WSTRB[byte_index] == 1 ) begin // Respective byte enables are asserted as per write strobes // Slave register 0 slv_reg0[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8]; end 2'h1: for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 ) if ( S_AXI_WSTRB[byte_index] == 1 ) begin // Respective byte enables are asserted as per write strobes // Slave register 1 slv_reg1[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8]; end 2'h2: for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 ) if ( S_AXI_WSTRB[byte_index] == 1 ) begin // Respective byte enables are asserted as per write strobes // Slave register 2 slv_reg2[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8]; end //(2)//2'h3: //for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 ) //if ( S_AXI_WSTRB[byte_index] == 1 ) begin // Respective byte enables are asserted as per write strobes // Slave register 3 //slv_reg3[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8]; end default : begin slv_reg0 <= slv_reg0; slv_reg1 <= slv_reg1; slv_reg2 <= slv_reg2; //(3)//slv_reg3 <= slv_reg3; end endcase end endend

在用户定义代码处加上如下代码:

// Add user logic herealways @( posedge S_AXI_ACLK )begin if ( S_AXI_ARESETN == 1'b0 ) begin slv_reg3 <= 0; end else begin slv_reg3 <= PL_data_in; endend// User logic ends

当然,在输入端口处需要加上PL_data_in为输入端口。其他部分与单向情况类似。


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表