Как мне преобразовать число в дополнение к двум в verilog?

StackOverflow https://stackoverflow.com/questions/238894

  •  04-07-2019
  •  | 
  •  

Вопрос

Я пытаюсь спроектировать 4-битный сумматор в verilog. Это только вторая вещь, которую я когда-либо писал в verilog, и я еще не знаю весь правильный синтаксис. Это модуль, который у меня есть:

module Question3(carryin, X, Y, Z, S, carryout, overflow);
    parameter n = 4;
    input carryin, Z;
    input [n-1:0]X, Y;
    output reg [n-1:0]S;
    output reg carryout, overflow;

    if(Z==0)
    begin
        Y = not(y) + 4'b0001;
    end

    always @(X, Y, carryin)
        begin
            {carryout, S} = X + Y + carryin;
            overflow = carryout ^ X[n-1]^Y[n-1]^S[n-1];
        end

endmodule

Мой компилятор (xilinx 10.1) продолжает говорить "Синтаксическая ошибка рядом с if." Я испробовал много разных способов сделать преобразование, в том числе просто использовать регистр, который принимает Y в качестве аргумента, затем проверяет все возможные 4-битные комбинации и преобразует их в дополнение к двум.

Z - это то, что определяет, делает ли сумматор вычитание или сложение. Если это 0, это означает вычитание, и я хочу преобразовать y в дополнение к двум, а затем просто сделать регулярное сложение. Я уверен, что остальная часть сумматора верна, я просто не знаю, что не так с той частью, где я пытаюсь конвертировать.

Это было полезно?

Решение

reg [n-1:0] Y_compl;

always @( Z, Y, X, carryin ) begin
  Y_ = ( ~Y + 4'b0001 );
  if ( Z == 1'b0 ) begin
    {carryout, S} = X + Y_compl + carryin;
    overflow = carryout ^ X[n-1] ^ Y_compl[n-1] ^ S[n-1];
  end
  else begin
    {carryout, S} = X + Y + carryin;
    overflow = carryout ^ X[n-1] ^ Y[n-1] ^ S[n-1];
  end

end

Пара важных моментов.

<Ол>
  • Поместите оператор if внутри блока always. Не используйте два блока всегда, вы создадите условие гонки в симуляторе.
  • Я создал новую переменную Y_, потому что использование Y, который, как вы помните, является вводом в левой части присваивания, вероятно, будет выводить защелки или делать что-то еще неприятное, когда вы синтезируете.
  • Я предлагаю использовать оператор побитового обращения '~' для инвертирования Y вместо 'not' примитивный. У инструмента синтеза больше свободы для оптимизации кода таким образом.
  • Дважды проверьте правильность результатов, прошло некоторое время с тех пор, как я построил сумматор.
  • Другие советы

    Вы используете строчную букву " y " в "Y = not (y) + 4'b0001;"

    Кроме того, вы используете больше дополнений, чем нужно. X-Y - это то же самое, что и NOT (NOT (X) + Y).

    поместите оператор if в начальный блок
    http://www.asic-world.com/verilog/vbehave1.html

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top