OSDN Git Service

bg transparent color set.
[motonesfpga/motonesfpga.git] / simulation / ppu / render.vhd
1 library ieee;
2 use ieee.std_logic_1164.all;
3 use ieee.std_logic_arith.conv_std_logic_vector;
4 use ieee.std_logic_unsigned.all;
5
6 entity ppu_render is 
7     port (  clk         : in std_logic;
8             rst_n       : in std_logic;
9             vblank_n    : out std_logic;
10             rd_n        : out std_logic;
11             wr_n        : out std_logic;
12             ale         : out std_logic;
13             vram_ad     : inout std_logic_vector (7 downto 0);
14             vram_a      : out std_logic_vector (13 downto 8);
15             plt_bus_ce_n : in std_logic;
16             plt_r_nw    : in std_logic;
17             plt_addr    : in std_logic_vector (4 downto 0);
18             plt_data    : inout std_logic_vector (7 downto 0);
19             pos_x       : out std_logic_vector (8 downto 0);
20             pos_y       : out std_logic_vector (8 downto 0);
21             r           : out std_logic_vector (3 downto 0);
22             g           : out std_logic_vector (3 downto 0);
23             b           : out std_logic_vector (3 downto 0)
24     );
25 end ppu_render;
26
27 architecture rtl of ppu_render is
28
29 component counter_register
30     generic (
31         dsize       : integer := 8
32     );
33     port (  clk         : in std_logic;
34             rst_n       : in std_logic;
35             set_n       : in std_logic;
36             ce_n        : in std_logic;
37             d           : in std_logic_vector(dsize - 1 downto 0);
38             q           : out std_logic_vector(dsize - 1 downto 0)
39     );
40 end component;
41
42 component shift_register
43     generic (
44         dsize : integer := 8;
45         shift : integer := 1
46     );
47     port (  clk         : in std_logic;
48             rst_n       : in std_logic;
49             ce_n        : in std_logic;
50             we_n        : in std_logic;
51             d           : buffer std_logic_vector(dsize - 1 downto 0);
52             q           : out std_logic_vector(dsize - 1 downto 0)
53     );
54 end component;
55
56 component d_flip_flop
57     generic (
58             dsize : integer := 8
59             );
60     port (  
61             clk     : in std_logic;
62             res_n   : in std_logic;
63             set_n   : in std_logic;
64             we_n    : in std_logic;
65             d       : in std_logic_vector (dsize - 1 downto 0);
66             q       : out std_logic_vector (dsize - 1 downto 0)
67         );
68 end component;
69
70 component tri_state_buffer
71     generic (
72             dsize : integer := 8
73             );
74     port (  
75             oe_n    : in std_logic;
76             d       : in std_logic_vector (dsize - 1 downto 0);
77             q       : out std_logic_vector (dsize - 1 downto 0)
78         );
79 end component;
80
81 component test_module_init_data
82     port (  clk             : in std_logic;
83             v_rd_n          : out std_logic;
84             v_wr_n          : out std_logic;
85             v_ale           : out std_logic;
86             v_ad            : out std_logic_vector (7 downto 0);
87             v_a             : out std_logic_vector (13 downto 8);
88             plt_bus_ce_n    : out std_logic;
89             plt_r_nw        : out std_logic;
90             plt_addr        : out std_logic_vector (4 downto 0);
91             plt_data        : out std_logic_vector (7 downto 0)
92     );
93 end component;
94
95 procedure d_print(msg : string) is
96 use std.textio.all;
97 use ieee.std_logic_textio.all;
98 variable out_l : line;
99 begin
100     write(out_l, msg);
101     writeline(output, out_l);
102 end  procedure;
103
104 function conv_hex8(ival : integer) return string is
105 variable tmp1, tmp2 : integer;
106 variable hex_chr: string (1 to 16) := "0123456789abcdef";
107 begin
108     tmp2 := (ival mod 16 ** 2) / 16 ** 1;
109     tmp1 := ival mod 16 ** 1;
110     return hex_chr(tmp2 + 1) & hex_chr(tmp1 + 1);
111 end;
112
113 function conv_hex8(ival : std_logic_vector) return string is
114 begin
115     return conv_hex8(conv_integer(ival));
116 end;
117
118 function conv_hex16(ival : integer) return string is
119 variable tmp1, tmp2 : integer;
120 variable hex_chr: string (1 to 16) := "0123456789abcdef";
121 begin
122     tmp2 := ival / 256;
123     tmp1 := ival mod 256;
124     return conv_hex8(tmp2) & conv_hex8(tmp1);
125 end;
126
127
128 constant X_SIZE       : integer := 9;
129 constant dsize        : integer := 8;
130 constant asize        : integer := 14;
131 constant HSCAN_MAX    : integer := 341;
132 constant VSCAN_MAX    : integer := 262;
133 constant HSCAN        : integer := 256;
134 constant VSCAN        : integer := 240;
135 constant HSCAN_NEXT_START    : integer := 320;
136 constant HSCAN_NEXT_EXTRA    : integer := 336;
137
138 subtype palette_data is std_logic_vector (dsize -1 downto 0);
139 type palette_array is array (0 to 15) of palette_data;
140 signal bg_palatte : palette_array := (others => (others => '0'));
141 signal sprite_palatte : palette_array := (others => (others => '0'));
142
143 subtype nes_color_data is std_logic_vector (11 downto 0);
144 type nes_color_array is array (0 to 63) of nes_color_data;
145 --ref: http://hlc6502.web.fc2.com/NesPal2.htm
146 constant nes_color_palette : nes_color_array := (
147         conv_std_logic_vector(16#787878#, 12), 
148         conv_std_logic_vector(16#2000B0#, 12), 
149         conv_std_logic_vector(16#2800B8#, 12), 
150         conv_std_logic_vector(16#6010A0#, 12), 
151         conv_std_logic_vector(16#982078#, 12), 
152         conv_std_logic_vector(16#B01030#, 12), 
153         conv_std_logic_vector(16#A03000#, 12), 
154         conv_std_logic_vector(16#784000#, 12), 
155         conv_std_logic_vector(16#485800#, 12), 
156         conv_std_logic_vector(16#386800#, 12), 
157         conv_std_logic_vector(16#386C00#, 12), 
158         conv_std_logic_vector(16#306040#, 12), 
159         conv_std_logic_vector(16#305080#, 12), 
160         conv_std_logic_vector(16#000000#, 12), 
161         conv_std_logic_vector(16#000000#, 12), 
162         conv_std_logic_vector(16#000000#, 12),
163         conv_std_logic_vector(16#B0B0B0#, 12), 
164         conv_std_logic_vector(16#4060F8#, 12), 
165         conv_std_logic_vector(16#4040FF#, 12), 
166         conv_std_logic_vector(16#9040F0#, 12), 
167         conv_std_logic_vector(16#D840C0#, 12), 
168         conv_std_logic_vector(16#D84060#, 12), 
169         conv_std_logic_vector(16#E05000#, 12), 
170         conv_std_logic_vector(16#C07000#, 12), 
171         conv_std_logic_vector(16#888800#, 12), 
172         conv_std_logic_vector(16#50A000#, 12), 
173         conv_std_logic_vector(16#48A810#, 12), 
174         conv_std_logic_vector(16#48A068#, 12), 
175         conv_std_logic_vector(16#4090C0#, 12), 
176         conv_std_logic_vector(16#000000#, 12), 
177         conv_std_logic_vector(16#000000#, 12), 
178         conv_std_logic_vector(16#000000#, 12),
179
180         conv_std_logic_vector(16#FFFFFF#, 12), 
181         conv_std_logic_vector(16#60A0FF#, 12), 
182         conv_std_logic_vector(16#5080FF#, 12), 
183         conv_std_logic_vector(16#A070FF#, 12), 
184         conv_std_logic_vector(16#F060FF#, 12), 
185         conv_std_logic_vector(16#FF60B0#, 12), 
186         conv_std_logic_vector(16#FF7830#, 12), 
187         conv_std_logic_vector(16#FFA000#, 12), 
188         conv_std_logic_vector(16#E8D020#, 12), 
189         conv_std_logic_vector(16#98E800#, 12), 
190         conv_std_logic_vector(16#70F040#, 12), 
191         conv_std_logic_vector(16#70E090#, 12), 
192         conv_std_logic_vector(16#60D0E0#, 12), 
193         conv_std_logic_vector(16#787878#, 12), 
194         conv_std_logic_vector(16#000000#, 12), 
195         conv_std_logic_vector(16#000000#, 12),
196         conv_std_logic_vector(16#FFFFFF#, 12), 
197         conv_std_logic_vector(16#90D0FF#, 12), 
198         conv_std_logic_vector(16#A0B8FF#, 12), 
199         conv_std_logic_vector(16#C0B0FF#, 12), 
200         conv_std_logic_vector(16#E0B0FF#, 12), 
201         conv_std_logic_vector(16#FFB8E8#, 12), 
202         conv_std_logic_vector(16#FFC8B8#, 12), 
203         conv_std_logic_vector(16#FFD8A0#, 12), 
204         conv_std_logic_vector(16#FFF090#, 12), 
205         conv_std_logic_vector(16#C8F080#, 12), 
206         conv_std_logic_vector(16#A0F0A0#, 12), 
207         conv_std_logic_vector(16#A0FFC8#, 12), 
208         conv_std_logic_vector(16#A0FFF0#, 12), 
209         conv_std_logic_vector(16#A0A0A0#, 12), 
210         conv_std_logic_vector(16#000000#, 12), 
211         conv_std_logic_vector(16#000000#, 12)
212         );
213
214 signal rst              : std_logic;
215 signal clk_n            : std_logic;
216
217 signal io_cnt           : std_logic_vector(0 downto 0);
218 signal io_oe_n          : std_logic;
219
220 signal render_x_en_n    : std_logic;
221 signal render_x_res_n   : std_logic;
222 signal render_y_en_n    : std_logic;
223 signal render_y_res_n   : std_logic;
224
225 signal cur_x            : std_logic_vector(X_SIZE - 1 downto 0);
226 signal cur_y            : std_logic_vector(X_SIZE - 1 downto 0);
227 signal next_x           : std_logic_vector(X_SIZE - 1 downto 0);
228 signal next_y           : std_logic_vector(X_SIZE - 1 downto 0);
229
230 signal nt_next_we_n     : std_logic;
231 signal nt_val           : std_logic_vector (dsize - 1 downto 0);
232 signal nt_next_val      : std_logic_vector (dsize - 1 downto 0);
233
234 signal attr_ce_n        : std_logic;
235 signal attr_we_n        : std_logic;
236 signal attr_in          : std_logic_vector (dsize - 1 downto 0);
237 signal attr_val         : std_logic_vector (dsize - 1 downto 0);
238
239 signal ptn_en_n         : std_logic;
240
241 signal ptn_l_next_we_n  : std_logic;
242 signal ptn_l_next_in    : std_logic_vector (dsize * 2 - 1 downto 0);
243 signal ptn_l_next_in_rev: std_logic_vector (dsize * 2 - 1 downto 0);
244 signal ptn_l_next_val   : std_logic_vector (dsize * 2 - 1 downto 0);
245 signal ptn_l_in         : std_logic_vector (dsize * 2 - 1 downto 0);
246 signal ptn_l_val        : std_logic_vector (dsize * 2 - 1 downto 0);
247
248 signal ptn_h_next_we_n  : std_logic;
249 signal ptn_h_next_in    : std_logic_vector (dsize * 2 - 1 downto 0);
250 signal ptn_h_next_in_rev: std_logic_vector (dsize * 2 - 1 downto 0);
251 signal ptn_h_next_val   : std_logic_vector (dsize * 2 - 1 downto 0);
252 signal ptn_h_val        : std_logic_vector (dsize * 2 - 1 downto 0);
253
254 signal vram_addr        : std_logic_vector (asize - 1 downto 0);
255 signal ptn_addr        : std_logic_vector (asize - 1 downto 0);
256
257 ----test init data.
258 signal init_ale         : std_logic;
259 signal init_rd_n        : std_logic;
260 signal init_wr_n        : std_logic;
261
262 signal init_plt_bus_ce_n : std_logic;
263 signal init_plt_r_nw    : std_logic;
264 signal init_plt_addr    : std_logic_vector (4 downto 0);
265 signal init_plt_data    : std_logic_vector (7 downto 0);
266
267 begin
268
269     rst <= not rst_n;
270     clk_n <= not clk;
271
272     render_x_en_n <= '0';
273
274 --    wr_n <= '1';
275 --    ale <= not cur_x(0) when rst_n = '1' else '1';
276 --    rd_n <= not cur_x(0) when rst_n = '1' else '1';
277
278     io_cnt_inst : counter_register generic map (1)
279             port map (clk, render_x_res_n, '1', '0', (others => '0'), io_cnt);
280
281     ale <= io_cnt(0) when rst_n = '1' else init_ale;
282     rd_n <= io_cnt(0) when rst_n = '1' else init_rd_n;
283     wr_n <= '1' when rst_n = '1' else init_wr_n;
284     io_oe_n <= not io_cnt(0) when rst_n = '1' else '1';
285
286     ---x pos is 8 cycle ahead of current pos.
287     next_x <= cur_x + "000010000" 
288                     when cur_x <  conv_std_logic_vector(HSCAN_NEXT_START, X_SIZE) else
289               cur_x + "011000000";
290     next_y <= cur_y 
291                     when cur_x <  conv_std_logic_vector(HSCAN_NEXT_START, X_SIZE) else
292               "000000000" 
293                     when cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE) else
294               cur_y + "000000001";
295
296     --current x,y pos
297     cur_x_inst : counter_register generic map (X_SIZE)
298             port map (clk_n, render_x_res_n, '1', 
299                     render_x_en_n, (others => '0'), cur_x);
300     cur_y_inst : counter_register generic map (X_SIZE)
301             port map (clk_n, render_y_res_n, '1', 
302                     render_y_en_n, (others => '0'), cur_y);
303
304     nt_next_inst : d_flip_flop generic map(dsize)
305             port map (clk_n, rst_n, '1', nt_next_we_n, vram_ad, nt_next_val);
306     nt_inst : d_flip_flop generic map(dsize)
307             port map (clk_n, rst_n, '1', nt_next_we_n, nt_next_val, nt_val);
308
309     attr_in <= vram_ad;
310     at_inst : shift_register generic map(dsize, 2)
311             port map (clk_n, rst_n, attr_ce_n, attr_we_n, attr_in, attr_val);
312
313
314     --chr rom data's bit is stored in opposite direction.
315     --reverse bit when loading...
316     ptn_l_next_in_rev <= vram_ad & ptn_l_next_val (dsize downto 1);
317     ptn_h_next_in_rev <= vram_ad & ptn_h_next_val (dsize downto 1);
318     bit_rev: for cnt in 0 to 7 generate
319         ptn_l_next_in(dsize * 2 - 1 - cnt) <= ptn_l_next_in_rev(dsize + cnt);
320         ptn_h_next_in(dsize * 2 - 1 - cnt) <= ptn_h_next_in_rev(dsize + cnt);
321     end generate;
322     ptn_l_next_in(dsize - 1 downto 0) <= ptn_l_next_in_rev(dsize - 1 downto 0);
323     ptn_h_next_in(dsize - 1 downto 0) <= ptn_h_next_in_rev(dsize - 1 downto 0);
324
325
326     ptn_en_n <= '0' when cur_x < conv_std_logic_vector(HSCAN_NEXT_EXTRA, X_SIZE) else
327                 '1';
328
329     ptn_l_next_inst : shift_register generic map(dsize * 2, 1)
330             port map (clk_n, rst_n, ptn_en_n, ptn_l_next_we_n, 
331                     ptn_l_next_in, ptn_l_next_val);
332
333     --2 bit shift restored to align with the ptn_h.
334     ptn_l_in <= ptn_l_next_val(13 downto 6) & ptn_l_val(8 downto 1);
335     ptn_l_inst : shift_register generic map(dsize * 2, 1)
336             port map (clk_n, rst_n, ptn_en_n, ptn_h_next_we_n, 
337                     ptn_l_in, ptn_l_val);
338
339     ptn_h_next_inst : shift_register generic map(dsize * 2, 1)
340             port map (clk_n, rst_n, ptn_en_n, ptn_h_next_we_n, 
341                     ptn_h_next_in, ptn_h_next_val);
342     ptn_h_val <= ptn_h_next_val;
343
344     vram_io_buf : tri_state_buffer generic map (dsize)
345             port map (io_oe_n, vram_addr(dsize - 1 downto 0), vram_ad);
346
347     vram_a_buf : tri_state_buffer generic map (6)
348             port map (rst, vram_addr(asize - 1 downto dsize), vram_a);
349
350     pos_x <= cur_x;
351     pos_y <= cur_y;
352
353     clk_p : process (rst_n, clk) 
354
355 procedure output_bg_rgb is
356 variable plt_addr : integer;
357 variable palette_index : integer;
358 begin
359     --firs t color in the palette is transparent color.
360     if ((ptn_l_val(0) or ptn_h_val(0)) = '1') then
361         plt_addr := conv_integer(attr_val(1 downto 0) & ptn_h_val(0) & ptn_l_val(0));
362         palette_index := conv_integer(bg_palatte(plt_addr));
363         b <= nes_color_palette(palette_index) (11 downto 8);
364         g <= nes_color_palette(palette_index) (7 downto 4);
365         r <= nes_color_palette(palette_index) (3 downto 0);
366
367 --        d_print("output_bg_rgb");
368 --        d_print("pht h:" & conv_hex8(ptn_h_val));
369 --        d_print("pht l:" & conv_hex8(ptn_l_val));
370 --        d_print("rgb:" &
371 --        conv_hex8(nes_color_palette(palette_index) (3 downto 0)) & "," & 
372 --        conv_hex8(nes_color_palette(palette_index) (7 downto 4)) & "," & 
373 --        conv_hex8(nes_color_palette(palette_index) (11 downto 8)));
374     else
375         b <= (others => '0');
376         g <= (others => '0');
377         r <= (others => '0');
378     end if; --if ((ptn_l_val(0) or ptn_h_val(0)) = '1') then
379 end;
380
381     begin
382         if (rst_n = '0') then
383             render_x_res_n <= '0';
384             render_y_res_n <= '0';
385             nt_next_we_n <= '1';
386         else
387             if (clk'event) then
388                 --x pos reset.
389                 if (clk = '0' and 
390                         cur_x = conv_std_logic_vector(HSCAN_MAX - 1, X_SIZE)) then
391                     render_x_res_n <= '0';
392
393                     --y pos reset.
394                     if (cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE)) then
395                         render_y_res_n <= '0';
396                     else
397                         render_y_res_n <= '1';
398                     end if;
399                 else
400                     render_x_res_n <= '1';
401                     render_y_res_n <= '1';
402                 end if;
403             end if; --if (clk'event) then
404
405             if (clk'event and clk = '1') then
406                 --y pos increment.
407                 if (cur_x = conv_std_logic_vector(HSCAN_MAX - 1, X_SIZE)) then
408                     render_y_en_n <= '0';
409                 else
410                     render_y_en_n <= '1';
411                 end if;
412             end if; --if (clk'event) then
413
414             if (clk'event and clk = '0') then
415                 d_print("-");
416             end if;
417
418             if (clk'event and clk = '1') then
419                 d_print("*");
420
421                 --visible area and last pixel for the next sirst pixel.
422                 if (cur_x <= conv_std_logic_vector(HSCAN, X_SIZE) or 
423                         (cur_x > conv_std_logic_vector(HSCAN_NEXT_START, X_SIZE) and 
424                          cur_x < conv_std_logic_vector(HSCAN_NEXT_EXTRA, X_SIZE) )) 
425                     then
426
427                     ----fetch next tile byte.
428                     if (cur_x (2 downto 0) = "001" ) then
429                         --vram addr is incremented every 8 cycle.
430                         --name table at 0x2000
431                         vram_addr(9 downto 0) 
432                             <= next_y(dsize - 1 downto 3) 
433                                 & next_x(dsize - 1 downto 3);
434                         vram_addr(asize - 1 downto 10) <= "1000";
435                     end if;
436                     if (cur_x (2 downto 0) = "010" ) then
437                         nt_next_we_n <= '0';
438                     else
439                         nt_next_we_n <= '1';
440                     end if;
441
442                     ----fetch attr table byte.
443                     if (cur_x (4 downto 0) = "00011" ) then
444                         --attribute table is loaded every 32 cycle.
445                         --attr table at 0x23c0
446                         vram_addr(dsize - 1 downto 0) 
447                             <= "110" & cur_x(dsize - 1 downto 3);
448                         vram_addr(asize - 1 downto dsize) <= "100011";
449                     end if;--if (cur_x (2 downto 0) = "010" ) then
450                     if (cur_x (4 downto 0) = "00100" ) then
451                         attr_we_n <= '0';
452                     else
453                         attr_we_n <= '1';
454                     end if;
455                     ---attribute is shifted every 16 bit.
456                     if (cur_x (3 downto 0) = "0100" ) then
457                         attr_ce_n <= '0';
458                     else
459                         attr_ce_n <= '1';
460                     end if;
461
462                     ----fetch pattern table low byte.
463                     if (cur_x (2 downto 0) = "101" ) then
464                         --vram addr is incremented every 8 cycle.
465                         vram_addr <= "01" & nt_next_val(dsize - 1 downto 0) 
466                                             & "0"  & next_y(2  downto 0);
467                     end if;--if (cur_x (2 downto 0) = "100" ) then
468                     if (cur_x (2 downto 0) = "110" ) then
469                         ptn_l_next_we_n <= '0';
470                     else
471                         ptn_l_next_we_n <= '1';
472                     end if;
473
474                     ----fetch pattern table high byte.
475                     if (cur_x (2 downto 0) = "111" ) then
476                         --vram addr is incremented every 8 cycle.
477                         vram_addr <= "01" & nt_next_val(dsize - 1 downto 0) 
478                                             & "0"  & next_y(2  downto 0) + 8;
479                     end if; --if (cur_x (2 downto 0) = "110" ) then
480                     if (cur_x (2 downto 0) = "000") then
481                         ptn_h_next_we_n <= '0';
482                     else
483                         ptn_h_next_we_n <= '1';
484                     end if;--if (cur_x (2 downto 0) = "001" ) then
485
486                 end if; --if (cur_x <= conv_std_logic_vector(HSCAN, X_SIZE) or 
487
488     d_print("cur_x: " & conv_hex16(conv_integer(cur_x)));
489     d_print("cur_y: " & conv_hex16(conv_integer(cur_y)));
490     d_print("next_x: " & conv_hex16(conv_integer(next_x)));
491     d_print("nt_next_val: " & conv_hex8(conv_integer(nt_next_val)));
492     d_print("vram_addr: " & conv_hex16(conv_integer(vram_addr)));
493
494                 --output visible area only.
495                 if ((cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and
496                     (cur_y < conv_std_logic_vector(VSCAN, X_SIZE))) then
497                     --output image.
498                     output_bg_rgb;
499                 end if;
500
501             end if; --if (clk'event and clk = '1') then
502         end if;--if (rst_n = '0') then
503     end process;
504
505 --    ------------------- palette access process -------------------
506 --    plt_rw : process (plt_bus_ce_n, plt_r_nw, plt_addr, plt_data)
507 --    begin
508 --        if (plt_bus_ce_n = '0') then
509 --            if (plt_r_nw = '0') then
510 --                if (plt_addr(4) = '0') then
511 --                    bg_palatte(conv_integer(plt_addr)) <= plt_data;
512 --                else
513 --                    sprite_palatte(conv_integer(plt_addr)) <= plt_data;
514 --                end if;
515 --            end if;
516 --
517 --            if (plt_r_nw = '1') then
518 --                if (plt_addr(4) = '0') then
519 --                    plt_data <= bg_palatte(conv_integer(plt_addr));
520 --                else
521 --                    plt_data <= sprite_palatte(conv_integer(plt_addr));
522 --                end if;
523 --            end if;
524 --        else
525 --            plt_data <= (others => 'Z');
526 --        end if;
527 --    end process;
528
529     -----fill test data during the reset.....
530     init_data : test_module_init_data 
531         port map (clk, init_rd_n, init_wr_n, init_ale, vram_ad, vram_a,
532                 init_plt_bus_ce_n, init_plt_r_nw, init_plt_addr, init_plt_data
533                 );
534
535     ----- test initial value stting.
536     plt_init_w : process (init_plt_bus_ce_n, init_plt_r_nw, 
537                          init_plt_addr, init_plt_data)
538     begin
539         if (init_plt_bus_ce_n = '0') then
540             if (init_plt_r_nw = '0') then
541                 if (init_plt_addr(4) = '0') then
542 --                    d_print("dummy addr:" & conv_hex8(conv_integer(init_plt_addr)));
543 --                    d_print("plt val:" & conv_hex8(conv_integer(init_plt_data)));
544                     bg_palatte(conv_integer(init_plt_addr)) <= init_plt_data;
545                 end if;
546             end if;
547         end if;
548     end process;
549
550 end rtl;
551
552
553
554 ------------------------------------------------------
555 ------------------------------------------------------
556 ------------------------------------------------------
557 ------------------------------------------------------
558 --       initialize with dummy data
559 ------------------------------------------------------
560 ------------------------------------------------------
561 ------------------------------------------------------
562 ------------------------------------------------------
563 library IEEE;
564 use IEEE.std_logic_1164.all;
565 use ieee.std_logic_arith.all;
566
567 entity test_module_init_data is
568     port (  clk             : in std_logic;
569             v_rd_n          : out std_logic;
570             v_wr_n          : out std_logic;
571             v_ale           : out std_logic;
572             v_ad            : out std_logic_vector (7 downto 0);
573             v_a             : out std_logic_vector (13 downto 8);
574             plt_bus_ce_n    : out std_logic;
575             plt_r_nw        : out std_logic;
576             plt_addr        : out std_logic_vector (4 downto 0);
577             plt_data        : out std_logic_vector (7 downto 0)
578     );
579 end test_module_init_data;
580
581 architecture stimulus of test_module_init_data is
582
583     constant ppu_clk : time := 186 ns;
584     constant size8 : integer := 8;
585     constant size16 : integer := 16;
586     constant size14 : integer := 14;
587
588     signal v_addr       : std_logic_vector (size14 - 1 downto 0);
589
590 begin
591
592     v_ad <= v_addr(size8 - 1 downto 0);
593     v_a <= v_addr(size14 - 1 downto size8);
594
595     -----test for vram/chr-rom
596     p_vram_init : process
597     variable i : integer := 0;
598     variable tmp : std_logic_vector (size8 - 1 downto 0);
599     constant loopcnt : integer := 15;
600     begin
601
602         ---dummy power up wait (same amount of time as testbench)
603         wait for 7 us;
604
605         --copy from chr rom to name tbl.
606         for i in 0 to loopcnt loop
607             --write name tbl #0
608             v_ale <= '1';
609             v_rd_n <= '1';
610             v_wr_n <= '1';
611             v_addr <= conv_std_logic_vector(16#2000# + i, size14);
612             wait for ppu_clk;
613             v_addr(7 downto 0) <= (others => 'Z');
614             v_ale <= '0';
615             v_rd_n <= '1';
616             v_wr_n <= '0';
617             ---bg start from 0.
618             v_addr(7 downto 0) <= conv_std_logic_vector(i + 32, size8);
619             wait for ppu_clk;
620
621             --write attr tbl #0
622             v_ale <= '1';
623             v_rd_n <= '1';
624             v_wr_n <= '1';
625             v_addr <= conv_std_logic_vector(16#23c0# + i, size14);
626             wait for ppu_clk;
627             v_addr(7 downto 0) <= (others => 'Z');
628             v_ale <= '0';
629             v_rd_n <= '1';
630             v_wr_n <= '0';
631             v_addr(7 downto 0) <= conv_std_logic_vector(16#a0# + i, size8);
632             wait for ppu_clk;
633         end loop;
634
635         v_addr <= (others => 'Z');
636
637         wait;
638     end process;
639
640     p_palette_init : process
641     variable i : integer := 0;
642     begin
643         wait for 7 us;
644
645         --fill palette teble.
646         plt_bus_ce_n <= '0';
647         plt_r_nw <= '0';
648         for i in 0 to 32 loop
649             plt_addr <= conv_std_logic_vector(i, 5);
650             plt_data <= conv_std_logic_vector(i, 8);
651             wait for ppu_clk;
652         end loop;
653
654         plt_bus_ce_n <= '1';
655         plt_data <= (others => 'Z');
656
657         wait;
658     end process;
659
660 end stimulus ;
661