首页 > 其他分享 >04 AXI4总线axi-full-slave

04 AXI4总线axi-full-slave

时间:2023-12-30 14:56:10浏览次数:30  
标签:begin full slave 04 araddr axi && end AXI

软件版本:vitis2021.1(vivado2021.1)

操作系统:WIN10 64bit

硬件平台:适用XILINX A7/K7/Z7/ZU/KU系列FPGA

登录"米联客"FPGA社区-www.uisrc.com视频课程、答疑解惑!

1概述

使用XILINX 的软件工具VIVADO以及XILINX的7代以上的FPGA或者SOC掌握AXI-4总线结束,并且可以灵活使用AXI-4总线技术完成数据的交换,可以让我们在构建强大的FPGA内部总线数据互联通信方面取得高效、高速、标准化的优势。

关于AXI4总线协议的部分介绍请阅读"01AXI4总线axi-lite-slave"。

本文实验目的:

1:掌握基于VIVADO工具产生AXI协议模板

2:掌握通过VIVADO工具产生AXI-full-slave代码

3:理解AXI-full-slave中自定义寄存器的地址分配

4:掌握通过VIVADO封装AXI-full-slave图形化IP

5:通过仿真验证AXI-full-slave IP的工作是否正常。

2创建axi4-full-slave总线接口IP

新建fpga工程,过程省略

新建完成工程后,单击菜单栏Tools->Create and Package New IP,开始创建一个AXI4-Full接口总线IP

选择使用vivado自带的AXI总线模板创建一个AXI4-FULL接口IP

设置IP的名字为saxi_full

模板支持3种协议,分别是AXI4-Full ,AXI4-Lite ,AXI4-Stream,这里选择full;

总线包括Master和Slave两种模式,这里选择Slave模式

 

这里选择Verify Peripheral IP using AXI4 VIP 可以对AXI4-FULL快速验证

单击Finish后展开VIVADO自动产生的demo,单击Block Design的工程,可以看到如下2个IP。其中saxi_full_0就是我们自定义的IP,另外一个master_0是用来读写我们自定义的saxi_full_0,以此验证我们的IP正确性。

采用默认地址分配即可

 

继续再看代码看看里面有什么东西

3程序分析

1:axi-full-slave的axi_awready

当满足条件(~axi_awready && S_AXI_AWVALID && ~axi_awv_awr_flag && ~axi_arv_arr_flag)=1的时候表示可以进行一次AXI-FULL的burst写操作了,这个时候AXI-FULL-SLAVE设置axi_awready <= 1'b1和axi_awv_awr_flag <= 1'b1

// axi_awready is asserted for one S_AXI_ACLK clock cycle when both

    // S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_awready is

    // de-asserted when reset is low.

 

    always @( posedge S_AXI_ACLK )

    begin

      if ( S_AXI_ARESETN == 1'b0 )

        begin

          axi_awready <= 1'b0;

          axi_awv_awr_flag <= 1'b0;

        end

      else

        begin    

          if (~axi_awready && S_AXI_AWVALID && ~axi_awv_awr_flag && ~axi_arv_arr_flag)

            begin

              // slave is ready to accept an address and

              // associated control signals

              axi_awready <= 1'b1;

              axi_awv_awr_flag  <= 1'b1;

              // used for generation of bresp() and bvalid

            end

          else if (S_AXI_WLAST && axi_wready)          

          // preparing to accept next address after current write burst tx completion

            begin

              axi_awv_awr_flag  <= 1'b0;

            end

          else        

            begin

              axi_awready <= 1'b0;

            end

        end

    end    

2:axi-full-slave的axi_awaddr

AXI的burst模式包括3种:

1:fixed burst这种模式下地址都是相同的

2: incremental burst这种模式下地址递增

3: Wrapping burst 这只模式下地址达到设置的最大地址边界后返回原来的地址。

本文demo中以下三种模式的具体代码如下:

    //This process is used to latch the address when both

    //S_AXI_ARVALID and S_AXI_RVALID are valid.

    always @( posedge S_AXI_ACLK )

    begin

      if ( S_AXI_ARESETN == 1'b0 )

        begin

          axi_araddr <= 0;

          axi_arlen_cntr <= 0;

          axi_arburst <= 0;

          axi_arlen <= 0;

          axi_rlast <= 1'b0;

          axi_ruser <= 0;

        end

      else

        begin    

          if (~axi_arready && S_AXI_ARVALID && ~axi_arv_arr_flag)

            begin

              // address latching

              axi_araddr <= S_AXI_ARADDR[C_S_AXI_ADDR_WIDTH - 1:0];

              axi_arburst <= S_AXI_ARBURST;

              axi_arlen <= S_AXI_ARLEN;    

              // start address of transfer

              axi_arlen_cntr <= 0;

              axi_rlast <= 1'b0;

            end  

          else if((axi_arlen_cntr <= axi_arlen) && axi_rvalid && S_AXI_RREADY)        

            begin

               

              axi_arlen_cntr <= axi_arlen_cntr + 1;

              axi_rlast <= 1'b0;

             

              case (axi_arburst)

                2'b00: // fixed burst

                 // The read address for all the beats in the transaction are fixed

                  begin

                    axi_araddr       <= axi_araddr;        

                    //for arsize = 4 bytes (010)

                  end  

                2'b01: //incremental burst

                // The read address for all the beats in the transaction are increments by awsize

                  begin

                    axi_araddr[C_S_AXI_ADDR_WIDTH - 1:ADDR_LSB] <= axi_araddr[C_S_AXI_ADDR_WIDTH - 1:ADDR_LSB] + 1;

                    //araddr aligned to 4 byte boundary

                    axi_araddr[ADDR_LSB-1:0]  <= {ADDR_LSB{1'b0}};  

                    //for awsize = 4 bytes (010)

                  end  

                2'b10: //Wrapping burst

                // The read address wraps when the address reaches wrap boundary

                  if (ar_wrap_en)

                    begin

                      axi_araddr <= (axi_araddr - ar_wrap_size);

                    end

                  else

                    begin

                    axi_araddr[C_S_AXI_ADDR_WIDTH - 1:ADDR_LSB] <= axi_araddr[C_S_AXI_ADDR_WIDTH - 1:ADDR_LSB] + 1;

                    //araddr aligned to 4 byte boundary

                    axi_araddr[ADDR_LSB-1:0]  <= {ADDR_LSB{1'b0}};  

                    end                      

                default: //reserved (incremental burst for example)

                  begin

                    axi_araddr <= axi_araddr[C_S_AXI_ADDR_WIDTH - 1:ADDR_LSB]+1;

                    //for arsize = 4 bytes (010)

                  end

              endcase              

            end

          else if((axi_arlen_cntr == axi_arlen) && ~axi_rlast && axi_arv_arr_flag )  

            begin

              axi_rlast <= 1'b1;

            end          

          else if (S_AXI_RREADY)  

            begin

              axi_rlast <= 1'b0;

            end          

        end

    end

3:axi-full-slave的axi_wready

当满足条件( ~axi_wready && S_AXI_WVALID && axi_awv_awr_flag)==1 设置axi_wready为1.这里可以看出,S_AXI_WVALID必须在一次burst中持续有效,直到满足条件(S_AXI_WLAST && axi_wready),否则AXI-FULL-SLAVE会出错,这一点有别于AXI-LITE-SLAVE每次只读写一个数据。

    // axi_wready is asserted for one S_AXI_ACLK clock cycle when both

    // S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_wready is

    // de-asserted when reset is low.

 

    always @( posedge S_AXI_ACLK )

    begin

      if ( S_AXI_ARESETN == 1'b0 )

        begin

          axi_wready <= 1'b0;

        end

      else

        begin    

          if ( ~axi_wready && S_AXI_WVALID && axi_awv_awr_flag)

            begin

              // slave can accept the write data

              axi_wready <= 1'b1;

            end

          //else if (~axi_awv_awr_flag)

          else if (S_AXI_WLAST && axi_wready)

            begin

              axi_wready <= 1'b0;

            end

        end

    end      

4:axi-full-slave的axi_bvalid信号

axi_bvalid用于告知axi master axi-slave端已经完成数据接收了

给出ACK,写操作LAST信号的下一个时钟,AXI-SLAVE给出ACK信号

    always @( posedge S_AXI_ACLK )

    begin

      if ( S_AXI_ARESETN == 1'b0 )

        begin

          axi_bvalid <= 0;

          axi_bresp <= 2'b0;

          axi_buser <= 0;

        end

      else

        begin    

          if (axi_awv_awr_flag && axi_wready && S_AXI_WVALID && ~axi_bvalid && S_AXI_WLAST )

            begin

              axi_bvalid <= 1'b1;

              axi_bresp  <= 2'b0;

              // 'OKAY' response

            end                  

          else

            begin

              if (S_AXI_BREADY && axi_bvalid)

              //check if bready is asserted while bvalid is high)

              //(there is a possibility that bready is always asserted high)  

                begin

                  axi_bvalid <= 1'b0;

                end  

            end

        end

     end  

5:axi-full-slave的axi_arready信号

当满足条件(~axi_arready && S_AXI_ARVALID && ~axi_awv_awr_flag && ~axi_arv_arr_flag)=1的时候表示可以进行一次AXI-FULL的burst读操作了,这个时候AXI -FULL-SLAVE设置axi_arready <= 1'b1和axi_arv_arr_flag <= 1'b1

// S_AXI_ARVALID is asserted. axi_awready is

    // de-asserted when reset (active low) is asserted.

    // The read address is also latched when S_AXI_ARVALID is

    // asserted. axi_araddr is reset to zero on reset assertion.

 

    always @( posedge S_AXI_ACLK )

    begin

      if ( S_AXI_ARESETN == 1'b0 )

        begin

          axi_arready <= 1'b0;

          axi_arv_arr_flag <= 1'b0;

        end

      else

        begin    

          if (~axi_arready && S_AXI_ARVALID && ~axi_awv_awr_flag && ~axi_arv_arr_flag)

            begin

              axi_arready <= 1'b1;

              axi_arv_arr_flag <= 1'b1;

            end

          else if (axi_rvalid && S_AXI_RREADY && axi_arlen_cntr == axi_arlen)

          // preparing to accept next address after current read completion

            begin

              axi_arv_arr_flag  <= 1'b0;

            end

          else        

            begin

              axi_arready <= 1'b0;

            end

        end

    end      

6:axi-full-slave的axi_araddr信号

AXI-的读写操作几乎是相对的代码,AXI的burst模式包括3种:

1:fixed burst这种模式下地址都是相同的

2: incremental burst这种模式下地址递增

3: Wrapping burst 这只模式下地址达到设置的最大地址边界后返回原来的地址。

本文demo种以下三种模式的具体代码如下:

 

//This process is used to latch the address when both

    //S_AXI_ARVALID and S_AXI_RVALID are valid.

    always @( posedge S_AXI_ACLK )

    begin

      if ( S_AXI_ARESETN == 1'b0 )

        begin

          axi_araddr <= 0;

          axi_arlen_cntr <= 0;

          axi_arburst <= 0;

          axi_arlen <= 0;

          axi_rlast <= 1'b0;

          axi_ruser <= 0;

        end

      else

        begin    

          if (~axi_arready && S_AXI_ARVALID && ~axi_arv_arr_flag)

            begin

              // address latching

              axi_araddr <= S_AXI_ARADDR[C_S_AXI_ADDR_WIDTH - 1:0];

              axi_arburst <= S_AXI_ARBURST;

              axi_arlen <= S_AXI_ARLEN;    

              // start address of transfer

              axi_arlen_cntr <= 0;

              axi_rlast <= 1'b0;

            end  

          else if((axi_arlen_cntr <= axi_arlen) && axi_rvalid && S_AXI_RREADY)        

            begin

               

              axi_arlen_cntr <= axi_arlen_cntr + 1;

              axi_rlast <= 1'b0;

             

              case (axi_arburst)

                2'b00: // fixed burst

                 // The read address for all the beats in the transaction are fixed

                  begin

                    axi_araddr       <= axi_araddr;        

                    //for arsize = 4 bytes (010)

                  end  

                2'b01: //incremental burst

                // The read address for all the beats in the transaction are increments by awsize

                  begin

                    axi_araddr[C_S_AXI_ADDR_WIDTH - 1:ADDR_LSB] <= axi_araddr[C_S_AXI_ADDR_WIDTH - 1:ADDR_LSB] + 1;

                    //araddr aligned to 4 byte boundary

                    axi_araddr[ADDR_LSB-1:0]  <= {ADDR_LSB{1'b0}};  

                    //for awsize = 4 bytes (010)

                  end  

                2'b10: //Wrapping burst

                // The read address wraps when the address reaches wrap boundary

                  if (ar_wrap_en)

                    begin

                      axi_araddr <= (axi_araddr - ar_wrap_size);

                    end

                  else

                    begin

                    axi_araddr[C_S_AXI_ADDR_WIDTH - 1:ADDR_LSB] <= axi_araddr[C_S_AXI_ADDR_WIDTH - 1:ADDR_LSB] + 1;

                    //araddr aligned to 4 byte boundary

                    axi_araddr[ADDR_LSB-1:0]  <= {ADDR_LSB{1'b0}};  

                    end                      

                default: //reserved (incremental burst for example)

                  begin

                    axi_araddr <= axi_araddr[C_S_AXI_ADDR_WIDTH - 1:ADDR_LSB]+1;

                    //for arsize = 4 bytes (010)

                  end

              endcase              

            end

          else if((axi_arlen_cntr == axi_arlen) && ~axi_rlast && axi_arv_arr_flag )  

            begin

              axi_rlast <= 1'b1;

            end          

          else if (S_AXI_RREADY)  

            begin

              axi_rlast <= 1'b0;

            end          

        end

    end    

7:axi-full-slave的axi_rvalid信号

在用VIVADO模板产生的demo中,读操作数据不是连续读的,通过axi_rvalid设置AXI-SLAVE FULL读数据有效。

    always @( posedge S_AXI_ACLK )

    begin

      if ( S_AXI_ARESETN == 1'b0 )

        begin

          axi_rvalid <= 0;

          axi_rresp  <= 0;

        end

      else

        begin    

          if (axi_arv_arr_flag && ~axi_rvalid)

            begin

              axi_rvalid <= 1'b1;

              axi_rresp  <= 2'b0;

              // 'OKAY' response

            end  

          else if (axi_rvalid && S_AXI_RREADY)

            begin

              axi_rvalid <= 1'b0;

            end            

        end

    end

8:数据保存到bock ram

以下是利用block ram完成数据的保存和回读

    // implement Block RAM(s)

    generate

      for(i=0; i<= USER_NUM_MEM-1; i=i+1)

        begin:BRAM_GEN

          wire mem_rden;

          wire mem_wren;

     

          assign mem_wren = axi_wready && S_AXI_WVALID ;

     

          assign mem_rden = axi_arv_arr_flag ; //& ~axi_rvalid

           

          for(mem_byte_index=0; mem_byte_index<= (C_S_AXI_DATA_WIDTH/8-1); mem_byte_index=mem_byte_index+1)

          begin:BYTE_BRAM_GEN

            wire [8-1:0] data_in ;

            wire [8-1:0] data_out;

            reg  [8-1:0] byte_ram [0 : 15];

            integer  j;

           

            //assigning 8 bit data

            assign data_in  = S_AXI_WDATA[(mem_byte_index*8+7) -: 8];

            assign data_out = byte_ram[mem_address];

           

            always @( posedge S_AXI_ACLK )

            begin

              if (mem_wren && S_AXI_WSTRB[mem_byte_index])

                begin

                  byte_ram[mem_address] <= data_in;

                end  

            end    

           

            always @( posedge S_AXI_ACLK )

            begin

              if (mem_rden)

                begin

                  mem_data_out[i][(mem_byte_index*8+7) -: 8] <= data_out;

                end  

            end    

                     

        end

      end      

    endgenerate

4实验结果

仿真结果:

标签:begin,full,slave,04,araddr,axi,&&,end,AXI
From: https://www.cnblogs.com/milianke/p/17936362.html

相关文章

  • 05 AXI4总线axi-full-master
    软件版本:vitis2021.1(vivado2021.1)操作系统:WIN1064bit硬件平台:适用XILINXA7/K7/Z7/ZU/KU系列FPGA登录"米联客"FPGA社区-www.uisrc.com视频课程、答疑解惑!1概述使用XILINX的软件工具VIVADO以及XILINX的7代以上的FPGA或者SOC掌握AXI-4总线结束,并且可以灵活使用AXI-4总线技......
  • 02 AXI4总线axi-lite-slave
    软件版本:vitis2021.1(vivado2021.1)操作系统:WIN1064bit硬件平台:适用XILINXA7/K7/Z7/ZU/KU系列FPGA登录"米联客"FPGA社区-www.uisrc.com视频课程、答疑解惑!1概述使用XILINX的软件工具VIVADO以及XILINX的7代以上的FPGA或者SOC掌握AXI-4总线协议,并且可以灵活使用AXI-4总线技......
  • 3-1-04 FPGA使用fdma读写DDR
    软件版本:vitis2021.1(vivado2021.1)操作系统:WIN1064bit硬件平台:适用XILINXA7/K7/Z7/ZU/KU系列FPGA登录"米联客"FPGA社区-www.uisrc.com视频课程、答疑解惑!4.1概述    在前文的实验中我们详细介绍了FDMA的使用方法,前面一节课演示了FDMA读写AXI-BRAM,本文我们继续使用FDM......
  • 3-1-02AXI4-FULL-uiFDMA IP仿真验证
    软件版本:vitis2021.1(vivado2021.1)操作系统:WIN1064bit硬件平台:适用XILINXA7/K7/Z7/ZU/KU系列FPGA登录"米联客"FPGA社区-www.uisrc.com视频课程、答疑解惑!2.1概述本文试验中对前面编写的FDMAIP进行仿真验证。2.2saxi_full_memIP介绍这个IP的源码可以基于XILINX提供的ax......
  • 3-1-01 AXI4-FULL-MASTER IP FDMA介绍
    件版本:vitis2021.1(vivado2021.1)操作系统:WIN1064bit硬件平台:适用XILINXA7/K7/Z7/ZU/KU系列FPGA登录"米联客"FPGA社区-www.uisrc.com视频课程、答疑解惑!1.1概述    FDMA是米联客的基于AXI4总线协议定制的一个DMA控制器。本文对AXI4-FULL总线接口进行了封装,同时定义了简......
  • 1-1-04 VIVADO设置VSCODE为第三方编译器
    使用第三方编辑工具可以让开发代码变的更加高效,vscode是非常好用的第三方编辑器,下面我们演示如何vivado中设置vscode为第三方编译器双击打开vivado程序点击设置选择代码编译器"TextEditor"选择编辑器,里面包含Notepad++等各类编译器,但是我们要设置的VSCODE并不包含在里面......
  • 初中英语优秀范文100篇-042Is It Good for Students to Play Video Games?学生玩游戏
    PDF格式公众号回复关键字:SHCZFW042记忆树1Videogameshavebecomemoreandmorepopularnow.翻译现在视频游戏变得越来越流行。简化记忆流行句子结构1主语(Subject):"Videogames"(电子游戏)是句子的主题,表示现在完成时态的承受者。2谓语(Predicate):"havebe......
  • 代码随想录算法训练营第十七天 | 110.平衡二叉树,257. 二叉树的所有路径,404.左叶子之和
    一、110.平衡二叉树题目链接:LeetCode110.平衡二叉树学习:思路:后序遍历。实际上是由叶结点到根结点,若有一颗子树不是平衡二叉树,则直接返回给根结点二、257.二叉树的所有路径题目链接:LeetCode257.二叉树的所有路径学习:思路:递归+回溯。因为是线=先遍历根结点,然后遍历左孩......
  • 【黑产攻防道04】利用pow工作量证明降低黑产的破解效率
    上一期我们提到,黑产有三种常见的破解方式:1.通过识别出验证码图片答案实现批量破解验证,即图片答案识别;2.在了解通讯流程之后直接携带相关参数发请求,即协议破解;3.使用各种客户端模拟器来模拟真人通过验证,即模拟器破解。针对这黑产的“三板斧”,极验总结了一一对应的验证码攻防点:图片答......
  • 如何在 Ubuntu 16.04 上使用 Minio 设置对象存储服务器
    前些天发现了一个人工智能学习网站,通俗易懂,风趣幽默,最重要的屌图甚多,忍不住分享一下给大家。点击跳转到网站。介绍从基于云的备份解决方案到高可用性内容交付网络(CDN),对象存储已成为现代技术领域不可或缺的一部分。而且,凭借其占用空间小、界面简单以及与多种云存储服务的兼容性......