SystemVerilog中的有符号和无符号定点乘法

时间:2019-07-01 19:08:32

标签: system-verilog multiplication unsigned signed

我有一个具体问题,需要更一般的指导。

我的问题是,在SystemVerilog中将带符号的数字乘以无符号的数字最干净的方法是什么?

下面是一些说明问题的测试代码。 “ a”是无符号数字。 “ b”是签名号。为了产生正确的带符号结果,SystemVerilog似乎要求对乘法的两个操作数进行签名。为了在这里工作,我必须在无符号数字的前面添加一个额外的“ 0”以使其成为有效的带符号数字。我在想必须有一种更清洁的方法。

更一般而言,我才刚刚开始在SystemVerilog中进行定点数学运算。在VHDL中,有非常具体的语法,甚至是一个标准的程序包,都支持有符号和无符号定点数学运算以及舍入等。在SystemVerilog世界中是否有类似的东西?

谢谢

module testbench ();
    localparam int Wa = 8;
    localparam int Wb = 8;

    logic  [Wa-1:0] a;       // unsigned
    logic  [Wa:0] a_signed;  // signed word with extra bit to hold unsigned number.
    logic  [Wb-1:0] b;       // signed
    logic  [Wa+Wb-1:0] c;    // result

    localparam clk_period = 10;

    assign a_signed = {1'b0, a};
    assign c = $signed(a_signed)*$signed(b);

    initial begin
        a = +5;
        b = +10;
        #(clk_period*1);
        $display("Hex: a=%x,b=%x, c=%x; Dec: a=%d, b=%d, c=%d", a, b, c, a, $signed(b), $signed(c));

        a = +5;
        b = -10;
        #(clk_period*1);
        $display("Hex: a=%x,b=%x, c=%x; Dec: a=%d, b=%d, c=%d", a, b, c, a, $signed(b), $signed(c));

        a = +255;
        b = +10;
        #(clk_period*1);
        $display("Hex: a=%x,b=%x, c=%x; Dec: a=%d, b=%d, c=%d", a, b, c, a, $signed(b), $signed(c));

        a = +255;
        b = -10;
        #(clk_period*1);
        $display("Hex: a=%x,b=%x, c=%x; Dec: a=%d, b=%d, c=%d", a, b, c, a, $signed(b), $signed(c));

        $stop;
    end

endmodule

1 个答案:

答案 0 :(得分:0)

系统Verilog规则说

  

如果任何操作数是无符号的,则结果是无符号的,而不管运算符是什么

     

将表达式(或自定义子表达式)的类型和大小传播回表达式的上下文确定操作数

     

当传播达到11.5中定义的简单操作数时,则应将该操作数转换为传播的类型和大小。

因此,换句话说,当您使用带符号的数字和无符号的数字时,表达式类型将确定为unsigned。这将被传播回操作数,所有带符号的也将被视为无符号。

因此,您的结果将等于两个无符号数字相乘的结果。因此,如果需要带符号的结果,最干净的方法是将所有操作数转换为带符号的数字。

您还需要在操作数中加一个位,以放置符号位。否则,在8位符号转换中将255视为-1