1. 需求拆解:先别急着写代码,想清楚“向量乘法器”到底要干什么
“向量乘法器设计”这个标题看着简单,但真动起手来你会发现,不同场景下要做的产品完全是两码事。我接手过好几个类似的项目需求,有做课程设计的,有做FPGA加速的,还有做ASIC里DSP单元的,同样是“向量乘法器”,侧重点可以差出十万八千里。
先给个最基本的定义:向量乘法器,本质上是同时对一组(两个以上)输入数执行乘法运算的硬件单元。它和普通标量乘法器最大的区别在于“并行度”——不是一次乘一对数,而是把多个乘法操作放到同一个时钟周期里并发完成。常见的形态有:
- 点积运算单元 :把两个等长向量的对应元素相乘后累加,输出一个标量。这是神经网络推理里最频繁的操作(全连接层、卷积层都要用到)。
- 逐元素乘法单元 :两个向量对应位置相乘,输出仍是一个向量。例如图像处理里的加权融合、信号处理里的加窗操作。
- 矩阵乘法子单元 :本质上是多个点积的组合,但结构上会复用乘法器的结果做累加,考验的是数据复用与调度。
所以接到这个题目,第一件事不是打开Verilog编辑器,而是和提出需求的人把下面几个问题对齐:
第一,位宽是多少? 输入是8位、16位、32位还是自定义浮点数?这直接决定乘法器面积和时序。8位乘8位在FPGA上就是LUT里塞几个查表的事,32位乘32位就得考虑DSP48硬核怎么分配了。如果是浮点数,还要明确格式——IEEE 754单精度、半精度还是自定义定点格式?格式一变,设计难度完全不同。
第二,输入输出格式是定是浮? 定点数又要区分整数、小数位在哪里;浮点数要处理阶码对齐和尾数规格化,逻辑会多出好几倍。很多新手一上来就选浮点,结果卡在对齐和舍入上,不如先做定点版本跑通流程,再扩展。
第三,时钟约束多少? 这是一个非常容易被忽视但决定方案选型的问题。如果目标时钟只有50MHz,直接暴力组合逻辑乘法完全没问题;但如果要求跑300MHz以上,就必须考虑流水线切级、Booth编码、Wallace树这些优化手段。换句话说,时序要求决定了你要不要“炫技”。
第四,是纯组合逻辑输出还是需要流水线? 纯组合逻辑简单直观,但路径延迟高;流水线能提高吞吐率,但引入latency,需要配合外部时序做同步,控制逻辑会复杂一些。
第五,目标器件是什么? 如果是Xilinx/AMD的FPGA,乘法器可以直接映射到DSP48E1/E2硬核上;如果是Altera/Intel的平台,对应的是DSP Block。用硬核和用LUT搭乘法器,资源占用、功耗和代码风格都完全不一样。ASIC方向则可以针对标准单元库做逻辑综合优化。
这些参数不敲定,后面所有设计都是白做。我见过有人拿到题目就开写,写完发现位宽需求变了,整个数据通路推倒重来。所以项目的第一步永远是“需求反确认”,哪怕标题看起来再简单,也要把这个环节做扎实。
2. 算法选型背后的门道:Booth编码、Wallace树和移位累加怎么挑
确定需求之后,进入最核心的算法设计阶段。一个向量乘法器的性能上限,其实在你选定算法的那一刻就基本决定了。这一节我把三种最常见的乘法实现思路拆开讲,直接对比它们的优缺点和适用场景,方便你做选择。
2.1 朴素移位累加:最适合入门但不适合向量场景
移位累加法是最原始的乘法实现:把乘数逐位扫描,如果当前位是1,就把被乘数左移对应位数后累加。例如计算 1011 × 0110,需要扫描4个比特位,产生最多4个部分积,再逐个累加。
这个方案的优点是逻辑极其简单,写起来不容易出错,DEBUG也容易;缺点是乘法的时间复杂度是O(N),N是位宽。对单次乘法来说可能还能接受,但向量乘法器一次要跑几十上百路乘法,如果每路都这样串行累加,延迟会变成灾难。
适用场景 :教学演示、位宽小于8位的简单控制逻辑、以及对延迟完全不敏感的功能验证模型。在真正的向量运算单元里,我基本不推荐这个方案。
2.2 Booth编码:不是必须的,但能减一半部分积
Booth编码的核心思想是:通过重新编码乘数,让部分积的数量从“位数数量”减少约一半,从而减少累加次数和硬件加法器数量。它利用了二进制补码的数学性质——连续的“1”序列可以用一次加法和一次减法来表达。
举个例子,乘数011110可以看成100000 - 000010,这样本来要加4次的部分积,变成了一次加、一次减,逻辑上少了两级。Booth最常用的变体是Radix-4 Booth编码(也称为Booth-2),它每两位乘数产生一个部分积,部分积数量从N直接降到N/2,同时还能直接处理有符号数,无需额外的符号修正逻辑。
Radix-4 Booth编码的规则表如下:
| 乘数位组合(b[2i+1], b[2i], b[2i-1]) | 操作 |
|---|
471




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



