2 use ieee.std_logic_1164.all;
4 -- this address decoder inserts dummy setup time on write.
5 entity address_decoder is
6 generic (abus_size : integer := 16; dbus_size : integer := 8);
7 port ( phi2 : in std_logic; --dropping edge syncronized clock.
8 mem_clk : in std_logic;
9 R_nW : in std_logic; -- active high on read / active low on write.
10 addr : in std_logic_vector (abus_size - 1 downto 0);
11 d_io : inout std_logic_vector (dbus_size - 1 downto 0);
12 ppu_ce_n : out std_logic;
13 apu_ce_n : out std_logic
19 -- * 0x0000 - 0x07FF RAM
20 -- * 0x0800 - 0x1FFF mirror RAM
21 -- * 0x2000 - 0x2007 I/O PPU
22 -- * 0x4000 - 0x401F I/O APU
23 -- * 0x6000 - 0x7FFF battery backup ram
24 -- * 0x8000 - 0xFFFF PRG-ROM
27 architecture rtl of address_decoder is
29 generic (abus_size : integer := 16; dbus_size : integer := 8);
30 port ( ce_n, oe_n, we_n : in std_logic; --select pin active low.
31 addr : in std_logic_vector (abus_size - 1 downto 0);
32 d_io : inout std_logic_vector (dbus_size - 1 downto 0)
36 generic (abus_size : integer := 15; dbus_size : integer := 8);
39 ce_n : in std_logic; --active low.
40 addr : in std_logic_vector (abus_size - 1 downto 0);
41 data : out std_logic_vector (dbus_size - 1 downto 0)
45 component single_port_rom
48 DATA_WIDTH : natural := 8;
49 ADDR_WIDTH : natural := 8
55 addr : in std_logic_vector (ADDR_WIDTH - 1 downto 0);
56 q : out std_logic_vector((DATA_WIDTH -1) downto 0)
60 constant dsize : integer := 8;
61 constant ram_2k : integer := 11; --2k = 11 bit width.
62 constant rom_32k : integer := 15; --32k = 15 bit width.
64 constant CPU_DST : time := 100 ns; --write data setup time.
66 signal rom_ce_n : std_logic;
67 signal rom_out : std_logic_vector (dsize - 1 downto 0);
69 signal ram_ce_n : std_logic;
70 signal ram_oe_n : std_logic;
71 signal ram_io : std_logic_vector (dsize - 1 downto 0);
75 rom_ce_n <= '0' when (addr(15) = '1' and R_nW = '1') else
77 -- romport : prg_rom generic map (rom_32k, dsize)
78 -- port map (mem_clk, rom_ce_n, addr(rom_32k - 1 downto 0), rom_out);
79 prg_romp_inst : single_port_rom generic map (8, 15)
80 port map (mem_clk, rom_ce_n, addr(rom_32k - 1 downto 0), rom_out);
83 when (r_nw = '0' and ((addr(15) or addr(14) or addr(13)) = '0')) else
86 -- ramport : ram generic map (ram_2k, dsize)
87 -- port map (ram_ce_n, ram_oe_n, R_nW,
88 -- addr(ram_2k - 1 downto 0), ram_io);
90 --must explicitly drive to for inout port.
92 when (((addr(15) or addr(14) or addr(13)) = '0') and r_nw = '1') else
94 when ((addr(15) = '1') and r_nw = '1') else
99 when (addr(15) = '0' and addr(14) = '0' and addr(13) = '1') else
103 when (addr(15) = '0' and addr(14) = '1' and addr(13) = '0') else
107 main_p : process (phi2, addr, d_io, R_nW)
109 -- ram range : 0 - 0x2000.
110 -- 0x2000 is 0010_0000_0000_0000
111 if ((addr(15) or addr(14) or addr(13)) = '0') then
112 --if (addr < "0010000000000000") then
115 --write timing slided by half clock.
116 ram_ce_n <= not phi2;
117 elsif (R_nW = '1') then
132 -----------------------------------------------------
133 -----------------------------------------------------
134 ---------- VRAM / CHR ROM Address Decoder -----------
135 -----------------------------------------------------
136 -----------------------------------------------------
139 use ieee.std_logic_1164.all;
141 entity v_address_decoder is
142 generic (abus_size : integer := 14; dbus_size : integer := 8);
143 port ( clk : in std_logic;
147 vram_ad : inout std_logic_vector (7 downto 0);
148 vram_a : in std_logic_vector (13 downto 8)
150 end v_address_decoder;
152 -- Address Size Description
153 -- $0000-$0FFF $1000 Pattern Table 0 [lower CHR bank]
154 -- $1000-$1FFF $1000 Pattern Table 1 [upper CHR bank]
155 -- $2000-$23FF $0400 Name Table #0
156 -- $2400-$27FF $0400 Name Table #1
157 -- $2800-$2BFF $0400 Name Table #2
158 -- $2C00-$2FFF $0400 Name Table #3
159 -- $3000-$3EFF $0F00 Mirrors of $2000-$2FFF
160 -- $3F00-$3F1F $0020 Palette RAM indexes [not RGB values]
161 -- $3F20-$3FFF $0080 Mirrors of $3F00-$3F1F
163 architecture rtl of v_address_decoder is
165 generic (abus_size : integer := 16; dbus_size : integer := 8);
166 port ( ce_n, oe_n, we_n : in std_logic; --select pin active low.
167 addr : in std_logic_vector (abus_size - 1 downto 0);
168 d_io : inout std_logic_vector (dbus_size - 1 downto 0)
173 generic (abus_size : integer := 13; dbus_size : integer := 8);
174 port ( ce_n : in std_logic; --active low.
175 addr : in std_logic_vector (abus_size - 1 downto 0);
176 data : out std_logic_vector (dbus_size - 1 downto 0);
177 nt_v_mirror : out std_logic
185 port ( c : in std_logic;
187 d : in std_logic_vector(dsize - 1 downto 0);
188 q : out std_logic_vector(dsize - 1 downto 0)
192 constant dsize : integer := 8;
193 constant vram_1k : integer := 10; --2k = 11 bit width.
194 constant chr_rom_8k : integer := 13; --32k = 15 bit width.
196 signal v_addr : std_logic_vector (13 downto 0);
197 --signal nt_v_mirror2 : std_logic;
198 signal nt_v_mirror : std_logic;
200 signal pt_ce_n : std_logic;
201 signal nt0_ce_n : std_logic;
202 signal nt1_ce_n : std_logic;
206 --transparent d-latch
207 latch_inst : ls373 generic map (dsize)
208 port map(ale, '0', vram_ad, v_addr(7 downto 0));
209 v_addr (13 downto 8) <= vram_a;
212 pt_ce_n <= '0' when (v_addr(13) = '0' and rd_n = '0') else
214 --nt_v_mirror <= '0';
215 pattern_tbl : chr_rom generic map (chr_rom_8k, dsize)
216 port map (pt_ce_n, v_addr(chr_rom_8k - 1 downto 0), vram_ad, nt_v_mirror);
218 --name table/attr table
219 name_tbl0 : ram generic map (vram_1k, dsize)
220 port map (nt0_ce_n, rd_n, wr_n,
221 v_addr(vram_1k - 1 downto 0), vram_ad);
223 name_tbl1 : ram generic map (vram_1k, dsize)
224 port map (nt1_ce_n, rd_n, wr_n,
225 v_addr(vram_1k - 1 downto 0), vram_ad);
227 --palette table data is stored in the inside ppu
230 main_p : process (clk, v_addr, vram_ad, wr_n)
232 if (v_addr(13) = '1') then
234 if ((v_addr(12) and v_addr(11) and v_addr(10)
235 and v_addr(9) and v_addr(8)) = '0') then
236 if (nt_v_mirror = '1') then
237 --bit 10 is the name table selector.
238 if (v_addr(10) = '0') then
239 --name table 0 enable.
244 elsif (rd_n = '0') then
251 --name table 1 enable.
256 elsif (rd_n = '0') then
265 --bit 11 is the name table selector.
266 if (v_addr(11) = '0') then
267 --name table 0 enable.
272 elsif (rd_n = '0') then
279 --name table 1 enable.
284 elsif (rd_n = '0') then
291 end if; --if (nt_v_mirror = '1') then
299 end if; --if (v_addr(13) = '1') then