变量x与固定系数h二补数乘积算法及其Verilog实现(signed 2’scomplement)
一、二补数乘法算法
- 我们设计有符号乘法器时会遇到一个问题,负数二进制数不能直接移位相乘再相加,这样做的结果是错误的,官方的做法是先把负数转换成二补数,接着再按一定规则进行计算,本质还是移位相加,但多了一些细节要注意。
1.1 算法概述
- 第一步:将是负数的被乘数和乘数按取反再加一原则转换成二补数,如下-3与-2 -> 101与110
- 第二步:按乘法规则等式计算,注意这一步要将输出位宽扩展至被乘数或者乘数其中最高位宽的2倍,按乘法规则每一位移位相乘计算过程中补充位按原最高位补齐,但是超过2倍位宽的要截断。
- 第三步:乘数y最高位乘以x时,前面符号是负号。
- 第四步:将移位数据相加求和(包括一行减数据),输出的依然是二补数,既是乘法器输出。
1.2 二补数乘法算法具体流程-辅助理解
二、二补数乘法算法Verilog实现并验证
2.1 Verilog设计
** 上节算法的Verilog实现代码如下所示:**
`timescale 1ns/1ps
module Mult_2scomplement
#( parameter N_bit_x = 11, //xin width
parameter hin = 10'b01_1111_1111) //hin 2'scomplenemt
(
input [N_bit_x-1:0] xin,
output reg [2*N_bit_x-1:0] Mult_2scomplement_out
);
reg [2*N_bit_x-1:0] x;
reg [2*N_bit_x-1:0] h0,h1,h2,h3,h4,h5,h6,h7,h8,h9;
reg [2*N_bit_x-1:0] out0,out1,out2,out3,out4,out5,out6,out7,out8,out9;
//stretch twofold width xin to x
always@(*) begin
x <= {{{N_bit_x}{xin[N_bit_x-1]}},xin};
end
//shifter
always@(*) begin
h0 <= {{2*N_bit_x}{hin[0]}}&x;
h1 <= {{2*N_bit_x}{hin[1]}}&x;
h2 <= {{2*N_bit_x}{hin[2]}}&x;
h3 <= {{2*N_bit_x}{hin[3]}}&x;
h4 <= {{2*N_bit_x}{hin[4]}}&x;
h5 <= {{2*N_bit_x}{hin[5]}}&x;
h6 <= {{2*N_bit_x}{hin[6]}}&x;
h7 <= {{2*N_bit_x}{hin[7]}}&x;
h8 <= {{2*N_bit_x}{hin[8]}}&x;
h9 <= {{2*N_bit_x}{hin[9]}}&x;
out0 <= {h0[2*N_bit_x-1:0]};
out1 <= {h1[2*N_bit_x-2:0],1'b0};
out2 <= {h2[2*N_bit_x-3:0],2'b0};
out3 <= {h3[2*N_bit_x-4:0],3'b0};
out4 <= {h4[2*N_bit_x-5:0],4'b0};
out5 <= {h5[2*N_bit_x-6:0],5'b0};
out6 <= {h6[2*N_bit_x-7:0],6'b0};
out7 <= {h7[2*N_bit_x-8:0],7'b0};
out8 <= {h8[2*N_bit_x-9:0],8'b0};
out9 <= {h9[2*N_bit_x-10:0],9'b0};
//shifter sum(out0-8) and sub(out9)
Mult_2scomplement_out <= (((out0 + out1 + out2) + (out3 + out4 + out5) +
(out6 + out7+ out8)) - out9);
end
endmodule
2.2 门级仿真验证
1) xin乘hin(+1)通过:
2)xin乘hin(+255)通过
3)xin乘hin(+511)通过
4)xin乘hin(-1)通过
5)xin乘hin(-255)通过
6)xin乘hin(-511)通过
总结:此二补数(2’scomplement)乘法器满足功能需求,验证通过,需要的同学可自取