硬件描述语言的最佳实践是什么(Verilog,VHDL等)

时间:2022-04-11 20:23:12

What best practices should be observed when implementing HDL code?

实施HDL代码时应注意哪些最佳实践?

What are the commonalities and differences when compared to more common software development fields?

与更常见的软件开发领域相比,有哪些共性和差异?

6 个解决方案

#1


45  

The best book on this topic is Reuse Methodology Manual. It covers both VHDL and Verilog.

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

And in particular some issues that don't have an exact match in software:

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

  • No latches
  • Be careful with resets
  • 小心重置

  • Check your internal and external timing
  • 检查内部和外部时间

  • Use only synthesizable code
  • 仅使用可合成代码

  • Register your outputs of all modules
  • 注册所有模块的输出

  • Be careful with blocking vs. non-blocking assignments
  • 小心阻塞与非阻塞分配

  • Be careful with sensitive lists for combinatorial logic (or use @(*) in Verilog)
  • 小心组合逻辑的敏感列表(或在Verilog中使用@(*))

Some that are the same include

一些相同的包括

  • Use CM
  • Have code reviews
  • 有代码审查

  • Test (simulate) your code
  • 测试(模拟)您的代码

  • Reuse code when appropriate
  • 适当时重用代码

  • Have an up-to-date schedule
  • 有一个最新的时间表

  • Have a spec or use cases or an Agile customer
  • 有规范或用例或敏捷客户

#2


58  

Sort of an old thread, but wanted to put in my $0.02. This isn't really specific to Verilog/VHDL.. more on hardware design in general... specifically synthesizable design for custom ASICs.

一个旧线程的排序,但想要我的0.02美元。这并非真正特定于Verilog / VHDL ..更多关于硬件设计的信息......特别是针对定制ASIC的可综合设计。

This is my opinion based on years of industry (as opposed to academic) experience on design. They are in no particular order

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

My umbrella statement is to Design for validation execution. In hardware design, validation is paramount. Bugs are a lot more expensive when found in actual silicon. You can't just re-compile. Therefore, pre-silicon is given much more focus.

我的总结声明是Design for validation execution。在硬件设计中,验证是至关重要的。当在实际的硅中发现时,错误要贵得多。你不能只是重新编译。因此,预硅更受关注。

  • Know the difference between control paths and data paths. This enables you to create much more elegant and maintainable code. Also allows you to save gates and minimize X propagation. For instance, data paths should never need resettable flops, control paths should always need it.

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

  • Prove functionality before validation. Either through a formal approach or through waveforms. This has many advantages, I will explain 2. First, it will save you wasted time onion peeling through issues. Unlike lots of application level design (esp while learning) and most course work, the turn-around time for code changes is very large (anywhere from 10 minutes to days, depending on complexity). Every time you change code, you need to go through elaboration, lint checking, compiling, waveform bring-up, and finally actual simulation.. which can itself take hours. Second, you are much less likely to have difficult to hit corner cases. Note this is with respect to pre-silicon validation. These will surely hit at post-silicon costing you lots of $$$. Trust me, the up front cost of proving functionality greatly minimizes risk and is well worth the effort. This is sometimes difficult to convince recent college grads.

    验证前证明功能。通过正式方法或通过波形。这有很多优点,我将解释2.首先,它将节省你浪费时间洋葱剥皮问题。与许多应用程序级别设计(尤其是学习时)和大多数课程工作不同,代码更改的周转时间非常长(根据复杂程度,从10分钟到数天不等)。每次更改代码时,都需要经过详细说明,lint检查,编译,波形启动,最后进行实际模拟......这本身可能需要数小时。其次,你不太可能遇到困难的角落案件。请注意,这与硅前验证有关。这些肯定会在后硅片上花费你很多$$$。相信我,证明功能的前期成本大大降低了风险,非常值得付出努力。这有时难以说服最近的大学毕业生。

  • Have "chicken bits". Chicken bits are bits in MMIO set via the driver to disable a feature in silicon. It's intended to revert changes made in which confidence is not high (confidence is directly proportional to validation efforts). It is next to impossible to hit every possible state in pre-silicon. Confidence on your design cannot truly be met until it's proven in post-silicon. Even if there is only 1 state that is hit 0.000005% of the time that exposes the bug, it WILL HIT in post-silicon, but not necessarily in pre-silicon.

    有“鸡块”。鸡位是通过驱动程序设置的MMIO中的位,以禁用硅中的功能。它旨在恢复信心不高的变化(置信度与验证工作成正比)。在硅之前几乎不可能达到每种可能的状态。只有在后硅片中证明,才能真正满足您对设计的信心。即使只有1个状态在暴露出错误的时间内达到0.000005%,它也会在后硅片中出现,但不一定在预制硅片中。

  • Avoid exceptions in the control path at all costs. Every new exception you have doubles your validation efforts. This one is hard to explain. Lets say there is a DMA block that will save out data to memory that another block will use. Lets say the data structure saved out is dependent on some function being done. If you decided to design such that the data structure saved was different between different functions, you just multiplied your validation efforts by the number of DMA functions. If this rule is followed, the data structure saved out would be a super-set of all data available for every function where the content locations are hardcoded. Once the DMA save logic is validated for 1 function its validated for all functions.

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

  • Minimize interfaces (read minimize control paths). This is related to minimizing exceptions. First, every new interface requires validation. This includes new checkers/trackers, assertions, coverage points, and bus functional models in your testbench. Secondly, it can increase your validation efforts exponentially! Lets say you have 1 interface for reading data in caches. Now lets say (for some odd reason) you decide you want another interface for reading main memory. You just quadrupled your validation efforts. You now need to validate these combinations at any given time n:

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

    • no cache read, no memory read
    • 没有缓存读取,没有内存读取

    • no cache read, memory read
    • 没有缓存读取,内存读取

    • cache read, no memory read
    • 缓存读取,无内存读取

    • cache read, memory read
    • 缓存读取,内存读取

  • Understand and communicate assumptions. Lacking this is the main reason for block to block communication issues. You could have a perfect block fully validated.. however, without understanding all assumptions, your block will fail when its connected.

    理解并传达假设。缺乏这是阻止通信问题的主要原因。您可以完全验证完美的块。但是,如果不了解所有假设,您的块将在连接时失败。

  • Minimize potential states. The less states (intended or unintended) a design has, the less effort required to validate. It's good practice to group like functions into 1 top level function (like sequencers and arbiters). It is very difficult to identify and define this high level function such that it encompasses as many smaller functions as possible, but in doing so you vastly eliminate state and in turn potential for bugs.

    尽量减少潜在的状态。设计所处的状态越少(有意或无意),验证所需的工作量就越少。将类似函数分组为1个*函数(如序列发生器和仲裁器)是一种很好的做法。识别和定义这个高级函数非常困难,因此它包含尽可能多的较小函数,但这样做可以大大消除状态,从而可能导致错误。

  • Always provide a strong signal leaving your block. Most of the time flopping it is the solution. You have no idea what the endpoint block(s) will do with it. You could run into timing issues which can have a direct impact on your perfect implementation.

    始终提供强大的信号离开你的街区。大部分时间都是解决方案。您不知道端点块将使用它做什么。您可能会遇到可能对您的完美实施产生直接影响的计时问题。

  • Avoid mealy type FSMs unless performance is negatively impacted. Mealy FSMs are more likely to produce timing issues over Moore

    除非性能受到负面影响,否则请避免使用类型FSM。 Mealy FSM更有可能产生超过摩尔的时间问题

  • .. and finally the one I dislike the most: "if it ain't broke, don't fix it" Because of the risk involved and the high cost of bugs, many times hacking is a more practical solution to solving problems. Others have eluded to this by mentioning utilization of existing components.

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

As for comparing against more traditional software design:

至于与更传统的软件设计进行比较:

  • discrete event driven programming is a completely different paradigm. People see verilog syntax and think "oh, its just like C"... however, this cannot be further from the truth. Although the syntax is similar, one must think differently. For example, a traditional debugger is virtually meaningless on synthesizable RTL (Testbench design is different). Waveforms on paper are the best tool available. However, that being said, FSM design can at times mimic procedural programming. People with a software background tend to go crazy with FSMs (I know I did at first).

    离散事件驱动编程是一种完全不同的范例。人们看到verilog语法,并认为“哦,它就像C”......但是,这不能说实话。虽然语法类似,但必须以不同的方式思考。例如,传统调试器在可综合RTL上几乎毫无意义(Testbench设计不同)。纸上的波形是最好的工具。然而,话虽如此,FSM设计有时可能模仿程序编程。拥有软件背景的人往往会对FSM感到疯狂(我知道我最初做过)。

  • System Verilog has lots and lots (and lots) of testbench specific features. It is completely object oriented. As far as testbench design goes, its very similar to traditional software design. However, it does have 1 more dimension associated with it, that of time. race conditions and protocol delays must be accounted for

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

  • As for validation, it is also different (and the same). There are 3 main approaches;

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

    • Formal propagative verification (FPV): You prove through logic that it will always work
    • 正式传播验证(FPV):您通过逻辑证明它将始终有效

    • Directed random testing. Randomly set delays, input values, and feature enabling as defined by a seed. directed means that the seed puts weight on paths that have less confidence. This approach uses coverage points to indicate health
    • 定向随机测试。随机设置种子定义的延迟,输入值和特征启用。定向意味着种子将重量放在信心不足的路径上。该方法使用覆盖点来指示健康

    • Focus testing. This is similar to traditional software testing
    • 重点测试。这类似于传统的软件测试

... for completeness, I need to also discuss best test-bench design practices... but that's for another day

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

Sorry for the length.. I was in "The Zone" :)

对不起,长度......我在“The Zone”:)

#3


25  

HDL's like Verilog and VHDL really seem to encourage spaghetti code. Most modules consist of several 'always' (Verilog) or 'process' (VHDL) blocks that can be in any order. The overall algorithm or function of the module is often totally obscured. Figuring out how the code works (if you didn't write it) is a painful process.

像Verilog和VHDL这样的HDL似乎真的鼓励意大利面条代码。大多数模块由几个“始终”(Verilog)或“进程”(VHDL)块组成,可以按任何顺序排列。模块的整体算法或功能通常是完全模糊的。弄清楚代码是如何工作的(如果你没有编写代码)是一个痛苦的过程。

A few years ago I came across this paper that outlines a more structured method for VHDL design. The basic idea is that each module has only 2 process blocks. One for combinatorial code, and other for synchronous (the registers). It is great for producing readable and maintainable code.

几年前,我遇到了这篇文章,概述了一种更加结构化的VHDL设计方法。基本思想是每个模块只有2个过程块。一个用于组合代码,另一个用于同步(寄存器)。它非常适合生成可读和可维护的代码。

#4


6  

  • in HDL, some parts of the code can work at the same time, for example two lines of code "can work" at the same time, this is an advantage, to use wisely. this is something that a programmer who is accustomed to line by line languages may find hard to grasp at first:

    在HDL中,代码的某些部分可以同时工作,例如两行代码“可以同时工作”,这是一个优点,明智地使用。这是习惯于逐行语言的程序员最初可能很难掌握的东西:

    • Long and specific for your needs pipelines can be created.
    • 可以创建长而且特定的需求管道。

    • You can make your big modules work at the same time.
    • 您可以让您的大模块同时工作。

    • instead of one unit to do a repeated action on different data, you can create several units, and do the work in parallel.
    • 而不是一个单元对不同的数据进行重复操作,您可以创建多个单元,并行地进行工作。

  • Special attention should be given to the booting process - once your chip is functional, you have made a huge way.

    应特别注意启动过程 - 一旦你的芯片正常运行,你已经做了很大的工作。

Debugging on hardware is usually much harder than debugging software so:

在硬件上进行调试通常比调试软件困难得多:

  • Simple code is preferred, sometimes there are other ways to speed-up your code, after it is already running, for example using an higher speed chip, etc'.

    简单的代码是首选,有时还有其他方法可以在代码运行后加速代码,例如使用更高速的芯片等。

  • Avoid "smart" protocols between components.

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

  • A working code in HDL is more precious than on other software, as hardware is so hard to debug, so reuse, and also consider using "libraries" of modules which some are free and others sold.

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

  • designing should consider not only bugs in the HDL code, but also failures on the chip you are programming, and on other hardware devices that interface with the chip, so one should really think about a design that is easy to check.

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

Some debugging tips:

一些调试技巧:

  • If a design includes several building blocks, one would probably want to create lines from the interfaces between those blocks to testing points outside the chip.

    如果设计包含多个构建块,则可能需要从这些块之间的接口创建线到芯片外部的测试点。

  • You will want to save enough lines in your design to divert interesting data to be inspected with external devices. also you can use this lines, and your code as a way of telling you the current state of execution - for example if you receive data at some point, you write some value to the lines, at a later stage of execution you write another value, etc'

    您需要在设计中保存足够的线条,以转移有趣的数据,以便使用外部设备进行检查。你也可以使用这一行,并将你的代码作为告诉你当前执行状态的一种方式 - 例如,如果你在某个时刻收到数据,你就会给行写一些值,在执行的后期你写另一个值等等'

    If your chip is reconfigurable this will become even more handy, as you can tailor specific tests, and reprogram the outputs for each test as you go (this looks very well with leds :). )

    如果你的芯片是可重新配置的,这将变得更加方便,因为你可以定制特定的测试,并在你去的时候重新编程每个测试的输出(这与leds :)非常相似。 )

Edit:

By smart protocols, I've meant that should two of your physical units connect, they should communicate with the simplest communication protocol available. that is, do not use any sophisticated home-made protocols, between them.

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

The reason, is this - Fidning bugs "inside" an FPGA/ASIC is reletivly easy as you have simulators. So if you are sure that data comes as you want it, and goes out as your program sends it, you've reached Hardware utopia - being able to work at software level :) (with the simulator). But if your data doesn't get to you, the way you want it to, and you have to figure out why... you'll have to connect to the lines, and that's not that easy.

原因是这样的 - 因为你有模拟器,所以在FPGA / ASIC内部“填补”错误相当容易。因此,如果您确定数据按照您的需要进行,并在程序发送时熄灭,那么您已达到硬件乌托邦 - 能够在软件级别工作:)(使用模拟器)。但是如果你的数据没有找到你想要它的方式,你必须找出原因......你必须连接到线路,这并不容易。

Finding a bug on the lines, is hard as you have to connect to the lines with special equipment, that record the states of the lines, on different times, and you'll have to make sure your lines act according to the protocol.

找到线路上的错误是很困难的,因为你必须连接到具有特殊设备的线路,记录线路的状态,在不同的时间,你必须确保你的线路按照协议行事。

If you need to connect two of your physical units make the "protocol" as simple as it can , up to the point it won't be called a protocol :) For example if the units share a clock, add x data lines between them, and make one unit write those and the other unit read, thus passing one "word" which has x bits between them on each clock fall, for example. If you have FPGA's, should the original clock rate be too fast for parallel data - you can control the speed of this, according to your experiments, for example making the data stay on lines of at least 't' clock cycles etc'. I assume parallel data transfer is simpler, as you can work with at lower clock rates and get the same performances, without the need to split your words on one unit, and reassemble on the other. (hopefully there is no delay between the 'clock' each unit receives). Even this is probably too complex :)

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

Regarding SPI, I2C etc' I haven't implemented any of them, I can say that I've connected legs of two FPGA's running from the same clock, (don't remember the exact formation of resistors in the middle), at much higher rates, so I really can't think of a good reason to use those, as the main way to pass data between your own FPGA's, unless the FPGA's are located very far one from another, which is one reason to use a serial rather than a parallel bus.

关于SPI,I2C等'我还没有实现它们中的任何一个,我可以说我已经连接了两个从同一个时钟运行的FPGA的脚,(不记得中间电阻的确切形成),很多更高的速率,所以我真的想不出使用它们的一个很好的理由,作为在你自己的FPGA之间传递数据的主要方式,除非FPGA位于彼此很远的地方,这是使用串口的一个原因而不是并行总线。

JTAG is used by some FPGA companies, to test/program their products, but not sure if it's used as way to transport data at high speeds, and It is a protocol... (still one which may have some built-in on chip support).

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

If you do have to implement any known protocol, consider using a pre-made HDL code for this - which can be found or purchased.

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

#5


5  

This is the question that requires JBDAVID's 10 commandments for Hardware design.

  1. Use Revision/Version Control, just like in Software. SVN and Hg are free.
  2. 使用版本/版本控制,就像在软件中一样。 SVN和Hg是免费的。

  3. Require the code to pass syntax checking before check-in. A LINT tool is better.
  4. 要求代码在签入前通过语法检查。 LINT工具更好。

  5. Use a full-strength Hardware Verification Language for design Verification. System-Verilog is nearly a safe choice.
  6. 使用全强度硬件验​​证语言进行设计验证。 System-Verilog几乎是一个安全的选择。

  7. Track Bugs. Bugzilla and GNATS are free tools. FogBugz requires a little $.
  8. 跟踪错误。 Bugzilla和GNATS是免费工具。 FogBugz需要一点钱。

  9. Use Assertions to catch issues with incorrect use.
  10. 使用断言来捕获错误使用的问题。

  11. The Coverage Triad makes for a stable design: Measure Code coverage, Functional coverage and Assertion coverage in both simulation and formal tools.
  12. Coverage Triad实现了稳定的设计:在模拟和正式工具中测量代码覆盖率,功能覆盖率和断言覆盖率。

  13. Power is King: use CPF or UPF to capture, enforce and verify your Power-Intent.
  14. Power is King:使用CPF或UPF来捕获,执行和验证您的Power-Intent。

  15. the real design is often mixed signal, Use a Mixed-Signal language to verify the analog with the digital. Verilog-AMS is one such solution. But don't go overboard. Realnumber modeling can accomplish most of the functional aspects of mixed-signal behavior.
  16. 真正的设计通常是混合信号,使用混合信号语言来验证模拟与数字。 Verilog-AMS就是这样一种解决方案。但不要过火。 Realnumber建模可以完成混合信号行为的大多数功能方面。

  17. Use Hardware Acceleration to validate the Software that has to work with the silicon!
  18. 使用硬件加速来验证必须使用芯片的软件!

  19. Syntax Aware text editors for your HDL/HVL are a minimum requirement for developer IDE.
  20. 语法Aware HDL / HVL的文本编辑器是开发人员IDE的最低要求。

#6


4  

For FPGAs, Xilinx has this page. Almost all would apply to other FPGA vendors, or would have equivalent rules. A great deal is applicable to ASIC designs.

对于FPGA,Xilinx有此页面。几乎所有这些都适用于其他FPGA供应商,或者具有相同的规则。很多适用于ASIC设计。

Intel has Recommended HDL Coding Styles and Design Recommendations(PDF)under this page.

英特尔在此页面下推荐了HDL编码样式和设计建议(PDF)。

#1


45  

The best book on this topic is Reuse Methodology Manual. It covers both VHDL and Verilog.

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

And in particular some issues that don't have an exact match in software:

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

  • No latches
  • Be careful with resets
  • 小心重置

  • Check your internal and external timing
  • 检查内部和外部时间

  • Use only synthesizable code
  • 仅使用可合成代码

  • Register your outputs of all modules
  • 注册所有模块的输出

  • Be careful with blocking vs. non-blocking assignments
  • 小心阻塞与非阻塞分配

  • Be careful with sensitive lists for combinatorial logic (or use @(*) in Verilog)
  • 小心组合逻辑的敏感列表(或在Verilog中使用@(*))

Some that are the same include

一些相同的包括

  • Use CM
  • Have code reviews
  • 有代码审查

  • Test (simulate) your code
  • 测试(模拟)您的代码

  • Reuse code when appropriate
  • 适当时重用代码

  • Have an up-to-date schedule
  • 有一个最新的时间表

  • Have a spec or use cases or an Agile customer
  • 有规范或用例或敏捷客户

#2


58  

Sort of an old thread, but wanted to put in my $0.02. This isn't really specific to Verilog/VHDL.. more on hardware design in general... specifically synthesizable design for custom ASICs.

一个旧线程的排序,但想要我的0.02美元。这并非真正特定于Verilog / VHDL ..更多关于硬件设计的信息......特别是针对定制ASIC的可综合设计。

This is my opinion based on years of industry (as opposed to academic) experience on design. They are in no particular order

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

My umbrella statement is to Design for validation execution. In hardware design, validation is paramount. Bugs are a lot more expensive when found in actual silicon. You can't just re-compile. Therefore, pre-silicon is given much more focus.

我的总结声明是Design for validation execution。在硬件设计中,验证是至关重要的。当在实际的硅中发现时,错误要贵得多。你不能只是重新编译。因此,预硅更受关注。

  • Know the difference between control paths and data paths. This enables you to create much more elegant and maintainable code. Also allows you to save gates and minimize X propagation. For instance, data paths should never need resettable flops, control paths should always need it.

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

  • Prove functionality before validation. Either through a formal approach or through waveforms. This has many advantages, I will explain 2. First, it will save you wasted time onion peeling through issues. Unlike lots of application level design (esp while learning) and most course work, the turn-around time for code changes is very large (anywhere from 10 minutes to days, depending on complexity). Every time you change code, you need to go through elaboration, lint checking, compiling, waveform bring-up, and finally actual simulation.. which can itself take hours. Second, you are much less likely to have difficult to hit corner cases. Note this is with respect to pre-silicon validation. These will surely hit at post-silicon costing you lots of $$$. Trust me, the up front cost of proving functionality greatly minimizes risk and is well worth the effort. This is sometimes difficult to convince recent college grads.

    验证前证明功能。通过正式方法或通过波形。这有很多优点,我将解释2.首先,它将节省你浪费时间洋葱剥皮问题。与许多应用程序级别设计(尤其是学习时)和大多数课程工作不同,代码更改的周转时间非常长(根据复杂程度,从10分钟到数天不等)。每次更改代码时,都需要经过详细说明,lint检查,编译,波形启动,最后进行实际模拟......这本身可能需要数小时。其次,你不太可能遇到困难的角落案件。请注意,这与硅前验证有关。这些肯定会在后硅片上花费你很多$$$。相信我,证明功能的前期成本大大降低了风险,非常值得付出努力。这有时难以说服最近的大学毕业生。

  • Have "chicken bits". Chicken bits are bits in MMIO set via the driver to disable a feature in silicon. It's intended to revert changes made in which confidence is not high (confidence is directly proportional to validation efforts). It is next to impossible to hit every possible state in pre-silicon. Confidence on your design cannot truly be met until it's proven in post-silicon. Even if there is only 1 state that is hit 0.000005% of the time that exposes the bug, it WILL HIT in post-silicon, but not necessarily in pre-silicon.

    有“鸡块”。鸡位是通过驱动程序设置的MMIO中的位,以禁用硅中的功能。它旨在恢复信心不高的变化(置信度与验证工作成正比)。在硅之前几乎不可能达到每种可能的状态。只有在后硅片中证明,才能真正满足您对设计的信心。即使只有1个状态在暴露出错误的时间内达到0.000005%,它也会在后硅片中出现,但不一定在预制硅片中。

  • Avoid exceptions in the control path at all costs. Every new exception you have doubles your validation efforts. This one is hard to explain. Lets say there is a DMA block that will save out data to memory that another block will use. Lets say the data structure saved out is dependent on some function being done. If you decided to design such that the data structure saved was different between different functions, you just multiplied your validation efforts by the number of DMA functions. If this rule is followed, the data structure saved out would be a super-set of all data available for every function where the content locations are hardcoded. Once the DMA save logic is validated for 1 function its validated for all functions.

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

  • Minimize interfaces (read minimize control paths). This is related to minimizing exceptions. First, every new interface requires validation. This includes new checkers/trackers, assertions, coverage points, and bus functional models in your testbench. Secondly, it can increase your validation efforts exponentially! Lets say you have 1 interface for reading data in caches. Now lets say (for some odd reason) you decide you want another interface for reading main memory. You just quadrupled your validation efforts. You now need to validate these combinations at any given time n:

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

    • no cache read, no memory read
    • 没有缓存读取,没有内存读取

    • no cache read, memory read
    • 没有缓存读取,内存读取

    • cache read, no memory read
    • 缓存读取,无内存读取

    • cache read, memory read
    • 缓存读取,内存读取

  • Understand and communicate assumptions. Lacking this is the main reason for block to block communication issues. You could have a perfect block fully validated.. however, without understanding all assumptions, your block will fail when its connected.

    理解并传达假设。缺乏这是阻止通信问题的主要原因。您可以完全验证完美的块。但是,如果不了解所有假设,您的块将在连接时失败。

  • Minimize potential states. The less states (intended or unintended) a design has, the less effort required to validate. It's good practice to group like functions into 1 top level function (like sequencers and arbiters). It is very difficult to identify and define this high level function such that it encompasses as many smaller functions as possible, but in doing so you vastly eliminate state and in turn potential for bugs.

    尽量减少潜在的状态。设计所处的状态越少(有意或无意),验证所需的工作量就越少。将类似函数分组为1个*函数(如序列发生器和仲裁器)是一种很好的做法。识别和定义这个高级函数非常困难,因此它包含尽可能多的较小函数,但这样做可以大大消除状态,从而可能导致错误。

  • Always provide a strong signal leaving your block. Most of the time flopping it is the solution. You have no idea what the endpoint block(s) will do with it. You could run into timing issues which can have a direct impact on your perfect implementation.

    始终提供强大的信号离开你的街区。大部分时间都是解决方案。您不知道端点块将使用它做什么。您可能会遇到可能对您的完美实施产生直接影响的计时问题。

  • Avoid mealy type FSMs unless performance is negatively impacted. Mealy FSMs are more likely to produce timing issues over Moore

    除非性能受到负面影响,否则请避免使用类型FSM。 Mealy FSM更有可能产生超过摩尔的时间问题

  • .. and finally the one I dislike the most: "if it ain't broke, don't fix it" Because of the risk involved and the high cost of bugs, many times hacking is a more practical solution to solving problems. Others have eluded to this by mentioning utilization of existing components.

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

As for comparing against more traditional software design:

至于与更传统的软件设计进行比较:

  • discrete event driven programming is a completely different paradigm. People see verilog syntax and think "oh, its just like C"... however, this cannot be further from the truth. Although the syntax is similar, one must think differently. For example, a traditional debugger is virtually meaningless on synthesizable RTL (Testbench design is different). Waveforms on paper are the best tool available. However, that being said, FSM design can at times mimic procedural programming. People with a software background tend to go crazy with FSMs (I know I did at first).

    离散事件驱动编程是一种完全不同的范例。人们看到verilog语法,并认为“哦,它就像C”......但是,这不能说实话。虽然语法类似,但必须以不同的方式思考。例如,传统调试器在可综合RTL上几乎毫无意义(Testbench设计不同)。纸上的波形是最好的工具。然而,话虽如此,FSM设计有时可能模仿程序编程。拥有软件背景的人往往会对FSM感到疯狂(我知道我最初做过)。

  • System Verilog has lots and lots (and lots) of testbench specific features. It is completely object oriented. As far as testbench design goes, its very similar to traditional software design. However, it does have 1 more dimension associated with it, that of time. race conditions and protocol delays must be accounted for

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

  • As for validation, it is also different (and the same). There are 3 main approaches;

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

    • Formal propagative verification (FPV): You prove through logic that it will always work
    • 正式传播验证(FPV):您通过逻辑证明它将始终有效

    • Directed random testing. Randomly set delays, input values, and feature enabling as defined by a seed. directed means that the seed puts weight on paths that have less confidence. This approach uses coverage points to indicate health
    • 定向随机测试。随机设置种子定义的延迟,输入值和特征启用。定向意味着种子将重量放在信心不足的路径上。该方法使用覆盖点来指示健康

    • Focus testing. This is similar to traditional software testing
    • 重点测试。这类似于传统的软件测试

... for completeness, I need to also discuss best test-bench design practices... but that's for another day

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

Sorry for the length.. I was in "The Zone" :)

对不起,长度......我在“The Zone”:)

#3


25  

HDL's like Verilog and VHDL really seem to encourage spaghetti code. Most modules consist of several 'always' (Verilog) or 'process' (VHDL) blocks that can be in any order. The overall algorithm or function of the module is often totally obscured. Figuring out how the code works (if you didn't write it) is a painful process.

像Verilog和VHDL这样的HDL似乎真的鼓励意大利面条代码。大多数模块由几个“始终”(Verilog)或“进程”(VHDL)块组成,可以按任何顺序排列。模块的整体算法或功能通常是完全模糊的。弄清楚代码是如何工作的(如果你没有编写代码)是一个痛苦的过程。

A few years ago I came across this paper that outlines a more structured method for VHDL design. The basic idea is that each module has only 2 process blocks. One for combinatorial code, and other for synchronous (the registers). It is great for producing readable and maintainable code.

几年前,我遇到了这篇文章,概述了一种更加结构化的VHDL设计方法。基本思想是每个模块只有2个过程块。一个用于组合代码,另一个用于同步(寄存器)。它非常适合生成可读和可维护的代码。

#4


6  

  • in HDL, some parts of the code can work at the same time, for example two lines of code "can work" at the same time, this is an advantage, to use wisely. this is something that a programmer who is accustomed to line by line languages may find hard to grasp at first:

    在HDL中,代码的某些部分可以同时工作,例如两行代码“可以同时工作”,这是一个优点,明智地使用。这是习惯于逐行语言的程序员最初可能很难掌握的东西:

    • Long and specific for your needs pipelines can be created.
    • 可以创建长而且特定的需求管道。

    • You can make your big modules work at the same time.
    • 您可以让您的大模块同时工作。

    • instead of one unit to do a repeated action on different data, you can create several units, and do the work in parallel.
    • 而不是一个单元对不同的数据进行重复操作,您可以创建多个单元,并行地进行工作。

  • Special attention should be given to the booting process - once your chip is functional, you have made a huge way.

    应特别注意启动过程 - 一旦你的芯片正常运行,你已经做了很大的工作。

Debugging on hardware is usually much harder than debugging software so:

在硬件上进行调试通常比调试软件困难得多:

  • Simple code is preferred, sometimes there are other ways to speed-up your code, after it is already running, for example using an higher speed chip, etc'.

    简单的代码是首选,有时还有其他方法可以在代码运行后加速代码,例如使用更高速的芯片等。

  • Avoid "smart" protocols between components.

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

  • A working code in HDL is more precious than on other software, as hardware is so hard to debug, so reuse, and also consider using "libraries" of modules which some are free and others sold.

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

  • designing should consider not only bugs in the HDL code, but also failures on the chip you are programming, and on other hardware devices that interface with the chip, so one should really think about a design that is easy to check.

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

Some debugging tips:

一些调试技巧:

  • If a design includes several building blocks, one would probably want to create lines from the interfaces between those blocks to testing points outside the chip.

    如果设计包含多个构建块,则可能需要从这些块之间的接口创建线到芯片外部的测试点。

  • You will want to save enough lines in your design to divert interesting data to be inspected with external devices. also you can use this lines, and your code as a way of telling you the current state of execution - for example if you receive data at some point, you write some value to the lines, at a later stage of execution you write another value, etc'

    您需要在设计中保存足够的线条,以转移有趣的数据,以便使用外部设备进行检查。你也可以使用这一行,并将你的代码作为告诉你当前执行状态的一种方式 - 例如,如果你在某个时刻收到数据,你就会给行写一些值,在执行的后期你写另一个值等等'

    If your chip is reconfigurable this will become even more handy, as you can tailor specific tests, and reprogram the outputs for each test as you go (this looks very well with leds :). )

    如果你的芯片是可重新配置的,这将变得更加方便,因为你可以定制特定的测试,并在你去的时候重新编程每个测试的输出(这与leds :)非常相似。 )

Edit:

By smart protocols, I've meant that should two of your physical units connect, they should communicate with the simplest communication protocol available. that is, do not use any sophisticated home-made protocols, between them.

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

The reason, is this - Fidning bugs "inside" an FPGA/ASIC is reletivly easy as you have simulators. So if you are sure that data comes as you want it, and goes out as your program sends it, you've reached Hardware utopia - being able to work at software level :) (with the simulator). But if your data doesn't get to you, the way you want it to, and you have to figure out why... you'll have to connect to the lines, and that's not that easy.

原因是这样的 - 因为你有模拟器,所以在FPGA / ASIC内部“填补”错误相当容易。因此,如果您确定数据按照您的需要进行,并在程序发送时熄灭,那么您已达到硬件乌托邦 - 能够在软件级别工作:)(使用模拟器)。但是如果你的数据没有找到你想要它的方式,你必须找出原因......你必须连接到线路,这并不容易。

Finding a bug on the lines, is hard as you have to connect to the lines with special equipment, that record the states of the lines, on different times, and you'll have to make sure your lines act according to the protocol.

找到线路上的错误是很困难的,因为你必须连接到具有特殊设备的线路,记录线路的状态,在不同的时间,你必须确保你的线路按照协议行事。

If you need to connect two of your physical units make the "protocol" as simple as it can , up to the point it won't be called a protocol :) For example if the units share a clock, add x data lines between them, and make one unit write those and the other unit read, thus passing one "word" which has x bits between them on each clock fall, for example. If you have FPGA's, should the original clock rate be too fast for parallel data - you can control the speed of this, according to your experiments, for example making the data stay on lines of at least 't' clock cycles etc'. I assume parallel data transfer is simpler, as you can work with at lower clock rates and get the same performances, without the need to split your words on one unit, and reassemble on the other. (hopefully there is no delay between the 'clock' each unit receives). Even this is probably too complex :)

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

Regarding SPI, I2C etc' I haven't implemented any of them, I can say that I've connected legs of two FPGA's running from the same clock, (don't remember the exact formation of resistors in the middle), at much higher rates, so I really can't think of a good reason to use those, as the main way to pass data between your own FPGA's, unless the FPGA's are located very far one from another, which is one reason to use a serial rather than a parallel bus.

关于SPI,I2C等'我还没有实现它们中的任何一个,我可以说我已经连接了两个从同一个时钟运行的FPGA的脚,(不记得中间电阻的确切形成),很多更高的速率,所以我真的想不出使用它们的一个很好的理由,作为在你自己的FPGA之间传递数据的主要方式,除非FPGA位于彼此很远的地方,这是使用串口的一个原因而不是并行总线。

JTAG is used by some FPGA companies, to test/program their products, but not sure if it's used as way to transport data at high speeds, and It is a protocol... (still one which may have some built-in on chip support).

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

If you do have to implement any known protocol, consider using a pre-made HDL code for this - which can be found or purchased.

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

#5


5  

This is the question that requires JBDAVID's 10 commandments for Hardware design.

  1. Use Revision/Version Control, just like in Software. SVN and Hg are free.
  2. 使用版本/版本控制,就像在软件中一样。 SVN和Hg是免费的。

  3. Require the code to pass syntax checking before check-in. A LINT tool is better.
  4. 要求代码在签入前通过语法检查。 LINT工具更好。

  5. Use a full-strength Hardware Verification Language for design Verification. System-Verilog is nearly a safe choice.
  6. 使用全强度硬件验​​证语言进行设计验证。 System-Verilog几乎是一个安全的选择。

  7. Track Bugs. Bugzilla and GNATS are free tools. FogBugz requires a little $.
  8. 跟踪错误。 Bugzilla和GNATS是免费工具。 FogBugz需要一点钱。

  9. Use Assertions to catch issues with incorrect use.
  10. 使用断言来捕获错误使用的问题。

  11. The Coverage Triad makes for a stable design: Measure Code coverage, Functional coverage and Assertion coverage in both simulation and formal tools.
  12. Coverage Triad实现了稳定的设计:在模拟和正式工具中测量代码覆盖率,功能覆盖率和断言覆盖率。

  13. Power is King: use CPF or UPF to capture, enforce and verify your Power-Intent.
  14. Power is King:使用CPF或UPF来捕获,执行和验证您的Power-Intent。

  15. the real design is often mixed signal, Use a Mixed-Signal language to verify the analog with the digital. Verilog-AMS is one such solution. But don't go overboard. Realnumber modeling can accomplish most of the functional aspects of mixed-signal behavior.
  16. 真正的设计通常是混合信号,使用混合信号语言来验证模拟与数字。 Verilog-AMS就是这样一种解决方案。但不要过火。 Realnumber建模可以完成混合信号行为的大多数功能方面。

  17. Use Hardware Acceleration to validate the Software that has to work with the silicon!
  18. 使用硬件加速来验证必须使用芯片的软件!

  19. Syntax Aware text editors for your HDL/HVL are a minimum requirement for developer IDE.
  20. 语法Aware HDL / HVL的文本编辑器是开发人员IDE的最低要求。

#6


4  

For FPGAs, Xilinx has this page. Almost all would apply to other FPGA vendors, or would have equivalent rules. A great deal is applicable to ASIC designs.

对于FPGA,Xilinx有此页面。几乎所有这些都适用于其他FPGA供应商,或者具有相同的规则。很多适用于ASIC设计。

Intel has Recommended HDL Coding Styles and Design Recommendations(PDF)under this page.

英特尔在此页面下推荐了HDL编码样式和设计建议(PDF)。