AXI backpressure反压机制代码

 本文将xilinx的axi读写代码进行修改,实现吞吐量达到50%

写入

原本的逻辑是在S_AXI_AWVALID 和 S_AXI_WVALID均有效后,axi_awready 有效,维持一个时钟周期
并且若S_AXI_BREADY&&axi_bvalid一直无效,aw_en将保持无效,从而使axi_awready无效再次有效来接收下一次写入

axi_awready 在一个 S_AXI_ACLK 时钟周期内被置位
always @( posedge S_AXI_ACLK )
	begin
	  if ( S_AXI_ARESETN == 1'b0 )
	    begin
	      axi_awready <= 1'b0;
	      aw_en <= 1'b1;
	    end 
	  else
	    begin    
	      if (~axi_awready && S_AXI_AWVALID && S_AXI_WVALID && aw_en)
	        begin
	          axi_awready <= 1'b1;
	          aw_en <= 1'b0;
	        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
———————————————————————————————————————————————————————————————————————————————————————
修改为这种逻辑,表示从机准备好了【S_AXI_BVALID拉高】但是主机一直未准备好【S_AXI_BREADY为低】

always @(posedge S_AXI_ACLK)
		axil_awready <= (S_AXI_AWVALID && S_AXI_WVALID)
			&& (!S_AXI_BVALID || S_AXI_BREADY);

但是这样不够,因为若axil_awready 保留超过一个时钟周期,还是有可能在BVALID && !BREADY有效时,
axil_awready有效,那这样子主机【此时上一个数据还未被正确接收响应】将会误以为可以发送下一个

所以修改为
initial	axil_awready = 1'b0;
	always @(posedge S_AXI_ACLK)
	if (!S_AXI_ARESETN)
		axil_awready <= 1'b0;
	else
		axil_awready <= !axil_awready
			&& (S_AXI_AWVALID && S_AXI_WVALID)
			&& (!S_AXI_BVALID || S_AXI_BREADY);

—————————————————————————— **axil_bvalid 的定义** ————————————————————————————————————
**axil_bvalid 在收到**axil_awready写准备信号之后,开始有效,直到得到主机发出的S_AXI_BREADY

initial	axil_bvalid = 0;
	always @(posedge S_AXI_ACLK)
	if (i_reset)
		axil_bvalid <= 0;
	else if (axil_awready)
		axil_bvalid <= 1;
	else if (S_AXI_BREADY)
		axil_bvalid <= 0;

	assign	S_AXI_BVALID = axil_bvalid;

修改逻辑后可以实现50%的吞吐量

 读取

always @( posedge S_AXI_ACLK )
	begin
	  if ( S_AXI_ARESETN == 1'b0 )
	    begin
	      axi_rvalid <= 0;
	      axi_rresp  <= 0;
	    end 
	  else
	    begin    
	      if (axi_arready && S_AXI_ARVALID && ~axi_rvalid)//在slv_reg_rden 读使能有效时
	        begin//告知完读取的地址,axi_rvalid 有效,一直保持到主机发出S_AXI_RREADY
	          // Valid read data is available at the read data bus
	          axi_rvalid <= 1'b1;
	          axi_rresp  <= 2'b0; // 'OKAY' response
	        end   
	      else if (axi_rvalid && S_AXI_RREADY)
	        begin
	          // Read data is accepted by the master
	          axi_rvalid <= 1'b0;
	        end                
	    end
	end
// 在接收到了S_AXI_ARVALID有效信号后,axi_arready维持一周期的有效,
// 直接读取地址【告知从机要读取的寄存器是哪一个】
always @( posedge S_AXI_ACLK )
	begin
	  if ( S_AXI_ARESETN == 1'b0 )
	    begin
	      axi_arready <= 1'b0;
	      axi_araddr  <= 32'b0;
	    end 
	  else
	    begin    
	      if (~axi_arready && S_AXI_ARVALID)
	        begin
	          // indicates that the slave has acceped the valid read address
	          axi_arready <= 1'b1;
	          // Read address latching
	          axi_araddr  <= S_AXI_ARADDR;
	        end
	      else
	        begin
	          axi_arready <= 1'b0;
	        end
	    end 
	end
assign slv_reg_rden = axi_arready & S_AXI_ARVALID & ~axi_rvalid;
// 这个逻辑表示在接收到了地址之后的下一个周期,读数据使能有效

—————————————————————————— **修改之后的逻辑** ————————————————————————————————————
当S_AXI_ARVALID && S_AXI_ARREADY有效后【也就是地址读完之后】
S_AXI_RVALID 有效 ,axil_arready 无效
接收到S_AXI_RREADY,S_AXI_RVALID 无效,axil_arready 再次有效,可以读取下一次的数据

always @(*)
		axil_arready = !S_AXI_RVALID;
// 这允许我们将 S_AXI_ARREADY 保持在高电平,直到读请求到来,然后立即将其丢弃,直到读响应发出。

assign	S_AXI_ARREADY = axil_arready;

assign	S_AXI_RVALID = axil_read_valid;

assign	axil_read_ready = (S_AXI_ARVALID && S_AXI_ARREADY);

initial	axil_read_valid = 1'b0;
	always @(posedge S_AXI_ACLK)
	if (i_reset)
		axil_read_valid <= 1'b0;
	else if (S_AXI_ARVALID && S_AXI_ARREADY)
		axil_read_valid <= 1'b1;
	else if (S_AXI_RREADY)
		axil_read_valid <= 1'b0;

在!S_AXI_RVALID || S_AXI_RREADY以及
S_AXI_ARVALID && S_AXI_ARREADY有效时,读取数据

当使用缓冲机制,RVALID一直有效,只要上级发出RREADY,就可以迅速读取
assign	axil_read_ready = arskd_valid
&& (!axil_read_valid || S_AXI_RREADY);

二者的区别在于有缓冲器下,S_AXI_RREADY有效axil_read_ready 就有效

assign	axil_read_ready = (S_AXI_ARVALID && S_AXI_ARREADY);

  • 9
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
AXI (Advanced eXtensible Interface) to APB (Advanced Peripheral Bus) 的转换是在设计集成电路中进行不同接口间的连接和互通的重要处理。 在进行AXI到APB的转换时,我们需要一个中间的接口模块,将AXI主机接口和APB主机接口互通。这个模块需要实现AXI到APB的转换、地址映射、读写控制等功能。 首先,我们需要将AXI的地址、数据、控制信号等转换成适合APB接口的形式。具体来说,需要对地址进行适当的映射,并且将AXI的数据及控制信号切分成APB所需的大小。 其次,我们需要根据AXI协议的读写信号,转换成APB的读写控制信号。例如,当AXI发起读请求时,我们需要将其转换为APB的读控制信号,以及将AXI的读数据转换为APB的数据输出。 同时,读写地址映射也是必要的。因为AXI与APB的地址空间可能不匹配,我们需要在转换模块中进行地址的映射,以确保读写操作发生在正确的设备上。 最后,需要将APB的读写数据和控制信号转换为AXI的输出。例如,将APB的读数据输出转换为AXI的读数据输出,将APB的写请求转换为AXI的写请求等。 总之,AXI到APB的转换是在两种不同的总线接口间进行数据和控制信号的适配工作。通过实现一个中间转换模块,能够实现AXI和APB之间的互联,使它们可以相互通信和交换数据。这种转换过程在设计集成电路时是非常常见和重要的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值