MAX10のコンフィグをシリアルUARTで書き換える [FPGA]

MAX10のデュアルコンフィグ機能を使って内蔵フラッシュを書き換えるツールをリリースしました。
 → MAX10 Serial Config Updater

Githubリポジトリ
 → max10_config_updater


・仕掛けの解説

MAX10のCFM0にブートローダとなるQsysモジュールを書き込んでおき、CONFIG_SEL='0' でまずこのイメージがブートされる。
ブートローダのQsysはPERIDOTのコンフィグレーション層(のエミュレーション)とAvalonMMブリッジを内蔵していて、これでQsysのシステムIDやチップユニークIDの読み出し、内蔵フラッシュの読み書き、デュアルブートコアのアクセスなどを行う。
ホストPCからはASモードに設定された(FPGAコンフィグ機能が使えない)PERIDOTの派生ボードとして見えているので、Canarium.jsのavmメソッドで内部アクセスができる。

MAX10の内蔵フラッシュペリフェラルはAvalonMMスレーブとしてメモリアドレスにマップされている。フラッシュ書き込みの待ち時間もAvalonMMのwaitrequestでハード的に行われるので、Canarium.jsからは単にメモリ領域の読み書きを行っているだけで済んでいる。
コンフィグレーションデータは32ビット単位でビット順を入れ替える必要があるものの、こういうのはChromeアプリ側でやってしまえるので、ハードウェア側で特別に対応する必要はない。

欠点としてはデュアルコンフィグをベースとするので、M9Kの初期値が使えない、CONFIG_SELピンがI/Oとして使えない&外部からH/Lを選択できないといけない、CFMをユーザー領域に使えない、などがある。

あと、一番最初のブートローダーを書き込むのにはUSB-Blasterが必要、というのは変わらないので、ここはなんとかしたい。ので、今はブートローダー書き込み済みのボードを販売できるよう準備を進めているところ。
チップ単品売りも考えてはいるけど、これは手間とか管理コストがかかるので、どこかしら代理店になってくれるとこがあれば。

CZPMPLwWYAAA0oW.jpg
Chromebookからも使えます。

MAX10のデュアルコンフィグPOFを自動生成させたい [FPGA]

いまのとこQuartusPrimeは、MAX10のPOFはシングルイメージコンフィグではコンパイルフローで自動で生成されるものの、メモリ初期値付きの圧縮コンフィグとデュアルイメージコンフィグを使う場合はConvert Programming Filesで手作業で変換してやらないといけない。
USB-BlasterとQuartus Programmerでやる分にはSOFを直接流し込めるので、さほど手間ではないのだけれど、Chromeアプリとシリアル経由でコンフィグするPERIDOT Projectでは毎回RPDを生成せねばならず、なかなかに面倒くさい。

なので、MAX10のデュアルイメージコンフィグ用のファイル(POFと書き込み用RPD)を自動で生成するTclを作った。
 → auto_generate_dualboot_rpd.tcl

このtclファイルをプロジェクトフォルダの直下に置き、qsfファイルに以下の一行を追加する。(表示の都合で2行に折り返されてるけどそこは心眼で)

set_global_assignment -name POST_MODULE_SCRIPT_FILE "quartus_sh:auto_generate_dualboot_rpd.tcl"

これでoutput_filesフォルダの下に自動でPOFとRPDが生成される。RPDは4ファイル生成され、各ファイルの内容は以下のとおり。

<project名>_auto.rpd
内蔵フラッシュ全領域のイメージ

<project名>_cfm0_auto.rpd
コンフィグレーション0領域のイメージ

<project名>_cfm1_auto.rpd
コンフィグレーション1領域のイメージ

<project名>_ufm_auto.rpd
ユーザーフラッシュ領域のイメージ

ただしこのTclで生成しているデータではcfm0とcfm1は同一でufmは利用しておらず、実際に使うのはcfm1のRPDだけ。

なお、このtclはMAX10のデュアルイメージコンフィグ専用なので、それ以外のコンフィグモードを使ってるプロジェクトに設定するとエラーで止まると思いまず。

CZGAW93UYAAYyoc.jpg

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コアで行えるのは、あくまで同一コンフィグレーションスキームのデータ差し替えに限定されることに注意しなければならない。


振り返り [雑談]

2015年も押し迫ってきまして、ここで唐突に自分の基板設計遍歴を、年ごとにバックアップでさかのぼれるまで振り返ってみたいと思います。

・2007年「TURQUOISE(ターコイズ)」
2007_pcb.png
当時P板.comがようやくローンチしたぐらいの時期に作ったやつ。
秋月300円カラーグラフィック液晶を駆動するVDP基板。この成果により、ニコニコ技術部で「アルテラマスターP」の通り名を拝命する。
 → sm2999516[ニコニコ動画]

・2008年「AMETHYST(アメジスト)」
2008_pcb.png
P名付けて貰ったのに気分よくして作った秋月300円液晶シリーズ第二弾。
当時はまだスマホの普及もなく、小型モバイルで映像を表示できるものは無かった。なんとかeneloop×2で駆動できないか研究の産物。筐体をどうするか悩みつつそのままに。
やたら動画に凝り出すのもこの時期。当時はSNSもなく、動画でリプ&レスを送り合うような牧歌的な時代だった。
 → sm3806028[ニコニコ動画]

・2009年「プロジェクトABiES(アビエス)」
2009_pcb.png
秋月300円液晶シリーズの最終版。この辺りで身辺にイロイロあり、動画作成欲が激減してしまう。
 → sm11919377[ニコニコ動画]

・2010年「ONYX(オニキス)シリーズ」
2010_pcb.png
DIPスケールFPGAボードのはしり。この後、ONYX→SARDONYX→BLACKONYXまでシリーズが続く。在る意味、現在の方向性を決めたプロジェクト。

・2011年「SARDONYX(サードニクス)」
2011_pcb.png
ONYXボードのアップデート仕様。

・2012年
この年に作成したガーバーデータは無かったので、どうもそれどころではなかったっぽい。

・2013年「PERIDOT(ペリドット)」
2013_pcb.png
ご存じ、現在のメインボード。2013年に独立して事業化すべく右往左往している真っ最中。
購入はPERIDOT CRAFTでどうぞ!
 → PERIDOTボード[PERIDOT CRAFTオンラインショップ]

・2014年「SODALITE(ソーダライト)」
2014_pcb.png
久々に登場のALTERA新製品、MAX10を搭載したプロトタイピング用のボード。
SDRAMも搭載してDIPスケールでブレッドボードにもささる優れもの。最近某出版社からも似たようなボードが出てきてますが、発表はこっちが先。
こちらもPERIDOT CRAFTで取り扱っています!
 → SODALITEボード[PERIDOT CRAFTオンラインショップ]

・2015年「mov(モブ)」
2015_pcb.png
2015年に入って一転、高集積度の基板からDIP品の低集積基板にシフト。もっとも高集積の方はまともなCADで製品化するようになったから、というのが大きな理由ですが。
このMESH GPIOモジュールで動くムービングベースキットもPERIDOT CRAFTで取り扱っています
 → mov基板[PERIDOT CRAFTオンラインショップ]


こうやって振り返って見ると、ずっとPCBEでガリガリ書いてるのであんま進歩してないなー‥‥。と地味に凹みます。
そろそろKiCADあたりに乗り換える頃合いですかねえ。

FM音源のDACインターフェース解析 [IPコア]

ちょっと必要になったので、各方面のご協力のもと各種FM音源のDACインターフェースフォーマットを調べた。
音源チップのレジスタや蘊蓄なんかは多数引っかかるのだけど、やっぱりソフトからもボードからも見えない部分の情報はなかなか出てこない。

まとめたのは、YM2151、YM2608、YMF262、YMF288の4つ。YM2203はフォーマットそのものはYM2151と同じなのだけど、モノチャネルなのでクロックが半分になってる可能性があるのだがよく分からなかった。

DAC出力フォーマット_20151106.pdf
FM音源のDACインターフェース解析の更新(2016-09-26)に続く

system2.jpg