自定义AXI总线IP之补全寄存器的输入输出配置

Posted electricdream

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自定义AXI总线IP之补全寄存器的输入输出配置相关的知识,希望对你有一定的参考价值。

自定义AXI总线IP之补全寄存器配置输入和输出

1、实验目的

在使用默认的AXI4的配置时,不会有寄存器的配置,无法配置端口的输入还是输出。根据前面的AXI总线的理解,这里通过仲裁器判断,将AXI4的从地址0x04对应的寄存器用于端口的配置。通过寄存器的读取后直接输出到顶层。也可以直接将端口的数据加载到从机发射。

2、实验操作

(1)创建自定义IP

tools中的第一个就是新建一个IP核,设置就不多叙述。

(2)将slv_reg1de1数据加入判断序列

    always @( posedge S_AXI_ACLK )
    begin
      if ( S_AXI_ARESETN == 1b0 )
        begin
          slv_reg0 <= 0;
          slv_reg1 <= 0;
          slv_reg2 <= 0;
          slv_reg3 <= 0;
        end 
      else begin
        if (slv_reg_wren && slv_reg1==16h0000)
          begin
            case ( axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] )
              2h0:
                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  
              2h1:
                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  
              2h2:
                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  
              2h3:
                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;
                          slv_reg3 <= slv_reg3;
                        end
            endcase
          end
      end
    end

将这个判断加入到slv_reg0的接收模块。(这个判断不加的话可能存在为主机输入信号时可以向从机写入数据)

    assign slv_reg_rden = axi_arready & S_AXI_ARVALID & ~axi_rvalid;
    always @(*)
    begin
          // Address decoding for reading registers
          case ( axi_araddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] &&slv_reg1==16hffff )
            2h0   : reg_data_out <= (slv_reg1==16hffff)? SWS_VALID: slv_reg0;
            2h1   : reg_data_out <= slv_reg1;
            2h2   : reg_data_out <= slv_reg2;
            2h3   : reg_data_out <= slv_reg3;
            default : reg_data_out <= 0;
          endcase
    end

这个是从机发送数据时的数据加载。利用这个判断可以将SWS的信号传到主机。

    // Add user logic here
    assign LED_VALID=(slv_reg1==16h0000)? slv_reg0 : 1b0;
    // User logic ends

这个是将缓存器中的数据读取出来。

3、方案缺陷

这个三行修改的代码实现的功能,还是有许多的缺陷的。相对于专用的GPIO的设计,这个设计用两个端口分别读取输入输出,不能合并使用。优点就是可以适应输入输出的转化而不需要顾及端口不足的问题。还有一些其他细节的数据清零问题。由于是开始学习,就不过多的考虑其他因素。

4、验证操作

就是使用bd视图调用原理图就可以构建软件平台。软件通过寄存器的读取,即可测试输入输出信号是否有效。

技术图片

这是初步的连接的原理图,后面的验证工作就是基于这个平台来支持读取和写入的切换的。这里根据开发板设置具体参数即可。

5、软件测试

这里的综合时间比较长,后面一篇续篇再做这个部分。

6、总结

这次的实验采取简单的仲裁逻辑判断输入输出,利用简单逻辑叠加和三目选择运算符实现一位宽数据的输入输出切换。官方IP核切换通过开发软件设置完成。个人自制的一般需要是确认为输入输出信号,这个设置其实只是为了熟悉AXI中各个信号的作用,实际作用并不大。

 

以上是关于自定义AXI总线IP之补全寄存器的输入输出配置的主要内容,如果未能解决你的问题,请参考以下文章

AXI-自定义IP-PS设计

AXI-Lite总线及其自定义IP核使用分析总结

自定义AXI-IP核(转)

zc702-自定义AXI-IP核实验

PS-AXI-PL流水灯设计

将自己写的HDL代码封装成带AXI总线的IP