FPGA开发(4)——AXI_LITE总线协议

这篇具有很好参考价值的文章主要介绍了FPGA开发(4)——AXI_LITE总线协议。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、AXI总线简介

对于axi总线的学习我主要是参考了赛灵思的ug1037文档以及arm的INI0022D手册,对其中的内容做了总结。axi_lite,fpga开发
AXI是amba总线的一种,包含三种,axi full、axi lite和axi stream。
axi_lite,fpga开发
axi_lite,fpga开发
AXI工作:axi接口包含了五组通道,分别是读地址、写地址、读数据、写数据以及写响应。数据可以在主机和从机中双向传输,AXI4支持最大256突发读写,AXI-lite只不支持突发读写。
axi_lite,fpga开发
axi_lite,fpga开发
1、axi支持数据突发传输,读和写通道可同时工作。Axi-lite则不支持突发传输,axi-stream可支持任意突发长度传输
2、其次,axi和axi-lite是地址映射的,axi-stream不是地址映射。Axi和axi-stream还可以结合起来,例如DMA等。

axi_lite,fpga开发
axi_lite,fpga开发
axi_lite,fpga开发
AXI接口:
1、赛灵思官方本身提供很多带axi接口的ip,有axi、axistream等
2、自行封装带有axi接口的ip,axi协议自动生成,添加DIY代码即可
3、外部添加axi-接口IP
4、HLS
5、axi for dsp
……
axi_lite,fpga开发
Vivado中axi互联
主要有interconnect和smartconnect,其中smart更精密,inter适用于所有。两种都作为axi ip核与arm axi接口之间转换的功能接口。
Inter和smart都是地址映射,axi-stream无法连接,但是axi-stream可以连接axis-inter,然后转换为地址映射
axi_lite,fpga开发
Axi互联核心提供1对多、多对1和多对多的接口。
axi_lite,fpga开发
axi_lite,fpga开发
axi_lite,fpga开发
包含了五组信号,写通道和读通道可以同时进行数据的传输
axi_lite,fpga开发
1、每一个独立的通道都包含valid和ready这样的握手机制
2、读通道和写通道数据传输最后会有一个last信号
3、读地址和写地址
4、读数据通道,数据支持多种位宽,然后读响应说明读的状态。
5、写数据通道,多种带宽,每个字节信号有一个频闪信号,用来说明数据有效。
6、写响应通道,从机用写响应通道反馈写的状态

二、AXI总线五组接口介绍

axi_lite,fpga开发
对于写地址通道,有这么一些关键的接口
1、写地址
2、写长度
3、写大小
4、写突发,有三种模式,固定、自增、回环
5、valid
6、ready
axi_lite,fpga开发
对于写数据通道,有这么一些关键的接口
1、写数据
2、频闪信号,表示数据有效
3、last,表示传输数据最后一个的标志
4、valid
5、ready
axi_lite,fpga开发
对于写响应通道,有这么一些关键的接口
1、bresp,代表了从机对主机写的回应,判断是否写入成功
2、valid
3、ready
axi_lite,fpga开发
axi_lite,fpga开发
读地址和读数据通道,与写相似

三、AXI信号约束

axi_lite,fpga开发
axi_lite,fpga开发
axi_lite,fpga开发

信号约束
共用时钟线,上升沿数据采样,在上升沿之后数据才可以变化。
低电平复位,复位时主机控制写地址、读地址和写数据的valid,从机控制读数据和写响应的valid。
axi_lite,fpga开发
axi_lite,fpga开发
信号约束
说明了五组信号中valid和ready信号的关系
当源端的数据或者地址或者控制信号有效时,拉高valid信号。然后这个valid信号要一直保持高电平直到ready信号为高并采样为止。
axi_lite,fpga开发
读地址和读数据的信号先后关系
1、主机arvaild信号不必等从机的arready
2、从机的arready可以等主机的arvalid
3、从机的arready可以先于主机的arvalid
4、从机的rvalid一定要在arvalid和arready之后才出现(重要)
5、从机的rvalid不必等主机的rready
6、主机的rready可以等从机的rvalid
7、主机的rready可以先于从机的rvalid
axi_lite,fpga开发
写地址和写通道类似前面读的过程
要注意一点,主机valid不要等待从机ready,否则有可能会引发死锁的产生。
axi_lite,fpga开发
axi_lite,fpga开发
axi_lite,fpga开发
在非高带宽应用场景,axi-lite接口是很常用的,比axi4少了很多信号。其有以下的特点:
1、不支持突发传输
2、传输的位宽位32或者64位
3、传输无缓存,不可配置
4、不支持独立访问
这边主要来学习axi-lite协议。

四、AXI-LITE信号时序图

axi_lite,fpga开发
首先上面这张图是输入信号的时序图。
axi_lite,fpga开发axi_lite,fpga开发
上面两张图是我根据看的两个手册画的axi-lite协议的时序图。

五、AXI-LITE的verilog代码

根据上面的时序图写了下述的代码,其内容也很简单就是定义了19组信号。这19个信号分为五组,分别是写地址、写数据、读地址、读数据以及写响应。每一组数据都含有valid和ready信号,基于握手机制传输数据。代码并不复杂,根据时序图就能很快写出来。

module axi_test(
    //aclk and reset_n
    input s_axi_aclk,
    input s_axi_aresetn,
    //write addr
    input [3:0] s_axi_awaddr,
    input [2:0] s_axi_awprot,
    input s_axi_awvalid,
    output s_axi_awready,
    //write data
    input [31:0] s_axi_wdata,
    input [3:0] s_axi_wstrb,
    input s_axi_wvalid,
    output s_axi_wready,
    //write response
    output [1:0] s_axi_bresp,
    output s_axi_bvalid,
    input s_axi_bready,
    //read addr
    input [3:0] s_axi_araddr,
    input [2:0] s_axi_arprot,
    input s_axi_arvalid,
    output s_axi_arready,
    //read data
    output [31:0] s_axi_rdata,
    output [1:0] s_axi_rresp,
    output s_axi_rvalid,
    input s_axi_rready,
    //output signal
    output axi_test
);


//axi4_lite signal
reg [3:0] axi_awaddr;
reg [3:0] axi_araddr;

reg axi_awready;
reg axi_wready;
reg axi_bvalid;
reg [1:0] axi_bresp;
reg axi_arready;
reg axi_rvalid;
reg [31:0] axi_rdata;
reg [1:0] axi_rresp;

//slave registers to save data
reg [31:0] slv_reg0;
reg [31:0] slv_reg1;
reg [31:0] slv_reg2;
reg [31:0] slv_reg3;
reg [31:0] reg_data_out;
reg aw_en;
integer byte_index;
wire slv_reg_rden;
wire slv_reg_wren;

//axi4-lite signal define
assign s_axi_awready=axi_awready;
assign s_axi_wready=axi_wready;
assign s_axi_bvalid=axi_bvalid;
assign s_axi_bresp=axi_bresp;
assign s_axi_arready=axi_arready;
assign s_axi_rdata=axi_rdata;
assign s_axi_rvalid=axi_rvalid;
assign s_axi_rresp=axi_rresp;

//awready signal
//aresetn:0
//~awready & awvalid & wvalid & awen:1
//bready & bvalide:0
//other:0
always @(posedge s_axi_aclk) begin
    if(~s_axi_aresetn)begin
      aw_en<=1'b1;
      axi_awready<=1'b0;
    end
    else begin
      if(~axi_awready && aw_en && s_axi_awvalid && s_axi_wvalid)begin
        aw_en<=1'b0;
        axi_awready<=1'b1;
      end
      else if(s_axi_bready && axi_bvalid)begin
        aw_en<=1'b1;
        axi_awready<=1'b0;
      end
      else begin
        axi_awready<=1'b0;
      end
    end
end

//awaddr signal
//aresetn:0
//~awready & awvalid & wvalid & awen:1
//other:same 
always @(posedge s_axi_aclk) begin
    if(~s_axi_aresetn)begin
      axi_awaddr<=4'd0;
    end
    else begin
      if(~axi_awready && aw_en && s_axi_awvalid && s_axi_wvalid)begin
        axi_awaddr<=s_axi_awaddr;
      end
    end
end

//axi_wready signal 
//aresetn:0
//~awready & awvalid & wvalid & awen:1
//other:0
always @(posedge s_axi_aclk) begin
    if(~s_axi_aresetn)begin
      axi_wready<=1'b0;
    end
    else begin
      if(~axi_awready && aw_en && s_axi_awvalid && s_axi_wvalid)begin
        axi_wready<=1'b1;
      end
      else begin
        axi_wready<=1'b0;
      end
    end
end

//wren signal
//awready && awvalid && wready && wvalid:1
//other:0
assign slv_reg_wren=s_axi_awvalid && s_axi_wvalid && axi_awready && axi_wready;

//write data to reg0 to reg3
always @(posedge s_axi_aclk) begin
    if(~s_axi_aresetn)begin
      slv_reg0<=32'd0;
      slv_reg1<=32'd0;
      slv_reg2<=32'd0;
      slv_reg3<=32'd0;
    end
    else begin
      if(slv_reg_wren)begin
        case(axi_awaddr[3:2])
            //reg0
            2'h0:begin
              for(byte_index=0;byte_index<=3;byte_index=byte_index+1)begin
                if(s_axi_wstrb[byte_index]==1'b1)begin
                  slv_reg0[(byte_index*8) +: 8]<=s_axi_wdata[(byte_index*8) +: 8];
                end
              end
            end
            //reg1
            2'h1:begin
              for(byte_index=0;byte_index<=3;byte_index=byte_index+1)begin
                if(s_axi_wstrb[byte_index]==1'b1)begin
                  slv_reg1[(byte_index*8) +: 8]<=s_axi_wdata[(byte_index*8) +: 8];
                end
              end
            end
            //reg2
            2'h2:begin
              for(byte_index=0;byte_index<=3;byte_index=byte_index+1)begin
                if(s_axi_wstrb[byte_index]==1'b1)begin
                  slv_reg2[(byte_index*8) +: 8]<=s_axi_wdata[(byte_index*8) +: 8];
                end
              end
            end
            //reg3
            2'h3:begin
              for(byte_index=0;byte_index<=3;byte_index=byte_index+1)begin
                if(s_axi_wstrb[byte_index]==1'b1)begin
                  slv_reg3[(byte_index*8) +: 8]<=s_axi_wdata[(byte_index*8) +: 8];
                end
              end
            end
            //no reg 
            default:begin
              slv_reg0<=slv_reg0;
              slv_reg1<=slv_reg1;
              slv_reg2<=slv_reg2;
              slv_reg3<=slv_reg3;
            end
        endcase
      end
    end
end

//breasp and bvalid signal
//aresetn:0
//awready && wready && awvalid && wvalid && ~bvalid:1
//bvalid && bready:1
always @(posedge s_axi_aclk) begin
    if(~s_axi_aresetn)begin
      axi_bvalid<=1'b0;
      axi_bresp<=2'd0;
    end
    else begin
      if(axi_awready && axi_wready && s_axi_wvalid && s_axi_awvalid && ~axi_bvalid)begin
        axi_bvalid<=1'b1;
        axi_bresp<=2'd0;
      end
      else if(s_axi_bready && axi_bvalid)begin
        axi_bvalid<=1'b0;
      end
    end
end

//arready signal 
//araddr save
//arsetn:0
//~arready && arvalid:1
//other:0
always @(posedge s_axi_aclk) begin
    if(~s_axi_aresetn)begin
      axi_arready<=1'b0;
      axi_araddr<=4'd0;
    end
    else begin
      if(~axi_arready && s_axi_arvalid)begin
        axi_arready<=1'b1;
        axi_araddr<=s_axi_araddr;
      end
      else begin
        axi_arready<=1'b0;
      end
    end
end

//rvalid and rresp signal 
//aresetn:0
//arready && arvalid && ~rvalid:1
//rvalid & rready:0
//other:0
always @(posedge s_axi_aclk) begin
    if(~s_axi_aresetn)begin
      axi_rvalid<=1'b0;
      axi_rresp<=2'd0;
    end
    else begin
      if(axi_arready && s_axi_arvalid && ~axi_rvalid)begin
        axi_rvalid<=1'b1;
        axi_rresp<=2'd0;
      end
      else if(axi_rvalid && s_axi_rready)begin
        axi_rvalid<=1'b0;
      end
    end
end

//read data from reg0 to reg3
assign slv_reg_rden=axi_arready && s_axi_arvalid && ~axi_rvalid;
always @(*) begin
    case(axi_araddr[3:2])
        2'h0:reg_data_out<=slv_reg0;
        2'h1:reg_data_out<=slv_reg1;
        2'h2:reg_data_out<=slv_reg2;
        2'h3:reg_data_out<=slv_reg3;
        default:reg_data_out<=32'd0;
    endcase
end

//output data
always @(posedge s_axi_aclk) begin
    if(~s_axi_aresetn)begin
      axi_rdata<=32'd0;
    end
    else begin
      if(slv_reg_rden)begin
        axi_rdata<=reg_data_out;
      end
    end
end

//axi_test
breath_led u_breath_led(
    .sys_clk            ( s_axi_aclk            ),
    .sys_rst_n          ( s_axi_aresetn         ),
    .sw_ctrl            ( slv_reg0[0]           ),
    .set_en             ( slv_reg1[31]          ),
    .set_freq_step      ( slv_reg1[9:0]         ),
    .led                ( axi_test              )
);


endmodule 

六、AXI-LITE测试——ps与pl互通

下面是我的block design,作为参照,我还使用vivado自带封装AXI接口的ip核封装了一个呼吸灯的代码,然后两个IP完成的功能是一样的,都是可以控制呼吸灯的闪烁,然后都可以从ps读取pl寄存器的值。
axi_lite,fpga开发
下面是我的ps端的C代码,主要完成功能就是对两个IP分别读写寄存器,来控制呼吸灯。还有另外一一个ip是number_recog是神经网络识别mnist的,这里不相关。只需看breath led和axi test这两个IP就可以。

#include "math.h"
#include "stdio.h"
#include "breathLED.h"
#include "xparameters.h"
#include "xil_io.h"

//baseaddr define
#define breath_led_baseaddr XPAR_BREATHLED_0_S00_AXI_BASEADDR
#define axi_test_baseaddr XPAR_AXI_TEST_0_BASEADDR
#define axi_num_recog_baseaddr XPAR_AXI_NUM_RECOG_TEST_0_BASEADDR

int main()
{
	//led test signal
	int a1;
	int a2;
	int a1_1;
	int a2_1;
	//data read from PL
	int data[10];
	//data change to double
	double data_lf[10];
	//find max data and cnt
	u32 i;
	u32 cnt;
	double max;
	//calculate the number probability
	double pro_all=0;
	double pro_num[10];

	//led control test
  	Xil_Out32(breath_led_baseaddr+BREATHLED_S00_AXI_SLV_REG0_OFFSET,0x00000001);
  	Xil_Out32(breath_led_baseaddr+BREATHLED_S00_AXI_SLV_REG1_OFFSET,0x80000050);
  	a1=Xil_In32(breath_led_baseaddr+BREATHLED_S00_AXI_SLV_REG0_OFFSET);
  	a2=Xil_In32(breath_led_baseaddr+BREATHLED_S00_AXI_SLV_REG1_OFFSET);
  	Xil_Out32(axi_test_baseaddr+0,0x00000001);
  	Xil_Out32(axi_test_baseaddr+4,0x80000050);
  	a1_1=Xil_In32(axi_test_baseaddr+0);
  	a2_1=Xil_In32(axi_test_baseaddr+4);
  	//data read
  	for(i=0;i<10;i++)
  	{
  		data[i]=Xil_In32(axi_num_recog_baseaddr+i*4);
  	}
  	//data change
  	for(i=0;i<10;i++)
  	{
  		data_lf[i]=data[i];
  	}
  	//find max data and cnt
  	max=data_lf[0];
  	cnt=0;
  	for(i=0;i<10;i++)
  	{
  		if(max<=data_lf[i])
  		{
  			max=data_lf[i];
  			cnt=i;
  		}
  	}
  	Xil_Out32(axi_num_recog_baseaddr+10*4,cnt);
  	//calculate the probability
  	for(i=0;i<10;i++)
  	{
  		data_lf[i]=data_lf[i]/max*10;
  	}
  	for(i=0;i<10;i++)
  	{
  		pro_all=pro_all+exp(data_lf[i]);
  	};
  	for(i=0;i<10;i++)
  	{
  		pro_num[i]=exp(data_lf[i])/pro_all;
  	}

  	printf("breath led test\n");
  	printf("a1=%d\n",a1);
  	printf("a2=%d\n",a2);
  	printf("\n");

  	printf("breath led  DIY test\n");
  	printf("a1_1=%d\n",a1_1);
  	printf("a2_1=%d\n",a2_1);
  	printf("\n");

  	printf("read num data test\n");
  	for(i=0;i<10;i++)
  	{
  	  	printf("data_%d=%d\n",i,data[i]);
  	}
  	printf("\n");

  	printf("output number and probability\n");
  	for(i=0;i<10;i++)
  	{
  		printf("The probability of the number %d is %f\n",i,pro_num[i]);
  	}
  	printf("the number is %d\n",cnt);


	return 0;
}

最终通过串口也可以得到,两个IP可以接收到的数据是一样的。说明自己写的axi-lite接口可以实现ps与pl之间的互通。
axi_lite,fpga开发文章来源地址https://www.toymoban.com/news/detail-792504.html

到了这里,关于FPGA开发(4)——AXI_LITE总线协议的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • <AMBA总线篇> AXI总线协议介绍

    目录 01 AXI协议简介 AXI协议特性 AXI协议传输特性 02 AXI协议架构 AXI协议架构 write transaction(写传输) read tramsaction(读传输) Interface and interconnect 典型的AXI系统拓扑 03 文章总结 大家好,这里是程序员 杰克 。一名平平无奇的嵌入式软件工程师。 对于学习Xilinx FPGA(ZYNQ)而言,官方提

    2024年02月10日
    浏览(43)
  • AXI总线协议

    目录 AXI协议简介 通道结构 基本传输 读burst示例 连续读burst示例  写burst示例 传输顺序 握手过程 写地址通道 写数据通道 写响应通道 读地址通道 读数据通道 通道之间的关系 通道握手信号的依赖关系 关于寻址选择 burst长度 burst大小 burst类型  地址固定的burst 地址递增的bur

    2024年02月15日
    浏览(37)
  • FPGA——AXI4总线详解

    目录 AXI4总线 1、什么是AXI 2、AXI4协议的优势 AXI4的工作模式 AXI4读操作: AXI4写操作 AXI4和AXI4-Lite、AXI4-Stream接口信号 握手信号 AXI相关术语     AXI(Advanced eXtensible Interface高级可扩展总线)是一种总线协议     AXI4包含3种类型的接口: 1)AXI4:主要面向高性能地址映射通信的

    2024年02月02日
    浏览(55)
  • AXI协议详解(9)-数据总线

    本章描述了 AXI 读写数据总线上不同大小的传输,以及接口如何使用字节不变字节序来处理混合字节序传输。 它包含以下部分: 数据总线 写选通 窄传输 字节不变性 AXI协议有两条独立的数据总线,一条用于读数据,一条用于写数据。 因为这些数据总线有自己独立的握手信号

    2024年02月04日
    浏览(40)
  • AMBA总线协议AXI——学习笔记

    2023.3.25 2023.4.23 AXI :高级可拓展接口 高性能、高带宽、低延迟 单向通道体系结构 独立的地址和数据通道 支持多项数据交换。通过 并行执行burst操作 ,极大地提高了数据吞吐能力。 AXI4 :高性能内存映射需求(如读写DDR、使用BRAM控制器读写BRAM等),为了区别,有时候也叫这

    2023年04月23日
    浏览(49)
  • FPGA AXI4总线信号介绍篇

    AXI是一种总线协议,可以挂在多个master和slave:         (1)AXI4:主要面向高性能地址映射通信的需求;(突发数据)(地址映射模式)         (2)AXI4-Lite:是一个轻量级的,适用于吞吐量较小的地址映射通信总线;(无突发)(地址映射模式)         (3)AXI4-

    2024年04月11日
    浏览(58)
  • 【接口协议】FPGA AXI接口协议详解

    AXI是一种高频率,高带宽,低延迟的总线协议,是一种突发传输协议,即相邻存储器连续进行数据传输。是由ARM公司推出的,后被用于FPGA。主要分为三种类型:AXI_FULL(全功能版),AXI_LITE(简化版),AXI_STREAM(面向数据流的)。本文详细说明AXI_FULL类型,后面两种类型是FULL型的简

    2024年02月20日
    浏览(49)
  • FPGA — AXI接口协议介绍

    基于Vivado的AXI参考指南UG1037 ARM文档:AMBA AXI协议规范(IHI0022D) 可去官网下载英文文档查看,也可下载资源:https://download.csdn.net/download/unique_ZRF/87008791 AXI(高级可扩展接口) 是ARM AMBA的一部分 AMBA(Advanced Microcontorller Bus Architecture)高级微控制器总线架构 ;是1996年首次引入的一组

    2024年02月09日
    浏览(48)
  • 【ARM AMBA AXI 入门 15 -- AXI-Lite 详细介绍】

    请阅读 【ARM AMBA AXI 总线 文章专栏导读】 AMBA AXI4 规范中包含三种不同的协议接口,分别是: AXI4-Full AXI4-Lite AXI4-Stream 上图中的 AXI FULL 和 AIX-Lite 我们都把它们叫做 Memory map, memory map的协议是可以寻址的,它是有地址的,它每次的访问都是针对内存中的一个

    2024年02月04日
    浏览(47)
  • FPGA中AXI协议的理解及接口信号的中文描述

    AXI简介 AXI4 所采用的是一种 READY , VALID 握手通信机制,即主从模块进行数据通信前, 先根据操作对各所用到的数据、地址通道进行握手。主要操作包括传输发送者 A 等到传输接受者 B 的 READY 信号后, A 将数据与 VALID 信号同时发送给 B ,这是一种典型的握手机制。 AXI 总线支

    2024年02月01日
    浏览(56)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包