2

モジュールがインスタンス化されるときに設定されるパラメーターに基づいてパラメーターを設定したいと思います。私は次のものを持っています。

module foo #(WORDS = 8);

parameter P00 = 33;
logic [7:0] tmp;

generate
  case (WORDS)
    4: begin : A
         assign tmp = 8'haa;
         parameter P00 = 4;
       end
    8: begin : B
         assign tmp = 8'hbb;
         parameter P00 = 8;
       end
   16: begin : C
         assign tmp = 8'hcc;
         parameter P00 = 16;
       end
   default: begin : D
              assign tmp = 8'hdd;
              parameter P00 = 8;
            end
  endcase
endgenerate

initial begin
  $display ("WORDS = %d", WORDS);
  $display ("tmp   = %h", tmp);
  $display ("P00   = %d", P00);
end

endmodule

P00 を再定義するとエラーが発生すると予想していましたが、コンパイルして実行すると、代わりに次のように表示されました。

WORDS =       8
tmp    = bb
P00    = 33

「パラメータ P00 = 33」の割り当てにコメントすると、「識別子 P00 はまだ宣言されていません」というメッセージが表示されます。エラー。

生成ブロックが無視されているようです。ここで何が問題なのですか?

4

3 に答える 3

1

生成ブロック内にパラメーター定義を配置すると、生成ブロック内の階層スコープに関連する新しいローカル パラメーターが生成されます。defparam通常、パラメータ値をオーバーライドする方法です。ただし、IEEE std 1800-2012 ではdefparam、§23.10.1 で親スコープに影響を与えることはできないと明示的に述べています。

生成ブロック インスタンス (第 27 節を参照) またはインスタンスの配列 (第 28.3.5 節および第 23.3.2 節を参照) 内または下の階層内の defparam ステートメントは、その階層外のパラメーター値を変更してはなりません。

複雑な派生パラメーターの割り当てには、関数を使用できます。例えば:

parameter P01 = FUNC01(WORDS,P00);
function byte FUNC01(input byte w,p);
/* ... */
endfunction

これも合法です:module foo #(parameter WORDS, P00=FUNC00(WORDS));

課題は、各パラメーターが独自の機能を必要とする場合があることです。struct データ型のパラメーターを使用すると、代入を 1 つの関数にグループ化するための潜在的な回避策になります。このアプローチは、シミュレーター、シンセサイザー、およびその他のツールで評価する必要があります。例:

typedef struct packed {
  int sub00;
  byte sub01;
  /* ... */
 bit [13:0] subNN
} param_t;
paramter param_t P = FUNC_P(/* inputs */);

function param_t FUNC_P(/* inputs */);
  param_t rtn;
  /* assign all rtn.sub* */
  return rtn;
endfunction

logic [P.sub01-1:0] tmpvar;

Morganが述べているように、ほとんどの as を定義しparameterslogic組み合わせブロックを使用できます。ただし、値が計算であることを保証するためalways_combに、の代わりにブロックを使用することを強く主張します。LRM §9.2.2.2.2always @*に記載されているとおり:

always_comb は時間ゼロで 1 回自動的に実行されますが、常に @* は推測されたセンシティビティ リスト内のシグナルで変更が発生するまで待機します。

于 2013-09-28T01:04:30.187 に答える
1

最近、これらのことを正しく教えていない新しいチュートリアルが書かれているかどうかわからない、生成と割り当てを不適切に使用するという質問がかなりあります。

パラメーターまたは Localparams は複数回定義してはなりません。これらは定数であるため、値を変更することはできません。モジュール foo のパラメータ キーワードも欠落していると思います。

module foo #(
  parameter WORDS = 8
);

localparam P00 = WORD;

スケーリング係数として使用するのが一般的です。

module foo #(
  parameter WIDTH = 8
  parameter MAX_VALUE = 2**WIDTH
);

定義したものは、値を保持するためにパラメーターではなくロジックを使用する必要があるように見えます。

全体を次のように書き直します。

module foo #(WORDS = 8);

logic [31:0] P00 = 33;
logic [7:0]  tmp;

always @* begin
  case (WORDS)
    4: begin : A
         tmp = 8'haa;
         P00 = 4;
       end
    8: begin : B
         tmp = 8'hbb;
         P00 = 8;
       end
   16: begin : C
         tmp = 8'hcc;
         P00 = 16;
       end
   default: begin : D
            tmp = 8'hdd;
            P00 = 8;
      end
  endcase
end

ここで達成しようとしていることには、generate の使用は不要です。

于 2013-07-19T06:56:59.343 に答える