OSDN Git Service

4k rom working
[motonesfpga/motonesfpga.git] / de1_nes / address_decoder.vhd
1 library ieee;
2 use ieee.std_logic_1164.all;
3
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
14         );
15 end address_decoder;
16
17 --/*
18 -- * NES memory map
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
25 -- * */
26
27 architecture rtl of address_decoder is
28     component ram
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)
33         );
34     end component;
35     component prg_rom
36         generic (abus_size : integer := 15; dbus_size : integer := 8);
37         port (
38                 clk             : in std_logic;
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)
42         );
43     end component;
44
45     constant dsize : integer := 8;
46     constant ram_2k : integer := 11;      --2k = 11 bit width.
47     constant rom_32k : integer := 15;     --32k = 15 bit width.
48     constant rom_4k : integer := 12;     --4k = 12 bit width.
49
50     constant CPU_DST : time := 100 ns;    --write data setup time.
51
52     signal rom_ce_n : std_logic;
53     signal rom_out : std_logic_vector (dsize - 1 downto 0);
54
55     signal ram_ce_n : std_logic;
56     signal ram_oe_n : std_logic;
57     signal ram_io : std_logic_vector (dsize - 1 downto 0);
58     
59     
60     component single_port_rom
61     generic 
62     (
63         DATA_WIDTH : natural := 8;
64         ADDR_WIDTH : natural := 8
65     );
66     port 
67     (
68         clk             : in std_logic;
69         ce              : in std_logic;
70         addr            : in std_logic_vector (ADDR_WIDTH - 1 downto 0);
71         q               : out std_logic_vector((DATA_WIDTH -1) downto 0)
72     );
73 end component;
74
75 begin
76
77     rom_ce_n <= '0' when (addr(15) = '1' and R_nW = '1') else
78              '1' ;
79
80 --    romport : prg_rom generic map (rom_32k, dsize)
81 --            port map (mem_clk, rom_ce_n, addr(rom_32k - 1 downto 0), rom_out);
82     --mask address 4k.
83     romport : prg_rom generic map (rom_4k, dsize)
84             port map (mem_clk, rom_ce_n, addr(rom_4k - 1 downto 0), rom_out);
85 --    romport : single_port_rom generic map (dsize, rom_4k)
86 --            port map (mem_clk, rom_ce_n, addr(rom_4k - 1 downto 0), rom_out);
87
88     ram_io <= d_io 
89         when (r_nw = '0' and ((addr(15) or addr(14) or addr(13)) = '0')) else
90         "ZZZZZZZZ";
91     ram_oe_n <= not R_nW;
92 --    ramport : ram generic map (ram_2k, dsize)
93 --            port map (ram_ce_n, ram_oe_n, R_nW, 
94 --                    addr(ram_2k - 1 downto 0), ram_io);
95
96     --must explicitly drive to for inout port.
97     d_io <= ram_io 
98             when (((addr(15) or addr(14) or addr(13)) = '0') and r_nw = '1')  else
99         rom_out 
100             when ((addr(15) = '1') and r_nw = '1') else
101         (others => 'Z');
102
103
104     ppu_ce_n <= '0'
105             when (addr(15) = '0' and addr(14) = '0' and addr(13) = '1')  else
106                 '1';
107
108     apu_ce_n <= '0'
109             when (addr(15) = '0' and addr(14) = '1' and addr(13) = '0')  else
110                 '1';
111
112     --ram io timing.
113     main_p : process (phi2, addr, d_io, R_nW)
114     begin
115             -- ram range : 0 - 0x2000.
116             -- 0x2000 is 0010_0000_0000_0000
117         if ((addr(15) or addr(14) or addr(13)) = '0') then
118         --if (addr < "0010000000000000") then
119             if (R_nW = '0') then
120                 --write
121                 --write timing slided by half clock.
122                 ram_ce_n <= not phi2;
123             elsif (R_nW = '1') then 
124                 --read
125                 ram_ce_n <= '0';
126             else
127                 ram_ce_n <= '1';
128             end if;
129         else
130             ram_ce_n <= '1';
131         end if;
132     end process;
133
134 end rtl;
135
136
137
138 -----------------------------------------------------
139 -----------------------------------------------------
140 ---------- VRAM / CHR ROM Address Decoder -----------
141 -----------------------------------------------------
142 -----------------------------------------------------
143
144 library ieee;
145 use ieee.std_logic_1164.all;
146
147 entity v_address_decoder is
148 generic (abus_size : integer := 14; dbus_size : integer := 8);
149     port (  clk         : in std_logic; 
150             rd_n        : in std_logic;
151             wr_n        : in std_logic;
152             ale         : in std_logic;
153             vram_ad     : inout std_logic_vector (7 downto 0);
154             vram_a      : in std_logic_vector (13 downto 8)
155         );
156 end v_address_decoder;
157
158 -- Address      Size    Description
159 -- $0000-$0FFF  $1000   Pattern Table 0 [lower CHR bank]
160 -- $1000-$1FFF  $1000   Pattern Table 1 [upper CHR bank]
161 -- $2000-$23FF  $0400   Name Table #0
162 -- $2400-$27FF  $0400   Name Table #1
163 -- $2800-$2BFF  $0400   Name Table #2
164 -- $2C00-$2FFF  $0400   Name Table #3
165 -- $3000-$3EFF  $0F00   Mirrors of $2000-$2FFF
166 -- $3F00-$3F1F  $0020   Palette RAM indexes [not RGB values]
167 -- $3F20-$3FFF  $0080   Mirrors of $3F00-$3F1F
168
169 architecture rtl of v_address_decoder is
170     component ram
171         generic (abus_size : integer := 16; dbus_size : integer := 8);
172         port (  ce_n, oe_n, we_n  : in std_logic;   --select pin active low.
173                 addr              : in std_logic_vector (abus_size - 1 downto 0);
174                 d_io              : inout std_logic_vector (dbus_size - 1 downto 0)
175         );
176     end component;
177
178     component chr_rom
179         generic (abus_size : integer := 13; dbus_size : integer := 8);
180         port (  ce_n            : in std_logic;     --active low.
181                 addr            : in std_logic_vector (abus_size - 1 downto 0);
182                 data            : out std_logic_vector (dbus_size - 1 downto 0);
183                 nt_v_mirror     : out std_logic
184         );
185     end component;
186
187     component ls373
188         generic (
189             dsize : integer := 8
190         );
191         port (  c         : in std_logic;
192                 oc_n      : in std_logic;
193                 d         : in std_logic_vector(dsize - 1 downto 0);
194                 q         : out std_logic_vector(dsize - 1 downto 0)
195         );
196     end component;
197
198     constant dsize : integer := 8;
199     constant vram_1k : integer := 10;      --2k = 11 bit width.
200     constant chr_rom_8k : integer := 13;     --32k = 15 bit width.
201
202     signal v_addr : std_logic_vector (13 downto 0);
203     --signal nt_v_mirror2  : std_logic;
204     signal nt_v_mirror  : std_logic;
205
206     signal pt_ce_n : std_logic;
207     signal nt0_ce_n : std_logic;
208     signal nt1_ce_n : std_logic;
209
210 begin
211
212     --transparent d-latch
213     latch_inst : ls373 generic map (dsize)
214                 port map(ale, '0', vram_ad, v_addr(7 downto 0));
215     v_addr (13 downto 8) <= vram_a;
216
217     --pattern table
218     pt_ce_n <= '0' when (v_addr(13) = '0' and rd_n = '0') else
219              '1' ;
220     --nt_v_mirror <= '0';
221     pattern_tbl : chr_rom generic map (chr_rom_8k, dsize)
222             port map (pt_ce_n, v_addr(chr_rom_8k - 1 downto 0), vram_ad, nt_v_mirror);
223
224     --name table/attr table
225     name_tbl0 : ram generic map (vram_1k, dsize)
226             port map (nt0_ce_n, rd_n, wr_n, 
227                     v_addr(vram_1k - 1 downto 0), vram_ad);
228
229     name_tbl1 : ram generic map (vram_1k, dsize)
230             port map (nt1_ce_n, rd_n, wr_n, 
231                     v_addr(vram_1k - 1 downto 0), vram_ad);
232
233     --palette table data is stored in the inside ppu
234
235     --ram io timing.
236     main_p : process (clk, v_addr, vram_ad, wr_n)
237     begin
238         if (v_addr(13) = '1') then
239             ---name tbl
240             if ((v_addr(12) and v_addr(11) and v_addr(10) 
241                         and v_addr(9) and v_addr(8)) = '0') then
242                 if (nt_v_mirror = '1') then
243                     --bit 10 is the name table selector.
244                     if (v_addr(10) = '0') then
245                         --name table 0 enable.
246                         nt1_ce_n <= '1';
247                         if (wr_n = '0') then
248                             --write
249                             nt0_ce_n <= clk;
250                         elsif (rd_n = '0') then 
251                             --read
252                             nt0_ce_n <= '0';
253                         else
254                             nt0_ce_n <= '1';
255                         end if;
256                     else
257                         --name table 1 enable.
258                         nt0_ce_n <= '1';
259                         if (wr_n = '0') then
260                             --write
261                             nt1_ce_n <= clk;
262                         elsif (rd_n = '0') then 
263                             --read
264                             nt1_ce_n <= '0';
265                         else
266                             nt1_ce_n <= '1';
267                         end if;
268                     end if;
269                 else
270                     --horizontal mirror.
271                     --bit 11 is the name table selector.
272                     if (v_addr(11) = '0') then
273                         --name table 0 enable.
274                         nt1_ce_n <= '1';
275                         if (wr_n = '0') then
276                             --write
277                             nt0_ce_n <= clk;
278                         elsif (rd_n = '0') then 
279                             --read
280                             nt0_ce_n <= '0';
281                         else
282                             nt0_ce_n <= '1';
283                         end if;
284                     else
285                         --name table 1 enable.
286                         nt0_ce_n <= '1';
287                         if (wr_n = '0') then
288                             --write
289                             nt1_ce_n <= clk;
290                         elsif (rd_n = '0') then 
291                             --read
292                             nt1_ce_n <= '0';
293                         else
294                             nt1_ce_n <= '1';
295                         end if;
296                     end if;
297                 end if; --if (nt_v_mirror = '1') then
298             else
299                 nt0_ce_n <= '1';
300                 nt1_ce_n <= '1';
301             end if;
302         else
303             nt0_ce_n <= '1';
304             nt1_ce_n <= '1';
305         end if; --if (v_addr(13) = '1') then
306     end process;
307
308 end rtl;
309