【问题标题】:verilog subtraction does not yield carry outverilog 减法不产生执行
【发布时间】:2015-03-30 09:14:27
【问题描述】:

我想设计一个 ALU 来对两个 8 位寄存器( A , B )执行一些操作,为了检测进位输出,我将一个 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 被 unsigned ,对吧?

【问题讨论】:

  • “减速”是什么意思?
  • @mkrieger1 这是声明的错字,已编辑问题。
  • 我明白了 ;) @Pooya,因为结果可能是负数,所以您也应该将 temp 声明为已签名。

标签: verilog alu


【解决方案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

但是对于第二个无符号值的加法,您需要一个 0 来表示它是一个正数,并且您将有 1 位的位增长:

1 1 1110 0101  // -27
0 0 1100 0111  // 199
0 0 1010 1100  // 172 (-27+199)

这里的扩展位(不是进位)是 0。不是你预测的 1。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-31
    • 1970-01-01
    相关资源
    最近更新 更多