умножение со знаком и без знака в SystemVerilog - PullRequest
0 голосов
/ 01 июля 2019

У меня есть конкретный вопрос и просьба о более общих указаниях.

У меня вопрос, какой самый чистый способ умножить число со знаком на число без знака в SystemVerilog?

Ниже приведенонебольшой тестовый код, который иллюстрирует проблему.«а» - это число без знака.«б» является подписанным номером.Для получения правильного результата со знаком 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 голосов
/ 02 июля 2019

Системные правила verilog говорят:

Если какой-либо операнд не подписан, результат будет без знака, независимо от оператора

Распространение типа и размера выражения (или самоопределениеподвыражение) обратно к контекстно-определенным операндам выражения

Когда распространение достигает простого операнда, как определено в 11.5, этот операнд должен быть преобразован в распространяемый тип и размер.

Таким образом, другими словами, при использовании чисел с несколькими знаками и без знака тип выражения будет определяться как unsigned.Это будет распространено обратно к операндам, и все подписанные будут также рассматриваться как беззнаковые.

, поэтому ваш результат будет идентичен результату умножения двух чисел без знака.Итак, самый простой способ, если вам нужен результат со знаком, - преобразовать все операнды в число со знаком.

Вам также понадобится дополнительный бит в операндах, чтобы иметь место для знака.В противном случае 255 будет считаться -1 при 8-битном преобразовании знака.

...