01signal.com

FPGA 设计师需要的理论技能

本页是关于如何成为专业 FPGA 设计师的系列五篇文章中的第二篇。在本页中,我会逐一介绍我认为每位 FPGA 设计师都应该掌握的各种理论主题,并试着解释为什么我认为每一项都很重要。

逻辑理论

懂理论不是锦上添花。它是一切的基础,哪怕在你跟一个死活不配合的开发工具较劲,或者硬件似乎自有主张的时候,感觉并非如此。

FPGA 工程师需要能够在脑子里想象出自己写的 Verilog 会怎样变成逻辑单元。不必细致到每一个细节,但至少要能判断出哪些部分会拖慢设计、限制时钟频率,哪些部分会吃掉大量逻辑资源。这一点至关重要,比如在判断某项任务是否需要通过添加寄存器来流水线化(pipeline)时。流水线通常会让设计变复杂,但它往往也是达到所需速度的唯一办法。其他重要的设计决策同样依赖这种能力。

对于看懂综合器(synthesizer)做了什么、为什么这么做,这种能力也至关重要。比如,知道综合器倾向于把什么优化掉,你就能写出既易读又高效的 Verilog 代码。如果你不知道综合器会怎么处理你的代码,那你就是在盲写。

那么哪些主题是相关的?我建议从下面这份清单入手。我并不是说它涵盖了全部内容。

逻辑范式与技巧

除了纯逻辑理论之外,还有一些主题是写出可靠、高效,并且在硬件里和仿真中表现一致的代码所必需的。这在软件世界里几乎是理所当然的事,但 FPGA 设计师生活在另一片天地里。每一位 FPGA 设计师都必须时刻把这些主题放在心上。

RTL 范式,即寄存器传输级(Register Transfer Level),是核心思想。简而言之,它意味着任何存储数值的东西,都只在时钟边沿到来时才改变这个数值。异步复位(asynchronous reset)可以是那个被小心控制的例外。一旦你把这种思维方式内化于心,你就有很大机会把设计做对。

复位本身就是一个专门的课题。同步复位与异步复位(synchronous reset、asynchronous reset)以及复位同步,是你在每个项目里都必须理清楚的事。如果不理清楚,你的设计在大部分时间里运行良好,只是偶尔出点莫名其妙的毛病。你会把一个能用的系统交付出去,却因为这些偶发故障而没法发布。项目会越拖越晚,而你对问题出在哪里毫无头绪。这种时候,人们通常不会想到是复位没做好。这个主题真的值得你深入理解。本网站上有一组相关短文。

与此密切相关的是时钟使能(clock enable)与门控时钟之争。本质上这是两种不同的技巧,目的都是让逻辑设计不必在每个时钟周期都工作。FPGA 有针对时钟门控的专用资源,但用错了就是制造诡异问题的绝佳方式。稳妥的习惯是在逻辑中使用时钟使能,不过如果你想利用较低的有效时钟频率来放宽时序约束,也可能遇上麻烦。

状态机编码也值得一提。二进制编码、独热(one-hot)编码和格雷(Gray)编码各有各的用武之地,选哪种会影响速度和资源占用。工具常常会替你选,但你应该知道这些选项意味着什么。尤其是独热编码,非常适合大型状态机。但如果状态机没有正确复位,这种编码会让它做出在 Verilog 代码看来根本不可能的事。看起来像是 FPGA 里在闹鬼,或者综合器有 bug,但都不是:这是独热编码加上不恰当的复位造成的。

最后是流水线(pipeline)。它不只是一项技巧,更是一种思维方式。加一个寄存器本身很简单,但数据处理要跨越好几个时钟周期,这会带来一大堆可能的问题。比如,在这批有效数据的最前面几个到达之前,接收端该做什么?如果输入数据不是连续到来的,流水线需要临时冻结,那该怎么办?在不使用一个扇出(fan-out)巨大、要连到处理链中所有逻辑单元的时钟使能信号的前提下,这又怎么实现?

每一种场景都需要不同形式的流水线设计,每一种都有自己的挑战和怪脾气。

数字设计

如前所述,FPGA 设计师需要能在脑子里想象 Verilog 最终怎样变成 FPGA 里的逻辑单元。举一个具体的例子。

假设我在 Verilog 里写了一句朴素的 "assign x = a + b;"。这个加法器是怎么实现的?这块特定的 FPGA 有没有用什么特殊技巧来实现加法器?它会不会用上一块专用硬核,比如 DSP 块?如果用上了,那么当加法器的结果是一个寄存器而不是一根线时,这又能帮上多少忙?如果我加三个数,写成 "assign x = a + b + c;",又会怎样?FPGA 对三个数相加有没有什么捷径?答案多半是没有,所以它会被实现成类似 (a + b) + c 的形式。两级逻辑串联会让设计明显变慢。但在你所用的那块具体 FPGA 上,它究竟是怎么工作的?

清楚你所针对的具体 FPGA 里有哪些资源可用,这很重要。它会塑造你写 Verilog 的方式,好让综合器能生成又快又高效的逻辑。综合器不是魔术师,不能把你扔给它的任何问题都变没了。如果你把 Verilog 写得聪明,又了解它的局限,你得到的设计就会占用资源少、功耗相对低,还能跑在较高的时钟频率上。这靠经验积累,而数字设计知识能加快你获得这种智慧的过程。

实践中,我们通常只有在解决时序收敛(timing closure)问题时,才被迫去研究 FPGA 内部的逻辑实现,因为需要弄清楚为什么结果太慢或者占用资源太多。于是我们一个一个地排查逻辑实现里的细节,找出浪费时间或资源的地方。不过偶尔主动分析一下结果也是个好习惯,既能增长知识,也能确认没有发生什么离谱的事情。从长远看,这是有回报的。

了解你的 FPGA

想象 Verilog 如何变成逻辑单元的另一个方面,与基本逻辑资源有关。也就是说,要了解 FPGA 的构成单元,以及它们适合用来做什么。

首先是 FPGA 本身的结构:基本单元、CLB,以及你的 FPGA 上的 slice(切片)。写 Verilog 代码时,如果你能想象出这些单元会怎样被用来实现所需的逻辑,那是极大的优势。这样你就能判断自己写的东西会不会成为设计时序收敛的瓶颈,或者这段代码是不是永远都不会再来烦你。

大多数 FPGA 的结构或多或少是相似的。它们都有高效实现算术加法器、多路复用器、解复用器等的手段,因为这些功能用得非常多。例如,很多 FPGA 把乘法器做成硬核,让 "assign x = a * b;" 这类运算能跑在很高的时钟频率上。

但这些乘法器的具体特性可能各不相同。在某些 FPGA 上,这些乘法器块的位宽是 18 位有符号整数。因此,操作数宽度不超过这个值的乘法,其时钟频率会比其中一个操作数是 19 位时高得多。这又是一个说明了解 FPGA 逻辑块为何重要的例子:仅仅多出一个比特,就可能明显拉低时钟频率。注意,换到另一个 FPGA 系列,可能是完全不同的局面,操作数宽度也另有一套。

布线资源也很重要。逻辑单元只是故事的一半,它们之间的连线是另一半。很多时候,设计达不到目标时钟频率,是因为布线变得拥塞,因而变慢。如果你打算把 FPGA 的逻辑容量用到接近 100%,而且设计里有大量宽数据总线,这一点就要好好考虑。FPGA 里有些布线资源(“线”)很快,有些则较慢。快线用完了,整个设计就会慢下来。

你还应该理解 FIFO 和 BRAM。这些是 FPGA 内部的存储资源,你会一直在用它们,既用来存放和缓冲数据,也用来做跨时钟域传输。会用 FIFO 是最基本的功夫。本网站上有一组相关文章。

时钟资源是它们自己的一个小宇宙:PLL、时钟缓冲器,以及全局和区域时钟网络。PLL 是把输入时钟变成你的逻辑真正需要的各种时钟的部件。它能倍频、分频,还支持相移。搞清楚哪些时钟相位对齐、哪些不对齐也很重要。比如,假设一个 PLL 输出两个时钟,其中一个频率是另一个的两倍:用第一个时钟驱动的寄存器去采样第二个时钟驱动的寄存器输出,安全吗?通常安全,但这取决于这两个时钟是否相位对齐。而你必须知道怎么确认情况确实如此。本网站上有一篇文章讨论这个主题。

接下来是 I/O 块资源。在涉及高速 I/O 信号的设计中,比如 DDR 和 SERDES,你需要理解 I/O 块能为你做什么,以及它们如何支持远高于设计时钟频率的数据速率。它们还能被配置来配合阻抗匹配,方式是加上端接电阻以及提供其他底层电子功能。

如果你需要每秒一千兆比特以上的数据速率,那就要用多千兆位收发器(Multi-Gigabit Transceiver,MGT)了。这是一个相对进阶而复杂的主题,不适合初学者,除非某个具体项目需要。本网站上也有一组文章讲这个主题。

最后一个有点枯燥的主题:配置存储器和比特流(bitstream)加载。设计做完之后,你不会希望每次都从电脑把比特流加载进 FPGA。所以 FPGA 可以自己从闪存里加载,或者从 SD 卡加载。也可以让板上的另一个独立元件把比特流推给 FPGA,板上如果有独立处理器,通常就会选这种做法。

FPGA 的加载技术没什么好玩的,但如果你在一个小团队里工作,这也会是你的责任。而且上电之后 FPGA 要多久才能跑起来,往往也有要求。这都得靠你去琢磨。

关注这个主题的另一个原因是,FPGA 上电时常常会自动从闪存加载,尤其在评估板上。更麻烦的是,FPGA 板通常有不止一个可以加载比特流的存储器来源。当人们不知道装进 FPGA 的是旧版本项目时,就会出现极其漫长的调试过程:无论在设计里怎么改,FPGA 的行为都一模一样,因为他们每次更新的都是错误的闪存。

时序

先简单说说时序(在逻辑设计的语境下)是什么。长话短说,FPGA 内部和外部的每一个数字信号,都必须在特定的时间范围内保持电气稳定,通常是与时钟边沿相关。否则,逻辑的行为就变得不可预测。开发工具会在需要的地方保证这些时序要求得到满足。但要做到这一点,我们必须给这些工具提供明确的信息,而且要给得非常准确。此外,逻辑设计本身也必须写成让工具能够满足时序要求的样子。这就是时序问题的大致内容。

时序大概是 FPGA 设计师工作中最难的部分,也是最需要真正掌握并正确落实的领域。可惜的是,忽略这个主题却依然做出一个还过得去的设计,甚至好到让你以为自己快完工了,是相当容易的。一切都运行良好,但 FPGA 里似乎有种超自然力量,一到满月就会突然出故障。我把这种心态称为“黑魔法模式”,另有一篇文章专门讲它。

运气好的时候,一个没考虑时序就写出来的 FPGA 设计,只要补上几条时序约束(timing constraints)就能修好。有时候却几乎什么都要从头来过,因为一旦强制施加正确的时序要求,开发工具就没办法让它在所需的时钟频率下工作。于是 Verilog 代码本身也得重构。

运气特别差的时候,PCB 还得部分重新设计,因为无法保证板子上所有物理信号都能在它们必须稳定的时间段内保持电压稳定。如果能在 PCB 定稿投产之前做一次正经的时序分析,问题是能暴露出来的;可要是忽略了,硬件就未必担得起这个任务。

但如果你把时序做得细致、做得正确,FPGA 就是世界上最可靠的元件。很多 FPGA 设计师害怕对设计做哪怕一点点改动,每次生产用上新一批 FPGA 芯片就提心吊胆。散热搞得夸张得不行,因为 FPGA 一发热就像天要塌了。我的看法是:确保把时序做对,然后把这些顾虑统统忘掉。

你需要从第一天起就完美掌握它吗?我其实想说,是的。原则上我也同意,如果你在一个 FPGA 设计师团队里,只要有一个人真正擅长时序,那就够了。那就去做那一个吧,理由很简单:多半不会有别人。

本网站上有相当长的一组关于时序的文章,所以在这里展开讲没什么意义。下面只列一份我认为每位 FPGA 设计师都应该熟练掌握的主题清单:

电子学

FPGA 是一种电子器件,而 FPGA 设计是电气工程中的一个专业领域。而且是那种要跟原理图和数据手册、电压和电流、信号完整性和阻抗匹配打交道的电气工程。这是每一位 PCB 设计师都必须具备的知识,而 FPGA 设计师如果也懂这些,日子会好过得多。

常见的情况是,FPGA 设计师被指定负责确保 FPGA 与板子上其他元件正确对接。事实上,PCB 设计师为了甩掉让这些元件正常工作的责任,把能连的东西都连到 FPGA 上,这种情况并不罕见。因此,FPGA 设计师常常需要对 PCB 上各元件之间如何对接有深入的理解。那些在高频下翻转的线路上可能存在、需要解决的信号完整性问题,往往也得由 FPGA 工程师来指出。

设计新 PCB 时,团队里的 FPGA 设计师通常要审核设计,也就是检查与 FPGA 相关的连接是否正确。并非所有 FPGA 引脚都适合所有用途,而有时某些连接必须、或者显著更适合归属于 FPGA 引脚的某个特定组(“bank”)。这些是 FPGA 设计师必须掌握、至少要有明确判断的事。

FPGA 设计师中不乏原先做 PCB 设计的人。从板级设计转向 FPGA 设计是一条很自然的路,走过这条路的人有天然的优势。即使 PCB 设计师很负责,设计出一块完美的板子,FPGA 设计师仍然需要理解 PCB 上高速信号带来的挑战,才能把 FPGA 的 I/O 块配置得当。

正如我前面提到的,并非所有 FPGA 工程师都直接和电子硬件打交道。有些人只负责开发内部逻辑,也就是我所说的“处理逻辑”,有时公司招一个工程师就是专门做仿真和验证的。但我们大多数人确实直接和电子硬件打交道,那样的话,就需要一些相关的知识。

从最基础的东西开始:电压、电流、电阻和欧姆定律。数字信号就是靠这些从一个元件传到另一个元件的。了解电容以及电容器如何充放电,也是个好主意。这样你就能理解电流和电容如何影响开关速度和功耗。

你应该能看懂原理图:集成电路、模块、电感、电源、数字地与模拟地。MOSFET 和双极型晶体管有时也会出现,至少你应该认得它们。对 MOSFET 的行为有个大致概念,也没有坏处。

你还会花大量时间读数据手册。最难也最重要的部分,是把数据手册里的时序指标转换成时序约束(timing constraints),或者在 FPGA 上设计出合适的 I/O。板级偏斜(board skew)是你可能需要纳入 I/O 时序考虑的东西。

但你还要负责看懂数据手册里的电压和电流指标,并用正确的电压标准配置 FPGA 相应的 I/O 块:单端与差分接口、LVCMOS、SSTL、LVDS 等等。

真的所有 FPGA 设计师都能把这些做对吗?答案是不能。常常能看到一些设计,按电子学上的失误来说根本就不该工作,可它偏偏看起来运行得好好的。某个元件的输出引脚以高于绝对最大额定值的电压去驱动另一个元件的输入引脚,这种情况并不少见。这当然是个大错,按照数据手册,承受过高电压的元件原则上随时可能烧掉。可它偏偏就这么一直好好的。直到某天突然坏掉,然后聪明人开始为这件事编造各种傻乎乎的借口。

我再补一份清单,这些主题毫无疑问是 PCB 设计师的责任。但当这个人不那么出色时,FPGA 工程师对它们懂一点也会有帮助:

那么,从这一大堆东西里,FPGA 设计师真正需要知道的是什么?从一开始就必须掌握的关键又是什么?说实话,我也很难讲清楚。你周围的团队越强,你需要懂的电子学就越少。但我会说,任何 FPGA 设计师都应该能看懂原理图,能理解 FPGA 上连着的是什么,并大致明白为什么要那样连接。

本系列的第二页到此结束。下一页延续上面的思路,转向实用技能。1

本页由机器从英文翻译而来。如有疑问,请参阅原文。
Copyright © 2021-2026. All rights reserved. (852e87d4)