我正在尝试使用 Verilog 将衰减包络应用于正弦波形。硬件限制阻止使用乘法来简单地乘以包络。我只是使用的正弦值和包络值存储在 ROM 中以加速一切。
现在,如果正弦值较大,我只是通过从正弦值中减去指数值来计算输出样本。如果指数值大于正弦值,则输出样本为零。这很好用,但是要减去的当前指数值需要通过正弦波上的当前位置进行调制,以便在正弦最大时减去完整值,当正弦为零时减去零。
我很感激任何人都可以提供的任何建议,如果需要,我可以提供更多详细信息。
我正在尝试使用 Verilog 将衰减包络应用于正弦波形。硬件限制阻止使用乘法来简单地乘以包络。我只是使用的正弦值和包络值存储在 ROM 中以加速一切。
现在,如果正弦值较大,我只是通过从正弦值中减去指数值来计算输出样本。如果指数值大于正弦值,则输出样本为零。这很好用,但是要减去的当前指数值需要通过正弦波上的当前位置进行调制,以便在正弦最大时减去完整值,当正弦为零时减去零。
我很感激任何人都可以提供的任何建议,如果需要,我可以提供更多详细信息。
如果您不能支持直接硬件乘法,还有其他方法,但您将不得不牺牲一些东西。例如,如果您有多个时钟周期可用,则可以使用迭代方法。类 C 伪代码:
accum = 0
for (i = 0; i < LENGTH(envelope); ++i)
{
if (((envelope >> i) & 0x1) == 0) accum += signal >> (i + 1)
}
// "accum" now holds the multiplication result
将上述功能翻译成 Verilog 是留给感兴趣的读者的一个练习(我已经有一段时间没有用那种语言编写了)。该方案本质上是使用加法和移位来执行长以 2 为底的乘法。对于在包络缩放因子中设置的每一位,将信号样本的适当右移版本添加到累加器。循环完成后,乘法的结果保存在累加器中。
正如我所说,这不是世界上最有效的方法。即使在没有硬件乘法器的设备上,一个好的综合工具也可能会产生更好的东西。此方法以执行展开乘法的迭代所需的额外时钟周期的形式用资源使用换取延迟。我想知道是什么驱动了您的应用程序中的无乘法约束。你能补充更多细节吗?
注意:您可能需要根据 和 的数字格式在添加到累加器时调整应用于信号的额外移位accum
量signal
。如果它们都是相同的定点格式(如 Q15),那么上述方法应该可以正常工作。