AXI协议详解(8)-排序模型

排序模型

本章介绍 AXI 协议如何使用事务 ID 标签来启用多个未完成地址的发布和无序事务处理。 它包含以下部分:

  • 排序模型
  • 传输 ID 字段
  • 阅读排序
  • 正常写入排序
  • 写入数据交错
  • 读写交互
  • ID 字段的互连使用
  • 推荐的 ID 字段宽度

8.1 关于排序模型

AXI 协议支持乱序事务(out of order)和多个未完成地址的发送(outstanding)。 这些特性能够实现高性能互连,最大限度地提高数据吞吐量和系统效率。

ID 信号通过使每个端口充当多个有序端口来支持无序事务。 所有具有给定 ID 的事务都必须排序,但对具有不同 ID 的事务的排序没有限制。 这五个事务ID 是:
AWID 信号写地址组的 ID 标签。

WID 写入事务的写入 ID 标记。 与写入数据一起,Master传输 WID 以匹配相应地址的 AWID。

BID 写响应的 ID 标签。 Slave传输一个 BID 以匹配它正在响应的事务的 AWID 和 WID。

ARID 信号读取地址组的 ID 标签。

RID 读取事务的读取 ID 标签。 Slave传输一个 RID 以匹配它正在响应的事务的 ARID。
注意:
Slave和Master不需要使用这些高级功能。 简单的Slave和Master可以按照它们发出的顺序一次处理一个事务。

发射多个未完成地址的能力意味着Master可以发射事务地址,而无需等待较早的事务完成。 此功能可以提高系统性能,因为它可以并行处理事务。

无序完成事务的能力意味着可以完成对较快内存区域的事务,而无需等待较早的事务对较慢的内存区域。 此功能还可以提高系统性能,因为它减少了事务延迟的影响。
注意:
事务的重新排序总是相对于其他事务。 没有用于在突发内重新排序数据传输的设施。 定义突发的地址和控制信号控制突发内的传输顺序。

8.2 传输 ID 字段

AXI 协议提供了一个 ID 字段,使Master能够发出多个单独的事务,每个事务必须按顺序返回。

master 可以使用事务的 ARID 或 AWID 字段来提供有关 master 排序要求的附加信息。 管理事务排序的规则如下:

  • 来自不同Master的事务没有顺序限制。他们可以按任何顺序完成。
  • 来自同一Master但具有不同 ID 值的事务没有排序限制。他们可以按任何顺序完成。
  • 具有相同 AWID 值的一系列写入事务的数据必须按照master发出地址的相同顺序完成。
  • 具有相同ARID值的一系列读事务的数据必须按照以下顺序返回:
    • 当具有相同 ARID 的读取来自同一slave时,slave必须确保读取数据以与接收地址相同的顺序返回。
    • 当具有相同 ARID 的读取来自不同的salve时,互连必须确保读取数据的返回顺序与master发出地址的顺序相同。
  • 具有相同AWIDARID 的读和写事务之间没有顺序限制。如果 master 需要排序限制,那么它必须确保在发出第二个事务之前完全完成第一个事务。

8.3 读排序

在Master接口上,来自具有相同 ARID 值的读取事务的读取数据必须以与master接口发出地址相同的顺序到达。具有不同 ARID 值的读取事务的数据可以以任何顺序返回,也可以将具有不同 ARID 字段的事务的读取数据交错。

Slave必须按照接收地址的相同顺序,从具有相同 ARID 值的一系列读取事务中返回读取数据。在具有不同 ARID 值的读取事务序列中,Slave可以以与事务到达的顺序不同的顺序返回读取数据。

Slave必须确保任何返回读取数据的 RID 值与其响应的地址的 ARID 值匹配。

互连必须确保来自不同Slave的具有相同 ARID 值的读取事务序列按顺序完成。

读数据重排序深度是指从Slave中可被重排序的待处理地址的数量。按顺序处理所有事务的Slave的读取数据重新排序深度为 1。读取数据重新排序深度是一个静态值,必须由Slave设计者指定。

8.4 正常写入排序

如果Slave不支持写入数据交错,则Master必须以其发出事务地址的相同顺序发出写入事务的数据。

大多数Slave设计不支持写入数据交错,因此这些类型的Slave设计必须按照它们接收地址的相同顺序接收写入数据。 如果互连将来自不同Master的写事务合并到一个Slave,则必须确保它按地址顺序合并写入数据。

即使写入事务具有不同的 AWID 值,这些限制也适用。

8.5 写入数据交错

写入数据交错使Slave接口能够接受具有不同 AWID 值的交错写入数据。 Slave声明写入数据交错深度,指示接口是否可以接受来自具有不同 AWID 值的源发出的交错写入数据。 写入数据交错深度是静态配置的。 缺省情况下,任一接口的写数据交错深度为1。
注意:
不允许交错具有相同 AWID 的不同事务的写入数据。(不同事务但是AWID相同时,不能交错)

写数据交错深度是当前在Slave接口中可以提供写数据的不同地址的数量。例如,一个写数据交错深度为2的Slave有4个不同的地址,所有地址都具有不同的 AWID 值,挂起可以接受前两个挂起地址中的任何一个的数据。

Slave接收每个事务的第一个数据项的顺序必须与它接收事务地址的顺序相同。

写入数据交错可以防止当多个互连组合发往同一个Slave的写入数据流时,发生停顿。 互连可能将来自慢速源的一个写入数据流和来自快速源的另一个写入数据流组合在一起。 通过交错两个写入数据流,可以提高系统性能。
注意:
如果具有不同 AWID 值的两个写入事务访问相同或重叠的地址位置,则未定义处理顺序。 更高级别的协议必须确保事务处理的正确顺序。

能够生成仅具有一个 AWID 值的写数据的Master接口会按照其发出地址的相同顺序生成所有写数据。 但是,如果Slave接口的写入数据交错深度大于 1,则Master接口可以使用不同的 WID 值交错写入数据。

对于大多数可以在内部控制写入数据生成的Master,写入数据交错是没有必要的。 这样的Master可以按照它生成地址的相同顺序生成写数据。 但是,以不同速度从多个源传递写入数据的Master接口可以交错这些源以最大限度地利用互连。

为避免死锁情况,Slave接口必须具有大于 1 的写入交错深度,前提是它可以连续接受交错写入数据。 Slave接口绝不能为了改变写入数据的顺序而停止接受写入数据。

8.6 读写交互

读和写事务之间没有顺序限制,它们可以以任何顺序完成。

如果Master需要给出读取和写入事务之间的关系,则它必须确保在发出较晚的事务之前完成较早的事务。在读取的情况下,当最后读取的数据返回到Master时,可以认为较早的事务已完成。在写的情况下,只有当Master收到写响应时才认为事务完成,当所有写数据都发送时认为写事务完成是不可接受的。

对于外设占用的地址区域,这通常意味着在需要排序限制的读写事务之间切换时,等待较早的事务完成。

对于内存区域,Master可以对未完成的事务执行地址检查,以确定新事务是否可能位于相同或重叠的地址区域。如果事务不重叠,则新事务可以开始而无需等待较早的事务完成。

8.7 ID 字段的互连使用

当Master接口连接到互连时,互连将附加位附加到该Master端口唯一的 ARID、AWID 和 WID 字段。

这有两个影响:

  • Master不必知道其他Master使用什么 ID 值,因为互连在将Master编号附加到字段时使 ID 值唯一。
  • Slave接口的ID 字段宽度比Master接口的ID 字段宽。

对于读取数据,互连使用 RID 字段的附加位来确定读取数据的目的地是哪个Master端口。 在将 RID 值传递到正确的Master端口之前,互连会删除 RID 字段的这些位。

8.8 ID 字段的推荐宽度

要利用 AXI 乱序事务功能,请使用以下建议:
• 在master组件中实现最多四位的事务 ID。
• 为互连中的master端口号实现最多四个额外的事务 ID 位。
• 在Slave组件中实现八位 ID 支持。

对于仅支持单个有序接口的master,可以将 ID 输出绑定到一个常量值,例如 0。

对于不使用排序信息而只是按顺序处理所有事务的Slave,可以使用标准的现成模块为Slave添加 ID 功能,从而可以设计不存在 ID 信号的基本功能 Slave。

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个基于AXI4协议的接口文件的示例代码: ``` interface axi4_interface( input logic CLK, // 时钟信号 input logic RST, // 复位信号 input logic [31:0] AWADDR, // AXI4写地址信号 input logic [2:0] AWPROT, // AXI4写保护信号 input logic [3:0] AWID, // AXI4写ID信号 input logic [7:0] AWLEN, // AXI4写传输长度信号 input logic [2:0] AWSIZE, // AXI4写传输大小信号 input logic [1:0] AWBURST, // AXI4写突发类型信号 input logic [31:0] WDATA, // AXI4写数据信号 input logic [3:0] WSTRB, // AXI4写数据使能信号 input logic WLAST, // AXI4写最后一个数据信号 input logic [31:0] ARADDR, // AXI4读地址信号 input logic [2:0] ARPROT, // AXI4读保护信号 input logic [3:0] ARID, // AXI4读ID信号 input logic [7:0] ARLEN, // AXI4读传输长度信号 input logic [2:0] ARSIZE, // AXI4读传输大小信号 input logic [1:0] ARBURST, // AXI4读突发类型信号 output logic [31:0] RDATA, // AXI4读数据信号 output logic [1:0] RRESP, // AXI4读响应信号 output logic RLAST, // AXI4读最后一个数据信号 output logic RVALID, // AXI4读有效信号 input logic RREADY, // AXI4读准备好信号 output logic BRESP, // AXI4写响应信号 output logic BVALID, // AXI4写有效信号 input logic BREADY // AXI4写准备好信号 ); // AXI4写接口 logic [31:0] awaddr_reg; logic [2:0] awprot_reg; logic [3:0] awid_reg; logic [7:0] awlen_reg; logic [2:0] awsize_reg; logic [1:0] awburst_reg; logic [31:0] wdata_reg; logic [3:0] wstrb_reg; logic wlast_reg; logic [1:0] bresp_reg; logic bvalid_reg; always_ff @(posedge CLK) begin if (RST) begin awaddr_reg <= 0; awprot_reg <= 0; awid_reg <= 0; awlen_reg <= 0; awsize_reg <= 0; awburst_reg <= 0; wdata_reg <= 0; wstrb_reg <= 0; wlast_reg <= 0; bresp_reg <= 0; bvalid_reg <= 0; end else begin awaddr_reg <= AWADDR; awprot_reg <= AWPROT; awid_reg <= AWID; awlen_reg <= AWLEN; awsize_reg <= AWSIZE; awburst_reg <= AWBURST; wdata_reg <= WDATA; wstrb_reg <= WSTRB; wlast_reg <= WLAST; if (BVALID && BREADY) begin bvalid_reg <= 0; end else if (!BVALID && BREADY) begin bvalid_reg <= 1; bresp_reg <= 0; end end end // AXI4读接口 logic [31:0] araddr_reg; logic [2:0] arprot_reg; logic [3:0] arid_reg; logic [7:0] arlen_reg; logic [2:0] arsize_reg; logic [1:0] arburst_reg; logic [31:0] rdata_reg; logic [1:0] rresp_reg; logic rlast_reg; logic rvalid_reg; always_ff @(posedge CLK) begin if (RST) begin araddr_reg <= 0; arprot_reg <= 0; arid_reg <= 0; arlen_reg <= 0; arsize_reg <= 0; arburst_reg <= 0; rdata_reg <= 0; rresp_reg <= 0; rlast_reg <= 0; rvalid_reg <= 0; end else begin araddr_reg <= ARADDR; arprot_reg <= ARPROT; arid_reg <= ARID; arlen_reg <= ARLEN; arsize_reg <= ARSIZE; arburst_reg <= ARBURST; if (RVALID && RREADY) begin rvalid_reg <= 0; end else if (!RVALID && RREADY) begin rvalid_reg <= 1; rdata_reg <= 0; // TODO: read data from memory rresp_reg <= 0; rlast_reg <= 0; end end end // AXI4写响应 assign BRESP = bresp_reg; assign BVALID = bvalid_reg; assign BREADY = !bvalid_reg || BRESP != 0; // AXI4读响应 assign RDATA = rdata_reg; assign RRESP = rresp_reg; assign RLAST = rlast_reg; assign RVALID = rvalid_reg; assign RREADY = 1; endinterface ``` 这个接口文件包含了AXI4协议中的所有信号,并且包含了一个简单的状态机,用于处理写入和读取操作。在这个示例中,我们假设所有的写入和读取操作都是针对一个简单的内存模块进行的,因此我们只需要在状态机中添加一些逻辑,以便从内存中读取和写入数据。需要注意的是,在实际应用中,AXI4接口文件通常会被分成多个子接口,以便处理不同的数据类型和交通流量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值