OSDN Git Service

07f272d3a62c14035fda64e972e247c0957f0330
[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        : in std_logic_vector (dbus_size - 1 downto 0);
12             rom_ce_n    : out std_logic;
13             ram_ce_n    : out std_logic;
14             ppu_ce_n    : out std_logic;
15             apu_ce_n    : out std_logic
16         );
17 end address_decoder;
18
19 --/*
20 -- * NES memory map
21 -- * 0x0000   -   0x07FF      RAM
22 -- * 0x0800   -   0x1FFF      mirror RAM
23 -- * 0x2000   -   0x2007      I/O PPU
24 -- * 0x4000   -   0x401F      I/O APU
25 -- * 0x6000   -   0x7FFF      battery backup ram
26 -- * 0x8000   -   0xFFFF      PRG-ROM
27 -- * */
28
29 architecture rtl of address_decoder is
30
31 component ram_ctrl
32     port (  
33             clk              : in std_logic;
34             ce_n, oe_n, we_n : in std_logic;
35             sync_ce_n        : out std_logic
36         );
37 end component;
38
39 signal ram_ce_n_in    : std_logic;
40 signal r_n            : std_logic;
41
42 begin
43
44     rom_ce_n <= '0' when (addr(15) = '1' and R_nW = '1') else
45              '1' ;
46
47     ppu_ce_n <= '0'
48             when (addr(15) = '0' and addr(14) = '0' and addr(13) = '1')  else
49                 '1';
50
51     apu_ce_n <= '0'
52             when (addr(15) = '0' and addr(14) = '1' and addr(13) = '0')  else
53                 '1';
54
55     r_n <= not r_nw;
56     ram_ctl_inst : ram_ctrl
57             port map (mem_clk, ram_ce_n_in, r_n, r_nw, ram_ce_n);
58
59     --ram io timing.
60     main_p : process (phi2, addr, d_io, R_nW)
61     begin
62             -- ram range : 0 - 0x2000.
63             -- 0x2000 is 0010_0000_0000_0000
64         if ((addr(15) or addr(14) or addr(13)) = '0') then
65         --if (addr < "0010000000000000") then
66             if (R_nW = '0') then
67                 --write
68                 --write timing slided by half clock.
69                 ram_ce_n_in <= not phi2;
70             elsif (R_nW = '1') then 
71                 --read
72                 ram_ce_n_in <= '0';
73             else
74                 ram_ce_n_in <= '1';
75             end if;
76         else
77             ram_ce_n_in <= '1';
78         end if;
79     end process;
80
81 end rtl;
82
83
84
85 -----------------------------------------------------
86 -----------------------------------------------------
87 ---------- VRAM / CHR ROM Address Decoder -----------
88 -----------------------------------------------------
89 -----------------------------------------------------
90
91 library ieee;
92 use ieee.std_logic_1164.all;
93
94 entity v_address_decoder is
95 generic (abus_size : integer := 14; dbus_size : integer := 8);
96     port (  clk         : in std_logic; 
97             mem_clk     : in std_logic;
98             rd_n        : in std_logic;
99             wr_n        : in std_logic;
100             ale         : in std_logic;
101             v_addr      : in std_logic_vector (13 downto 0);
102             v_data      : in std_logic_vector (7 downto 0);
103             nt_v_mirror : in std_logic;
104             pt_ce_n     : out std_logic;
105             nt0_ce_n    : out std_logic;
106             nt1_ce_n    : out std_logic
107         );
108 end v_address_decoder;
109
110 -- Address      Size    Description
111 -- $0000-$0FFF  $1000   Pattern Table 0 [lower CHR bank]
112 -- $1000-$1FFF  $1000   Pattern Table 1 [upper CHR bank]
113 -- $2000-$23FF  $0400   Name Table #0
114 -- $2400-$27FF  $0400   Name Table #1
115 -- $2800-$2BFF  $0400   Name Table #2
116 -- $2C00-$2FFF  $0400   Name Table #3
117 -- $3000-$3EFF  $0F00   Mirrors of $2000-$2FFF
118 -- $3F00-$3F1F  $0020   Palette RAM indexes [not RGB values]
119 -- $3F20-$3FFF  $0080   Mirrors of $3F00-$3F1F
120
121 architecture rtl of v_address_decoder is
122
123 component ram_ctrl
124     port (  
125             clk              : in std_logic;
126             ce_n, oe_n, we_n : in std_logic;
127             sync_ce_n        : out std_logic
128         );
129 end component;
130
131 signal nt0_ce_n_in    : std_logic;
132 signal nt1_ce_n_in    : std_logic;
133 begin
134
135     --pattern table
136     pt_ce_n <= '0' when (v_addr(13) = '0' and rd_n = '0') else
137              '1' ;
138
139     nt0_ram_ctl : ram_ctrl
140             port map (mem_clk, nt0_ce_n_in, rd_n, wr_n, nt0_ce_n);
141     nt1_ram_ctl : ram_ctrl
142             port map (mem_clk, nt1_ce_n_in, rd_n, wr_n, nt1_ce_n);
143
144     --ram io timing.
145     main_p : process (clk, v_addr, v_data, wr_n)
146     begin
147         if (v_addr(13) = '1') then
148             ---name tbl
149             if ((v_addr(12) and v_addr(11) and v_addr(10) 
150                         and v_addr(9) and v_addr(8)) = '0') then
151                 if (nt_v_mirror = '1') then
152                     --bit 10 is the name table selector.
153                     if (v_addr(10) = '0') then
154                         --name table 0 enable.
155                         nt1_ce_n_in <= '1';
156                         if (wr_n = '0') then
157                             --write
158                             nt0_ce_n_in <= clk;
159                         elsif (rd_n = '0') then 
160                             --read
161                             nt0_ce_n_in <= '0';
162                         else
163                             nt0_ce_n_in <= '1';
164                         end if;
165                     else
166                         --name table 1 enable.
167                         nt0_ce_n_in <= '1';
168                         if (wr_n = '0') then
169                             --write
170                             nt1_ce_n_in <= clk;
171                         elsif (rd_n = '0') then 
172                             --read
173                             nt1_ce_n_in <= '0';
174                         else
175                             nt1_ce_n_in <= '1';
176                         end if;
177                     end if;
178                 else
179                     --horizontal mirror.
180                     --bit 11 is the name table selector.
181                     if (v_addr(11) = '0') then
182                         --name table 0 enable.
183                         nt1_ce_n_in <= '1';
184                         if (wr_n = '0') then
185                             --write
186                             nt0_ce_n_in <= clk;
187                         elsif (rd_n = '0') then 
188                             --read
189                             nt0_ce_n_in <= '0';
190                         else
191                             nt0_ce_n_in <= '1';
192                         end if;
193                     else
194                         --name table 1 enable.
195                         nt0_ce_n_in <= '1';
196                         if (wr_n = '0') then
197                             --write
198                             nt1_ce_n_in <= clk;
199                         elsif (rd_n = '0') then 
200                             --read
201                             nt1_ce_n_in <= '0';
202                         else
203                             nt1_ce_n_in <= '1';
204                         end if;
205                     end if;
206                 end if; --if (nt_v_mirror = '1') then
207             else
208                 nt0_ce_n_in <= '1';
209                 nt1_ce_n_in <= '1';
210             end if;
211         else
212             nt0_ce_n_in <= '1';
213             nt1_ce_n_in <= '1';
214         end if; --if (v_addr(13) = '1') then
215     end process;
216
217 end rtl;
218