library ieee; use ieee.std_logic_1164.all; -- this address decoder inserts dummy setup time on write. entity address_decoder is generic (abus_size : integer := 16; dbus_size : integer := 8); port ( addr : in std_logic_vector (abus_size - 1 downto 0); rom_ce_n : out std_logic; ram_ce_n : out std_logic; ppu_ce_n : out std_logic; apu_ce_n : out std_logic ); end address_decoder; --/* -- * NES memory map -- * 0x0000 - 0x07FF RAM -- * 0x0800 - 0x1FFF mirror RAM -- * 0x2000 - 0x2007 I/O PPU -- * 0x4000 - 0x401F I/O APU -- * 0x6000 - 0x7FFF battery backup ram -- * 0x8000 - 0xFFFF PRG-ROM -- * */ architecture rtl of address_decoder is begin rom_ce_n <= not addr(15); ppu_ce_n <= '0' when (addr(15) = '0' and addr(14) = '0' and addr(13) = '1') else '1'; apu_ce_n <= '0' when (addr(15) = '0' and addr(14) = '1' and addr(13) = '0') else '1'; -- ram range : 0 - 0x2000. -- 0x2000 is 0010_0000_0000_0000 ram_ce_n <= '0' when ((addr(15) or addr(14) or addr(13)) = '0') else '1'; end rtl; ----------------------------------------------------- ----------------------------------------------------- ---------- VRAM / CHR ROM Address Decoder ----------- ----------------------------------------------------- ----------------------------------------------------- library ieee; use ieee.std_logic_1164.all; entity v_address_decoder is generic (abus_size : integer := 14; dbus_size : integer := 8); port ( v_addr : in std_logic_vector (13 downto 0); nt_v_mirror : in std_logic; pt_ce_n : out std_logic; nt0_ce_n : out std_logic; nt1_ce_n : out std_logic ); end v_address_decoder; -- Address Size Description -- $0000-$0FFF $1000 Pattern Table 0 [lower CHR bank] -- $1000-$1FFF $1000 Pattern Table 1 [upper CHR bank] -- $2000-$23FF $0400 Name Table #0 -- $2400-$27FF $0400 Name Table #1 -- $2800-$2BFF $0400 Name Table #2 -- $2C00-$2FFF $0400 Name Table #3 -- $3000-$3EFF $0F00 Mirrors of $2000-$2FFF -- $3F00-$3F1F $0020 Palette RAM indexes [not RGB values] -- $3F20-$3FFF $0080 Mirrors of $3F00-$3F1F architecture rtl of v_address_decoder is begin --pattern table pt_ce_n <= '0' when (v_addr(13) = '0') else '1' ; --name table0 nt0_ce_n <= '1' when (v_addr(13) = '0') else '1' when (v_addr(13 downto 8) = "111111") else '0' when (((v_addr(11) or v_addr(10)) = '0') or (nt_v_mirror = '1' and v_addr(11) = '1' and v_addr(10) = '0') or (nt_v_mirror = '0' and v_addr(11) = '0' and v_addr(10) = '1')) else '1'; --name table1 nt1_ce_n <= '1' when (v_addr(13) = '0') else '1' when (v_addr(13 downto 8) = "111111") else '0' when (((v_addr(11) and v_addr(10)) = '1') or (nt_v_mirror = '1' and v_addr(11) = '0' and v_addr(10) = '1') or (nt_v_mirror = '0' and v_addr(11) = '1' and v_addr(10) = '0')) else '1'; end rtl;