前言
verilog数字位宽的拓展、加法以及乘法运算的位宽计算
一、有符号数拓展位宽
8位宽有符号数拓展为10位宽有符号数,在原始数据前添加不足的符号位。位宽拓展是为了在加法或者乘法是保持位宽一致。
reg signed [7:0] data_a;
wire signed [9:0] mult;
assign mult = {{2{data_a[9]}}, data_a};
二、加法位宽
2.1无符号数加法
reg [7:0] data_a;
reg [7:0] data_b;
wire [8:0] add_out;
add_out = data_a + data_b;
加法器立刻输出,不是非阻塞赋值。
2.2有符号加法
reg signed [7:0] data_a;
reg signed [3:0] data_b;
wire signed [7:0] data_b1;
assign data_b1 = {{4{data_b1[3]}},data_b1};
wire signed [8:0] add_out;
assign add_out = data_a + data_b1;
对于两个有符号数相加,结果的位宽设计应为 max(M,N)+1 位,其中 M 和 N 分别为两个操作数的位宽。这样可以确保结果的全精度输出,并正确处理可能产生的进位。
2.3注意事项
注意事项:
1、加法运算符两边的信号,位宽一致;
2、加法运算符两边的信号,要么都是有符号数,要么都是无符号数;
3、考虑到加法可能产生进位,输出信号比输入信号多1bit即可
三、乘法位宽
3.1无符号数乘法
reg [7:0] data_a;
reg [4:0] data_b;
wire [12:0] mult_out;
assign mult_out = data_a * data_b;
两个无符号数相乘,输出信号位宽直接定义成两个输入信号位宽之和即可。
3.2 有符号数乘法
reg signed [7:0] data_a;
reg signed [4:0] data_b;
wire signed [11:0] mult_out;
assign mult_out = data_a*data_b;
两个有符号数相乘,其结果所需的位宽取决于两个乘数的位宽。一般来说,两个有符号数相乘的结果位宽为两个乘数位宽之和。例如,对于一个M位的有符号数和一个N位的有符号数相乘,结果通常需要M+N位来表示。
需要注意的是,在某些特殊情况下,如果两个乘数均为所能表示的最小数(最高位为1,其余为0),则需要M+N位字长来存放结果;而在其他情况下,由于存在两位相同的符号位,实际上只需要M+N-1位宽即可存放运算结果
所以一般有符号数乘法一般采用M+N-1位的位宽。