Systemverilog проблема с конструкцией always_comb - PullRequest
1 голос
/ 19 мая 2011

У меня проблема с этим кодом Systemverilog. Я новичок в этом языке и очень сложен найти соответствующую документацию по этому языку. Вот код:

модуль mult (умножение, множитель, произведение, clk, очистить, Startm, endm);

input [31:0] multiplicand;
input [31:0] multiplier  ;
input clk;
input clear; 
input Startm;

output logic [63:0] Product;
output logic endm;


enum logic [1:0] { inicio, multiplicar, nao_multiplicar, fim } estados;
logic [1:0] state;

logic [31:0] mplier;
logic [31:0] mplier_aux;
logic [31:0] mcand ;
logic [31:0] mcand_aux;
logic [63:0] Prod  ;
logic [63:0] Prod_aux;
logic [5:0] cont;
logic [5:0] cont_aux;

initial begin
    mplier     = multiplier;
    mplier_aux = multiplier;
    mcand     = multiplicand;
    mcand_aux = multiplicand;
    Prod      = 0;
    Prod_aux  = 0;
    state     = inicio;
    cont      = 0;
    cont_aux  = 0; 
end

always_ff @( posedge clk )
begin
    if( clear ) 
    begin
        state <= inicio;
    end
    else if ( Startm )
    begin
        case( state )
        inicio :
        begin
                    if( mplier[0] == 0 )
                    begin
                        state <= nao_multiplicar;
                    end
                    else if( mplier[0] == 1 )
                    begin
                        state <= multiplicar;
                    end
        end
        multiplicar :
        begin
                    if( cont == 32 )
                        state <= fim;
                    else if( mplier[0] == 0 )
                    begin
                        state <= nao_multiplicar;
                    end
                    else if( mplier[0] == 1 )
                    begin
                        state <= multiplicar;
                    end
        end
        nao_multiplicar:
        begin
                    if( cont == 32 )
                        state <= fim;
                    else if( mplier[0] == 0 )
                    begin
                        state <= nao_multiplicar;
                    end
                    else if( mplier[0] == 1 )
                    begin
                        state <= multiplicar;
                    end
        end
        fim:
        begin
                    state <= inicio;
        end
        endcase
    end
end
    always_comb
    begin
        case(state)
        inicio:
        begin
                    mplier = multiplier;
                    mcand  = multiplicand;
                    Prod   = 0;
                    cont_aux = cont + 1;
                    cont = cont_aux;
        end
        multiplicar:
        begin   
                    mcand_aux  = mcand  << 1;
                    mcand      = mcand_aux  ;
                    mplier_aux = mplier >> 1;
                    mplier     = mplier_aux ;
                    Prod_aux   = Prod + mcand;
                    Prod       = Prod_aux;
                    cont_aux   = cont + 1;
                    cont       = cont_aux;
        end
        nao_multiplicar:
        begin
                    cont_aux = cont + 1;
                    cont     = cont_aux;
        end
        fim:
        begin
                    Product = Prod;
                    endm    = 1;
        end
        endcase
    end     

endmodule

Я пытаюсь написать мультипликатор с входами 32 бит и произведение 64 бит, используя Алгоритм Бута. Эта ошибка происходит: «конструкция Always_comb не подразумевает чисто комбинационную логику». Почему это происходит?

Ответы [ 4 ]

5 голосов
/ 19 мая 2011

При описании комбинационной логики в блоках always вы должны убедиться, что все ваши переменные присвоены значению во всех путях в вашем коде.В противном случае будет обнаружена защелка.Легко пропустить что-то подобное в традиционных блоках always, поэтому в SystemVerilog был введен блок always_comb, чтобы явно проверить это.

В вашем случае у вас есть несколько шин, которые не назначенызначения в каждой ветви оператора case, например, mcand не имеет значения, назначенного ему в ветвях nao_multiplicar и fim.

Существует 2 решения.Во-первых, нужно назначить все переменные во всех ветвях кода.

Другое решение - записать значения по умолчанию для всех переменных в always_comb перед оператором case.Таким образом, каждая переменная всегда будет присваиваться значению каждый раз, когда срабатывает блок always_comb, и предупреждений не будет.В этом случае вы должны иметь дело только с переменными, которые нужно изменить:

always_comb
begin
    // Defaults (I think I got them all)
    mplier     = multiplier;
    mcand      = multiplicand;
    Prod_aux   = 0;
    Prod       = 0;
    cont_aux   = 0;
    cont       = 0;
    Product    = 0;
    endm       = 0;

    // Now override the defaults when appropriate
    case(state)
    inicio:
    begin
                mplier = multiplier;
                mcand  = multiplicand;
                Prod   = 0;
                cont_aux = cont + 1;
                cont = cont_aux;
    end
    multiplicar:
    begin   
                mcand_aux  = mcand  << 1;
                mcand      = mcand_aux  ;
                mplier_aux = mplier >> 1;
                mplier     = mplier_aux ;
                Prod_aux   = Prod + mcand;
                Prod       = Prod_aux;
                cont_aux   = cont + 1;
                cont       = cont_aux;
    end
    nao_multiplicar:
    begin
                cont_aux = cont + 1;
                cont     = cont_aux;
    end
    fim:
    begin
                Product = Prod;
                endm    = 1;
    end
    endcase
end     
3 голосов
/ 19 мая 2011

Все ошибки компиляции устраняются, когда я избавляюсь от блока initial.Я использую симуляторы от Cadence и Synopsys.

Вот цитата из IEEE Std, 1800-2009, раздел 9.2.2.4 "Процедура последовательной логики всегда_ff":

Процедура Always_ff налагает ограничение на то, что она содержит один и только один элемент управления событиями и не содержит блокирующих элементов управления таймингом.Переменные в левой части присваиваний в процедуре Always_ff, включая переменные из содержимого вызываемой функции, не должны записываться никаким другим процессом.

Аналогичная кавычка для always_comb.

Документация доступна в IEEE.У вашего симулятора также должна быть документация.

Сообщение об ошибке, которое вы получаете от вашего инструмента, в этом случае, кажется, не очень полезно.

0 голосов
/ 20 августа 2016

always_comb будет выводить комбинационную логику, однако в вашем блоке always_comb вы выполняете назначения, подобные коду C, например:

always_comb
begin
  ...
  cont_aux   = cont + 1;
  cont       = cont_aux;
  ...
end

Здесь вы просите создать комбинационную логику с обратной связью.

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

always_ff @(posedge clk)
begin
  ...
  cont <= cont + 1;
  ...
end
0 голосов
/ 20 мая 2011

LRM - самая полезная документация, которую я использую для системного verilog

http://www.vhdl.org/sv/SystemVerilog_3.1a.pdf

...