次のようなプロトコルがあるとします。マスターが に設定req
されるfill
と、スレーブは を介して 4 つの転送を通知しrsp
ます。
このトランザクション全体の SVA シーケンスは次のようになります (スレーブがidle
サイクル間にtrans
サイクルを挿入できると仮定)。
req == fill ##1 (trans [->1]) [*4];
ここで、マスターがリクエストのパイプライン処理を許可されているとします。これはfill
、4trans
サイクルが完了する前に次のサイクルを開始できることを意味します。
上記の SVA シーケンスは役に立ちません。2 番目はfill
4 サイクルと誤って一致trans
し、最後のtrans
「フローティング」のままになるからです。trans
前のサイクルが一致した後にのみ、一致するサイクルを開始する必要がありfill
ます。
シーケンスには、単一の評価では利用できないグローバル情報が必要です。基本的に、別のインスタンスが実行されていることを知る必要があります。これを実装する唯一の方法は、RTL サポート コードを使用することです。
int num_trans_seen;
bit trans_ongoing;
bit trans_done;
bit trans_queued;
always @(posedge clk or negedge rst_n)
if (!rst_n) begin
num_trans_seen;
trans_ongoing <= 0;
trans_done <= 0;
trans_queued <= 0;
end
else begin
if (trans_ongoing)
if (num_trans_seen == 3 && req == trans) begin
trans_done <= 1;
if (req == fill || trans_queued)
trans_queued <= 0;
else
trans_ongoing <= 0;
num_trans_seen == 0;
end
else
if (trans_queued) begin
trans_queued <= 0;
trans_ongoing <= 1;
end
if (trans_done)
trans_done <= 0;
end
上記のコードは、トランザクションの進行中にビットを上げ、aの最後のトランザクションが送信されたときにクロック サイクルtrans_ongoing
でパルスします。(私はそれをテストしていないのですべきだと言いますが、これはポイントではありません。それが機能すると仮定しましょう。)trans_done
trans
fill
このようなものがあると、シーケンスを次のように書き換えることができます。
req == fill ##0 (trans_ongoing ##0 trans_done [->1]) [*0:1]
##1 (trans [->1]) [*4];
これで問題なく動作するはずですが、サポート コードが必要であるという事実に特に感心しているわけではありません。基本的に、トランザクションとは何か、パイプラインがどのように機能するかについてかなりの部分を再説明したため、これには多くの冗長性があります。また、再利用も容易ではありません。をパッケージに入れて、別のsequence
場所にインポートできます。サポート コードは、一部のモジュールに配置して再利用することしかできませんが、シーケンスを格納するパッケージとは異なる論理エンティティです。
ここでの問題は、サポート コードを必要とせずにパイプライン化されたバージョンのシーケンスを記述する方法はないかということです。