7 / 24 · 概念
メモリ要求と応答のタイミング契約
同期読み出し、遅延させたタグ、同一アドレスの衝突を区別します。
レッスンは無料で読めます。受講登録すると進捗を保存できます。
メモリは単なる大きなレジスタ配列ではない
メモリのインターフェースには容量だけでなくタイミングの契約も必要です。非同期読み出しでは、アドレスが変わると組み合わせ出力が変わります。同期読み出しはエッジでアドレスをサンプリングし、その後に出力を変えます。この2つのモデルでは異なるスケジュールが必要です。デバイスのメモリリソースへの推論も、記述方法と対象ツールに依存します。ここでは同期読み出しを備える16個の8ビットエントリを定義します。
エッジkでアドレスとタグをサンプリングします。対応するデータと遅延させたタグはそのエッジ後に現れ、最初に消費できる機会はエッジk+1です。1サイクル読み出しは即時の組み合わせ応答を意味しません。応答validも同じだけ遅らせる必要があります。遅延した値に現在の入力タグを組み合わせると、連続する要求の対応が崩れます。
logic [7:0] mem [0:15];
logic [7:0] rd_data;
logic [3:0] rd_tag;
logic rd_valid;
always_ff @(posedge clk) begin
if (wr_en) mem[wr_addr] <= wr_data;
rd_valid <= req_valid;
if (req_valid) begin
rd_data <= mem[req_addr];
rd_tag <= req_tag;
end
if (rst) rd_valid <= 1'b0;
endこの動作モデルでは、同じアドレスを同時に読み書きすると古い値を返します。ノンブロッキング代入が更新前の状態を読むためです。実際のメモリプリミティブには明示的な衝突モードと制限があります。AMD UG901の読み書きモードを参照し、対象と合成結果で意図したモードを確認してください。validのリセットは配列の初期化ではありません。
| エッジ | 受け入れた要求 | 効果 |
|---|---|---|
| 2 | addr=3,tag=7 | 古いmem[3]=42を取り込む |
| 3 | addr=4,tag=8 | 42,7を消費し、次の値を取り込む |
| 4 | 要求なし | 応答validをクリア |
このスケジュールは消費側がストールしないことを前提にしています。エッジ3でストールすると、次の応答がrd_dataを上書きする可能性があります。応答用の記憶領域を追加するか、すでに処理中の応答も含めて空き容量に基づき要求を制限してください。値を検査する前に、テスト用メモリを明示的に初期化します。応答データだけでなくアドレスとタグの対応も検証してください。値が正しくても別の要求に付いていれば失敗です。
自分で考えてみましょう
mem[3]=42として、同じエッジでアドレス3を読み、そこに99を書き込みます。このモデルでrd_dataに入る値と、更新後のメモリ値は何ですか。出力ストールには何が必要ですか。
解説を見る
rd_dataは42、mem[3]は99になります。両代入は更新前の状態を読みます。ストールには応答用の記憶領域と、処理中の応答を数える受け入れ制御が必要です。実際の対象メモリの衝突モードは別に検証してください。