新闻详情

新闻详情

首页 / 资讯中心 / 详情

Innovus中CTS与Func模式SDC切换的五大关键步骤

发布时间:2026/9/25 2:00:00来源:尧图网络
Innovus中CTS与Func模式SDC切换的五大关键步骤
做数字后端的人基本都知道一个常识CTS不是把时钟树的线连上就完事更不是一份SDC从头用到尾。我之前在项目里就吃过一次亏——CTS做完report_clock_tree出来skew大得离谱插了三千多个buffer却不见收敛后来查来查去发现根因根本不是CTS配置的问题而是我切到CTS模式时SDC里还挂着Func模式下的clock uncertainty。那个值本来是设计早期用来估算时钟质量的CTS阶段工具却把它当成了硬性优化目标于是时钟树优化朝着一个不合理的skew目标去卷树自然越修越歪。从那次之后我养成了一个习惯凡是跑时钟树综合先确认当前analysis view挂的是哪份SDC、约束意图是什么。这篇东西写给正在做Innovus数字后端的工程师朋友尤其是刚接触CTS、对Func模式SDC和CTS模式SDC之间切换逻辑还比较模糊的人。我会把“为什么要切换”“切换前后到底发生了什么”“具体的五大关键步骤是什么”全部拆开讲清楚附带可以直接参考的命令、SDC示例和踩坑经验。读完之后你至少能独立搭出一套相对规范的CTS与Func视图切换流程。1. 为什么CTS阶段不能直接沿用Func模式的SDC——先理清两种约束的“服务对象”很多刚入行的同学会问一句话功能模式下的SDC明明已经把时钟约束写好了时序例外也都在CTS阶段为什么不直接用非要再弄一份专门的CTS SDC这个问题问得非常好因为它背后牵扯的是数字后端里一个核心概念——约束的“意图”不同。1.1 Func模式SDC服务的是“布局选点”时钟是理想模型在Place阶段工具要解决的核心问题是“单元放在哪里”。这个时候时钟树还没有长出来工具只能把时钟当作一个理想网络来估算。所以Func模式的SDC里会写set_clock_uncertainty、set_clock_latency、set_clock_transition这些值本质上都是“拍脑袋估出来的余量”用来模拟未来时钟树的不确定性。set_clock_uncertainty是预留的时钟抖动和OCV余量。set_clock_latency是估算从时钟源到触发器时钟引脚的插入延迟。set_clock_transition是预估时钟边沿的转换时间。这些值存在的意义是让Place阶段的时序报告尽量接近真实从而指导布局工具把关键路径上的单元放得紧凑一些。它从来不是为了精确刻画时钟网络的物理特性而是为了在“没有时钟树”的前提下做相对靠谱的时序预判。1.2 CTS模式SDC服务的是“真实树形”目标是让时钟物理化到了CTS阶段工具要做的事情变成了“真的把时钟buffer插到版图上”它需要回答的问题也变了在哪些节点插buffer、插多大多快的buffer、如何让同一时钟域的sink点延迟接近、怎么满足transition和DRC约束。这些问题不能用Func模式下的那一套理想参数来指导。举个例子func.sdc里的clock uncertainty为0.5ns如果CTS阶段继续用它工具会把“把skew优化到0.5ns以内”当作硬性目标。但skew目标越激进工具就会插入更多buffer、拉出更长的树反而带来了更大的insertion delay和功耗开销。有时候优化结果甚至比一个更宽松的skew目标更差因为你是在用一个拍脑袋的数字去约束一个物理构建过程。所以CTS专用SDC的核心思想是把那些“估算用”的约束拿掉把“物理构建用”的约束加进来。1.3 一张表看清Func.sdc与CTS.sdc的关键差异我把两者最常见的差异整理成了一张表方便对照理解。约束类型Func模式SDCCTS模式SDC时钟状态ideal clock用latency/uncertainty估算保持时钟定义完整由工具构建真实网络延迟clock uncertainty设置用于覆盖时钟抖动和OCV建议删除或大幅缩小否则会过度约束时钟树skewclock latencysource latency可保留片内latency估算值删除或修改source latency保留片内latency不设置由工具计算clock transition设置理想transition一般不设置由工具根据库约束和option修复例外约束保留参与时序分析和优化保留避免影响时钟树综合的优化方向时钟网络DRC不设或较少关注通过set_clock_tree_options设置max_transition、max_fanout、max_cap时钟树例外不需要设置dont_touch_subtrees、dont_buffer_nets、stop_pin等case analysis视需求设置必须设置用于固定scan_mode/test_mode防止测试逻辑干扰时钟树这张表建议存下来写CTS SDC的时候逐条核对。2. 动手之前的底子在Innovus中用MMMC机制把Func和CTS做成两条独立视图上一章说的是“为什么”这一章来说“怎么做准备”。在Innovus里CTS和Func模式SDC的切换不是简单地把某个文件替换掉而是通过MMMCMulti-Mode Multi-Corner机制把不同的约束和不同的延迟corner组合成独立的analysis view然后在不同阶段切换视图。2.1 为什么不用“手动替换SDC文件”这种粗暴做法有工程师图省事每次到了CTS阶段就直接把SDC文件内容清空重写一遍或者用source命令强制覆盖。这种做法在单corner、单mode的小模块里勉强能用但在真正的SoC项目里会带来几个问题SDC里的约束和corner是绑定的只换文件不换corner时序分析用的库、RC参数还是旧的。切换过程没有可追溯性出了问题不知道当前是哪个mode、哪份约束在起作用。多mode项目里func、scan、mbist这些模式都有各自的约束文件手动替换几乎无法管理。MMMC机制的思路是把约束constraint mode、时序库和RC角delay corner分别抽象出来再用analysis view把它们组合成一个完整的分析环境。你可以在同一个设计session里定义多个view随时切换工具内部会保持数据的一致性。2.2 Innovus中创建视图的完整命令流程下面是一套最常见的创建命令花几分钟把逻辑理清楚后面所有切换都建立在这套基础上。# 1. 创建RC corner指定工艺角和温度 create_rc_corner -name rc_worst_125c \ -temperature 125 # 2. 创建delay corner绑定RC corner和时序库 create_delay_corner -name dc_worst_125c \ -rc_corner rc_worst_125c \ -lib_cell_files [list slow_lib.lib] # 3. 创建constraint mode每份SDC对应一个mode create_constraint_mode -name func_mode \ -sdc_files [list ./sdc/func.sdc] create_constraint_mode -name cts_mode \ -sdc_files [list ./sdc/cts.sdc] # 4. 创建analysis view把mode和delay corner组合起来 create_analysis_view -name func_view \ -constraint_mode func_mode \ -delay_corner dc_worst_125c create_analysis_view -name cts_view \ -constraint_mode cts_mode \ -delay_corner dc_worst_125c # 5. 设置当前分析视图setup和hold可以设不同视图 set_analysis_view -setup {func_view} -hold {func_view} update_analysis_view注意这里set_analysis_view是设置“当前工具用哪些视图做分析和优化”-setup和-hold可以分别指定不同的view。很多项目里hold分析会用一个fast corner例如一个setup视图配一个hold视图。上面的例子为了清晰只建了一个corner实际项目请按自己的corner strategy扩展。2.3 工程中常见的视图划分实践一般一个中等规模的SoC视图数量会在5到10个之间。我列一个典型划分方式供参考视图名称Constraint Mode用途func_setup_viewfunc_mode功能模式setup分析func_hold_viewfunc_mode fast corner功能模式hold分析cts_viewcts_mode时钟树综合专用视图scan_shift_viewscan_shift_mode扫描移位模式测试时钟树验证mbist_viewmbist_mode内建自测试模式约束和IO检查在CTS阶段通常会在cts_view下做时钟树综合在CTS完成之后切回func_setup_view做时序收敛。这两套视图的SDC来源不同约束内容不同但共享同一个设计数据和时钟树。3. 五大关键步骤拆解从约束准备到回归切换下面进入正题。我把整套“CTS与Func模式SDC切换”的操作拆成了五个步骤前两个步骤偏向“准备”中间两个步骤偏向“执行”最后一个步骤偏向“流程固化”。每一步我都会解释为什么这么做以及常见的错误做法是什么。3.1 步骤一从Func SDC中改造出CTS专用SDC并挂到CTS视图上不要直接在一份空白文件里重写时钟定义那样很容易漏约束。正确做法是以func.sdc为底本做一次“减法”和一次“加法”生成一份独立的cts.sdc。“减法”指的是删除或修改那些会误导时钟树构建的约束删除set_clock_uncertainty或者把它减小到一个只覆盖基本OCV的值常见做法是留50ps左右。删除set_clock_latency里的片内延迟估算只保留片外source latency。删除set_clock_transition交给工具通过库约束来修复。“加法”指的是加入CTS阶段特有的约束set_clock_tree_options里的max_transition、max_fanout、max_capacitance。set_clock_tree_exceptions里的dont_touch_subtrees、dont_buffer_nets、stop_pin。set_case_analysis固定scan_mode、test_mode等控制引脚。一份简化版的cts.sdc大概长这样# cts.sdc 关键内容(基于常见实践整理字段按项目实际替换) create_clock -name clk_a -period 10 [get_ports clk_a] create_clock -name clk_b -period 8 [get_ports clk_b] create_generated_clock -name clk_a_div2 \ -source [get_ports clk_a] -divide_by 2 [get_pins u_div/CLKOUT] # 不设置 set_clock_uncertainty # 不设置片内 set_clock_latency # 保留关键时序例外参与CTS阶段判断优化方向 set_false_path -from [get_clocks clk_a] -to [get_clocks clk_b] set_multicycle_path -setup 2 -from [get_pins u_data_reg/CK] -to [get_pins u_data_reg/D] # 时钟树目标 set_clock_tree_options -max_transition 0.15 set_clock_tree_options -max_fanout 32 set_clock_tree_options -max_capacitance 0.2 # 时钟树例外 set_clock_tree_exceptions -dont_buffer_nets [get_nets clk_a_div_net] set_clock_tree_exceptions -dont_touch_subtrees [get_cells u_clk_gate/u_icg] set_clock_tree_exceptions -stop_pin [get_pins u_pll/CLKOUT] # 固定模式引脚 set_case_analysis 0 [get_ports scan_mode] set_case_analysis 0 [get_ports scan_enable]这份cts.sdc写好之后挂到前面建好的cts_mode上视图切换时工具就会自动读入它。3.2 步骤二用“减法”和“加法”确认切换后的视图约束符合预期视图切换本身是一条命令的事但真正容易出错的地方在于“切完之后你知不知道当前生效的约束是什么”。所以我习惯在每次切换视图之后立刻做三件事set_analysis_view -setup {cts_view} -hold {cts_view} update_analysis_view # 1. 查看当前使用哪些视图 report_analysis_view -verbose # 2. 查看当前约束模式下SDC的加载情况 report_constraints -view cts_view # 3. 重点核实时钟是否仍在生效 report_clocks -view cts_view这一步不能省。我见过有人切换视图之后没有update_analysis_view结果工具还在用旧的func约束跑CTS也有人CTS视图里时钟定义不完整导致后面clock_design只综合了一半时钟域最后在setup分析时才发现问题来回返工。另外CTS视图里建议做一次“时钟存在性检查”因为CTS工具只会综合当前视图里能看到的时钟。如果某个时钟没有定义在cts.sdc里它对应的时钟树就完全不会被构建切回Func视图后该时钟域的所有路径都会崩。用下面这个小脚本可以快速扫一遍set clk_list [get_clocks -quiet *] foreach clk $clk_list { set n [sizeof_collection [get_clocks $clk -quiet]] if {$n 0} { puts Warning: clock $clk not defined in current view } }3.3 步骤三在CTS视图下配置时钟树综合并执行clock_design在cts_view下做时钟树综合这个阶段工具会读取cts.sdc中的时钟定义、时钟树例外和时钟树选项开始真实插入buffer。Innovus现在默认走CCopt的流程配置项比传统CTS多一些但基本逻辑是一致的。set_analysis_view -setup {cts_view} -hold {cts_view} update_analysis_view # CCopt流程下可以先设置属性再跑时钟树 set_ccopt_property -max_transition 0.15 set_ccopt_property -max_fanout 32 set_ccopt_property -max_capacitance 0.2 # 执行时钟树综合 clock_design -prefix cts如果你在维护一个老版本项目用的还是传统CTS流程那么把set_ccopt_property换成set_clock_tree_options即可主体命令clock_design是通用的。跑完之后建议立刻查看时钟树质量不要急着切回Func视图# 汇总报告看skew、latency、DRV report_clock_tree -summary # 细致报告按时钟域分别检查 report_clock_tree -clock [get_clocks clk_a] -detail这里有一个很容易犯的错误CTS做完后不看报告直接切回Func视图跑时序结果发现setup大面积违例很难定位到底是树没做好还是约束有问题。正确做法是先确认时钟树本身质量比如skew是否在预期范围内、transition是否满足、有没有DRV违例再进入时序收敛阶段。CTS阶段还有一个操作要点如果项目里有special net或者需要手工指定树形的时钟需要在clock_design之前用specifyClockTree这类命令提前约束好。这类手动配置必须在CTS执行前完成否则跑完之后再改只能做ECO式的局部修改效果远不如一把过来得干净。3.4 步骤四CTS完成后切回Func视图确认时钟已由ideal变成propagated时钟树综合完成后工具会自动把时钟网络标记为propagated也就是说从这一刻开始所有时序分析都会基于真实插入的时钟树延迟而不是之前的理想估算。这时候切回Func视图做后续的post-CTS优化和时序收敛才是正确的流程。set_analysis_view -setup {func_view} -hold {func_view} update_analysis_view # 确认时钟已变成propagated report_clock -view func_view # 检查CTS后的时序总览 time_design -pre_route -num_static_paths 50关于ideal和propagated我多说一句。不是“切回Func视图时手动把时钟变成propagated”而是CTS完成之后设计内部的状态已经变了。如果你发现切回func_view后时钟还是ideal大概率是CTS没有真正成功或者设计状态出了问题这时候应该回头检查clock_design是否正常完成而不是手动去设什么propagated属性。切换回Func视图之后原本func.sdc里的clock uncertainty、latency这些约束会重新生效。所以一个很常见的现象是在cts_view下看数据的skew很好时序也很漂亮一切回func_viewsetup和hold slack立刻变差不少这就是uncertainty被重新加回去导致的。这不是流程有bug而是约束意图的回归不必慌。CT S完成后的Func视图时序检查要重点看三类路径寄存器到寄存器的setup和hold。输入端口到寄存器的路径检查input delay是否合理。寄存器到输出端口的路径检查output delay是否覆盖。如果这些路径上有明显违例先回到时钟树报告里确认对应时钟域的skew和insertion delay再决定是优化时钟树还是优化逻辑路径。3.5 步骤五把视图切换固化到Flow脚本里避免ECO阶段“手滑”最后一个步骤也是最容易被忽略的不要依靠手工敲命令来管理视图切换把它固化到脚本里。为什么因为一个项目周期里视图切换会发生很多次Place阶段用func_view、CTS阶段切到cts_view、CTS后又切回func_view、ECO阶段还要再切到eco相关的view。手工敲命令很容易搞错顺序尤其在赶项目的时候少敲一条update_analysis_view都很常见而这类错误往往不是立刻暴露的直到第二天发现时序报告和昨天的对不上才回头查原因。下面是我平时用的一小段脚本框架供参考# switch_view.tcl —— 视图切换工具脚本 proc switch_view {mode} { switch $mode { func { set_analysis_view -setup {func_view} -hold {func_view} } cts { set_analysis_view -setup {cts_view} -hold {cts_view} } scan { set_analysis_view -setup {scan_shift_view} -hold {scan_shift_view} } default { puts Error: unknown mode $mode return } } update_analysis_view report_analysis_view -verbose }有了这个脚本在流程里切换视图只需要调用switch_view cts或switch_view func每次都自动执行update和report避免漏掉关键步骤。同时脚本里对视图的命名做了集中管理后续要加新的mode只改一处。3.6 多模式场景下CTS与Func约束的联动管理真实项目里往往不止Func和CTS两个模式还会有scan_shift、scan_capture、mbist等。每个模式都有各自的SDC约束而CTS阶段需要保证“所有需要真实时钟树的模式”都被覆盖到。举个例子扫描链shift模式需要扫描时钟组成的时钟树如果CTS时只综合了func时钟而没综合scan时钟那么后续scan shift模式的时序分析就是空的——时钟都没有路径全崩。所以多模式项目的CTS视图通常会同时把func和scan的SDC都挂进来或者为每个模式建立独立的CTS视图。这时候视图管理就更复杂了。我的建议是建一个“视图-约束-用途”的对照表放在flow说明文档里每次跑流程前先看一眼当前视图和用途是否匹配。这一步看着繁琐但可以省掉后面大量的排错时间。4. 切换过程中我踩过的坑以及完整排查的思路前面五步讲的是标准流程但实际项目里几乎不可能一帆风顺。下面我把这几年在Innovus里做CTS与Func SDC切换时踩过的坑挑了几个典型的连同排查思路一起写出来。你如果遇到类似问题直接按这个链路走。4.1 坑一CTS做完后skew很大根因是uncertainty没从cts.sdc里去掉这个坑我在开头提过这里把完整过程说一下。现象是CTS跑完后report_clock_treeskew远大于预期而且insertion delay也偏大buffer数量比同类模块多出不少。一开始我以为是CTS的option没设好反复调max_transition和max_fanout效果都不理想。排查链路查看report_clock_tree -summary确认skew和insertion delay的具体数值。查看当前视图是不是cts_view确认SDC挂的是哪一份。用report_constraints -view cts_view查看时钟相关约束。发现问题cts.sdc里保留着从func.sdc复制过来的set_clock_uncertainty 0.5。根因清楚了。工具把0.5ns当成了时钟树的skew目标于是拼命优化但物理上却无法收敛到那么小的skew只能靠加buffer硬凑结果树越拉越长。处理方式也简单从cts.sdc里删掉uncertainty重新跑一遍CTSskew立刻恢复正常范围。4.2 坑二切回Func视图后时钟还是ideal时序报告异常乐观这个现象我是在另一个项目里遇到的。CTS已经跑完了切回func_view做time_design结果报告非常干净所有slack都是正数而且正得像假的一样。直觉告诉我哪里不对我就去查clock报告。现象是report_clock显示时钟状态还是ideal。正常情况下CTS跑完之后时钟应该标记为propagated。继续往下查发现CTS其实没有真正完成clock_design命令报了一个critical warning后就退出了但我没有留意terminal输出。排查链路Report_clock查看时钟状态发现ideal立刻警觉。回到log里搜“warning”“error”找到clock_design中断的线索。修复了CTS之前遗留的dont_touch子树和stop_pin冲突问题重新跑CTS。CTS正常完成后时钟状态变为propagated时序报告也变成了合理范围。这个坑的核心教训是不要只看时序报告遇到异常乐观的结果先确认时钟状态是不是propagated。4.3 坑三generated clock在CTS视图里推不出来有一个模块里用了分频时钟func视图下generated clock能正常识别但切到cts_view后report_clocks里找不到这个generated clock。这直接导致后续CTS对该分频时钟域完全没建树时序分析全部落空。排查链路用report_clocks -view cts_view确认缺失的时钟。检查cts.sdc里是否定义了对应的master clock结果发现master clock在但generated clock定义被误删了。检查generated clock的source pin路径从master clock到divider的CLKOUT之间是否因为set_case_analysis把某个MUX固定到了错误的方向导致时钟路径被切断。修正cts.sdc里的时钟定义和case analysis重新加载视图后正常。这里想提醒的是在裁剪Func.sdc生成cts.sdc时“减法”要谨慎尤其是generated clock定义删掉之前一定要确认它对应的时钟路径在当前视图下仍然存在。最保险的做法是先源用原func.sdc做一次时钟树综合前的仿真检查确认所有generated clock都能推出来再执行裁剪。4.4 坑四切换视图后数据版本不一致导致前期的Place结果被意外打散这不是SDC本身的问题而是流程管理的问题。有一次我在CTS前的func_view下做完了一部分placement然后手工切到cts_view去跑时钟树因为视图切换时没有同步保存design导致CTS完成后切回func_view时数据的某些状态和之前不一致工具重新优化布局把之前的placement结果打散了。排查链路发现post-CTS优化后模块面积和绕线密度异常怀疑数据版本不对。检查保存的design快照和当前内存里的数据版本确认CTS前后没有加载到同一份数据。修正流程每次切换视图前先保存一份design快照CTS前后用同一个session继续避免跨session加载数据。这个问题看起来蠢但确实容易在赶项目时发生。视图切换的操作本身不会丢失数据但如果你在一个新开的session里加载了不同的design快照又用了另一套视图定义前后就会出现不一致。所以流程脚本里建议把“保存快照”和“切换视图”绑定在一起执行少一步都不行。4.5 一个完整的排错思路模板把上面这些坑串起来我逐渐形成了一个固定排错思路分享给各位第一步查视图report_analysis_view确认当前生效的是哪个viewSDC挂的是哪份。第二步查时钟report_clocks确认时钟定义完整状态是ideal还是propagatedgenerated clock有没有推出。第三步查约束report_constraints确认uncertainty、latency、例外是否和当前阶段的约束意图一致。第四步查数据确认design快照版本和流程阶段匹配。第五步查日志回到log里搜warning和error关注clock_design是否有异常中断。这五步下来绝大多数CTS与Func SDC切换相关的问题都能定位到根因。5. 一些个人经验和小建议话说到这基本把CTS与Func模式SDC切换的核心内容讲完了。最后分享一点个人习惯给正在做Innovus后端的同行参考。我个人的体会是CTS和Func SDC切换这件事真正难的从来不是命令怎么写而是你能不能理解“当前阶段的约束意图是什么”。Func阶段的约束是估算、是余量、是指导布局CTS阶段的约束是构建、是物理目标、是树形控制。你一旦把这个问题想透写cts.sdc、建view、做切换全部都是顺理成章的事情。还有一个经验项目启动第一天就把SDC目录、视图名称、切换脚本、报告输出路径这些基础架构搭好后面会省出至少两三天排错时间。我见过太多项目做到一半才开始补流程结果视图命名混乱、SDC文件东一个西一个到最后谁都不敢动这些文件。如果你正处在项目初期请务必重视这块。如果你也在这个流程里踩过什么特别的坑或者有更好的视图管理经验欢迎私下交流。后端这一行经验都是靠一个一个坑堆出来的。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

TensorRT Model Optimizer高级技巧:自定义量化策略与性能调优指南 2026/9/25 3:47:38

TensorRT Model Optimizer高级技巧:自定义量化策略与性能调优指南

TensorRT Model Optimizer高级技巧:自定义量化策略与性能调优指南 【免费下载链接】Model-Optimizer A unified library of SOTA model optimization techniques like quantization, distillation, pruning, neural architecture search, speculative decoding, etc…

阅读更多 →
哈工大SSE练习39:C语言在线评测从拆题到AC的完整指南 2026/9/25 3:47:31

哈工大SSE练习39:C语言在线评测从拆题到AC的完整指南

看到标题里的“SSE”,先别急着把它跟前端那个 Server-Sent Events 对应起来。在哈工大,SSE 是同学们对 C 语言课程那个在线编程练习平台的约定俗成叫法。不管是软件学院还是计算学部的同学,大一学 C 语言基本都绕不开在这上面刷题。系统界面不…

阅读更多 →
conventional-changelog-writer 版本演进全解析:从 v1 到 v9 的架构变迁与配置项深度指南 2026/9/25 3:47:31

conventional-changelog-writer 版本演进全解析:从 v1 到 v9 的架构变迁与配置项深度指南

开发工具CLI文档 【免费下载链接】conventional-changelog Generate changelogs and release notes from a projects commit messages and metadata. 项目地址: https://gitcode.com/gh_mirrors/co/conventional-changelog 点击查看 免费下载 本文以 packages/conv…

阅读更多 →
ESP32上WASM为何不能直接调用硬件:架构设计与安全隔离 2026/9/25 3:47:25

ESP32上WASM为何不能直接调用硬件:架构设计与安全隔离

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

阅读更多 →
sliver 项目 vendored 的纯 Go xz 压缩库:ulikunitz/xz 开发路线图(TODO.md)与实现解析 2026/9/25 3:47:19

sliver 项目 vendored 的纯 Go xz 压缩库:ulikunitz/xz 开发路线图(TODO.md)与实现解析

网络安全 【免费下载链接】sliver Adversary Emulation Framework 项目地址: https://gitcode.com/gh_mirrors/sl/sliver 点击查看 免费下载 导读 vendor/github.com/ulikunitz/xz/TODO.md 是 Go 语言 xz 压缩库 ulikunitz/xz 的开发者路线图与发布日志&#xff0…

阅读更多 →
GrowthBook Mintlify 文档编写规范:MDX Frontmatter YAML 引号规则与 CI 强制校验 2026/9/25 3:47:12

GrowthBook Mintlify 文档编写规范:MDX Frontmatter YAML 引号规则与 CI 强制校验

后端前端数据分析数据可视化 【免费下载链接】growthbook Open Source Feature Flags, Experimentation, and Product Analytics 项目地址: https://gitcode.com/gh_mirrors/gr/growthbook 点击查看 免费下载 GrowthBook 的官方文档以 Mintlify MDX 页面形式存放于…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉