关注、星标公众号,精彩内容每日送达
来源:网络素材
背景与目标:
标准的 SDR 接收方案要求 通道内所有数据线对时钟对齐良好,否则容易导致采样错误。而逐位 deskew 的方案可以在运行时自动调整每一位的采样延迟,从而 对抗 PCB 走线、IO delay、发送端偏差 等带来的时序失配。
基本原理与架构:
双 ISERDES + 双 IODELAYE2:
每个数据引脚使用:
两个
IODELAYE2两个
ISERDESE2
👉 通常使用 LVDS 输入标准(差分输入),FPGA 每对管脚两个 IO,因此可以“白嫖”使用双套 ISERDES。
🕒 延迟设置:
- 主 delay(master)
:设为 eye 中心(例如由训练得出)
- 从 delay(slave)
:比 master 提前或滞后 半个 UI(bit 单位间隔)
👉 这样就得到同一数据位 两个采样点(相差 ½ UI)
Deskew 算法逻辑:
条件 | 判断说明 | 操作 |
|---|---|---|
主/从采样结果 相同(无跳变) | 当前采样点太晚,采到的是数据稳定期 | ⬅️延迟减一tap(更早) |
主/从采样结果 不同(跳变) | 当前采样点太早,采到的是过渡区 | ➡️延迟加一tap(更晚) |
这样系统会自动趋向 eye 中心位置采样,实现 实时逐位自适应采样校准。
数据路径说明:
由于不能实时判断采样点位置,实际对比的是:
两个 ISERDES 输出的 7-bit 并行数据
分析其变化模式来判断当前采样点是否合适
异常处理:
若 delay 环绕(比如 tap 加到最大或最小),可能会出现:
某 bit 重复接收两次
或漏掉一位
➡️ 解决方案:
设计中加入 寄存器 + 多路复用器 + pipeline 处理,避免数据损坏
注意事项与建议:
本方案对 每一位单独 deskew,有效消除 PCB 布线不等长、pad delay 不一致等影响
推荐控制在 ±¼ UI 范围内
超过这个范围虽然还能工作,但会增加后级逻辑复杂度(比如需要 word 级别 deskew)
特点总结:
项目 | 内容 |
|---|---|
是否逐位 deskew | ✅ 是,实时逐位校准 |
使用资源 | 每位2个 ISERDES + 2个 IODELAYE2 |
对 PCB 走线要求 | 较宽松 |
是否适合多通道 | ✅ 适合,通道间可不对齐 |
Bitslip 是否还需 | ✅ 需要做字对齐(但不是逐位) |
应用领域 | 高速视频接口、数据采集等存在线长不一的系统 |
为什么要使用双 ISERDES + 双 IODELAYE2:
在 Xilinx 7 系列 FPGA 中,为了实现 逐位去偏斜(per-bit deskew) 的接收方案,需要使用 双 ISERDES + 双 IODELAYE2。原因如下:
核心目标:
实时测量每一位数据的最佳采样时间点,并自动调节采样延迟,使采样点处于数据眼图的中心,从而实现稳定接收。
为什么要用“双 IODELAYE2 + 双 ISERDES”?
组件 | 作用 |
|---|---|
| 第一个 IODELAYE2 + ISERDES(Master) | 用来在当前延迟设定下真正接收数据 |
| 第二个 IODELAYE2 + ISERDES(Slave) | 将延迟设置为相对于主通道早或晚半个 bit 时间,用于和主通道采样结果做对比 |
这个结构能做什么?
通过两个采样点(主采样点和偏移半 bit 的采样点)进行比较,可以判断当前采样位置处于 eye diagram 的哪一部分:
📊 示例判断逻辑:
现象 | 表明 | 调整建议 |
|---|---|---|
两次采样结果一样(例如都是 1 或都是 0) | 采样位置过晚(已进入数据稳定区) | 应该减小 delay(向前移动) |
两次采样结果不同(例如一个是 0,一个是 1) | 采样位置过早(还在跳变区) | 应该增大 delay(向后移动) |
这样可通过自动调整 主通道的 delay tap 值,找到数据眼中心,从而提升接收鲁棒性。
为什么能“白嫖”用两套 ISERDES 和 IODELAYE2?
因为输入信号是 LVDS 差分对(比如 DIFF_P 和 DIFF_N),在 FPGA 的 I/O 结构中每对差分信号实际上占用两个输入引脚,每个引脚对应一个 ISERDES + IODELAYE2。因此用双通道不需要额外成本。
优点总结:
实现 每个位线独立延迟调节,适应 PCB 走线差异
去除时序分析中的走线 skew 影响,提高设计可扩展性
自动训练和自适应,适合高速、多通道并行数据接收场景
如果使用的是非差分输入(比如 CMOS 单端),那这套双 ISERDES 的架构可能会资源不足,此时你可能只能做通道级 deskew,无法做到 per-bit。这个结构就是为高速、高密度差分输入专门优化的。
什么时候是最佳采样了
在 Xilinx 7 系列 FPGA 的 ISERDES 接收路径中,最佳采样点是指:
采样时钟沿落在数据眼图中间(眼中心)的位置,此时数据最稳定、抗干扰能力最强,采样准确率最高。
判断采样点为“最佳”的条件:
在使用 双 ISERDES + 双 IODELAYE2 实现“逐位去偏斜(per-bit deskew)”时,系统会做如下比较:
Slave 采样(偏早或偏晚 ½ UI) | Master 当前采样 | 比较结果 | 判断 | 下一步 |
|---|---|---|---|---|
与 Master 不同 | ✔ 不同 | 在数据跳变边沿附近,说明 Master 落在眼图中间附近(稳定区边缘) | ✅ 当前 delay 就是最佳采样点! | |
与 Master 相同 | ✘ 相同 | 两者都落在同一稳定区(0或1),说明 Master 太晚或太早 | ❌ 继续调整 delay |
举例说明:
Master 采样的是
1Slave(提前 ½ UI)采样的是
0
👉 表示采样点跨过了跳变沿
✅ 说明采样点刚好落在边沿附近,是可接受的中点位置
为什么这时是最佳采样?
因为:
采样点既不太早(可能采到旧数据)
又不太晚(可能错过新数据)
而是正好在数据的稳定区域中部
如果采样点再靠近边沿,就可能采样不稳定(setup/hold 违例)
最终动作:
停止调整 delay,锁定当前延迟值。
将该 delay 应用于所有数据位的主 IODELAYE2。
使用该采样配置进入正式接收阶段。
使用该方式调节之后,如何确定多个通道数据是对齐了,而不是单通道对齐了时钟,但是多通道的数据流呢?
🌟 为何存在通道间错位(inter-channel skew)?
因为:
PCB 布线长度不一致;
FPGA 管脚传播延迟差异;
不同通道上驱动器或接口的延迟不同;
同一时钟驱动多个通道,但每个通道的IODELAY值可能不同;
如何确保多通道对齐(通道间数据同步)?
Xilinx 提供的解决方案分为两步:
第一步:逐位对齐(Per-bit Deskew)
使用双 ISERDES + 双 IODELAYE2,确保每一位的最佳采样点落在其眼图中点,解决的是“位级时序”稳定性问题。
👉 它只保证:每条线的数据采得准,但不保证各通道之间同步。
第二步:字对齐(word alignment)+ 通道对齐(channel alignment)
实现思路如下:
方法一:使用“帧标识符”/帧头(Frame Marker)
上游发送的数据中,每隔 N 个字节(或时钟周期)插入一个特定的 帧同步标志(如 1100001 或 1100011)。
每个通道在采样完毕后:
利用 ISERDES 的 Bitslip 功能
在采样到帧标识符时对齐位移量
多个通道最终输出的并行数据中,帧头都处于相同位置 ➜ 通道同步完成。
这是 XAPP585 推荐的做法。
方法二:FPGA 内部使用“Gearbox FIFO + 同步逻辑”
每个通道数据进 FPGA 后,进入各自的 同步 FIFO 或 FIFO + Gearbox
在 FPGA 内部使用参考通道(通常是通道 0)作为基准时钟/帧头
其他通道在采集到相同帧头之后,在 FIFO 内插入或丢弃字节,实现通道对齐
方法三:用户自定义同步协议
适用于用户协议,例如:
数据以固定帧格式发送(如:[帧头][数据块][CRC])
FPGA 中检测到所有通道同时具有帧头时,启动通道对齐标志
如何验证已经“多通道对齐”?
打印接收到的并行数据,看帧头是否在所有通道同一位置。
Scope/ILA 观察多个通道的数据流,看是否同步跳变。
FPGA 中可加入调试信号输出当前“通道偏移状态”,对齐后打标。
总结
问题 | 解决方式 |
|---|---|
单通道采样点对不准 | 双 ISERDES + 双 IODELAYE2 实时采样优化 |
多通道数据流未对齐(通道间 skew) | 使用帧头 + Bitslip + 多通道同步机制 |
多通道对齐之后保持同步 | 采用全局参考时钟或锁存标志机制 |
如果每个通道都对自己的数据做 Bitslip,万一某个通道刚好对齐到一个完整字(偏移了 7 bit = 1 word),那么各通道虽然帧头对了,但它们对应的实际“帧”却不一致。
这意味着:
所有通道都输出了帧头(如
1100001),但这些帧头其实来自不同时间点的数据帧,
也就是说 —— 通道之间仍未对齐,只是每个通道各自“字对齐”了。
所以:Bitslip 只能保证 字对齐(Word Alignment),不能自动保证 通道对齐(Channel Alignment)
要解决这个问题,必须再加一层:
通道对齐(Channel Alignment)补充机制
下面是常见的三种方法:
方法一:全通道共享帧头序列 + 位置比较
前提:所有通道的帧头是一样的(例如全都是
1100001);在所有通道都完成 Bitslip 之后,
检查每个通道帧头出现的时钟周期编号;
与通道0作为参考,比较其它通道是否**“同一拍”**;
若某个通道晚了 1 word,就用 FIFO 延迟;
若某个通道早了 1 word,就用 FIFO 提前读出(或插入一组 dummy 数据)。
📌 这就需要每个通道后面带一个 Elastic Buffer(弹性 FIFO),实现通道延迟匹配。
方法二:在帧头后附加帧编号(Frame ID)
类似帧结构:
帧结构:| 帧头 | 帧编号 | 数据0 | 数据1 | 数据2 | ...每个通道的帧头后带一个递增的编号,如
0001,0002,0003;当所有通道都对齐了帧头后,
检查各通道解出的 Frame ID 是否一致;
不一致 → FIFO 补偿;
一致 → 通道对齐完成。
🔧 缺点是要牺牲部分数据带宽来传编号(适合协议数据流,不适合裸图像数据流)。
方法三:信号同步窗口法(更工程化)
在设计链路上游时,每隔 N 个数据帧插入一个 全通道同步标志帧;
比如每隔 1024 个字,插入一组
SYNC帧;所有通道的接收端在看到 SYNC 帧时统一时间标记;
若某些通道 SYNC 提前到达,就暂缓输出;
若某些通道 SYNC 延后到达,就用 FIFO 临时缓存。
这适用于图像视频、音频等时钟容忍度强的接口。
总结
问题 | Bitslip是否能解决 |
|---|---|
单通道字对齐 | ✅ 是 |
多通道数据帧对齐 | ❌ 否(需要额外机制) |
检查每个通道帧头出现的时钟周期编号如何检查?
这是个很深入的问题,我们来系统地解答:如何检查每个通道帧头出现的时钟周期编号,也就是通道对齐中最关键的一步。
背景回顾:
当你使用 ISERDES 把串行数据反序列化成 7 bit 并行数据后,你在每个通道都能拿到一组 “每个时钟周期更新一次” 的 7-bit 并行数据。我们希望:
每个通道都能在相同的时钟周期看到一个一致的帧头(如
1100001);如果某些通道比别人早或晚了看到帧头,就说明它们时序上提前或滞后;
然后再用 FIFO(延迟队列) 统一这些通道的输出,使它们“对齐”。
方法:通过时钟域的“帧头打拍”来实现检测帧头出现时刻
以下是一种可行、实用的方案流程:
步骤 1:每个通道上,检测帧头
你在每个通道上都可以用一个比较器判断:
wire frame_header_detected = (parallel_data == 7'b1100001);
这表示:当前时钟周期,是否检测到了帧头。
🧩 步骤 2:打拍“检测信号”进帧对齐逻辑
你定义一个“全局帧计数器”,每个接收通道在帧头检测到的那个周期,把当前帧计数器的值存下来:
reg [7:0] frame_counter;always @(posedge clk) begin frame_counter <= frame_counter + 1;endreg [7:0] detected_frame_index_ch0;always @(posedge clk) beginif (frame_header_detected_ch0) detected_frame_index_ch0 <= frame_counter;end// 对于每个通道都做一次
这样,detected_frame_index_ch0 表示通道0帧头出现的时间点(用全局frame_counter标记)。
步骤 3:对比每个通道的帧到达时刻
对所有通道,你都做类似记录,得到:
通道编号 | 帧头检测时刻(frame_counter) |
|---|---|
CH0 | 101 |
CH1 | 100 |
CH2 | 101 |
CH3 | 102 |
然后以最慢通道为标准(最大值),将其它通道的数据暂存在 FIFO 中延迟对应数量的周期:
CH1:早到 1 拍 → FIFO 延迟 1;
CH3:晚到 1 拍 → FIFO 提前处理,或报错根据场景;
CH0/CH2:不动。
延伸说明:为什么用 frame_counter?
因为 ISERDES 输出的是 按时钟对齐的数据帧,我们用系统时钟的 frame_counter 来标记“这个帧在什么时候出现的”,从而可以做“通道间同步”。
工程实现技巧:
- 检测帧头并锁存时间戳
,用的是比较器 + 打拍;
- 延迟补偿
用的是每通道一个小深度 FIFO;
- 通道数大时
,建议引入中央控制模块统一比较并配置补偿量;
- 帧头可能多次出现
,所以要只用第一次匹配成功时的帧号作为参考;
- 后续帧号
也可以用作监测通道是否发生偏移,做动态校正。
总结
步骤 | 说明 |
|---|---|
1 | 用比较器检测 ISERDES 输出的帧头数据 |
2 | 每个通道在检测到帧头时记录 |
3 | 所有通道汇总帧头出现时刻,计算延迟差值 |
4 | 用 FIFO 等待/补偿,最终实现通道对齐 |
(全文完)
声明:我们尊重原创,也注重分享;文字、图片版权归原作者所有。转载目的在于分享更多信息,不代表本号立场,如有侵犯您的权益请及时联系,我们将第一时间删除,谢谢!

想要了解FPGA吗?这里有实例分享,ZYNQ设计,关注我们的公众号,探索
404

被折叠的 条评论
为什么被折叠?



