HDL 编译/综合成什么?

电器工程 FPGA 模拟 英特尔-FPGA 编译器
2022-01-24 01:04:44

我是一名软件工程师。作为一名程序员,我了解我的编译器为我做了什么,因为我已经手动编写了它输出的接近文本表示(例如汇编)。有关输出的详细信息,我可以查看 ELF/COFF/MachO 规范(例如,它将我的代码翻译成的文件类型,结果可能因语言而异)。要弄清楚指令的编码是什么,我可以看看我的处理器的说明手册。这给了我足够的信息来理解编译器输出的数据类型。它还为我提供了提出诸如“如何检查 ELF 文件的详细信息”之类的问题的词汇,并且该问题的格式相对较好。我也可以问“我如何查看我的编译器生成的程序集”,这个问题的格式是正确的。

对于 FPGA,我完全不清楚等效的步骤/问题。我不知道 Verilog 或 VHDL 被翻译成什么。我不知道 FPGA 使用的底层原语是什么。我不知道如何问像上面两个格式良好的问题这样的问题,因为我只是缺少要问的词。在这种情况下,等效问题可能没有意义,但我目前无法知道这一点。我所知道的是我可以编写一些 Verilog,然后它最终可以在模拟器或 FPGA 上运行。

我写了一些 Verilog,然后合成到……什么?那是什么东西?它是我可以检查的文件吗?是否有我可以查找的标准格式?例如,如果我想自己编写一个模拟器,我的模拟器会使用什么格式?

之后,合成的输出被编程到 FPGA 上。该 FPGA 使用什么原语?如果这是一个嵌入式设备,那么通常字节将被原始写入闪存或某种存储。FPGA有没有等价物?也许一个更抽象、更容易回答的问题是“在对 FPGA 进行编程时,哪些字节通过了写入?”

4个回答

就像程序编程语言通过几个步骤(编译、汇编、链接)来生成可执行文件一样,HDL 必须通过几个过程才能生成 FPGA 的可用配置文件。这些包括

  • 综合 --- 将 HDL 代码转换为描述逻辑元素之间连接的网表。

  • 映射 --- 将网表转换为更精细的网表,使用 FPGA 器件上实际可用的资源。

  • Place and route --- 选择设备上的哪些实际资源将用于映射器输出中的每个所需元素,并选择哪些路由资源将用于互连它们。

  • 位文件生成 --- 将布局布线输出转换为实际用于对器件进行编程的格式。

因此,如果当你问综合的输出是什么时,你的意思是这个过程的第一步的输出是什么,那么它就是一个用作映射器输入的中间文件。如果您的意思是整个过程的输出是什么,它是FPGA可以用来配置其所有逻辑和路由资源的位文件。

寄存器传输逻辑 (RTL)是第一个翻译阶段的结果,在它被映射到特定于供应商的资源之前,这些资源在供应商之间甚至在来自同一供应商的不同 FPGA 之间是不可移植的。本质上 RTL 显示了组合逻辑和同步寄存器(D 触发器),因此状态机是可识别的。Altera 和 Xilinx 之间的 RTL 非常一致,可能是最有趣和最有用的检查阶段。综合问题首先在 RTL 阶段变得可见,并且设计仍然可以识别。一旦进入特定于供应商的映射,它就会被分割和打乱。尝试对芯片特定的比特流进行解码是高成本、低收益的,并且当您转移到不同的供应商甚至同一系列中不同尺寸的 FPGA 时将毫无用处。您可以在 RTL 级别看到您需要看到的内容。

通过在测试台或简单的顶层模块中对其进行实例化并检查 RTL 代码来测试新开发的 Verilog 或 VHDL 代码始终是一种很好的做法。Xilinx ISE 非常适合将 RTL 作为原理图进行检查(尽管它有时会遗漏一些东西。)最常见的问题是:

  • 打算使用总线的 1 位网络
  • 优化器意外删除了大块逻辑......类似于简单的自旋锁延迟循环如何被代码优化静默删除。
  • 由于程序方法而不是真值表方法,输出未完全指定。如果工具认为输出始终为 0 或始终为 1,它将丢弃生成该结果的所有逻辑。
  • 模块逻辑被修剪掉,因为其中一个子模块被优化为始终为 0 或始终为 1;这可以一直级联到顶层

除非您保持模块小而简单,否则这种 RTL 检查会变得非常笨拙。使用测试平台是一个重要的工具。

我也是从嵌入式系统编程开始,其次是verilog,而像我们这样的人在学习HDL编码时最大的危险是它看起来像一种过程编程语言,感觉就像一种过程编程语言(在模拟期间),但随后一切当您尝试合成工作代码时会爆炸。您确实必须考虑硬件的外观,并确保 RTL 代码包含您期望的所有硬件。

除了 Verilog/VHDL 涉及将一些源代码输入计算机文件这一事实之外,与传统的 C/C++/etc 并没有太多相似之处。您的编程经验很少会转移。专注于将大问题分解为小问题,详细记录所有内容并编写测试平台。如果您还没有一台好的数字采样示波器,也可以投资购买一台。看看 opencores.org 上发布的一些示例代码,就像使用 C/C++ 一样,您可以从阅读其他人的代码中学到很多技术(无论好坏)。

让我对 FPGA 开发发疯的一件事是,源代码控制并不是工具链供应商似乎认为的重要特性。Xilinx Vivado 在这方面尤其糟糕,他们的建议似乎是在进行新的 checkout 时从头开始重新生成项目文件。尝试使用 100Mb+ zip 文件进行项目移交是令人生畏的。

另一个让我对 FPGA 开发发疯的事情是 Quartus/ISE/Vivado 工具并没有真正令人满意的方法来平息大量警告消息。当我编写 C/C++ 程序时,我希望能够单独处理每条警告消息并修复或批准它,这样我最终可以获得零警告的干净编译。从未真正见过有人在 FPGA 开发中做到这一点;其他 FPGA 开发人员(比我聪明)似乎只是接受一个普通项目有很多诊断信息,他们经常忽略这些信息,把它留给做实验室工作和在真实硬件上验证。

如果您曾经开发过自己的 FPGA 板(我不推荐),请务必将任何未使用的 I/O 引脚引出到某个地方的接头 - 尽可能多 - 因为这将是您的生命线您必须调试 FPGA 代码,或实施一些最后一小时的补丁。

您提到用汇编语言进行编程是一种对计算机正在执行的操作进行精确控制的方法,并且可以通过使用非便携式、供应商特定的原语对 FPGA 代码进行类似的精确控制。这对于每个供应商和每个 FPGA 都是不同的,就像不同 CPU 的汇编语言不同一样。对于 Xilinx,您将编写一个约束文件(对于 ISE 工具链或 Vivado 工具链不同)。约束文件将调用特定实例或特定网络,并指定时序要求。通常,低级 CLB/LUT/whateverUnits 排列在网格中,因此您可以确定特定的低级基元以位于特定的 X、Y 网格位置。查找 Spartan 3 系列的旧 Xilinx“FPGA 编辑器”,他们曾经鼓励人们以这种方式使用它。我认为不支持较新的系列 7 和 Zynq 芯片。就像组装一样,它对技术来说非常具体,因此是一种不稳定的技能组合。

与汇编类似,除了琐碎的“家庭作业”练习之外,您确实希望尽量减少编写的汇编量;98%-99% 使用 C/C++,只为对性能敏感的 1% 编写程序集。例如,如果您的 FPGA 设计需要一些子进程以 200MHz 运行,那么值得深入研究低级映射以了解这些工具在做什么。优化的最佳回报是您是否可以消除不必要的工作阶段。只有在将热元素削减到最低限度之后,才值得开始手动路由哪些 IOB 属于哪些网格位置。让机器完成大部分工作,这样您就可以集中精力。

FPGA 的物理原语是可配置逻辑块 (CLB)。

每个逻辑块在内存中都有一个专用位置,即所谓的配置内存,它决定了它的配置方式和连接位置。

HDL 最终以一堆 1 和 0 结束,即放置在此配置存储器中的所谓比特流。

大多数 FPGA 没有板载非易失性配置存储器。相反,配置比特流存储在外部配置 FLASH ROM 上,并且在上电时,FPGA 将该比特流从外部非易失性存储器加载到其内部配置 SRAM 中,该 SRAM 直接连接到并控制 CLB。

与软件不同,此比特流不是“运行”的。它只是被加载,然后它只是“是”。它不像正在执行的指令,而更像是包含设置的寄存器。

它是一个文件,例如 *.bit。没有标准格式。当 FPGA 开发工具附带模拟器时,我不确定为什么要自己编写模拟器。为此付出了很多努力,他们比任何人都更了解自己的设备,因为与软件不同,比特流中指定的每个原语都必须物理位于 FPGA 芯片上的某个位置,并且平面图可以决定某些设计的成败。

对 FPGA 进行编程时,哪些字节通过了写入?

这通常不太容易回答,因为它是 100% 特定于制造商和特定于设备的。一些制造商为此发布了数据表;其他制造商认为这是“商业机密”,您需要签署 NDA 才能找到答案。

无论如何,使用 C(或任何其他语言)编译器,原始字节不是最基本的部分。最基本的部分是实现您的程序的一系列处理器指令,原始字节只是您如何告诉处理器这些指令是什么。这些指令使处理器使用其各种硬件设施(例如加法器、乘法器等)执行操作,并在寄存器和存储器中存储或检索数据。

这在 FPGA 中非常相似,只是您从较低级别开始。您拥有的不是要运行的指令列表,而是 FPGA 中的每个门应如何互连的列表。大多数 FPGA 还包含用于 RAM 和其他功能的专门部分,您的程序还将包括如何连接这些部分。

你最终得到的是一个网表,就像你设计一个带有一百万个逻辑芯片的 PCB 一样。从概念上讲,这是 FPGA 编译器的最基本输出,用于告诉您它在做什么,就像汇编程序列表在概念上是您的 C 编译器的最基本输出,用于告诉您处理器在做什么。

当然,编译器随后会继续生成一个二进制文件,该文件将使用该网表对 FPGA 进行编程,就像 C 编译器继续生成一个二进制文件,该文件使用该汇编器对您的微控制器进行编程一样。