dev NES
CPU、PPU、APU、WRAM、VRAMをモジュールとして持ち、
それらの接続と外部インタフェース部分を記述しています。

アドレスラインをおおざっぱに描くとこんな感じでしょうか。
CPUから出力する16bitのアドレスのうち、WRAMには下位11bit、
PPUのI/Oには下位3bit、APUには下位5bit、カートリッジには下位15bitを接続しています。
_ ▼ CPUメモリマップ
any{
A_reg<15:13>==0b000 : par{ // $0000-$07FF WRAM
map_wmem();
mpu.din = wmem.dout;
}
A_reg<15:13>==0b001 : par{ // $2000-$2007 PPU
map_ppu();
mpu.din = ppu.Dout;
}
A_reg<15:13>==0b010 : any{
A_reg<12:5>==0b00000000 : par{ // $4000-$401F APU, PAD
map_apu();
mpu.din = io_reg;
}
else : par{ // $4020-$5FFF ExROM
map_nesrom();
mpu.din = prg_din;
}
}
A_reg<15:13>==0b011 : par{ // $6000-$7FFF ExRAM
map_nesrom();
mpu.din = prg_din;
}
A_reg<15> : par{ // $8000-$FFFF ROM
map_nesrom();
mpu.din = prg_din;
}
}
アドレス$4020以降はカートリッジへのアクセスとなります。
APUとPADアクセス部分では、読み込みと書き込みで用途が異なる部分があります。
読み込み時にはウエイト部分を励起する必要があります。
_ ▼ PPUメモリマップ
if(VRAM_CSn==0b0){
// VRAM
ppu.PDin = vmem.dout;
}
else{
// カートリッジ(CHR-ROM)
ppu.PDin = chr_din;
}
VRAM_CS(チップセレクト)はカートリッジからの入力です。
この信号がLowの間、VRAMへのアクセスとなります。
カラーパレットはPPU内部にあり、PPU外部のメモリマップには現れません。
_ ▼ リードアクセスウエイト
FPGAクロック33MHzにおいて内部ブロックRAMへのアクセスは2クロック
(リード要求、データ取得)必要です。
またCPUからカートリッジへのアクセスでは安全のため、
CPUが次に励起される直前までウエイトをかけています(15クロック)。
ウエイトの後、CPUに対してACKを入力することで、
CPUはレジスタへデータを書き込みます。
PPUからカートリッジへのアクセスではCPUよりも短いウエイトとなっています(9クロック)。
_ ▼ DMA
DMAが動作している間は、CPUのレディ信号に対して0を入力し、CPUを停止させておきます。
これも実機とクロック数を合わせるためです。
一部情報では、転送元でROMを指定してもDMAできないようだ。
転送元にWRAMを指定すると問題ないみたい。
実装では今のところROMからもDMAできる実装となっているが、
解析結果によっては削減できるかもしれない。
_ ▼ 動作タイミングをがんばって実機に近づける! 2019/05/20
NES内のCPUやPPUは異なるサイクルで動作するので、
通常は速めのクロックを入れて、カウンタで分周したイネーブル信号でサイクルを生成します。
ポイントはNESコアは単一クロックで動くようにしてPLL使用数を抑え、
使用するクロック周波数も任意のものを使用したいということです。
いやNESのクロックをベースにして周辺回路を動かした方がスマートかもしれないですけど。
ここで使用するのがイネーブルカウンタこと、
ダイレクト・ディジタル・シンセサイザ
(Direct Digital Synthesizer, DDS)を応用した任意イネーブルサイクルの生成です。
カウンタ計算機や解説はこちら。
このカウンタの良い所は、
イネーブルトリガがばらけていること(出現が偏っていないこと)と、
ある程度の小さな誤差を許容するならカウンタビット幅を抑えられること。
例えばベースクロック50MHzからPPUサイクル5.369318MHzを作るには、
誤差0にするなら26bitのカウンタが必要ですが、
0.000003Hzの誤差を許容して22bitのカウンタを使用しています。
Copyright(C) pgate1 All Rights Reserved.
|