深入SRIO协议栈:手把手解析NWRITE/SWRITE包格式与AXI4总线转换的Verilog实现
深入SRIO协议栈:手把手解析NWRITE/SWRITE包格式与AXI4总线转换的Verilog实现
在异构计算架构中,SRIO(Serial RapidIO)作为高性能互连技术,其低延迟、高带宽特性使其成为DSP与FPGA协同处理的理想选择。本文将聚焦协议栈最核心的数据包转换场景,通过Verilog实现演示如何构建高效的硬件数据通路。不同于常规的概念性介绍,我们将直接切入RTL设计细节,为FPGA工程师提供可直接复用的设计模式。
1. SRIO协议包深度解析
1.1 NWRITE包结构拆解
标准NWRITE事务包包含14字节固定包头和可变长度有效载荷。关键字段分布如下(以大端序表示):
// 包头字段位域定义(单位:字节) typedef struct packed { logic [7:0] ft; // 0x20 for NWRITE logic [7:0] tt; // 传输类型 logic [15:0] tid; // 事务ID logic [63:0] dest_addr; // 目标地址 logic [15:0] data_len; // 数据长度(单位:字节) logic [7:0] wdptr; // 写指针控制 logic [7:0] xamsbs; // 地址扩展位 } nwrite_header_t;提取目的地址和数据长度的Verilog代码示例:
always_comb begin dest_addr = {header.xamsbs[3:0], header.dest_addr}; payload_size = header.data_len; end1.2 SWRITE包的特殊处理
相比NWRITE,SWRITE包省略了目标地址字段(复用前次配置),其包头仅8字节:
| 字段偏移 | 位宽 | 描述 |
|---|---|---|
| 0x0 | 8 | 包类型(0x34 for SWRITE) |
| 0x1 | 8 | 传输类型与优先级 |
| 0x2 | 16 | 事务ID |
| 0x4 | 16 | 数据长度 |
注意:SWRITE要求目标设备预先配置地址寄存器,实际工程中需维护地址上下文状态机
2. AXI4总线转换架构设计
2.1 核心状态机设计
转换控制器需要处理三种主要状态:
- 包头解析状态:检测输入流起始边界,提取关键参数
- AXI突发计算状态:根据4KB边界限制拆分传输请求
- 数据搬运状态:协调AXI通道信号时序
状态转换示意图:
enum logic [1:0] { IDLE, HEADER, BURST_CALC, DATA_XFER } state, next_state; always_ff @(posedge clk) begin if (reset) state <= IDLE; else state <= next_state; end2.2 突发传输拆分算法
当遇到跨4KB边界的传输请求时,需自动拆分为多个AXI突发:
// 突发拆分计算示例 function automatic burst_split_t calc_bursts( input logic [63:0] addr, input logic [31:0] len ); burst_split_t result; logic [63:0] boundary = (addr + 4096) & ~(4096-1); logic [31:0] remain_len = boundary - addr; if (len <= remain_len) begin result.burst_num = 1; result.burst_len[0] = len; end else begin result.burst_num = 2; result.burst_len[0] = remain_len; result.burst_len[1] = len - remain_len; end return result; endfunction3. 字节序转换硬件实现
3.1 大端转小端处理
SRIO采用大端序而AXI通常使用小端序,需在数据路径插入转换模块:
generate for (genvar i = 0; i < DATA_WIDTH/64; i++) begin assign out_data[i*64 +: 8] = in_data[i*64 + 56 +: 8]; assign out_data[i*64+8 +: 8] = in_data[i*64 + 48 +: 8]; // ... 继续处理剩余6个字节 end endgenerate3.2 流水线优化技巧
为保持时序性能,建议采用三级流水线结构:
- 字节重排阶段:完成64位数据内部的字节交换
- 字序调整阶段:处理128/256位宽数据的字间交换
- 缓冲输出阶段:匹配AXI总线时钟域
4. 门铃事务的硬件处理
4.1 中断脉冲生成电路
门铃中断需要满足最小脉冲宽度要求:
// 脉冲宽度扩展电路 reg [1:0] db_irq_shift; always_ff @(posedge clk) begin db_irq_shift <= {db_irq_shift[0], doorbell_valid}; db_irq <= |db_irq_shift; end4.2 优先级响应机制
响应包的prio字段生成逻辑:
assign resp_prio = recv_prio + 1'b1;寄存器组配置建议:
| 寄存器名 | 偏移地址 | 功能描述 |
|---|---|---|
| DB_CTRL | 0x00 | 门铃中断使能/状态 |
| DB_INFO | 0x04 | 最新门铃信息 |
| DB_RESP_TIMER | 0x08 | 响应超时设置 |
实际工程中,当处理156.25MHz时钟域的门铃事务时,建议采用双缓冲技术避免跨时钟域问题。在Xilinx器件中,可实例化xpm_cdc_handshake宏实现安全的数据传递。
