当前位置: 首页 > news >正文

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

相关文章:

  • 什么是进程线程
  • ubuntu 和 RV1126 交叉编译Mosqutiio-1.6.9
  • linux批量使用多个用户名登录脚本、为了给主机增加一个指定用户名的登录记录、无需root密码的主机切换到root方式
  • 【玩转全栈】---- Pinia 组件状态管理器
  • 卷积神经网络与计算机视觉:从数学基础到实战应用
  • 沉浸式CSS学习路径
  • 【贪心算法3】
  • git设置本地仓库和远程仓库
  • 解决 word 2016 粘贴图片老是乱飘的问题
  • 十分钟用DeepSeek v3快速搭建企业级本地私有知识库(保姆级教程),AI终于私有化了!
  • Java糊涂包(Hutool)的安装教程并进行网络爬虫
  • 训练大模型LLM选择哪种开发语言最好
  • 2.3 DeepSeek SDK接入与鉴权体系设计
  • RabbitMQ (Java)学习笔记
  • electron+vue+webview内嵌网页并注入js
  • Android Glide 框架线程管理模块原理的源码级别深入分析
  • 第七次CCF-CSP认证(含C++源码)
  • 微前端最佳实践:Module Federation 的使用步骤详解
  • OmniParser技术分析(一)
  • c++ constraints与concepts使用笔记
  • 媒体:机票盲盒值不值得开?年轻人正用行为博弈的逻辑重构规则
  • 乘客被困停滞车厢超4小时,哈尔滨铁路局客服:列车晚点,表示歉意
  • 中国固体火箭发动机领域杰出专家赵殿礼逝世,享年92岁
  • “非思”的思想——探索失语者的思想史
  • 山西太原一居民小区发生爆炸,应急管理部派工作组赴现场
  • 哈莉·贝瑞、洪常秀等出任戛纳主竞赛单元评委