verilog减法不会产生执行

时间:2015-03-30 09:14:27

标签: verilog alu

我想设计一个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是无符号的,对吧?

1 个答案:

答案 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.而不是你所预测的。