2

この SystemVerilog コードに問題があります。コードは次のとおりです。

module mult ( multiplicand, multiplier, Product, clk, clear, 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

4 に答える 4

6

組み合わせロジックをalwaysブロックで記述する場合、すべての変数がコード内のすべてのパスの値に割り当てられていることを確認する必要があります。それ以外の場合、ラッチが推論されます。always従来のブロックではこのようなものを見落としやすいためalways_comb、SystemVerilog ではこれを明示的にチェックするためにブロックが導入されました。

あなたの場合、 case ステートメントの各ブランチに値が割り当てられていないバスがいくつかあります。たとえば、ブランチとmcandに値が割り当てられていません。nao_multiplicarfim

2つの解決策があります。まず、すべてのコード ブランチのすべての変数に割り当てます。

always_combもう 1 つの解決策は、case ステートメントの前にすべての変数の「デフォルト」値を書き込むことです。このように、各変数はブロックがトリガーされるたびに常に値に割り当てられ、always_comb警告は発生しません。あなたの case ステートメントは、変更が必要な変数のみを処理する必要があります。

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     
于 2011-05-19T06:16:53.857 に答える
3

initialブロックを取り除くと、すべてのコンパイル エラーが解消されます。Cadence と Synopsys のシミュレーターを使用しています。

以下は、IEEE Std、1800-2009、セクション 9.2.2.4「Sequential logic always_ff procedure」からの引用です。

always_ff プロシージャは、イベント コントロールを 1 つだけ含み、ブロッキング タイミング コントロールを含まないという制限を課します。呼び出された関数の内容からの変数を含む、always_ff プロシージャ内の代入の左側の変数は、他のプロセスによって書き込まれてはなりません。

にも同様の引用がありますalways_comb

ドキュメントは、IEEE から簡単に入手できます。シミュレーターにもドキュメントが必要です。

この場合、ツールから受け取るエラー メッセージはあまり役に立たないようです。

于 2011-05-19T13:01:14.377 に答える
0

LRM は、私がシステム Verilog に使用する最も有用なドキュメントです。

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

于 2011-05-19T20:31:38.077 に答える