これは、 Partial Reconfiguration、または Dynamic Function eXchange (DFX) と Xilinxの Vivadoに関する4 つのシリーズの最初の投稿です。この投稿の意図は、このトピックの主な概念を説明することです。これにより、 Partial Reconfigurationを使用して FPGA プロジェクトをセットアップするための実際的な手順の概要を説明する次の投稿の準備が整います。
序章
Partial reconfiguration は、 FPGAの一部のパーツを logic に交換し、他のパーツは正常に動作させる技術です。これは、電源投入時に機能をプログラムする最初の bitstream とまったく同じように、 FPGA に bitstreamを供給することで構成されます。ただし、 Partial Reconfiguration 用の bitstream は、 FPGA を停止させません。代わりに、特定の logic elementsで動作し、動作を制御するメモリ セルを更新します。特定の logic blocksの hot replacement です。
Xilinxの FPGAs は、 Virtex-4 (および Series-Vから始まる Intelの FPGAs ) 以降、この機能をサポートしています。
この投稿では、 Partial Reconfiguration の背後にある概念について、実際の技術的な詳細には触れずに説明します。これは、まさにそれを行う次の投稿の準備として行います。すべてがこのトピックのすべてに関連しているため、個々のアクションに分解する前にフレームワーク全体を理解することが重要です。
もう一度説明しますか?
FPGA の機能が Partial Reconfigurationなしでどのように変更されるかから始めましょう。 design hierarchyのどこかに module の instantiation があるとしましょう。たとえば、 Verilogでは次のようになります。
moduleA reconfig_ins
(
.clk(clk),
.this(this_w),
.that(that_w),
[ ... ]
);
または VHDLでは:
reconfig_ins : moduleA
port map(
clk => clk,
this => this_w,
that => that_w,
[ ... ]
);
明らかに、プロジェクトのどこかに moduleA.v または moduleA.vhd と呼ばれる module 、または moduleAと呼ばれる IP があり、 instantiation を (その submodulesとともに) 取り込みます。そのため、プロジェクトの implementation を実行して bitstream ファイルを取得し、それを FPGA にロードします。ここまでは通常の手順です。
しかし、ここで、上記のコードで moduleA の代わりに moduleB を記述し、 logic の implementation を実行して bitstream ファイルを取得するとします。これが機能するには、 designに moduleB.v または moduleB.vhd、または moduleB と呼ばれる IP が必要です。
これで、 reconfig_ins と呼ばれる instance 内にある logic で異なる 2 つの bitstream ファイルができました。これら 2 つの bitstreamsを切り替えるには、 FPGA 全体に目的の bitstreamをロードする必要があります。これにより、 FPGAの操作が中断されます。
Partial Reconfiguration は、この中断なしに、あるバージョンから別のバージョンに変更できるようにする手法です。 FPGA は正常に動作し続けますが、 reconfig_ins の logic は moduleA から moduleBに変更され、その逆も同様です。言うまでもなく、これは designs を 2 台別々に使用した implementation だけでは不可能です。
moduleA と moduleB は Reconfigurable Modules (RM)と呼ばれます。これは、 Partial Reconfigurationによって logic を FPGA に挿入できることを意味します。
動機
Partial Reconfigurationを使用する理由はいくつかあります。
- flash memoryへの書き込みを行わずに、 FPGAの logic の Remote Update を許可します。たとえば、 FPGA が PCIeを介してコンピュータに接続されている場合、 hostのソフトウェアのアップグレードと共に FPGAの logic をアップグレードすることが望ましい場合がよくあります。双方のバージョンが同期していることを確認するには、 FPGAの bitstream をコンピューターに保存し、 PCIe インターフェイスを使用して FPGA をロードするのが自然です (これを実現する簡単な方法については、 このページを参照してください)。
- 大規模な FPGAsの場合、すべての logicが含まれていると、 bitstream のロードに時間がかかりすぎる可能性があります。これは、圧縮された bitstreamsを使用することで解決でき、必要最小限の logic を最初の bitstreamに実装します。このようにして、絶対に必要なニーズを満たすために、 FPGA は迅速に動作を開始します。 logic の残りの部分は、 Partial Reconfigurationを実行する第 2 段階でロードされます。これはしばしば Tandem Configurationと呼ばれます。
- logic resources を異なるタスクに再利用することで FPGA のコストを削減するには、同時に作業する必要はありません。たとえば、 FPGA が複数の image filtersの 1 つを実装している場合、現在使用中の image filter のみが FPGA logicを占有します。別の filter が必要な場合、 filter に割り当てられている FPGA の領域が再ロードされますが、 FPGA の残りの部分は正常に動作し続けます。
- 特定の logic elements から JTAG( FPGAで実行される microprocessor の executable code を含む block RAMs など) を更新するには。これにより、ソフトウェアの迅速な開発サイクルが可能になります。
- FPGAで実行されている design に data probe および/またはデバッグ ツールを挿入します。 Partial Reconfiguration は、ある design implementation から別の FPGA に行き来する問題に特に役立ちます (これは、 clocking、 timing などに関する design の根本的な欠陥を示していますが、それは別の話です)。
部分的な bitstream
FPGA designの使用経験がある場合は、単純なルーチンに慣れている可能性があります。 designの source code (および IPs) を編集し、 implementation toolsを起動して、問題なく動作することを確認します。次に、 bitstream を JTAGを介して FPGA にロードします。または、 bitstreamの image を flash device にロードします。
これは私たち全員が慣れ親しんでいるものであるため、 bitstream を、 FPGA 全体を各 logic element がどのように動作するべきかについての神秘的な情報で満たす大量のデータであると誤解しがちです。実際には、 bitstream は、 FPGA がロードされたときに順次実行される一連のコマンドで構成されています。実際、一般的な bitstream は FPGA 全体に情報をロードしますが、手順の進行を制御するいくつかのコマンドで実行されます。これらのコマンドのより重要な側面は、どの logic elements が各データでロードされるかを決定することです。
bitstream 自体が影響を受ける logic elements を示しているため、一部の logic elementsのみを変更し、他の logic elements をそのまま残す bitstream を作成することができます。それが Partial Reconfigurationの礎です。
そうは言っても、 partial bitstream は、 FPGAに既に搭載されている logic と互換性がある必要があります。間違った logic elementsを上書きするだけの問題ではありません。 初期の bitstream は、部分的な bitstreamと密接に結合されています。特に、初期の bitstream は、部分的な bitstreamによって変更される領域内にある logic と routing resources を使用するためです。部分的な bitstream が初期の bitstreamに対して正しく設定されている場合、この繊細なダンスは見過ごされます。そうでない場合、 FPGA はおそらく、手付かずのまま残されるべき機能を含めて狂ってしまうでしょう。
部分的な bitstreamのロード
FPGA の実行中にプロセスを実行できる限り、 Partial Configuration bitstream から FPGA への配信は、 bitstreamsのロードを許可する任意のインターフェイスで実行できます。これには JTAG インターフェイスが含まれているため、 Partial Configuration 用の .bit ファイルは通常どおり Hardware Manager でロードできます。さらに興味深いのは、専用の Internal Configuration Access Port (ICAP)を使用して、 FPGA自体の logic内から実行できることです。この port は、 bitstream をロードする FPGAの logic fabric 内の部分がプロセス全体で無傷のままでなければならないため、 Partial Reconfigurationにのみ使用できます。
ICAP は、 bitstreamsをロードするための FPGAのサブシステムへの単なるインターフェースであり、 bitstreamのソースについては何も指定しません。したがって、 bitstream データが FPGAに到達する方法、またはその保存場所と方法に制限はありません。 ICAPにフィードする FPGA logic の部分で何らかの形で利用できる必要があります。
たとえば、 Xillybus は、ボードに PCIe または USB 3.x インターフェイスがある場合、 bitstream ファイルをコンピュータから ICAP に送信するための簡単な手段を提供します。
Static logic
Partial Reconfiguration を正しく行うには、反対側の部分を尊重する必要があります。 static logic。これは、 FPGA design で手つかずのままにしておく必要がある部品の総称であり、最初の bitstream がロードされたときから存在します。
この logic は、次の 2 つの側面で静的です。 logic は、 FPGAの最初の起動から中断することなく機能する FPGA design (HDL および IP) のパーツで構成されていることを意味します。同様に重要な 2 番目の側面は、この logic の配置が、静的として割り当てられた logic fabric 内のサイトに限定されることです。これらのサイトでは、それ以降の操作は許可されていません。
実際の designでは、 static logic が変更されないだけでは十分ではありませんが、 FPGA の他の部分が変更されても、 static logic が適切に機能し続けることも重要です。 static logic と logic の間を接続する nets がほぼ確実に存在するため、すべてがスムーズに実行されるようにするのは FPGA designerの責任です。このシリーズの3 番目の投稿では、これについて説明します。
static logic と reconfigurable logicの分離
Partial Reconfiguration を実現するには、 static logic と reconfigurable logicを厳密に分離する必要があります。特に、 FPGA に bitstreamがロードされているため、 static logic を含むサイトが影響を受けないように、 FPGA 上の物理 logic elements を分離する必要があります。
これが何を必要としているのかを理解するために、まず私たちが慣れ親しんでいるものを見てみましょう。
通常の FPGA implementation プロセスは、 HDL designの synthesis で開始されることを思い出してください。 HDL の modules の instantiation は、それらの間の分離を意味しないことに注意してください。反対のことが当てはまります。 synthesizer は instantiations を、 logic がどのように動作するかの説明として扱います。したがって、 synthesizer は、 design 全体を logicの 1 つの大きくて平らな部分と見なすことができます。 modules の境界を超える最適化は、許可されるだけでなく、望ましく、頻繁に発生します。たとえば、 module X 内の register が module Y内のまったく無関係な register と同等である場合、 registers の 1 つが削除され、残りの 1 つが両方の modules で使用されます ( synthesizer がそれを控えるように特に指示されない限り)。
HDL の synthesis が完成すると、 synthesized netlist は designの IPs (存在する場合) の IPs と混合されます。
次に、この logic elements の大きな塊を FPGAの logic fabric全体に配置し、 timing constraints およびその他の目標を達成する方法でワイヤを配線します。 design の異なる部分に属する Logic は、同じ sliceにパックすることも、 FPGAの反対側の部分にパックすることもできます。 design のわずかな変更でも、配置が劇的に異なる可能性があります。各 implementation は独立しており、 logic が FPGAの logic fabricにどのように分散されているかは誰が気にするので、これは無秩序ですが無害です。
Partial Reconfigurationに戻る: 前述のように、この機能を実現するには、 static logic と reconfigurable logicを明確に区別する必要があります。これを確実にするために、 Hierarchical Design と呼ばれる技術が使用されます。 PCBの物理的なコンポーネントのように、 design 全体をコンポーネントの集合として見るという考え方です。これの 1 つの側面は、各コンポーネント (つまり、 instantiated module) が logic fabric上の特定の領域に割り当てられていることです。また、各コンポーネントを分離する必要があるため、コンポーネントを個別に作成するのと同じように、個別に synthesis を実行することは明らかに理にかなっています。
では、この概念を Partial Reconfigurationと結び付けてみましょう。これは、 designとの作業における 2 つの主な違いに要約されます。
- Floorplanning: FPGA designer は、 reconfigurable logic用に FPGA fabric の物理領域を明示的に割り当てる必要があります。これは reconfigurable partitionと呼ばれます。残りは static logicで構成されます。
- Synthesis: reconfigurable logic の synthesis (およびおそらく関連する IPs も) は、 static logicとは別に行われます。その結果、 reconfigurable logic と static logicには独立した netlists があります。
Pblocks
floorplanning unit に対するVivadoの用語は Pblockであり、これは Vivado内の情報の単なるプレースホルダーです。 Pblockを作成し、それに logic cells を追加し、 FPGA logic sitesのグループ (sets) を追加する Tcl 関数があります。 Vivado はこれを、 Pblock に追加された logic cells が割り当てられた sites にのみ配置される必要がある placement constraint として解釈します。結局のところ、 Pblocks は XDC ファイル内の他の constraints と同じです。
Pblocks は、多くの場合、 synthesized design または implemented designを開いて FPGAのグラフィカル表現に長方形の領域を描画することにより、 Vivadoの GUI を使用して定義されます。これにより、描画された長方形にすべての logic elements を含む Pblock が作成されます。より正確には、すべてのタイプの logic elements が含まれているわけではなく、 floorplanning (その FPGA ファミリ) に許可されているものだけが含まれています。したがって、 Vivado は四角形を logic elementsの範囲に変換します。
XDC ファイルを編集してこれらの範囲を手動で設定しても問題ありません。また、複数の長方形で構成される領域を作成することもできるため、形状は 1 つの長方形よりも複雑になる可能性があります。ただし、 Xilinxのドキュメント (UG909) では、 routingでの問題を回避するために形状を単純に保つことを提案しています。
これは、 Kintex-7用の XDC ファイルの例です。
create_pblock pblock_pr_block_ins add_cells_to_pblock [get_pblocks pblock_pr_block_ins] [get_cells -quiet [list pr_block_ins]] resize_pblock [get_pblocks pblock_pr_block_ins] -add {SLICE_X118Y0:SLICE_X153Y99 SLICE_X118Y250:SLICE_X145Y349 SLICE_X0Y0:SLICE_X117Y349} resize_pblock [get_pblocks pblock_pr_block_ins] -add {DSP48_X5Y100:DSP48_X5Y139 DSP48_X5Y0:DSP48_X5Y39 DSP48_X0Y0:DSP48_X4Y139} resize_pblock [get_pblocks pblock_pr_block_ins] -add {RAMB18_X4Y0:RAMB18_X6Y39 RAMB18_X4Y100:RAMB18_X5Y139 RAMB18_X0Y0:RAMB18_X3Y139} resize_pblock [get_pblocks pblock_pr_block_ins] -add {RAMB36_X4Y0:RAMB36_X6Y19 RAMB36_X4Y50:RAMB36_X5Y69 RAMB36_X0Y0:RAMB36_X3Y69}
下の画像は、 implemented designでどのように見えるかを示しています。 reconfigurable partition ( pblock_pr_block_insという名前で、この例では logic がほとんど含まれていません) は紫色で描かれています。その形状は、3 つの長方形 (上記の各 resize_pblock コマンドにリストされている 3 つの範囲) の union として作成されます。
この図では、すべての placed logic がシアンで描かれています。 logic の大部分は static regionに属しており、狭い範囲に閉じ込められていることは明らかです。
constraintsによって制限されるのは、 slices、 RAMs 、および DSP48 だけであることに注意してください。これらは、 Partial Reconfiguration が series-7 FPGAsで制御できる唯一のタイプの logic です。実際には「純粋な logic」以外のすべてのものは、 static designに属している必要があります。
Ultrascale FPGAs 以降では、ほぼすべての logic を Partial Reconfigurationでリロードできます。
Pblocksには追加の制限がありますが、ここで UG909 の第 6 章から第 8 章を繰り返しても意味がありません。
とにかく、何があっても implemented designを開いて、 FPGAのビューをズームインおよびズームアウトし、 logic elements が FPGAでどのように構成されているかを確認することをお勧めします。特に、同じタイプの logic の列があることに注意してください。列の中央にいくつかの logic elements があり、均一性が損なわれる場合があります (特に、 ICAP ブロック、 PCIe ブロックなどの特別な logic elements)。
Pblocks のトピックは Partial Reconfigurationに固有のものではないことに注意してください。たとえば、このセクションで説明されていることはすべて、 hierarchical designに Pblocks を使用する場合にも当てはまります。
floorplanningの詳細
そして、直感に反する事実がいくつかあります。 floorplanning のグラフィック表現は、 FPGAのマップ上に描かれた形状で構成されていますが、 placement constraintsによって制御される logic のタイプにのみ適用されます。したがって、 FPGA のほとんどすべての slices が Partial Reconfigurationに割り当てられている場合、これらの slices によって完全に囲まれている他の logic elements の島は、 static logicに属する可能性が非常に高くなります。たとえば、 ICAP ブロック自体が Partial Reconfigurationに割り当てられた長方形の中央にある場合は、まったく問題ありません。
Partial Reconfiguration bitstream が特定の logic elements に向けられ、他の logic elements は無傷のままであることを考えると、これはそれほど奇妙なことではありません。しかし、 routingはどうでしょうか。 ICAP ブロックが reconfigurable logicの途中で詰まっている場合、 static logicの slices への配線はどのように行われますか?
これは、直観に反する第 2 の事実につながります。 static design の routing は、 reconfigurable region内のリソースを使用します。この routing は、 Partial Reconfiguration プロセス全体で安定したままです。そうでなければ、 static logicにはなりません。したがって、 reconfigurable regionの内部では、 reconfigurable logic の routing が変更されますが、 static logic の routing は変更されません。このトピック全体について魔法のように感じられることがあるとすれば、それはこの小さな事実です。また、 static logic と互換性のない partial bitstream を使用すると、 FPGA が完全に混乱する可能性がある理由でもあります。
もちろん、逆は当てはまりません。 reconfigurable logic は、上記の XDC の例のように明示的にリストされているものを除いて、リソースを使用しません。 routing リソースに関しては、 Partial Reconfiguration bitstream がロードされている間、 static region の何も変更されないため、その意味で、 reconfigurable logic が static regionに影響を与えることはありません。まあ、それはほとんど真実です: reconfigurable region の形状が単純な長方形でない場合、 Vivado は routing を reconfigurable regionの外に出すことができます。これは、 routingを改善する目的で、 Ultrascale FPGAsでのみ発生します。
この時点で明らかなことは、 floorplanning を描画するためのルールは単純ではないということです。良いニュースは、 Vivado が floorplanningのルール違反に対応して、かなり有益な Critical Warnings を生成することです。したがって、試行錯誤によって適切な floorplan を見つけることが合理的な方法です。
Parent implementations および Child implementations
reconfigurable logicの implementation に関しては、 FPGA 内のすべての path が timing constraintsを達成する必要があり、 reconfigurable logic がロードされる前と後にそれが真でなければならないことに留意することが重要です。したがって、 static logicとは別の reconfigurable logicの implementation は不可能です。むしろ、 implementation は常に各 reconfigurable moduleの FPGA 全体で実行されます。 timing constraints (および他の constraints) は、各 implementationに適用されます。
この点を明確にするために、上記の moduleA と moduleB の例に戻りましょう。この例では、 Vivado は moduleA を含む完全な design の implementation を実行し、次に moduleBで同じことを実行します。副産物として、これら 2 つのオプションのそれぞれに通常の bitstream ファイルがあります。
強調する価値があります: すべての implementations は、完全な initial bitstream と partial bitstreamを生成します。これは、 Parent であろうと Childであろうと、すべての implementations に当てはまります。したがって、 FPGA の電源を入れると、これらの initial bitstreamsのいずれかをロードできます。
moduleA から Partial Reconfigurationを使用して moduleB に移行できるようにするには、 static partition のすべてがまったく同じでなければなりません。これには、 logic 自体、 placement および routingが含まれます。これを実現するために、 Vivado は Parent Implementationとして 1 つのシナリオ (たとえば moduleAを使用) で implementation を実行します。次に、他のすべてのシナリオで Child Implementations を実行します (たとえば、 moduleBを使用)。これがどのように正確に行われるかは、このシリーズの最後の投稿で詳しく説明されていますが、簡単に言うと:
Vivado は、 Hierarchical Designの場合と同様に、 moduleA 用の Parent Implementation を実行することから始まります。これは、 static logic と reconfigurable logic の synthesis が別々に行われ、 floorplanning constraints が placements を FPGA上の別々のサイトに強制することを意味します。これら 2 つの違い以外は、通常の implementation が実行されます。特に、 placement と routing は、この特定のシナリオで最適な結果を得るために実行されます ( floorplanning constraints と別の synthesis を使用すると、最適なパフォーマンスが得られない場合があります)。
次のステップは、 moduleBに対して Child Implementation を実行することです。これは Parent Implementationに代わって既に行われているため、 static designの synthesis は必要ありません。したがって、 synthesis は reconfigurable logicでのみ実行されます。
implementation は、 Parent Implementationと同じ方法で実行されますが、1 つの重要な違いがあります。 すべての static logic の place and route は、 Parent Implementationの結果と同じになるように強制されます。この制限があるため、最適な結果を得るために reconfigurable logic の place and route を実行します。
したがって、 Parent と Child の関係の鍵は、 Child Implementation が Parent Implementation が終了したところから始まり、 reconfigurable logic を独自の logicに置き換えることです。 Child Implementation は通常どおり続行しますが、 static logicの領域には何も触れません。
すべての Child Implementations は、 static logicの placements および routesに適応する必要があるため、 designの通常の implementation と比較して、 timing constraintsを実現するのは難しいかもしれません。実際には、次の 2 つの障害があります。
- design が static logic と reconfigurable logic に階層的に分離されているため、それらの境界を越えた最適化が妨げられています。
- static logicの place and route が reconfigurable logicに最適であるとは限りません。
Parent Implementationに選択する reconfigurable modules を選択する際には、この点に留意する必要があります。たとえば、 timing constraints を実現するのが最も難しいのは module かもしれません。または、 static logicと接続する方法で他の modules を表す module 。または、その逆: static logicの中立的な implementation を実現するために、事実上 logic をまったく含まない reconfigurable module (「grey box」)。
bitstreamsの使用に関しては、 Partial Reconfiguration を使用するプロジェクトの implementation に対する Vivadoのパラダイムは、すべての bitstreams が最新で相互に互換性がある場合に implementation が終了することです。つまり、 implementationsの initial bitstreams のいずれも、最初に FPGA をロードするために使用できます。この後、 implementationsの partial bitstreams のいずれかをロードできます。
したがって、最初の「Generate Bitstream」は Parent Implementation とすべての Child Implementationsを開始します。以降の compilations では、 Vivado は通常どおり、更新が必要な runs のみを実行します。
Dynamic Function eXchange Wizard
Tools メニューから開始できるこの Wizardの目的は、 Parent Implementation と Child Implementations、特にどの Implementation にどの reconfigurable moduleが含まれるかを定義することです。
この Wizard を説明するのは、 Child Implementationを追加するときに作成される Tcl コマンドを見ると最も簡単です。
create_reconfig_module -name bpf -partition_def [get_partition_defs pr ]
add_files -norecurse /path/to/pr_block1.v -of_objects [get_reconfig_modules bpf]
create_pr_configuration -name config_2 -partitions [list pr_block_ins:bpf ]
create_run child_0_impl_1 -parent_run impl_1 -pr_config config_2 -flow {Vivado Implementation 2020}
この Tcl シーケンスを、最後の行から最初の行まで逆方向に見ていきます。
したがって、最後の行で Child Implementation run が作成されます。新しい run には「child_0_impl_1」という名前が付けられ、その parent run は「impl_1」に選ばれました。重要なことに、この新しい run の configuration は「config_2」に設定されています。
「config_2」は 3 行目に定義されており、「bpf」は「pr_block_ins」という名前の reconfigurable partition を対象とした reconfigurable module です。以上、「pr_block_ins」について触れてきましたが、「bpf」とは?
最初の行では、 reconfig_module が作成され、「bpf」という名前が付けられます。これは、 logic の機能を伝えるのに便利な任意の名前です。 2 行目は、特定の Verilog ファイルがこの reconfigurable moduleに追加されていることを示しています。
全体として、これら 4 つの行は新しい Child Implementationを作成し、 reconfigurable moduleを作成するには特定の Verilog ファイルの synthesis が必要であることを示します。また、 Tcl environment の 2 つの objects 、「bpf」と「config_2」が作成されます。
Dynamic Function eXchange Wizardに戻ります。 design sources、 reconfigurable modules、 configurations 、 implementation runsの関係を表す GUI ツールです。上記のような Tcl コマンドを生成するための情報を伝達するための便利な方法です。
このツールは非常に複雑に見えるかもしれませんが、それは例が単純だからです。現実的な designでは、 reconfig_module に複数の source filesが割り当てられ、おそらく IPs が割り当てられている可能性があります。したがって、 GUI は物事をより簡単にします。
しかし、なぜ configuration ("config_2") が必要なのでしょうか? create_run コマンドで「bpf」と「pr_block_ins」を接続しないのはなぜですか?繰り返しますが、これは正当な質問です。この投稿は 1 つの reconfigurable partitionのみに制限されているためです。そのような partitionsが複数ある場合、 configuration は、どの partition がどの reconfigurable moduleを取得するかを定義するため、 config_*のように、そのような組み合わせごとに名前を付けるのが理にかなっています。
複数の partitionsがある場合、 reconfigurable modulesの可能な組み合わせごとに implementation を作成する必要がありますか?この質問は、この一連の投稿には関係ないので、次のセクションに進んでください。
Vivadoの implementation は、 design全体、つまり static logic と reconfigurable logic を合わせたものであり、全体として timing constraints を満たすようになっていることを思い出してください。したがって、複数の partitionsがある場合、 Partial Reconfiguration を使用する安全な方法は、すべての partitions を partial bitstreamsでロードして、すべての partial bitstreams が同じ implementation runの結果になるようにすることです。つまり、すべての partial bitstreams は同じ configuration (例: "config_2") で作成されているため、これらの partial bitstreams の組み合わせは、ツールによって検証された implementation の結果です。特に、この implementation は timing constraintsを達成することが知られています。
それでも、 reconfigurable modules に相互の相互作用がない場合 (つまり、 reconfigurable modules のすべての top-level ports が static logicに接続されており、相互に接続されていない場合)、各 partition を個別に扱うと何が問題になるのかわかりません。実際、 Vivado は、異なる runs の partial bitstreams が混在して使用される場合、 FPGA 全体の timing を明示的に承認していません。しかし、 static logic を搭載したすべての paths は timing constraintsを達成しており、 static logic はすべての implementation runsでまったく同じであるため、それで十分ではないでしょうか?公式ドキュメントは、この問題に関する情報を提供していないようです。
Routing および Partition Pins
パズルにはまだ 1 つのピースが欠けています。 static logic と reconfigurable logicを接続する routing 。 Parent Implementation は、関連する configurationに含まれる reconfigurable logic に最適な方法で design の place and route を実行することを思い出してください。ただし、 childの reconfigurable module は同じ reconfigurable partitionに適合し、 static designに接続する必要があります。 routing の少なくとも一部は static logicに属しているため、変更できません。
ここで Partition Pins の出番です。概念的には、 reconfigurable logic を物理コンポーネントと考え、 partition pins を PCBに接続された金属ピンと考えることができます。
ただし、実際には、 partition pins は、 routingの FPGAのリソースの座標系内の位置にすぎません。それらは、 static logicの routing が終了し、 reconfigurable logicの routing が続く場所です。それらの唯一の重要性は、 Parent Implementation と Child Implementations がどこにあるかについて合意することです。
これらのアンカー ポイントを確立するために LUTs や flip-flops などの物理リソースは必要なく、追加の routing delayを提供しません。もちろん、 partition pins に出入りする routing のセグメントは delayを作成しますが、 partition pins 自体は delayを追加しません。
partition pins の位置は、 Parent implementation が実行されている間、ツールによって自動的に選択され、 Child implementations は自動的に適応させられます。つまり、 static logic と reconfigurable logic の間の routing は、 Parent Implementation がそうすると言ったところから始まり、 Child Implementation は reconfigurable partitionの中でしかベストを尽くすことができません。一部の partition pins が Childの reconfigurable logicにとって好ましくない位置に配置されていることが判明する可能性があり、 timing constraintsの実現が困難になる可能性があります。
Partition pins は、多くの場合、 reconfigurable partitionの周囲に近い場所でグループ化されます。 Vivado は、特定の designに特化しすぎていないサイトを選択するように設計されているようです。
ただし、 partition pins は、 Parent Implementationの間に timing constraints を達成するために必要であった場合、 reconfigurable partition内のどこにでも見つけることができます。 static design は、 reconfigurable partition内にある routing のリソースを使用できることを思い出してください。したがって、 static routingのセグメントの一部が reconfigurable partitionに入っても問題はありません。
timing constraints および partition pinsの問題を回避するには、 reconfigurable module の output ports が registersであり、 inputs が registers によってもサンプリングされる場合に有益です。同様に、 static logic も同様に registers を適用した方がよいでしょう。実際、 designが複雑にならない限り、可能な限りこの規則に従うことをお勧めします。
Greybox
DFX Wizard に関するもう 1 つの点は、 greyboxです。 Edit Configuration ウィンドウでは、通常の reconfigurable modulesの代わりに、 greybox を reconfigurable moduleとして割り当てることができます。 greybox は、 Vivadoによって生成された偽の module です。本物の reconfigurable moduleの ports に適合しますが、本物の logicの代わりに、 port pinごとに 1 つの LUT があります。 inputs 用に生成された LUTs は、もう一方の端では何も接続されておらず、 outputs 用の LUTs はゼロ値を生成します。 vector portsの場合、 vectorの bit ごとに LUT が作成されます。
place and route プロセスが簡単になりすぎるため、 Parent Implementationで greybox を使用することはお勧めできません。 reconfigurable modules が互いに非常に異なっていたとしても、ツールにある程度挑戦する単純な module を作成する方がよいでしょう。
ただし、最小限の logicで initial bitstream ファイルを作成するには、 greybox modules のみを含む child implementation が役立つ場合があります。すべての implementations が完全な bitstreamsを生成することを思い出してください。これらはすべて、まったく同じ static logicを持っているため、すべて initial bitstreamとして使用できます。
Clearing Bitstreams (Ultrascale のみ)
これは Ultrascale FPGAs のみに関連します ( Ultrascale+には関連しません)。
前述のように、すべての implementations は 2 つの bitstreamsを作成します。 design全体に対して 1 つの bitstream 。関連する reconfigurable module を含む FPGA を最初にロードするために使用できます。 2 番目の bitstream は、同じ reconfigurable moduleを持つ Partial Reconfiguration 用です。
Ultrascale デバイスでは、各 implementationで作成される 3 番目の bitstream、「clearing bitstream」があります。この bitstream は、 partial bitstreamの前に FPGA に送信する必要があります。 FPGA に送信される clearing bitstream は、ロードしようとしている bitstream ではなく、現在 FPGA内にある logic と一致する必要があることに注意してください。したがって、 FPGAの現在の状況を追跡する必要がありますが、これは他の FPGA ファミリでは必要ありません。
clearing bitstream をロードすると、 logicは実際には変更されませんが、 reconfigurable moduleはシャットダウンします。この module の output ports は、新しい partial bitstream がロードされて開始されるまで、任意の値を示すことがあります。
UG909によると、間違った reconfigurable module (つまり、既に FPGAにある logic と一致する clearing bitstream ではない) の clearing bitstream をロードすると、 static logic も混乱し、 reconfiguration メカニズムの誤動作を引き起こす可能性があります。
Xilinxのドキュメントは、最初に clearing bitstream をロードせずに partial bitstream をロードした場合に何が起こるかについて曖昧なようです。 UG909 の第 9 章では、最初に次のように述べています。 「Prior to loading in a partial bitstream for a new Reconfigurable Module, the existing Reconfigurable Module must be cleared」。したがって、結論として、 clearing bitstream は必須です。
しかし、数行下の同じガイドには「If a clearing bit file is not loaded, initialization routines (GSR) have no effect」と書かれています。これは、すべての synchronous elements (原則としてRAMs と flip-flops) が不明な状態で起動しても問題ない場合、 clearing bitstream をまったく使用しなくても問題ないことを意味します。 clearing bitstream をスキップした私自身の逸話的な実験では、問題は見られませんでしたが、それは何の証明にもなりませんでした。
したがって、 Ultrascale FPGAsでは、 FPGAにロードされているものを追跡する必要があります。これは、たとえば、 reconfigurable moduleごとに異なる定数値 ( ID code) を持つ reconfigurable moduleに output port を追加することによって実行できます。これにより、 static logic はどの reconfigurable module が現在ロードされているかを識別できます。いずれにせよ、このような ID code は良いアイデアです。
Plugin と Remote Update の使用例
Vivado が採用したこの parent-child 方法論は、特定のユース ケース ( plugin usageと呼ぶことにします) 向けに設計されているようです。 FPGA 内に可能なすべての機能を常に搭載するのではなく、現在必要な reconfigurable module をロードすることによって、 FPGAのコストを削減します。たとえば、 FPGA を使用して複数の image filtersを実装する場合、 Partial Reconfiguration を使用すると、各 filter を reconfigurable moduleとして実装し、必要な filter だけで FPGA をリロードできます。
Xilinx は、 Partial Configurationに対して「Dynamic Function eXchange」(DFX) という用語を使用しており、この手法の主な使用目的を反映しているようです。
これが Partial Reconfigurationの目的である場合、 parent-child メソッドはうまく機能します。 bitstream files の完全なキットが生成されます。 initial bitstreams のいずれかを使用して FPGAを初期化でき、すべての reconfigurable bitstreams を後で Partial Reconfigurationに使用できます。プロジェクトの新しいバージョンがリリースされると、すべての bitfilesで構成されるキット全体が置き換えられます。
しかし、 Remote Updateと呼ぶ別の使用パターンがあります。おそらく遠い将来、 Partial Reconfiguration がバージョン アップグレードの手段として使用されるときです。この使用シナリオでは、 initial bitstream はある時点でリリースされ、後で変更することはできません。その後、 partial bitstreams がリリースされましたが、これらは initial bitstreamと互換性がある必要があります。これらの新しいリリースは、数年間続く可能性があります。
Remote Updateの場合、 parent-child の方法をそのまま使用するのは難しい場合があります。 Child Implementation を実行して、 parentの Implementation を繰り返さずに新しい partial bitstream を取得することは可能ですが、これを長時間実行するのは困難な場合があります。たとえば、 static logic の source code を誤って変更すると、 parentの designが無効になり、 Parent Implementationが繰り返されます。その結果、新しい static logic は以前の static logic と互換性がなくなり、それをベースにした partial bitstream は元の initial bitstreamでは使用できません。
そのため、 Partial Reconfiguration が FPGA design を継続的に更新する方法として意図されている場合、 implementation 手順には何らかの操作が必要です。このトピックについては、このシリーズの最後の投稿で説明しています。
bitstreamsの圧縮
これは Partial Reconfigurationとは直接関係ありませんが、特に FPGAの迅速な起動を確実にするために、小さな initial bitstream ファイルが必要な場合があります。このコンテキストでは、 Partial Reconfiguration は、クイック スタート後にブリングアップ プロセスを完了するための手段になります。これは、同じデータソース (例 SPI flash) または完全に異なるもの (例 PCIe インターフェイス) から実行できます。
bitstream の圧縮は、 initial bitstream と partial bitstreamsの両方で許可されています。
これは、圧縮された bitstreamを要求するために XDC ファイルに追加する行です。
set_property bitstream.general.compress true [current_design]
これで理論的な部分は終わりです。次の投稿では、 Partial Reconfigurationを使用するようにプロジェクトを構成するための実際的な手順を示します。