2 use ieee.std_logic_1164.all;
5 port ( clk : in std_logic;
9 cpu_addr : in std_logic_vector (2 downto 0);
10 cpu_d : inout std_logic_vector (7 downto 0);
11 vblank_n : out std_logic;
15 vram_ad : inout std_logic_vector (7 downto 0);
16 vram_a : out std_logic_vector (13 downto 8);
17 vga_clk : in std_logic;
18 h_sync_n : out std_logic;
19 v_sync_n : out std_logic;
20 r : out std_logic_vector(3 downto 0);
21 g : out std_logic_vector(3 downto 0);
22 b : out std_logic_vector(3 downto 0)
26 architecture rtl of ppu is
29 port ( clk : in std_logic;
31 vblank_n : out std_logic;
35 vram_ad : inout std_logic_vector (7 downto 0);
36 vram_a : out std_logic_vector (13 downto 8);
37 pos_x : out std_logic_vector (8 downto 0);
38 pos_y : out std_logic_vector (8 downto 0);
39 r : out std_logic_vector (3 downto 0);
40 g : out std_logic_vector (3 downto 0);
41 b : out std_logic_vector (3 downto 0);
42 ppu_ctrl : in std_logic_vector (7 downto 0);
43 ppu_mask : in std_logic_vector (7 downto 0);
44 ppu_status : out std_logic_vector (7 downto 0);
45 ppu_scroll_x : in std_logic_vector (7 downto 0);
46 ppu_scroll_y : in std_logic_vector (7 downto 0);
48 oam_bus_ce_n : in std_logic;
49 oam_addr : in std_logic_vector (7 downto 0);
50 oam_data : inout std_logic_vector (7 downto 0);
51 plt_bus_ce_n : in std_logic;
52 plt_addr : in std_logic_vector (4 downto 0);
53 plt_data : inout std_logic_vector (5 downto 0)
58 port ( ppu_clk : in std_logic;
59 vga_clk : in std_logic;
61 pos_x : in std_logic_vector (8 downto 0);
62 pos_y : in std_logic_vector (8 downto 0);
63 nes_r : in std_logic_vector (3 downto 0);
64 nes_g : in std_logic_vector (3 downto 0);
65 nes_b : in std_logic_vector (3 downto 0);
66 h_sync_n : out std_logic;
67 v_sync_n : out std_logic;
68 r : out std_logic_vector(3 downto 0);
69 g : out std_logic_vector(3 downto 0);
70 b : out std_logic_vector(3 downto 0)
83 d : in std_logic_vector (dsize - 1 downto 0);
84 q : out std_logic_vector (dsize - 1 downto 0)
88 component counter_register
92 port ( clk : in std_logic;
96 d : in std_logic_vector(dsize - 1 downto 0);
97 q : out std_logic_vector(dsize - 1 downto 0)
101 signal pos_x : std_logic_vector (8 downto 0);
102 signal pos_y : std_logic_vector (8 downto 0);
103 signal nes_r : std_logic_vector (3 downto 0);
104 signal nes_g : std_logic_vector (3 downto 0);
105 signal nes_b : std_logic_vector (3 downto 0);
107 constant dsize : integer := 8;
109 constant PPUCTRL : std_logic_vector(2 downto 0) := "000";
110 constant PPUMASK : std_logic_vector(2 downto 0) := "001";
111 constant PPUSTATUS : std_logic_vector(2 downto 0) := "010";
112 constant OAMADDR : std_logic_vector(2 downto 0) := "011";
113 constant OAMDATA : std_logic_vector(2 downto 0) := "100";
114 constant PPUSCROLL : std_logic_vector(2 downto 0) := "101";
115 constant PPUADDR : std_logic_vector(2 downto 0) := "110";
116 constant PPUDATA : std_logic_vector(2 downto 0) := "111";
118 signal clk_n : std_logic;
120 signal ppu_ctrl_we_n : std_logic;
121 signal ppu_mask_we_n : std_logic;
122 signal ppu_status_we_n : std_logic;
123 signal oam_bus_ce_n : std_logic;
124 signal oam_addr_we_n : std_logic;
125 signal oam_data_we_n : std_logic;
126 signal ppu_scroll_x_we_n : std_logic;
127 signal ppu_scroll_y_we_n : std_logic;
128 signal ppu_scroll_cnt_ce_n : std_logic;
129 signal ppu_addr_we_n : std_logic;
130 signal ppu_addr_cnt_ce_n : std_logic;
131 signal ppu_data_we_n : std_logic;
133 signal ppu_ctrl : std_logic_vector (dsize - 1 downto 0);
134 signal ppu_mask : std_logic_vector (dsize - 1 downto 0);
135 signal ppu_status : std_logic_vector (dsize - 1 downto 0);
136 signal oam_addr : std_logic_vector (dsize - 1 downto 0);
137 signal oam_data : std_logic_vector (dsize - 1 downto 0);
138 signal ppu_scroll_x : std_logic_vector (dsize - 1 downto 0);
139 signal ppu_scroll_y : std_logic_vector (dsize - 1 downto 0);
140 signal ppu_scroll_cnt : std_logic_vector (0 downto 0);
141 signal ppu_addr : std_logic_vector (13 downto 0);
142 signal ppu_addr_in : std_logic_vector (13 downto 0);
143 signal ppu_addr_cnt : std_logic_vector (0 downto 0);
144 signal ppu_data : std_logic_vector (dsize - 1 downto 0);
146 signal plt_bus_ce_n : std_logic;
147 signal plt_addr : std_logic_vector (4 downto 0);
148 signal plt_data : std_logic_vector (5 downto 0);
152 render_inst : ppu_render port map (clk, rst_n, vblank_n,
153 rd_n, wr_n, ale, vram_ad, vram_a,
154 pos_x, pos_y, nes_r, nes_g, nes_b,
155 ppu_ctrl, ppu_mask, ppu_status, ppu_scroll_x, ppu_scroll_y,
156 r_nw, oam_bus_ce_n, oam_addr, oam_data,
157 plt_bus_ce_n, plt_addr, plt_data);
159 -- render_ad_buf : tri_state_buffer generic map (dsize)
160 -- port map ('0', render_vram_ad, vram_ad);
161 -- render_d_buf : tri_state_buffer generic map (6)
162 -- port map ('0', render_vram_a, vram_a);
164 vga_inst : vga_ctl port map (clk, vga_clk, rst_n,
165 pos_x, pos_y, nes_r, nes_g, nes_b,
166 h_sync_n, v_sync_n, r, g, b);
170 ppu_ctrl_inst : d_flip_flop generic map(dsize)
171 port map (clk_n, rst_n, '1', ppu_ctrl_we_n, cpu_d, ppu_ctrl);
173 ppu_mask_inst : d_flip_flop generic map(dsize)
174 port map (clk_n, rst_n, '1', ppu_mask_we_n, cpu_d, ppu_mask);
176 ppu_status_inst : d_flip_flop generic map(dsize)
177 port map (clk_n, rst_n, '1', ppu_status_we_n, cpu_d, ppu_status);
179 oma_addr_inst : d_flip_flop generic map(dsize)
180 port map (clk_n, rst_n, '1', oam_addr_we_n, cpu_d, oam_addr);
181 oma_data_inst : d_flip_flop generic map(dsize)
182 port map (clk_n, rst_n, '1', oam_data_we_n, cpu_d, oam_data);
184 ppu_scroll_x_inst : d_flip_flop generic map(dsize)
185 port map (clk_n, rst_n, '1', ppu_scroll_x_we_n, cpu_d, ppu_scroll_x);
186 ppu_scroll_y_inst : d_flip_flop generic map(dsize)
187 port map (clk_n, rst_n, '1', ppu_scroll_y_we_n, cpu_d, ppu_scroll_y);
188 ppu_scroll_cnt_inst : counter_register generic map (1)
189 port map (clk_n, rst_n, '1', ppu_scroll_cnt_ce_n, (others => '0'), ppu_scroll_cnt);
191 ppu_addr_inst : d_flip_flop generic map(14)
192 port map (clk_n, rst_n, '1', ppu_addr_we_n, ppu_addr_in, ppu_addr);
193 ppu_addr_cnt_inst : counter_register generic map (1)
194 port map (clk_n, rst_n, '1', ppu_addr_cnt_ce_n, (others => '0'), ppu_addr_cnt);
195 ppu_data_inst : d_flip_flop generic map(dsize)
196 port map (clk_n, rst_n, '1', ppu_data_we_n, cpu_d, ppu_data);
199 clock_p : process (clk)
202 if (clk'event and clk = '1') then
205 if(cpu_addr = PPUCTRL) then
206 ppu_ctrl_we_n <= '0';
208 ppu_ctrl_we_n <= '1';
211 if(cpu_addr = PPUMASK) then
212 ppu_mask_we_n <= '0';
214 ppu_mask_we_n <= '1';
217 if(cpu_addr = PPUSTATUS) then
218 ppu_status_we_n <= '0';
220 ppu_status_we_n <= '1';
223 if(cpu_addr = OAMADDR) then
224 oam_addr_we_n <= '0';
226 oam_addr_we_n <= '1';
229 if(cpu_addr = OAMDATA) then
230 oam_data_we_n <= '0';
232 oam_data_we_n <= '1';
235 if(cpu_addr = PPUSCROLL) then
236 ppu_scroll_cnt_ce_n <= '0';
237 if (ppu_scroll_cnt(0) = '0') then
238 ppu_scroll_x_we_n <= '0';
239 ppu_scroll_y_we_n <= '1';
241 ppu_scroll_y_we_n <= '0';
242 ppu_scroll_x_we_n <= '1';
245 ppu_scroll_x_we_n <= '1';
246 ppu_scroll_y_we_n <= '1';
247 ppu_scroll_cnt_ce_n <= '1';
250 if(cpu_addr = PPUADDR) then
251 ppu_addr_cnt_ce_n <= '0';
252 ppu_addr_we_n <= '0';
253 if (ppu_addr_cnt(0) = '0') then
254 ppu_addr_in <= cpu_d(5 downto 0) & ppu_addr(7 downto 0);
257 ppu_addr_in <= ppu_addr(13 downto 8) & cpu_d;
258 vram_ad <= ppu_addr(7 downto 0);
259 vram_a <= ppu_addr(13 downto 8);
263 ppu_addr_cnt_ce_n <= '1';
264 ppu_addr_we_n <= '1';
268 if(cpu_addr = PPUDATA) then
269 ppu_data_we_n <= '0';
273 ppu_data_we_n <= '1';
279 ppu_ctrl_we_n <= '1';
280 ppu_mask_we_n <= '1';
281 ppu_status_we_n <= '1';
283 oam_addr_we_n <= '1';
284 oam_data_we_n <= '1';
285 ppu_scroll_x_we_n <= '1';
286 ppu_scroll_y_we_n <= '1';
287 ppu_scroll_cnt_ce_n <= '1';
288 ppu_addr_we_n <= '1';
289 ppu_addr_cnt_ce_n <= '1';
290 ppu_data_we_n <= '1';
295 vram_ad <= (others => 'Z');
296 vram_a <= (others => 'Z');
297 end if; --if (ce_n = '0') then
300 end if;--if (clk'event and clk = '1') then
304 ----test init value set.
305 -- p_palette_init : process
306 -- variable i : integer := 0;
307 --use ieee.std_logic_arith.all;
308 --constant ppu_clk_time : time := 186 ns;
312 -- --fill palette teble.
313 -- plt_bus_ce_n <= '0';
315 -- for i in 0 to 32 loop
316 -- plt_addr <= conv_std_logic_vector(i, 5);
317 -- plt_data <= conv_std_logic_vector((i - 1) * 4 + 17, 6);
318 -- wait for ppu_clk_time;
320 -- plt_bus_ce_n <= '1';
322 -- ---TODO: for the time being...
323 -- plt_bus_ce_n <= 'Z';
325 -- plt_addr <= (others => 'Z');
326 -- plt_data <= (others => 'Z');