OSDN Git Service

rom/ram 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 component single_port_rom
46     generic 
47     (
48         DATA_WIDTH : natural := 8;
49         ADDR_WIDTH : natural := 8
50     );
51     port 
52     (
53         clk             : in std_logic;
54         ce              : in std_logic;
55         addr            : in std_logic_vector (ADDR_WIDTH - 1 downto 0);
56         q               : out std_logic_vector((DATA_WIDTH -1) downto 0)
57     );
58 end component;
59
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.
63
64     constant CPU_DST : time := 100 ns;    --write data setup time.
65
66     signal rom_ce_n : std_logic;
67     signal rom_out : std_logic_vector (dsize - 1 downto 0);
68
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);
72     
73 begin
74
75     rom_ce_n <= '0' when (addr(15) = '1' and R_nW = '1') else
76              '1' ;
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);
81
82     ram_io <= d_io 
83         when (r_nw = '0' and ((addr(15) or addr(14) or addr(13)) = '0')) else
84         "ZZZZZZZZ";
85     ram_oe_n <= not R_nW;
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);
89
90     --must explicitly drive to for inout port.
91     d_io <= ram_io 
92             when (((addr(15) or addr(14) or addr(13)) = '0') and r_nw = '1')  else
93         rom_out 
94             when ((addr(15) = '1') and r_nw = '1') else
95         (others => 'Z');
96
97
98     ppu_ce_n <= '0'
99             when (addr(15) = '0' and addr(14) = '0' and addr(13) = '1')  else
100                 '1';
101
102     apu_ce_n <= '0'
103             when (addr(15) = '0' and addr(14) = '1' and addr(13) = '0')  else
104                 '1';
105
106     --ram io timing.
107     main_p : process (phi2, addr, d_io, R_nW)
108     begin
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
113             if (R_nW = '0') then
114                 --write
115                 --write timing slided by half clock.
116                 ram_ce_n <= not phi2;
117             elsif (R_nW = '1') then 
118                 --read
119                 ram_ce_n <= '0';
120             else
121                 ram_ce_n <= '1';
122             end if;
123         else
124             ram_ce_n <= '1';
125         end if;
126     end process;
127
128 end rtl;
129
130
131
132 -----------------------------------------------------
133 -----------------------------------------------------
134 ---------- VRAM / CHR ROM Address Decoder -----------
135 -----------------------------------------------------
136 -----------------------------------------------------
137
138 library ieee;
139 use ieee.std_logic_1164.all;
140
141 entity v_address_decoder is
142 generic (abus_size : integer := 14; dbus_size : integer := 8);
143     port (  clk         : in std_logic; 
144             rd_n        : in std_logic;
145             wr_n        : in std_logic;
146             ale         : in std_logic;
147             vram_ad     : inout std_logic_vector (7 downto 0);
148             vram_a      : in std_logic_vector (13 downto 8)
149         );
150 end v_address_decoder;
151
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
162
163 architecture rtl of v_address_decoder is
164     component ram
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)
169         );
170     end component;
171
172     component chr_rom
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
178         );
179     end component;
180
181     component ls373
182         generic (
183             dsize : integer := 8
184         );
185         port (  c         : in std_logic;
186                 oc_n      : in std_logic;
187                 d         : in std_logic_vector(dsize - 1 downto 0);
188                 q         : out std_logic_vector(dsize - 1 downto 0)
189         );
190     end component;
191
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.
195
196     signal v_addr : std_logic_vector (13 downto 0);
197     --signal nt_v_mirror2  : std_logic;
198     signal nt_v_mirror  : std_logic;
199
200     signal pt_ce_n : std_logic;
201     signal nt0_ce_n : std_logic;
202     signal nt1_ce_n : std_logic;
203
204 begin
205
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;
210
211     --pattern table
212     pt_ce_n <= '0' when (v_addr(13) = '0' and rd_n = '0') else
213              '1' ;
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);
217
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);
222
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);
226
227     --palette table data is stored in the inside ppu
228
229     --ram io timing.
230     main_p : process (clk, v_addr, vram_ad, wr_n)
231     begin
232         if (v_addr(13) = '1') then
233             ---name tbl
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.
240                         nt1_ce_n <= '1';
241                         if (wr_n = '0') then
242                             --write
243                             nt0_ce_n <= clk;
244                         elsif (rd_n = '0') then 
245                             --read
246                             nt0_ce_n <= '0';
247                         else
248                             nt0_ce_n <= '1';
249                         end if;
250                     else
251                         --name table 1 enable.
252                         nt0_ce_n <= '1';
253                         if (wr_n = '0') then
254                             --write
255                             nt1_ce_n <= clk;
256                         elsif (rd_n = '0') then 
257                             --read
258                             nt1_ce_n <= '0';
259                         else
260                             nt1_ce_n <= '1';
261                         end if;
262                     end if;
263                 else
264                     --horizontal mirror.
265                     --bit 11 is the name table selector.
266                     if (v_addr(11) = '0') then
267                         --name table 0 enable.
268                         nt1_ce_n <= '1';
269                         if (wr_n = '0') then
270                             --write
271                             nt0_ce_n <= clk;
272                         elsif (rd_n = '0') then 
273                             --read
274                             nt0_ce_n <= '0';
275                         else
276                             nt0_ce_n <= '1';
277                         end if;
278                     else
279                         --name table 1 enable.
280                         nt0_ce_n <= '1';
281                         if (wr_n = '0') then
282                             --write
283                             nt1_ce_n <= clk;
284                         elsif (rd_n = '0') then 
285                             --read
286                             nt1_ce_n <= '0';
287                         else
288                             nt1_ce_n <= '1';
289                         end if;
290                     end if;
291                 end if; --if (nt_v_mirror = '1') then
292             else
293                 nt0_ce_n <= '1';
294                 nt1_ce_n <= '1';
295             end if;
296         else
297             nt0_ce_n <= '1';
298             nt1_ce_n <= '1';
299         end if; --if (v_addr(13) = '1') then
300     end process;
301
302 end rtl;
303