3

16 ビット幅のレジスタを持つレジスタ マップがあります。幅が 16 ビットを超えるフィールドがあるため、2 つのアドレスにまたがる必要があります。このフィールドへのバックドア アクセスを定義するにはどうすればよいですか?

これは私が自分の分野で試したことですtest_pattern[23:0]:

register_a.add_hdl_path_slice("path.to.regmap.test_pattern[15:0]", 0, 16);
register_b.add_hdl_path_slice("path.to.regmap.test_pattern[23:16]", 0, 8);

これは次のエラーで失敗します:

エラー: VPI TYPERR vpi_handle_by_name() はパーツ選択へのハンドルを取得できません。

これが私のツールの制約なのか、それとも UVM コードが VPI を使用する方法の制約なのかは明らかではありません。UVM コード内を調べてみると、部分選択を処理する必要があるコードが表示されますが、それは#ifdef QUESTAディレクティブ内にあるため、これはツールの制約であると思います。

これに対する良い回避策はありますか?

4

3 に答える 3

0

このコードに貢献した人 (おそらくメンター?) が、 でラップされたユニバーサルライブラリに便利な機能を追加する必要があると感じたのは非常に残念ですifdefs。実際、UVM_1_2DPI/PLI インターフェイス ファイル全体がシミュレーター固有の実装に分割されているブランチでは、さらに悪化します。

git://git.code.sf.net/p/uvm/code のマスター ブランチを見るとdistrib/src/dpi/uvm_hdl.c、QUESTA 固有のコードは次の関数だけのようです。

static int uvm_hdl_set_vlog_partsel(char *path, p_vpi_vecval value, PLI_INT32 flag);
static int uvm_hdl_get_vlog_partsel(char *path, p_vpi_vecval value, PLI_INT32 flag);

次の DPI 定義値を使用します。

svLogic logic_bit;
svGetBitselLogic(&bit_value,0);
svLogicVecVal bit_value;
svGetPartselLogic(&bit_value,value,i,1);
svPutPartselLogic(value,bit_value,i,1);

理論的には、シミュレーターと Mentor コードの両方が標準に準拠している場合、 を削除しても動作ifdefsするはずです。

パス内のパーツ選択を検出しvpi_handle_by_index、個々のビットを読み取るために使用することでこれを行うこともできます。これは、どのシミュレーターでもサポートされている必要があります。

注意: コードが Mentor 固有のものであるという私の最初の回答は間違っていました。@dave_59 に感謝します。

于 2014-06-16T16:40:40.630 に答える
0

UVMクラスリファレンスによると:

function void add_hdl_path_slice(文字列名,
    int オフセット、
    int サイズ、
    ビットファースト = 0、
    文字列の種類 = "RTL")

ソリューションではoffset、開始インデックスを選択するために を使用する必要があると思います。

register_a.add_hdl_path_slice("path.to.regmap.test_pattern", 0, 16);
register_b.add_hdl_path_slice("path.to.regmap.test_pattern", 16, 8);

可能な代替、for ループでのビット選択:

for (int i=0; i<16; i++) begin
  string tmp_path_s;
  tmp_path_s = $sformatf("path.to.regmap.test_pattern[%0d]", i);
  register_a.add_hdl_path_slice(tmp_path_s, i, 1);
end
for (int i=0; i<8; i++) begin
  string tmp_path_s;
  tmp_path_s = $sformatf("path.to.regmap.test_pattern[%0d]", i+16);
  register_a.add_hdl_path_slice(tmp_path_s, i, 1);
end
于 2014-06-13T19:41:54.103 に答える
0

これを 2 つのレジスタに分割しない理由はありますか。レジスタのサイズは 16 ビットなので、これより大きいレジスタを宣言しても意味がありません。

このような大きなフィールドが定義されているのを私が見た方法は、それぞれに別のフィールドを持つ 2 つのレジスタを宣言することです。たとえば、32 ビット ポインターが必要な場合は、次のようになります。

16 ビット フィールドを持つ addr_high 16 ビット フィールドを持つ addr_low

便宜上、両方に順番にアクセスするタスクを追加できます。

于 2015-02-17T22:51:07.280 に答える