薛 培,官 剑,邵春伟,张鑫刚,郑思旭
(1.无锡华普微电子有限公司,江苏 无锡 214000;2.中国电子科技集团公司第五十八研究所,江苏 无锡 214000)
随着嵌入式系统性能的快速提升,板间互连、板内芯片互连对数据带宽、可靠性、灵活性要求逐步提升,传统的并行传输方式已经很难满足实际的需求。Serial RapidIO(SRIO)高速串行总线协议,成为一种使用范围极广的高速协议[1]。SRIO 是一种基于数据包交换的互联体系结构,在芯片互联、实时视频传输、小型化系统等场合得到了广泛的使用[2]。
在国内外有关SRIO 文献的研究中,研究较多的有SRIO 和FPGA 之间通信[3]、FPGA 实现多协议转换SRIO设计[4],本文即为研究多协议接口和SRIO 之间的转换。
本文以XILINX 公司FPGA 提供的SRIO IP 为基础,设计了多通道发送和接收控制系统的设计方法,其中发送通道采用了一种Round-Robin 数据处理方法,有效控制多通道数据同时发送时可能造成的数据拥塞。基于该设计方法而开发的SRIO 多通道控制系统,经过仿真与调试,已用于某型号项目通信系统,达到了高带宽、低延时的效果,具有很好的通道扩展性。
本系统采用MSG 消息方式,利用MSG 接口中的mail‐box 空间作为通道ID 区分,采用该方法,相较于其他多接口SRIO 设计中采用Nwrite/Nread 的方法。具有以下优点:
(1)无需占用SRIO paylod 区域,提高了单个包的带宽。
(2)最大支持64 个通道的输入输出,具备良好的扩展性。
(3)发送端采用Round-Robin 机制,多协议接口具备优先级控制,相较于其他方法,在不同优先级通道同时发送数据时,可实现通道差异化。
SRIO 采用三层分级体系结构,该结构如图1 所示。
图1 SRIO 三层分级体系
其中逻辑层位于最高层,定义了包的格式,包为端点发起和完成事务提供必要的信息;传输层位于中间层定义了SRIO 地址空间和在端点器件间传输包所需要的路由信息;物理层在整个分级结构的最底部,主要规定了物理层方式[5]。
SRIO 数据包由包头、有效的数据载荷和16 位CRC校验组成[6]。包头的长度最大的有效载荷长度为256 B。由于包长度短,因此传输延时较小,硬件上也易于实现,适合数字信号处理场合对传输延时要求较高的应用[7]。XILINX 的部分FPGA 中[4]已经集成了GTP、GTX或GTH 等高速串行收发电路,这些是FPGA 实现SRIO高速传输的物理层基础。
在XILINX 的开发环境下,可直接调用Serial Rapi‐dIO gen2 IP 来实现SRIO 的LOG、BUF 及PHY 三层结构[8]。在本文所述的系统中,IP 设置为Condensed I/O 模式,Messaging 接口设置为Separate Messaging Port。
完成如上的设置,生成IP 后,开放的主要接口为四组:MSGIREQ、MSGIRESP、MSGTREQ、MSGTRESP,这些接口间的信号流向和功能分别如图2 和表1 所示。
表1 SRIO 接口功能表
本系统的包头使用HELLO 包[9]中的MSG 和RESP包。包头格式见图3。
图3 HELLO 帧头格式
在该系统中,为了适应任意数量的发送通道和接收通道,需要将通道ID 加入到SRIO 包中。本系统采用了MSG 包的mailbox 参数和RESP 包中特有的TargetTID 参数来表示当前发送通道和接收通道的通道数信息。
SRIO IP 开放的接口均为AXI4-stream 接口[10]。其中MSGIREQ 和MSGIRESP 为发送控制处理逻辑模块所连接的接口,本地SRIO 节点所有发送通道的数据均需要转换为这两组接口的HELLO 包。MSGTREQ 和MSGTRESP 接口为从对端SRIO 接收到的接口,经过接收控制处理逻辑模块对HELLO 包进行处理,转化为接收通道输出的数据。
系统整体框架如图4 所示。
图4 系统整体框架
在发送控制处理逻辑,根据待发送的发送通道数信息(假设为M通道),将M填充到MSGIREQ 包的mailbox参数中,实现本地SRIO 的数据发送;发送完成后,发送通道(M)进入到等待ACK 的状态。发送控制处理逻辑仍然可继续其他发送通道的数据发送。
当MSGIRESP 收到RESP 包(TargetTID 信息等于M)时,发送通道M从等待ACK 状态进入到收到ACK 状态。此时发送通道M认为对端SRIO 已正确接收上一次的发送数据。
在接收控制处理逻辑中,其起始状态为接收到MSGTREQ 接口的MSG 包头。根据mailbox 参数(假设为N,最大可支持到64),则该MSG 包的接收通道为N,同时提取payload 数据转换为接收通道N的输出时序,完成后,向MSGTRESP 接口发送RESP 包,其TargetTID参数填充为N,实现对端SRIO 包的响应反馈。
基于以上架构,可实现多路不同时域、不同速度的数据在SRIO 链路之间的传输。
本系统采用一种通用的发送通道和接收通道时序,如图5 所示。
图5 通道接口时序
接口由6 个信号组成,分别是时钟CLK、复位RST_N、数据有效标志ENABLE、地址ADDR、数据DATA、准备标志READY,数据位宽为16 bit。
所有的信号均为CLK 时钟下的同步信号,RST_N 低电平复位,ENABLE、ADDR、DATA 必须在READY 为高时有效;ENABLE 为高时,地址ADDR=0 时 的DATA 值为CTRL 值,CTRL 值内含一次SRIO 包的数据长度等信息,其中最高bit 为1 时意味着SRIO 传输包有效,低位bit 代表着包的包长;ADDR=1 到ADDR=N 范围内的DATA 值为一次SRIO 传输包的有效数据。由于一个SRIO 包最大支持256 B,则该地址位N最大为128。
当有多个不同时钟域、不同收发速度的数据接口接入到SRIO 系统时,均可通过极简单的控制逻辑转换为该接口的时序,实现SRIO 的快速应用。
发送控制模块主要由双口RAM、Round-Robin 模块和发送控制状态机三部分组成。发送接口数据首先按接口时序中的地址信号存入到发送双口RAM 模块,等待后续模块读取。Round-Robin 模块用于实现所有通道发送的优先级顺序处理;发送控制模块则完成发送双口RAM 通道和SRIO IP 接口(MSGIREQ 和MSGIRESP)的转换。发送模块整体框架如图6 所示。
图6 发送模块整体框架
2.2.1 发送双口RAM
发送双口RAM 模块核心为简单双口RAM,其中A口为16 bit 数据;B 口为64 bit 数据。
写入部分将多通道接口时序发送部分的数据写入到双口RAM 的A 口中,当I_srio_tx_enable 为高时I_srio_tx_addr[15:0]/I_srio_tx_datain[15:0]信号分别写入双口RAM 的地址和数据部分。其中地址0 存入的数据,最高位为状态位,低位为word 个数。
读出部分为发送控制状态机控制。
2.2.2 Round-Robin 优先级控制模块
Round-Robin(轮询调度算法)优先级控制模块根据不同输入通道的优先级顺序,实现不同重要性通道的数据发送SRIO 包的先后顺序处理。
Round-Robin 的原理是每一次将来自输入接口的请求轮流分配给内部中的发送处理逻辑,从优先级1(优先级最高)开始,直到优先级N(优先级最低),然后重新开始循环,来实现各个任务的顺序执行。同时,每个输入接口有一个Aging(变化值),保证了等待过久的任务也依然能被执行到。
每个通道都被分配了一个优先级号码,作为Aging CountDown(递减计数)的起始值。也就是说,优先级越高的进程,会更早地CountDown to 0,即最高优先级,从而更早地被执行。
本模块所用的状态机如图7 所示。
图7 Round-Robin 状态机图
每个通道均具有一个优先级,举例通道1 为X1 优先级;通道2 为X2 优先级…通道N为Xn优先级。
在完成SRIO 链路初始化后(port_initialized 和link_initialized 均为1),首先进入查询空闲的状态,接着进入到读取通道X 的模式。其中查询空闲和读取通道X 两个状态互相循环,即完成读取完某一个通道的数据后,先返回到查询空闲状态,再进入读取通道X 状态。
首先读取最高优先级Xmax 的通道MAX,同时Ag‐ing 计数Aging(max)-1,查询状态(通过读取地址I_srio_tx_addr 为0 时的I_srio_tx_datain 最高位)是否为1,如果为1,则开始通道MAX 的数据读取,如果等于0,则进入查询其他通道X 的状态。读取完通道MAX 的数据后,进入到查询空闲状态。
依此方式循环,即可以兼顾优先级的次序,又可以实现低优先级长时间轮询失败的问题。
2.2.3 发送控制状态机
发送控制状态机实现从优先级控制模块输出的对应RAM 读出数据,转换为MSGIREQ 和MSGIRESP 两个接口时序的模块。状态机如图8 所示。
图8 发送控制状态机图
如图8 所示:上电后C_idle 状态下,在完成SRIO 链路初始化后(port_initialized 和link_initialized 均为1),发送状态机进入到C_tx_idle 状态。
C_tx_idle 状态下,直接进入C_tx_read_ram0 状态。
C_tx_read_ram0 状态下,读通道0 的发送双口RAM-0 中地址0 的数据。如果地址0 数据的最高位为1,代表该通道有待发送的数据,则进入C_tx_send_
start0 状态下,如果最高位为0,则进入到C_tx_read_ramn 状态。
C_tx_send_start0 状态下,进入C_tx_send_header状态。
C_tx_read_ramn 状态下,按Round-Robin 模块输出的读通道顺序读取该通道的RAM 地址0 中的数据。如果数据的最高位为1,代表该通道有待发送的数据,则进入C_tx_send_header 状态;如果最高位为0,则重新到C_tx_read_ram0 状态,回到读RAM-0 状态。
C_tx_send_header 状态下,判断MSGIREQ 接口的msgireq_tready 值,如果等于1,即可认为MSGIREQ 接口可以发数据,此时进入到C_tx_send_ready 状态。
C_tx_send_ready 状态,输出msgireq_tvalid 和ms‐gireq_tdata[63:0]=MSG 包头的数据。接着进入到C_tx_send_data0_idle 状态。
C_tx_send_data0_idle 状态下,需要判断待发送的数据包长度是否为8 字节,如果小于或等于8 字节,直接进入到C_tx_send_last 状态;如果大于8 字节,则进入到C_tx_send_data 状态。
C_tx_send_data 状态下,输出msgireq_tvalid=1 和ms‐gireq_tdata[63:0]=payload 数据给到MSGIREQ 接口。
C_tx_send_last 状态下,输出msgireq_tvalid=1、ms‐gireq_tvalid=1、msgireq_tdata[63: 0]=payload 数据到MSGIREQ 接口。此状态下,即完成一整个SRIO 包的通道数据发送。完成后进入到C_tx_send_end 状态。
C_tx_send_end 状态下,重新回到C_tx_idle 状态。同时相应通道的接收响应状态机会启动,等待对端SRIO 的响应包,使用此方式,不影响通道数据的继续发送。
如当前发送的为第Y 个通道,则通道Y 的接收响应状态机会进入到C_tx_receive_header 状态,此刻此通道需要等待MSGIRESP 回应对应通道的响应包,如果接收到 MSGIRESP 接口的 msgiresp_tvalid=1,同时 ms‐giresp_tdata[63:54]值即TargetTID 值等于Y,即接收到Y通道发送数据的响应。此时完成Y 通道的所有发送流程。
基于以上方式,可实现N个通道接口的数据流水式发送,在完成一个通道的发送后,可以继续其他通道的数据发送。同时能收到RESP 包,确保每个发送通道发送数据的可靠性。
接收控制模块主要由接收双口RAM 和接收控制状态机两部分组成。通过SRIO 接口MSGTREQ 和MSGTRESP 的数据,首先进入到接收控制状态机,经过对MSG 包的解析,分析确定mailbox 位通道数,写入到对应的接收双口 RAM。最后发出 RESP 包到MSGTRESP 接口。完成该操作后,即可完成SRIO 多通道数据的接收。接收模块整体框架如图9 所示。
图9 接收模块整体框架
2.3.1 接收控制状态机
接收控制状态机实现SRIO IP 的MSGTREQ 和MSGTRESP 两个接口处理的逻辑。该模块接收MSGTREQ 接口的数据,解析MSG 包中帧头部分的mailbox 值,确定接收到的SRIO 包对应的接收通道,同时完成该SRIO 包的payload 部分接收并写入到后续的接收双口RAM 模块,完成该操作后,再发送RESP 包给MSGTRESP 接口。整个接收控制状态机流程如图10所示。
图10 接收控制状态机
如图10 所示,上电后接收状态机进入到C_idle 状态。完成SRIO 链路初始化后,发送状态机进入到C_rx_idle 状态。
C_rx_idle 状态下,判断是否接收msgtreq_tvalid=1,如果接收到,直接进入C_rx_treq_header 状态。
C_rx_treq_header 状态下,如果接收到msgtreq_tvalid=1,则认为接收到MSG 包的帧头,此时进入到C_rx_treq_data 状态;如果接收到msgtreq_tlast=1,则认为接收到MSG 的最后一个64 bit payload 数据,此时进入到C_rx_treq_data 状态;如果未接收到以上两种状态,则进入到C_rx_treq_idle 状态。
C_rx_treq_data 状态下,如果接收到msgtreq_tlast=1,则接收到MSG 的最后一个64 bit payload 数据,此时进入到C_rx_treq_last 状态;如果未接收到,则进入到C_rx_treq_idle 状态。
C_rx_treq_idle 状态下,如果接收到msgtreq_tvalid=1,则认为接收到MSG 包的payload 数据,此时进入到C_rx_treq_data 状态;如果接收到msgtreq_tlast=1,则认为接收到MSG 的最后一个64 bit payload 数据,此时进入到C_rx_treq_last 状态;如果未接收到以上两种状态,则继续保持本状态。
C_rx_treq_last 状态下,则认为完成一个SRIO 的接收处理,SRIO payload 中的数据需要存入到接收RAM模块中。状态进入到C_rx_treq_end 状态。
C_rx_treq_end 状态下,进入C_rx_resp_valid 状态,后续为MSGTRESP 接口的处理。
C_rx_resp_valid 状态下,判断msgtresp_tready,如果为1,则进入到C_rx_resp_ready 状态;如果为0,则继续保持本状态。
C_rx_resp_ready 状态完成响应包RESP 的发送。
2.3.2 接收控制状态机
在C_rx_treq_header 状态时,从接收到的SRIO 包头TargetTID 位,确定收到的包的SRIO 通道。同时根据C_rx_treq_data 和 C_rx_treq_last 状态下收到的msg_treq_data,解析出payload 部分,写入到双口RAM 的A 口。
B 口实时监测地址0 的标志位,当标志位=1 时,读取存入到B 口的数据,并转换为通道通用时序。
如图11 所示,为SRIO 3 通道系统的发送时序仿真。
图11 发送接口时序仿真图
该仿真设置的优先级顺序为:通道2>通道1>通道3。
在I_sys_clk 时钟下I_srio_tx_enable[0]/I_srio_tx_addr[15:0]/ I_srio_tx_datain[15:0]为第一通道,前4 个时钟下,分别向地址1、2、3、4 写入了16′h1234、16′h5678、16′h9ABC、16′hDEF0 数据;第5 个时钟下,向地址0 写入了控制数据16′h8004,最高bit 位为1 代表着标志位,4 代表着存有4 个word。
I_srio_tx_enable[1]/ I_srio_tx_addr[31:16]/I_srio_tx_datain[31:16]为第二通道,前4 个时钟下,分别向地址1、2、3、4 写入了 16′h2345、16′h6789、16′hABCD、16′hEF10 数据;第5 个时钟下,向地址0 写入了控制数据16′h8004,最高bit 位为1 代表着标志位,4 代表着存有4 个word。
发送通道转换为MSGIREQ 接口的仿真时序如图12所示。从图中可以看出,帧头数据为64′h00B020700000 0012,发送的数据为64′hEF10ABCD67892345。mailbox位为1,代表着通道2。可以看出通道2 最先发出,实现了优先级的发送顺序控制。
图12 MSGIREQ 仿真图
发送通道接收到对端SRIO 的响应包的时序如图13所示。
图13 MSGIRESP 接口仿真图
在图13 中,212 600 ns 时刻左右,MSGIRESP 接口接收到RESP 包,其包头为64′h01D1400000000000。RESP包的TargetTID=1,即为MSG 通道2 的响应包。与发送通道MSGIREQ 接口比较,其延时为212600-208475=4 125 ns,即4.125 μs(SRIO 线速率为2.5 Gb/s)。
接收通道接收到数据的时序仿真如图14 所示。
图14 MSGTREQ 和MSGTRESP 接口仿真
从图14 中可见,接收通道的MSGTREQ 接收到64’h00B0207000000002,从包头可以分析MSG 包为通道1。接收通道输出接口同样为通道1 有效(O_srio_rx_enable[0]=1),接收时序与设计一致。
本文设计了一种SRIO 应用于多通道发送和接收的控制系统,可降低SRIO IP 使用的复杂度,同时兼容最大64 个发送接收通道的直接扩展。通过代码实现与仿真,同一通道发包到确认收包,实际延时可到4 μs 左右(2.5 Gb/s 线速率),具有较好的可靠性。
该系统已经应用到某型号项目通信系统,可大幅节约通讯线缆。系统运行稳定可靠,同时对用户来说,接口使用方便,可极大地加速了SRIO 的应用开发。后续可以通过改进优化,移植到Nwrite/Swrite/Nread 包[11]方式,实现更多的SRIO 通信应用。