如何获得绝对适用于实际硬件的 FPGA 设计

电器工程 数字逻辑 FPGA 设计 赛灵思 合成
2022-01-16 18:10:17

我刚刚开始使用 FPGA 学习数字逻辑设计,并且已经构建了很多项目。大多数时候(因为我是一个菜鸟),我的设计可以完美地模拟(行为模拟)但不能正确合成。

所以,我的问题是“我可以在我的工作流程中加入哪些设计步骤,以确保我的设计能够在我的 FPGA 上正常工作?”

我有两个主要方面我希望提出建议,但这绝对是基于我作为初学者的一个非常狭隘的观点,欢迎更多:

  • 我应该学习哪些所有步骤(查看 RTL 原理图、综合后仿真……)以获得最佳实践。
  • 在设计我的逻辑(比如 FSM 或时序电路)以避免任何意外结果时,我应该记住什么。

我正在使用 Xilinx Spartan 6 FPGA 和 Xilinx ISE 设计套件来完成我的工作。

4个回答

在我工作的地方,有两个 FPGA 设计师阵营。我称之为模拟、模拟、模拟或立方的一个营地。另一个阵营都是关于设计的。

s 立方体的家伙使用像 modelsim 这样的模拟器,他们会通过编码方法和/或设计套件中的块来提出初始设计。然后他们会模拟它并找到不起作用的东西,然后更改代码。这个过程重复了好几次,直到他们想出了一个可行的设计。

设计阵营(我更喜欢)会在纸上(或像 visio 这样的数字纸)上设计波形,这正是所需要的。然后拿出一个逻辑图。这是一个自我记录的过程。然后将图表转换为代码(代码和图表是 1:1 的,如果图表中有东西,代码中就有处理它的过程)。然后进行仿真,将仿真波形与纸上设计的波形进行对比,预期一致。

我最终都做了,有时我会进入 s 立方模式,这不是很有趣。我发现我有时会忘记自己的目标。例如,我会更改状态机中的状态,并且更改会波及到下一个状态,然后我必须修复它。我最终花了更多的时间而不是考虑它。

你更愿意去哪个阵营?我认为需要严谨的设计,做适合你的事情,但我认为你设计得越细致严谨,从长远来看,你遇到的问题就越少。我举了一些可能的例子,它们可能不适合你工作场所的组织结构。设计细节和仔细规划之所以如此有用,是因为它迫使你思考你在做什么。它使调试变得容易。开发一个允许这种情况发生的设计工作流程。此外,要真正熟悉模拟工具并编写好的测试平台,以测试模拟设备可能遇到的所有条件。这当然需要与时间平衡。例如,编写 ADC HDL 代码,在您的模拟中模拟设备。

FPGA 设计中最有价值的工具(在我看来)是一个很好的测试程序,它可以让您全面测试您的设计并按照它的速度运行它。不能期望 FPGA 设计“正常工作”,它需要努力确保所有部分都工作。如果发现错误,请返回仿真和设计,了解仿真 FPGA 和 RTL 之间的区别。这主要来自经验,但如果设计在模拟中有效,而不是在硬件中有效,那么您需要找出为什么会有差异。

我学到了一些关键的东西:
1)清理你的输入,时钟和复位电路需要干净,否则你可以通过你的系统传播亚稳态。了解什么是双列同步器。复位电路有许多不同的拓扑结构,知道如何使用它们(网上有一篇很棒的文章,不过我手头没有)。
2) 预先了解设计要求,然后围绕这些要求进行设计。如果你周围的人不会给你明确的要求,那么你自己想出一些。
3) Matlab 定点工具箱非常适合模拟控制系统和 DSP 应用程序,但您可能无权使用它。这是在编码之前证明设计的好方法。
4) 先设计,再编码,再模拟。
5) 强类型,同时保持 pcb 原理图和 hdl 上的信号名称一致。(这也是为什么我更喜欢 VHDL 而不是 verilog。

主要的事情是:

  • 仔细编码以避免不可合成的结构
  • 最小化逻辑电平以获得更好的时序性能(使寄存器之间的逻辑尽可能简单)
  • 测试,测试,测试以确保功能正确性并检查未初始化的 regs 和断开的电线等内容
  • 综合并检查综合日志是否有警告,确保警告不表示问题(即删除寄存器警告可能是有意的(未使用模块输出)或无意的(忘记连接模块输出/错字/等))
  • 映射并检查映射报告以获取利用率数据,确保 FPGA 没有太满
  • 布局布线和时序分析,确保您的设计将以所需的时钟速度运行

按照上述方法,我已经有几个相当复杂的设计在实际 FPGA 上的第一次测试中正常工作(或至少大部分工作正常)。无需检查 RTL 原理图,这对于大型设计来说非常麻烦且完全浪费时间。综合后模拟会更有用。

您所有可合成的代码都需要可表示为:

  • LUT
  • 人字拖
  • 供应商特定的原语

供应商特定的原语要么显式实例化,要么由供应商的向导生成,或者由非常特定的编码模式推断,因此不应有任何歧义。

例如,在 VHDL 中,您不能wait for在可综合代码中使用。要了解原因,请尝试wait for 100 ns使用 LUT 或触发器进行确定性表达。你不能。

这并不意味着您不能通过设置具有已知时钟频率(周期可分 100 ns)的计数器来实现它,并使用它的计数来知道时间到了。但是综合引擎不会自动提出这个方案,您需要在组合逻辑(门/LUT)和寄存器方面明确架构。

因此,为了生成可合成的代码,要记住的主要事情是对代码如何变成逻辑门和触发器有一个相对清晰的了解。就是这样。

最明显的第一步是检查警告。

Xilinx 工具会生成日志文件,这些文件会警告任何可能不是编码人员想要的内容。有时这很烦人,当您收到大量关于未使用信号的警告时,您完全知道这些信号是未使用的。但有时它会捕获真正的错误。如果您是新手,那么您犯错的机会会大大增加。

然后你需要设置时序约束。在时钟 A 的上升沿后多快需要设置数据线 B?或者数据线 B 在时钟 A 的下降沿之前需要保持多长时间?时间限制将让您指定所有这些。如果您没有时序限制,编译器可能会假设您并不特别在意并且可以将您的信号路由到任何地方。如果您有时序约束,编译器将通过移动布局来确保您的信号满足这些约束。如果它不能满足时序约束,它会发出警告。

如果您的问题是输出没有达到您的预期,请详细查看 I/O 块。每个 I/O 引脚都有一些相关的逻辑和触发器。您在代码中指定逻辑和状态变量的顺序可能无法使您的代码适合此架构,因此您会从碰巧放置的地方获得额外的延迟。时序约束的警告会告诉您是否会发生这种情况(假设您已经设置了时序约束),但修复它需要您了解硬件以及您的设计将如何映射到硬件。通常,这仅在您开始达到高时钟速率时才会出现问题,但值得一提。