我正在尝试为两个4位二进制补码的比较器编写一些简单的verilog代码。我有两个4位输入(A [3:0],B [3:0])和3个输出(AeqB,AgtB,AltB)来显示A和B是否相等,如果A大于B,或者A小于B.还有一个名为sign的第三个输入,如果0表示数字是无符号的,如果为1则表示数字是有符号的。
所以我知道两个签名的两个补码数可以通过减去它们进行比较,但我不能让它在我的设计中正常工作。这是我尝试过的:
if(sign==0)
begin
if(({sign,A}-{sign,B})==0)
AeqB = 1;
else if(({sign,A}-{sign,B}) > 0)
AgtB = 1;
else if (({sign,A}-{sign,B}) < 0
AltB = 1;
end
好像这应该有效。我将符号位连接到4位数字的前面,减去它们,然后检查它们是否大于或等于零。如果A-B <0,那么B小于A,因为它们都是负数。
然而,当我模拟这个设计时,只要A = B就是正确的,但在其他情况下都显示AgtB,而不是AltB。
关于我做错了什么想法?
答案 0 :(得分:1)
我不确定您使用{sign,A}
做了什么。这将强制数字在具有签名格式时为负数。除非标志强迫他们消极?
您可以定义要签名的输入或强制进行签名比较,并在无符号情况下填充msb以共享硬件,您所暗示的是并行的三个减法器。综合可能会做得很好并且共享硬件,但是每次它都给你提供了你想要的东西。
if (sign) begin
A_i = {A[3], A};
B_i = {B[3], B};
end
else begin
A_i = {1'b0, A};
B_i = {1'b0, B};
end
AgtB = $signed(A_i) > $signed(B_i) ;
AltB = ~AgtB ;
当添加减法数时,结果位增长是最大位宽输入+1。对于无符号0填充和中断结果为无符号。对于带符号的数字,通过重复MSB来对符号进行扩展。
为了帮助理解2的补码,我已经包含了一些符号无符号算术的4位示例。
无符号算术:
3 : (0)0011
+ 1 : (0)0001
= 4 : 0 0100
大型无符号算术:
15 : (0)1111 //Zero pad for correct bitwidths
+ 1 : (0)0001
=16 : 1 0000
大签名(溢出):
在结果上,不同的(01)MSB指示溢出以截断回到4位
7 : (0)0111
+1 : (0)0001
=8 : 0 1000 bits
<强>减法:强>
7 : (0)0111
-1 : (1)1111 //(twos complement of 1)
// Sum the bits as you did for unsigned
=6 : 0 0110