23

ISE 12.4 で構文チェックに合格するモジュールを取得しようとしていますが、理解できないエラーが表示されます。最初のコード スニペット:

parameter ROWBITS = 4;

reg [ROWBITS-1:0] temp;

genvar c;
generate
    always @(posedge sysclk) begin
        for (c = 0; c < ROWBITS; c = c + 1) begin: test
            temp[c] <= 1'b0;
        end
    end
endgenerate

構文チェックを試みると、次のエラー メッセージが表示されます。

ERROR:HDLCompiler:731 - "test.v" 46 行目: 非レジスタ <c> への手続き型代入は許可されていません。

なぜそれが不平を言っているのか、私は本当に理解していません。「c」はワイヤではなく、genvar です。これは、完全に正当な構文と同等である必要があります。

reg [3:0] temp;

always @(posedge sysclk) begin
    temp[0] <= 1'b0;
    temp[1] <= 1'b0;
    temp[2] <= 1'b0;
    temp[3] <= 1'b0;
end

生成せずにこれを書く方がいかに簡単かについてのコメントはありません。これは、複数の if と "temp" へのノンブロッキング代入を含む、はるかに複雑なコード部分の簡略化された例です。また、新しいバージョンの ISE があるとだけ言わないでください。私はすでにそれを知っています。OTOH さん、ISE の新しいバージョンで修正されていることがわかっている場合は、動作することがわかっているバージョンを教えてください。

4

6 に答える 6

27

生成ブロック内のネストを逆にする必要があります。

genvar c;
generate
    for (c = 0; c < ROWBITS; c = c + 1) begin: test
        always @(posedge sysclk) begin
            temp[c] <= 1'b0;
        end
    end
endgenerate

技術的には、これにより 4 つの always ブロックが生成されます。

always @(posedge sysclk) temp[0] <= 1'b0;
always @(posedge sysclk) temp[1] <= 1'b0;
always @(posedge sysclk) temp[2] <= 1'b0;
always @(posedge sysclk) temp[3] <= 1'b0;

この単純な例では、4 つの always ブロックと 4 つの代入を含む 1 つの always ブロックの動作に違いはありませんが、他の場合には違いがある可能性があります。

デザインのメモリ内表現を構築するとき (シミュレータの場合)、または論理ゲートにマッピングするとき (合成ツールの場合)、genvar 依存の操作を解決する必要があります。always @posedgeデザインが動作するまでは意味がありません。

特定の制限を条件として、合成可能なコードであっても、always ブロック内に for ループを配置できます。合成では、ループが展開されます。ただし、その場合、for ループはreginteger、または同様のもので動作する必要があります。を使用することはできませんgenvar。always ブロック内に for ループがあると、クロックの各エッジで発生する操作が記述され、設計のエラボレーション中に静的に展開できる操作ではないためです。

于 2012-09-20T01:15:51.940 に答える
6

temp同じ always ブロックに割り当てられたすべてのビットが必要な場合は、生成ブロックは必要ありません。

parameter ROWBITS = 4;
reg [ROWBITS-1:0] temp;
always @(posedge sysclk) begin
    for (integer c=0; c<ROWBITS; c=c+1) begin: test
        temp[c] <= 1'b0;
    end
end

または、シミュレーターが IEEE 1800 (SytemVerilog) をサポートしている場合は、

parameter ROWBITS = 4;
reg [ROWBITS-1:0] temp;
always @(posedge sysclk) begin
        temp <= '0; // fill with 0
    end
end
于 2013-07-02T00:12:21.930 に答える
4

ファイルをコンパイル/生成する必要がない場合は、前処理手法を使用できます。これにより、生成のパワーが得られますが、クリーンな Verilog ファイルが生成され、多くの場合、デバッグが容易になり、シミュレーターの問題が少なくなります。

RubyItを使用して、ERB (Embedded Ruby) を使用してテンプレートから Verilog ファイルを生成します。

parameter ROWBITS = <%= ROWBITS %> ;
always @(posedge sysclk) begin
  <% (0...ROWBITS).each do |addr| -%>
    temp[<%= addr %>] <= 1'b0;
  <% end -%>
end

以下を使用して module_name.v ファイルを生成します。

$ ruby_it --parameter ROWBITS=4 --outpath ./ --file ./module_name.rv

生成された module_name.v

parameter ROWBITS = 4 ;
always @(posedge sysclk) begin
  temp[0] <= 1'b0;
  temp[1] <= 1'b0;
  temp[2] <= 1'b0;
  temp[3] <= 1'b0;
end
于 2012-09-21T14:55:22.023 に答える
2

モジュール内で、Verilog には基本的に項目とステートメントの 2 つの構造が含まれます。ステートメントは、begin..end、関数、タスク、always ブロック、initial ブロッ​​クの間のすべてを含む手続き型コンテキストで常に検出されます。生成コンストラクトなどのアイテムは、モジュールに直接リストされます。for ループとほとんどの変数/定数宣言は、両方のコンテキストに存在できます。

あなたのコードでは、for ループを生成項目として評価する必要があるように見えますが、ループは実際には always ブロックの手続き型コンテキストの一部です。for ループが生成ループとして扱われるには、それがモジュール コンテキスト内にある必要があります。generate..endgenerate キーワードは完全にオプションであり (一部のツールでは必要です)、効果はありません。生成ループの評価方法の例については、この回答を参照してください。

//Compiler sees this
parameter ROWBITS = 4;
reg [ROWBITS-1:0] temp;
genvar c;

    always @(posedge sysclk) //Procedural context starts here
    begin
        for (c = 0; c < ROWBITS; c = c + 1) begin: test
            temp[c] <= 1'b0; //Still a genvar
        end
    end
于 2012-09-20T05:42:20.077 に答える
0

Verilogの場合は

parameter ROWBITS = 4;
reg [ROWBITS-1:0] temp;
always @(posedge sysclk) begin
  temp <= {ROWBITS{1'b0}}; // fill with 0
end
于 2014-12-12T10:37:54.420 に答える