From: astoria-d@fc Date: Mon, 12 Sep 2016 07:53:59 +0000 (+0900) Subject: sprite state machine added X-Git-Tag: ppu-work-160915~11 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=2429873e3e21a0b7fd3c5169ed651bc959e7c806;p=motonesfpga%2Fmotonesfpga.git sprite state machine added --- diff --git a/de0_cv_nes/dummy-mos6502.vhd b/de0_cv_nes/dummy-mos6502.vhd index 11e9951..175c83f 100644 --- a/de0_cv_nes/dummy-mos6502.vhd +++ b/de0_cv_nes/dummy-mos6502.vhd @@ -279,7 +279,7 @@ end; else io_brk; - if (nt_step_cnt > 17 * cpu_io_multi) then + if (nt_step_cnt > 4 * cpu_io_multi) then global_step_cnt := global_step_cnt + 1; end if; end if; diff --git a/de0_cv_nes/ppu/render.vhd b/de0_cv_nes/ppu/render.vhd index 764a962..fe54014 100644 --- a/de0_cv_nes/ppu/render.vhd +++ b/de0_cv_nes/ppu/render.vhd @@ -54,6 +54,18 @@ end render; architecture rtl of render is +--secondary oam ram. +component ram + generic (abus_size : integer := 16; dbus_size : integer := 8); + port ( + pi_base_clk : in std_logic; + pi_ce_n : in std_logic; + pi_oe_n : in std_logic; + pi_we_n : in std_logic; + pi_addr : in std_logic_vector (abus_size - 1 downto 0); + pio_d_io : inout std_logic_vector (dbus_size - 1 downto 0) + ); +end component; --------- VGA screen constant ----------- constant VGA_W : integer := 640; @@ -207,6 +219,7 @@ type vac_state is ( REG_SET3 ); +-------------bg registers. signal reg_v_cur_state : vac_state; signal reg_v_next_state : vac_state; @@ -228,6 +241,50 @@ signal reg_plt_wr_n : std_logic; signal reg_plt_addr : std_logic_vector (4 downto 0); signal reg_plt_data : std_logic_vector (7 downto 0); +---------------oam registers. + +type s_oam_state is ( + IDLE, + AD_SET0, + AD_SET1, + AD_SET2, + AD_SET3, + REG_CLR0, + REG_CLR1, + REG_CLR2, + REG_CLR3, + REG_CP0, + REG_CP1, + REG_CP2, + REG_CP3, + REG_NT0, + REG_NT1, + REG_NT2, + REG_NT3, + REG_AT0, + REG_AT1, + REG_AT2, + REG_AT3, + REG_PL0, + REG_PL1, + REG_PL2, + REG_PL3, + REG_PH0, + REG_PH1, + REG_PH2, + REG_PH3 + ); + + +signal reg_s_oam_cur_state : s_oam_state; +signal reg_s_oam_next_state : s_oam_state; + +signal reg_s_oam_ce_n : std_logic; +signal reg_s_oam_rd_n : std_logic; +signal reg_s_oam_wr_n : std_logic; +signal reg_s_oam_addr : std_logic_vector (4 downto 0); +signal reg_s_oam_data : std_logic_vector (7 downto 0); + begin --position and sync signal generate. @@ -291,13 +348,15 @@ begin end if;--if (pi_rst_n = '0') then end process; - --vram access state machine (state transition)... - vac_set_stat_p : process (pi_rst_n, pi_base_clk) + --state transition process... + set_stat_p : process (pi_rst_n, pi_base_clk) begin if (pi_rst_n = '0') then + reg_s_oam_cur_state <= IDLE; reg_v_cur_state <= IDLE; elsif (rising_edge(pi_base_clk)) then reg_v_cur_state <= reg_v_next_state; + reg_s_oam_cur_state <= reg_s_oam_next_state; end if;--if (pi_rst_n = '0') then end process; @@ -593,6 +652,7 @@ end; end if;--if (pi_rst_n = '0') then end process; + --vga output process... rgb_out_p : process (pi_rst_n, pi_base_clk) begin if (pi_rst_n = '0') then @@ -616,6 +676,290 @@ end; end if;--if (rst_n = '0') then end process;--output_p + ---secondary oam ram inst. + secondary_oam_inst : ram generic map (5, 8) port map ( + pi_base_clk, + reg_s_oam_ce_n, + reg_s_oam_rd_n, + reg_s_oam_wr_n, + reg_s_oam_addr, + reg_s_oam_data + ); + + + --state change to next. + s_oam_next_stat_p : process (reg_s_oam_cur_state, pi_rnd_en, pi_ppu_mask(PPUSSP), reg_nes_x, reg_nes_y) +function is_idle ( + pm_ssp : in std_logic; + pm_nes_x : in integer range 0 to VGA_W_MAX - 1; + pm_nes_y : in integer range 0 to VGA_H_MAX - 1 + )return integer is +begin + if (pm_ssp = '0' or + (pm_nes_x > HSCAN_SPR_MAX) or + (pm_nes_y >= VSCAN and pm_nes_y < VSCAN_NEXT_START)) then + return 1; + else + return 0; + end if; +end; + begin + case reg_s_oam_cur_state is + when IDLE => + if (pi_ppu_mask(PPUSSP) = '1' and reg_nes_x = 0 and + (reg_nes_y < VSCAN or reg_nes_y = VSCAN_NEXT_START) and + pi_rnd_en(2) = '1') then + --start sprite clear. + reg_s_oam_next_state <= AD_SET0; + else + reg_s_oam_next_state <= reg_s_oam_cur_state; + end if; + when AD_SET0 => + if (is_idle(pi_ppu_mask(PPUSSP), reg_nes_x, reg_nes_y) = 1) then + reg_s_oam_next_state <= IDLE; + elsif (pi_rnd_en(3) = '1') then + reg_s_oam_next_state <= AD_SET1; + else + reg_s_oam_next_state <= reg_s_oam_cur_state; + end if; + when AD_SET1 => + if (is_idle(pi_ppu_mask(PPUSSP), reg_nes_x, reg_nes_y) = 1) then + reg_s_oam_next_state <= IDLE; + elsif (pi_rnd_en(0) = '1') then + reg_s_oam_next_state <= AD_SET2; + else + reg_s_oam_next_state <= reg_s_oam_cur_state; + end if; + when AD_SET2 => + if (is_idle(pi_ppu_mask(PPUSSP), reg_nes_x, reg_nes_y) = 1) then + reg_s_oam_next_state <= IDLE; + elsif (pi_rnd_en(1) = '1') then + reg_s_oam_next_state <= AD_SET3; + else + reg_s_oam_next_state <= reg_s_oam_cur_state; + end if; + when AD_SET3 => + if (is_idle(pi_ppu_mask(PPUSSP), reg_nes_x, reg_nes_y) = 1) then + reg_s_oam_next_state <= IDLE; + elsif (pi_rnd_en(2) = '1') then + if (reg_nes_x < HSCAN_OAM_EVA_START) then + --first 64 is oam clear. + reg_s_oam_next_state <= REG_CLR0; + elsif (reg_nes_x <= HSCAN) then + --next until 256 is evaluate. + --TODO: must add evaluation logic... + reg_s_oam_next_state <= REG_CP0; + else + if (reg_nes_x mod 8 = 1) then + reg_s_oam_next_state <= REG_NT0; + elsif (reg_nes_x mod 8 = 3) then + reg_s_oam_next_state <= REG_AT0; + elsif (reg_nes_x mod 8 = 5) then + reg_s_oam_next_state <= REG_PL0; + elsif (reg_nes_x mod 8 = 7) then + reg_s_oam_next_state <= REG_PH0; + else + reg_s_oam_next_state <= reg_s_oam_cur_state; + end if; + end if; + else + reg_s_oam_next_state <= reg_s_oam_cur_state; + end if; + when REG_CLR0 => + if (is_idle(pi_ppu_mask(PPUSSP), reg_nes_x, reg_nes_y) = 1) then + reg_s_oam_next_state <= IDLE; + elsif (pi_rnd_en(3) = '1') then + reg_s_oam_next_state <= REG_CLR1; + else + reg_s_oam_next_state <= reg_s_oam_cur_state; + end if; + when REG_CLR1 => + if (is_idle(pi_ppu_mask(PPUSSP), reg_nes_x, reg_nes_y) = 1) then + reg_s_oam_next_state <= IDLE; + elsif (pi_rnd_en(0) = '1') then + reg_s_oam_next_state <= REG_CLR2; + else + reg_s_oam_next_state <= reg_s_oam_cur_state; + end if; + when REG_CLR2 => + if (is_idle(pi_ppu_mask(PPUSSP), reg_nes_x, reg_nes_y) = 1) then + reg_s_oam_next_state <= IDLE; + elsif (pi_rnd_en(1) = '1') then + reg_s_oam_next_state <= REG_CLR3; + else + reg_s_oam_next_state <= reg_s_oam_cur_state; + end if; + when REG_CLR3 => + if (is_idle(pi_ppu_mask(PPUSSP), reg_nes_x, reg_nes_y) = 1) then + reg_s_oam_next_state <= IDLE; + elsif (pi_rnd_en(2) = '1') then + reg_s_oam_next_state <= AD_SET0; + else + reg_s_oam_next_state <= reg_s_oam_cur_state; + end if; + when REG_CP0 => + if (is_idle(pi_ppu_mask(PPUSSP), reg_nes_x, reg_nes_y) = 1) then + reg_s_oam_next_state <= IDLE; + elsif (pi_rnd_en(3) = '1') then + reg_s_oam_next_state <= REG_CP1; + else + reg_s_oam_next_state <= reg_s_oam_cur_state; + end if; + when REG_CP1 => + if (is_idle(pi_ppu_mask(PPUSSP), reg_nes_x, reg_nes_y) = 1) then + reg_s_oam_next_state <= IDLE; + elsif (pi_rnd_en(0) = '1') then + reg_s_oam_next_state <= REG_CP2; + else + reg_s_oam_next_state <= reg_s_oam_cur_state; + end if; + when REG_CP2 => + if (is_idle(pi_ppu_mask(PPUSSP), reg_nes_x, reg_nes_y) = 1) then + reg_s_oam_next_state <= IDLE; + elsif (pi_rnd_en(1) = '1') then + reg_s_oam_next_state <= REG_CP3; + else + reg_s_oam_next_state <= reg_s_oam_cur_state; + end if; + when REG_CP3 => + if (is_idle(pi_ppu_mask(PPUSSP), reg_nes_x, reg_nes_y) = 1) then + reg_s_oam_next_state <= IDLE; + elsif (pi_rnd_en(2) = '1') then + reg_s_oam_next_state <= AD_SET0; + else + reg_s_oam_next_state <= reg_s_oam_cur_state; + end if; + when REG_NT0 => + if (is_idle(pi_ppu_mask(PPUSSP), reg_nes_x, reg_nes_y) = 1) then + reg_s_oam_next_state <= IDLE; + elsif (pi_rnd_en(3) = '1') then + reg_s_oam_next_state <= REG_NT1; + else + reg_s_oam_next_state <= reg_s_oam_cur_state; + end if; + when REG_NT1 => + if (is_idle(pi_ppu_mask(PPUSSP), reg_nes_x, reg_nes_y) = 1) then + reg_s_oam_next_state <= IDLE; + elsif (pi_rnd_en(0) = '1') then + reg_s_oam_next_state <= REG_NT2; + else + reg_s_oam_next_state <= reg_s_oam_cur_state; + end if; + when REG_NT2 => + if (is_idle(pi_ppu_mask(PPUSSP), reg_nes_x, reg_nes_y) = 1) then + reg_s_oam_next_state <= IDLE; + elsif (pi_rnd_en(1) = '1') then + reg_s_oam_next_state <= REG_NT3; + else + reg_s_oam_next_state <= reg_s_oam_cur_state; + end if; + when REG_NT3 => + if (is_idle(pi_ppu_mask(PPUSSP), reg_nes_x, reg_nes_y) = 1) then + reg_s_oam_next_state <= IDLE; + elsif (pi_rnd_en(2) = '1') then + reg_s_oam_next_state <= AD_SET0; + else + reg_s_oam_next_state <= reg_s_oam_cur_state; + end if; + when REG_AT0 => + if (is_idle(pi_ppu_mask(PPUSSP), reg_nes_x, reg_nes_y) = 1) then + reg_s_oam_next_state <= IDLE; + elsif (pi_rnd_en(3) = '1') then + reg_s_oam_next_state <= REG_AT1; + else + reg_s_oam_next_state <= reg_s_oam_cur_state; + end if; + when REG_AT1 => + if (is_idle(pi_ppu_mask(PPUSSP), reg_nes_x, reg_nes_y) = 1) then + reg_s_oam_next_state <= IDLE; + elsif (pi_rnd_en(0) = '1') then + reg_s_oam_next_state <= REG_AT2; + else + reg_s_oam_next_state <= reg_s_oam_cur_state; + end if; + when REG_AT2 => + if (is_idle(pi_ppu_mask(PPUSSP), reg_nes_x, reg_nes_y) = 1) then + reg_s_oam_next_state <= IDLE; + elsif (pi_rnd_en(1) = '1') then + reg_s_oam_next_state <= REG_AT3; + else + reg_s_oam_next_state <= reg_s_oam_cur_state; + end if; + when REG_AT3 => + if (is_idle(pi_ppu_mask(PPUSSP), reg_nes_x, reg_nes_y) = 1) then + reg_s_oam_next_state <= IDLE; + elsif (pi_rnd_en(2) = '1') then + reg_s_oam_next_state <= AD_SET0; + else + reg_s_oam_next_state <= reg_s_oam_cur_state; + end if; + when REG_PL0 => + if (is_idle(pi_ppu_mask(PPUSSP), reg_nes_x, reg_nes_y) = 1) then + reg_s_oam_next_state <= IDLE; + elsif (pi_rnd_en(3) = '1') then + reg_s_oam_next_state <= REG_PL1; + else + reg_s_oam_next_state <= reg_s_oam_cur_state; + end if; + when REG_PL1 => + if (is_idle(pi_ppu_mask(PPUSSP), reg_nes_x, reg_nes_y) = 1) then + reg_s_oam_next_state <= IDLE; + elsif (pi_rnd_en(0) = '1') then + reg_s_oam_next_state <= REG_PL2; + else + reg_s_oam_next_state <= reg_s_oam_cur_state; + end if; + when REG_PL2 => + if (is_idle(pi_ppu_mask(PPUSSP), reg_nes_x, reg_nes_y) = 1) then + reg_s_oam_next_state <= IDLE; + elsif (pi_rnd_en(1) = '1') then + reg_s_oam_next_state <= REG_PL3; + else + reg_s_oam_next_state <= reg_s_oam_cur_state; + end if; + when REG_PL3 => + if (is_idle(pi_ppu_mask(PPUSSP), reg_nes_x, reg_nes_y) = 1) then + reg_s_oam_next_state <= IDLE; + elsif (pi_rnd_en(2) = '1') then + reg_s_oam_next_state <= AD_SET0; + else + reg_s_oam_next_state <= reg_s_oam_cur_state; + end if; + when REG_PH0 => + if (is_idle(pi_ppu_mask(PPUSSP), reg_nes_x, reg_nes_y) = 1) then + reg_s_oam_next_state <= IDLE; + elsif (pi_rnd_en(3) = '1') then + reg_s_oam_next_state <= REG_PH1; + else + reg_s_oam_next_state <= reg_s_oam_cur_state; + end if; + when REG_PH1 => + if (is_idle(pi_ppu_mask(PPUSSP), reg_nes_x, reg_nes_y) = 1) then + reg_s_oam_next_state <= IDLE; + elsif (pi_rnd_en(0) = '1') then + reg_s_oam_next_state <= REG_PH2; + else + reg_s_oam_next_state <= reg_s_oam_cur_state; + end if; + when REG_PH2 => + if (is_idle(pi_ppu_mask(PPUSSP), reg_nes_x, reg_nes_y) = 1) then + reg_s_oam_next_state <= IDLE; + elsif (pi_rnd_en(1) = '1') then + reg_s_oam_next_state <= REG_PH3; + else + reg_s_oam_next_state <= reg_s_oam_cur_state; + end if; + when REG_PH3 => + if (is_idle(pi_ppu_mask(PPUSSP), reg_nes_x, reg_nes_y) = 1) then + reg_s_oam_next_state <= IDLE; + elsif (pi_rnd_en(2) = '1') then + reg_s_oam_next_state <= AD_SET0; + else + reg_s_oam_next_state <= reg_s_oam_cur_state; + end if; + end case; + end process; + po_ppu_status <= (others => '0'); po_spr_ce_n <= 'Z'; diff --git a/de0_cv_nes/simulation/modelsim/de0_cv_nes_run_msim_rtl_vhdl.do b/de0_cv_nes/simulation/modelsim/de0_cv_nes_run_msim_rtl_vhdl.do index ff0ad3b..b8a36d4 100644 --- a/de0_cv_nes/simulation/modelsim/de0_cv_nes_run_msim_rtl_vhdl.do +++ b/de0_cv_nes/simulation/modelsim/de0_cv_nes_run_msim_rtl_vhdl.do @@ -28,23 +28,23 @@ add wave -label addr -radix hex sim:/testbench_motones_sim/sim_board/wr_addr add wave -label d_io -radix hex sim:/testbench_motones_sim/sim_board/wr_d_io; -add wave -divider ppu -add wave -label pi_ce_n -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/pi_ce_n; -add wave -label ppu_ctrl -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/reg_ppu_ctrl; -add wave -label ppu_mask -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/reg_ppu_mask; -add wave -label ppu_status -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/pi_ppu_status; -add wave -label oam_addr -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/reg_oam_addr; -add wave -label oam_data -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/reg_oam_data; -add wave -label ppu_scroll_x -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/reg_ppu_scroll_x; -add wave -label ppu_scroll_y -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/reg_ppu_scroll_y; -add wave -label ppu_addr -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/reg_ppu_addr; -add wave -label ppu_data -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/reg_ppu_data; - -add wave -divider vram -add wave -label v_rd_n -radix hex sim:/testbench_motones_sim/sim_board/wr_v_rd_n; -add wave -label v_wr_n -radix hex sim:/testbench_motones_sim/sim_board/wr_v_wr_n; -add wave -label vram_addr -radix hex sim:/testbench_motones_sim/sim_board/wr_v_addr; -add wave -label vram_data -radix hex sim:/testbench_motones_sim/sim_board/wr_v_data; +#add wave -divider ppu +#add wave -label pi_ce_n -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/pi_ce_n; +#add wave -label ppu_ctrl -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/reg_ppu_ctrl; +#add wave -label ppu_mask -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/reg_ppu_mask; +#add wave -label ppu_status -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/pi_ppu_status; +#add wave -label oam_addr -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/reg_oam_addr; +#add wave -label oam_data -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/reg_oam_data; +#add wave -label ppu_scroll_x -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/reg_ppu_scroll_x; +#add wave -label ppu_scroll_y -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/reg_ppu_scroll_y; +#add wave -label ppu_addr -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/reg_ppu_addr; +#add wave -label ppu_data -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/reg_ppu_data; +# +#add wave -divider vram +#add wave -label v_rd_n -radix hex sim:/testbench_motones_sim/sim_board/wr_v_rd_n; +#add wave -label v_wr_n -radix hex sim:/testbench_motones_sim/sim_board/wr_v_wr_n; +#add wave -label vram_addr -radix hex sim:/testbench_motones_sim/sim_board/wr_v_addr; +#add wave -label vram_data -radix hex sim:/testbench_motones_sim/sim_board/wr_v_data; add wave -divider render #add wave -label vga_x sim:/testbench_motones_sim/sim_board/render_inst/reg_vga_x; @@ -52,15 +52,19 @@ add wave -divider render add wave -label nes_x sim:/testbench_motones_sim/sim_board/render_inst/reg_nes_x; add wave -label nes_y sim:/testbench_motones_sim/sim_board/render_inst/reg_nes_y; #add wave -label wr_rnd_en sim:/testbench_motones_sim/sim_board/wr_rnd_en; -add wave -label reg_v_cur_state sim:/testbench_motones_sim/sim_board/render_inst/reg_v_cur_state; +#add wave -label reg_v_cur_state sim:/testbench_motones_sim/sim_board/render_inst/reg_v_cur_state; #add wave -label prf_x sim:/testbench_motones_sim/sim_board/render_inst/reg_prf_x; #add wave -label prf_y sim:/testbench_motones_sim/sim_board/render_inst/reg_prf_y; -add wave -label disp_nt -radix hex sim:/testbench_motones_sim/sim_board/render_inst/reg_disp_nt; -add wave -label disp_attr -radix hex sim:/testbench_motones_sim/sim_board/render_inst/reg_disp_attr; -add wave -label sft_ptn_l -radix hex sim:/testbench_motones_sim/sim_board/render_inst/reg_sft_ptn_l; -add wave -label sft_ptn_h -radix hex sim:/testbench_motones_sim/sim_board/render_inst/reg_sft_ptn_h; +#add wave -label disp_nt -radix hex sim:/testbench_motones_sim/sim_board/render_inst/reg_disp_nt; +#add wave -label disp_attr -radix hex sim:/testbench_motones_sim/sim_board/render_inst/reg_disp_attr; +#add wave -label sft_ptn_l -radix hex sim:/testbench_motones_sim/sim_board/render_inst/reg_sft_ptn_l; +#add wave -label sft_ptn_h -radix hex sim:/testbench_motones_sim/sim_board/render_inst/reg_sft_ptn_h; +add wave -divider sprite +add wave -label reg_s_oam_cur_state sim:/testbench_motones_sim/sim_board/render_inst/reg_s_oam_cur_state; + +add wave -divider palette add wave -label plt_addr -radix hex sim:/testbench_motones_sim/sim_board/render_inst/reg_plt_addr; add wave -label plt_data -radix hex sim:/testbench_motones_sim/sim_board/render_inst/reg_plt_data; @@ -82,5 +86,5 @@ view signals run 4 us wave zoom full -run 166 us +run 190 us