OSDN Git Service

test init value set modified.
[motonesfpga/motonesfpga.git] / simulation / ppu / ppu.vhd
1 library ieee;
2 use ieee.std_logic_1164.all;
3
4 entity ppu is 
5     port (  clk         : in std_logic;
6             ce_n        : in std_logic;
7             rst_n       : in std_logic;
8             r_nw        : 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;
12             rd_n        : out std_logic;
13             wr_n        : out std_logic;
14             ale         : 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)
23     );
24 end ppu;
25
26 architecture rtl of ppu is
27
28 component ppu_render
29     port (  clk         : in std_logic;
30             rst_n       : in std_logic;
31             vblank_n    : out std_logic;
32             rd_n        : out std_logic;
33             wr_n        : out std_logic;
34             ale         : 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);
47             r_nw            : in std_logic;
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)
54     );
55 end component;
56
57 component vga_ctl
58     port (  ppu_clk     : in std_logic;
59             vga_clk     : in std_logic;
60             rst_n       : 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)
71     );
72 end component;
73
74 component d_flip_flop
75     generic (
76             dsize : integer := 8
77             );
78     port (
79             clk     : in std_logic;
80             res_n   : in std_logic;
81             set_n   : in std_logic;
82             we_n    : in std_logic;
83             d       : in std_logic_vector (dsize - 1 downto 0);
84             q       : out std_logic_vector (dsize - 1 downto 0)
85         );
86 end component;
87
88 component counter_register
89     generic (
90         dsize       : integer := 8
91     );
92     port (  clk         : in std_logic;
93             rst_n       : in std_logic;
94             set_n       : in std_logic;
95             ce_n        : in std_logic;
96             d           : in std_logic_vector(dsize - 1 downto 0);
97             q           : out std_logic_vector(dsize - 1 downto 0)
98     );
99 end component;
100
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);
106
107 constant dsize     : integer := 8;
108
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";
117
118 signal clk_n            : std_logic;
119
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;
132
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);
145
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);
149
150 begin
151
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);
158
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);
163
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);
167
168     --PPU registers.
169     clk_n <= not clk;
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);
172
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);
175
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);
178
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);
183
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);
190
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);
197
198
199     clock_p : process (clk)
200     begin
201
202         if (clk'event and clk = '1') then
203             if (ce_n = '0') then
204                 --register set.
205                 if(cpu_addr = PPUCTRL) then
206                     ppu_ctrl_we_n <= '0';
207                 else
208                     ppu_ctrl_we_n <= '1';
209                 end if;
210
211                 if(cpu_addr = PPUMASK) then
212                     ppu_mask_we_n <= '0';
213                 else
214                     ppu_mask_we_n <= '1';
215                 end if;
216
217                 if(cpu_addr = PPUSTATUS) then
218                     ppu_status_we_n <= '0';
219                 else
220                     ppu_status_we_n <= '1';
221                 end if;
222
223                 if(cpu_addr = OAMADDR) then
224                     oam_addr_we_n <= '0';
225                 else
226                     oam_addr_we_n <= '1';
227                 end if;
228
229                 if(cpu_addr = OAMDATA) then
230                     oam_data_we_n <= '0';
231                 else
232                     oam_data_we_n <= '1';
233                 end if;
234
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';
240                     else
241                         ppu_scroll_y_we_n <= '0';
242                         ppu_scroll_x_we_n <= '1';
243                     end if;
244                 else
245                     ppu_scroll_x_we_n <= '1';
246                     ppu_scroll_y_we_n <= '1';
247                     ppu_scroll_cnt_ce_n <= '1';
248                 end if;
249
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);
255                         ale <= '1';
256                     else
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);
260                         ale <= '0';
261                     end if;
262                 else
263                     ppu_addr_cnt_ce_n <= '1';
264                     ppu_addr_we_n <= '1';
265                     ale <= '1';
266                 end if;
267
268                 if(cpu_addr = PPUDATA) then
269                     ppu_data_we_n <= '0';
270                     rd_n <= not r_nw;
271                     wr_n <= r_nw;
272                 else
273                     ppu_data_we_n <= '1';
274                     rd_n <= '1';
275                     wr_n <= '1';
276                 end if;
277
278             else
279                 ppu_ctrl_we_n    <= '1';
280                 ppu_mask_we_n    <= '1';
281                 ppu_status_we_n  <= '1';
282                 oam_bus_ce_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';
291
292                 ale <= 'Z';
293                 rd_n <= 'Z';
294                 wr_n <= 'Z';
295                 vram_ad <= (others => 'Z');
296                 vram_a <= (others => 'Z');
297             end if; --if (ce_n = '0') then
298         else
299
300         end if;--if (clk'event and clk = '1') then
301
302     end process;
303
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;
309 --    begin
310 --        wait for 7 us;
311 --
312 --        --fill palette teble.
313 --        plt_bus_ce_n <= '0';
314 --        plt_r_nw <= '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;
319 --        end loop;
320 --        plt_bus_ce_n <= '1';
321 --
322 --        ---TODO: for the time being...
323 --        plt_bus_ce_n <= 'Z';
324 --        plt_r_nw <= 'Z';
325 --        plt_addr <= (others => 'Z');
326 --        plt_data <= (others => 'Z');
327 --
328 --        wait;
329 --    end process;
330
331 end rtl;
332