详解赛灵思SRIO IP并提供一种FIFO封装SRIO的收发控制器仿真验证

概述

RapidIO标准定义为三层:逻辑层、传输层、物理层。

  • 逻辑层:定义总体协议和包格式,包含设备发起/完成事务的必要信息。

  • 传输层:提供包传输的路由信息(对顶层不可见)。

  • 物理层:描述设备级接口细节(包传输机制、流控、电气特性、低级错误管理)。


逻辑层(LOG)

逻辑层划分为模块控制并解析数据包,包含三种接口:

  1. 用户接口(User Interface)

    • 可配置端口数量和事务类型。

    • 支持通过AXI4-Lite总线访问本地/远程寄存器。

  2. 传输接口(Transport Interface)

    • 相当于缓存Buffer(对顶层不可见)。
  3. 配置接口(Configuration Fabric Interface)

    • 读写本地配置空间及逻辑层/传输层寄存器。

用户接口详解

  • I/O端口集

    1. 支持I/O事务(NWRITEs、NWRITE_Rs、SWRITEs、NREADs、RESPONSEs)。

    2. 可选支持消息事务(取决于IP核配置)。

    3. 支持门铃事务。

  • 消息端口:专用于消息事务。

  • 维护端口:专用于维护事务。

  • 用户自定义端口:支持自定义事务类型(未使能时丢弃包)。

I/O端口类型
  1. Condensed I/O

    • 单AXI4-Stream通道发送/接收所有包类型。
  2. Initiator/Target

    • 分离请求与响应事务,共4个AXI4-Stream通道。
数据流协议
  • 支持HELLO格式与SRIO Stream格式。

  • 通道映射关系:

    • s_axis_ireq* → ireq(本地请求)

    • m_axis_iresp* → iresp(远程响应)

    • m_axis_treq* → treq(远程请求)

    • s_axis_tresp* → tresp(本地响应)


物理层(PHY)

  • 功能:处理链路训练、初始化、协议、CRC校验、应答标识符插入。

  • 接口:

    • 通过AXI4-Stream通道连接传输层。

    • AXI4-Lite接口连接配置层。

    • 串行接口连接高速收发器(通常使用FPGA集成的GT接口)。

寄存器空间

  • 能力寄存器空间(CAR)

  • 命令和状态寄存器空间(CSR)

均在逻辑层实现。

HELLO包格式

  • 标准化包头域,包头与数据分离传输。

  • Size域规则

    • 值 = 传输字节总数 - 1(有效范围0~255,对应实际1~256字节)。

    • 需与RapidIO包的size/address/wdptr域一致。

    • 因AXI4-Stream的tdata为8字节,需分情况处理:

      • 数据量 < 8字节

      • 数据量 > 8字节


SRIO事务类型及关系梳理

1. 直接I/O(DMA)事务

事务类型 特性 应用场景
NWRITE 写操作,无需响应 高效无确认数据传输
NWRITE_R 写操作,需响应 需数据完整性的场景
SWRITE 流式写(数据长度需为8B整数倍) 连续数据流(如视频)
NREAD 读操作,返回响应包+数据 读取目标地址数据

2. 消息传递事务

事务类型 特性 应用场景
DOORBELL 短消息通知(如中断触发) 轻量级事件通知
MESSAGE 长消息传输(邮箱路由) 动态通信/软件管理交互

3. 维护事务

  • MAINTENANCE READ/WRITE:读写配置寄存器(初始化/错误处理)。

事务对比

特性 直接I/O事务 消息传递事务
效率 高(硬件控制) 低(软件介入)
可靠性 NWRITE无确认 依赖软件处理
延迟 较高
典型场景 DSP与FPGA间实时通信 多处理器系统通知

事务类型对应表如下,更具体地可以见PG007开发手册P73页。


SRIO事务时序仿真

仿真步骤(Vivado 2020.1)

  1. 创建工程及SRIO IP核。

  2. 右键IP核 → "Open IP Example Design"。

  3. 运行仿真,添加request/response模块观察信号。

  1. 运行约1000us捕获事务动作。

关键事务时序

  1. MAINTENANCE READ REQUEST
    • 接收请求,无响应(val_tresp_tvalid=0)。
  1. SWRITE请求(发送)

    • val_ireq_tvalid拉高,ftype=6, ttype=0

  2. SWRITE请求(接收)

    • response模块验证事务类型。

      ftype(6)和ttype(0)

  3. NWRITE_R请求(发送)

    • 请求包发送。

  4. NWRITE_R请求(接收+响应)

    • 接收请求后发送响应包,和发送的请求包一致,该事务会产生响应,在一段时间后可以看到val_tresp_tvalid拉高一个周期,发送响应包val_tresp_tdata = 64'h25d0_4000_0000_0000。

  5. NREAD请求(发送)

    • 仅包头无数据。

  6. NREAD请求(接收)

    • 接收模块返回响应包+数据。
  1. NREAD响应(发送)
    • size=8'h3f → 发送64字节数据(8个周期)。
  1. NREAD响应(接收)
    • 接收包头(val_iresp_tdata=64'h4bd8400000000000)及数据。 跟在包头后面的是数据0。

自定义事务传输仿真

计划仿真NWRITE和SWRITE两种事务类型,通过FIFO实现用户层时钟到IP核跨时钟传输以及数据缓存的功能,方便用户直接使用。

移植srio_example工程

  1. 配置参数

    复制代码
    parameter SIM_VERBOSE            = 1,  // 仿真详细日志
    parameter VALIDATION_FEATURES    = 0,  // 关闭验证功能
    parameter QUICK_STARTUP          = 1,  // 启用快速启动
    parameter STATISTICS_GATHERING   = 0,  // 关闭统计功能
    parameter C_LINK_WIDTH           = 4   // 4x通道
  2. 将示例工程文件夹import拷贝到自己工程中

  1. 添加文件

    除了仿真文件其余都加进去。

添加好的工程目录如下:

搭建好总的框架,并对SRIO官方案例工程进行一些修改

  1. 创建收发模块
  • 首先创建好两个模块,分别是Message_TX数据发送模块和Message_RX数据接收模块。
  1. 创建顶层模块
  • 创建一个顶层模块srio_demo。

  1. 对srio_example模块进行修改
  • 要提前对srio_example模块进行一些处理,添加一些信号给数据收发模块用。(下面图片中左边时示例程序,右边是对其修改后的程序)

  • 首先把一些不必要的报告和一些附加功能屏蔽掉

  • 然后把port_initialized和link_initialized两个信号引出来
  • 然后把log_clk用户时钟引出来给外部使用
  • 然后把ireq和treq相关AXI总线信号引出来
  • 最后就是把IP核的其他输入信号赋上一些初始值,主要是iresp和tresp,保证IP核正常运行。
  • 最终修改好之后整体框架如下图:

加上FIFO IP核,并配置好相应参数,编写好发送模块

  • 这里描述简单些,例化好FIFO IP,并给FIFO相关信号赋值
  • 最后编写发送模块的剩余代码,发送模块状态转换图如下图所示

加上FIFO IP核,并配置好相应参数,编写好接收模块

  • 这里描述简单些,接收模块的状态转换图如下图所示

编写仿真程序,仿真调试

  • 首先创建仿真文件
  • 把顶层文件的端口添加到仿真文件中
  • 例化两个端,分别是PORTA端和PORTB端,两个端TX和RX引脚反接,并设置A端作为发送端,B端设为接收端
  • 产生时钟和复位信号
  • 添加上一些监测信号

  • 编译完成后,点击仿真,添加PORTA的tx模块和PORTB的rx模块进波形窗口

  • 继续运行仿真,看一下是否link上。在58us左右的时候,port_initialized拉高
  • 在77us左右link_initialized拉高,表示建链成功。一般port_initialized&link_initialized作为初始化完成的标志。
  • 在94us左右treq_tdata不会有动作,跟之前示例工程有区别,这是没有传数过去,是正常的。
  • 编写传输数据流程:
  • 点击开始仿真,100us时tx_vld正常拉高,tx_data数据传输也正常。
  • ireq信号启动发送流程,时间大概再100.6us左右,这里帧头是0x006020fcd0000600,事务类型是SWRITE。
  • PORTB的接收模块的treq信号在101.6us左右有动作。
  • 接收模块输出的结果如下图所示,即rx_vld信号拉高之后开始数据接收的数据,不包括SRIO帧头。

至此,仿真验证结束,结果符合预期。

本期分享结束,感谢大家看完,私信我可获取相关源码工程

相关推荐
第二层皮-合肥5 小时前
高速采集卡FPGA设计方案及代码
fpga开发
嵌入式-老费8 小时前
再谈fpga开发(fpga调试方法)
fpga开发
XINVRY-FPGA12 小时前
XCZU4EV-1FBVB900E Xilinx FPGA AMD Zynq UltraScale+ MPSoC EV(Embedded Vision)
arm开发·嵌入式硬件·计算机视觉·fpga开发·硬件架构·硬件工程·fpga
从今天开始学习Verilog12 小时前
FFT算法实现之fft IP核
算法·fpga开发
Turing_kun20 小时前
基于FPGA的SPI控制FLASH读写
fpga开发
hahaha60161 天前
差模干扰 & 共模干扰
fpga开发
璞致电子1 天前
【PZ-KU060-KFB】——Kintex UltraScale 纯 FPGA 开发平台,释放高速并行计算潜能,高性价比的 FPGA 解决方案
fpga开发·fpga
我爱C编程1 天前
基于FPGA的16QAM软解调+卷积编码Viterbi译码通信系统,包含帧同步,信道,误码统计,可设置SNR
fpga开发·16qam·软解调·帧同步·卷积编码·viterbi译码
南棱笑笑生1 天前
20250726让荣品的PRO-RK3566开发板使用TF卡启动
fpga开发