我正在 Verilog 中制作一个签名比较器。这是代码:

module signedComparator(a0, a1, a2, b0, b1, b2, G, E, L);
input a0, a1, a2, b0, b1, b2;
output reg G, E, L;

always@(a0 or a1 or a2 or b0 or b1 or b2)
begin

    if(a2 == 0 && b2 == 0) //both a and b >= 0
    begin
        L <= {a1,a0} < {b1,b0};
        G <= {a1,a0} > {b1,b0};
        E <= {a1,a0} == {b1,b0};
    end
    else if(a2 == 1 && b2 == 0) //a negative, b >= 0
    begin
        L <= 1;
        G <= 0;
        E <= 0;
    end
    else if(a2 == 0 && b2 == 1) //a >= 0, b negative
    begin
        L <= 0;
        G <= 1;
        E <= 0;
    end
    else //both a and b negative
    begin
        L <= (~{a1,a0} + 1) > (~{b1,b0} + 1);
        G <= (~{a1,a0} + 1) < (~{b1,b0} + 1);
        E <= (~{a1,a0} + 1) == (~{b1,b0} + 1);
    end

end
endmodule

我想知道,在添加向量时,中间结果的长度是多少?我担心最后一种情况( L <= (~{a1,a0} + 1) > (~{b1,b0} + 1); )。将~{a1,a0} 加1 时,比较结果的长度是三位,还是{1,1} + 1 = {0,0}?是否有关于 verilog 中中间结果的数据类型的文档?这很难搜索,因为我还不知道正确的术语。

最佳答案

我假设这是用于综合并且对您的代码有一些评论。您似乎使用单个位作为模块的输入,然后使用串联来制作向量。您可以通过将端口声明为有符号向量并直接进行比较来避免这种情况。

input signed [2:0] a,b;
...
if(a == b)
...
else if(a > b)
...
else
...

此外,您正在使用非阻塞分配来模拟组合逻辑。这些将在您发布的代码中工作,但实际上不应该以这种方式使用。它们通过时钟过程更好地建模同步逻辑。有一个 good paper 总结了一个很好的综合编码风格。



规范为此提供了一个表格,因为它取决于操作数和上下文。
  • 整数:未定义大小的常量至少为 32 位
  • {a,b} : sizeof(a) + sizeof(b)
  • ~{a} : sizeof(a)
  • a + b : max(sizeof(a),sizeof(b))

  • 因此,您的比较操作数都将是(至少)32 位。您可以通过在值前使用勾号来显式分配一个常量大小。
    4'b1 // 0001 Binary 1
    4'd1 // 0001 Decimal 1
    4'd8 // 1000 Decimal 8
    1'b1 //    1 Binary 1
    'b1  // The same as 1, tick here only specifies dec/oct/bin format
    



    到目前为止,我找到的有关此类详细信息的最佳资源是规范本身,即 IEEE 1364。

    关于verilog - Verilog 中算术运算结果的大小,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8015709/

    10-12 18:39