NES on FPGA 2024/08/09

NES on FPGA feat. TangNano series

Gowin社 のFPGAを搭載した Sipeed社 の Tang Nano シリーズに NES on FPGA を移植したメモ。

目標は、基本的な『スーパーマリオブラザーズ』から、 ROMサイズの大きい『星のカービィ』『沙羅曼蛇』も動かしたい。

そしてNESの次は…!

Tang Nano シリーズ

Sipeed から販売されている Gowin のFPGAを使用したボードたち。 なお Tang Nano 1K についてはLUT数が少なくNES入らないので割愛。

今回はWindows 10 22H2 にて、Gowin EDA FPGA Designer ver. 1.9.9 (64-bit) を使用。

NES on FPGA 見積もり

Gowin EDA での合成結果では、約3,600LUTsとなった。 また必要なBlockSRAMは、WorkRAMが2kByteとVRAMが2kByteに加え+αでラインバッファ等がある。 ソフトはPRG-ROM(プログラム)とCHR-ROM(キャラクタ)からなり、 これをどうやってメモリに配置するか、 そしてCPUからのPRG-ROMアクセスと、PPUからのCHR-ROMアクセスをどう捌くかが実装のカギとなる。 ちなみに、PRG-ROMアクセスは約560ns間隔で、CHR-ROMアクセスは約372ns間隔で発生するので、 メモリアクセスはこの時間の間に収めなければならない。

NES on FPGA feat. TangNano4K

価格約2,000円
デバイスLittleBee GW1NSR-LV4CQN48PC6/I5 (55nm LP embedded flash)
リソース4,608 LUTs、BlockSRAM 約22kByte
メモリHyperRAM 8MByte
参考 Sipeed wiki Tang Nano 4K

NES on FPGA feat. TangNano4K

使用率93%でMapper 0のみ実装して、マリオやレッキングクルーをUSB-JTAG経由で送信して動かせました。4KでNESは誰もやってなかったので移植してみたけど、LED1個でデバグつら。 pic.twitter.com/2aKNpUjpHM

— かんな丸⁧!!⁨ (@pgate1) 2024年1月4日

メモリマッピング

PRG-ROMとCHR-ROMをHyperRAMに共存させようとしても、 HyperRAMのリードアクセス時間が長いため不可。 このため、PRG-ROMのみHyperRAMに配置し、CHR-ROMは8kByteのBlockSRAMを使用する。 よって動かせるソフトはCHR-ROM(もしくはCHR-RAM)が8kByteまでのものに限られる。

BlockSRAM推論

要件としては、1クロックでWriteできることと、 Readした次のクロックおよび永続的にデータを参照できること。 SFL+の記述は従来通りで変更はなく、ここから生成される VerilogHDLでSDPB(Semi Dual Port Block SRAM)に推論される。
ram_8x8k.sflp
circuit ram_8x8k
{
	input adrs<13>, din<8>;
	instrin write(adrs, din);
	instrin read(adrs);
	output dout<8>;

	mem ram[8192]<8>;

	reg dout_reg<8>; // 出力レジスタ使用
	if(write) ram[adrs] := din;
	if(read) dout_reg := ram[adrs];
	dout = dout_reg;
}

HyperRAM

Gowin EDAのHyperRAM_Memory_Interface IPを 49.95 MHz で最短のバースト長16で試したところ、 リードアクセス時間は 686 ns となり、遅すぎてPRG-ROMアクセスが間に合わない。 そこで、バースト無しメモリアクセスコントローラを使用すべく、 以下のPSRAM用コントローラを少し書き換えて使用させて頂いた。

参考: psram-tang-nano-9k

これならリードアクセスが 282 ns で間に合う。 ちなみにGowinのIPは 643 LUTs、今回のコントローラは 118 LUTs で済むのも嬉しい。

最初、HyperRAMが動かなくて困っていたけど、 サンプル通りのポート宣言に修正したらポートが正常に割り当てられて動いた。

NES_top.v
    // OK こちらで動作した
    output wire [0:0] O_hpram_ck,
    output wire [0:0] O_hpram_ck_n,
    output wire [0:0] O_hpram_cs_n,
    output wire [0:0] O_hpram_reset_n,
    inout  wire [7:0] IO_hpram_dq,
    inout  wire [0:0] IO_hpram_rwds
    /*
    // NG ピンが正常に割り当てられない
    output wire O_hpram_ck,
    output wire O_hpram_ck_n,
    output wire O_hpram_cs_n,
    output wire O_hpram_reset_n,
    inout  wire [7:0] IO_hpram_dq,
    inout  wire IO_hpram_rwds
    */

USB-JTAG UART

ソフトROMをFPGA内メモリに配置するには、仮想COMポートを使用したUSB-UARTが楽だが、 残念ながらTangNano4KではUSB-UARTのピンがFPGAに接続されていない。 そこで、USB-JTAG経由でのUARTを使用する。 USB-JTAG UARTには以下を参考にデータ受信UARTモジュールを作成した。

参考: Tang-Nano-4Kとパソコンとの、JTAG経由の直接通信

UARTにはJTAGピンをユーザピンとして使用している。 このため、FPGAデータを書き込むと Gowin Programmer からは見えなくなるが、 電源を入れなおせば再度FPGA内にデフォルトデータが書き込まれるので問題ない。 ただしデバグの度にUSB電源とHDMIケーブルを抜き差しするのが非常に面倒だった。

注意点として、FPGAデータは SRAM Program を使用すること。 Flash Program で書き込んでしまうと電源を入れなおしてもそれがFPGAに書き込まれてしまうため Gowin Programmer から認識されなくなってしまう。 対処法としては、JTAGSEL(ピン8)をGNDに接続した状態で、JTAGピンをユーザIOとして使用していないデザインを書き込むといいらしい。

PCからはFTDIドライバを使用してFT_Writeでデータを送信する。 データ送信が速いとHyperRAMへのWiteが間に合わなかったので、1バイトずつFT_Writeしている。 最大65535Byteまで送信できるので、マリオの約40kByteは問題なし。

ftdi_send.cpp
	// ポートオープン
	FT_HANDLE ftHandle;
	FT_OpenEx((PVOID)"USB Debugger A", FT_OPEN_BY_DESCRIPTION, &ftHandle);

	int send_size = 16 + 32768 + 8192 + 2 + 3;

	// Sendサイズセット
	uint8 init[3];
	init[0] = 0x31; // Writeコマンド
	init[1] = (uint8)send_size;
	init[2] = (uint8)(send_size >> 8);
	uint32 write_size;
	FT_Write(ftHandle, init, 3, &write_size); // Writeサイズセット(初期化)

	// ROMのロード
	FILE *fp = fopen("mario.nes", "rb");
	uint8 *rom = new uint8[16+32768+8192];
	fread(rom, 1, 16+32768+8192, fp);
	fclose(fp);

	uint8 begin[1];
	begin[0] = 0x00; // Mapper 0
	FT_Write(ftHandle, begin, 1, &write_size);
	FT_Write(ftHandle, begin, 1, &write_size);
	// ヘッダー send
	for(i=0; i<16; i++){
		FT_Write(ftHandle, rom+i, 1, &write_size);
	}
	// PRG-ROM send
	for(i=16; i<16+32768; i++){
		FT_Write(ftHandle, rom+i, 1, &write_size);
	}
	// CHR-ROM send
	for(i=16+32768; i<16+32768+8192; i++){
		FT_Write(ftHandle, rom+i, 1, &write_size);
	}
	uint8 end[1];
	FT_Write(ftHandle, end, 1, &write_size);
	FT_Write(ftHandle, end, 1, &write_size);
	FT_Write(ftHandle, end, 1, &write_size);

	delete[] rom;
	FT_Close(ftHandle);

映像出力

Gowin EDA で生成できる DVI_TX のIPを使用する。

最初、NES解像度を倍にした 512 x 448 で表示させてみたところ、 HDMI-USBキャプチャではスケーリング表示できたが、例のモニタでは表示できなかった。 他のモニタでも確実に表示されるよう、 640 x 480 で出力し 512 x 448 はスケーリングせずに中央に描画させた。

サウンド出力

一応APUもFPGAに入るかの確認のため、サウンド出力は1bitΔΣを通してLEDに接続してる。 IOピンに接続するとノイズになってしまうので、今のところLEDに接続。 音がモヨモヨ光る様子が見て取れる。

クロック

NESの実装見積もりで Fmax 30MHz 程度だったことも考慮し、 DVI_TXクロックを 124.875 MHz とし、NESコア用クロックは5分の1の 24.975 MHz とした。 HyperRAMクロックはNESコアの2倍の 49.95 MHz を使用。

NESコアは 25 MHz もしくは 50 MHz をベースに実装しているので、 クロックを 25.2 MHz にした場合、PPUの描画がHsyncに間に合わず、画面が下に流れてしまう現象が発生してしまう。 よって今回は、25 MHz 以下で設定する必要があった。

動作確認

実装はMapper0のみ、『スパーマリオブラザーズ』『レッキングクルー』等が動作した。

LED1個でデバグするのは非常につらいので、Gowin Analizer Oscilloscopeを活用した。

レポート

リソース使用率4264/4608 LUTs (93%)
BlockSRAM使用率9/10 (90%)
NESコアFmax30.7 MHz
論理合成・配置配線時間40 sec
FPGAデータ・コード Tang Nano 4K 用FPGAデータ(GitHub)

試しにいくつかのMapperを有効化して合成してみたところ、 LUT使用率ほぼ100%になった。 それでも合成・配置配線時間は変わらず、Fmaxも達成している。 Gowin EDA やるじゃん。

NES on FPGA feat. TangNano9K

価格約2,300円
デバイスLittleBee GW1NR-LV9QN88PC6/I5 (55nm LP embedded flash)
リソース8640 LUTs、BlockSRAM 約58kByte
メモリPSRAM 64Mbit (32Mbit 2ch)
参考 Sipeed wiki Tang Nano 9K

NES on FPGA feat. TangNano9K

PSRAMが2つ使えてそれぞれPRG-ROM・CHR-ROMとして実装できるので移植難易度は低いですね。使用率は61%程度なのでMapperも複数実装できる。容量の大きいマリオ3や沙羅曼蛇も難なく動きました。 pic.twitter.com/8AEa3zZ0UF

— かんな丸⁧!!⁨ (@pgate1) 2024年1月6日

メモリマッピング

PSRAMとして4MByteのダイが2つ載っており2chで使えるので、それぞれPRG-ROMとCHR-ROMとして使用する。 一番楽かもしれない。

PSRAM

Gowin EDAのPSRAM_Memory_Interface_HS_2CH_V2 IPを 49.95 MHz で最短のバースト長16で試したところ、 リードアクセス時間は 727 ns となり、遅すぎてPRG-ROMアクセスもCHR-ROMアクセスも間に合わない。 そこで、以下のPSRAM用コントローラを使用させて頂いた。 少し修正すればバーストなしバイトアクセスが可能。

参考: psram-tang-nano-9k

これならリードアクセスが 282 ns で間に合う。 ちなみにGowinのIPは 1017 LUTs、今回のコントローラは 118×2=236 LUTs で済むのも嬉しい。

microSDカード

いわゆるTFカードスロットが付いているので、ROMはここから読み込む。 回路図を見るに、配線はSPIモードの接続のみ。 他FPGAプロジェクトから、SDカードSPIアクセスモジュールとFAT16モジュールを流用する。 FAT16なので、microSDカードは最大2GBまでのものをたくさん用意した。

サウンド出力

HDMI Audio を使えばHDMIから出力できそうで、そのためのLUTも余裕はあるけど、 今のところちょっと難しそうなのでパス。 1bitΔΣを通してLEDに接続してる。

HDMI-Audio追加 2024/07/28

HDMIでサウンドも出力したかったので、以下の HDMI IP を使わせて頂いた。

参考: hdl-util / hdmi

ただ、NES coreからのサウンド出力をそのままHDMIモジュールに接続しても、 クロックドメインが異なるためノイズが乗る。 HDMIモジュール内ではaudio_clkの立ち上がりでAudio信号をホールドしているようなので、 以下のようにaudio_clkの立ち下がりでサウンドを保持することによりノイズは消えた。
NES_top.sv
localparam CLKFRQ = 25000000;
localparam AUDIO_RATE = 32000;
localparam AUDIO_CLK_DELAY = CLKFRQ / AUDIO_RATE / 2;

reg [$clog2(AUDIO_CLK_DELAY)-1:0] audio_divider;
reg audio_clk;
wire [15:0] Audio [1:0];
reg [15:0] s_Audio [1:0];

	always @(posedge pixel_clk) begin
		if(audio_divider != AUDIO_CLK_DELAY - 1)
			audio_divider++;
		else begin
			audio_clk <= ~audio_clk;
			audio_divider <= 0;
			// クロックたち下がりでホールド
			if(audio_clk) s_Audio <= Audio;
		end
	end

あと、電源を入れた後に「ブツッ…ブツッ…」という定常的なノイズがあるのが謎(1分くらいで消える)。

映像出力

DVI出力は Tang Nano 4K 同様の実装とした。

上記の HDMI IP に移行してもちろん映像は映るものの、 ドットクロックがIP想定25.2MHzのところ、24.975MHzのためか画面がちょっと横にずれる。 HDMIモジュールの入力にオフセット指定できるポートがあるので微調整した。

クロック

NESの実装見積もりで Fmax 30MHz 程度だったことも考慮し、 DVI_TXクロック 124.875 MHz、NESコアクロックは5分の1の 24.975 MHz とした。 PSRAMクロックはNESコアの倍の 49.95 MHz とした。

入力クロック 27 MHz から、49.5 MHz および 24.75 MHz を作るより、 まずDVI用のクロックを作って割った方が 25 MHz に近いのはたまたまなのか、 それとも高クロックからクロックツリーを設計すべきなのか。

また、CHR-ROMリードが間に合ってなかったので、 1クロック早くリードリクエストを出せるようにちょっと修正。

動作確認

実装はMapper0,1,2,3,4,73 を実装してみた。 『スパーマリオブラザーズ3』『星のカービィ』『沙羅曼蛇』等が動作した。

レポート

リソース使用率5190/8640 LUTs (61%)
BlockSRAM使用率10/26 (39%)
NESコアFmax34.7 MHz
論理合成・配置配線時間50 sec
FPGAデータ・コード Tang Nano 9K 用FPGAデータ(GitHub)

USB-UART追加 2024/06/11

ROM入れ替えのために毎回microSDカードを抜き差しするのが面倒だったため、 PCからUART経由でROMを送信できるようにした。 UARTモジュールでタイミングを攻めれば、ボーレート230,400×8=1,843,200 baud まで速度出せることを確認 (実効速度約200kByte/s)。 ついでにUART送信ソフトにキー入力機能を付けて、 キー情報をUART経由で送信しゲームをプレイできるようにした。

映像はHDMI-USBキャプチャでOBSに映してて、 UARTでキャプチャできればUSBキャプチャいらないのでは!?と考えたが、 1画面(256x240)は約122kByteなので1fps程度だと気づく (テーブルゲームのようなものならいけそう)。

NES on FPGA feat. TangNano9K:ROMデータをUART経由で送信するアプリ作ったので、ついでにキー操作もUARTで送信してゲームプレイできるようにした!PCにゲームパッドつなげて使えるようにすればもっと操作性良くなるかな pic.twitter.com/KMB6Hr4qTc

— かんな丸⁧!!⁨ (@pgate1) 2024年6月11日

NSF演奏時の画面エフェクト追加 2024/08/09

サウンドが出るようになったので、NSF演奏マッパーも有効にしてみた。 そしてせっかくなのでピアノロール的波形エフェクト回路も移植。

違うFPGAボードだけど動きはこんな感じ。

NSFプレイヤーにピアノロール的波形エフェクト画面を追加してみました。ちなみに3曲目のV.G.NEOは拡張音源のVRC7を使っている曲で、VRC7の本体としてvm2413を使わせて頂いています。 pic.twitter.com/kAPpSmT6zw

— かんな丸⁧!!⁨ (@pgate1) 2022年9月22日

NES on FPGA feat. TangNano20K

価格約4,000円
デバイスArora GW2AR-LV18QN88C8/I7 (55nm LP SRAM)
リソース20,736 LUTs、BlockSRAM 約103kByte
メモリSDR SDRAM 8MByte
参考 Sipeed wiki Tang Nano 20K

NES on FPGA feat. TangNano20K

1chipMSXに移植した時と同様に、SDRAM1個をPRG-ROMとCHR-ROMで共有してます。9Kよりも動作周波数上がって、NESコアは約50MHzでいけた。 pic.twitter.com/KKi8Dzhvzm

— かんな丸⁧!!⁨ (@pgate1) 2024年1月7日

メモリマッピング

SDRAMが1個なので、PRG-ROMとCHR-ROMを共存させる。 CPUとPPUからのメモリアクセスアービトレーションは必要。

SDRAM

他のFPGAプロジェクトから、バースト無しSDRAMコントローラを流用する。 もちろんPRG-ROMアクセスとCHR-ROMアクセスをアービトレーションする仕組みは必要だけど、 NES on FPGA feat. 1chipMSX での実装と同様の構成で動いた。

クロック

NESの実装見積もりで Fmax 70MHz いけたので、 DVI_TXクロック 124.875 MHz を 5分の2 してNESコアクロックは 49.95 MHz とした。 SDRAMクロックもNESコアと同じ 49.95 MHz を使用。

動作確認

実装はMapper0,1,2,3,4,73 を実装してみた。 『スパーマリオブラザーズ3』『星のカービィ』『沙羅曼蛇』等が動作した。 他のマッパーも余裕で追加できる程度にはリソースが余っている。

レポート

リソース使用率5240/20736 LUTs (26%)
BlockSRAM使用率10/46 (22%)
NESコアFmax68.1 MHz
論理合成・配置配線時間45 sec
FPGAデータ・コード Tang Nano 20K 用FPGAデータ(GitHub)

microSDカードアクセスとDVI出力とサウンド出力は Tang Nano 9K 同様の実装とした。

ちなみにTFスロット(microSDスロット)はSDモードが使用できるよう配線接続されているので、 そのうちSDモードアクセスモジュールに切り替えてROMの読み込み時間を半分にしたい (NESの場合は数十kByteなので読み込み一瞬だけど、SNESだと数MByteなので読み込みに少し時間がかかる)。 あとはmicroSDHCカードとFAT32のサポートに移行したい。

2024/02/18 追記: microSDHCコントローラとFAT32モジュールを実装し移行した。

Retro Game Emulation Kits

ゲーム操作したかったし音も出したかったため購入。 似非プレステパッド2個付きで約6300円+ホーン236円+送料2500円。

こんな感じでセッティング。 反対側にもパッドコネクタを増設できるが、LEDとピン共有されているため今は使用せず。 あとTFスロットがUSBコネクタの裏側にあってmicroSDカードの抜き差しがしづらい…。

2024/05/04: プレステパッドつなげて操作できるようになった。 他のボードにつなげた時とちょっと受信信号がずれる(?)ので少し調整。 付属の似非プレステパッドもオリジナルプレステパッドとほぼ同じアクセスで使用できたが、 振動や感圧は無し。

NES on FPGA feat. TangNano20K:プレステパッドつなげて操作できるようになった。他のボードにつなげたときとちょっと受信信号がずれる(なんでだろ?)ので少し調整。これは自由に動けるようになって喜ぶ人 pic.twitter.com/7fSw8dWnoV

— かんな丸⁧!!⁨ (@pgate1) 2024年5月4日

2024/05/06: ホーンからサウンド出せた。 アンプICのディジタル入力にはバンクIOの制約で3.3Vを使用。 低音が弱いので、三角波の音量を倍にする感じでちょうどいい。

NES on FPGA feat. TangNano20K:おとでた
ピントは永遠に合わない
HDMIにオーディオ流すのはまた時間が取れたらにしよ pic.twitter.com/Na9rb4XAyc

— かんな丸⁧!!⁨ (@pgate1) 2024年5月6日

SNES on FPGA feat. TangNano20K

Tang Nano 20K はファミコン実装には贅沢なので、ついでにスーファミも実装してみた。 LUTが足りないためサウンドDSPはオミット。

SNES on FPGA feat. TangNano20K(No sound)

LUTが足りなくサウンドDSPを除外して使用率73%で実装しました。でもサウンドメモリは必要なのでBlockSRAMを使ってます。本当はSDRAM1個でWorkRAMと共存させたいけどアクセス速度がちょっと厳しくて無理だった。 pic.twitter.com/3IRMiSfHXs

— かんな丸⁧!!⁨ (@pgate1) 2024年1月8日

メモリマッピング

VRAM 64kByte は速度が要求されるためBlockSRAMで実装。

その他のCPUからアクセスするROMが最大 4MByte、WorkRAM 128kByte、SaveRAM 256kByteはSDRAMを共用する。 ただし、ROMからWorkRAMへのDMAは通常リードとライトが並列に動作するが、 ここでは同じSDRAM内のため並列動作は解除して順次動作としている。

また、SoundRAM 64kByteについてもSDRAMに共存させるつもりだったが、 CPUメモリアクセスとサウンドプロセッサメモリアクセスをアービトレーションしてもアクセスタイムオーバーのため共存は諦めた。 しかし、SNESのCPUはサウンドプロセッサと協調して動作するので、SoundRAMの実装は必須。 結果的には、SoundRAMは4分の1の 16kByte でBlockRAMとして実装した。 観測した限りではあるけど、サウンドドライバはSoundRAMの低アドレス領域(0x0000~0x3FFF)に配置しているケースが多かったので動いている模様。 サウンドDSPをオミットして音を出さないのであれば、後半(0x4000~0xFFFF)の波形メモリ領域が不要であり、このようなトリッキーな実装が可能だった。 なお、8kByteだとバハムートラグーンやクロノトリガーが動かず、 32kByteだとBlockSRAMが足りない。

2024/03/28 追記: アービトレーション回路を修正し、 SDRAMクロックを 99.9 MHz に引き上げ、 配置配線のオプションをタイミング優先にして SoundRAMもSDRAMで共存させることができた。 一応『クロノトリガー』や『バハムートラグーン』のOPデモをパス。 しかしやはりサウンドDSPが入らず音は出ない。 それに、影響ない部分の回路を変更すると動かなくなるし、 そもそもアクセスタイムぎりぎりで動かすためCDCケアしてないので この実装は実験的なものに終わった。

クロック

SNESコア実装の見積もりでFmaxが 40MHz 程度だった(速度最適化オプションありだと 46 MHz)ので、 DVI出力用に 124.875 MHz を、SNESコア用にその5分の1の 24.975 MHz を生成した。 SDRAMはSNESコアの2倍の 49.95 MHz を使用する (SoundRAMをSDRAMに同居させる場合は 99.9 MHz)。

できるだけSDRAMアクセス時間を短くしたいということもあり、 従来SDRAMリフレッシュはオートランさせていたが、 今回はSNESのDRAMリフレッシュタイミング中にリフレッシュを行うよう修正。 動作としてはこちらの方が実機に近いかな。

2024/11/08 追記: SNESコアのクリティカルパス箇所の修正と、不要なリセットの削減を行った。 また、リセットがLW(Long Wire、ロジックラインにも使用可能なパス)だったものを、 PRIMARY(グローバル専用ライン)に乗せた。 これによりSNESコアFmax 49.95MHz を達成した (ただしコア 24.975MHz の方が安定して動作する…)。
リセット信号をグローバルPRIMARYラインに乗せるには2通りの方法があるようだ。 ドキュメントだとグローバルクロックラインとあるが、 リセットも乗せられるらしい。

物理制約で指定する方法はリセット信号名が変わることがあるため、 今回はDQCEプリミティブを使用した。 ただしLWをPRIMARYにすると画面が20ドットほど下にずれる現象があったため調査中。

動作確認

『ロックマンX』や『FinalFantasyV』等が動作。 『バハムートラグーン』や『クロノトリガー』のオープニングデモをパスした。 セーブデータも読み込めることを確認。

SNES on FPGA feat. TangNano20K(No sound)

大好物なバハムートラグーンのOPデモもパスしました。どろどろ愛憎劇でリメイク待ってる。 pic.twitter.com/pBAiZa2ZrG

— かんな丸⁧!!⁨ (@pgate1) 2024年1月8日

SNES on FPGA feat. TangNano20K(No sound)

セーブデータも読めるようにした pic.twitter.com/jXk2MJ4XYR

— かんな丸⁧!!⁨ (@pgate1) 2024年1月9日

レポート

リソース使用率14960/20736 LUTs (73%)
BlockSRAM使用率46/46 (100%)
SNESコアFmax33.4 MHz
論理合成・配置配線時間150 sec
FPGAデータ・コード Tang Nano 20K 用FPGAデータ(GitHub)

非同期リセットか同期リセットか

FPGAベンダが出しているHDLコーディングガイド等で、 非同期リセットか同期リセットのどちらかが推奨されていたりする。 GowinEDA はどうかな?と思いドキュメントを探してみたけど見つけられず、 実際に SNES on FPGA で比較してみた。 sfl2vlの -sync_res オプションで容易に非同期・同期を切り替えられる。

以下の表は CPU,PPU,DMA 回路をリセットを変更して比較したもの。 なぜか同期リセットの方がLUT少し減ったような気もするけど、 どちらでもあまり変わりなさそう。

リセットタイプ 論理合成・配置配線時間 使用リソース Fmax
非同期リセット150 sec9237 LUTs, 4145 regs33.4 MHz
同期リセット160 sec9140 LUTs, 4150 regs35.1 MHz

おわりに

Gowin EDA については、 ファイルパスは絶対パスじゃなく相対パスで管理して欲しい。 あとFPGAデータ生成完了したら音を出して欲しい。 シンセシス途中で止めたいことがあるけど止まらない。 クリティカルパスってどうやったら見られるんだろう。

簡単なテストHDLでも、ボードによって動いたり動かなかったりするのは品質にばらつきがあるのかな? Tang Nano 60K の発売待ってますよ!Sipeedさん。

移植について

Tang Nano シリーズへの NES on FPGA の移植を通じで、その移植性、 つまりSFLから生成されたVerilogHDLの移植性の高さ、 もしくは Gowin Synthesis の十分な性能を感じることができた。 ゲーミングFPGAボードと言っていいのか分からないけど、 とりあえず SNES on FPGA も動いたのでまんぞく。

NESコアとSNESコアは、どちらもクロック1つの完全同期設計であることと、 CPUがマイクロプログラムベースではないためBlockSRAMを使わないで済むことも 移植が容易だった要因だろう。

HDMI-USBキャプチャ

DVI出力をPC画面に表示できるので、デバグするのに非常に役に立った。 DVI_DE信号を見ているようで、通常のモニタではサポートしていない低い解像度でも表示してくれて、 2,500円程度でコスパが良い。 買うならUSB3.0 1080p@60HzをサポートしているMS2130チップを搭載しているものがお勧め。

2,500円の中華製HDMI-USBキャプチャなかなか良くて小型モニタいらないね。TangNano4Kのカメラデモ普通に映ってるし。MS2130っていうチップ使ってるらしいhttps://t.co/3lgboU3VvK pic.twitter.com/YpjplBOXou

— かんな丸⁧!!⁨ (@pgate1) 2023年11月7日

©2024 pgate1