Verilog中带符号定点数绝对值向下取整问题排查
问题分析
你当前的取整逻辑错误在于负数处理环节:对负数截断后加1会导致结果向0方向偏移,而非要求的绝对值向下取整(向负无穷取整)。
正确取整逻辑(向负无穷取整)
Q16.16转Q8.8的核心是将小数位从16位压缩到8位,同时保证取整后结果的绝对值不大于原数值的绝对值(负数更靠近负无穷,正数保持截断):
- 对32位Q16.16补码进行算术右移8位,提取符号位、高7位整数部分、高8位小数部分,得到初始Q8.8值。
- 若原数为负数,且被截断的低8位小数不全为0,则将初始值减1(补码下减1等价于向负方向移动一个Q8.8最小单位)。
Verilog修正代码
module q16_to_q8 ( input wire [31:0] q16_data, // 32位Q16.16带符号补码输入 output reg [15:0] q8_data // 16位Q8.8带符号补码输出 ); wire is_negative = q16_data[31]; wire has_truncated_fraction = |q16_data[7:0]; // 检查低8位小数是否非零 always @(*) begin // 第一步:算术右移8位,得到初始Q8.8值 q8_data = q16_data >>> 8; // 第二步:负数且存在截断小数时,减1实现向负无穷取整 if (is_negative && has_truncated_fraction) begin q8_data = q8_data - 1'b1; end end endmodule
测试用例验证
| Q16.16输入(32位补码) | 原数值 | 预期Q8.8输出(16位补码) | 预期数值 |
|---|---|---|---|
32'h00012345 | 1.1367 | 16'h0123 | 1.1367 |
32'hFFFFF000 | -1.0625 | 16'hFEFF | -1.0039 |
32'hFFFFFEDD | -0.0047 | 16'hFFFD | -0.0078 |
32'hFFFF0000 | -1.0 | 16'hFF00 | -1.0 |
错误原因说明
原逻辑中对负数截断后加1,会将负数结果向0方向修正,违背了“绝对值向下取整”的要求——负数的绝对值向下取整意味着数值应更小、更靠近负无穷。修正后的逻辑通过在负数存在截断小数时减1,保证了结果是小于等于原数值的最大Q8.8值,完全符合取整要求。
内容的提问来源于stack exchange,提问作者Damien
相关产品推荐
相关产品推荐

