Как мне преобразовать число в дополнение к двум в verilog? - PullRequest
4 голосов
/ 27 октября 2008

Я пытаюсь спроектировать 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 в дополнение к двум, а затем просто сделать регулярное сложение. Я уверен, что остальная часть сумматора верна, я просто не знаю, что не так с той частью, где я пытаюсь конвертировать.

Ответы [ 3 ]

5 голосов
/ 17 июня 2009
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

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

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

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

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

0 голосов
/ 27 октября 2008

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

...