MAX10のUFMでNiosIIをブートする方法 [FPGA]

1.前準備
NiosII Gen2とUFMとメモリをQsysでインスタンスする。
NiosIIのリセットベクタをUFMに割り当てる。Exceptionベクタは適宜。
IDEでプロジェクトを作成。

2.BSPの設定
LinkerタブでrodataセクションとtextセクションをUFMに割り当てる。
bss、heap、rwdata、stackのセクションはメモリに割り当てる。
bsp_linker.png

Settings→Advanced→hal→linkerでallow_code_at_resetとenable_alt_load_copy_rwdataにチェックを入れる。Exceptionベクタをメモリに置いている場合はさらにenable_alt_load_copy_exceptionにもチェックを入れておく。
bsp_settings.png

GenerateでBSPを生成してプロジェクトをビルドする。

3.elfファイルをHEXファイルに変換
IDEでビルドしたelfファイルをメモリ初期値ファイルに変換する。
NiosII Shellを立ち上げてIDEプロジェクトのフォルダへ移動後、次のようにする。

$ elf2hex --base=<UFM先頭アドレス> --end=<UFM終了アドレス> --input=<elfファイル> --output=boot.hex --width=8

UFMは32kバイトのうち、前半16kバイトと後半16kバイトに分かれているが、POFにパッキングするときはまとめて32kバイトとして扱われる。
正しくBSPが設定されている場合、UFMのリセットベクタ(先頭32バイト)に実効コードへのジャンプ命令が追加されている(HEXファイルの2行目のデータフィールドが0で埋まってなければOK)

ちなみにhexファイル名は自由に付けてOK。
注意するのはその後、UFMの要素はバイト列なので --width=8 の指定を忘れないこと。

4.POFファイルを生成
QuartusIIに戻って、File→Convert Programming Files...を選択。

ファイルタイプはPOFを指定。ModeにはInernal Configrationを指定。出力ファイル名を指定して、Add Filesでsofファイルを追加する。
なお、最初にConfigration deviceがEPCEになってないと、ModeのプルダウンにInternal Configrationが出てこないので注意。
conv_sof2pof.png

全部設定できたら、Options/Boot info...をクリックして次へ

UFM sourceをLoad memory fileに変更して、File pathに先ほど生成したhexファイルを指定する。
conv_option.png

全部設定できたらGenerateボタンでPOFを生成する。

5.書き込み
ProgrammerでPOFファイルをMAX10に書き込む。
UFMのみにチェックをつければ、UFM部分だけを書き換えることができる。
programmer.png

デバイスをリブートすればUFMのコードでNiosIIが実行される。