[axi][学习笔记]Outstanding Transfer
主设备通过AR Channel发送读请求,使用ARVALID信号指示请求的有效性。从设备通过ARREADY信号确认接收请求。从设备通过R Channel返回数据,使用RVALID信号指示数据的有效性。主设备通过RREADY信号确认接收数据,并处理数据。主设备可以同时发起多个读请求,利用outstanding传输提高效率。通过这种方式,AXI4总线协议允许主设备在等待先前请求的响应时继续发送新的请求
在AXI4(Advanced eXtensible Interface 4)总线协议的上下文中,"Outstanding Transfer"通常指的是主设备(如处理器)已经发起但尚未完成的读或写操作。在AXI4协议中,主设备可以发起多个未完成的传输,这意味着它可以发送多个地址请求,而不必等待每个请求的响应。这种能力称为“outstanding”,它允许主设备在等待先前请求的响应时继续发送新的请求,从而提高了总线的利用率和系统的整体性能。
例如,如果主设备发起了一个读请求,但在从设备返回数据之前又发起了另一个读请求,那么这两个请求都被认为是“outstanding”的。主设备可以继续发起更多的请求,直到达到其配置的或协议允许的最大outstanding请求数。
在AXI4协议中,有几个信号和机制用于管理outstanding传输,包括:
ARVALID和AWVALID:用于指示读地址和写地址通道中的地址和控制信息是有效的。RREADY和WREADY:用于指示从设备准备好接收读数据和写数据。ARLEN和AWLEN:用于指定突发传输的长度。ARCACHE和AWCACHE:用于指定事务的缓存属性,这可以影响outstanding传输的行为。
通过有效地管理outstanding传输,系统设计者可以优化数据吞吐量和延迟,从而提高系统的性能。然而,过多的outstanding传输也可能导致资源争用和性能下降,因此需要在设计时进行仔细的平衡和优化。
让我们通过一个具体的例子来说明AXI4总线协议中的"Outstanding Transfer"概念。
假设我们有一个主设备(如处理器)和一个从设备(如存储器)通过AXI4总线连接。主设备想要从从设备读取数据,并且它希望利用outstanding传输来提高总线利用率和系统性能。
主设备首先发送一个读请求,包括地址和控制信息,通过读地址通道(AR Channel)发送。这个请求由ARVALID信号指示为有效,并且主设备等待从设备的ARREADY信号来确认从设备已经准备好接收这个请求。
一旦读请求被接受,主设备可以立即发送第二个读请求,而不必等待第一个请求的数据返回。这就是outstanding传输的体现。主设备可以继续发送更多的读请求,直到达到其配置的或协议允许的最大outstanding请求数。
例如,如果主设备配置为允许最多3个outstanding读请求,那么它可以连续发送3个读请求,而不必等待每个请求的响应。每个读请求的突发长度(由ARLEN信号指定)决定了将进行多少次连续的数据传输。
当从设备准备好返回第一个读请求的数据时,它通过读数据通道(R Channel)发送数据,使用RVALID信号指示数据的有效性。主设备使用RREADY信号来确认它已经准备好接收数据。
在这个过程中,主设备可以继续处理其他任务,同时等待从设备返回数据。这种并发处理提高了系统的效率,因为主设备不需要在每次请求后都等待响应。
总结来说,在AXI4总线协议中,outstanding传输允许主设备发起多个未完成的读或写操作,从而提高了总线的利用率和系统的整体性能。通过有效地管理这些outstanding传输,系统设计者可以优化数据吞吐量和延迟。
实例
假设我们有一个主设备(如处理器)和一个从设备(如存储器)通过AXI4总线连接。主设备想要从从设备读取数据,并且它希望利用outstanding传输来提高总线利用率和系统性能。主设备配置为允许最多3个outstanding读请求。
步骤1:发起第一个读请求
- 主设备发送第一个读请求,包括地址和控制信息,通过读地址通道(AR Channel)发送。
- 主设备设置
ARVALID信号为高电平,指示地址信息有效。 - 从设备通过设置
ARREADY信号为高电平来确认它已经准备好接收这个请求。 - 一旦
ARVALID和ARREADY都为高电平,读请求被接受,并且突发传输开始。
步骤2:发起第二个和第三个读请求
- 在等待第一个读请求的数据返回的同时,主设备发送第二个读请求,重复步骤1的过程。
- 主设备继续发送第三个读请求,同样重复步骤1的过程。
- 现在,主设备有3个outstanding读请求,每个请求都在等待数据返回。
步骤3:从设备返回数据
- 从设备准备好返回第一个读请求的数据,并通过读数据通道(R Channel)发送数据。
- 从设备设置
RVALID信号为高电平,指示数据有效。 - 主设备通过设置
RREADY信号为高电平来确认它已经准备好接收数据。 - 一旦
RVALID和RREADY都为高电平,主设备接收数据,并且从设备发送RLAST信号来指示这是突发传输的最后一个数据项。
步骤4:继续处理outstanding请求
- 主设备继续处理第二个和第三个读请求的数据返回,重复步骤3的过程。
- 如果主设备在处理这些请求时完成了其他任务,它可以继续发起新的读请求,只要不超过配置的outstanding请求数。
数据流总结
- 主设备通过AR Channel发送读请求,使用
ARVALID信号指示请求的有效性。 - 从设备通过
ARREADY信号确认接收请求。 - 从设备通过R Channel返回数据,使用
RVALID信号指示数据的有效性。 - 主设备通过
RREADY信号确认接收数据,并处理数据。 - 主设备可以同时发起多个读请求,利用outstanding传输提高效率。
通过这种方式,AXI4总线协议允许主设备在等待先前请求的响应时继续发送新的请求,从而提高了总线的利用率和系统的整体性能。
代码示例
在AXI4总线协议中,从设备(Slave)的逻辑负责处理来自主设备(Master)的读写请求,并返回相应的数据或确认。以下是一个简化的Verilog代码示例,用于模拟AXI4从设备的基本逻辑。这个示例将处理读请求,并返回数据。请注意,这个示例是为了说明目的而简化的,实际的AXI4从设备实现会更加复杂,并且需要处理更多的信号和协议细节。
module axi4_slave_sim(
input wire clk,
input wire reset,
// AXI4读地址通道
input wire [31:0] araddr,
input wire [3:0] arlen,
input wire arvalid,
output wire arready,
// AXI4读数据通道
output wire [31:0] rdata,
output wire rvalid,
input wire rready
);
// 配置参数
parameter BURST_LENGTH = 4;
// 状态机状态
enum { IDLE, PROCESS_REQUEST, SEND_DATA } state;
// 计数器
reg [31:0] burst_count;
reg [31:0] current_addr;
// 时钟上升沿触发
always @(posedge clk) begin
if (reset) begin
state <= IDLE;
burst_count <= 0;
current_addr <= 0;
end else begin
case (state)
IDLE: begin
if (arvalid) begin
// 接收读请求
arready <= 1;
current_addr <= araddr;
burst_count <= 0;
state <= PROCESS_REQUEST;
end else begin
arready <= 0;
end
end
PROCESS_REQUEST: begin
if (burst_count < BURST_LENGTH) begin
// 准备返回数据
rdata <= current_addr + (burst_count * 4); // 假设数据是地址的简单递增
rvalid <= 1;
burst_count <= burst_count + 1;
state <= SEND_DATA;
end else begin
// 突发传输完成
rvalid <= 0;
state <= IDLE;
end
end
SEND_DATA: begin
if (rready) begin
// 数据被接收,准备下一个数据
rvalid <= 1;
if (burst_count == BURST_LENGTH) begin
rvalid <= 0;
state <= IDLE;
end
end
end
endcase
end
end
endmodule
在这个简化的Verilog模块中,我们定义了一个状态机来管理读请求的处理和数据的返回。从设备在IDLE状态下等待读请求,一旦接收到有效的读请求,就进入PROCESS_REQUEST状态,并准备返回数据。在PROCESS_REQUEST状态下,从设备根据请求的地址和突发长度生成数据,并在SEND_DATA状态下返回数据。一旦主设备确认接收数据,从设备准备返回下一个数据,直到突发传输完成。
在AXI4总线协议中,从设备(Slave)的逻辑负责处理来自主设备(Master)的读写请求,并返回相应的数据或确认。以下是一个简化的Verilog代码示例,用于模拟AXI4从设备的基本逻辑。这个示例将处理读请求,并返回数据。请注意,这个示例是为了说明目的而简化的,实际的AXI4从设备实现会更加复杂,并且需要处理更多的信号和协议细节。
module axi4_slave_sim(
input wire clk,
input wire reset,
// AXI4读地址通道
input wire [31:0] araddr,
input wire [3:0] arlen,
input wire arvalid,
output wire arready,
// AXI4读数据通道
output wire [31:0] rdata,
output wire rvalid,
input wire rready
);
// 配置参数
parameter BURST_LENGTH = 4;
// 状态机状态
enum { IDLE, PROCESS_REQUEST, SEND_DATA } state;
// 计数器
reg [31:0] burst_count;
reg [31:0] current_addr;
// 时钟上升沿触发
always @(posedge clk) begin
if (reset) begin
state <= IDLE;
burst_count <= 0;
current_addr <= 0;
end else begin
case (state)
IDLE: begin
if (arvalid) begin
// 接收读请求
arready <= 1;
current_addr <= araddr;
burst_count <= 0;
state <= PROCESS_REQUEST;
end else begin
arready <= 0;
end
end
PROCESS_REQUEST: begin
if (burst_count < BURST_LENGTH) begin
// 准备返回数据
rdata <= current_addr + (burst_count * 4); // 假设数据是地址的简单递增
rvalid <= 1;
burst_count <= burst_count + 1;
state <= SEND_DATA;
end else begin
// 突发传输完成
rvalid <= 0;
state <= IDLE;
end
end
SEND_DATA: begin
if (rready) begin
// 数据被接收,准备下一个数据
rvalid <= 1;
if (burst_count == BURST_LENGTH) begin
rvalid <= 0;
state <= IDLE;
end
end
end
endcase
end
end
endmodule
在这个简化的Verilog模块中,我们定义了一个状态机来管理读请求的处理和数据的返回。从设备在IDLE状态下等待读请求,一旦接收到有效的读请求,就进入PROCESS_REQUEST状态,并准备返回数据。在PROCESS_REQUEST状态下,从设备根据请求的地址和突发长度生成数据,并在SEND_DATA状态下返回数据。一旦主设备确认接收数据,从设备准备返回下一个数据,直到突发传输完成。
以下是一个简化的Verilog测试平台示例,用于模拟AXI4主设备发起Outstanding Transfer并测试从设备模块的响应。
module axi4_slave_tb;
// 时钟和复位信号
reg clk = 0;
reg reset = 1;
// 生成时钟信号
always #5 clk = ~clk;
// 模拟复位
initial begin
#10 reset = 0;
end
// AXI4从设备接口
wire [31:0] araddr;
wire [3:0] arlen;
wire arvalid;
wire arready;
wire [31:0] rdata;
wire rvalid;
wire rready;
// 实例化从设备模块
axi4_slave_sim u_axi4_slave_sim(
.clk(clk),
.reset(reset),
.araddr(araddr),
.arlen(arlen),
.arvalid(arvalid),
.arready(arready),
.rdata(rdata),
.rvalid(rvalid),
.rready(rready)
);
// 测试平台逻辑
initial begin
// 等待复位释放
@(negedge reset);
// 发起Outstanding Transfer
for (integer i = 0; i < 3; i++) begin // 假设最多3个outstanding请求
@(posedge clk);
arvalid = 1;
araddr = 32'h1000 + (i * 32'h10); // 每个请求的地址递增
arlen = 4'd3; // 突发长度为4
// 等待从设备准备好
@(posedge arready);
arvalid = 0;
end
// 接收数据
for (integer i = 0; i < 3; i++) begin // 处理3个outstanding请求的数据
for (integer j = 0; j < 4; j++) begin // 每个请求有4个数据项
@(posedge clk);
rready = 1;
// 检查数据是否正确
if (rvalid) begin
$display("Received data for request %0d, item %0d: %h", i, j, rdata);
// 假设数据是地址的简单递增
if (rdata != (32'h1000 + (i * 32'h10) + (j * 4))) begin
$error("Data mismatch for request %0d, item %0d", i, j);
end
end
end
end
// 结束测试
$finish;
end
endmodule
在这个测试平台中,我们首先定义了时钟和复位信号,并生成了一个周期为10个时间单位的时钟信号。复位信号在10个时间单位后被释放。
我们实例化了之前定义的AXI4从设备模块,并连接了相应的信号。
在测试平台的初始块中,我们等待复位信号释放,然后发起3个读请求,每个请求都有4个数据项的突发长度。我们为每个请求设置了不同的起始地址,以模拟Outstanding Transfer。
接下来,我们进入两个嵌套的循环,外层循环处理每个outstanding请求,内层循环处理每个请求中的数据项。我们检查rvalid信号,并在数据有效时接收数据。我们假设数据是地址的简单递增,并检查接收到的数据是否符合预期。
最后,我们在接收完所有预期的数据后结束测试。
请注意,这个测试平台是一个非常基础的示例,没有包含完整的AXI4协议细节,也没有处理错误情况和异常处理。在实际的测试平台中,需要考虑更多的测试用例和协议细节,以确保从设备模块的正确性和健壮性。
更多推荐

所有评论(0)