寄存器传输逻辑 (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 属于哪些网格位置。让机器完成大部分工作,这样您就可以集中精力。