FPGA时序优化实战:SHREG_EXTRACT属性如何影响SRL推断与性能
1. 从一次意外的时序违例说起SHREG_EXTRACT的威力最近在做一个高速数据接口的项目用到了Xilinx的7系列FPGA。在代码里我为了确保数据对齐和降低亚稳态风险习惯性地写了一段移位寄存器链大概长这样reg [7:0] data_pipe [0:3]; always (posedge clk_200m) begin data_pipe[0] data_in; for (int i1; i4; ii1) begin data_pipe[i] data_pipe[i-1]; end end逻辑很简单就是四级流水线。综合后的时序报告一开始看着还行但当我尝试把时钟频率从200MHz推到250MHz时问题来了。Setup Time违例而且违例的路径集中在这条移位寄存器链上。更让我困惑的是查看综合后的网表发现这条链并没有被映射到FPGA里现成的SRL移位寄存器查找表资源上而是用了一堆分散的寄存器Flip-Flop和LUT来实现导致布线延迟Route Delay出奇地高。这不对劲。7系列FPGA的Slice里明明有高效的SRL32E、SRLC32E这些原语专门用来做移位寄存器既能节省资源又能优化时序。为什么Vivado综合器“视而不见”在和同事讨论并翻了一阵手册后一个平时很少注意的综合属性Synthesis Attribute进入了视野SHREG_EXTRACT。正是它在幕后默默地决定了我的移位寄存器代码最终会变成什么硬件结构。这次踩坑让我意识到对于FPGA设计尤其是对性能和面积有要求的场景理解并善用这些综合约束不再是可选项而是必备技能。2. SHREG_EXTRACT是什么理解综合器的“翻译”规则简单来说SHREG_EXTRACT是一个你可以附加在Verilog或VHDL代码上的指令属性用来直接告诉Vivado的综合工具Vivado Synthesis“请如何对待我写的这段移位寄存器逻辑”。FPGA的设计流程是从高层次描述HDL代码到低层次网表由LUT、FF、BRAM等基本单元组成的“翻译”过程。综合器就是这个翻译官。对于同一段代码翻译官有不同的“译法”。以移位寄存器为例综合器至少有两种主要的实现策略推断为SRLShift Register LUT这是FPGA架构提供的专用硬件资源。在Xilinx器件中一个LUT可以配置成最多32位的静态移位寄存器如SRL32E。它的好处非常明显面积小一个32位移位只需要一个LUT而用32个触发器FF则需要32个FF和额外的布线资源。时序优信号在SRL内部移动是走固定的快速路径比用离散的FF和LUT通过通用布线连接要快得多尤其对于长位移位链。功耗低动用的硬件资源少动态功耗自然更低。推断为寄存器Flip-Flop链这就是综合器“偷懒”或者在某些约束下选择的方案。它用一个个独立的触发器和可能的一些辅助逻辑来搭建移位功能。这种方案通常更灵活支持任意位宽、异步复位/置位等但在面积和时序上往往不如SRL高效。SHREG_EXTRACT属性就是让你来指导综合器在这两种主要策略之间做选择甚至给出更精细的指令。它的值可以是YES,NO,YES是默认值但它的行为远比一个开关复杂。注意这里存在一个常见的误解。很多人以为SHREG_EXTRACT “YES”就一定能得到SRL “NO”就一定得到FF链。实际上“YES”的意思是“请尝试提取Extract并映射为SRL”但最终能否成功映射还取决于你的代码写法是否满足SRL的硬件模板。而“NO”的意思是“禁止将其提取为SRL”强制使用FF链实现。理解这个“尝试”与“强制”的区别是避免后续疑惑的关键。3. 属性语法详解如何在代码中正确使用在Verilog中你可以通过注释语法来添加综合属性。SHREG_EXTRACT可以应用在不同的层级上作用范围也不同。3.1 模块级Module Level声明当你希望整个模块内所有的移位寄存器逻辑都遵循同一个规则时可以在模块声明前添加。这是最粗粒度的控制。(* SHREG_EXTRACT “NO” *) module my_shift_module ( input wire clk, input wire [7:0] din, output wire [7:0] dout ); // 这个模块内所有可推断的移位寄存器都将被强制用FF实现不会尝试用SRL。 reg [7:0] shift_reg [0:15]; always (posedge clk) begin shift_reg[0] din; for (int i1; i16; ii1) begin shift_reg[i] shift_reg[i-1]; end end assign dout shift_reg[15]; endmodule3.2 信号级Signal Level声明这是最常用、最精准的控制方式。你可以针对某一个特定的寄存器或寄存器数组施加属性而不会影响模块内的其他逻辑。module advanced_filter ( input wire clk, input wire signed [15:0] sample_in, output wire signed [15:0] sample_out ); // 这个移位寄存器用于延迟线对时序要求高我们希望工具尽量用SRL实现。 (* SHREG_EXTRACT “YES” *) reg signed [15:0] delay_line [0:31]; // 这个寄存器组有复杂的同步复位逻辑不适合SRL我们强制用FF。 (* SHREG_EXTRACT “NO” *) reg signed [15:0] state_reg [0:3]; always (posedge clk) begin // delay_line 的实现方式将由工具尝试优化为SRL delay_line[0] sample_in; for (int i1; i32; ii1) begin delay_line[i] delay_line[i-1]; end // state_reg 将始终用FF实现 if (reset) begin for (int j0; j4; jj1) begin state_reg[j] 0; end end else begin // ... 复杂的状态转移逻辑 end end assign sample_out delay_line[31]; endmodule3.3 使用XDC约束文件声明除了在HDL代码中嵌入属性你也可以在XDCXilinx Design Constraints约束文件中进行设置。这种方式将物理约束与逻辑代码分离是大型工程推荐的做法。语法略有不同作用对象需要通过[get_cells]或[get_nets]来指定。# 强制某个特定实例的移位寄存器不使用SRL set_property SHREG_EXTRACT NO [get_cells u_my_module/inst_shift_reg*] # 强制整个层次结构下的移位寄存器不使用SRL set_property SHREG_EXTRACT NO [get_cells -hierarchical -filter {NAME ~ *shift_pipe*}]在XDC中设置的优势在于你可以在不修改源代码的情况下在不同综合实现中灵活切换策略方便进行设计探索Design Exploration。4. 代码风格与SRL推断为什么你的“YES”可能失效设置了SHREG_EXTRACT “YES”却没有看到SRL问题很可能出在你的代码写法上。综合器要成功推断出SRL你的HDL描述必须匹配目标FPGA中SRL硬件的“模板”。以下是一些关键规则和常见陷阱4.1 理想的、可推断的SRL代码模式最简单也是最容易推断的模式是线性移位无额外控制逻辑。// 模式一位宽为1的深度移位寄存器最容易推断 (* SHREG_EXTRACT “YES” *) reg [31:0] srl32; always (posedge clk) begin srl32 {srl32[30:0], din}; // 经典的拼接移位 end assign dout srl32[31]; // 模式二通过数组实现的移位寄存器链同样容易推断 (* SHREG_EXTRACT “YES” *) reg [7:0] pipe [0:31]; // 8位宽32深度 always (posedge clk) begin pipe[0] din; for (int i1; i32; ii1) begin pipe[i] pipe[i-1]; end end assign dout pipe[31];4.2 导致SRL推断失败的常见代码“坏味道”异步复位/置位Asynchronous Reset/PresetSRL硬件原语如SRL32E通常只支持同步复位通过可选引脚CE。如果你的代码包含了异步复位综合器为了保持行为一致会退回到使用FF实现。// 无法推断为SRL的代码 always (posedge clk or posedge async_rst) begin if (async_rst) begin shift_reg 32‘b0; end else begin shift_reg {shift_reg[30:0], din}; end end使能信号Enable的非标准使用SRL有专用的时钟使能CE引脚。如果你的使能逻辑不是简单的if (ce) ...而是与其他条件混合也可能导致推断失败。// 可能推断失败的代码 always (posedge clk) begin if (mode 2‘b01) begin // 复杂的使能条件 shift_reg {shift_reg[30:0], din}; end end移位链中的逻辑操作如果在移位路径上插入了算术或逻辑运算那就不是纯粹的移位寄存器了自然无法用SRL实现。// 无法推断为SRL always (posedge clk) begin shift_reg[0] din mask; // 输入有逻辑操作 for (int i1; i32; ii1) begin shift_reg[i] shift_reg[i-1] 1; // 链中有加法操作 end end非固定深度的移位或动态抽头SRL的深度和抽头位置在配置时是固定的。如果你的代码需要运行时可变长度的移位如桶形移位寄存器或动态选择抽头综合器只能用LUT和FF搭建。// 动态抽头无法用单个SRL实现 always (posedge clk) begin shift_reg {shift_reg[30:0], din}; end assign dout shift_reg[tap_select]; // tap_select是变量位宽过宽虽然一个LUT最多可实现32位深度、1位宽度的移位。对于多位宽数据综合器会尝试并行使用多个SRL。但如果位宽不是2的幂次或与LUT结构不匹配工具可能会权衡后选择其他实现。实操心得当你希望使用SRL时最稳妥的方法是检查综合后的“Synthesis Report”。在Vivado中打开“Synthesis Open Synthesized Design Report Report HDL Attributes”或者直接查看网表Schematic。如果代码被成功推断为SRL你会在网表中看到SRL16E、SRL32E等原语符号而不是一连串的FDRE触发器。5. 实战场景何时用YES何时用NO了解了机制关键在于应用。根据我的经验可以遵循以下决策流程5.1 场景一追求高性能与高频率——优先尝试SHREG_EXTRACT “YES”这是SRL的主场。适用于纯延迟线、同步FIFO的读指针延迟、流水线打拍等对时序要求苛刻的路径。优势关键路径延迟小易于满足时序约束。操作编写规范的、可推断的移位寄存器代码无异步复位、简单使能。在关键路径的信号上添加(* SHREG_EXTRACT “YES” *)属性。综合后务必查看时序报告和资源利用率报告确认SRL被使用且时序改善。案例在一个高速SerDes的Rx路径上需要对恢复出的数据和时钟沿进行多拍对齐。使用SRL实现的延迟线比FF链的版本在250MHz下减少了约0.3ns的路径延迟轻松满足了建立时间要求。5.2 场景二需要复杂控制逻辑——主动使用SHREG_EXTRACT “NO”当你需要异步复位、置位或者在移位过程中嵌入条件逻辑时应该主动禁止SRL推断避免综合器做出不符合预期的优化或产生仿真与硬件不一致的风险。优势行为确定与代码描述严格一致避免潜在的功能错误。操作在包含复杂控制的移位寄存器代码前明确添加(* SHREG_EXTRACT “NO” *)。案例一个状态机的历史状态记录器。每个时钟周期新的状态被移入但当发生异常事件async_exception时需要立即清空整个记录器。这里必须使用带异步复位的FF链。(* SHREG_EXTRACT “NO” *) // 明确禁止因为需要异步复位 reg [2:0] history [0:7]; always (posedge clk or posedge async_exception) begin if (async_exception) begin for (int i0; i8; ii1) history[i] 3‘b0; end else begin history[0] current_state; for (int i1; i8; ii1) begin history[i] history[i-1]; end end end5.3 场景三设计探索与面积优化在资源紧张的设计中SRL是节省Slice资源的利器。你可以通过全局设置SHREG_EXTRACT “YES”并优化代码风格让工具尽可能多地使用SRL从而将节省下来的FF和LUT用于其他更复杂的逻辑。操作在综合设置中可以设置全局的“-shreg_min_size”参数或在Vivado GUI中设置。这个参数告诉综合器只有当推断出的移位寄存器深度大于等于这个值时才尝试使用SRL。例如设置为5意味着深度为4及以下的移位寄存器将直接用FF实现深度5及以上的才会尝试用SRL。这可以避免用SRL实现很短的移位链可能面积收益不大但控制逻辑更复杂。5.4 场景四解决跨时钟域CDC路径的时序问题这是一个高级技巧。在某些非常紧张的CDC路径上即使使用了双触发器同步器也可能因为第一级触发器的输出到第二级触发器的输入这段路径的延迟过大而出现亚稳态。一种加固方案是将同步器的第一级用SHREG_EXTRACT “NO”强制为FF链而将第二级用SHREG_EXTRACT “YES”尝试推成SRL。原理强制第一级为FF链可以将其布局在靠近时钟域边界的IO附近第二级使用SRL可以利用其紧凑的结构和快速内部路径最小化两级寄存器之间的延迟提高同步器的MTBF平均无故障时间。注意这需要仔细的布局约束配合属于进阶优化手段。6. 调试与验证如何确认属性生效及影响属性加对了没有综合器听你的话了吗光看代码不行必须检查综合结果。6.1 查看综合报告在Vivado Tcl控制台或通过GUI操作打开综合后的设计 (open_synthesized_design)。运行命令report_hdl_attributes。这个报告会列出设计中所有被设置的HDL属性及其值你可以在这里确认SHREG_EXTRACT是否被正确读取和应用到目标对象上。6.2 分析网表Schematic与资源利用率这是最直观的方法。在“Synthesized Design”视图下找到你关心的模块或层次。打开原理图。如果你看到SRL16E,SRL32E,SRLC32E这样的符号说明SRL推断成功。如果你看到的是一系列FDRE,FDSE触发器以及LUT6等说明实现方式是FF和LUT。查看“Utilization Report”资源利用率报告。在“Slice Logic”部分关注“Register as Flip-Flop”和“Register as Latch”的数量同时也会单独列出“Shift Register as SRL”的数量。通过前后对比设置属性前后可以清晰看到资源使用的变化。6.3 对比时序报告这是评估属性设置是否有效的终极标准。在综合或实现Implementation后打开“Timing Report”。找到涉及你修改的移位寄存器路径。重点关注逻辑延迟Logic Delay从SRL实现变为FF链实现逻辑延迟通常会增加。布线延迟Route DelayFF链的实现通常需要更长的布线导致布线延迟显著增加。SRL的内部走线是固定的几乎不贡献布线延迟。总延迟WNS, Worst Negative Slack观察路径的裕量Slack是改善还是恶化了。我自己的那个200MHz违例的项目在代码规范并添加SHREG_EXTRACT “YES”后该路径的布线延迟从约1.2ns下降到了0.2ns以内整个路径的时序裕量从-0.5ns变成了0.8ns问题迎刃而解。7. 与其他综合属性的协同与注意事项SHREG_EXTRACT不会孤立工作它需要与其他设计约束和属性配合也需要注意一些边界情况。7.1 与KEEP_HIERARCHY的冲突KEEP_HIERARCHY属性用于强制综合器保持模块的层次边界这有时会阻止跨层次的优化。如果一个移位寄存器链跨越了被KEEP_HIERARCHY保护的模块边界综合器可能无法将其识别为一个完整的、可映射为SRL的长链。在这种情况下即使设置了SHREG_EXTRACT “YES”也可能失效。你需要权衡是保持层次更重要还是获得SRL优化更重要。7.2 与MAX_FANOUT的权衡MAX_FANOUT用于限制信号的最大扇出以缓解布线拥堵和延迟。如果你对一个高扇出的移位寄存器输出信号设置了较低的MAX_FANOUT综合器可能会对其进行复制复制触发器。如果这个移位寄存器原本被推断为SRL复制操作会变得复杂需要复制整个SRL链还是仅复制输出可能导致工具放弃SRL推断转而使用更容易复制的FF链。在这种情况下你可能需要调整MAX_FANOUT的值或者在复制后的路径上分别设置属性。7.3 仿真与综合的一致性这是一个至关重要的点。使用SHREG_EXTRACT “NO”可以最大程度保证仿真行为与综合后硬件行为的一致性因为FF链的行为是标准且确定的。而SRL的实现尤其是当综合器进行深度优化如将多个小位宽SRL合并时其初始值上电后的值在仿真中可能与门级仿真或实际硬件有细微差别。对于有严格初始化要求的电路需要特别注意。通常的解决方法是在代码中为移位寄存器变量赋予明确的初始值如果支持或者依赖全局的GSR全局置位/复位信号。7.4 版本与器件差异不同版本的Vivado工具其综合引擎的优化策略和SRL推断能力可能有细微差别。同样不同系列的FPGA器件如UltraScale与7系列其SRL的底层结构如是否有预取输出也可能不同。因此在一个项目和器件上验证成功的策略在另一个环境中可能需要重新检查。养成查看综合报告和网表的习惯比盲目相信属性更有用。在我经历过的多个项目中SHREG_EXTRACT就像一位沉默的助手平时不显山露水但在关键时刻——无论是为了压住那最后几十皮秒的时序还是为了从拥挤的布局中省出几个宝贵的Slice——它总能提供一种直接而有效的干预手段。理解它意味着你从“写代码让工具去猜”的阶段进入了“写代码指导工具去实现”的更深层次。FPGA设计的乐趣和挑战往往就藏在这些细节的控制之中。下次当你写下reg [N:0] shift_reg;的时候不妨先想一想我到底希望它在芯片里变成什么样

相关新闻

数据库分库分表实战:从核心原理到ShardingSphere-JDBC应用

数据库分库分表实战:从核心原理到ShardingSphere-JDBC应用

1. 项目概述:当数据库成为瓶颈时做后端开发或者系统架构,有一个场景你迟早会遇到:某个核心业务表的记录数从百万级悄无声息地爬升到千万级,甚至上亿。起初,加个索引、优化一下慢查询,系统还能勉强支撑。但突…

2026/10/7 15:23:15 阅读更多 →
DELL R210 II服务器清灰维护、硬件升级与Ubuntu系统部署全流程实战

DELL R210 II服务器清灰维护、硬件升级与Ubuntu系统部署全流程实战

1. 项目概述:一次经典的服务器维护与回顾最近在整理机房角落,翻出了一台老朋友——DELL PowerEdge R210 II。这台1U机架式服务器,当年可是不少中小型项目、边缘计算节点甚至家庭实验室的“入门神器”。灰尘已经积了厚厚一层,风扇的…

2026/10/10 3:11:34 阅读更多 →
维生素C补充真相:鲜枣甜椒性价比远超猕猴桃

维生素C补充真相:鲜枣甜椒性价比远超猕猴桃

这次我们来看一个关于水果营养的科普话题。很多人可能都听过“猕猴桃是维C之王”的说法,但事实真的如此吗?这篇文章将直接切入主题,通过对比数据和分析,揭示哪些水果的维生素C含量被严重低估,以及如何更经济、高效地补…

2026/10/4 5:39:19 阅读更多 →

最新新闻

数据中心机柜温湿度精细化监测:分层多点以太网采集系统实践

数据中心机柜温湿度精细化监测:分层多点以太网采集系统实践

1. 从"空调没报警但服务器降频"说起:粗粒度监测的盲区到底在哪去年夏天做机房巡检时碰到一个很典型的案例:动环平台显示机房平均温度24.5℃,一个告警都没有,但监控大屏上某一排机柜的服务器核心温度持续走高&#xff0c…

2026/10/14 16:08:13 阅读更多 →
大模型落地不只是写提示词:企业用AI,算法工程师在解决哪4个问题

大模型落地不只是写提示词:企业用AI,算法工程师在解决哪4个问题

很多自媒体把“会用AI工具”讲得很简单,仿佛写几句提示词就能替代整个技术团队。实际企业落地时,算法工程师的工作量往往在工具背后:让模型懂业务、不出错、成本低、可审计。一、问题1:模型不了解企业内部数据通用大模型见过公开互…

2026/10/14 16:08:13 阅读更多 →
MCU直连CDC设备实战:CH32V307 USB Host枚举与批量收发

MCU直连CDC设备实战:CH32V307 USB Host枚举与批量收发

简介:这份资料面向嵌入式开发者与USB协议学习者,聚焦MCU作为USB Host识别并驱动CDC类设备这一实际难题,帮助打破传统RS232接口在嵌入式板卡上的技术壁垒。内容从插入检测、总线复位、NRZI编码与同步域讲起,逐步拆解SOP/EOP、PID类…

2026/10/14 16:08:13 阅读更多 →
2024网络安全产业人才发展报告深度拆解:岗位画像、薪资对照与AI技能缺口

2024网络安全产业人才发展报告深度拆解:岗位画像、薪资对照与AI技能缺口

简介:《2024年网络安全产业人才发展报告》面向政府决策者、企业管理者、教育机构以及网络安全从业者和学生,系统梳理全球与国内网络安全产业的人才供需现状,帮助读者把握行业趋势、规划职业路径与制定用人策略。报告涵盖从业人员画像、薪酬水…

2026/10/14 16:08:13 阅读更多 →
KRONE农业机械来料检验案例_大型部件为什么不再搬到质检区

KRONE农业机械来料检验案例_大型部件为什么不再搬到质检区

​农业机械制造商 KRONE 使用安宝特合作伙伴 Visometry 拓影 Twyn,把部分大型来料的视觉质量检查直接放在到货位置完成,无需为了常规 CAD 实物核对,先将工件统一搬运到专门质检区。​质检人员通过平板电脑将 3D CAD 设计状态与现场实物叠加&a…

2026/10/14 16:08:13 阅读更多 →
UK-5099在肿瘤代谢与线粒体功能研究中的应用指南

UK-5099在肿瘤代谢与线粒体功能研究中的应用指南

1. 项目概述UK-5099作为一种线粒体丙酮酸载体(MPC)抑制剂,近年来在肿瘤代谢研究和线粒体功能调控领域引起了广泛关注。这个实验指南旨在为科研人员提供从基础原理到实操细节的完整解决方案,帮助研究者快速掌握UK-5099在肿瘤微环境…

2026/10/14 16:07:13 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

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

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

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

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

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

2026/10/14 7:53:34 阅读更多 →