乘法器代码如下
module muilt2b(RX,AX,BX);
input [3:0]AX,BX;//有符号数AX,BX
output [6:0]RX; //RX输出
reg[6:0]RX,TA; //RX[5:0]是RX的数值部分 TA是AX不断进位
reg[2:0]TB; //BX的数值部分
reg [0:0] QX ; //保存符号
always @(AX or BX)
begin
RX=0;
TA=AX[2:0];
TB=BX[2:0];
QX=AX[3]+BX[3];//计算符号
repeat(3)
begin
if(TB[0])
begin
RX=RX+TA;
end
TA=TA<<1;
TB=TB>>1;
end
RX={QX,RX[5:0]};//RX为符号位加数值位
end
endmodule
但是仿真的时候出现了错误
这里AX 为1111的时候 为什么显示值是-1呢 不应该是-7么 BX 为1010 为-2 却显示为-6 计算结果RX为0001110 为14是对的
AX为0110 值为6是对 BX为1000 为0 却显示为-8 RX为 0000000 计算结果为0是对的
AX为1110 值应该是-6 显示为-2 BX为1100 应该是-4 显示为-4 计算结果RX为 0011000 为24 显示为24是正确的
可见这里正数显示都是正确的 负数会显示错误 但是计算是正确的。
即逻辑没有错误。
其实是我忽略了一个很大问题,有符号数的负数是用补码的形式来表示的 即 -5不是1101 而是1011 -2不是1010而是1110
我是傻逼!
那么怎么考虑其负数是补码的情况下计算呢
修改代码如下
module muilt2b(RX,AX,BX);
input [3:0]AX,BX;//有符号数AX,BX
output [7:0]RX; //RX输出
reg[7:0]RX,TA; //RX[5:0]是RX的数值部分 TA是AX不断进位
reg[2:0]TB; //BX的数值部分
reg [0:0] QX ; //保存符号
always @(AX or BX)
begin
RX=0;
TA=AX[3]?(~AX+1'b1):AX; //若为负数就取反加1用正数乘,反之不变
TB=BX[3]?(~BX+1'b1):BX; //同上
QX=AX[3]+BX[3];//计算符号
repeat(4)
begin
if(TB[0])
begin
RX=RX+TA;
end
TA=TA<<1;
TB=TB>>1;
end
RX=QX?(~RX+1'b1):RX;//RX为符号位加数值位
end
endmodule
得仿真结果如下
可见当AX为正数时仿真正确,负数时却仿真错误。不知道为啥
修改后代码:
module muilt2b(DX,AX,BX);
input [3:0]AX,BX;//有符号数AX,BX
output [7:0]DX; //RX输出
reg[7:0]RX,TA;//RX[5:0]是RX的数值部分 TA是AX不断进位
reg[7:0]DX; // shuchu
reg[2:0]TB; //BX的数值部分
reg [0:0] QX ; //保存符号
always @(AX or BX)
begin
RX=0;
TA={4'b0000,AX[3]?(~AX+1'b1):AX}; //若为负数就取反加1用正数乘,反之不变
TB=BX[3]?(~BX+1'b1):BX; //同上
QX=AX[3]+BX[3];//计算符号
repeat(4)
begin
if(TB[0])
begin
RX=RX+TA;
end
TA=TA<<1;
TB=TB>>1;
end
DX=QX?(~RX+1'b1):RX;//若QX为正则取反,反正不变
end
endmodule
TA赋值时确保不出错
仿真结果如图
不再出错。
所以之前可能是TA赋值出现问题
查阅资料后发现短位赋值长位时有如下规则:资料链接:https://zhuanlan.zhihu.com/p/265295436
所以会出现再给TA赋值时。若AX为正则无误,若AX为负则出错的情况。
即上错例 -2*2 TA 理应赋值为00000010 错赋值为11110010 计算后得28