7

Verilog に 256 ビットの値があります。

reg [255:0] val;

VPI を使用して外部 C を呼び出すシステム タスク $foo を定義したいので、次のように $foo を呼び出すことができます。

$foo(val);

関数 'foo' の C 定義では、引数を整数 (PLI_INT32) として単純に読み取ることはできません。しかし、引数を文字列として読み取ることができます。これはバイト配列と同じです。ここに私が書いたものがあります:

static int foo(char *userdata) {
  vpiHandle systfref, args_iter, argh;
  struct t_vpi_value argval;
  PLI_BYTE8 *value;

  systfref = vpi_handle(vpiSysTfCall, NULL);
  args_iter = vpi_iterate(vpiArgument, systfref);

  argval.format = vpiStringVal;
  argh = vpi_scan(args_iter);
  vpi_get_value(argh, &argval);
  value = argval.value.str;

  int i;

  for (i = 0; i < 32; i++) {
    vpi_printf("%.2x ", value[i]);
  }
  vpi_printf("\n");

  vpi_free_object(args_iter);
  return 0;
}

ご覧のとおり、このコードは引数を文字列として読み取り、文字列内の各文字 (別名バイト) を出力します。これはほぼ完璧に機能します。ただし、バイト00は常に として読み取られ20ます。たとえば、次のように Verilog reg を割り当てるとします。

 val = 256'h000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f;

を使用して呼び出すと$foo(val)、C 関数はシミュレーション時にこれを出力します。

VPI: 20 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f

これをさまざまな値でテストしたところ、 のどこに何回出現しても、バイト00は常に にマップされることがわかりました。20val

また、値を として読み取り、vpiHexStrVal文字列を出力すると、うまく見えることに注意してください。

だから、2つの質問:

  1. Verilog から 256 ビット値を読み込むより良い方法はありますか?
  2. で何が起こっているの20ですか?これはバグですか?何か不足していますか?

注: シミュレーションには Aldec を使用しています。

4

1 に答える 1

4

vpiStringValC 文字列へのポインターとして値を取得するために、値が ASCII テキストであると予想される場合に使用されます。これは、C 文字列を必要とする C 関数で使用したい場合に便利です。たとえば、 などprintf()%s形式がありますfopen()。ただし、C 文字列には null 文字を含めることはできません (null は C 文字列を終了するために使用されるため)。は x ビットまたは z ビットを表すため、可能なベクトル値を区別する必要がある場合に使用する形式ではありません。使用しているシミュレーターは、ヌル文字をスペース (0x20) としてフォーマットしているようです。他のシミュレーターはそれらをスキップするだけですが、それも役に立ちません。可能なベクトル値を区別するには、vpiVectorVal(最もコンパクトな表現) またはvpiBinStrVal(ビットごとに 1 つの 0/1/x/z 文字を含むバイナリ文字列) を使用します。

于 2010-02-18T03:02:40.960 に答える