拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

紫光同创FPGA开发实战:从PDS工具到引脚时序约束全攻略

紫光同创FPGA开发实战:从PDS工具到引脚时序约束全攻略

1. 软件环境准备与工程创建

1.1 下载安装:先搞清楚PDS和TD的区别

刚接触紫光同创的FPGA,最容易懵的一点是:到底该用哪个软件?紫光同创目前的工具链主要有两套,一套叫PDS,另一套叫TD。很多初学者在官网看到两个下载入口,直接不知道该点哪个。

我个人的经验是,PDS主要面向中高端器件,比如Logos系列、Compa系列、28nm工艺的芯片,功能更全,支持Team License和Node-Locked License,适合正经做项目的场景。TD则偏轻量,适合快速验证、教学使用,尤其在早期的代码移植和学习阶段,启动快、界面清爽,对应的器件以低端、中小规模为主。

这里给一个最简单的判断方法:你手头是哪颗芯片,去PDS或TD的Device Support列表里查一下,能识别到哪颗就用哪个。不要为了“功能全”硬上PDS,如果器件本身不在支持列表里,反而会多出很多麻烦。我见过有人拿TD建的工程,硬想用PDS打开,结果版本报错半天,最后发现选错工具链,白白浪费了一个下午。

下载安装这块,要注意几个小细节。第一,安装路径不要有中文,这几乎是所有FPGA工具的通用禁忌,紫光同创的软件也不例外,之前有人装到D盘的“新建文件夹”里,结果综合的时候各种诡异报错,换路径重装就好了。第二,安装前先关掉杀毒软件,部分安全软件会对License相关的进程误报,导致工具起不来。第三,建议按默认装到C盘,虽然C盘空间吃紧,但后续的License绑定、环境变量配置会省心很多。

安装完成之后,第一次启动需要配置License。紫光同创的License文件一般是.lic或.dat格式,可以通过环境变量LM_LICENSE_FILE指定,也可以在软件界面里直接选择License文件路径。这里有个经验:如果你用的是试用License,建议把到期时间记在手机备忘里,免得做到一半License过期,工程都打不开,那才叫欲哭无泪。

1.2 新建工程的基本流程:一个demo带你跑通

装好软件之后,我建议先不要急着写代码,花十分钟建一个空工程,把整个流程点一遍,建立“工程管理”的体感。紫光同创的工程界面和Xilinx ISE/Vivado有七八分神似,用惯了Vivado的人上手很快,纯新手也不用慌,逻辑是完全相通的。

新建工程的路径一般是“File -> New Project”,弹出向导之后会要你填工程名、工程路径、器件型号。这里说一下我踩过的坑:工程名尽量用英文,不要有空格,uart_rx_top这种命名就很好,uart rx top这种带空格的命名,后续生成文件的时候容易在一些工具脚本里报找不到路径的问题。

器件选型这一步要仔细。紫光同创的芯片命名规则,比如SL2-25E-8F676C,包含系列、容量、速度等级、封装等信息。如果你不确定手里的开发板具体是哪颗芯片,可以从开发板资料或圆片标记上看。选错了器件型号,后面综合、布局布线基本不可能过,哪怕勉强过了,下载也大概率失败,因为JTAG ID对不上。

工程建完之后,PDS会自动生成一个默认的目录结构,通常包含src(源码)、constr(约束)、sim(仿真)、out(输出)几个目录。我强烈建议你从一开始就遵守这个结构,而不是把文件一股脑丢在根目录。等工程变大了,几十个文件混在一起,你就知道目录干净有多重要了。

新建工程这一步做完,可以顺手点一下综合(Synthesis),不写任何代码,空的顶层模块能编译通过,就说明环境基本没问题。这一步通过之后,再正式开始写代码和约束,排查问题的时候你才能把“环境问题”和“代码问题”分开,不然两边混在一起,调试会很痛苦。

2. 约束文件:FPGA开发的“地基”

2.1 约束文件到底管什么

很多人写FPGA代码,上来就是module xxx(...)一顿操作,代码写得飞起,等到要上板了才想起来约束文件还没写。这个顺序其实是有问题的。约束文件不是工程的“补丁”,而是工程的一部分,它决定了你的逻辑在真实芯片上以什么样的物理形态落地。

从功能维度看,约束文件主要管三件事:

  • 物理位置约束:告诉工具,某条信号应该分配到芯片的哪个引脚、哪个Bank、哪个时钟引脚上。
  • 电平标准约束:告诉工具,这个引脚工作在什么电压、什么IO标准下,比如3.3V LVCMOS、1.8V LVCOM18、还是差分LVDS。
  • 时序约束:告诉工具,你的设计期望跑多快的时钟,数据路径的建立时间和保持时间要多苛刻,工具才能根据这些约束来布局布线。

拿建房打比方:代码解决了“这个房子要盖几层、每个房间是什么功能”的问题,而约束文件解决的是“这块地怎么分配、每面墙用多厚的砖、门窗开在哪”的问题。没有约束文件,代码只是纸面上的设计,约束文件才是让设计落地的施工图。

在紫光同创的工具链里,约束文件的后缀通常有两种,一种是.pdc(物理约束),一种是.sdc(时序约束),和Synopsys的SDC格式有渊源。也有人会把引脚约束和时序约束写在同一个顶层约束文件里,叫法比较灵活。但行业惯例是物理约束和时序约束分开,因为它们的关注点不同,分开写便于排查问题。

2.2 不写约束直接编译会怎样

这个问题几乎每个入门的人都会问:我不写约束,让工具自己分配行不行?答案是:行,但结果往往很糟糕。

先说引脚,不写引脚约束,工具会按默认策略自动分配引脚,这个分配结果是随机的。下载到板上之后,你会发现板上的LED不亮、UART的TX没有波形,因为工具分配的引脚跟你实际接线的引脚对不上,逻辑再好也没用。所以引脚约束是必须写的,没有商量余地。

再说时序,不写时序约束,工具会以“尽量布线成功”为目标,不对时钟频率做任何保证。芯片内部能跑多少兆赫兹,你的设计是否满足建立时间和保持时间,工具压根不管。最典型的现象是:仿真完全正确,上板在低速情况下也正常,一超频就乱码、偶发错误,十有八九是时序约束缺失、芯片内部时序违例导致的。

这个坑我在带团队的时候见过太多次。有一个踩坑比较典型的案例,同事做一个MIPI接口的图像采集项目,功能仿真全都过了,上板之后图像时好时坏,找了两天问题,最后发现顶层约束文件是空的。加上时钟约束精确到10MHz,重新布局布线,问题直接消失。所以约束文件不是“锦上添花”,而是“雪中送炭”。

我还想补充一点:不写约束还有一个隐性风险,就是器件内部的时钟资源分配混乱。FPGA内部不只是可编程逻辑,还有专用的时钟布线网络、PLL/MMCM等时钟资源。如果不加约束,工具可能把一个高频信号从普通逻辑路径绕过去,导致时钟偏斜严重。约束文件写得好不好,直接决定了你的设计在物理上是不是“顺路”的。

3. 引脚配置与约束语法:手把手写PDC

3.1 先说清楚PDC文件的基本语法

紫光同创的物理约束文件(PDC)语法和Xilinx UCF类似,但具体关键字有差别。以下是几个最常用的写法,我建议直接把这段当成模板用,改一改就上板。

引脚分配最基础的语法是IO_LOC,形如:

IO_LOC "clk" 2; IO_LOC "rst_n" 3; IO_LOC "uart_tx" 45; IO_LOC "uart_rx" 46;

注意,引脚的编号是芯片封装的物理引脚号,而不是逻辑引脚名。你必须对着芯片的封装图或开发板的原理图来写。这一点和Xilinx不一样,Xilinx常用的是包引脚名比如A15、K17,而紫光同创的引脚编号更像是纯数字或者数字加字母的物理封装脚位,要格外仔细。

分配电平标准用IO_PORT,比如:

IO_PORT "clk" IO_TYPE=LVCMOS33; IO_PORT "uart_tx" IO_TYPE=LVCMOS33;

如果你是差分信号,比如LVDS、Mini-LVDS,写法会不一样。紫光同创通常要求成对的引脚,比如P端和N端,需要额外指定差分对,类似IO_PORT "lvds_p" IO_TYPE=LVDS;这样的形式。同时,IO_PORT里还可以附加其他参数,常见的包括DRIVE(驱动强度)、SLEW(压摆率)、PULLUP(上拉)、TERM(端接)等,这些参数的应用场景各不相同。

举个例子,如果某个信号是I2C的数据线,是开漏输出,那你大概率要加上拉;如果某个信号是高速时钟,那你可能要考虑更严格的压摆率、更强的驱动。这些细节决定了信号在PCB上的真实电气表现,别偷懒。

3.2 引脚位置怎么查:封装图是唯一的“参考答案”

写引脚约束的第一步,不是写代码,而是查原理图、查封装图。紫光同创芯片的封装资料,包括引脚位图(Pin Diagram)、封装引脚定义表(Pin Table),在官网对应器件的技术文档里都能找到,通常是PDF格式。

查引脚要注意几个坑:

  • 引脚编号要和封装对应。同系列不同封装,引脚编号完全不一样,比如F676封装和F484封装,引脚位置差得不是一星半点,千万别拿别人的工程直接改芯片型号就上。
  • 注意电源引脚和地引脚。FPGA不比单片机,电源脚和地脚非常多,分布在各Bank周围。在画原理图和写约束时,要确保所有Bank电源(VCCIO)接对了电压,否则特定Bank的引脚即使约束了,电平也可能不对。
  • 留意NC引脚。NC表示No Connect,不能接任何网络,有些开发板会把NC脚引出来做扩展接口,这在FPGA开发中是禁忌。

我以前见过一个经典翻车案例:一个同学在淘宝买了一块开发板,不看原理图,直接拿网上的同一个系列的引脚约束文件想当然改了一下,结果下载后板子毫无反应。排查了半天,发现他把引脚号对错了,代码里写的是IO_LOC "led" 27;,而板子上的LED实际接的是引脚45。这就是不看原理图、不看封装图的代价。

如果你的板子买的是市面上常见的开发板,比如像黑金、小梅哥这些厂商出的板子,一般资料包里有现成的引脚约束模板,直接拿过来改一改最省事。如果是自己画板子,那就没有捷径,必须对着自己画的原理图和CAD封装,把每个脚的信息逐一核对,这个过程虽然枯燥,但值得认真做。

3.3 时钟约束:让工具知道你的“速度期望”

引脚配完之后,还要加上时钟约束。紫光同创的PDS支持SDC格式的时序约束,最核心的语法是create_clock。

比如你的板上有一颗50MHz的有源晶振,接在芯片的某个时钟专用引脚上,那么在SDC文件(或PDC同名的SDC文件里)这样写:

create_clock -name clk -period 20.000 [get_ports clk]

-period 20.000表示时钟周期是20纳秒,对应50MHz。时钟周期换算公式是T_ns = 1000 / F_MHz,50MHz对应20ns,100MHz对应10ns,这个换算关系要熟练,很多人在1秒和1纳秒的换算上栽过跟头。

除了create_clock,还有几个约束在实际项目中经常用到。set_input_delay和set_output_delay定义信号相对时钟的时序裕量,对高速IO特别重要。set_false_path用来告诉工具某些路径不需要做时序收敛,比如跨时钟域的异步信号,可以把它标成false path,免得工具在这些路径上浪费布线资源。set_max_delay则对异步信号的延迟上限做约束。

时序约束的完整写法需要结合具体的接口协议来设计,这里不做展开,但对入门者来说,明白一件事就够了:时钟约束是你告诉工具“我这颗芯片期望跑多快”的唯一途径。写好了,工具会努力满足你的期望;没写好,工具就放养了。

3.4 用模板+手动改,快速完成引脚配置文件

有一说一,对一个新入门的人,从零敲一个完整的约束文件并不容易。我的建议是:找一个同系列或者同芯片的官方模板,基于模板手动改,速度最快。

典型步骤是:

  1. 打开PDS工程,展开约束目录,新建一个PDC文件。
  2. 通过“Tools -> Pin Planner”打开引脚规划器,这个功能可视化了芯片封装图,鼠标点某个引脚,就能看到引脚号、Bank、可用电压等属性,极其方便。
  3. 在引脚规划器里,把设计中的所有IO信号手动拖到目标引脚上,或者直接在右侧属性表里填引脚号。
  4. 保存后,PDS会自动生成对应的PDC文件,你再手动补上IO_TYPE和SLEW等参数。
  5. 再建一个SDC文件,写上时钟约束,保存,约束部分就完成了。

这里要特意表扬一下引脚规划器。紫光同创的PDS在引脚可视化这块做得挺顺手,比某些老牌工具更直观,它可以按Bank高亮、按信号名搜索、检查引脚冲突,这些功能在人工检查的时候作用很大。新手完全可以从Pin Planner入手,不需要背引脚号。

4. 综合、布局布线与下载调试

4.1 从约束到比特流的完整流程

约束文件写完,接下来就是FPGA开发的标准流程:综合 -> 布局布线 -> 生成下载文件 -> 上板调试。在PDS里,这些操作一般在“Process”窗口里依次双击即可。

综合(Synthesis)的作用是将RTL代码转换成网表。这一步会检查语法错误、模块例化关系、信号位宽等问题。综合通过并不代表设计没问题,它只代表语法层面没有报错。布局布线(Place & Route)则是把网表映射到芯片的实际逻辑单元上,这个过程对时序约束的依赖最大。如果时序约束写得严苛,布局布线的时间会变长,甚至出现负余量(Negative Slack)。

在PDS中,生成下载文件一般叫“Generate Bitstream”或“Generate Programming File”,生成的文件是.bit或者.pdi格式。这一步做完之后,通过下载器把bit流烧进芯片。

下载环节有几个要注意的点。首先是下载器,紫光同创的下载器一般是JTAG接口,市面上有官方下载器也有兼容的第三方下载器。插上之后在PDS里打开“Programmer”工具,选择对应器件,加载bit文件,点击Program就可以了。如果是自己画的板子,JTAG的TCK、TDO、TMS、TDI四根线要按菊花链顺序连对,初始化失败的时候首先检查这几根线有没有虚焊。

4.2 布局布线其实没那么玄,但要会看报告

很多入门者觉得布局布线就是点一下按钮,等它跑完就行。其实布局布线器的日志和报告里藏着大量有用信息,学会看报告,能省很多排查时间。

布局布线跑完之后,PDS会生成一份.twr时序报告和.rpt布局布线报告。你要重点关注的内容包括:

  • 时序余量(Setup Slack / Hold Slack):如果两个余量都是正的,说明时序收敛;如果有负余量,说明设计在特定时钟频率下无法满足时序要求,需要优化代码或约束。
  • 资源占用率:LUT、FF、BRAM、DSP的使用百分比。如果某个资源用得超过90%,布局布线器几乎没有优化空间,出现时序违例的概率会大增。这时候要主动优化代码结构,而不是加约束硬压。
  • 扇出(Fanout)警告:某个信号扇出特别大,工具会提示。面向全局复位的信号扇出几千个是一个正常的事,但如果一个业务信号扇出几千个,说明代码结构有问题,会导致布线拥塞、时序变差。

举一个实际的例子,之前做一个图像处理项目,用了某个厂商的软核处理器,综合完之后显示LUT占用92%,布局布线后一大堆时序违例。后来把一个组合逻辑很重的信号拆成两拍流水,LUT占用降到80%以下,时序也收敛了。这说明你改了代码结构,比硬调约束有用得多。

4.3 下载与调试:板子没有反应时怎么排查

假设你已经把bit流成功下载进FPGA,结果板子上的LED不亮,UART不发数据,这时候该怎么排?我建议按照“从简单到复杂”的顺序来排查。

先检查最基础的电路信号,包括时钟是否进入芯片、复位信号电平是否正确、电源是否稳定。这些都可以用示波器或万用表快速确认。如果时钟有波形、电源电压正常、复位电平也对,那大概率是引脚约束或代码逻辑的问题。

再检查引脚约束是否和你实际的板子接线一致。对照开发板的原理图,把你写的PDC文件里的每个信号逐一核对。这个步骤看起来很笨拙,但真的能解决80%的“板子没反应”问题。

然后是逻辑问题。用在线逻辑分析仪抓内部信号,看看FPGA内部的时钟、复位、核心状态机是否正常工作。紫光同创的PDS自带逻辑分析仪工具,不过数量和触发条件有限,入门调试基本够用。

最后说一个容易被忽视的电源问题。在很多个人设计的板卡上,FPGA核心电压(VCCINT)和IO电压(VCCIO)必须严格对上,核心电压一般需要专用LDO或DCDC稳压器。如果VCCIO接错了电压,引脚即使约束了也会工作得不正常,这个在排查时很难发现,建议从原理图开始就检查一遍。

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

5.1 几个高频报错和对应解决思路

我整理了在紫光同创FPGA开发中比较高频的几个报错,以及我自己总结的排查思路,做成一个速查表供参考:

报错/现象常见原因排查方向
ERROR:IO constraint not found某些引脚没有在PDC中约束打开Pin Planner,看是否有未分配的IO
ERROR:Bank VCCIO mismatchBank的IO电压与约束类型不匹配检查原理图对应Bank的VCCIO电压是否与IO_TYPE一致
WARNING:Timing violation时序约束未满足查看时序报告,看是Setup还是Hold违例
ERROR:Clock net has no driver时钟信号没有正确连接检查代码,确认时钟命名和SDC中的get_ports是否一致
Program failed / JTAG ID mismatch选择了错误的器件型号或JTAG接线问题查芯片型号,查JTAG四线连接

这几个报错看起来分散,其实背后的共性是:别急着看报错信息,先问自己三个问题——约束文件写对了吗?芯片型号选对了吗?原理图接线看对了吗?这三个问题的答案一旦确认,大多数报错都能自己解开。

5.2 资料少、案例少,怎么办

国产FPGA的一个现实问题是生态和工具链比不过Xilinx和Intel/Altera,中文教程相对少,案例也不像国外厂商那么丰富。这确实是入门者绕不开的一个坎,但不能因此就放弃。

我的经验是分三步走。第一步,把官方文档读透,特别是UG和TRM系列文档。紫光同创官网和官方公众号有技术文档和用户指南,这些文档虽然排版风格比较干,但信息密度大,引脚说明、寄存器定义、工具流程都在里面。第二步,利用社区资源,比如开源社区、技术论坛、B站的FPGA入门视频,很多UP主和站长整理了紫光同创的开发笔记。第三步,动手把开发板的官方demo跑通一个,再基于demo做小改动,从小灯到UART到SPI,逐步建立起自己的工程复用库。

还有一个小建议:学会“翻译式学习”。用Xilinx的文档当成参考,搜同一个问题的英文名字,比如“Xilinx create_clock constraint”,看懂了原理,再迁移到紫光同创的写法上,这个策略在工具不够用的时候尤其有效。因为FPGA开发的核心方法论是通用的,具体工具只是表达方式不同。

5.3 关于“国产FPGA值不值得学”的一点体会

用国产FPGA做产品这件事,前几年大家还有顾虑,现在越来越多工程师开始接触它。紫光同创、高云、安路这些国产FPGA厂商的器件,在性价比和中低端容量区间已经很能打了。对于学习和开发者来说,最大的价值在于:你可以用“练习价”的板子,体验一套完整的FPGA开发流程。流程跑通了之后,万一产品量产要换芯片,再迁移也不难,因为逻辑设计本身是可移植的,改的主要是约束和底层接口。

我个人在实际开发中还有一个很深的体会:国产FPGA工具链虽然比Vivado简陋一些,但代码质量和实现效果不差。如果写的是贴近工业场景的逻辑,比如UART、SPI、IIC、SDRAM控制器这类接口逻辑,紫光同创的中低端器件完全够用。如果你习惯先做仿真再上板,哪怕工具再简陋,也拦不住你把功能调通。

最后说一个最实用的建议:在正式项目里,约束文件的版本管理一定要重视。每次修改引脚约束,都要更新工程说明文档,哪怕只是改了一个引脚号。因为一个项目周期动辄几个月,等到你自己都忘了某条约束为什么这么写的时候,文档就是你唯一的回忆。这一点,和工具链没有关系,是每个FPGA工程师都应该养成的习惯。

返回列表