1 -------------------------------------------------------------
\r
2 -------------------------------------------------------------
\r
3 -------------- VGA RGB Output Control w/ SDRAM --------------
\r
4 -------------------------------------------------------------
\r
5 -------------------------------------------------------------
\r
9 use ieee.std_logic_1164.all;
10 use ieee.std_logic_unsigned.conv_integer;
11 use ieee.std_logic_arith.conv_std_logic_vector;
12 use work.motonesfpga_common.all;
13 use ieee.std_logic_unsigned.all;
\r
17 signal dbg_vga_x : out std_logic_vector (9 downto 0);
\r
18 signal dbg_vga_y : out std_logic_vector (9 downto 0);
\r
19 signal dbg_nes_x : out std_logic_vector(7 downto 0);
\r
20 signal dbg_nes_x_old : out std_logic_vector(7 downto 0);
\r
21 signal dbg_sw_state : out std_logic_vector(2 downto 0);
\r
23 signal dbg_f_in : out std_logic_vector(11 downto 0);
\r
24 signal dbg_f_out : out std_logic_vector(11 downto 0);
\r
25 signal dbg_f_cnt : out std_logic_vector(7 downto 0);
\r
26 signal dbg_f_rd, dbg_f_wr, dbg_f_emp, dbg_f_ful
\r
28 signal dbg_bst_cnt : out std_logic_vector(7 downto 0);
\r
30 ppu_clk : in std_logic;
31 vga_clk : in std_logic;
\r
32 mem_clk : in std_logic;
\r
34 pos_x : in std_logic_vector (8 downto 0);
35 pos_y : in std_logic_vector (8 downto 0);
36 nes_r : in std_logic_vector (3 downto 0);
37 nes_g : in std_logic_vector (3 downto 0);
38 nes_b : in std_logic_vector (3 downto 0);
39 h_sync_n : out std_logic;
40 v_sync_n : out std_logic;
41 r : out std_logic_vector(3 downto 0);
42 g : out std_logic_vector(3 downto 0);
43 b : out std_logic_vector(3 downto 0);
46 wbs_adr_i : out std_logic_vector (21 downto 0); --Address (Bank, Row, Col)
\r
47 wbs_dat_i : out std_logic_vector (15 downto 0); --Data In (16 bits)
\r
48 wbs_we_i : out std_logic; --Write Enable
\r
49 wbs_tga_i : out std_logic_vector (7 downto 0); --Address Tag : Read/write burst length-1 (0 represents 1 word, FF represents 256 words)
\r
50 wbs_cyc_i : out std_logic; --Cycle Command from interface
\r
51 wbs_stb_i : out std_logic; --Strobe Command from interface
\r
52 wbs_dat_o : in std_logic_vector (15 downto 0); --Data Out (16 bits)
\r
53 wbs_stall_o : in std_logic; --Slave is not ready to receive new data
\r
54 wbs_err_o : in std_logic; --Error flag: OOR Burst. Burst length is greater that 256-column address
\r
55 wbs_ack_o : in std_logic --When Read Burst: DATA bus must be valid in this cycle
\r
59 architecture rtl of vga_ctl is
61 component counter_register
66 port ( clk : in std_logic;
70 d : in std_logic_vector(dsize - 1 downto 0);
71 q : out std_logic_vector(dsize - 1 downto 0)
75 component d_flip_flop
\r
77 dsize : integer := 8
\r
81 res_n : in std_logic;
\r
82 set_n : in std_logic;
\r
83 we_n : in std_logic;
\r
84 d : in std_logic_vector (dsize - 1 downto 0);
\r
85 q : out std_logic_vector (dsize - 1 downto 0)
\r
89 component sdram_write_fifo
\r
92 aclr : IN STD_LOGIC ;
\r
93 clock : IN STD_LOGIC ;
\r
94 data : IN STD_LOGIC_VECTOR (11 DOWNTO 0);
\r
95 rdreq : IN STD_LOGIC ;
\r
96 wrreq : IN STD_LOGIC ;
\r
97 empty : OUT STD_LOGIC ;
\r
98 full : OUT STD_LOGIC ;
\r
99 q : OUT STD_LOGIC_VECTOR (11 DOWNTO 0);
\r
100 usedw : OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
\r
104 --------- screen constant -----------
105 constant VGA_W : integer := 640;
106 constant VGA_H : integer := 480;
107 constant VGA_W_MAX : integer := 800;
108 constant VGA_H_MAX : integer := 525;
109 constant H_SP : integer := 95;
110 constant H_BP : integer := 48;
111 constant H_FP : integer := 15;
112 constant V_SP : integer := 2;
113 constant V_BP : integer := 33;
114 constant V_FP : integer := 10;
116 constant NES_W : integer := 256;
\r
117 constant NES_H : integer := 240;
\r
120 --------- signal declaration -----------
\r
121 signal vga_x : std_logic_vector (9 downto 0);
122 signal vga_y : std_logic_vector (9 downto 0);
123 signal x_res_n : std_logic;
\r
124 signal y_res_n : std_logic;
\r
125 signal y_en_n : std_logic;
\r
127 signal cnt_clk : std_logic;
\r
128 signal mem_clk_n : std_logic;
\r
130 --signal mem_cnt : std_logic_vector (4 downto 0);
\r
132 signal count5_res_n : std_logic;
\r
133 signal count5 : std_logic_vector(2 downto 0);
\r
134 signal nes_x_en_n : std_logic;
\r
135 signal nes_x : std_logic_vector(7 downto 0);
\r
137 signal dram_col_we_n : std_logic;
\r
138 signal dram_col : std_logic_vector(15 downto 0);
\r
140 signal pos_x_we_n : std_logic;
\r
141 signal pos_x_old : std_logic_vector(8 downto 0);
\r
142 signal nes_x_we_n : std_logic;
\r
143 signal nes_x_old : std_logic_vector(7 downto 0);
\r
146 signal rst : std_logic;
\r
147 signal f_in : std_logic_vector(11 downto 0);
\r
148 signal f_out : std_logic_vector(11 downto 0);
\r
149 signal f_val : std_logic_vector(11 downto 0);
\r
150 signal f_cnt : std_logic_vector(7 downto 0);
\r
151 signal f_val_we_n : std_logic;
\r
154 signal sdram_write_addr : std_logic_vector (21 downto 0);
\r
155 signal sdram_addr_inc_n : std_logic;
\r
156 signal sdram_addr_res_n : std_logic;
\r
157 signal bst_wr_cnt : std_logic_vector (7 downto 0);
\r
158 signal bst_wr_cnt_we_n : std_logic;
\r
160 signal f_rd, f_wr, f_emp, f_ful
\r
163 constant sw_idle : std_logic_vector(2 downto 0) := "000";
\r
164 constant sw_pop_fifo : std_logic_vector(2 downto 0) := "001";
\r
165 constant sw_write : std_logic_vector(2 downto 0) := "010";
\r
166 constant sw_write_ack : std_logic_vector(2 downto 0) := "011";
\r
167 constant sw_write_burst : std_logic_vector(2 downto 0) := "100";
\r
168 constant sw_write_burst_last : std_logic_vector(2 downto 0) := "101";
\r
170 signal sw_state : std_logic_vector(2 downto 0);
\r
172 constant SDRAM_READ_WAIT_CNT : integer := 10;
\r
175 ---DE1 base clock 50 MHz
\r
176 ---motones sim project uses following clock.
\r
177 --cpu clock = base clock / 24 = 2.08 MHz (480 ns / cycle)
\r
178 --ppu clock = base clock / 8
\r
179 --vga clock = base clock / 2
\r
180 --sdram clock = 133.333 MHz
\r
183 dbg_vga_x <= vga_x ;
\r
184 --dbg_vga_y <= "0" & pos_x_old;
\r
185 dbg_vga_y <= vga_y ;
\r
186 dbg_nes_x <= nes_x ;
\r
187 dbg_nes_x_old <= nes_x_old;
\r
188 dbg_sw_state <= sw_state ;
\r
191 dbg_f_out <= f_out ;
\r
192 dbg_f_cnt <= f_cnt ;
\r
193 dbg_bst_cnt <= bst_wr_cnt ;
\r
196 dbg_f_emp <= f_emp ;
\r
197 dbg_f_ful <= f_ful ;
\r
201 cnt_clk <= not vga_clk;
\r
202 mem_clk_n <= not mem_clk;
\r
205 x_inst : counter_register generic map (10, 1)
206 port map (cnt_clk , x_res_n, '0', '1', (others => '0'), vga_x);
208 y_inst : counter_register generic map (10, 1)
\r
209 port map (cnt_clk , y_res_n, y_en_n, '1', (others => '0'), vga_y);
\r
211 nes_x_inst : counter_register generic map (8, 1)
\r
212 port map (vga_clk, x_res_n, nes_x_en_n, '1', (others => '0'), nes_x);
\r
214 nes_x_old_inst: d_flip_flop generic map (8)
\r
215 port map (mem_clk_n, rst_n, '1', nes_x_we_n, nes_x, nes_x_old);
\r
217 count5_inst : counter_register generic map (3, 1)
\r
218 port map (cnt_clk, count5_res_n, '0', '1', (others => '0'), count5);
\r
220 pos_x_old_inst: d_flip_flop generic map (9)
\r
221 port map (mem_clk_n, rst_n, '1', pos_x_we_n, pos_x, pos_x_old);
\r
223 fifo_inst : sdram_write_fifo port map
\r
224 (rst, mem_clk_n, f_in, f_rd, f_wr, f_emp, f_ful, f_out, f_cnt);
\r
226 sdram_wr_addr_inst : counter_register generic map (22, 1)
\r
227 port map (mem_clk, sdram_addr_res_n, sdram_addr_inc_n, '1', (others => '0'), sdram_write_addr);
\r
229 fifo_bst_wr_cnt : counter_register generic map (8, 255)
\r
230 port map (mem_clk, sdram_addr_res_n, sdram_addr_inc_n, bst_wr_cnt_we_n, f_cnt, bst_wr_cnt);
\r
232 fifo_data_inst: d_flip_flop generic map (12)
\r
233 port map (mem_clk, rst_n, '1', f_val_we_n, f_out, f_val);
\r
235 -- dram_rd_inst : d_flip_flop generic map (16)
\r
236 -- port map (mem_clk, rst_n, '1', dram_col_we_n, wbs_dat_o, dram_col);
\r
238 pos_x_p : process (rst_n, mem_clk)
\r
240 if (rst_n = '0') then
\r
242 elsif (rising_edge(mem_clk)) then
\r
243 if (pos_x /= pos_x_old) then
\r
251 nes_x_p : process (rst_n, mem_clk)
\r
253 if (rst_n = '0') then
\r
255 elsif (rising_edge(mem_clk)) then
\r
256 if (nes_x /= nes_x_old) then
\r
264 f_in <= nes_r & nes_g & nes_b;
\r
265 fifo_w_p : process (rst_n, mem_clk)
\r
267 if (rst_n = '0') then
\r
269 elsif (rising_edge(mem_clk)) then
\r
271 if (pos_x < conv_std_logic_vector(NES_W, 9) and
\r
272 pos_y < conv_std_logic_vector(NES_H, 9)) then
\r
273 if (pos_x /= pos_x_old) then
\r
274 --add data to fifo when pos_x is changed.
\r
281 end if; --pos_x < conv_std_logic_vector(NES_W, 9) and pos_y < conv_std_logic_vector(NES_H, 9)
\r
285 sw_state_p : process (rst_n, mem_clk)
\r
287 if (rst_n = '0') then
\r
288 sw_state <= sw_idle;
\r
289 elsif (rising_edge(mem_clk)) then
\r
290 if (vga_x >= conv_std_logic_vector(VGA_W , 10)
\r
291 or vga_y >= conv_std_logic_vector(VGA_H, 10)) then
\r
292 --write to sdram status
\r
294 when sw_idle => --0: idle...
\r
295 if (f_cnt < "00001000") then --wait until fifo > 8
\r
296 sw_state <= sw_idle;
\r
298 sw_state <= sw_pop_fifo;
\r
301 when sw_pop_fifo => --1: initialize writing...
\r
302 sw_state <= sw_write;
\r
304 when sw_write => --2: start writing
\r
305 sw_state <= sw_write_ack;
\r
307 when sw_write_ack => --3: push first data
\r
308 sw_state <= sw_write_burst;
\r
310 when sw_write_burst => --4: repeat...
\r
311 if (bst_wr_cnt > "00000001") then -- busrt write
\r
312 sw_state <= sw_write_burst;
\r
314 sw_state <= sw_write_burst_last;
\r
317 when others => --other and burst last...
\r
318 sw_state <= sw_idle;
\r
322 sw_state <= sw_idle;
\r
323 end if; --if (vga_x >=conv_std_
\r
327 f_rd <= '0' when rst_n = '0' else
\r
328 '1' when (sw_state = sw_pop_fifo) else
\r
329 '1' when (sw_state = sw_write_burst) else
\r
331 f_val_we_n <= not f_rd;
\r
332 sdram_addr_inc_n <= not f_rd;
\r
334 sdram_addr_res_n <= rst_n;
\r
335 bst_wr_cnt_we_n <= '1' when rst_n = '0' else
\r
336 '0' when sw_state = sw_idle else
\r
338 wbs_adr_i <= sdram_write_addr - 1;
\r
339 wbs_dat_i <= "0000" & f_val;
\r
340 wbs_tga_i <= bst_wr_cnt + 1;
\r
341 wbs_cyc_i <= '0' when rst_n = '0' else
\r
342 '1' when sw_state >= sw_write else
\r
344 wbs_stb_i <= '0' when rst_n = '0' else
\r
345 '1' when sw_state >= sw_write else
\r
347 wbs_we_i <= '0' when rst_n = '0' else
\r
348 '1' when sw_state >= sw_write else
\r
351 ----------- vga position conversion 640 to 256
\r
352 dram_latch_p : process (rst_n, vga_clk)
\r
354 if (rst_n = '0') then
\r
357 elsif (falling_edge(vga_clk)) then
\r
359 if (count5 = "001" or count5 = "011") then
\r
367 vga_out_p : process (rst_n, vga_clk)
369 if (rst_n = '0') then
378 b<=(others => '0');
\r
380 elsif (rising_edge(vga_clk)) then
382 if (vga_x = conv_std_logic_vector(VGA_W_MAX, 10)) then
386 if (vga_y = conv_std_logic_vector(VGA_H_MAX, 10)) then
397 --sync signal assert.
398 if (vga_x >= conv_std_logic_vector((VGA_W + H_FP) , 10) and
399 vga_x < conv_std_logic_vector((VGA_W + H_FP + H_SP) , 10)) then
405 if (vga_y >= conv_std_logic_vector((VGA_H + V_FP) , 10) and
406 vga_y < conv_std_logic_vector((VGA_H + V_FP + V_SP) , 10)) then
412 if (vga_y <=conv_std_logic_vector((VGA_H) , 10)) then
413 if (vga_x < conv_std_logic_vector((VGA_W) , 10)) then
414 r<= dram_col(11 downto 8);
415 g<= dram_col(7 downto 4);
416 b<= dram_col(3 downto 0);
\r
428 if (vga_x = conv_std_logic_vector(VGA_W_MAX, 10)) then
\r
429 count5_res_n <= '0';
\r
430 elsif (count5 = "100") then
\r
431 count5_res_n <= '0';
\r
433 count5_res_n <= '1';
\r
443 -------------------------------------------------------------
\r
444 -------------------------------------------------------------
\r
445 ----------------- Dummy PPU image generator -----------------
\r
446 -------------------------------------------------------------
\r
447 -------------------------------------------------------------
\r
451 use ieee.std_logic_1164.all;
\r
452 use ieee.std_logic_unsigned.all;
\r
453 use ieee.std_logic_arith.conv_std_logic_vector;
\r
455 entity dummy_ppu is
\r
456 port ( ppu_clk : in std_logic;
\r
457 rst_n : in std_logic;
\r
458 pos_x : buffer std_logic_vector (8 downto 0);
\r
459 pos_y : buffer std_logic_vector (8 downto 0);
\r
460 nes_r : buffer std_logic_vector (3 downto 0);
\r
461 nes_g : buffer std_logic_vector (3 downto 0);
\r
462 nes_b : buffer std_logic_vector (3 downto 0)
\r
467 architecture rtl of dummy_ppu is
\r
469 component counter_register
\r
471 dsize : integer := 8;
\r
474 port ( clk : in std_logic;
\r
475 rst_n : in std_logic;
\r
476 ce_n : in std_logic;
\r
477 we_n : in std_logic;
\r
478 d : in std_logic_vector(dsize - 1 downto 0);
\r
479 q : out std_logic_vector(dsize - 1 downto 0)
\r
483 signal x_res_n, y_res_n, y_en_n : std_logic;
\r
484 signal cnt_clk : std_logic;
\r
485 signal frame_en_n : std_logic;
\r
488 signal frame_cnt : std_logic_vector(7 downto 0);
\r
492 cnt_clk <= not ppu_clk;
\r
493 x_inst : counter_register generic map (9, 1)
\r
494 port map (cnt_clk , x_res_n, '0', '1', (others => '0'), pos_x);
\r
495 y_inst : counter_register generic map (9, 1)
\r
496 port map (cnt_clk , y_res_n, y_en_n, '1', (others => '0'), pos_y);
\r
498 frame_cnt_inst : counter_register generic map (8, 1)
\r
499 port map (cnt_clk , rst_n, frame_en_n, '1', (others => '0'), frame_cnt);
\r
502 p_write : process (rst_n, ppu_clk)
\r
504 if (rst_n = '0') then
\r
508 nes_r <= (others => '0');
\r
509 nes_g <= (others => '0');
\r
510 nes_b <= (others => '0');
\r
511 elsif (rising_edge(ppu_clk)) then
\r
513 if (pos_x = conv_std_logic_vector(340, 9)) then
\r
517 if (pos_y = conv_std_logic_vector(261, 9)) then
\r
531 nes_b <= pos_x(3 downto 0);
\r
532 nes_g <= pos_x(7 downto 4);
\r
533 if (pos_x <= conv_std_logic_vector(64, 9)) then
\r
535 elsif (pos_x <= conv_std_logic_vector(128, 9)) then
\r
537 elsif (pos_x <= conv_std_logic_vector(192, 9)) then
\r