FIFO Generator はどこへ行ったのか?
Versal FPGA を使う場合、AMD は Verilog や VHDL のインスタンシエーション(instantiation)でそのまま使えるプレーンな FIFO を実装する IP ブロックを提供していません。おなじみの FIFO Generator IP も、これらの FPGA では利用できません。少なくとも Vivado 2022.1 以前ではそうなっています。
したがって、既存の FPGA 設計の FPGA 部分を Versal FPGA に変更する場合、プロジェクトにいくつかの変更が必要になる可能性が高いでしょう。ほとんどすべての FPGA プロジェクトが FIFO Generator を使っていますから。
Memory Generator も同様です。ブロック RAM を作るために使われることのある IP も、Versal FPGA では廃止されました。ただし、この IP はそれほど使われていません。ブロック RAM は多くの場合、推論(inference)によって作られるからです。つまり、RAM を作る目的で Verilog(または VHDL)の配列を宣言するのが普通、ということです。
AXI インターフェイスを持つ FIFO や RAM は、今でも IP として利用できることに注意してください。Versal FPGA でのサポートがなくなったのは、「native」インターフェイスを持つ FIFO とブロック RAM だけです。
この問題を回避する方法はいくつかあります。ここでは、2 つの方法を紹介します。
FIFO 全般のチュートリアルについては、こちらの一連のページを参照してください。
方法 1: AMD Parameterized Macros を使う
AMD Parameterized Macros は、Vivado がサポートするすべての FPGA(すなわち series-7 FPGA 以降)で利用できます。これらのマクロは、Verilog や VHDL の通常のモジュールと同じように、インスタンシエーションの中で使うことができます。ドキュメントは、FPGA のプリミティブ(primitive)とともに提供されています(たとえば、Versal Architecture Premium Series Libraries Guide、UG1485)。
ただし、プリミティブと Parameterized Macros には重要な違いがあります。シンセサイザ(synthesizer)がプリミティブを処理すると、通常は合成後のネットリストに 1 つの論理エレメントしか生成されません。一方、Parameterized Macro は Verilog モジュールと同じように、多数の論理エレメントを生成します。
FIFO を生成する Parameterized Macros はいくつかありますが、特に次の 2 つが代表的です。
- xpm_fifo_sync: 同期 FIFO(シングルクロック)を生成します。
- xpm_fifo_async: 非同期 FIFO(デュアルクロック)を生成します。
これらの 2 つのマクロで生成される FIFO は「native」インターフェイス、つまり wr_en や rd_en のようなポートを備えています。FIFO Generator で利用できたオプションのほとんどは、マクロのインスタンシエーション・パラメータを設定することで有効にできます。たとえば、これらの FIFO は「Standard FIFOs」または First Word Fall Through(FWFT)のどちらかとして実装できます。
RAM を実装するためのマクロもいくつかあります。また、各種の AXI-Stream FIFO もいくつかありますが、これらは Versal FPGA であっても IP ブロックとして作成できます。
これらのマクロの詳細については、Versal FPGA 向けの Libraries Guide、すなわち UG1485 を参照してください。Vivado でインスタンシエーション・テンプレートを取得することもできます。Tools > Language Templates を選択し、Verilog > AMD Parameterized Macros (XPM) > XPM > XPM_FIFO と進み、該当する Synchronous FIFO または Asynchronous FIFO を選択してください。
以下に、このページで紹介したものと同じ動作をする、基本構成の同期 FIFO の作成例を示します。
module fifo_8x2048
#(parameter width = 8, depth = 2048)
(
input clk,
input rst,
input wr_en,
input [(width-1):0] din,
input rd_en,
output [(width-1):0] dout,
output full,
output empty
);
xpm_fifo_sync #(
.DOUT_RESET_VALUE("0"),
.ECC_MODE("no_ecc"),
.FIFO_MEMORY_TYPE("auto"),
.FIFO_READ_LATENCY(1),
.FIFO_WRITE_DEPTH(depth),
.FULL_RESET_VALUE(1),
.READ_DATA_WIDTH(width),
.READ_MODE("std"),
.SIM_ASSERT_CHK(0),
.USE_ADV_FEATURES("0000"),
.WAKEUP_TIME(0),
.WRITE_DATA_WIDTH(width)
)
xpm_fifo_sync_inst (
.almost_empty(),
.almost_full(),
.data_valid(),
.dbiterr(),
.dout(dout),
.empty(empty),
.full(full),
.overflow(),
.prog_empty(),
.prog_full(),
.rd_data_count(),
.rd_rst_busy(),
.sbiterr(),
.underflow(),
.wr_ack(),
.wr_data_count(),
.wr_rst_busy(),
.din(din),
.injectdbiterr(1'b0),
.injectsbiterr(1'b0),
.rd_en(rd_en),
.rst(rst),
.sleep(1'b0),
.wr_clk(clk),
.wr_en(wr_en)
);
endmodule
方法 2: Embedded FIFO Generator を使う
Embedded FIFO Generator は、おなじみの FIFO Generator と実質的に同じものですが、ブロックデザイン内でしか使用できません。
したがって、もっともわかりやすい解決策は、ブロックデザインを作成して Embedded FIFO Generator を追加し、この IP ブロックのパラメータを従来の FIFO Generator とまったく同じように設定することです。その後、FIFO のすべてのポートを外部ポートに接続します。その結果、FIFO と同じポートを持ち、FIFO と同じように動作するブロックデザインができます。つまり、これは FIFO です。
この方法は少しスマートさに欠けます。特に、FIFO のポート名が通常より長くなってしまいます。たとえば、wr_en ではなく FIFO_WRITE_0_wr_en というポート名になります。
まとめ
FIFO Generator が Vivado の IP Catalog から消えてしまったのは突然で説明がつきませんが、この IP を Parameterized Macro やブロックデザインに置き換えるのは、通常それほど難しくありません。
より広い視点で見ると、Versal FPGA への移行を考えているかどうかとは関係なく、FIFO Generator をサポートしている FPGA であっても使うのをやめるのは、長い目で見れば良い考えかもしれません。