ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

FPGA在线调试实战:SignalTap与ISSP高效定位时序问题

FPGA在线调试实战:SignalTap与ISSP高效定位时序问题 1. 为什么在线调试值得单独拿出来讲做FPGA开发的人都有一个共同的痛点综合、布局布线、生成比特流一套流程跑下来少则十几分钟多则一两个小时。结果板子跑起来行为不对你只能靠猜——是逻辑写错了是时序没收敛还是引脚约束搞错了传统做法是改代码、加计数器、引到LED或者预留测试引脚上再重新编译一遍。一轮下来半天没了效率极低。Quartus提供的在线调试能力核心就是解决这个问题的。它让你在不重新编译整个工程的前提下直接读取FPGA内部信号的状态甚至实时修改寄存器的值。这里面最常用的两个工具就是SignalTap II Logic Analyzer简称SignalTap和In-System Sources and Probes简称ISSP。前者相当于把一台逻辑分析仪塞进了FPGA内部后者相当于给你一组可以远程操作的拨码开关和LED指示灯。这篇文章适合谁看如果你已经能跑通Quartus的基本流程会写Verilog或VHDL能下载比特流到板子上但还没系统用过在线调试工具那这篇就是写给你的。如果你已经用过SignalTap但只会“抓波形”不知道ISSP怎么配合使用或者遇到过采样深度不够、信号被优化掉、JTAG链识别不到器件这些问题这篇文章也会覆盖到。我下面会从设计思路、工具原理、实操步骤、常见问题四个维度展开把这两个工具的使用方法讲透。所有操作基于Quartus Prime Standard/Lite版本老版本的Quartus II操作逻辑基本一致差异我会单独标注。2. 两个工具的整体设计与选型思路2.1 SignalTap和ISSP各自解决什么问题先把这个事情说清楚很多人搞混这两个工具的定位。SignalTap的本质是一个嵌入式逻辑分析仪。它在FPGA内部例化一块Block RAM作为采样缓冲区按照你设定的时钟域和触发条件把指定信号的波形采集下来然后通过JTAG接口上传到Quartus的波形窗口里显示。你看到的就是真实的时序波形和外部逻辑分析仪抓出来的效果一样只不过采样点是FPGA内部的信号。ISSP的本质是一组虚拟的输入输出端口。它提供两种资源Sources源可以驱动FPGA内部信号相当于你在Quartus界面里拨动一个开关FPGA内部对应的信号就变了Probes探针可以读取FPGA内部信号的值相当于在Quartus界面里看到一个实时更新的状态指示。它不采集波形只反映当前时刻的值。两者的核心区别用一句话概括SignalTap看的是历史波形ISSP操作的是当前状态。那为什么两个都要用因为在实际调试中你往往需要“先看后改”。比如你在调一个状态机先用SignalTap抓到状态跳转的异常时刻发现某个控制寄存器的值不对这时候用ISSP直接把这个寄存器的值改掉观察系统行为是否恢复正常。如果正常了说明问题定位准确如果不正常继续用SignalTap抓下一轮波形。这个“抓-改-抓”的循环是在线调试的精髓。2.2 为什么不用外部逻辑分析仪有人会问我手上有示波器和逻辑分析仪为什么要用片上的第一引脚不够。FPGA的可用IO是有限的你要抓16根内部信号就得引出16个引脚还要考虑引脚分配、电平标准、PCB走线。很多时候根本没有那么多空闲引脚。第二信号完整性。内部信号引到引脚上经过IO缓冲器、PCB走线、探头波形已经变形了。你看到的上升沿可能不是真实的上升沿。片上采样不存在这个问题采的就是FPGA内部的实际值。第三触发条件复杂。外部逻辑分析仪的触发条件通常比较简单而SignalTap支持多级触发、状态机触发可以设置非常复杂的触发序列比如“信号A上升沿之后信号B连续3个时钟为高然后信号C出现下降沿”这种条件。第四成本。SignalTap和ISSP都是Quartus自带的功能不需要额外硬件只需要一根JTAG下载线。当然SignalTap也有代价它消耗FPGA内部的Block RAM和逻辑资源。采样深度越大、采样信号越多消耗的资源就越多。这个后面会详细讲怎么权衡。2.3 资源消耗的预估与权衡在动手之前你需要对资源消耗有个基本概念。SignalTap消耗的资源主要包括三部分采样缓冲区存储在Block RAM里。采样深度的计算公式是缓冲区大小 采样深度 × 采样信号总位宽。比如你抓32根信号采样深度设为1024那需要的RAM就是 1024 × 32 32768 bit 4 KB。一个M9K Block RAM是9216 bit所以大概需要4个M9K。触发逻辑用LELogic Element实现通常几百个LE。JTAG通信逻辑也是LE实现固定开销。ISSP消耗的资源相对小很多主要是JTAG通信逻辑和少量的寄存器通常几十到一百多个LE。注意SignalTap的采样缓冲区会占用Block RAM如果你的设计本身RAM就很紧张可能需要降低采样深度或者减少采样信号数量。一个技巧是只抓关键信号不要贪多。选型建议如果你的FPGA资源比较充裕比如Cyclone IV以上逻辑单元超过10K可以放心用。如果是资源很紧张的小器件优先用ISSP因为它消耗小而且很多时候你只需要看几个关键寄存器的值不需要完整波形。3. SignalTap的核心细节与实操要点3.1 SignalTap的工作原理SignalTap的架构可以分成三个部分来理解。采样前端在你指定的采样时钟上升沿所有被选中的信号值被锁存到一个寄存器组里。这个寄存器组的位宽等于所有采样信号的位宽之和。触发逻辑每个采样时钟周期触发逻辑会检查当前采样值是否满足你设定的触发条件。如果满足就开始把后续的采样值写入Block RAM缓冲区。触发条件可以是简单的信号电平比较也可以是多级触发序列。存储与上传采样数据存入Block RAM后通过JTAG接口上传到PC端的Quartus软件。上传速度取决于JTAG时钟频率通常几秒钟就能传完。这里有一个关键点采样时钟的选择。采样时钟必须是设计中真实存在的时钟信号而且这个时钟必须在采样期间持续运行。如果采样时钟停了SignalTap就抓不到任何数据。另外采样时钟的频率决定了你能抓到的信号最高频率——根据奈奎斯特采样定理采样频率至少是被测信号频率的2倍实际工程中通常建议5倍以上。3.2 创建SignalTap文件的完整步骤第一步在Quartus中打开你的工程确保工程已经成功编译过一次需要知道信号名称和层次结构。第二步通过菜单File - New - SignalTap II Logic Analyzer File创建一个新的.stp文件。也可以直接在工具栏上点SignalTap的图标。第三步在SignalTap编辑器里设置采样时钟。点击Setup标签页在Clock栏点...按钮从工程中所有可用时钟列表里选择你要用的采样时钟。通常选择被测逻辑的主时钟。第四步添加采样信号。在Setup标签页的Signal区域双击空白处会弹出Node Finder窗口。这里有个技巧先把Node Finder的Filter设为“SignalTap II: pre-synthesis”这样可以看到综合前的信号名包括被综合器优化掉的信号。如果你选“post-fitting”有些信号可能已经不存在了。第五步设置采样深度。在Setup标签页的Sample depth下拉框中选择。可选值通常是128、256、512、1024、2048、4096等。采样深度越大能观察的时间窗口越长但消耗的RAM越多。第六步设置触发条件。在Setup标签页的Trigger列每个信号可以设置触发条件Dont Care、Low、High、Falling Edge、Rising Edge、Either Edge。至少有一个信号不能设为Dont Care否则会立即触发。第七步保存.stp文件然后重新编译工程。SignalTap文件需要参与编译Quartus会把采样逻辑和缓冲区插入到你的设计中。第八步编译完成后通过Tools - Programmer下载比特流此时比特流已经包含了SignalTap逻辑然后在SignalTap编辑器里点Run Analysis按钮开始采集。3.3 触发条件的进阶设置基础的电平触发大家都会用但SignalTap真正强大的地方在于多级触发。在SignalTap编辑器的Setup标签页有一个Trigger Flow Control选项可以设置为Sequential顺序触发。设置之后每个信号旁边会出现Trigger和Position两列。你可以把触发条件分成多个阶段第1级信号A上升沿第2级信号B为高电平第3级信号C下降沿只有当前一级条件满足后才会检查下一级条件。这就像写了一个状态机来触发非常适合抓取复杂的事件序列。还有一个实用功能是触发位置。在Trigger标签页的Trigger position设置中你可以指定触发事件在采样缓冲区中的位置。比如设为Center那触发前后的数据各占一半设为Pre-trigger那大部分数据是触发前的设为Post-trigger那大部分数据是触发后的。这个设置决定了你能看到多少“前因”和多少“后果”。3.4 采样深度的计算与资源优化采样深度的选择是一个权衡。深度越大能观察的时间窗口越长但消耗的RAM越多。计算公式时间窗口 采样深度 / 采样时钟频率举个例子采样时钟100 MHz采样深度1024那时间窗口就是 1024 / 100M 10.24 微秒。如果你要观察一个1毫秒的事件那至少需要 100M × 1ms 100000 的采样深度这显然不现实。所以实际做法是用触发条件缩小观察范围。你不需要从头到尾看整个1毫秒只需要看事件发生前后的几百个时钟周期。把触发条件设好采样深度设个1024或2048就够了。如果RAM实在不够还有几个优化方向减少采样信号数量只抓最关键的几位降低采样时钟频率如果被测信号频率不高的话使用分段采样Segmented Buffer把一块RAM分成多段每段独立触发实操心得我通常会把采样深度设为2048触发位置设为Center这样触发前后各1024个采样点对于大多数调试场景够用了。如果不够再针对性调整。3.5 信号被优化掉怎么办这是新手最常遇到的问题明明代码里写了这个信号但在Node Finder里找不到。原因通常是综合器把这个信号优化掉了。比如你定义了一个寄存器但它的值从来没有被其他逻辑使用过综合器就会把它删掉以节省资源。解决方法有几种方法一在Node Finder里把Filter设为“SignalTap II: pre-synthesis”这样可以看到综合前的信号。但注意这些信号名可能和综合后的不一致而且有些信号可能无法被正确映射。方法二在代码里加综合属性阻止综合器优化。Verilog中的写法是(* keep *) reg debug_signal; (* preserve *) reg another_signal;keep属性告诉综合器保留这个信号preserve属性告诉综合器保留这个信号的层次结构。方法三把信号引出到顶层端口但这样会消耗引脚不推荐。方法四把信号接入一个未使用的逻辑比如异或到一个常量上让综合器认为它被使用了。这种方法比较hack但有时候很管用。4. ISSP的使用方法与实战技巧4.1 ISSP的两种资源Sources和ProbesISSP的全称是In-System Sources and Probes它提供两种资源Sources从Quartus界面驱动FPGA内部信号。你可以把它理解为一组虚拟的输入引脚你在Quartus的ISSP编辑器里改变这些“引脚”的值FPGA内部对应的信号就会跟着变。Sources的输出位宽可以配置从1位到几十位都行。Probes从FPGA内部读取信号值到Quartus界面。相当于一组虚拟的输出引脚FPGA内部信号的值会实时显示在ISSP编辑器里。Sources和Probes可以独立使用也可以配合使用。配合使用的典型场景是用Sources驱动一个控制寄存器的输入用Probes读取状态机的当前状态这样你就能在PC端“遥控”FPGA的行为。4.2 在代码中例化ISSPISSP的例化有两种方式通过IP Catalog生成或者直接在代码中例化。通过IP Catalog生成的步骤打开Tools - IP Catalog在搜索框输入“In-System Sources and Probes”双击打开配置界面设置Sources的位宽和Probes的位宽设置JTAG ID多器件链时需要生成IP得到例化模板直接在代码中例化的方式更灵活不需要生成IP文件。以Verilog为例issp_debug u_issp ( .source (source_data), // 输出到FPGA内部位宽由配置决定 .probe (probe_data), // 从FPGA内部输入位宽由配置决定 .source_clk (clk), // Sources的更新时钟 .probe_clk (clk) // Probes的采样时钟 );注意source是ISSP的输出连接到你的逻辑中作为控制信号probe是ISSP的输入连接你要观察的内部信号。4.3 ISSP的典型应用场景场景一动态修改参数。比如你在调一个PWM模块需要测试不同占空比下的效果。传统做法是改代码、重新编译、下载一轮好几分钟。用ISSP的话把占空比寄存器的输入接到Sources上在Quartus界面里直接改数值FPGA立刻响应效率提升几十倍。场景二状态机调试。把状态机的状态编码接到Probes上实时观察状态跳转。配合Sources强制状态跳转可以测试状态机的所有分支。场景三通信协议调试。比如你在调SPI或I2C可以把发送和接收的数据接到Probes上实时观察数据流。用Sources模拟从设备的响应测试主设备的行为。场景四多板卡协同调试。如果系统中有多块FPGA通过JTAG链连接可以用ISSP在不同板卡之间传递调试信息。4.4 ISSP与SignalTap的配合使用单独用ISSP只能看当前值看不到历史变化。单独用SignalTap只能看波形不能实时修改。两者配合起来调试效率会大幅提升。我的常用做法是先用SignalTap抓一段波形定位到异常发生的时刻分析波形找出可疑的控制信号或状态变量把这些信号接到ISSP的Probes上实时观察把相关的控制寄存器接到ISSP的Sources上尝试修改观察修改后的系统行为验证假设这个流程的关键是快速迭代。SignalTap和ISSP都不需要重新编译前提是已经编译过一次并包含了这些调试逻辑所以你可以反复抓、反复改几分钟就能完成一轮调试。注意ISSP的Sources值在JTAG连接断开后会保持最后的值不会自动复位。如果你需要上电默认值需要在代码里做初始化。5. 实操过程中的常见问题与排查5.1 JTAG识别不到器件这是最常见的问题表现为Programmer或SignalTap里看不到FPGA器件。排查步骤检查物理连接USB线是否插好JTAG排线是否接反板子是否上电。这些看似简单的问题实际上占了故障的一半以上。检查驱动在设备管理器里看USB-Blaster是否被正确识别。如果显示黄色感叹号需要重新安装驱动。Quartus安装目录下的drivers文件夹里有驱动文件。检查JTAG链设置如果板子上有多片FPGA或其他JTAG器件需要在Programmer里点Auto Detect扫描链。如果扫描不到可能是链上的某个器件有问题。检查JTAG时钟频率在Programmer的硬件设置里可以调整JTAG时钟频率。频率太高可能导致通信不稳定可以尝试降低到6 MHz或更低。检查电源有些板子的JTAG接口需要单独供电如果FPGA核心电压没起来JTAG也无法工作。5.2 SignalTap采不到数据编译成功、下载成功但SignalTap运行后没有波形。可能的原因采样时钟没有运行如果采样时钟来自PLL而PLL没有锁定时钟就不存在。检查PLL的locked信号。触发条件太严格如果触发条件设置得很难满足可能等很久都触发不了。先把触发条件设为最简单的比如某个信号为高确认能触发后再改复杂。采样时钟频率太低如果采样时钟频率远低于被测信号频率可能采不到有效的跳变。信号被优化前面讲过检查信号是否被综合器优化掉了。5.3 采样数据看起来不对波形抓到了但数据看起来和预期不符。可能的原因采样时钟域不对如果你抓的是另一个时钟域的信号但采样时钟用的是当前时钟域会看到亚稳态或数据错位。确保采样时钟和被测信号是同一个时钟域或者至少频率匹配。触发位置设置不当如果触发位置设为Pre-trigger大部分数据是触发前的你可能看不到触发后的行为。改成Center或Post-trigger试试。信号位宽不匹配比如你抓的是一个8位计数器但只连接了低4位那看到的数据当然不对。5.4 ISSP的Sources不生效在Quartus界面里改了Sources的值但FPGA内部信号没变化。排查检查时钟Sources的更新需要时钟驱动。如果source_clk没有连接或没有运行Sources值不会更新。检查位宽Sources的位宽和你在代码中连接的信号位宽必须一致。检查JTAG连接ISSP需要JTAG连接才能工作。如果JTAG断了Sources值不会更新。检查综合属性如果Sources驱动的信号被综合器优化掉了那改了也没用。5.5 常见问题速查表问题现象可能原因解决方法JTAG识别不到器件物理连接/驱动/时钟频率检查连线、重装驱动、降低JTAG频率SignalTap无波形采样时钟未运行/触发条件太严检查时钟、简化触发条件波形数据异常时钟域不匹配/触发位置不当统一时钟域、调整触发位置信号找不到被综合器优化加keep属性、用pre-synthesis过滤ISSP Sources不生效时钟未连接/位宽不匹配检查时钟和位宽配置采样深度不够RAM资源限制减少信号数、降低深度、用分段采样编译报错资源不足SignalTap占用太多RAM减少采样信号、降低采样深度6. 几个容易被忽略的实操细节6.1 调试逻辑的资源开销要提前规划很多人在项目初期不规划调试资源等到后期发现RAM不够用了才想起来SignalTap占了不少Block RAM。我的建议是在项目架构设计阶段就预留调试资源。比如你的FPGA有30个M9K设计本身用了20个那剩下10个可以留给SignalTap。如果设计本身就要用28个那调试时就得非常节省。一个实用的做法是在顶层模块预留一个调试接口把常用的调试信号时钟、复位、关键状态引到顶层这样后期加SignalTap时不需要改太多代码。6.2 采样时钟的选择有讲究采样时钟不一定要用系统主时钟。如果被测信号的频率较低可以用一个分频后的时钟作为采样时钟这样在同样的采样深度下能覆盖更长的时间窗口。比如系统主时钟100 MHz你要观察一个1 kHz的慢速信号。如果用100 MHz采样1024深度只能覆盖10微秒根本看不到1毫秒周期的变化。但如果用一个100 kHz的时钟采样1024深度就能覆盖10毫秒足够看到10个周期了。当然采样时钟频率必须满足奈奎斯特条件至少是被测信号最高频率的2倍。实际工程中建议5倍以上。6.3 触发条件的组合逻辑SignalTap的触发条件支持组合逻辑。在Trigger标签页你可以设置多个信号的触发条件然后用Trigger Flow Control选择Sequential或Boolean模式。Sequential模式多级触发前一级满足后才检查下一级。Boolean模式所有条件同时满足才触发。Boolean模式适合抓取“多个信号同时满足某个条件”的场景。比如你要抓“state3 且 data_valid1 且 error_flag0”的时刻就可以用Boolean模式。6.4 ISSP的Sources可以做复位源这是一个很实用的技巧把ISSP的Sources连接到系统的复位逻辑上。这样你可以在不重新下载比特流的情况下通过Quartus界面手动触发复位观察系统从上电到稳定的完整过程。具体做法是把Sources的某一位定义为“软复位”在代码里用这个信号和外部复位信号做或运算产生系统复位。调试时在ISSP界面里把这一位置1再置0系统就复位了。6.5 保存和复用调试配置SignalTap的.stp文件和ISSP的配置都可以保存和复用。如果你有多个工程需要调试可以把调试配置导出在新工程里导入省去重新配置的时间。具体操作在SignalTap编辑器里File - Export可以导出触发配置和信号列表。在新工程里File - Import导入即可。注意导入后需要重新映射信号名因为不同工程的信号名可能不同。6.6 在线调试对时序的影响SignalTap和ISSP都会在设计中插入额外的逻辑这可能会影响时序收敛。特别是SignalTap的采样逻辑如果采样信号很多可能会增加关键路径的延迟。我的经验是调试版本和发布版本分开编译。调试时加上SignalTap和ISSP方便定位问题问题解决后去掉调试逻辑重新编译发布版本。不要带着调试逻辑发布既浪费资源又可能影响时序。如果必须在带调试逻辑的情况下满足时序可以尝试以下方法降低采样时钟频率减少采样信号数量把采样逻辑放在单独的时钟域使用set_false_path或set_multicycle_path约束调试逻辑的路径6.7 多器件JTAG链中的调试如果你的板子上有多片FPGA或其他JTAG器件SignalTap和ISSP需要指定目标器件。在SignalTap编辑器的Setup标签页有一个JTAG ID设置需要选择正确的器件ID。如果JTAG链上有多个器件建议在Programmer里先Auto Detect扫描链确认每个器件的ID和位置。然后在SignalTap里选择对应的JTAG ID。注意多器件链中如果某个器件没有上电或JTAG连接有问题整个链都可能无法识别。排查时需要逐个器件检查。7. 从调试效率角度看工具组合策略7.1 什么时候用SignalTap什么时候用ISSP这个问题没有标准答案但可以根据调试目标来判断需要看时序关系用SignalTap。比如你要确认两个信号之间的建立保持关系或者看状态机的跳转时序。需要看当前值用ISSP。比如你要确认某个配置寄存器的当前值或者实时监控一个计数器的值。需要修改参数用ISSP。比如你要测试不同参数下的系统行为。需要抓异常事件用SignalTap。设置触发条件抓取异常发生时的波形。实际调试中通常是先用SignalTap定位问题范围再用ISSP做精细调整。7.2 调试流程的标准化我自己的调试流程通常是这样的确认基本功能先确保时钟、复位、电源这些基础条件正常。用ISSP的Probes监控时钟locked信号和复位状态。抓取关键波形用SignalTap抓取主要接口的波形确认数据流是否正确。定位异常点分析波形找出异常发生的时刻和相关的信号。修改参数验证用ISSP的Sources修改可疑参数观察系统行为是否改善。迭代优化重复步骤2-4直到问题解决。移除调试逻辑问题解决后去掉SignalTap和ISSP重新编译发布版本。这个流程的关键是快速迭代。每一步都不需要重新编译所以一轮调试可能只需要几分钟。7.3 调试逻辑的版本管理调试逻辑也是代码也需要版本管理。我的做法是把SignalTap的.stp文件和ISSP的配置文件纳入版本控制在代码中用ifdef条件编译控制调试逻辑的开关每次修改调试配置时记录修改原因和结果这样做的目的是当问题再次出现时可以快速恢复到之前的调试状态而不需要从头配置。ifdef DEBUG_ENABLE // ISSP例化 issp_debug u_issp ( .source (debug_source), .probe (debug_probe), .source_clk (clk), .probe_clk (clk) ); endif这样在不需要调试时只需要去掉DEBUG_ENABLE宏定义重新编译即可。7.4 在线调试的局限性虽然SignalTap和ISSP很强大但也有一些局限性需要了解需要JTAG连接调试时板子必须连着JTAG下载线不能脱机运行。消耗FPGA资源调试逻辑会占用LE和Block RAM可能影响时序和资源利用率。采样深度有限受限于FPGA的RAM资源不能无限增加采样深度。不能抓模拟信号只能抓数字信号模拟信号需要外部测量。对高速信号有限制采样时钟频率有限对于GHz级别的高速信号可能无法直接采样。了解这些局限性有助于在合适的场景选择合适的工具。对于高速信号可能需要用外部高速逻辑分析仪对于模拟信号需要用示波器对于长时间监控可能需要用外部数据记录设备。7.5 一个完整的调试案例最后分享一个我实际遇到的调试案例把上面的内容串起来。问题描述一个SPI主控模块在发送数据时偶尔出现数据错位概率大概百分之一。调试过程第一步用SignalTap抓取SPI接口的波形。采样时钟用SPI时钟采样深度2048触发条件设为cs_n下降沿。抓了几次发现数据错位时sclk的边沿和mosi的数据变化几乎同时发生存在竞争冒险的风险。第二步分析波形怀疑是mosi的建立时间不够。把mosi相关的几个信号接到ISSP的Probes上实时观察。同时把SPI时钟的分频系数接到Sources上尝试降低SPI时钟频率。第三步在ISSP界面里把分频系数从4改成8SPI时钟频率降低一半。观察了一段时间数据错位不再出现。确认问题是时序余量不足。第四步回到代码中在mosi的输出逻辑上增加一级寄存器改善建立时间。重新编译后问题彻底解决。第五步去掉SignalTap和ISSP编译发布版本。这个案例中SignalTap帮我定位了问题现象ISSP帮我验证了问题原因两者配合整个调试过程不到一个小时。如果靠改代码、重新编译的方式可能要大半天。7.6 一些零散但实用的技巧SignalTap的采样数据可以导出在波形窗口右键可以导出为CSV或VCD格式方便用其他工具分析。ISSP的Probes可以设置显示格式在ISSP编辑器里可以设置Probes的显示格式为二进制、十进制、十六进制方便阅读。SignalTap支持多个实例一个工程可以创建多个.stp文件分别抓不同的信号组。但注意资源消耗会累加。ISSP的Sources可以设置初始值在IP配置界面可以设置Sources的上电初始值避免上电时出现不确定状态。SignalTap的触发条件可以用信号名搜索在Trigger标签页可以用搜索框快速找到要设置的信号。调试完成后记得清理去掉SignalTap和ISSP后要重新编译并确认时序收敛。不要直接使用带调试逻辑的比特流作为发布版本。最后再分享一个小技巧如果你经常需要调试同一类问题可以把常用的SignalTap配置和ISSP配置做成模板新工程直接导入。这样能省去大量重复配置的时间。我自己的模板里包含了常用的时钟、复位、状态机信号基本上导入后改改信号名就能用。
返回列表