我正在自学verilog。我正在阅读的书在介绍章节中指出,要执行除法,我们使用“/”运算符或“%”运算符。在后面的章节中说除法对于verilog来说太复杂并且无法合成,因此为了执行除法它引入了一个很长的算法。
所以我很困惑,verilog不能处理简单的划分吗?/ 运算符没用吗?
我正在自学verilog。我正在阅读的书在介绍章节中指出,要执行除法,我们使用“/”运算符或“%”运算符。在后面的章节中说除法对于verilog来说太复杂并且无法合成,因此为了执行除法它引入了一个很长的算法。
所以我很困惑,verilog不能处理简单的划分吗?/ 运算符没用吗?
这完全取决于您正在编写什么类型的代码。
如果您正在编写您打算合成的代码,您打算进入 FPGA 或 ASIC,那么您可能不想使用除法或模运算符。当您将任何算术运算符放在 RTL 中时,合成器会实例化一个电路来完成这项工作;+
&的加法器-
;的乘数*
。当您写作时,/
您要求的是分压电路,但分压电路是一件非常复杂的事情。它通常需要多个时钟周期,并且可能使用查找表。它需要很多综合工具来推断你在编写时想要什么a / b
。
(显然除以 2 的幂很简单,但通常你会使用移位运算符)
如果您正在编写不想被综合的代码,例如测试台的一部分,那么您可以随意使用除法。
因此,要回答您的问题,/
运营商并非毫无用处,但您必须清楚自己在何处以及为何使用它。也是如此*
,但程度较轻。乘法器非常昂贵,但大多数合成器都能够推断出它们。
你必须考虑硬件。
当您编写 a <= b/c 时,您是在对综合工具说“我想要一个可以在每个时钟周期提供结果并且没有中间管道寄存器的除法器”。
如果您计算出创建它所需的逻辑电路,它会非常复杂,尤其是对于更高的位数。通常 FPGA 没有用于划分的专用硬件块,因此必须使用通用逻辑资源来实现。它可能既大(很多 lut)又慢(低 fmax)。
无论如何,一些合成器可能会实现它(从快速搜索看来 quartus 会实现),其他合成器不会打扰,因为他们认为它在实践中不是很有用。
如果您除以一个常数并且可以接受近似结果,那么您可以使用乘数进行技巧。取你想要除以的倒数,乘以 2 的幂,然后四舍五入到最接近的整数。
然后在您的verilog中,您可以通过乘法来实现近似除法(这在现代FPGA上并不太昂贵),然后是移位(在硬件中移位固定位数基本上是免费的)。确保为中间结果留出足够的位。
如果您需要一个准确的答案,或者如果您需要除以不是预定义常量的东西,您将不得不决定您想要什么样的除法器。如果您的吞吐量很低,那么您可以使用基于状态机的方法,该方法每 n 个时钟周期进行一次除法。如果您的吞吐量很高并且您可以负担得起设备面积,那么每个时钟周期进行除法的流水线方法(但需要多个周期才能使结果流过)可能更合适。
通常,工具供应商会为这类东西提供预制块(Altera 称它们为宏功能)。这些的优点是工具供应商可能会为设备仔细优化它们。不利的一面是它们会带来供应商锁定,如果您想转移到不同的设备供应商,您很可能必须换出块,而您与之交换的块可能具有不同的特征。
所以我很困惑。Verilog 不能处理简单的除法吗?/ 运算符没用吗?
verilog 综合规范(IEEE 1364.1)实际上表明应该支持所有具有整数操作数的算术运算符,但没有人遵循这个规范。一些综合工具可以进行整数除法,但其他工具会拒绝它(我认为 XST 仍然可以),因为组合除法通常非常低效。多周期实现是常态,但不能从“/”合成。
除法和模数从来都不是“简单的”。如果可以,请避免使用它们,例如通过位掩码或移位操作。特别是变量除数在硬件中实现起来非常复杂。
“Verilog 语言”可以很好地处理除法和模数 - 当您使用计算机模拟您的代码时,您可以完全访问它的所有功能。
当您将代码合成到特定芯片时,存在一些限制。这些限制往往是基于工具供应商认为什么是“明智的”,而不是什么是可行的。
在过去,除 2 的幂以外的任何除法对硅来说都是不明智的,因为它占用了大量空间并且运行速度非常慢。目前,一些合成器会为您创建“除以常数”电路。
将来,我认为没有理由合成器不应该为您创建一个分频器(或使用一个潜在的未来架构的 DSP 块中的一个)。会与否还有待观察,但见证乘数的进步(从“只有二的幂”到“一个输入常数”再到“完全实现”短短几年)
在 verilog 中可以使用 '/' 进行除法。但它不是一个可综合的算子。使用“*”进行乘法也是如此。在 verliog 中有某些算法可以执行这些操作,如果代码需要可合成,则使用它们。IE。如果您需要等效的硬件。
我不知道任何除法算法,但对于乘法,我使用了布斯算法。
如果您想要可合成的代码,您可以使用 Divison_IP 或者您可以使用右移运算符进行某些除法,例如 64/8=8 相同的 64>>3 = 8。
除法在硬件上并不简单,因为人们花了很多时间在一个高效快速的乘法器上。但是,您可以通过在硬件中右移一位来轻松除以 2。
使用result <= a/b
并完美运行。
请记住,使用<=
运算符时,会立即计算答案,但答案会在下一个时钟上升沿输入到“结果”寄存器中。
如果您不想等到下一个时钟上升沿使用result = a/b.
请记住,任何算术运算电路都需要一些时间来完成运算,并且在此期间电路会生成随机数(位)。
就像当 A-10 疣猪攻击机攻击坦克时,它会发射大量子弹。这就是除法器电路在除法时的作用方式,它会吐出随机位。几纳秒后,它将完成除法并返回稳定的良好结果。
这就是为什么我们要等到“结果”寄存器的下一个时钟周期。我们试图保护它免受随机垃圾号码的影响。
除法是最复杂的运算,所以计算会有延迟。对于 16 位除法,结果将在大约 6 纳秒内计算出来。