5

1ビットのシリアルポートからのデータがあり、可変長のバイトの倍数で次のようになります。

byte expected_1 [$] = {8'hBA, 8'hDD, 8'hC0, 8'hDE};
byte expected_2 [$] = {8'h01, 8'h23, 8'h45, 8'h67, 8'h89, 8'hAB, 8'hCD, 8'hEF};  

各正のクロック エッジで、1 ビットが送信されます。何百ものシーケンスをテストベンチする必要があるため (将来的には数千になる可能性があります)、システム Verilog でアサーションを使用してプロセスを自動化したいと考えています。新しい 2012 標準では、キューをプロパティに渡すことができますが、再帰プロパティを介してキューを送信できますか? 階層参照に関するエラーを受け取りました。

これは私がこれまでに持っているものです(@Greg hereの助けを借りて):

default clocking sck @(posedge sck); endclocking : sck  

sequence seq_serial(logic signal, logic [7:0] expected); // check each bit
  byte idx = 7;
  (signal == expected[idx], idx--)[*8];
endsequence : seq_serial

property recurring_queue(bit en, logic data, byte data_e [$])
  int queue_size = data_e.size;
  logic [7:0] expected = data_e.pop_front(); 

  if(queue_size != 0) (
    !en throughout (seq_serial(data, expected) ##1 recurring_queue(en, data, data_e))
  );

endproperty : recurring_queue

`define ez_assert(exp)
   assert property (recurring_queue(en, data, exp))
   else $error("Bad Sequence @ time: %t. Info: %m", $time);

テストベンチでアサーションを呼び出すのは、次のように簡単です。

A1 : `ez_assert(expected_1);

エラーメッセージは次のとおりです。

1) passing hierarchical ref to be used in another hierarchical ref is not supported 
2) Illegal SVA property in RHS of'##' expression 
3) Local variable queue_size referenced in expression before getting initialized

長い可変長シリアル シーケンスをアサートするための他のアイデアを受け入れます。

4

1 に答える 1

1

と同じ戦略を試してくださいseq_serial:

sequence seq_queue_pattern(bit en, logic data, byte expt_queue [$]);
    int qidx = 0;
    ( !en throughout (seq_serial(data,expt_queue[qidx]), qidx++)[*] )
    ##1 (qidx==expt_queue.size);
endsequence : seq_queue_pattern

asrt_expected_1 : assert property ( $fell(en) |-> seq_queue_pattern(en,data,expected_1));
asrt_expected_2 : assert property ( $fell(en) |-> seq_queue_pattern(en,data,expected_2));

en が高い場合、またはseq_serialチェーンが期待どおりに一致しない場合、このアサーションは失敗します。括弧の位置は重要ではありません:

  • enfinalseq_serialが完了してから 1 クロック後は don't care です。
    • ( !en throughout (seq_serial(data,expt_queue[qidx]), qidx++)[*] ) ##1 (qidx==expt_queue.size)
  • enseq_serial最終的な完了または失敗の 1 クロック後に低くなければならず、その後は気にしません
    • !en throughout ( (seq_serial(data,expt_queue[qidx]), qidx++)[*] ##1 (qidx==expt_queue.size) )
  • enfinal が完了してから 1 クロック後にローでなければならseq_serialず、その後は気にしません
    • !en throughout ( (seq_serial(data,expt_queue[qidx]), qidx++)[*] ##1 (qidx==expt_queue.size) ) ##1 (qidx==expt_queue.size)

シーケンスおよびプロパティ内のキューは新しいものであり、まだすべてのシミュレーターで完全にサポートされているわけではありません。この制限を回避するには、パラメータ化されたマクロを使用して、予想されるキュー ストリームごとにシーケンスを作成します。

`define asrt_qpat(en,monitor, expt_queue) \
    sequence seq_queue_pattern__``expt_queue (bit en, logic data); \
        int qidx = 0; \
        (!en throughout (seq_serial(data,expt_queue[qidx]), qidx++)[*]) \
        ##1 (qidx==expt_queue.size); \
    endsequence : seq_queue_pattern__``expt_queue \
    \
    asrt_``expt_queue : assert property( @(posedge clk) \
        $fell(en) |=> seq_queue_pattern__``expt_queue (en,monitor) ) \
    else $error("Bad Sequence @ time: %t. Info: %m", $time);

`asrt_qpat(en,data[0],expected_1)
`asrt_qpat(en,data[1],expected_2)
于 2013-06-17T21:17:15.167 に答える