Xilinx-ZYNQ7000系列-学习笔记(27):AXI时序分析

Xilinx-ZYNQ7000系列-学习笔记(27):AXI时序分析

一、AXI基本知识

此部分之前的博客写过,大家请参考Xilinx-ZYNQ7000系列-学习笔记(10):AXI总线

下面将AXI_LITE各信号所表示的意义拿来:
在这里插入图片描述
在这里插入图片描述
官方给出的AXI握手协议如下:

AXI4 所采用的是一种 READY,==VALID ==握手通信机制,简单来说主从双方进行数据通信前,有一个握手的过程。 传输源 产生 VLAID 信号来指明何时数据或控制信息有效。而 目地源产生 READY 信号来指明已经准备好接受数据或控制信息。传输发生在 VALID和 READY 信号同时为高的时候。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、AXI读写监测时序图

2.1 AXI写

(1)得到axi_awready信号,表示写地址准备好了。 该信号表明从机已准备好接受地址和相关的控制信号。
在这里插入图片描述

在这里插入图片描述
(2)给axi_awaddr信号赋值,S_AXI_AWADDR为写地址,从PS端输出进来。
在这里插入图片描述
在这里插入图片描述
(3)得到axi_wready信号,表示写准备好了。 该信号表示从机可以接受写数据。
在这里插入图片描述
在这里插入图片描述
(4)寄存器写使能信号slv_reg_wren,用于指示什么时候向slv_reg中写数。

assign slv_reg_wren = axi_wready && S_AXI_WVALID && axi_awready && S_AXI_AWVALID;

在这里插入图片描述
slv_reg_wren拉高,开始判断axi_awaddr地址内的值,进而确定向哪个寄存器中写入数据,写入的数据由S_AXI_WDATA输入进来,并在S_AXI_WSTRB写选通信号拉高时写入(该信号指示哪些字节通道保存有效数据, 写数据总线的每八位有一个写选通位 )。整体过程如下图:
在这里插入图片描述
(5)写应答有效信号axi_bvalid,该信号表示通道正在发出有效的写响应信号。
在这里插入图片描述
在这里插入图片描述

2.2 AXI读

(1)得到axi_arready信号,表示读地址准备好了。 该信号表明从机已准备好接受地址和相关的控制信号。 得到axi_araddr信号,表示读地址。
在这里插入图片描述
在这里插入图片描述
(2)得到axi_rvalid信号,此信号表示通道正在发送所需的读取数据信号。
在这里插入图片描述
(3)寄存器写使能信号slv_reg_rden,用于指示什么时候从slv_reg中读数。

assign slv_reg_rden = axi_arready & S_AXI_ARVALID & ~axi_rvalid;

在这里插入图片描述
在这里插入图片描述

在任意触发状态下,reg_data_out都在被赋值,至于为哪个slv_reg的值由地址axi_araddr地址来决定。当slv_reg_rden拉高,reg_data_out的值被赋给axi_rdata,即输出出去,此时PS端即可读取到寄存器的值。整体过程如下图:
在这里插入图片描述

2.3 结合上位机分析完成程序
module data_addr(
    input   wire    sclk,
    input   wire  [31:0]  pl_addr,  //写入fpga的地址
    output  wire  [31:0]  pl_data,  //根据地址查找得到的数据
    input   wire  [7:0]   GPS_addr, //写入GPS的地址
    output  wire  [7:0]   GPS_data  //查找得到的GPS数据
);

reg [31:0] pl_data_r;
reg [7:0]  GPS_data_r;

always @(*) begin
    case(GPS_addr)
    8'd1: GPS_data_r <= 31'd11;
    8'd2: GPS_data_r <= 31'd12;
    8'd3: GPS_data_r <= 31'd13;
    8'd4: GPS_data_r <= 31'd14;
    8'd5: GPS_data_r <= 31'd15;
    default: GPS_data_r <= 31'd00;
    endcase
end

always @(*) begin
    case(pl_addr)
    31'd1: pl_data_r <= 31'd10000;
    31'd2: pl_data_r <= 31'd20000;
    31'd3: pl_data_r <= 31'd30000;
    31'd4: pl_data_r <= 31'd40000;
    31'd5: pl_data_r <= 31'd50000;
    default: pl_data_r <= 31'd88888;
    endcase
end
    
assign pl_data = pl_data_r;
assign GPS_data = GPS_data_r;
    
    
endmodule

首先从代码可以看出,向PL端的寄存器写指定的内容会输出指定的值。

int main()
{
	int pl_data;
	char gps_data;
	while(1){
		for(int i = 0;i<6;i++){
			XUartPl_WriteReg(XPAR_YIHUI_MPU_V1_0_BASEADDR, PL_ADDR, i);
			pl_data = XUartPl_ReadReg(XPAR_YIHUI_MPU_V1_0_BASEADDR, PL_DATA);
			printf("The data of PL ADDR[%d] = %d\n\r",i,pl_data);
			sleep(1);
		}
		for(int j = 0;j<6;j++){
			XUartPl_WriteReg(XPAR_YIHUI_MPU_V1_0_BASEADDR, GPS_ADDR, j);
			gps_data = XUartPl_ReadReg(XPAR_YIHUI_MPU_V1_0_BASEADDR, GPS_DATA);
			printf("The data of GPS ADDR[%d] = %d\n\r",j,gps_data);
			sleep(1);
		}
	}
    return 0;
}

向(AXI基地址+0)地址写数,即为向slv0为写入寄存器,写入的内容给了pl_addr
从(AXI基地址+4)地址读数,即从slv1寄存器读取数据,读取的内容由pl_data得到。
向(AXI基地址+8)地址写数,即为向slv2为写入寄存器,写入的内容给了GPS_addr
从(AXI基地址+12)地址读数,即从slv3寄存器读取数据,读取的内容由GPS_data得到。
在这里插入图片描述

在这里插入图片描述

以上是组合逻辑状态下,若为时序逻辑时,读写AXI需要进行打一拍操作。具体做法是:

写操作
S_AXI_AWADDR 、S_AXI_AWPROT、S_AXI_AWVALID、S_AXI_AWREADY、S_AXI_WDATA、S_AXI_WSTRB、S_AXI_WVALID、S_AXI_WREADY不进行操作。内部信号axi_awaddrslv_reg_wren需要延后一拍(axi_awaddr_d1、slv_reg_wren_d1),通过条件:

if(slv_reg_wren_d1 == 1'b1 && axi_awaddr_d1 == xxx(地址偏移量))

可以使用相应寄存器写入后的值,这里用延一拍的数据正好是当前写入后的寄存器中的新数据,不至于错拍。

读操作
S_AXI_ARADDR、S_AXI_ARPROT、S_AXI_ARVALID、S_AXI_ARREADY、S_AXI_RDATA、S_AXI_RRESPS_AXI_RVALID 、S_AXI_RREADY不进行操作。内部信号,axi_rvalid、axi_rresp、slv_reg_rden需要延后一拍(axi_rvalid_d1、axi_rresp_d1、slv_reg_rden_d1),通过条件:

if (slv_reg_rden_d1) // 刘大利修改
  begin
    axi_rdata <= reg_data_out;     // register read data
  end  

可以等一个时钟周期再将reg_data_out的数值发出去,等这个时钟周期的目的是等需要被读取出去的新数据生成并成功赋给slv_reg,这样reg_data_out才会被更新,新数才能发送出去:

 always@(slv_reg_rden,axi_araddr) // slv_reg_rden配合地址构成组合逻辑,生成fifo的读使能信号
 begin
     if(slv_reg_rden == 1'b1 && axi_araddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] == OFFSET_UART_RX_DOUT)
         UART_rx_rd_en <= 1'b1;
     else
         UART_rx_rd_en <= 1'b0;    
 end
 assign slv_reg81 = {20'h0, UART_rx_dout}; // FIFO输出连接到slv_reg81
  • 5
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值