Altifigence Academy

2 / 20 · 概念

有符号乘积与累加器位宽

根据操作数最坏取值范围推导累加器位宽。

包含最小负输入

W 位二进制补码输入的范围是 −2^(W−1) 到 2^(W−1)−1。两个输入都取最小负值时,会产生最大的正乘积。W=8 时,(−128)×(−128)=16384,大于 127×127=16129。两个 W 位输入的完整有符号乘积可以安全地用 2W 位表示。

对于包含 K 项的归约,本课程采用以下保守规则。K 必须为正;该规则假定操作数位宽相同,且不额外加入偏置。

Wacc=2W+⌈log⁡2K⌉W_{acc}=2W+\lceil\log_2 K\rceil

这是一条简单的安全界限,并不表示对所有 K 都是最小位宽。W=8、K=4 时,选择十八位。四个最大乘积之和为 65536。十七位有符号累加器最大为 65535,因此恰好在此边界失效。十八位涵盖 −131072 到 131071。K=1 时,不增加额外的累加位。

明确保留符号

声明中间信号,不要猜测表达式的位宽。AW 必须至少为 PW。

SystemVerilog
localparam int PW = 2*W;
localparam int AW = PW + $clog2(K);
logic signed [W-1:0] a, b;
logic signed [PW-1:0] product;
logic signed [AW-1:0] addend, acc;
assign product = $signed(a) * $signed(b);
assign addend = {{(AW-PW){product[PW-1]}}, product};

八位模式 0xFE 表示 −2。乘以三得到 −6;加宽该乘积需要符号扩展。零扩展会把负数变成正数。应记录无符号接口上的位模式在哪一步变成有符号算术值。

位宽取决于累加器中保留的完整归约。即使将 K 分块,如果部分累加器在合并前可能溢出,也不能因此缩窄它。加入偏置或合并多个归约,需要重新分析范围。

测试最小值×最小值、最小值×最大值、最大值×最大值和正负交替情况。同时保留宽整数参考和选定位宽的结果。在规定范围内精确累加,与范围外的回绕或饱和,是不同的约定;把所有不匹配都归为普通溢出,会掩盖真正的符号错误。

自己试试

W=4、K=3 时,求保守的 AW 和最大正和。乘积 −8×7 应使用哪个位值进行扩展?

阅读解释

PW=8,ceil(log2 3)=2,因此 AW=10。最大正和为 3×64=192。乘积为 −56,必须用一进行扩展。十位有符号数的范围为 −512..511。

你的选择适用于此浏览器,可随时在页脚更改。