OSDN Git Service

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