我想设计一个ALU来对两个8位寄存器(A,B)执行一些操作,为了检测carry_out,我将一个9位寄存器定义为temp,并将操作结果放在该寄存器中的A,b上。
该临时寄存器的MSb用作执行。
这是我的代码的一部分:
module ALU(input signed [7:0] A, input [7:0] B, input carry_in, input [2:0] acode, output reg [7:0] R, output zero, output reg carry_out);
reg [8:0] temp;
reg [15:0] temp2;
always @(A, B, acode) begin
case(is_shift)
1'b0: begin
case(acode)
3'b000: temp = A + B;
3'b010: temp = A - B;
endcase
R = temp[7:0];
carry_out = temp[8];
鉴于A = 11100101且B = 11000111,这是日志:
//addition
A: 11100101 , B: 11000111
acode: 000
R: 10101100
zero: 0, carry_out: 1
//subtraction
A: 11100101 , B: 11000111
acode: 010
R: 00011110
zero: 0, carry_out: 0
在这两种情况下,temp的第9位应该是1并且在加法情况下它是正确的但在减法情况下,减法是正确的但是temp的第9位没有设置为1。
这有什么问题?
顺便说一下:签名注册的效果只是在转移和延伸,是吗?所以这个问题不是因为A被签名而B是无符号的,对吧?
答案 0 :(得分:1)
声明登记的登记效果仅限于转移和延伸
不,它影响所有算术。虽然通常如果组合任何无符号或部分选择总线,它将默认返回无符号算术。
你真的不能有一个输入签名而一个没有,二进制补码算法根本不起作用。您至少必须签名扩展签名值并在无符号上插入0 MSB,确保它将被评估为正数。
你的第一个例子是:
1110 0101 // -27
1100 0111 // -57
1 1010 1100 // -84 (-27 -57)
第二个例子(减法)
1110 0101 // -27
0011 1001 // +57
1 0001 1110 // 30 (ignoring MSB) -226 Including MSB
但请注意,输出宽1位,RTL不允许您访问进位,而是额外求和,因此输入符号扩展。
1 1110 0101 // -27
1 1100 0111 // -57
1 1010 1100 // -84
1 1110 0101 // -27
0 0011 1001 // +57
0 0001 1110 // 30
注意,在正确符号扩展减法中,MSB为0
但是对于你添加的第二个值unsigned你需要一个0表示它是一个正数,你将有1位的位增长:
1 1 1110 0101 // -27
0 0 1100 0111 // 199
0 0 1010 1100 // 172 (-27+199)
这里扩展位(不是进位)是0.而不是你所预测的。