OSDN Git Service

ppu registers added.
[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             plt_bus_ce_n : in std_logic;
38             plt_r_nw    : in std_logic;
39             plt_addr    : in std_logic_vector (4 downto 0);
40             plt_data    : inout std_logic_vector (5 downto 0);
41             pos_x       : out std_logic_vector (8 downto 0);
42             pos_y       : out std_logic_vector (8 downto 0);
43             r           : out std_logic_vector (3 downto 0);
44             g           : out std_logic_vector (3 downto 0);
45             b           : out std_logic_vector (3 downto 0)
46     );
47 end component;
48
49 component vga_ctl
50     port (  ppu_clk     : in std_logic;
51             vga_clk     : in std_logic;
52             rst_n       : in std_logic;
53             pos_x       : in std_logic_vector (8 downto 0);
54             pos_y       : in std_logic_vector (8 downto 0);
55             nes_r       : in std_logic_vector (3 downto 0);
56             nes_g       : in std_logic_vector (3 downto 0);
57             nes_b       : in std_logic_vector (3 downto 0);
58             h_sync_n    : out std_logic;
59             v_sync_n    : out std_logic;
60             r           : out std_logic_vector(3 downto 0);
61             g           : out std_logic_vector(3 downto 0);
62             b           : out std_logic_vector(3 downto 0)
63     );
64 end component;
65
66 component d_flip_flop
67     generic (
68             dsize : integer := 8
69             );
70     port (
71             clk     : in std_logic;
72             res_n   : in std_logic;
73             set_n   : in std_logic;
74             we_n    : in std_logic;
75             d       : in std_logic_vector (dsize - 1 downto 0);
76             q       : out std_logic_vector (dsize - 1 downto 0)
77         );
78 end component;
79
80 component counter_register
81     generic (
82         dsize       : integer := 8
83     );
84     port (  clk         : in std_logic;
85             rst_n       : in std_logic;
86             set_n       : in std_logic;
87             ce_n        : in std_logic;
88             d           : in std_logic_vector(dsize - 1 downto 0);
89             q           : out std_logic_vector(dsize - 1 downto 0)
90     );
91 end component;
92
93 signal pos_x       : std_logic_vector (8 downto 0);
94 signal pos_y       : std_logic_vector (8 downto 0);
95 signal nes_r       : std_logic_vector (3 downto 0);
96 signal nes_g       : std_logic_vector (3 downto 0);
97 signal nes_b       : std_logic_vector (3 downto 0);
98
99 signal plt_bus_ce_n : std_logic;
100 signal plt_r_nw    : std_logic;
101 signal plt_addr    : std_logic_vector (4 downto 0);
102 signal plt_data    : std_logic_vector (5 downto 0);
103
104 constant dsize     : integer := 8;
105
106 constant PPUCTRL   : std_logic_vector(2 downto 0) := "000";
107 constant PPUMASK   : std_logic_vector(2 downto 0) := "001";
108 constant PPUSTATUS : std_logic_vector(2 downto 0) := "010";
109 constant OAMADDR   : std_logic_vector(2 downto 0) := "011";
110 constant OAMDATA   : std_logic_vector(2 downto 0) := "100";
111 constant PPUSCROLL : std_logic_vector(2 downto 0) := "101";
112 constant PPUADDR   : std_logic_vector(2 downto 0) := "110";
113 constant PPUDATA   : std_logic_vector(2 downto 0) := "111";
114
115 signal ppu_ctrl_we_n    : std_logic;
116 signal ppu_mask_we_n    : std_logic;
117 signal ppu_status_we_n  : std_logic;
118 signal oam_addr_we_n    : std_logic;
119 signal oam_data_we_n    : std_logic;
120 signal ppu_scroll_x_we_n    : std_logic;
121 signal ppu_scroll_y_we_n    : std_logic;
122 signal ppu_scroll_cnt_ce_n  : std_logic;
123 signal ppu_addr_we_n        : std_logic;
124 signal ppu_addr_cnt_ce_n    : std_logic;
125 signal ppu_data_we_n    : std_logic;
126
127 signal ppu_ctrl         : std_logic_vector (dsize - 1 downto 0);
128 signal ppu_mask         : std_logic_vector (dsize - 1 downto 0);
129 signal ppu_status       : std_logic_vector (dsize - 1 downto 0);
130 signal oam_addr         : std_logic_vector (dsize - 1 downto 0);
131 signal oam_data         : std_logic_vector (dsize - 1 downto 0);
132 signal ppu_scroll_x     : std_logic_vector (dsize - 1 downto 0);
133 signal ppu_scroll_y     : std_logic_vector (dsize - 1 downto 0);
134 signal ppu_scroll_cnt   : std_logic_vector (0 downto 0);
135 signal ppu_addr         : std_logic_vector (13 downto 0);
136 signal ppu_addr_in      : std_logic_vector (13 downto 0);
137 signal ppu_addr_cnt     : std_logic_vector (0 downto 0);
138 signal ppu_data         : std_logic_vector (dsize - 1 downto 0);
139
140 begin
141
142
143     render_inst : ppu_render port map (clk, rst_n, vblank_n, 
144             rd_n, wr_n, ale, vram_ad, vram_a,
145             plt_bus_ce_n, plt_r_nw, plt_addr, plt_data,
146             pos_x, pos_y, nes_r, nes_g, nes_b);
147
148     vga_inst : vga_ctl port map (clk, vga_clk, rst_n, 
149             pos_x, pos_y, nes_r, nes_g, nes_b,
150             h_sync_n, v_sync_n, r, g, b);
151
152     --PPU registers.
153     ppu_ctrl_inst : d_flip_flop generic map(dsize)
154             port map (clk, rst_n, '1', ppu_ctrl_we_n, cpu_d, ppu_ctrl);
155
156     ppu_mask_inst : d_flip_flop generic map(dsize)
157             port map (clk, rst_n, '1', ppu_mask_we_n, cpu_d, ppu_mask);
158
159     ppu_status_inst : d_flip_flop generic map(dsize)
160             port map (clk, rst_n, '1', ppu_status_we_n, cpu_d, ppu_status);
161
162     oma_addr_inst : d_flip_flop generic map(dsize)
163             port map (clk, rst_n, '1', oam_addr_we_n, cpu_d, oam_addr);
164     oma_data_inst : d_flip_flop generic map(dsize)
165             port map (clk, rst_n, '1', oam_data_we_n, cpu_d, oam_data);
166
167     ppu_scroll_x_inst : d_flip_flop generic map(dsize)
168             port map (clk, rst_n, '1', ppu_scroll_x_we_n, cpu_d, ppu_scroll_x);
169     ppu_scroll_y_inst : d_flip_flop generic map(dsize)
170             port map (clk, rst_n, '1', ppu_scroll_y_we_n, cpu_d, ppu_scroll_y);
171     ppu_scroll_cnt_inst : counter_register generic map (1)
172             port map (clk, rst_n, '1', ppu_scroll_cnt_ce_n, (others => '0'), ppu_scroll_cnt);
173
174     ppu_addr_inst : d_flip_flop generic map(14)
175             port map (clk, rst_n, '1', ppu_addr_we_n, ppu_addr_in, ppu_addr);
176     ppu_addr_cnt_inst : counter_register generic map (1)
177             port map (clk, rst_n, '1', ppu_addr_cnt_ce_n, (others => '0'), ppu_addr_cnt);
178     ppu_data_inst : d_flip_flop generic map(dsize)
179             port map (clk, rst_n, '1', ppu_data_we_n, cpu_d, ppu_data);
180
181
182     clock_p : process (clk)
183     begin
184
185         if (clk'event and clk = '1' and ce_n = '0') then
186             --register set.
187             if(cpu_addr = PPUCTRL) then
188                 ppu_ctrl_we_n <= '0';
189             else
190                 ppu_ctrl_we_n <= '1';
191             end if;
192
193             if(cpu_addr = PPUMASK) then
194                 ppu_mask_we_n <= '0';
195             else
196                 ppu_mask_we_n <= '1';
197             end if;
198
199             if(cpu_addr = PPUSTATUS) then
200                 ppu_status_we_n <= '0';
201             else
202                 ppu_status_we_n <= '1';
203             end if;
204
205             if(cpu_addr = OAMADDR) then
206                 oam_addr_we_n <= '0';
207             else
208                 oam_addr_we_n <= '1';
209             end if;
210
211             if(cpu_addr = OAMDATA) then
212                 oam_data_we_n <= '0';
213             else
214                 oam_data_we_n <= '1';
215             end if;
216
217             if(cpu_addr = PPUSCROLL) then
218                 ppu_scroll_cnt_ce_n <= '0';
219                 if (ppu_scroll_cnt(0) = '0') then
220                     ppu_scroll_x_we_n <= '0';
221                     ppu_scroll_y_we_n <= '1';
222                 else
223                     ppu_scroll_y_we_n <= '0';
224                     ppu_scroll_x_we_n <= '1';
225                 end if;
226             else
227                 ppu_scroll_x_we_n <= '1';
228                 ppu_scroll_y_we_n <= '1';
229                 ppu_scroll_cnt_ce_n <= '1';
230             end if;
231
232             if(cpu_addr = PPUADDR) then
233                 ppu_addr_cnt_ce_n <= '0';
234                 ppu_addr_we_n <= '0';
235                 if (ppu_addr_cnt(0) = '0') then
236                     ppu_addr_in <= ppu_addr(13 downto 8) & cpu_d;
237                 else
238                     ppu_addr_in <= cpu_d(5 downto 0) & ppu_addr(7 downto 0);
239                 end if;
240             else
241                 ppu_addr_cnt_ce_n <= '1';
242                 ppu_addr_we_n <= '1';
243             end if;
244
245             if(cpu_addr = PPUDATA) then
246                 ppu_data_we_n <= '0';
247             else
248                 ppu_data_we_n <= '1';
249             end if;
250
251         else
252
253         end if;
254
255     end process;
256
257 --test init value set.
258     p_palette_init : process
259     variable i : integer := 0;
260 use ieee.std_logic_arith.all;
261 constant ppu_clk_time : time := 186 ns;
262     begin
263         wait for 7 us;
264
265         --fill palette teble.
266         plt_bus_ce_n <= '0';
267         plt_r_nw <= '0';
268         for i in 0 to 32 loop
269             plt_addr <= conv_std_logic_vector(i, 5);
270             plt_data <= conv_std_logic_vector((i - 1) * 4 + 17, 6);
271             wait for ppu_clk_time;
272         end loop;
273         plt_bus_ce_n <= '1';
274
275         ---TODO: for the time being...
276         plt_bus_ce_n <= 'Z';
277         plt_r_nw <= 'Z';
278         plt_addr <= (others => 'Z');
279         plt_data <= (others => 'Z');
280
281         wait;
282     end process;
283
284 end rtl;
285