FPGA实战:从算法到硅片,手把手构建8位有符号Booth二位乘器
在数字信号处理、图像加速或者自定义指令集设计中,乘法器往往是性能瓶颈和资源消耗的大户。对于FPGA工程师和硬件设计学习者而言,理解乘法器的原理只是第一步,如何将教科书上的算法,例如经典的Booth算法,转化为高效、可综合、时序干净的RTL代码,才是真正体现功力的地方。今天,我们不谈冗长的数学推导,而是直接切入Vivado工程,用Verilog代码和状态机,将一个8位有符号Booth二位乘算法“雕刻”到FPGA的硅片逻辑中。这篇文章面向的是已经了解数字电路基础,并渴望将算法落地的实践者。我们将聚焦于设计决策、代码实现细节、仿真验证技巧,并提供一个可直接复用的工程框架,让你在理解“为什么”的同时,更清楚“怎么做”。
1. 为何选择Booth算法?超越朴素的硬件乘法
在FPGA中实现乘法,最直接的想法是使用LUT和专用DSP Slice。对于小位宽(如8位),直接使用*运算符让综合工具处理,通常也能获得不错的结果。那么,我们为何还要手动实现Booth算法呢?原因有三:
- 理解底层机制:手动实现是深入理解计算机算术运算单元(ALU)和硬件优化技巧的最佳途径。这就像学编程要理解指针一样,是内功。
- 资源与速度的定制权衡:Booth算法,特别是二位乘(Radix-4 Booth),通过减少部分积的数量,直接减少了加法器的级数。对于没有足够DSP资源的低成本FPGA,或在需要极高时钟频率的场景下,一个精心设计的Booth乘法器可能比工具自动推断的乘法器面积更小、速度更快。
- 有符号数的原生优雅处理:Booth算法的核心优势在于它能原生地、统一地处理有符号数。它不需要像“原码乘法再转补码”那样进行额外的符号处理和校正步骤,算法本身在补码体系下就是完备的。这对于处理大量有符号数据的应用(如音频、视频编解码)至关重要。
简单来说,Booth算法将乘法操作转化为一系列的移位和条件加法操作。二位乘算法通过一次查看乘数的三位(当前位、前一位、后一位的组合),将部分积的数量减少到大约原来的一半,从而显著提升速度。
提示:Booth算法并非总是比阵列乘法器或华莱士树更快,其优势在乘数中包含较长连续“1”或“0”时尤为明显,因为它能将连续的加法转换为一次加法和一次减法。评估时需结合具体数据模式。
2. 核心架构:状态机与数据通路的协同设计
我们的目标是设计一个时序电路,而非纯组合逻辑。这样做的好处是易于满足时序约束,便于流水线化,也更符合实际工程中与处理器时钟同步的需求。整个乘法器的核心是一个控制器(状态机)和一个数据通路。
数据通路负责执行核心的算术操作:根据控制信号,选择被乘数(X)、被乘数的相反数(-X)、2X或-2X,并将其与当前的部分积(Partial Product, PP)进行累加,然后右移。
**控制器(状态机)**则负责指挥数据通路。对于一个8位乘数,采用Booth二位乘,我们需要处理4组乘数位(因为每次看3位,步进为2位)。因此,状态机至少需要4个主要计算状态,外加一个空闲(Idle)和完成(Done)状态。
让我们用一个表格来清晰地定义状态机的行为:
| 状态 | 描述 | 执行操作 | 下一个状态 |
|---|---|---|---|
IDLE |
空闲 | 等待启动信号,初始化部分积和乘数寄存器。 | 收到start信号后跳转到CALC0。 |
CALC0 |
计算周期0 | 检查乘数位[1:0]及虚拟位y_{-1}=0,根据Booth编码表执行相应操作。 |
CALC1 |
CALC1 |
计算周期1 | 检查乘数位[3:1],执行操作。 | CALC2 |
CALC2 |
计算周期2 | 检查乘数位[5:3],执行操作。 | CALC3 |
CALC3 |
计算周期3 | 检查乘数位[7:5],执行操作。 | DONE |
DONE |
完成 | 输出最终乘积,并拉高完成信号。 | IDLE |
Booth二位乘的编码规则是设计的灵魂,它直接决定了数据通路中多路选择器的控制逻辑。下表是必须牢记于心的操作对照表:
| y(i-1) | y(i) | y(i+1) | 操作 | 解释(对部分积PP) |
|---|---|---|---|---|

&spm=1001.2101.3001.5002&articleId=149384879&d=1&t=3&u=d2d7244a811f4341b0ecb745b5649a3f)
795

被折叠的 条评论
为什么被折叠?



