我应该为我的FPGA使用哪种编码类型?正如我在前一篇文章中讨论的那样,编译器通常会为您决定——我建议您遵循编译器的决定。
然而,理解编码类型之间的差异以及为什么编译器可能会得出某种结论是很重要的。考虑到这一点,本文将带领您完成一个实验,该实验展示了一个示例FPGA应用程序,并逐步讨论哪种编码类型是最好的。
到目前为止,在本系列中,我们已经讨论了如何使用Verilog创建有限状态机(FSM),初始状态以及内存如何影响FPGA编码,以及一个高层次的概述比较二进制编码,单热点编码,灰色编码.
被测系统
对于这个实验,我想大量实例化一个状态机,以便在使用二进制编码、Gray编码和一次热编码时,放大结果硬件中的差异。
我最终选择的系统是康威的《生活游戏》,一种细胞自动机,模拟活细胞在其环境中的行为,它是一个矩形的二维细胞阵列。Conway的《Game of Life》模拟了这些细胞的诞生、繁殖和死亡,每个细胞都遵循一套简单的规则来决定下一个循环中会发生什么。每个活细胞可能存活或死亡,每个死细胞可能保持死亡或变成活细胞。以下是每个周期的规则:
- 有两三个活邻居的活细胞存活下来。
- 死掉的细胞和三个活的邻居会复活。
- 其他细胞要么死亡,要么保持死亡状态。
这些规则创造了许多有趣的行为和模式,这些行为和模式在计算机科学中得到了广泛的研究。
这是康威的《生命游戏》在运行所谓的单高斯帕滑翔机枪时的样子。
康威的《生命游戏》的变体,被称为比尔·高斯帕的滑翔机枪。Gif由卢卡斯维埃拉[3.0 CC冲锋队]
Verilog代码
回到我们的测试系统,每个单元都被设计为具有8个状态的状态机。诚然,在Conway的Game of Life中,单元格的逻辑可以在一个循环中解决,但我决定在使用不同编码时,让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
模块LifeCell (
输入时钟,
输入称说,
输入种子,
输入7:0的邻居,
输出reg活着);
注册(2:0)状态;
总是@ (posedge clk)
If (nrst == 0)
国家< = ' STATE_0;
其他的
例(状态)
“STATE_0:开始
/ /……
国家< = ' STATE_1;
结束
“STATE_1:开始
/ /……
国家< = ' STATE_2;
结束
/ /……
“STATE_7:开始
/ /……
国家< = ' STATE_1;
结束
endcase
endmodule
如果您想更仔细地查看代码,请检查GitHub上的项目.
FPGA编码实现
该系统被合成并实现为一个23x23细胞的世界,共有27个变体:使用了三种不同的FSMs,均采用上述三种编码,均在三种不同的目标fpga上。
FSM #1:原始模型
这台机器有一个初始状态,它运行一次,然后在一个循环中运行其余的七个状态。这几乎是一个完整的序列,所以Gray编码起初看起来很有希望。
FSM #2:序列
这台机器就像一个3位计数器,所以我也希望Gray编码能够击败竞争对手。
FSM #3:任意的混乱
这台机器具有与FSM #1相同的关键路径,但当已知活邻居的数量超过3时,它将通过任意路径。
对于这种任意的状态转换行为,我认为一次性编码是最好的选择。
目标架构
该系统用于三个目标fpga,使用其供应商的开发工具:
- Xilinx Vivado Suite,用于Artix 7 FPGA
- 英特尔Quartus Prime,用于Cyclone V FPGA
- Lattice Diamond,用于LatticeXP2 FPGA
比较结果
比较两个或多个系统的性能是很困难的,主要是因为结果取决于我们使用的指标,以及我们认为哪些方面比其他方面更重要。在这个实验中,我收集了以下数据,为每一个执行生成一个分数:
- 逻辑单元数。这些是Xilinx和Lattice fpga的lut(查找表),或Intel fpga的ALMs。分数:1分。
- 寄存器的数量。分数:1分。
- 估计最大频率。得分:2分。
- 估计芯片上的权力。得分:2分。
对于每一个实现,这四个方面在三种编码之间进行比较,所以在编码之间,我得到了一个最好的,一个最差的,一个中间的结果:最好的得到了正的分数,最差的得到了负的分数,中间的得到了0。
将每个模型的所有分数相加,得到如下结果:
所有27个实现的结果表。在每一行中,最好的编码用绿色表示,最差的编码用红色表示,如果没有平局,中间的编码用黄色表示。
这似乎表明要避免一次性编码,只有两种情况下它会赢,其中一种是平局。此外,虽然我最初预计one-hot是FSM模型#3的最佳编码,但结果却是最差的编码,没有开发工具推荐它。也就是说,在某些情况下,单热游戏胜过其他游戏,主要是在频率和功率指标上。
总的来说,灰色编码似乎是这个特定系统的最佳选择。
从这个表中提取获胜者,我们得到以下结果:
判决结果
尽管这种比较似乎更倾向于Gray编码而不是二进制编码和一次性编码,但结果在很大程度上取决于我们使用的指标,而这些指标反映了什么对我们来说是重要的。例如,在这个比较中,我认为频率和功率比使用(设计中逻辑元素和寄存器的数量)更重要。如果我把使用率看得比频率更重要,把频率看得比功率更重要,那么肯定会有不同的排名结果。
这种比较并不是对使用这些编码所获得的性能的确定工作。相反,它显示了在我使用的架构中由我的个人偏好产生的排名。
同样,如果您想查看代码,查看27个实现,或者查看我对Conway 's Game of Life的实际操作的模拟,请查看GitHub上的项目.
这是一篇很好的理论文章,
假设您使用FPGA,
恕我直言,使用默认的“自动”模式是最好的。
我知道的所有工具,都有内置的优化,
Basic,使用枚举类型编码状态机,
不要分配状态。
然后,这些工具将优化您的FPGA以满足您的时间限制。
这是工具的一个事实,如果设备是空的,那么工具就会想出一个解决方案,
当设备装满时,他们会想出另一种解决方案来满足你的设计,
记住,工具,运行直到它们符合你的时间和设备。
我作为顾问工作的大多数地方,都有设计指南,说明你只能使用自动模式,
一些大型机器的设计在移动到新设备时由于不使用自动模式而失败。