news 2026/10/3 1:35:59

AD9694调试经验:JESD204B链路建链与时钟同步实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
AD9694调试经验:JESD204B链路建链与时钟同步实战

1. 项目概述与核心难点

1.1 AD9694是什么,为什么调试它那么折腾

AD9694是ADI推出的一款四通道、14位、最高1 GSPS采样率的JESD204B接口ADC芯片。它的定位很明确:用于多通道、高带宽的数据采集场景,比如相控阵雷达、软件无线电、多通道示波器前端、宽带通信中频采样等。和传统LVDS/CMOS并行输出ADC相比,AD9694最大的特点就是把数据通道收敛到了高速串行链路上——四条lane(或者按配置减少)通过JESD204B协议把数据送到FPGA的GTX/GTY/GTH等高速收发器上。

这款芯片其实是AD9689/AD9208这些高端器件的“小兄弟”,但它的调试复杂程度一点都不“小”。我记得第一次拿到AD9694的板子时,光是把JESD204B链路跑通就花了将近三个工作日。回头复盘发现,卡住的点基本都是些文档里写得不够直白、或者时序细节容易被忽略的地方。这篇博文就是把这些坑整理出来,给准备调试AD9694的朋友省点走弯路的时间。

1.2 调试AD9694需要哪些前置条件

在动手之前,有几个前置条件必须确认,不然后面所有的努力都是白费:

  • 硬件层面:AD9694的电源供电必须正常,尤其要注意模拟电源AVDD、数字电源DVDD、以及FPGA侧高速收发器电源的时序关系。AD9694对电源纹波比较敏感,尤其是采样时钟的相位噪声会被直接折到输出信号里。
  • 时钟层面:AD9694需要外部提供参考时钟(CLK+/-),这颗时钟的质量直接决定了采样性能。如果是通过时钟芯片(比如AD9528、LMK04828)产生,那这个时钟芯片的配置要先行搞定,因为SYSREF也需要同源产生。
  • FPGA开发环境:我用的Vivado版本是2019.2以上,JESD204B IP核从Vivado 2017.4开始集成了比较完整的支持,但版本之间差异不小。如果是Intel(Altera)平台,对应的Transceiver JESD204B IP和ADI的HDL工程集成方式不太一样,本文以Xilinx环境为主。
  • 辅助工具:一个支持SPI读写的上位机(ADI的AD9694评估板软件、或者自己写一个SPI调试助手)、Ila逻辑分析仪核、以及一个靠谱的频谱分析仪(验证信号质量用)。

提示:AD9694的SPI接口虽然是标准的四线SPI,但它支持burst mode,也就是一次可以连续读写多个寄存器。调试时建议第一次全部读一遍芯片的寄存器ID和版本号,确认SPI链路没问题再开始配参数。这个习惯可以帮你排除一半以上的低级问题。

2. 整体调试思路与JESD204B协议要点

2.1 JESD204B在AD9694上的数据链路架构

JESD204B和传统并行接口最大的不同,是它把数据打包成帧,再以串行方式逐字节传输。打个比方:传统并行ADC是大巴车,32个人并排坐着一起下车;JESD204B更像是地铁,乘客按顺序刷卡出站,每个人还带着编号。

AD9694的JESD204B链路有几个关键参数:

  • L:通道数量,即lane数。AD9694最多支持4条lane,配置为LMF = 421(4 lane、2转换器、1 frame)或者更低的通道数。
  • M:转换器数量,AD9694是4通道,所以M = 4。
  • F:每帧字节数,由采样位数和通道数决定,对AD9694这样14bit采样、非半字节对齐的情况,需要关注是否配置填充位。
  • K:每多帧包含的帧数,K值一般选32,但要注意和SYSREF的配合关系。
  • N / N':N是实际转换位数(14bit),N'是有效传输位数,默认32bit对齐(即4字节),这部分由芯片自动处理。
  • CS:控制位数,通常为0。

调试之前,建议先在纸上把链路结构画出来:ADC端4个通道的数据,经过JESD204B的映射、加扰、8b10b编码,最终通过4条lane送到FPGA。每个环节都有对应的寄存器位控制,你必须让ADC端和FPGA端的参数完全一致,才能正常建链。

2.2 JESD204B子类1与SYSREF的时序关系

AD9694只支持子类1(Subclass 1),也就是设备必须支持确定性时延(Deterministic Latency)。这意味着除了设备时钟(Device Clock)和SYSREF,三者必须严格同源。

SYSREF的作用是告诉接收端“现在开始对齐多帧边界”。它可以是单脉冲,也可以是周期性的,常见做法是用时钟芯片输出连续SYSREF或者在配置完成后发送有限数量脉冲(比如LMK04828的B脉冲模式)。对于FPGA端的IP核来说,SYSREF信号必须满足setup/hold时间,而且一定要在设备时钟的上升沿附近稳定,否则出现了亚稳态,链路状态将是“薛定谔的同步”——每次上电结果可能都不一样。

实际操作中的经验是:

  1. 先把SYSREF的频率设置成设备时钟频率除以K的倍数关系,这是JESD204B规范里说的“SYSREF必须是多帧时钟的整数倍”,简单理解就是SYSREF要在同一个多帧边界点到来。
  2. 如果用的是ADI的评估板或者FPGA开发板,尽量用LMK04828的SYSREF输出,因为它的SYSREF边沿可以通过寄存器进行精细调节,能有效对冲PCB走线带来的skew问题。

我踩过一个特别典型的坑:SYSREF的上升沿和设备时钟靠得很近,Vivado的JESD204B IP核可以正常sync_arm和sync_req,但偶发出现链路同步失败。后来用示波器对比了设备时钟和SYSREF的时序,发现SYSREF的建立时间不满足,在FPGA端把SYSREF经过IBUFDS后加了一级IOBUF的输出延迟(IDELAY),问题就解决了。所以调试中如果你的SYSREF偶发失步,第一个要怀疑的就是时序裕量。

2.3 AD9694的SPI寄存器配置关键点

AD9694的寄存器表非常长,但真正关系链路建链的核心寄存器并不多。这里列出几个我在调试过程中反复打交道的:

寄存器地址名称作用备注
0x0EPLL Enable使能内部时钟分频/倍频如果使用外部参考时钟需要确认PLL状态
0x101JESD204B Link Enable使能JESD204B链路默认可能是关闭的
0x10BLMF配置设置Lane数L、转换器M、帧F必须和FPGA端一致
0x102编码模式使能8b10b编码通常使能
0x50测试模式控制设置可测试的pattern调试链路用

需要注意的是,AD9694的寄存器地址有点反人类,有些寄存器是read-back类型的(写进去不生效,只能读出芯片状态),有些是read/write的。建议拿到芯片后先读一下0x00寄存器,确认芯片ID是0xDF(AD9694的芯片ID,具体看手册),再往下配置。

寄存器配置顺序也有讲究:务必先配置时钟相关和JESD204B链路参数,最后一步再使能链路。如果顺序反了,芯片内部的部分模块可能处于不确定状态。这有点像煮饭:你得先把米洗好、水放好,再按煮饭键,否则按下去了才发现水不够,就很被动。

2.4 FPGA端JESD204B IP核的初始化流程

FPGA端的JESD204B IP核主要由三部分组成:JESD204B PHY、JESD204B Transport Layer、以及一个Link Layer的状态机。Vivado通过core configuration界面让你配置L、M、F等参数,但这远远不够。

核心初始化流程(我总结的一般步骤):

  1. 根据AD9694的采样率、位宽和lane数,计算线速率。公式:线速率 = 采样率 × 位宽 × M / L,再乘以8b10b的1.25倍系数,同时还要考虑Framing overhead。比如:4通道、14bit、500MSPS、4条lane,那么线速率大约是500M × 16(有效位)/ 4 × 10/8 = 2.5 Gbps左右。
  2. 在Vivado中配置GTX/GTH参考时钟,确保线速率在收发器的支持范围内。
  3. 例化JESD204B IP核,选择Subclass 1,配置好L、M、F等参数以及SYSREF相关的选项。
  4. 注意IP核的tx_sysref和rx_sysref要分别接到对应AD9694输出的SYSREF(实际上通常共用一个SYSREF源)。
  5. 协处理器(比如AXI-Lite接口)手动初始化:先写JESD204B IP核的寄存器,拉高reset,等locked信号有效后再配置链路层。

这里特别提醒:如果FPGA端JESD204B IP核显示链路已经up,但数据不对,大概率是Transport Layer的字节映射问题。AD9694的Sample输出在JESD204B帧里分布是有讲究的,不同LMF下映射关系不一样。这时候需要用ADI推荐的“lane mapping”设置,把ADC输出的lane顺序和FPGA接收端的lane顺序对应上,避免出现通道数据穿串。

3. 硬件设计与时钟树注意事项

3.1 AD9694的电源设计时序和噪声要求

AD9694的电源轨不少:模拟3.3V(或1.8V,取决于型号后缀)、数字1.8V、以及FPGA侧需要VCCINT、VMGTAVCC等。关键要求是上电时序不能乱。芯片手册一般会给出推荐的上电顺序,通常先模拟电源,再数字电源,再IO电源。如果电源轨上电顺序不对,芯片可能锁死在未知状态,表现出来就是SPI能通、但JESD链路死活建不起来。

如果板子上没有专门的电源时序控制芯片,可以在FPGA端用一个小模块控制各路电源DC-DC的EN引脚,输出一个电源好的指示信号,确保顺序无误。

噪声问题也要重视:AD9694对DVDD的纹波比较敏感,实测在500MSPS采样率下,当DVDD纹波大于50mV峰值时,输出频谱的杂散比会增加好几个dB。如果你发现SFDR性能变差,用示波器在AC耦合模式下看看DVDD的纹波,也许能找到原因。这要求电源设计时至少用LDO给模拟部分供电,数字部分适当放一些展频时钟也没有问题,但模拟采样时钟的供电必须干净。

3.2 采样时钟的关键指标和SYSREF联动

AD9694的采样时钟既可以直接用晶振产生,也可以通过PLL倍频。但如果你想发挥它的全部性能,建议用专用时钟芯片(LMK04828或者AD9528)。这颗芯片不仅提供设备时钟,还提供和它严格同步的SYSREF,可以解决你可能遇到的确定性延迟问题。

设备时钟的频率不是随便定的,它必须满足采样率和FFT分析的需求。AD9694内置了时钟分频器,你可以让外部输入一个较高频的时钟,再用内部分频得到实际采样率。但注意:内部分频不会改变输入时钟的相位噪声,所以输入时钟本身质量很重要。

一个具体案例:我们项目里用LMK04828输出两路时钟,一路是100MHz的设备时钟给AD9694,另一路是SYSREF脉冲给FPGA和AD9694。由于LMK04828的寄存器配置里SYSREF的输出延迟不是0,我需要在FPGA端调整SYSREF到JESD204B IP核的路径延迟。这里最笨但最有效的方法是在IP核的调试界面观察rx_sysref_status,这个信号会显示SYSREF是否被正确识别。如果状态不对,就调整LMK04828的SYSREF delay,直到状态稳定。

3.3 PCB布线与重要信号完整性约束

布线层面的一些经验总结:

  • 高速串行线(JESD204B lane)必须做100Ω差分阻抗控制,尽量减少过孔数量。JESD204B的速率通常在2.5Gbps以上,过孔stub会带来显著的反射,所以关键信号尽量走表层或者埋孔。
  • SYSREF走线最好单独包地,不要和高速lane并行过长距离。SYSREF是单端网段(通常用差分转单端器件),一旦耦合到高速lane的开关噪声上,时序裕量就会受到影响。
  • ADC采样时钟的走线建议远离数字逻辑部分,避免数字信号跳变通过空间耦合到时钟路径。现实中,数字信号和模拟时钟走线平行了2cm,就足以让采样时钟相位噪声恶化到不可接受。
  • FPGA侧的GTX参考时钟引脚要经过配置,确保对应bank的参考时钟源没配错。比如Vivado工程中如果误把参考时钟引到了GTX的另外一个bank,即使线速率正确,收发器也无法锁定。

这些看起来像老生常谈,但其实现场调试的时候,每当出现链路不稳、误码率偏高,回查硬件布线的耗时往往比查代码还长。前期把约束做好,能省掉大量后顾之忧。

4. 实操过程与核心环节实现

4.1 从零开始:AD9694的SPI初始化脚本

我在实际调试中,习惯用Vivado的MicroBlaze软核或者外部MCU通过SPI配置AD9694。下面给一个简化的初始化流程,对应AD9694手册的寄存器表(具体地址以手册为准,不同版本可能有个别差异):

1. 读寄存器0x00,验证SPI通信和芯片ID 2. 写0x0E = 0x01,使能内部PLL(如果使用外部参考时钟) 3. 配置JESD204B相关:0x101 = 0x00 先关闭链路 4. 配置LMF参数:0x10B = 0x24(举例:L=4,M=4,F=2,这里是示意值,具体要看实际配置) 5. 设置N/N':0x108 = 0x00,表示32bit对齐;0x109 = 0x00(N' 32 bit) 6. 设置SYSREF相关寄存器:0x110 = 使能SYSREF接受 7. 设置测试模式(如果需要): 0x50 = 0x01 使能输出固定pattern,方便FPGA端检查链路 8. 检查所有寄存器配置无误后,最后写0x101 = 0x01,使能JESD204B链路

调试时强烈建议先配置固定测试pattern,而不是一上来就传真实ADC数据。这样你可以先在FPGA端验证JESD204B链路是否建链、帧是否对齐。链路真正建好了,再关掉测试模式、换成真实数据。

4.2 FPGA端JESD204B IP核的例化和链路建立

以Vivado为例,打开IP Catalog搜索JESD204B,选择JESD204B PHY和JESD204B IP核。配置界面里有几个容易出错的地方:

  • JESD204B IP核的线速率设置:这个数值必须和你计算的电速率一致。
  • Reference Clock:要选择正确的GTX参考时钟。
  • 字节映射:如果ADC端做了lane reversal(比如物理布线把lane顺序调换了),需要在IP核里做相应调整。

例化完成后,需要用状态机控制IP核的复位和初始化。通常流程是:

  1. 等待GTX的reset_done拉高。
  2. 向JESD204B IP核写配置寄存器(确定L、M、F等)。
  3. 拉低tx_reset和rx_reset,发送sync信号。
  4. 等待link_up状态拉高(或者tx_link_ready/rx_link_ready)。
  5. 观察链路数据是否正常,可以用ILA抓数据看看。

这里特别提一点:JESD204B链路建链不是一蹴而就的,需要经历CODE GROUP SYNC、INIT LANE SYNC、FRAME SYNC等多个阶段。如果你在某个阶段卡住,比如一直处于CGS阶段无法进入ILAS阶段,大概率是SYSREF或者8b10b编码的问题。在ILA里观察rx_link_status或者sync信号的反饋,基本能定位卡在哪个阶段。

4.3 数据通路与DDC/NCO配置要点

AD9694除了纯粹的采样输出,内部还有DDC(数字下变频)和NCO(数控振荡器),可以在数字域把宽带信号搬到基带。这一块对于做窄带接收的朋友非常重要。

DDC和NCO配置的核心寄存器包括NCO频率字和DDC滤波系数:

  • NCO频率字计算:频率字 = 目标频率 × 2^32 / 采样率(假设32位累加器)。比如采样率500MSPS,想搬移100MHz的信号,频率字 = 100e6 × 2^32 / 500e6 ≈ 858993459。
  • DDC的抽取率和滤波带宽设置:AD9694提供了多种滤波档位,你需要根据目标信号带宽选择合适抽取率,同时注意带外抑制是否满足要求。

配置DDC之前,先确认JESD204B链路的M和F参数是不是需要调整。因为DDC开启后,数据率会降低,输出数据的结构也会变化。如果你是先配置好完整链路、再开启DDC,发现数据不对是很正常的——这两个模块会改变输出引脚上的帧格式。正确做法是在设计时就想好“到底是采样后全带宽输出,还是启用DDC后输出窄带信号”,然后据此配置M/F参数。

4.4 验证数据正确性:从固定pattern到真实信号

链路建好后,最关键的一步是验证数据是否真的正确。我自己一般分三步走:

第一步,用固定pattern验证。把AD9694设为输出0xAAAA或者递增pattern,然后在FPGA端用ILA抓数据,确认收到的数据和预期的pattern一致。这一步能确认JESD204B链路从物理层到传输层都没有问题。

第二步,输入一个已知信号。用信号发生器给AD9694输入一个单音正弦波(幅度控制在满量程的-1dBFS左右),在FPGA端采集一段时间数据,做FFT分析。观察频谱图中是否只在对应频点上有一个peak,杂散是否在合理范围(比如优于-60dBc)。如果杂散很多、甚至出现镜像,先怀疑采样时钟的相位噪声,其次检查输入信号是否过载或欠载。

第三步,测试动态范围。把信号源的输出幅度逐步减小,观察底噪电平是否合理。AD9694的理论底噪大约在-68dBFS左右(满量程相对底噪),如果实测底噪高出很多,大概率是PCB噪声或者电源纹波引入的。

验证项目判断标准常见异常现象可能原因
SPI读写芯片ID正确全0或全FSPI极性/速率不对,接线错误
链路建链link_up=1一直处于CGSSYSREF没来、线速率不对
固定pattern数据符合预期字节错位Transport Layer映射不对
单音测试频谱干净杂散/镜像多采样时钟质量差,信号过载
满量程幅度-1dBFS左右输出削顶输入幅度过大或PGA增益配置错误

5. 常见问题与排查技巧实录

5.1 JESD204B链路无法建链怎么办

这条是AD9694调试最常遇到的问题,没有之一。以我经验看,链路建不起来的原因按概率排序是:

  1. SYSREF时序不对(概率最高)。
  2. 线速率计算错误(尤其是8b10b的系数忘了乘)。
  3. ADC端和FPGA端的LMF参数不一致。
  4. GTX参考时钟没稳定。
  5. PCB走线导致信号质量太差。

排查的方法不要靠猜,用ILA把关键信号都抓出来:

  • 确认GTX的tx/rx_reset_done已经拉高。
  • 确认JESD204B IP核的tx/rx_sysref已经收到(用ILA观察sysref信号是否出现脉冲)。
  • 确认你配置的线速率和GTX实际锁定的速率一致。

如果这些都没问题,但链路还是起不来,可以试着降低线速率:把采样率从500MSPS降到100MSPS,按比例降低线速率,看看链路是否能建起来。如果能建起来,说明线路质量或GTX配置有问题,需要回头检查高速线缆、背板或者GTX的预加重/均衡参数。

5.2 数据出现周期性误码或者偶发错位

链路建起来之后,数据偶尔错位是比较恶心的问题。通常表现为:数据大部分时间正确,但偶尔出现一大块数据整体错位,然后又恢复正常。这种问题大概率是确定性时延没有被严格保证,即SYSREF相对多帧边界发生了偏移。

我在调试中遇到过一次类似现象,最后发现是FPGA端JESD204B IP核的SYSREF采样时钟域问题:IP核的rx_sysref没有同步到设备时钟域,导致偶发的亚稳态。解决方案是在FPGA逻辑里对rx_sysref做两级触发器同步,然后把它和rx_device_clk的相位比对。调整之后,连续运行72小时也没有再出现错位。

5.3 频谱质量差、底噪过高怎么定位

如果你按4.4的测试步骤输入单音信号,发现频谱质量不好,建议按以下顺序排查:

  1. 先确认信号源本身质量。把信号源直接接到频谱仪上看,确认信号源输出是否干净。
  2. 检查AD9694模拟输入前端的巴伦/放大器电路,是否正确地做了阻抗匹配。AD9694的输入阻抗不是标准的50Ω,可能需要并联电阻匹配。
  3. 检查电源纹波,尤其是DVDD和AVDD。
  4. 检查采样时钟是否为整数周期分频关系,有些时钟芯片配置乱套后,会产生较大的抖动。

其中,电源纹波的问题最隐蔽,因为很多开发板的电源纹波指标没有达到AD9694手册要求。如果项目对性能要求高,建议单独用高精度LDO给模拟电源供电,数字电源适当隔离。

5.4 通道间串扰问题的排查

AD9694是四通道器件,通道间串扰在指标上会有规定。但有时候你会发现两个相邻通道的信号互相泄露。常见原因:

  • 模拟前端没有分开供电或者参考地平面被分割不当。
  • JESD204B的lane mapping把两个通道的数据对应错了(这是FPGA端配置的问题,不是真正的模拟串扰)。
  • 输入信号通过PCB走线耦合到相邻通道的输入端。

排查时先把所有通道配置成同一测试模式,再看数据是否串扰。如果固定的pattern没有串扰,但实际模拟信号有串扰,那多半是PCB问题,而不是数字配置问题。

6. 写在最后:调试心得与扩展建议

调试AD9694这件事,说难也难,说简单也简单。难在它是一个交织了模拟、时钟、高速数字协议的复杂系统,任何一个环节稍有偏差,都可能让你的链路起不来或者性能不达标。简单在于,只要把时钟和JESD204B链路这两个核心原理吃透,剩下的大量工作都是在跟寄存器手册和波形图较劲。

我个人非常推荐第一次调AD9694的朋友,先不要一头扎进寄存器手册,而是先把JESD204B协议的白皮书通读一遍,特别是子类1的确定性时延机制。这个机制理解到位了,很多看起来莫名其妙的现象都会迎刃而解。另外,ADI的评估板软件(VisualAnalog、ACE等)虽然不直接对接你的FPGA工程,但用它能快速确认芯片配置和预期行为,可以作为很好的参照物。

后面如果再扩展,可以考虑给AD9694加一个多芯片同步的功能,让多片ADC共享同一个SYSREF,实现更大规模的多通道采集。这项技术在很多相控阵项目里是标配,但调试难度会再上一个台阶,核心在于SYSREF的路径延迟校准和链路延迟补偿。等你把单芯片的AD9694玩透了,再挑战多芯片同步,会顺手很多。

调试过程中遇到问题,不要急躁。AD9694这类高速数据采集系统,难点不是某个单独知识点,而是各个模块之间的协同。带着示波器和ILA,一个阶段一个阶段地验证,才能最终把性能压榨出来。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/3 1:35:22

Oracle性能优化实战:先诊断再调参,AWR+SQL优化让数据库变快

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/3 1:35:14

Scrapy爬虫实战:从零搭建深度学习论文数据采集管道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/3 1:34:25

Xenomai 4双内核架构详解:硬实时Linux安装与调优指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/3 1:34:06

Flink实时推荐系统实战:从用户行为到秒级特征更新

简介:基于Flink的商品实时推荐系统项目包,适合大数据开发与推荐系统学习者,用于解决实时商品热度统计、用户画像构建及个性化推荐排序等核心问题。资源共109个文件、压缩包3.74MB,以68个Java源文件为主,另有SQL建表脚本…

作者头像 李华
网站建设 2026/10/3 1:33:47

教务管理系统课程设计:E-R图、建表SQL与ASP增删改查全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/3 1:33:27

ESP32接大模型不算AI硬件:8个工程化难题与端云协同方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华