尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

FPGA时钟设计:Vivado PLL配置与差分时钟输入实战指南

FPGA时钟设计:Vivado PLL配置与差分时钟输入实战指南 我把这几年在 Vivado 里折腾 PLL 踩过的坑、翻过的车以及最终稳定跑通的一套流程整理了出来。这篇文章不打算讲太多锁相环的底层数学原理重点放在 Vivado 2020.2 里如何一步步配置 PLL IP 核尤其是差分时钟输入怎么处理以及最后怎么上板验证。如果你正在被时钟问题折磨或者刚接触 FPGA 想用 PLL 但不知道从哪里下手这篇内容应该能帮你省下不少时间。1. PLL IP核配置前先搞清楚这四件事1.1 为什么要用PLL而不是直接分频很多新手拿到板子第一反应是用寄存器写个计数器分频觉得又简单又不用碰 IP 核。这个思路在低速、对时序不敏感的场景下确实能用但一旦涉及高速接口、ADC/DAC 采样、DDR 读写计数器分频的方案就完全扛不住了。原因其实不复杂。计数器分频输出的是普通逻辑信号它走的是通用布线资源抖动jitter大而且和全局时钟网络的相位关系不可控。PLL 则完全不同它内部有鉴频鉴相器、电荷泵、压控振荡器和反馈分频器构成的闭环系统输出时钟是和输入时钟严格锁相的相位差基本恒定抖动也小得多。形象点说计数器分频是拿秒表掐时间PLL 是拿一根刚性连杆跟着输入时钟同步转稳定性和精度完全不是一个量级。另外PLL 还能做频率合成。输入一个 50MHz 的板载时钟PLL 能给你倍频出 200MHz、300MHz 甚至更高频率的核内工作时钟这是纯逻辑分频做不到的。在 FPGA 里跑高速逻辑比如 DDR 控制器、SerDes 收发器、图像传感器 MIPI 采集几乎都离不开MMCM/PLL提供的干净时钟。1.2 差分时钟输入到底特殊在哪里如果你用的是开发板自带的单端有源晶振比如 50MHz、100MHz 这种接到 FPGA 的MRCC或SRCC引脚就行配置 PLL 时选Single ended clock capable pin一切都比较简单。但实际项目里很多高速接口板卡、射频收发板、光纤通信模块上的参考时钟都是差分输出的最常见的是 LVDS 电平标准的差分时钟。差分信号用两根线传一根正一根负接收端比较的是两根线的电压差。这样做的好处是抗共模干扰能力强长距离传输时信号质量明显优于单端。那么问题来了FPGA 内部是单端逻辑差分时钟进来之后怎么办答案是用IBUFDS原语把差分信号转换成单端信号然后再送入 PLL。当你使用 Clocking Wizard 配置 PLL 时如果输入时钟源选的是Differential clock capable pinVivado 会自动在 IP 里例化好IBUFDS你不用手动写原语。但这里有个让人踩坑的点差分时钟不是随便接到哪两个引脚都行的。在 FPGA 的引脚上差分时钟必须接到芯片上专门支持差分输入的时钟引脚对比如 Xilinx 7 系列 FPGA 上IO_LXXP_TXX_MRCC和IO_LXXN_TXX_MRCC这种成对的引脚。如果接到普通差分 IO 对而 FPGA 型号不支持从该位置引入时钟综合和布局布线阶段会报错。所以第一步永远是查原理图确认板子上的差分时钟到底接到了哪个 Bank、哪个引脚对。1.3 用 clocking wizard 还是直接例化 PLLVivado 里配置锁相环有两种常见方式直接用PLLE2_BASE或PLLE2_ADV原语手动例化并配置参数使用Clocking WizardIP 核在 GUI 界面里配置我的建议很直接新手上路用 Clocking Wizard老手也建议先用 Clocking Wizard 生成一个初始配置再去看生成的 HDL 里原语是怎么例化的。原因很简单PLL 原语的参数极多CLKFBOUT_MULT、DIVCLK_DIVIDE、CLKOUT0_DIVIDE、BANDWIDTH、COMPENSATION这些参数相互关联直接手写很容易出错。Clocking Wizard 的价值在于它会在 GUI 界面里实时计算 VCO 频率范围告诉你哪些组合合法、哪些非法这就是新手最需要的护栏。Clocking Wizard 本质上就是帮你生成了一段包含PLLE2_ADV原语例化、时钟缓冲器、可能的IBUFDS在内的 HDL 代码。图形界面配置完后生成的代码其实还是那些原语但配置的合法性已经被工具帮你校验过了。1.4 生成 IP 前的关键信息清单在实际动手打开 Vivado 之前建议先把以下信息列一个清单免得配置到一半卡住输入时钟频率是多少单端还是差分差分时钟的话具体是哪个引脚对Bank 电压是多少需要输出几路时钟每路频率多少是否有相位偏移需求比如输出时钟和输入时钟差 90°、180°是否需要动态相移、重配置等功能不需要就选简单的PLL而不是MMCM我把这些信息写在纸上或者记在文本文件里再打开 Vivado操作起来顺畅很多不用反复切界面查原理图。2. Vivado 2020.2里的PLL配置实操2.1 新建工程和IP核的基本操作Vivado 2020.2 的 IP 核配置界面比早期版本做得友好不少但操作入口还是那几步。打开 Vivado创建新工程或者打开已有工程在左侧 Flow Navigator 找到IP Catalog搜索Clocking Wizard双击打开配置界面。有一点值得注意在IP Catalog里会看到Clocking Wizard和Clocking Wizard (UI)两个条目。如果你只是做基础 PLL 配置选简单版就行。UI 版本带的是 AXI4-Lite 接口的动态重配置功能对新手来说反而增加了使用门槛。配置界面打开后第一页Clocking Options主要是设置输入时钟。Input Clock Information区域里Input Clock选择Differential还是Single endedInput Clock Frequency填上实际频率比如 125.0Input Clock Jitter保持默认即可如果板子时钟质量差可以适当调大下面有个容易忽略的选项Source选External还是Global buffer。如果你的时钟经过引脚直接进入 PLL选External如果在进入 PLL 之前已经通过 BUFG 进入了全局时钟网络选Global buffer。这里选错有可能导致布线时报错或者时钟根本起不来。按绝大多数情况差分时钟直接进引脚时选External是正确的。2.2 输出时钟参数怎么填才合理配置输出时钟时很多人不看 VCO 频率范围直接乱填输出频率填 50MHz、75MHz、125MHz 各种值结果 Vivado 报错或者生成之后工作不正常。这里需要理解一个核心约束PLL 内部的 VCO压控振荡器有一个固定的允许范围。7 系列 FPGA 的 PLL 的 VCO 频率范围通常在 800MHz 到 1600MHz 之间不同速度等级有差异。PLL 的工作逻辑是输入时钟先经过一个预分频器D然后鉴频鉴相器把压控振荡器输出的反馈时钟和输入参考时钟比较VCO 频率需要等于输入频率除以 D 再乘以 M反馈倍频系数最终输出频率是 VCO 频率除以 O输出分频系数。通俗地讲F_vco F_in / D * MF_out F_vco / O。因此 D、M、O 三个数值必须让 VCO 落在合法范围内。Clocking Wizard 的好处是它会自动帮你算你只需要在Output Clocks页面填写目标频率Vivado 会在这个频率附近自动寻找合法的 M、D、O 组合。如果你的目标频率落在 PLL 可实现范围内界面上会显示绿色勾。在配置输出时钟时还有两个经常被忽视的选项Clock Output Source可以选择PLL还是MMCM的输出一般来说不用动Used For如果某路时钟是给高速收发器用的可以在这里声明工具会自动优化走线对于Phase和Duty Cycle初学者保持 0 度和 50% 即可除非你的设计明确需要特定相位关系。2.3 差分时钟输入在IP核里的正确配置这是整篇文章最容易被忽略但也是最关键的部分。当你在Clocking Options页面把输入时钟类型选成Differential之后Clocking Wizard 生成的文件里会自动多出一个IBUFDS原语实例。但很多人不知道的是Vivado 在生成 IP 时不会帮你检查差分时钟引脚是否接到了支持差分输入的位置。实际操作中我遇到过这样的场景板子上的差分时钟接到了普通差分 IO 引脚对而不是MRCC/SRCC引脚。如果该引脚并非时钟 capable pin综合能通过但到了布局布线阶段Vivado 可能报错说该引脚无法布线到全局时钟网络。解决方案有两个方向改原理图把差分时钟挪到支持时钟输入的差分引脚对在差分时钟进入 FPGA 后先用普通的IBUFDS把差分信号转成单端再通过BUFG进入全局时钟网络最后把这个信号作为 PLL 的输入时钟此时 PLL 的输入类型选Single endedSource 选Global buffer方案 2 在工程中实战验证是可行的虽然会多消耗一些布线资源但解决了引脚位置不对的问题。另外要注意差分时钟的引脚约束写法也有讲究。如果差分时钟接到的是IO_LxxP_Txx_MRCC和IO_LxxN_Txx_MRCC引脚对约束文件里只需要约束 P 端引脚N 端会自动匹配。在 XDC 里写法如下set_property PACKAGE_PIN AD12 [get_ports clk_p] set_property IOSTANDARD LVDS [get_ports clk_p]不需要为clk_n单独写约束。但在顶层模块里这两个端口都要暴露出来module top( input clk_p, input clk_n, ... );如果只声明clk_p却漏了clk_n综合时 Vivado 会报错。2.4 复位和locked信号怎么接配置完时钟输出之后Clocking Wizard 的界面里还有Reset和Locked两个信号的配置选项。默认情况下 Reset 是高电平有效Locked 是输出高电平表示锁定成功。这两个信号看起来平平无奇但接错会导致上板后整个系统完全跑不起来。Reset信号必须接一个干净、同步的复位源。如果你直接把板载按键消抖后的脉冲信号接上去PLL 可能会在这个过程中反复复位输出时钟断断续续下游逻辑集体失控。Locked信号一定要接出来并用于整个系统的复位管理。业界常见的做法是系统上电后先让 PLL 锁定Locked 信号拉高后再用这个信号作为全局复位的释放条件。更讲究一点的做法是用 Locked 信号去异步置位复位寄存器再同步释放给各个模块避免复位释放时产生亚稳态。如果 Locked 信号不接你根本不知道 PLL 输出时钟是否稳定后续排查问题会非常被动。3. 从IP核生成到上板实测的完整链路3.1 例化方式和时钟连接配置完成后点击GenerateVivado 会生成一整套 IP 相关文件。例化方式有两种一种是在设计代码里手动实例化 IP 模块另一种是用IP Integrator的 Block Design 里拖拽添加。对于纯 RTL 设计我推荐手动例化代码清晰可控。在生成的.veo文件里能直接看到 IP 的例化模板。以输出两路时钟为例核心的例化代码大致如下clk_wiz_0 u_clk_wiz_0( .clk_out1(clk_100m), .clk_out2(clk_200m), .locked(pll_locked), .clk_in1_p(clk_ref_p), .clk_in1_n(clk_ref_n), .reset(rst_n) );注意端口名称如果选择了差分输入顶层 IP 端口会显示为clk_in1_p和clk_in1_n两个如果是单端输入则只有一个clk_in1。连接时有一个高频踩坑点不要直接用 PLL 输出的时钟去驱动非全局时钟网络的逻辑。如果 PLL 输出的时钟要用来驱动普通逻辑Vivado 会自动插入 BUFG这没问题。但如果你手写代码时把clk_100m连到了普通 IO 输出引脚上Vivado 会报错或警告时钟走线问题。PLL 输出时钟最好只进入全局时钟网络如果需要输出到外部引脚必须经过ODDROBUFDS这种专用输出结构。3.2 仿真阶段怎么验证PLL配置正确上板之前强烈建议先跑行为仿真这一步能拦下大量低级错误。在Sources窗口选中 PLL IP右键选择Open IP Example DesignVivado 会自动生成一个包含仿真 Testbench 的示例工程里面已经有完整的激励可以直接跑仿真。如果不想用官方示例自己写 Testbench 也可以。仿真时要注意PLL 和 MMCM 这类模拟 IP 在行为仿真里有一个锁定时间的模拟通常在几微秒到几十微秒之间。仿真时locked信号不会一上来就拉高需要等待一段时间。简单的 Testbench 写法如下module tb_top(); reg clk_p; reg clk_n; wire clk_100m; wire clk_200m; wire locked; initial begin clk_p 0; clk_n 1; end always #4 clk_p ~clk_p; always #4 clk_n ~clk_n; clk_wiz_0 uut( .clk_out1(clk_100m), .clk_out2(clk_200m), .locked(locked), .clk_in1_p(clk_p), .clk_in1_n(clk_n), .reset(1b0) ); initial begin #1000; if (locked) $display(PLL locked!); else $display(PLL not locked!); #10000; $finish; end endmodule仿真波形里重点看两点locked信号是否最终拉高输出时钟频率是否符合预期比如输入 125MHz输出 200MHz那 5ns 一个周期应该差不多仿真通过后再上板能省掉大量调试时间。不要嫌仿真麻烦直接上板拿示波器看波形一旦不工作反而更浪费时间。3.3 引脚约束与上板实测操作仿真通过后进入综合和实现。打开Constraints添加 XDC 文件这里必须有正确的物理约束。以输入 125MHz 差分时钟、输出给 LED 指示为例set_property PACKAGE_PIN AC12 [get_ports clk_p] set_property IOSTANDARD LVDS [get_ports clk_p] set_property PACKAGE_PIN AC11 [get_ports led_on]写完约束之后运行综合Synthesis再运行实现Implementation。如果 Vivado 报了DRC RTSTAT-2之类的错误大概率是时钟引脚位置不对或者时钟端口没有被正确连接到全局时钟缓冲器。上板调试时有两类工具硬件管理器里的ILAIntegrated Logic Analyzer抓内部信号观察locked状态和输出时钟计数器示波器直接测引脚上的实际时钟波形对于新手推荐先用 ILA。在 IP Catalog 里添加一个 ILA IP把locked信号和一个时钟计数器挂上去设置触发条件为locked上升沿就能看到 PLL 锁定后的实际状态。使用 ILA 需要预先在 RTL 代码里把要观察的信号引到顶层否则综合时这些信号会被优化掉误以为设计有问题。如果是用示波器测时钟输出必须确保时钟信号是通过 ODDR 结构输出到引脚的。直接把 PLL 输出时钟连到普通引脚给示波器看在低速率下也许能出波形但信号完整性和负载驱动能力都没有保障示波器一接可能就测不到了。4. 常见问题排查与避坑实录4.1 vivado报错drc rtstat-2怎么办DRC RTSTAT-2是我在配置 PLL 时遇到最多的一类报错。这个错误的含义通常是时钟信号路径上没有合适的时钟缓冲器或者时钟到达了非时钟引脚。在处理这类报错时按这个顺序排查检查输入时钟是否连接到支持时钟输入的引脚检查 PLL 的输入时钟类型是否和实际连接一致差分还是单端检查 PLL 的输出时钟是否进入了全局时钟网络检查 XDC 里是否有set_property CLOCK_DEDICATED_ROUTE相关的覆盖性约束不建议使用最省事的方法是在面板中直接双击报错信息Vivado 会高亮显示蓝图里对应的路径帮助定位问题。跟随路径找出差异点比盲目改约束要快得多。还有一次我的问题和 Clocking Wizard 无关而是整个工程的复位信号用了独立时钟域在综合时导致时钟域交叉检查报警。花了一上午排查最后发现是复位信号没做异步复位同步释放PLL 锁定后复位才释放但复位释放瞬间系统出现亚稳态。这个问题并不是 PLL 本身引起的而是复位管理不规范建议养成统一用 Locked 管理全局复位的习惯很多时钟相关的奇怪问题会自然消失。4.2 仿真正常但上板不工作的排查思路上板实测时最常见的问题是仿真波形里 PLL 锁定正常输出时钟也符合预期但下载到板子上就是没动静。这种问题的排查顺序一定要讲究效率。我的常用流程是确认locked信号是否拉高。如果没拉高回到时钟输入和复位检查确认reset信号的电平是否和 IP 配置一致。Clocking Wizard 默认是高有效复位如果你在代码里接的复位信号是低有效就等于一直按着复位不放PLL 永远不工作检查是否生成了正确的比特流。Vivado 的硬件管理器里查看programmed状态用 ILA 抓内部信号而不是靠 LED 瞎猜我见过一个真实的案例同事配置 PLL 输出 200MHz 时钟驱动逻辑仿真正常上板后用 ILA 抓到的时钟频率却只有 100MHz。折腾半天发现是 XDC 里对某个普通端口用了set_property CLOCK_DEDICATED_ROUTE ANY_CMT_COLUMN的写法把 PLL 的输出时钟通过非优化路径布线到了逻辑实际上时钟频率对了一半波形严重失真。去掉这个约束后一切正常。4.3 配置差分时钟时常见的隐藏坑先说一个最容易被坑的XDC 里只写了 P 端引脚约束但顶层端口没有把 N 端也引出来。综合时报[Synth 8-3331] port clk_n not found一脸懵。解决方式很直接顶层端口必须同时声明clk_p和clk_n。另外差分时钟引脚对的IOSTANDARD要统一设置成LVDS不要一高一低。还有一类问题出在 Bank 电压上。7 系列 FPGA 的 HR Bank 和 HP Bank 支持的差分标准不同HP Bank 支持更高速率的 LVDSHR Bank 支持 1.8V-3.3V 的宽范围电压。如果板子的时钟 Bank 供电是 3.3V 而你在约束里写LVDSVivado 在生成比特流时会报电压不兼容的错误。遇到这种情况要么改原理图换 Bank要么改用LVDS_25等兼容电平具体查数据手册为准。另外还有一个被很多人忽略的操作细节在Clocking Wizard中配置输入时钟时默认会勾选MMCM而不是PLL。如果明确需要用 PLL可以在Clocking Options页面底部把Clocking Structure从MMCM改成PLL。MMCM 和 PLL 功能相似但资源不同MMCM 有动态相移和更宽的分频范围但 VCO 工作范围略有差异。在新手阶段PLL 就够用了真用到 MMCM 的时候一般你也知道为什么选了。4.4 现场问题速查表现象可能原因排查思路locked 一直不拉高复位信号电平接反核对 IP 配置的复位极性locked 不拉高且 reset 没问题输入时钟没进来用 ILA 抓输入时钟看引脚约束是否错误仿真不锁定输入时钟频率填错检查 Clocking Wizard 里 Input Frequency 是否与 Testbench 一致上板时钟频率不对约束覆盖了时钟路径查找CLOCK_DEDICATED_ROUTE约束上板后无输出时钟PLL 未锁定就使用输出必须等待 locked 信号有效后再使用输出时钟ILA 抓不到任何信号信号被综合优化掉了在 RTL 里加(* mark_debug true *)属性差分时钟有时钟但 PLL 无反应IBUFDS 没有正确例化核对 IP 配置是否选择 Differential 输入类型Vivado 布局布线报错时钟引脚不是时钟 capable pin查原理图确认引脚位置或改走 BUFG 方案这张表我每次做新板卡调试都会先过一遍很多问题其实都是同一类原因。5. 上板实测记录与调试心得5.1 一个完整的上板实测案例我用一块搭载 Xilinx Artix-7 系列 FPGA 的开发板做过一次完整的 PLL 上板测试。板载时钟源是一颗 125MHz 的差分晶振通过 LVDS 引脚对连接到 FPGA 的时钟专用引脚。在配置 Clocking Wizard 时输入类型选Differential输入频率填 125MHz输出配置为两路一路 200MHz 给逻辑主时钟一路 25MHz 给外设接口。Vivado 自动计算出 VCO 频率 1000MHzD1、M8、O15、O240完全落在合法范围内。上板实测时我在顶层模块里把locked信号和 200MHz 时钟的 2 分频信号都引到了 ILA。抓取波形后发现PLL 从复位释放到 locked 拉高大约花了 6.8 微秒200MHz 时钟的频率计显示为 200.003MHz误差主要来自示波器本身在可接受范围内。随后我做了一个简单的测试用 PLL 输出的 200MHz 时钟驱动一个从 0 计数的 32 位计数器再通过串口每隔一段时间把计数值发回上位机。通过对比时间戳和计数值可以间接验证 200MHz 时钟的稳定性。跑了半小时计数没有出现跳变或者累计误差说明 PLL 工作稳定。5.2 实测过程中遇到的一个异步复位释放问题有一个特别隐蔽的坑想单独拿出来说——异步复位同步释放。我在第一次上板实测时直接用了开发板上的一个按键输出作为 PLL 的reset输入按键按下为低电平而 PLL 的 reset 是高有效所以我加了一个反相器。仿真完全正常但上板后 PLL 经常锁定失败或者锁定后过一段时间自动失锁。用示波器看按键波形才发现按键按下释放的瞬间波形有大约 10-20ms 的抖动这个抖动直接进到了 PLL 的复位端相当于对 PLL 进行了一次随机复位。等到按键抖动结束PLL 重新锁定但系统里的其他模块已经处于混乱状态。解决方式就是所有外部按键、拨码开关信号先做同步和消抖处理再进入设计。PLL 的复位信号必须来自稳定的逻辑信号——最简单的方法是在内部产生一个上电复位计数器计数到某个值后释放复位或者直接使用系统 Locked 信号作为自己逻辑的复位。5.3 关于 Locked 信号的一个反常识认知很多人以为 PLL 的locked信号拉高就万事大吉输出时钟立即稳定可用。实际上locked拉高后输出时钟还有一小段短暂的稳定时间。在高速设计中如果你在locked上升沿的同一个时钟周期立刻开始采数据有极小概率采到不稳定的时钟沿。工程上常见做法是locked拉高后再用它驱动一个同步释放的复位逻辑让后续模块再等几个时钟周期才开始工作。这相当于给系统加了一层保险成本几乎为零但能避免很多幽灵般的偶发问题。6. 一个实用的模版工程片段最后分享一个我在新项目里固定使用的 PLL 例化模板包含了复位管理、Locked 处理、计数器验证三个部分。这个模板我在多个项目里复用稳定性很好。module clk_ctrl( input wire clk_ref_p, input wire clk_ref_n, input wire sys_rst_n, output wire clk_200m, output wire clk_25m, output wire pll_locked, output wire [31:0] counter_out ); wire rst_n_sync; reg [3:0] rst_cnt; reg rst_n_pll; // 上电复位计数器延时释放复位 always (posedge clk_200m or negedge sys_rst_n) begin if (!sys_rst_n) begin rst_cnt 4d0; rst_n_pll 1b0; end else if (rst_cnt 4d15) begin rst_cnt rst_cnt 1b1; rst_n_pll 1b0; end else begin rst_n_pll 1b1; end end clk_wiz_0 u_clk_wiz_0( .clk_out1(clk_200m), .clk_out2(clk_25m), .locked(pll_locked), .clk_in1_p(clk_ref_p), .clk_in1_n(clk_ref_n), .reset(~rst_n_pll) // 注意PLL reset高有效 ); // 用Locked信号做系统复位异步复位同步释放 reg [1:0] locked_r; always (posedge clk_200m or negedge pll_locked) begin if (!pll_locked) locked_r 2b00; else begin locked_r[0] 1b1; locked_r[1] locked_r[0]; end end assign rst_n_sync locked_r[1]; // 正常工作的计数器 reg [31:0] cnt; always (posedge clk_200m or negedge rst_n_sync) begin if (!rst_n_sync) cnt 32d0; else cnt cnt 1b1; end assign counter_out cnt; endmodule这个模板有三个值得借鉴的设计第一PLL 的reset不是简单地接按键而是经过一个上电复位计数器延时释放减少毛刺影响。第二系统逻辑的复位不是直接用locked而是把locked经过两级触发器同步后再作为复位释放信号这就是前面提到的“异步复位同步释放”标准写法。第三计数器只是作为验证手段实际项目里你可以替换成自己的业务逻辑。如果你拿到一个新板子不确定 PLL 部分是否工作直接用这个模板综合生成比特流看 ILA 里的pll_locked信号和计数器是否正常递增比从头调试省心得多。另外提醒一点这个模板里的clk_wiz_0是你用 Clocking Wizard 生成的 IP 名字新项目里注意改成你自己的 IP 实例名。在配置差分时钟的过程中我踩过最深的一个坑是选错了输入时钟类型GUI 里选成了Single ended但实际板子是差分时钟结果综合、布线全通过上板后 PLL 就是不锁定。后来用 ILA 抓时钟引脚才发现输入时钟根本没有正确转换。时间花了大半天原因只是界面里的下拉菜单选错了一项。所以配置完之后一定要打开生成的 HDL 代码看一眼确认里面有没有IBUFDS原语有的话才说明差分输入配置正确。最后说一个个人习惯每次生成完 PLL IP我都会在工程目录下保留一份配置截图和关键参数说明尤其是输入时钟类型、输出频率、复位极性和 Locked 信号连接方式。因为过几个月回来看这个工程时单看代码很难快速回忆起当初的配置思路但参数笔记能让你三分钟内进入状态。这个习惯帮我省了很多次重新排障的时间建议你也可以试试。
返回列表