JESD204B协议及IP仿真
JESD204B协议及IP仿真
1 摘要
JESD204B协议是一种高速串行接口标准,主要用于数据转换器(如ADC和DAC)与数字信号处理器(DSP)之间的数据传输。该协议支持高达12.5 Gbps的数据速率,适用于需要高带宽和高可靠性的应用场景。该接口的主要优势数据接口路由所需电路板布线空间更少,建立与保持时序要求更低,以及转换器和逻辑器件的封装更小。
2 JESD204B结构及工作模式
2.1 JESD204B协议层
协议层主要包括四层,分别为:物理层、链路层、传输层、应用层。
①物理层:约束接口规范(SEDES CML),串化,线速率等。
②链路层:并行数据组帧(添加控制位 约束位),8B/10B编码,链路建立
③传输层:链路建立后,传输ADC的数据,以半字节为单位。
④应用层:用户解析ADC数据并使用
2.2 JESD204B结构
JESD204B 核心框如图
从图中分析发送端产生的数据经过传输层并转串之后映射再经过数据加扰到达链路层,最后数据通过物理层发送。接收端首先通过物理层接受到数据之后,经过发送端逆向的过程。对得到的每个通道的数据在链路层进行同步、解扰,最后到达传输层进行串转并,最后恢复到原始发送数据的格式。这样接完成了整个JESD 204B的通信流程。
2.3 工作模式
JESD204支持3种子类模式,通过寄存器配置可以控制IP核的子类工作模式。子类1此模式需要SYSREF参考信号。二子类0和子类2则不需要SYSREF信号。
时钟芯片同时给发送端和接收端提供SYSREF和DeviceClock,接收端和发送端通过SYSREF去产生与DeviceClock同步的帧时钟和多帧时钟LMC。在链路建立阶段接收端通过拉低SYNC信号,达到同步多个lane数据。
3 JESD204B链路
3.1 链路建立
链路建立过程同步JESD204B链路,链路建立包括代码组同步(CGS)、初始通道对齐序列(ILAS)、用户数据三个阶段。
1)时钟同步(SYNC)
JESD204B通过时钟芯片同时给发送端和接收端提供主时钟Device Clock和对应的SYSREF信号。Device Clock经过分频后得到帧时钟Frame Clk和多帧时钟LMFC
2)代码组同步(CGS)
在代码组同步(Code Group Synchronization,CGS)期间,各接收器(FPGA)必须利用时钟和数据恢复(CDR)技术,在ADC传来的输入数据流中找到K28.5字符。一旦在所有链路通道上检测到某一数量的连续K28.5字符,接收器模块就会解除置位送至发送器模块的SYNC~ 信号。在发送端捕获到SYNC~ 的变化后,JESD204A和JESD204B的处理会略有不同。在JESD204A中,发送模块捕捉SYNC~ 信号的变化,经过固定数量的帧时钟之后,ILAS就会启动。在JESD204B中,发送模块捕捉SYNC~ 信号的变化,并在下一个本地多帧时(LMFC)
边界上启动ILAS。
具体流程:
1) 接收设备和发送设备同步收到一个SYSREF的脉冲,该脉冲的具体形式可以设置为单脉冲,周期脉冲,以及可控周期脉冲等。
2) 以SYSREF脉冲为基准准,接收设备和发送设备在经过传输延迟后产生本地多帧时钟(LMFC),LMFC即多帧计数器。
3) 在第一个SYSREF脉冲发出后,再经过一定的延迟,SYNC拉高,表示接收端发送一个同步请求给发送端,请求同步。这里的SYNC~表示低有效信号,部分文档中将其写作SYNCb。
4) 发送端检测到SYNC~拉高后,即表示其接收到接收端的同步请求,此时发送端会继续发送连续的K码,直至下一个LMFC的脉冲到来,当然这个过程中接收端必须连续收到4个正确的K码才算是完成码组同步这个过程。
3)初始通道对齐序列(ILAS)
ILAS的主要作用是对齐链路的所有通道,验证链路参数,以及确定帧和多帧边界在接收器的输入数据流中的位置。如下图所示,当码组同步完成后,在下个LMFC边沿处开始发送ILAS序列。ILAS序列由4个或更多多帧组成。第一、第三和第四个多帧以/R/字符开始,以/A/字符结束。第二个多帧包含/R/和/Q/字符,随后是链路参数。/Q/字符表示之后的数据是链路配置参数。如果接收器需要,ILAS可以添加其它多帧。最后一个ILAS多帧的最后一个/A/字符出现后,指示用户数据开始。
1) 当接收设备收到连续四个正确的K码后,在下一个LMFC的脉冲到来时开始发送初始化通道同步序列(Initial Lane Align Sequence,即ILAS),也就是四个多帧。当然期间会以第一个非K码作为多帧的起始点进行检查。
2) 在发送设备端发送ILAS到接收设备的过程中,接收端会使用一个BUFFER(即RBD中的B)来缓冲每一个通道的数据,由于走线的延时不完全一致,因此接收端接收到每个通道的时间点也不一致。当所有的通道都接收到ILAS这个序列后,在下一个LMFC脉冲到来时,释放所有通道的BUFFER缓存的数据。这样就对齐了通道之间不同延迟导致的数据参差,此时初始化通道同步完成,再开始发送数据即可。而由于这一个过程中LMFC的关键标志性作用,整个链路从发送端(并行数据的组帧完成之前)到接收端(接收并得到串行数据再转回并行帧)的整个延迟就是可以复现,可以控制的,即204B中关键技术确定性延迟(DL)。
4)用户数据
在这一阶段,用户数据根据发送器(ADC)中定义并转发到接收器(FPGA)的链路参数,以流形式从发送器传输到接收器。达到用户数据阶段后,如果需要,通过数据链路中的字符替换可以监视并纠正帧和通道对齐。
如图接收端检测到字符/R/之后,所接收到的数据时间是不同的,这是接收端会把/R/后面的数据存入BUFFER中,当接收端下一个LMFC边沿到来,且所有通道的BUFFER中都有数据时,所有通道的BUFFER数据开始输出,从而实现通道间的数据对齐。
3.2 链路示意
整个链路层数据链路建立,实际上链路层除了要理解协议之外,还有理解对齐过程中各信号的时序关系,包括SYNC~ 、 LMFC,SYSREF、‘‘R’’、”A“等指示信号和同步时钟的关系。
4 JESD204B确定性延迟
4.1JESD204B确定性延迟实现
JESD204B标准将确定性延迟定义为基于帧的样本到达串行发射器的时间与基于帧的样本从串行接收器输出的时间之差,核心是无论何时延迟都是恒定的。
子类一实现确定性延时的过程如下图所示,通过三个特征确保发送端的数据到接收端输出数据的延迟是恒定的。
①通过SYSREF同步所有器件的本地多帧Local Multi-Frame Clock (LMFC)时钟,且LMFC边沿与SYSREF之间的延迟是可以设置的。
②其次所有发送设备在LMFC同一边沿发送ILAS序列,保证所有通道同时发送数据。
③所有接收端设备通过ILAS来判断输出数据的开始和结束并和LMFC对齐,通过调整弹性缓冲器(elastic buffer:RBD)来补偿各通道上的延迟,使得接收端(RX)各通道的数据对齐输出。
JESD204B实现确定性延迟的过程就是通道对齐的过程:
1、SYSREF用于同步发送/接收的本地多帧时钟LMFC。
2、发送当SYNC变高后,所有通道在下一个LMFC边沿开始发送ILAS序列,标注数据的开始和结束。
3、接收端的各通道在接收到ILAS系列中的开始字符/R/后,按照RBD开设的缓冲器的大小缓存数据。
4、接收端的所有通道在下一个LMFC的上升沿(RBD=K)开始释放所有的缓冲数据,实现所有通道上的数据对齐。
经过上述过程后,发送端与接收端的数据传输延迟为LMFC周期整数倍加上接收端弹性buffer延时(RBD),其中前者为固定延时,后者为可以设置的可变延时。
4.2JESD204B确定性延迟的关键-设置RBD
接收端将ILAS序列存入弹性buffer中,在LMFC边沿时,如果所有通道的弹性buffer中均有有效数据,则所有通道经过RBD延时后同时从弹性buffer中读出数据给用户。
因此设置RBD的值可以调节弹性buffer数据释放点相对于LMFC上升沿的位置,RBD的取值范围[1,K],其中K表示每个多帧包含的帧数,通常取值为32。
例如RBD=K表示在下一个LMFC的上升沿读出接收端(RX)所有通道弹性buffer的数据。如果RBD=K-5,则表示在下一个LMFC上升沿之前的5个帧周期读出接收端(RX)所有通道弹性buffer的数据。
5 仿真实践
5.1 传输参数
传输层的功能是将A D / D A 的采集到的数据映射到非扰码的八字节的过程。如下图是一个传输层,在使用IP核仿真之前需要理解一些参数的含义。
L :每颗 ADC或者D A C芯片的高速收发器数量。
M:每颗芯片包含ADC或 DAC通道数量。
F:每个高速收发器的每个frame包含几个字节的数据。
S :每个 frame周期内芯片的采样点个数。
C S :每个采样点含有多少 bit控制位。
上图表示该芯片包含8路(M=8)分辨率为11(N = 11)的ADC,8路ADC的数据通过4路(L=4)高速收发器传输,每个采样点包含2 位(CS=2)控制位。ADC每个采样点的数据需要经过两个时钟才能输出,因此在计算高速收发器线速率时,ADC分辨率其实可以等效为16 位。
假设ADC采样率为X,则单个时钟ADC的采样数据为X∗M∗16bit,然后需要经过8B/10B编码,编码后的数据量为( X ∗ M ∗ 16 ) / 0.8 b i t =X∗M∗20bit,最后通过4 路高速收发器输出,每路高速收发器的线速率为X ∗ M ∗ 20 / 4 =X∗M∗5bps。当采样率为100 M H z 时,每路收发器线速率为100M∗8∗5=4000Mbps。具体应用中根据ADC手册进行 LMFS计算和设置。
5.2 工程搭建及IP使用
1)使用官方IP生成例程
2)选择共享逻辑
3)生成工程
5.3仿真测试
TestBench代码
`timescale 1ps / 1ps
module demo_tb ;
localparam pLanes = 2 ;
localparam pSimtimeout_count = 40;
localparam simtimeout = 100000000;
localparam initialresetintxcycles = 200;
localparam txcoreclockphaseperiod_h = 3200; // (in PS) See timescale setting above
localparam txcoreclockphaseperiod_l = 3200; // (in PS) See timescale setting above
localparam txcoreclockperiod = txcoreclockphaseperiod_h + txcoreclockphaseperiod_l;
localparam rxcoreclockphaseperiod_h = 3200; // (in PS) See timescale setting above
localparam rxcoreclockphaseperiod_l = 3200; // (in PS) See timescale setting above
localparam rxcoreclockperiod = rxcoreclockphaseperiod_h+rxcoreclockphaseperiod_l;
localparam txrefclockphaseperiod_h = 3200; // (in PS) See timescale setting above
localparam txrefclockphaseperiod_l = 3200; // (in PS) See timescale setting above
localparam txrefclockperiod = txrefclockphaseperiod_h+txrefclockphaseperiod_l;
localparam rxrefclockphaseperiod_h = 3200; // (in PS) See timescale setting above
localparam rxrefclockphaseperiod_l = 3200; // (in PS) See timescale setting above
localparam rxrefclockperiod = rxrefclockphaseperiod_h+rxrefclockphaseperiod_l;
localparam drpclockphaseperiod = 5000; // (in PS) See timescale setting above
localparam axiclockphaseperiod = 5000; // (in PS) See timescale setting above
localparam pBit_clock_h_phase = 80; //
localparam pBit_clock_l_phase = 80; //
//---------------------------------------------------------------------------
// Testbech signals
//---------------------------------------------------------------------------
reg reset;
reg phyreset;
reg coreClk_tx;
reg coreClk_rx;
reg drpclk_in;
reg refclk_common;
reg testactive; // Used to enable auto check/reporting in some bench blocks
reg mode_is_loopback;
wire [pLanes-1:0] txp;
wire [pLanes-1:0] txn;
wire [pLanes-1:0] rxp;
wire [pLanes-1:0] rxn;
wire [pLanes-1:0] rxp_gen;
wire [pLanes-1:0] rxn_gen;
wire gpio_led_txResetDone;
wire gpio_led_rxResetDone;
wire gpio_led_testPassed;
wire gpio_led_error;
reg enable_tx_bench;
reg enable_rx_bench;
reg rx_sync;
wire tx_check_error;
wire test_passed;
reg [31:0] simtimeout_count;
//---------------------------------------------------------------------------
// Registers to hold local params. (Allows for dynamic phase adjustment)
//---------------------------------------------------------------------------
reg [31:0] coreClockTxInPs_reg_h;
reg [31:0] coreClockTxInPs_reg_l;
reg [31:0] coreClockRxInPs_reg_h;
reg [31:0] coreClockRxInPs_reg_l;
reg [31:0] commonRefClockInPs_reg_h;
reg [31:0] commonRefClockInPs_reg_l;
reg [31:0] drpClockInPs_reg;
//---------------------------------------------------------------------------
// Time variables for simulation event reporting
//---------------------------------------------------------------------------
realtime testStartTime_sim;
realtime rxResetDoneTime_sim;
realtime txResetDoneTime_sim;
//---------------------------------------------------------------------------
// Data transmission time measurement
//---------------------------------------------------------------------------
realtime data_check_all_one_last_time;
realtime data_gen_all_one_last_time;
wire data_gen_all_one;
wire data_check_all_one;
wire [1:0] sel_out;
integer all_one_counter=0;
//---------------------------------------------------------------------------
// Bit clock measurement variables
//---------------------------------------------------------------------------
realtime txBitClkTime_last;
realtime txBitClkTime_work;
realtime txBitClkTime_stored;
reg [31:0] txBitClkTime_cnt;
realtime rxBitClkTime_last;
realtime rxBitClkTime_work;
realtime rxBitClkTime_stored;
reg [31:0] rxBitClkTime_cnt;
//---------------------------------------------------------------------------
// AXI Wire declarations
//---------------------------------------------------------------------------
reg [11:0] s_axi_awaddr;
reg s_axi_awvalid;
wire s_axi_awready;
reg [31:0] s_axi_wdata;
reg s_axi_wvalid;
wire s_axi_wready;
wire [1:0] s_axi_bresp;
wire s_axi_bvalid;
reg s_axi_bready;
reg [11:0] s_axi_araddr;
reg s_axi_arvalid;
wire s_axi_arready;
wire [31:0] s_axi_rdata;
wire [1:0] s_axi_rresp;
wire s_axi_rvalid;
reg s_axi_rready;
//---------------------------------------------------------------------------
// Counter variables
//---------------------------------------------------------------------------
integer cnt_i=0;
integer cnt_x=0;
integer iteration_count=0;
integer error_count=0;
integer data_err_count=0;
//---------------------------------------------------------------------------
// Testbench signals
//---------------------------------------------------------------------------
reg axiclk_in;
reg s_axi_aresetn;
//---------------------------------------------------------------------------
// Registers to hold local params. (Allows for dynamic phase adjustment)
//---------------------------------------------------------------------------
reg [31:0] axiClockInPs_reg;
reg [31:0] test_value