我应该使用哪种编码类型? FPGA 应用示例
遵循三个实验,这些实验展示了确定哪种编码适合给定 FPGA 的过程。
我的 FPGA 应该使用哪种编码类型?正如我在上一篇文章中所讨论的,编译器通常会为您做出决定——我建议您遵循编译器的决定。
然而,了解编码类型之间的差异以及编译器可能得出某个结论的原因很重要。考虑到这一点,本文将引导您完成一个实验,该实验展示了一个示例 FPGA 应用程序,并逐步讨论哪种编码类型最好。
到目前为止,在本系列中,我们讨论了如何使用 Verilog 创建有限状态机 (FSM)、初始状态以及内存如何影响 FPGA 编码,以及比较二进制编码与单热编码与格雷编码的高级概述.
被测系统
对于这个实验,我想多次实例化一个状态机,以放大使用二进制、格雷和单热编码时得到的硬件的差异。
我最终选择的系统是 Conway’s Game of Life,这是一种模拟活细胞在其环境中的行为的细胞自动机,它是一个矩形的 2D 细胞阵列。康威的生命游戏模拟了这些细胞的出生、繁殖和死亡,根据一组简单的规则,每个细胞都遵循这些规则来确定下一个循环中会发生什么。每个活细胞可能存活或死亡,每个死细胞可能保持死亡或存活。以下是每个周期的规则:
- 有两个或三个活邻居的活细胞存活下来。
- 带有三个活邻居的死细胞复活了。
- 所有其他细胞死亡或保持死亡。
这些规则创造了许多有趣的行为和模式,这些行为和模式在计算机科学中得到了广泛的研究。
这就是康威的生命游戏在运行所谓的单枪滑翔机时的样子。
康威生命游戏的变体,被称为比尔·戈斯珀的滑翔机枪。由 Lucas Vieira 创建的 Gif [CC BY-SA 3.0]
Verilog 代码
回到我们的测试系统,每个单元都被设计为具有八个状态的状态机。诚然,康威生命游戏中单元格的逻辑可以在一个周期内解决,但我决定制作一个 8 状态机,以便在使用不同编码时有显着差异。状态用于计算单元格的活邻居。
下面这段 Verilog 代码显示了这些机器的单元模块结构,包括状态的原始二进制编码。
`定义 STATE_0 3'b000
`定义 STATE_1 3'b001
`定义 STATE_2 3'b010
`定义 STATE_3 3'b011
`定义 STATE_4 3'b100
`定义 STATE_5 3'b101
`定义 STATE_6 3'b110
`定义 STATE_7 3'b111
module LifeCell(
输入时钟,
输入 nrst,
输入种子,
输入 [7:0] 邻居,
输出reg活着);
reg [2:0] 状态;
总是@(posedge clk)
if (nrst ==0)
state <=`STATE_0;
<代码> 其他代码>
case(state)
`STATE_0:开始
// ...
state <=`STATE_1;
结束
`STATE_1:开始
// ...
state <=`STATE_2;
结束
// ...
`STATE_7:开始
// ...
state <=`STATE_1;
结束
结尾
结束模块
如果您想仔细查看代码,请随时查看 GitHub 上的项目。
FPGA 编码实现
该系统被合成并实现为一个 23x23 单元的世界,共有 27 种变体:使用了三种不同的 FSM,全部采用上述三种编码,都在三个不同的目标 FPGA 上。
FSM #1:原始模型
这台机器有一个初始状态,它运行一次,然后循环运行剩余的七个状态。这几乎是一个完整的序列,因此格雷编码起初对我来说似乎很有希望。
FSM #2:一个序列
这台机器的行为就像一个 3 位计数器,所以我也预计格雷编码会击败竞争对手。
FSM #3:任意缠结
这台机器具有与 FSM #1 相同的关键路径,但是当已知存活邻居的数量超过 3 时,它会通过任意路径。
对于这种任意状态转换行为,我预计单热编码是最佳选择。
目标架构
该系统是为三个目标 FPGA 实现的,使用他们供应商的开发工具:
- 适用于 Artix 7 FPGA 的 Xilinx Vivado 套件
- 英特尔 Quartus Prime,用于 Cyclone V FPGA
- Lattice Diamond,用于 LatticeXP2 FPGA
比较结果
比较两个或多个系统的性能很困难,主要是因为判断取决于我们使用的指标以及我们认为哪些方面比其他方面更重要。对于这个实验,我收集了以下数据来为每个实现生成一个分数:
- 逻辑单元的数量。 这些是 Xilinx 和 Lattice FPGA 的 LUT(查找表),或 Intel FPGA 的 ALM。得分:1 分。
- 寄存器数量。 得分:1 分。
- 估计的最大频率。 得分:2 分。
- 估计的片上功率。 得分:2 分。
对于每个实现,这四个方面都在三种编码中进行了比较,因此在编码中,我得到了最好、最差和中间的结果:最好的得到了正分,最差的得到了负分,中间的一个得到 0。
将每个模型的所有分数相加后,得到以下结果:
所有 27 个实现的结果表。在每一行中,最好的编码用绿色显示,最差的用红色显示,如果没有平局,中间的则用黄色显示。
这似乎建议远离 one-hot 编码,只有两种情况下它获胜,其中一种是平局。此外,虽然我最初预计 one-hot 是 FSM 模型 #3 的最佳编码,但结果证明它是最差的编码,没有开发工具推荐它。也就是说,在某些情况下,一个热点胜过其他,主要是在频率和功率指标上。
总的来说,格雷编码似乎是这个特定系统的最佳选择。
从此表中提取获胜者,我们得到以下内容:
判决
尽管这种比较似乎有利于格雷编码而不是二进制和单热编码,但结果在很大程度上取决于我们使用的指标,而这些指标反映了对我们来说重要的东西。例如,在这个比较中,我认为频率和功率比使用(设计中的逻辑元件和寄存器的数量)更重要。如果我重视使用而不是频率和频率而不是功率,那么肯定会产生不同的排名。
这种比较并不打算成为使用这些编码获得的性能的权威性工作。相反,它显示了我个人偏好在我使用的架构中产生的排名。
再一次,如果您想查看代码,查看 27 个实现,或者查看我对康威生命游戏的模拟,请查看 GitHub 上的项目。
嵌入式