MAX10の内蔵Flashを書き換える [FPGA]

MAX10のonchip flashコアはUFMセクタのみを使う場合と、CFMセクタも使う場合ではいろいろと作法が違うのでまとめました。
レジスタマッピングやインスタンスの諸々はMAX10フラッシュメモリユーザーガイドを参照のこと。
 → https://www.altera.co.jp/ja_JP/pdfs/literature/hb/max-10/ug_m10_ufm_j.pdf

■altera_onchip_flashコアの設定

基本的にQsysからAvalon-MMで利用する場合、インターフェースはPallarel、バースト長は2(10M04および08)または4(10M16以上)を選択する。
MAX10の内蔵Flashは5つのセクタからなり、アドレスの若い順にUFM1、UFM0、CFM2、CFM1、CFM0と並んでいる。

・UFM1,UFM0

全てのデバイス、全てのコンフィグレーションモードで利用可能。
UFMのみ初期値をConvert Programing Files→Options/Boot infoのUser Flash Memoryセクションで設定できる。
UFM souceでLoad memory fileを選択して、File pathにHEXまたはMIFを設定する。両方とも0x0000からの絶対アドレスで認識するため、アドレスオフセットは適宜調整しておく(特にHEX)。

・CFM2

FグレードおよびAグレードのデバイスでのみ利用可能。
コンフィグレーションモードがSingle Complessed imageまたはSingle Uncomplessed Imageの場合にはユーザー領域として利用することができる。
Dual Complessed imageの場合にはコンフィグイメージ1の領域として利用される。

・CFM1

FグレードおよびAグレードのデバイスでのみ利用可能。
コンフィグレーションモードがSingle Complessed imageの場合にはユーザー領域として利用することができる。
Dual Complessed imageの場合にはCFM2と共にコンフィグイメージ1の領域として利用される。

・CFM0

FグレードおよびAグレードのデバイスでのみ利用可能。
コンフィグレーションモードがDual Complessed imageの場合に利用可能。
コンフィグイメージ0の領域として利用され、ユーザー領域としての利用はできない。


altera_onchip_flashコアに設定するコンフィグレーションモードと、Quartus側のDevice and Pin Options→Configuration→Configuration schemeの設定は一致していなければならない。
またDual Complessed imageを設定した場合、CFM0にはコンフィグイメージ0、CFM1/2にはコンフィグイメージ1を格納するため、ユーザー用メモリとしては利用できない。
なお、コンフィグレーションモードにDual Complessed imageを選択した場合、そのデザインには必ずaltera_dual_bootコアを含めなければならない。


■セクタの消去とプログラミング

セクタの消去はcsrスレーブへのアクセスで行う。
セクタのプロテクトビットと、セクタイレース、ページイレースのビットが同じコントロールレジスタに存在しているため、プロテクトビット解除→イレース指示の2回のレジスタ操作が必要。
イレース発行後はステータスレジスタで消去の完了を確認する。
以下はCFM2セクタのイレースを行うコード例。

IOWR(FLASH_CSR_BASE, 1, 0xfdffffff); // CFM2のプロテクトを解除
IOWR(FLASH_CSR_BASE, 1, 0xfdbffff); // CFM2のセクタイレースを発行
while((IORD(FLASH_CSR_BASE, 0) & 0x3) != 0x0) {} // セクタ消去終了を待つ

if ( (IORD(FLASH_CSR_BASE, 0) & 0x10) ) { // 消去の可否
 printf("Erase CFM2 success.\n");
} else {
 printf("Erase CFM2 failed.\n");
}


セクタのプログラミングは該当のメモリアドレスへ書き込むことで行う。
書き込み先のセクタは予めコントロールセクタの保護ビットを解除しておく必要がある。イレースと異なり、プログラミングの場合は複数セクタの保護ビットをクリアしておくことが可能。
セクタへの書き込みはAvalon-MMマスタから行う場合は書き込み完了までwaitrequestが発行されるため、ステータスレジスタで待ち時間を取る必要はない。ただし、書き込み時にはシングルアクセスで行う必要があり、NiosII /fコア等でバーストアクセスを持つマスタから書き込む場合には正しくシングルアクセスが行われるよう注意すること。
以下はCFM2、CFM1のプログラミングを行うコード例。

IOWR(FLASH_CSR_BASE, 1, 0xf9ffffff); // CFM2,CFM1のプロテクトを解除

for(i=CFM2_START_ADDR ; i<=CFM1_END_ADDR ; i+=4) {
 confdata = bit_reverse_u32(*rpddata++); // 32bit単位でビットを逆順にする
 IOWR_DIRECT32(FLASH_DATA_BASE, i, confdata); // 書き込み実行
 if ( !(IORD(FLASH_CSR_BASE, 0) & 0x8) ) { // 書き込みの可否
  printf("Write to 0x%x failed.\n", i);
  break;
 }
}

IOWR(FLASH_CSR_BASE, 1, 0xffffffff); // 全セクタプロテクト

CFMにコンフィグレーションデータを書き込む場合、Avalon-MMから見えるビット順とコンフィグレーションストリームとして読み出されるビット順が32bit単位で逆になっているので、RPDファイルを書き込む際にビット順を逆にする必要がある。
ビット逆順の操作はコンフィグレーションデータのみに行う。UFMとして使う場合は読み書き共にAvalon-MMのビット順で行われるため不要。


■Dual Complessed imageデータの作成

Dual Complessed image用のコンフィグデータは自動では作られないので、コンパイル後にConvert Programming Filesで専用のPOFを作成する必要がある。
Programming file typeで.pofを選択した状態で、Mode:プルダウンでInternal Configurationを選択する。
UFMに初期値を設定する場合はOptionsボタンのUser Flash MemoryセクションでHEX/MIFを設定する。

Input files to convertタブにSOF Dataを2つ追加する。
ここで追加できるのは両方ともコンフィグレーションスキームでDual Complessed imageを設定したsofのみ。それ以外のsofは設定できない。また、sofを1つだけ設定することもできない。
片方のイメージだけ利用する場合、両方に同じsofを設定してpofを生成する必要がある。

Quartus Programmer以外の手法でCFMを書き換える場合、Create config data RPDにチェックを入れておく。
RPDファイルを生成した場合、全領域用のfoo_auto.rpd、CFM0(イメージ0)用のfoo_cfm0_auto.rpd、CFM1/2(イメージ1)用のfoo_cfm1_auto.rpd、UFM0/1用のfoo_ufm_auto.rpdの4つのファイルが作られる。

Dual Complessed imageを設定する場合にはもう一つ、CONFIG_SELピンの扱いがある。Device and Pin OptionsのGeneralでEnable CONFIG_SEL pinにチェックを外すと、必ずイメージ0のコンフィグで起動する。この場合イメージ1へはイメージ0のaltera_dual_bootコアでリコンフィグレーションすることになるため、CONFIG_SELピンを使用しない場合はdual_bootコアを操作できるAvalon-MMマスタが存在しなければならない。これがないとイメージ0のデータが破損しない限りイメージ1へのスイッチが行われない。
イメージ1のコンフィグを直接ブートする場合は、イメージ0、1両方のデバイス設定でEnable CONFIG_SEL pinにチェックを入れておかなければならない。


■MAX10のコンフィグレーションについて

MAX10の内蔵Flashはaltera_onchip_flashコアを使って書き換える事ができるが、MAX10のコンフィグレーションスキームを書き換えることはできない。例えばDual complessed imageのPOFを書き込んだ後にCFMにSingle Complessed imageを書き込んでもブートできない。
これはMAX10のコンフィグレーションスキームを格納する領域(ICB)はPOFでしか書き込む事ができないため。
altera_onchip_flashコアで行えるのは、あくまで同一コンフィグレーションスキームのデータ差し替えに限定されることに注意しなければならない。