什么是最好的做法,用于硬件的描述语言(电气电子工程师学会,VHDL等)。 [关闭]

StackOverflow https://stackoverflow.com/questions/326880

  •  11-07-2019
  •  | 
  •  

什么样的最佳做法,应当可以观察到在执行高密度脂蛋白的代码?

有什么共同点和差异时相比更常见的软件开发领域?

有帮助吗?

解决方案

关于这个主题的最好的书是 重用方法手册. 。它涵盖了 VHDL 和 Verilog。

特别是一些软件中没有完全匹配的问题:

  • 无闩锁
  • 小心重置
  • 检查你的内部和外部时间安排
  • 仅使用可合成的代码
  • 注册所有模块的输出
  • 小心阻塞与阻塞非阻塞分配
  • 小心组合逻辑的敏感列表(或在 Verilog 中使用 @(*))

一些相同的包括

  • 使用CM
  • 有代码审查
  • 测试(模拟)您的代码
  • 适当时重用代码
  • 有最新的时间表
  • 有规范或用例或敏捷客户

其他提示

有点旧了,但想投入 0.02 美元。这并不是 Verilog/VHDL 特有的。更多关于一般硬件设计的信息...针对定制 ASIC 的专门可综合设计。

这是我的 观点 基于多年的行业(而不是学术)设计经验。它们没有特定的顺序

我的总括声明是为验证执行而设计。在硬件设计中,验证至关重要。在实际硅中发现缺陷的成本要高得多。你不能只是重新编译。因此,硅前技术受到更多关注。

  • 了解控制路径和数据路径之间的区别。这使您能够创建更优雅且可维护的代码。还允许您保存门并最小化 X 传播。例如,数据路径永远不需要可复位触发器,控制路径应该始终需要它。

  • 在验证之前证明功能。通过正式方法或通过波形。这有很多优点,我将解释2。首先,它可以节省您因解决问题而浪费的洋葱剥皮时间。与许多应用程序级设计(尤其是学习时)和大多数课程作业不同,代码更改的周转时间非常长(从 10 分钟到几天不等,具体取决于复杂性)。每次更改代码时,都需要经过详细阐述、lint 检查、编译、波形调出,最后进行实际仿真。这本身可能需要几个小时。其次,你不太可能遇到难以遇到的极端情况。请注意,这是关于硅前验证。这些肯定会在硅后出现,花费你很多钱。相信我,证明功能的前期成本极大地降低了风险,并且非常值得付出努力。有时很难说服刚毕业的大学毕业生。

  • 吃“鸡块”。Chicken 位是 MMIO 中通过驱动程序设置的位,用于禁用芯片中的某个功能。它的目的是恢复置信度不高的更改(置信度与验证工作成正比)。在硅前达到所有可能的状态几乎是不可能的。只有在硅后验证后才能真正满足您对设计的信心。即使只有 1 个状态在 0.000005% 的时间内出现暴露 bug,它也会在投片后出现,但不一定在投片前出现。

  • 不惜一切代价避免控制路径中出现异常。每遇到一个新的异常,您的验证工作都会加倍。这个很难解释。假设有一个 DMA 块会将数据保存到内存中,供另一个块使用。可以说保存的数据结构取决于正在执行的某些功能。如果您决定进行设计,使不同函数之间保存的数据结构不同,则只需将验证工作乘以 DMA 函数的数量即可。如果遵循此规则,则保存的数据结构将是对内容位置进行硬编码的每个函数可用的所有数据的超集。一旦 DMA 保存逻辑针对 1 个功能进行了验证,那么它就对所有功能进行了验证。

  • 最小化接口(请阅读最小化控制路径)。这与最小化异常有关。首先,每个新接口都需要验证。这包括测试平台中的新检查器/跟踪器、断言、覆盖点和总线功能模型。其次,它可以成倍地增加您的验证工作!假设您有 1 个用于读取缓存中数据的接口。现在假设(出于某种奇怪的原因)您决定需要另一个接口来读取主内存。您刚刚将验证工作量增加了四倍。您现在需要在任何给定时间验证这些组合 n:

    • 没有缓存读取,没有内存读取
    • 无缓存读取,内存读取
    • 读取缓存,不读取内存
    • 缓存读取、内存读取
  • 理解并传达假设。缺乏这一点是块间通信问题的主要原因。您可以拥有一个经过充分验证的完美区块。但是,如果不理解所有假设,您的块在连接时将会失败。

  • 最小化潜在状态。设计的状态(有意或无意)越少,验证所需的工作就越少。将类似的函数分组为 1 个顶级函数(如排序器和仲裁器)是一种很好的做法。识别和定义这个高级函数以使其包含尽可能多的较小函数是非常困难的,但这样做可以极大地消除状态,从而消除潜在的错误。

  • 始终提供离开您所在街区的强烈信号。大多数时候,失败就是解决方案。您不知道端点块将用它做什么。您可能会遇到时间问题,这可能会直接影响您的完美实施。

  • 除非性能受到负面影响,否则应避免使用粉状 FSM。与摩尔相比,Mealy FSM 更有可能产生时序问题

  • ..最后是我最不喜欢的:“如果它没有坏,就不要修复它” 由于涉及的风险和错误的高昂成本,很多时候黑客攻击是解决问题的更实际的解决方案。其他人则通过提及现有组件的利用来回避这一点。

至于对比更多 传统的 软件设计:

  • 离散事件驱动编程是一种完全不同的范例。人们看到 verilog 语法并想“哦,它就像 C 一样”......然而,这与事实相差甚远。尽管语法相似,但人们必须以不同的方式思考。例如,传统的调试器在可综合 RTL 上实际上毫无意义(测试平台设计不同)。纸上波形是最好的工具。然而,话虽这么说,FSM 设计有时可以模仿程序编程。有软件背景的人往往会对 FSM 着迷(我知道我一开始就是这么做的)。

  • System Verilog 有很多很多(很多)测试平台的特定功能。它是完全面向对象的。就测试平台设计而言,它与传统的软件设计非常相似。然而,它确实还有另一个与之相关的维度,即时间。必须考虑竞争条件和协议延迟

  • 至于验证,也是不同的(也是相同的)。有3种主要方法;

    • 形式传播验证(FPV):你通过逻辑证明它永远有效
    • 定向随机测试。根据种子的定义随机设置延迟、输入值和功能启用。 指导的 意味着种子将权重放在信心较低的路径上。此方法使用覆盖点来指示健康状况
    • 重点测试。这与传统的软件测试类似

...为了完整起见,我还需要讨论最佳测试台设计实践......但那是另一天的事了

抱歉长度..我在“区域”:)

HDL的像Verilog和VHDL似乎真的鼓励面条代码。大多数模块由若干个“总是”(Verilog的)的或“过程”(VHDL)嵌段,可以是任何顺序。该模块的整体算法或功能通常完全遮蔽。搞清楚代码是如何工作的(如果你没有写它)是一个痛苦的过程。

几年前我遇到它概述了一个更有条理的方法,本文 VHDL设计。的基本思想是,每个模块都具有唯一2处理块。一个用于组合的代码,以及其他为同步(寄存器)。这是伟大的生产可读和可维护的代码。

  • 在HDL中,代码的某些部分可以同时工作,例如两行代码“可以同时工作”,这是一个优点,要明智地使用。对于习惯了逐行语言的程序员来说,一开始可能会觉得很难理解:

    • 可以根据您的需求创建长且特定的管道。
    • 您可以让您的大模块同时工作。
    • 您可以创建多个单元并并行执行工作,而不是使用一个单元对不同数据执行重复操作。
  • 应特别注意启动过程 - 一旦您的芯片正常工作,您就已经取得了巨大的进步。

硬件调试通常比软件调试困难得多,因此:

  • 首选简单的代码,有时还有其他方法可以加速您的代码,例如使用更高的速度芯片等。

  • 避免组件之间的“智能”协议。

  • HDL 中的工作代码比其他软件更珍贵,因为硬件很难调试,因此要重用,并且还要考虑使用模块的“库”,其中一些是免费的,另一些是出售的。

  • 设计不仅应该考虑 HDL 代码中的错误,还应该考虑正在编程的芯片以及与该芯片接口的其他硬件设备上的故障,因此应该真正考虑一种易于检查的设计。

一些调试技巧:

  • 如果一项设计包含多个构建块,人们可能希望创建从这些块之间的接口到芯片外部测试点的线路。

  • 您需要在设计中保存足够的线路,以转移有趣的数据以使用外部设备进行检查。另外,您可以使用此行,而您的代码作为告诉您当前执行状态的一种方式 - 例如,如果您在某个时候接收到数据,则在执行的后期为行编写一些值,您可以编写另一个值, ETC'

    如果您的芯片是可重新配置的,这将变得更加方便,因为您可以定制特定的测试,并在进行时为每个测试重新编程输出(这对于 LED 来说看起来非常好:)。)

编辑:

我所说的智能协议是指,如果两个物理单元连接,它们应该使用最简单的可用通信协议进行通信。也就是说,在它们之间不要使用任何复杂的自制协议。

原因是 - fpga/asic fidning错误在您拥有模拟器时非常容易。因此,如果您确定数据会按照自己的需求进行,并且随着程序发送时,您已经到达了硬件乌托邦 - 能够在软件级别上工作:)(使用模拟器)。但是,如果您的数据没有按照您想要的方式到达您身边,那么您必须找出原因......你必须连接到线路,这并不容易。

查找线路上的错误非常困难,因为您必须使用特殊设备连接到线路,记录线路在不同时间的状态,并且您必须确保线路按照协议运行。

如果您需要连接两个物理单位,请尽可能简单地使“协议”变得简单,直到它不会称为协议:)例如,如果单元共享时钟,请在它们之间添加x数据行,使一个单元写下那些单元和另一个单元读取,从而传递一个“单词”,例如,每个时钟之间都有x位。如果您有 FPGA,如果原始时钟速率对于并行数据来说太快,您可以根据您的实验控制其速度,例如使数据保持在至少“t”个时钟周期等的线上。我认为并行数据传输更简单,因为您可以以较低的时钟速率工作并获得相同的性能,而无需在一个单元上拆分字,然后在另一个单元上重新组装。(希望每个单元接收到的“时钟”之间没有延迟)。即使这可能也太复杂了:)

关于SPI,I2C等,我还没有实施任何一个,我可以说我已经连接了两个FPGA的腿,从同一时钟运行(不记得中间电阻的确切形成),很大程度上是较高的价格,所以我真的想不到使用这些的理由,除非FPGA的位置很远,否则将其用作传递数据的主要方式比平行的巴士。

JTAG 被一些 FPGA 公司用来测试/编程他们的产品,但不确定它是否用作高速传输数据的方式,它是一种协议......(仍然可能有一些内置的芯片支持)。

如果您确实必须实现任何已知的协议,请考虑使用预制的 HDL 代码 - 可以找到或购买该代码。

这是需要JBDAVID硬件设计10条戒律的问题。

  1. 使用修订/版本控制,就像在软件中一样。SVN 和 Hg 是免费的。
  2. 要求代码在签入之前通过语法检查。LINT 工具更好。
  3. 使用全强度硬件验​​证语言进行设计验证。System-Verilog 几乎是一个安全的选择。
  4. 跟踪错误。Bugzilla 和 GNATS 是免费工具。FogBugz 需要一点美元。
  5. 使用断言来捕获错误使用的问题。
  6. 覆盖三合一可实现稳定的设计:在模拟和正式工具中测量代码覆盖率、功能覆盖率和断言覆盖率。
  7. 权力为王:使用 CPF 或 UPF 来捕获、执行和验证您的权力意图。
  8. 真正的设计通常是混合信号,使用混合信号语言来验证模拟与数字。Verilog-AMS 就是这样一种解决方案。但不要太过分。实数建模可以完成混合信号行为的大部分功能。
  9. 使用硬件加速来验证必须与芯片配合使用的软件!
  10. 适用于 HDL/HVL 的语法感知文本编辑器是开发人员 IDE 的最低要求。

为Fpga赛灵思了 这页.几乎所有的将适用于其他FPGA供应商,或者将具有同等的规则。一个很大的是适用于ASIC的设计。

英特尔建议HDL编码的风格和设计的建议(PDF)根据这一页.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top