在 C 上使用 Verilog 或 VHDL 的动机是什么?

电器工程 FPGA 验证日志 嵌入式 高密度脂蛋白 固件
2022-01-11 08:57:59

我来自编程背景,并没有过多地使用硬件或固件(最多是一点电子设备和 Arduino)。

使用诸如 Verilog 和 VHDL 之类的硬件描述语言 (HDL) 而不是诸如 C 或汇编语言之类的编程语言的动机是什么?

这是一个选择问题吗?

我读到了硬件,它的固件用 HDL 编写,在并行运行指令方面具有明显的优势。然而,我很惊讶地看到有人质疑是用 C 语言还是汇编语言编写固件(如果你不一定有 CPU,那么汇编如何合适?)但我得出结论,这也是一种选择。

因此,我有几个问题(不要犹豫解释任何事情):

  1. 固件真的可以用 HDL 或软件编程语言编写,还是只是完成相同任务的另一种方式?我很想有一些现实世界的例子。每个选项会产生什么限制?

  2. 我知道固件优于软件的常见用途是硬件加速器(例如 GPU、网络适配器、SSL 加速器等)。据我了解,这种加速并不总是必要的,只是推荐使用(例如,在 SSL 和复杂算法加速的情况下)。在所有情况下都可以在固件和软件之间进行选择吗?如果不是,我很高兴知道固件在哪些情况下是明确且明确合适的。

  3. 我读过固件主要烧在 ROM 或闪存上。它在那里是如何表现的?以比特为单位,比如软件?如果是这样,有什么深刻的区别?在固件的情况下是否可以使用适配电路?

我想我在某些假设中在这里和那里犯了一个错误,请原谅我。谢谢!

4个回答

使用诸如 Verilog 和 VHDL 之类的硬件描述语言 (HDL) 而不是诸如 C 或某些汇编之类的编程语言的动机是什么?

C 和汇编是告诉 CPU 做什么的好语言。它们描述了由单个状态机按顺序执行的操作。

HDL 是用于描述或定义任意数字电路集合的良好语言。它们可以以编程语言无法实现的方式表达并行完成的操作。它们还可以以编程语言无法描述的方式描述块之间接口的时序限制。

我很惊讶地看到有人质疑是用 C 语言还是用汇编语言编写固件(如果你不一定有 CPU,那么汇编如何合适?)

在那个问题中,要问的是,“如果您正在为微控制器编写代码,如果您使用汇编或 C 或其他一些高级语言编写,是否有真正的区别?”。

由于他专门询问带有微控制器(带有外围设备的 CPU)的系统,因此 C 或汇编都是固件开发的合理选择,而 HDL 则不是。

固件真的可以用 HDL 或软件编程语言编写,还是只是执行相同任务的另一种方式?

这取决于你有什么样的硬件。如果您有 CPU,请使用编程语言。如果您有 FPGA 或正在设计 ASIC,请使用 HDL。如果您正在设计大量的数字逻辑,您可以查看其中一种中间语言,例如 SystemVerilog。

我读过固件主要烧在 ROM 或闪存上。它在那里是如何表现的?以比特为单位,比如软件?如果是这样,有什么深刻的区别?在固件的情况下是否可以使用适配电路?

我认为您对“固件”一词很感兴趣。这个词最初意味着要在嵌入式系统上运行的代码,最终用户无法更改这些代码。如果您向某人出售了一台 PC,那么用户很有可能会更改在其上运行的软件。如果您向他们出售示波器,您不会希望他们更改在内部微处理器上运行的代码,因此您将其称为固件。

FPGA 用户将“固件”一词用于他们设计的输出,因为它比硬件(焊接在一起的东西)更易变化。但实际上,配置 FPGA 的“固件”不同于在 uC 上运行的“固件”。uC 固件通过一系列状态引导 uC 执行其功能。FPGA 固件定义了一组逻辑元素之间的互连,以及要存储在查找表中的值。

在任何一种情况下,固件通常作为位存储在 eeprom 上(或者在主机上的磁盘上,每当嵌入式系统重新启动时,它都会下载它)。但这并不能使它们彼此相似。

对于您问题的第一部分,关于使用其中一个的动机:C 和 HDL (VHDL/Verilog) 之间存在根本区别C 是一种软件编程语言(就像汇编一样),VHDL/Verilog 是硬件描述语言。它们的目的不同。

C 在编译时被翻译成汇编代码(以其二进制形式,即机器语言)该代码是一系列指令,告诉 CPU 执行一系列基本操作(更改寄存器值、执行加法等)。

另一方面,HDL 被合成到硬件中。例如,在 VHDL 中,您可以编写如下内容:

output <= input1 + input2;

(另请参见此处的更完整示例)。这将被合成到一个(硬件)加法器。如果代码是为FPGA合成的,这意味着可以配置特定 FPGA 以实现加法器(作为组合逻辑)的比特流。

实际上,您可以用 VHDL 设计一个 CPU(参见Soft core Processors VS Hard core Processors),然后用 C 语言为它编写软件......

关于固件:这实际上完全取决于您如何定义这个词。固件可以是在微控制器中运行的程序(软件)(例如用 C 或汇编程序编写),也可以是用于配置可编程(硬件)逻辑设备(CPLD 或 FPGA)的比特流。有时它可能是一个包含两者的包:如果您获取某些型号的 FritzBox(ADSL 调制解调器)的固件,它们实际上包含一个完整的 Linux 系统(用汇编程序、C 和许多其他编程语言编写)和一个比特流配置 FPGA(可能从 VHDL 或 Verilog 合成)。

VHDL和Verilog更适合描述硬件并发

电子可以同时在平行导线中流动,因此我们在设计硬件时要考虑到这一点。

在 VHDL 中,如果您编写如下内容:

x <= a or b;
y <= a and b;
z <= x xor y;

(在processor之外function,它明确地将其标记为顺序),那么您已经编码了以下事实:

  • x, y, z,ab是电线
  • ab输入信号
  • x连接到电路的输出端,该or电路采用ab作为输入
  • 其他线路依此类推

很容易看出如何将其合成到实际硬件中,并x同时y进行评估。

        +-----+
A--+----+     |  X
   |    | OR  +-----+
B----+--+     |     |  +-----+
   | |  +-----+     +--+     |
   | |                 | XOR +-- Z
   | |  +-----+     +--+     |
   | +--+     |  Y  |  +-----+
   |    | AND +-----+
   +----+     |
        +-----+

然后,当是时候模拟电路时,模拟器(通常是一个顺序程序)已经模拟了电路的物理特性,如下所示:

  • 已经ab改变了?是的?嘿,x取决于a让我们更新x
  • y也取决于a. 也更新一下。
  • z取决于x更新它,因为x已更新。
  • x依赖(a或)的内容是否b已更新?不?y相同z好的,我们完成了这一步。

这会导致“有趣”的可能结果,这些结果没有顺序模拟,但代表可能的物理情况:

  • x <= not x将导致模拟的无限递归。模拟器可以在一定深度后切断。
  • x <= 0; x <= 1导致错误(短路)。这也是存在的原因之一std_logic

尽管如此,尽管 VHDL 对硬件的建模比 C 更接近,但它本身并不是对它的完美详细描述:

最后,VHDL 在更高层次的人类可理解的电路功能和更低层次的可综合性之间提供了一个很好的平衡。

另一方面,C 更侧重于按顺序与 CPU 对话。

您当然可以使用 C 结构、枚举和数组对电路进行编码,然后像 VHDL 一样对其进行模拟(这看起来或多或少类似于System C所做的,但我从未尝试过)。

但是您实际上将重新实现 VHDL 模拟器,并使用更冗长的语言。我猜是正确工作的正确工具。

还有一些工具可以将 C 转换为 VHDL https://stackoverflow.com/questions/8988629/can-you-program-fpgas-in-c-like-languages但预计性能会降低,因为这些是更高级别的转换。

  1. 这取决于您的架构。如果您有 CPU(或者通常是微控制器),则需要使用常规编程语言(包括汇编)编写固件。如果你有类似 FPGA 的东西,你的固件需要用 HDL 编写。HDL 不能(据我所知)生成可以由传统 CPU 有效执行的程序,而 FPGA 也不能开箱即用地执行传统程序。但是,您可以将 FPGA 配置为 CPU,然后使用它执行常规程序。这将需要两层固件,较低层用 HDL 编写来构建 CPU,较高层用传统编程语言编写以在该 CPU 上执行。
  2. 固件和软件之间没有硬性区别。在许多设备上,固件将存储在例如闪存中,但在现代手机上,几乎所有内容都存储在闪存中,固件和软件之间的区别并不清楚(大多数人可能会考虑编程基带处理器固件的代码,并且大多数人会考虑应用程序软件,但确切的边界在哪里?)。
  3. 正如我在 2 中所说,除了固件更永久的想法之外,没有明确的区别。