例如,如果我想使用常数将滤波器系数存储在n-Tap FIR滤波器中,CONSTANT
声明是否会使用FPGA触发器将我的值存储在Block RAM或寄存器中?也可以使用SIGNAL
来存储系数而不使用RAM单元吗?
答案 0 :(得分:6)
常数本身并未存储"任何地方 - 它们的值只是替换为您使用它们的VHL代码。
它们存储的位置取决于您如何使用它们以及如何优化代码。
如果您将信号乘以常数2,例如,根本不使用任何元素 - 数据总线将以一种有效地将值左移一位的方式连接。
或者,它们可能最终成为其他元素的硬连线输入,例如乘法器。
无论哪种方式,您都应该查看综合结果以彻底了解生成的RTL。
答案 1 :(得分:4)
[...]
CONSTANT
声明会使用FPGA触发器将我的值存储在Block RAMs或寄存器中吗?
常量是存储在内存块还是寄存器中,或者它们是否合并到boolen方程中取决于算法的实现。让我们看看下面的数学方程式(不是VHDL代码):
y = c_1 * x_1 + c_2 * x_2 + c_3 * x_3 +... + c_N * x_N
N
是系数的数量,x_i
是输入值,c_i
是常数系数。
您可以通过以下方式在VHDL /硬件中实现此等式:
N
并行乘数和加法树来总结产品;所有这些都是在一个时钟周期内完成组合,甚至是流水线,每个时钟周期的吞吐量为一个结果。
或N
依次执行乘法累加步骤;每个时钟周期使用一次乘法累加。
你甚至可以将两者结合起来。
在情况1中,合成器使用常数优化每个乘法:
因此,在情况1中,不需要存储器或寄存器来存储常量。
在情况2中,合成器将乘法累加步骤映射到硬件乘法器加上加法器。此乘法器和加法器将重复用于所有N
步,因此必须在内存中查找系数。如果你有很多系数,那么使用内存块(Block-RAM)。当前迭代步骤i
将构成内存地址。如果只有少量系数,那么它们也可以存储在分布式存储器(LUT-RAM)中或通过布尔方程计算。但即使在这种情况下,系数也会不映射到触发器,因为它们的值不随时间变化。
也可以使用
SIGNAL
来存储系数而不使用RAM单元吗?
是的,当然。通过适当的同步描述,它们将被映射到触发器。
答案 2 :(得分:1)
使用过的存储元素:
...取决于您选择的VHDL描述和大小。
你应该使用常数而不是信号。此外,使用同步读取操作来推断已注册的输出可能会有所帮助。
查看综合报告以验证预期的描述。
答案 3 :(得分:0)
以Paebbels的回答为基础,这取决于。虽然它们也可以在分布式ROM(LUTROM)中实现。这取决于综合工具。例如,Xilinx的Vivado在其综合指南(UG901)中描述了如何推断RAM / ROM。
对于FIR滤波器的示例,您可能会有类似的内容:
type coeff_array is array(natural range<>) of std_logic_vector(17 downto 0);
constant coeffs : coeff_array(0 to N-1) := ( x"XXXX", x"XXXX", ..., x"XXXX" );
现在,这是分布式ROM还是RAM取决于工具。使用Vivado进行的快速测试表明,这种结构可以合成一个大门(只是LUT逻辑)。但是,它可以通过以下方式强制进入Block RAM(也就是块ROM)。
signal coeffs : coeff_array(0 to N-1) := ( x"XXXX", x"XXXX", ..., x"XXXX" );
attribute ROM_STYLE : string;
attribute ROM_STYLE of coeffs : signal is "block";
推断任何特定类型结构(LUT,LUTRAM,LUTROM,块ROM,块RAM)的方法取决于所讨论的工具。通过综合运行测试,看看你得到了什么。并查看合成器的综合指南,了解如何获得所需的合成器。