bbb
ghdl-dir
tmp/
+old/
bl.sh
motonesemu
*.bin
DE1_control_panel
~$*
*.lnk
-
+bin2hex*
simulation/modelsim/work/*\r
simulation/modelsim/transcript\r
simulation/modelsim/motones_modelsim.cr.mti\r
+simulation/modelsim/bookmarks.do\r
undo_redo.txt\r
*.work\r
serv_req_info.txt\r
mem_clk : in std_logic;
R_nW : in std_logic; -- active high on read / active low on write.
addr : in std_logic_vector (abus_size - 1 downto 0);
- d_io : in std_logic_vector (dbus_size - 1 downto 0);
rom_ce_n : out std_logic;
ram_ce_n : out std_logic;
ppu_ce_n : out std_logic;
begin
- rom_ce_n <= '0' when (addr(15) = '1' and R_nW = '1') else
- '1' ;
+ rom_ce_n <= not addr(15);
ppu_ce_n <= '0'
when (addr(15) = '0' and addr(14) = '0' and addr(13) = '1') else
port map (mem_clk, ram_ce_n_in, r_n, r_nw, ram_ce_n);
--ram io timing.
- main_p : process (phi2, addr, d_io, R_nW)
+ main_p : process (phi2, addr, R_nW)
begin
-- ram range : 0 - 0x2000.
-- 0x2000 is 0010_0000_0000_0000
nt1_ce_n_in <= '1';
if (wr_n = '0') then
--write
- nt0_ce_n_in <= clk;
+ nt0_ce_n_in <= not clk;
elsif (rd_n = '0') then
--read
nt0_ce_n_in <= '0';
architecture rtl of clock_divider is
-signal loop8 : std_logic_vector (2 downto 0);
-signal loop24 : std_logic_vector (4 downto 0);
-signal base_clk_n : std_logic;
-signal cpu_cnt_rst_n : std_logic;
-signal cpu_we_n : std_logic;
-signal cpu_clk_new : std_logic;
-signal cpu_clk_old : std_logic;
-
component counter_register
generic (
dsize : integer := 8;
);
end component;
+signal loop8 : std_logic_vector (2 downto 0);\r
+signal loop6 : std_logic_vector (2 downto 0);\r
+signal cpu_cnt_rst_n : std_logic;\r
+signal base_clk_n : std_logic;\r
+signal cpu_clk_wk : std_logic;\r
+\r
begin
--Actual NES base clock = 21.477272 MHz
--CPU clock = base clock / 12
--vga clock = base clock / 2
--mem clock = base clock
- base_clk_n <= not base_clk;
-
- cpu_clk_old <= not cpu_clk_new;
- cpu_clk <= cpu_clk_new;
-
- ppu_clk <= loop8(2);
+ ppu_clk <= not loop8(2);
vga_clk <= not loop8(0);
mem_clk <= base_clk;
+ --cpu_clk <= not (loop6(2) or loop6(1));\r
+ cpu_clk <= not cpu_clk_wk;\r
+ base_clk_n <= base_clk;\r
- cpu_we_n <= '0' when loop24 = "00011" else
- '0' when loop24 = "01111" else
- '1';
- ppu_clk_cnt : counter_register generic map (3) port map
- (base_clk, reset_n, '0', '1', (others=>'0'), loop8);
-
- cpu_clk_cnt : counter_register generic map (5) port map
- (base_clk_n, cpu_cnt_rst_n, '0', '1', (others=>'0'), loop24);
-
- cpu_clk_inst : d_flip_flop_bit port map
- (base_clk, reset_n, '1', cpu_we_n, cpu_clk_old, cpu_clk_new);
-
- clock_p : process (base_clk)
+ ppu_clk_cnt : counter_register generic map (3) port map \r
+ (base_clk_n, reset_n, '0', '1', (others=>'0'), loop8);\r
+\r
+ cpu_clk_cnt : counter_register generic map (3) port map \r
+ (loop8(1), cpu_cnt_rst_n, '0', '1', (others=>'0'), loop6);\r
+\r
+
+ clock_p : process (loop8(1))
begin
if (reset_n = '0') then
- cpu_cnt_rst_n <= '0';
+ cpu_clk_wk <= '0';
else
- if (base_clk'event and base_clk = '1') then
- if (loop24 = "10111") then
- cpu_cnt_rst_n <= '0';
- else
- cpu_cnt_rst_n <= '1';
- end if;
+ if (loop8(1)'event and loop8(1) = '0') then
+ if (loop6(0) = '1') then\r
+ cpu_clk_wk <= not cpu_clk_wk ;\r
+ end if;\r
end if;
end if;
end process;
+ clock_p2 : process (loop8(1))\r
+ begin\r
+ if (reset_n = '0') then\r
+ cpu_cnt_rst_n <= '0';\r
+ else\r
+ if (loop8(1)'event and loop8(1) = '1') then\r
+ if (loop6 = "100") then\r
+ cpu_cnt_rst_n <= '0';\r
+ else\r
+ cpu_cnt_rst_n <= '1';\r
+ end if;\r
+ end if;\r
+ end if;\r
+ end process;\r
+\r
end rtl;
r_nw <= '1';
dbuf_int_oe_n <= '0';
front_we(pcl_cmd, '0');
+ dl_al_oe_n <= '1';
+ dl_ah_oe_n <= '1';
if exec_cycle = R4 then
r_vec_oe_n <= '0';
+ n_vec_oe_n <= '1';
wk_next_cycle <= R5;
elsif exec_cycle = N4 then
+ r_vec_oe_n <= '1';
n_vec_oe_n <= '0';
wk_next_cycle <= N5;
end if;
front_we(pcl_cmd, '1');
--fetch reset vector hi
+ r_nw <= '1';
+ dbuf_int_oe_n <= '0';
front_we(pch_cmd, '0');
indir_n <= '0';
set_location_assignment PIN_R8 -to dram_we_n\r
\r
\r
-set_global_assignment -name VHDL_FILE mem/sdram_controller.vhd\r
-set_global_assignment -name QIP_FILE pll_clk_gen.qip\r
+#set_global_assignment -name VHDL_FILE apu/apu.vhd\r
+set_global_assignment -name VHDL_FILE address_decoder.vhd\r
set_global_assignment -name VHDL_FILE motonesfpga_common.vhd\r
+set_global_assignment -name VHDL_FILE clock/clock_divider.vhd\r
set_global_assignment -name VHDL_FILE mem/prg_rom.vhd\r
set_global_assignment -name VHDL_FILE mem/chr_rom.vhd\r
set_global_assignment -name VHDL_FILE mem/ram.vhd\r
-set_global_assignment -name VHDL_FILE cpu/cpu_registers.vhd\r
set_global_assignment -name VHDL_FILE ppu/ppu_registers.vhd\r
-set_global_assignment -name VHDL_FILE clock/clock_divider.vhd\r
set_global_assignment -name VHDL_FILE ppu/vga.vhd\r
set_global_assignment -name VHDL_FILE ppu/render.vhd\r
set_global_assignment -name VHDL_FILE ppu/ppu.vhd\r
-set_global_assignment -name VHDL_FILE apu/apu.vhd\r
-set_global_assignment -name VHDL_FILE cpu/decoder.vhd\r
set_global_assignment -name VHDL_FILE cpu/alu.vhd\r
+set_global_assignment -name VHDL_FILE cpu/cpu_registers.vhd\r
+set_global_assignment -name VHDL_FILE cpu/decoder.vhd\r
set_global_assignment -name VHDL_FILE cpu/mos6502.vhd\r
-set_global_assignment -name VHDL_FILE address_decoder.vhd\r
set_global_assignment -name VHDL_FILE de1_nes.vhd\r
+set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "3.3-V LVTTL"\r
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
\ No newline at end of file
signal dbg_d_io : out std_logic_vector( 8 - 1 downto 0);
signal dbg_vram_ad : out std_logic_vector (7 downto 0);
signal dbg_vram_a : out std_logic_vector (13 downto 8);
+
---monitor inside cpu
signal dbg_instruction : out std_logic_vector(7 downto 0);
signal dbg_int_d_bus : out std_logic_vector(7 downto 0);
- signal dbg_exec_cycle : out std_logic_vector (5 downto 0);\r
- \r
- signal dbg_ea_carry : out std_logic;\r
- signal dbg_wait_a58_branch_next : out std_logic;\r
-
+ signal dbg_exec_cycle : out std_logic_vector (5 downto 0);
+ signal dbg_ea_carry : out std_logic;
+ signal dbg_wait_a58_branch_next : out std_logic;
-- signal dbg_index_bus : out std_logic_vector(7 downto 0);
-- signal dbg_acc_bus : out std_logic_vector(7 downto 0);
signal dbg_status : out std_logic_vector(7 downto 0);
--- signal dbg_pcl, dbg_pch : out std_logic_vector(7 downto 0);\r
+-- signal dbg_pcl, dbg_pch : out std_logic_vector(7 downto 0);
signal dbg_sp, dbg_x, dbg_y, dbg_acc : out std_logic_vector(7 downto 0);
signal dbg_dec_oe_n : out std_logic;
signal dbg_dec_val : out std_logic_vector (7 downto 0);
signal dbg_int_dbus : out std_logic_vector (7 downto 0);
-- signal dbg_status_val : out std_logic_vector (7 downto 0);
-- signal dbg_stat_we_n : out std_logic;
--- signal dbg_idl_h, dbg_idl_l, dbg_dbb_r, dbg_dbb_w : out std_logic_vector (7 downto 0);\r
-\r
- signal dbg_ppu_ce_n : out std_logic;\r
- signal dbg_ppu_ctrl, dbg_ppu_mask, dbg_ppu_status : out std_logic_vector (7 downto 0);\r
- signal dbg_ppu_addr : out std_logic_vector (13 downto 0);\r
- signal dbg_ppu_data, dbg_ppu_scrl_x, dbg_ppu_scrl_y : out std_logic_vector (7 downto 0);\r
-\r
--- signal dbg_disp_nt, dbg_disp_attr : out std_logic_vector (7 downto 0);\r
--- signal dbg_disp_ptn_h, dbg_disp_ptn_l : out std_logic_vector (15 downto 0);\r
- signal dbg_ppu_addr_we_n : out std_logic;\r
- signal dbg_ppu_clk_cnt : out std_logic_vector(1 downto 0);\r
- \r
- \r
- \r
+-- signal dbg_idl_h, dbg_idl_l, dbg_dbb_r, dbg_dbb_w : out std_logic_vector (7 downto 0);
+
+--ppu debug pins
+ signal dbg_ppu_ce_n : out std_logic;
+ signal dbg_ppu_ctrl, dbg_ppu_mask, dbg_ppu_status : out std_logic_vector (7 downto 0);
+ signal dbg_ppu_addr : out std_logic_vector (13 downto 0);
+ signal dbg_ppu_data, dbg_ppu_scrl_x, dbg_ppu_scrl_y : out std_logic_vector (7 downto 0);
+ signal dbg_disp_nt, dbg_disp_attr : out std_logic_vector (7 downto 0);
+ signal dbg_disp_ptn_h, dbg_disp_ptn_l : out std_logic_vector (15 downto 0);
+
+
--NES instance
base_clk : in std_logic;
rst_n : in std_logic;
joypad1 : in std_logic_vector(7 downto 0);
joypad2 : in std_logic_vector(7 downto 0);
- vga_clk : out std_logic;
h_sync_n : out std_logic;
v_sync_n : out std_logic;
r : out std_logic_vector(3 downto 0);
g : out std_logic_vector(3 downto 0);
- b : out std_logic_vector(3 downto 0);\r
-
- --SDRAM Signals\r
- dram_addr : out std_logic_vector (11 downto 0); --Address (12 bit)\r
- dram_bank : out std_logic_vector (1 downto 0); --Bank\r
- dram_cas_n : out std_logic; --Column Address is being transmitted\r
- dram_cke : out std_logic; --Clock Enable\r
- dram_clk : out std_logic; --Clock\r
- dram_cs_n : out std_logic; --Chip Select (Here - Mask commands)\r
- dram_dq : inout std_logic_vector (15 downto 0); --Data in / Data out\r
- dram_ldqm : out std_logic; --Byte masking\r
- dram_udqm : out std_logic; --Byte masking\r
- dram_ras_n : out std_logic; --Row Address is being transmitted\r
- dram_we_n : out std_logic --Write Enable\r
+ b : out std_logic_vector(3 downto 0)
);
end de1_nes;
signal dbg_instruction : out std_logic_vector(7 downto 0);
signal dbg_int_d_bus : out std_logic_vector(7 downto 0);
signal dbg_exec_cycle : out std_logic_vector (5 downto 0);
- signal dbg_ea_carry : out std_logic;\r
- signal dbg_wait_a58_branch_next : out std_logic;\r
+ signal dbg_ea_carry : out std_logic;
+ signal dbg_wait_a58_branch_next : out std_logic;
-- signal dbg_index_bus : out std_logic_vector(7 downto 0);
-- signal dbg_acc_bus : out std_logic_vector(7 downto 0);
signal dbg_status : out std_logic_vector(7 downto 0);
signal dbg_int_dbus : out std_logic_vector (7 downto 0);
-- signal dbg_status_val : out std_logic_vector (7 downto 0);
signal dbg_stat_we_n : out std_logic;
- signal dbg_idl_h, dbg_idl_l, dbg_dbb_r, dbg_dbb_w : out std_logic_vector (7 downto 0);\r
+ signal dbg_idl_h, dbg_idl_l, dbg_dbb_r, dbg_dbb_w : out std_logic_vector (7 downto 0);
input_clk : in std_logic; --phi0 input pin.
rdy : in std_logic;
mem_clk : in std_logic;
R_nW : in std_logic;
addr : in std_logic_vector (abus_size - 1 downto 0);
- d_io : in std_logic_vector (dbus_size - 1 downto 0);
rom_ce_n : out std_logic;
ram_ce_n : out std_logic;
ppu_ce_n : out std_logic;
);
end component;
- component ppu
- port ( \r
- signal dbg_ppu_ce_n : out std_logic;\r
- signal dbg_ppu_ctrl, dbg_ppu_mask, dbg_ppu_status : out std_logic_vector (7 downto 0);\r
- signal dbg_ppu_addr : out std_logic_vector (13 downto 0);\r
- signal dbg_ppu_data, dbg_ppu_scrl_x, dbg_ppu_scrl_y : out std_logic_vector (7 downto 0);\r
- signal dbg_disp_nt, dbg_disp_attr : out std_logic_vector (7 downto 0);\r
- signal dbg_disp_ptn_h, dbg_disp_ptn_l : out std_logic_vector (15 downto 0);\r
- signal dbg_ppu_addr_we_n : out std_logic;\r
- signal dbg_ppu_clk_cnt : out std_logic_vector(1 downto 0);\r
- \r
- clk : in std_logic;
- mem_clk : in std_logic;
- sdram_clk : in std_logic;\r
- ce_n : in std_logic;
- rst_n : in std_logic;
- r_nw : in std_logic;
- cpu_addr : in std_logic_vector (2 downto 0);
- cpu_d : inout std_logic_vector (7 downto 0);
- vblank_n : out std_logic;
- rd_n : out std_logic;
- wr_n : out std_logic;
- ale : out std_logic;
- vram_ad : inout std_logic_vector (7 downto 0);
- vram_a : out std_logic_vector (13 downto 8);
- vga_clk : in std_logic;
- h_sync_n : out std_logic;
- v_sync_n : out std_logic;
- r : out std_logic_vector(3 downto 0);
- g : out std_logic_vector(3 downto 0);
- b : out std_logic_vector(3 downto 0);
- --SDRAM Signals\r
- wbs_adr_i : out std_logic_vector (21 downto 0); --Address (Bank, Row, Col)\r
- wbs_dat_i : out std_logic_vector (15 downto 0); --Data In (16 bits)\r
- wbs_we_i : out std_logic; --Write Enable\r
- 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
- wbs_cyc_i : out std_logic; --Cycle Command from interface\r
- wbs_stb_i : out std_logic; --Strobe Command from interface\r
- wbs_dat_o : in std_logic_vector (15 downto 0); --Data Out (16 bits)\r
- wbs_stall_o : in std_logic; --Slave is not ready to receive new data\r
- wbs_err_o : in std_logic; --Error flag: OOR Burst. Burst length is greater that 256-column address\r
- wbs_ack_o : in std_logic --When Read Burst: DATA bus must be valid in this cycle\r
+ component ppu port (
+ signal dbg_ppu_ce_n : out std_logic;
+ signal dbg_ppu_ctrl, dbg_ppu_mask, dbg_ppu_status : out std_logic_vector (7 downto 0);
+ signal dbg_ppu_addr : out std_logic_vector (13 downto 0);
+ signal dbg_ppu_data, dbg_ppu_scrl_x, dbg_ppu_scrl_y : out std_logic_vector (7 downto 0);
+
+ signal dbg_ppu_clk : out std_logic;
+ signal dbg_nes_x : out std_logic_vector (8 downto 0);
+ signal dbg_vga_x : out std_logic_vector (9 downto 0);
+ signal dbg_disp_nt, dbg_disp_attr : out std_logic_vector (7 downto 0);
+ signal dbg_disp_ptn_h, dbg_disp_ptn_l : out std_logic_vector (15 downto 0);
+ signal dbg_plt_ce_rn_wn : out std_logic_vector (2 downto 0);
+ signal dbg_plt_addr : out std_logic_vector (4 downto 0);
+ signal dbg_plt_data : out std_logic_vector (7 downto 0);
+ signal dbg_p_oam_ce_rn_wn : out std_logic_vector (2 downto 0);
+ signal dbg_p_oam_addr : out std_logic_vector (7 downto 0);
+ signal dbg_p_oam_data : out std_logic_vector (7 downto 0);
+ signal dbg_s_oam_ce_rn_wn : out std_logic_vector (2 downto 0);
+ signal dbg_s_oam_addr : out std_logic_vector (4 downto 0);
+ signal dbg_s_oam_data : out std_logic_vector (7 downto 0);
+
+ signal dbg_ppu_addr_we_n : out std_logic;
+ signal dbg_ppu_clk_cnt : out std_logic_vector(1 downto 0);
+
+ ppu_clk : in std_logic;\r
+ mem_clk : in std_logic;
+ ce_n : in std_logic;
+ rst_n : in std_logic;
+ r_nw : in std_logic;
+ cpu_addr : in std_logic_vector (2 downto 0);
+ cpu_d : inout std_logic_vector (7 downto 0);
+
+ vblank_n : out std_logic;
+ rd_n : out std_logic;
+ wr_n : out std_logic;
+ ale : out std_logic;
+ vram_ad : inout std_logic_vector (7 downto 0);
+ vram_a : out std_logic_vector (13 downto 8);
+
+ vga_clk : in std_logic;
+ h_sync_n : out std_logic;
+ v_sync_n : out std_logic;
+ r : out std_logic_vector(3 downto 0);
+ g : out std_logic_vector(3 downto 0);
+ b : out std_logic_vector(3 downto 0)
);
end component;
dsize : integer := 8
);
port ( c : in std_logic;
+ we_n : in std_logic;
oc_n : in std_logic;
d : in std_logic_vector(dsize - 1 downto 0);
q : out std_logic_vector(dsize - 1 downto 0)
rdy : out std_logic
);
end component;
-\r
- component pll_clk_gen\r
- PORT\r
- (\r
- inclk0 : IN STD_LOGIC := '0';\r
- c0 : OUT STD_LOGIC ;\r
- locked : OUT STD_LOGIC \r
- );\r
- end component;\r
-\r
- component sdram_controller\r
- generic\r
- (\r
- reset_polarity_g : std_logic := '0' --When rst = reset_polarity_g, system is in RESET mode\r
- );\r
- port (\r
- --Clocks and Reset \r
- clk_i : in std_logic; --Wishbone input clock\r
- rst : in std_logic; --Reset\r
- pll_locked : in std_logic; --PLL Locked indication, for CKE (Clock Enable) signal to SDRAM\r
- \r
- --SDRAM Signals\r
- dram_addr : out std_logic_vector (11 downto 0); --Address (12 bit)\r
- dram_bank : out std_logic_vector (1 downto 0); --Bank\r
- dram_cas_n : out std_logic; --Column Address is being transmitted\r
- dram_cke : out std_logic; --Clock Enable\r
- dram_cs_n : out std_logic; --Chip Select (Here - Mask commands)\r
- dram_dq : inout std_logic_vector (15 downto 0); --Data in / Data out\r
- dram_ldqm : out std_logic; --Byte masking\r
- dram_udqm : out std_logic; --Byte masking\r
- dram_ras_n : out std_logic; --Row Address is being transmitted\r
- dram_we_n : out std_logic; --Write Enable\r
- \r
- -- Wishbone Slave signals to Read/Write interface\r
- wbs_adr_i : in std_logic_vector (21 downto 0); --Address (Bank, Row, Col)\r
- wbs_dat_i : in std_logic_vector (15 downto 0); --Data In (16 bits)\r
- wbs_we_i : in std_logic; --Write Enable\r
- wbs_tga_i : in std_logic_vector (7 downto 0); --Address Tag : Read/write burst length-1 (0 represents 1 word, FF represents 256 words)\r
- wbs_cyc_i : in std_logic; --Cycle Command from interface\r
- wbs_stb_i : in std_logic; --Strobe Command from interface\r
- wbs_dat_o : out std_logic_vector (15 downto 0); --Data Out (16 bits)\r
- wbs_stall_o : out std_logic; --Slave is not ready to receive new data\r
- wbs_err_o : out std_logic; --Error flag: OOR Burst. Burst length is greater that 256-column address\r
- wbs_ack_o : out std_logic; --When Read Burst: DATA bus must be valid in this cycle\r
- --When Write Burst: Data has been read from SDRAM and is valid\r
-\r
- --Debug signals\r
- cmd_ack : out std_logic; --Command has been acknowledged\r
- cmd_done : out std_logic; --Command has finished (read/write)\r
- init_st_o : out std_logic_vector (3 downto 0); --Current init state\r
- main_st_o : out std_logic_vector (3 downto 0) --Current main state\r
- ); \r
- end component;\r
constant data_size : integer := 8;
constant addr_size : integer := 16;
signal cpu_clk : std_logic;
signal ppu_clk : std_logic;
signal mem_clk : std_logic;
- signal vga_out_clk : std_logic;
- signal sdram_clk : std_logic;\r
- signal sdram_clk_locked : std_logic;\r
+ signal vga_clk : std_logic;
signal rdy, irq_n, nmi_n, dbe, r_nw : std_logic;
signal phi1, phi2 : std_logic;
signal nt0_ce_n : std_logic;
signal nt1_ce_n : std_logic;
- -- SDRAM signals to Read/Write interface\r
- signal wbs_adr_i : std_logic_vector (21 downto 0); --Address (Bank, Row, Col)\r
- signal wbs_dat_i : std_logic_vector (15 downto 0); --Data In (16 bits)\r
- signal wbs_we_i : std_logic; --Write Enable\r
- signal wbs_tga_i : std_logic_vector (7 downto 0); --Address Tag : Read/write burst length-1 (0 represents 1 word, FF represents 256 words)\r
- signal wbs_cyc_i : std_logic; --Cycle Command from interface\r
- signal wbs_stb_i : std_logic; --Strobe Command from interface\r
- signal wbs_dat_o : std_logic_vector (15 downto 0); --Data Out (16 bits)\r
- signal wbs_stall_o : std_logic; --Slave is not ready to receive new data\r
- signal wbs_err_o : std_logic; --Error flag: OOR Burst. Burst length is greater that 256-column address\r
- signal wbs_ack_o : std_logic; --When Read Burst: DATA bus must be valid in this cycle\r
- --When Write Burst: Data has been read from SDRAM and is valid\r
- --Debug signals\r
- signal cmd_ack : std_logic; --Command has been acknowledged\r
- signal cmd_done : std_logic; --Command has finished (read/write)\r
- signal init_st_o : std_logic_vector (3 downto 0); --Current init state\r
- signal main_st_o : std_logic_vector (3 downto 0); --Current main state\r
-\r
- signal dbg_disp_nt, dbg_disp_attr : std_logic_vector (7 downto 0);\r
- signal dbg_disp_ptn_h, dbg_disp_ptn_l : std_logic_vector (15 downto 0);\r
- signal dbg_pcl, dbg_pch : std_logic_vector(7 downto 0);\r
- signal dbg_stat_we_n : std_logic;\r
- signal dbg_idl_h, dbg_idl_l, dbg_dbb_r, dbg_dbb_w : std_logic_vector (7 downto 0);\r
+ signal ale_n : std_logic;
+
+-- signal dbg_disp_nt, dbg_disp_attr : std_logic_vector (7 downto 0);
+-- signal dbg_disp_ptn_h, dbg_disp_ptn_l : std_logic_vector (15 downto 0);
+ signal dbg_pcl, dbg_pch : std_logic_vector(7 downto 0);
+ signal dbg_stat_we_n : std_logic;
+ signal dbg_idl_h, dbg_idl_l, dbg_dbb_r, dbg_dbb_w : std_logic_vector (7 downto 0);
+
+ signal dbg_ppu_addr_we_n : std_logic;
+ signal dbg_ppu_clk_cnt : std_logic_vector(1 downto 0);
+ signal dbg_ppu_addr_dummy : std_logic_vector (13 downto 0);
+ signal dbg_nes_x : std_logic_vector (8 downto 0);
+ signal dbg_vga_x : std_logic_vector (9 downto 0);
+ signal dbg_plt_ce_rn_wn : std_logic_vector (2 downto 0);
+ signal dbg_plt_addr : std_logic_vector (4 downto 0);
+ signal dbg_plt_data : std_logic_vector (7 downto 0);
+ signal dbg_p_oam_ce_rn_wn : std_logic_vector (2 downto 0);
+ signal dbg_p_oam_addr : std_logic_vector (7 downto 0);
+ signal dbg_p_oam_data : std_logic_vector (7 downto 0);
+ signal dbg_s_oam_ce_rn_wn : std_logic_vector (2 downto 0);
+ signal dbg_s_oam_addr : std_logic_vector (4 downto 0);
+ signal dbg_s_oam_data : std_logic_vector (7 downto 0);
+ signal dbg_ppu_data_dummy : std_logic_vector (7 downto 0);
+ signal dbg_ppu_status_dummy : std_logic_vector (7 downto 0);
+ signal dbg_ppu_scrl_x_dummy : std_logic_vector (7 downto 0);
+ signal dbg_ppu_scrl_y_dummy : std_logic_vector (7 downto 0);
+ signal dbg_disp_ptn_h_dummy, dbg_disp_ptn_l_dummy : std_logic_vector (15 downto 0);
begin
irq_n <= '0';
- vga_clk <= vga_out_clk;
--ppu/cpu clock generator
clock_inst : clock_divider port map
- (base_clk, rst_n, cpu_clk, ppu_clk, mem_clk, vga_out_clk);
+ (base_clk, rst_n, cpu_clk, ppu_clk, mem_clk, vga_clk);
--mos 6502 cpu instance
cpu_inst : mos6502 generic map (data_size, addr_size)
dbg_instruction,
dbg_int_d_bus,
dbg_exec_cycle,
- dbg_ea_carry,\r
- dbg_wait_a58_branch_next,\r
+ dbg_ea_carry,
+ dbg_wait_a58_branch_next,
-- dbg_index_bus,
-- dbg_acc_bus,
dbg_status,
dbg_int_dbus,
-- dbg_status_val ,
dbg_stat_we_n ,
- dbg_idl_h, dbg_idl_l, dbg_dbb_r, dbg_dbb_w,\r
+ dbg_idl_h, dbg_idl_l, dbg_dbb_r, dbg_dbb_w,
cpu_clk, '1', --rdy, -----for testing...
rst_n, irq_n, nmi_n, dbe, r_nw,
phi1, phi2, addr, d_io);
addr_dec_inst : address_decoder generic map (addr_size, data_size)
- port map (phi2, mem_clk, r_nw, addr, d_io, rom_ce_n, ram_ce_n, ppu_ce_n, apu_ce_n);
+ port map (phi2, mem_clk, r_nw, addr, rom_ce_n, ram_ce_n, ppu_ce_n, apu_ce_n);
--main ROM/RAM instance
-- prg_rom_inst : prg_rom generic map (rom_32k, data_size)
-- port map (mem_clk, rom_ce_n, addr(rom_32k - 1 downto 0), d_io);
+
prg_rom_inst : prg_rom generic map (rom_4k, data_size)
port map (mem_clk, rom_ce_n, addr(rom_4k - 1 downto 0), d_io);
prg_ram_inst : ram generic map (ram_2k, data_size)
port map (mem_clk, ram_ce_n, ram_oe_n, R_nW, addr(ram_2k - 1 downto 0), d_io);
+-- dbg_ppu_addr <= "00000" & dbg_nes_x;
+ dbg_ppu_scrl_x(0) <= ale;
+ dbg_ppu_scrl_x(1) <= rd_n;
+ dbg_ppu_scrl_x(2) <= wr_n;
+ dbg_ppu_scrl_x(3) <= nt0_ce_n;
+ dbg_ppu_scrl_x(4) <= vga_clk;
+ dbg_ppu_scrl_x(5) <= rom_ce_n;
+ dbg_ppu_scrl_x(6) <= ram_ce_n;
+ dbg_ppu_scrl_x(7) <= addr(15);
+ dbg_ppu_scrl_y(2 downto 0) <= dbg_p_oam_ce_rn_wn(2 downto 0);
+ dbg_ppu_scrl_y(5 downto 3) <= dbg_plt_ce_rn_wn(2 downto 0);
+-- dbg_disp_ptn_l (7 downto 0) <= dbg_p_oam_addr;
+-- dbg_disp_ptn_l (15 downto 8) <= dbg_p_oam_data;
+
+ dbg_cpu_clk <= cpu_clk;
+ dbg_mem_clk <= mem_clk;
+ dbg_r_nw <= r_nw;
+ dbg_addr <= addr;
+ dbg_d_io <= d_io;
+ dbg_vram_ad <= vram_ad ;
+ dbg_disp_ptn_l <= "00" & v_addr ;
+ dbg_disp_ptn_h <= "000" & dbg_plt_addr & dbg_plt_data;
+
--nes ppu instance
- ppu_inst : ppu
- port map (\r
- dbg_ppu_ce_n ,\r
- dbg_ppu_ctrl, dbg_ppu_mask, dbg_ppu_status, dbg_ppu_addr, \r
- dbg_ppu_data, dbg_ppu_scrl_x, dbg_ppu_scrl_y,\r
- dbg_disp_nt, dbg_disp_attr, dbg_disp_ptn_h, dbg_disp_ptn_l ,\r
- dbg_ppu_addr_we_n ,\r
- dbg_ppu_clk_cnt ,\r
- \r
- ppu_clk, mem_clk, sdram_clk, ppu_ce_n, rst_n, r_nw, addr(2 downto 0), d_io,
- nmi_n, rd_n, wr_n, ale, vram_ad, vram_a,
- vga_out_clk, h_sync_n, v_sync_n, r, g, b,\r
- --SDRAM Signals\r
- wbs_adr_i ,\r
- wbs_dat_i ,\r
- wbs_we_i ,\r
- wbs_tga_i ,\r
- wbs_cyc_i ,\r
- wbs_stb_i ,\r
- wbs_dat_o ,\r
- wbs_stall_o ,\r
- wbs_err_o ,\r
- wbs_ack_o \r
- );
+ ppu_inst: ppu port map (
+ dbg_ppu_ce_n ,
+ dbg_ppu_ctrl, dbg_ppu_mask, dbg_ppu_status ,
+ dbg_ppu_addr ,
+ dbg_ppu_data, dbg_ppu_scrl_x_dummy, dbg_ppu_scrl_y_dummy ,
+
+ dbg_ppu_clk ,
+ dbg_nes_x ,
+ dbg_vga_x ,
+ dbg_disp_nt, dbg_disp_attr ,
+ dbg_disp_ptn_h_dummy, dbg_disp_ptn_l_dummy ,
+ dbg_plt_ce_rn_wn ,
+ dbg_plt_addr ,
+ dbg_plt_data ,
+ dbg_p_oam_ce_rn_wn ,
+ dbg_p_oam_addr ,
+ dbg_p_oam_data ,
+ dbg_s_oam_ce_rn_wn ,
+ dbg_s_oam_addr ,
+ dbg_s_oam_data ,
+ dbg_ppu_addr_we_n ,
+ dbg_ppu_clk_cnt ,
+
+ ppu_clk ,
+ mem_clk ,
+ ppu_ce_n ,
+ rst_n ,
+ r_nw ,
+ addr(2 downto 0) ,
+ d_io ,
+
+ nmi_n ,
+ rd_n ,
+ wr_n ,
+ ale ,
+ vram_ad ,
+ vram_a ,
+
+ vga_clk ,
+ h_sync_n ,
+ v_sync_n ,
+ r ,
+ g ,
+ b
+
+ );
ppu_addr_decoder : v_address_decoder generic map (vram_size14, data_size)
port map (ppu_clk, mem_clk, rd_n, wr_n, ale, v_addr, vram_ad,
v_addr (13 downto 8) <= vram_a;
--transparent d-latch
- vram_latch : ls373 generic map (data_size)
- port map(ale, '0', vram_ad, v_addr(7 downto 0));
+ ale_n <= not ale;
+ vram_latch : ls373 generic map (data_size)
+ port map(vga_clk, ale_n, ale, vram_ad, v_addr(7 downto 0));
vchr_rom : chr_rom generic map (chr_rom_8k, data_size)
port map (mem_clk, pt_ce_n, v_addr(chr_rom_8k - 1 downto 0), vram_ad, nt_v_mirror);
-- --APU/DMA instance
-- apu_inst : apu
-- port map (cpu_clk, apu_ce_n, rst_n, r_nw, addr, d_io, rdy);
-\r
- pll_inst : pll_clk_gen\r
- PORT map ( base_clk, sdram_clk, sdram_clk_locked );\r
-\r
- dram_clk <= sdram_clk;\r
- sdram_ctl_inst : sdram_controller\r
- port map (\r
- --Clocks and Reset \r
- sdram_clk, \r
- rst_n, \r
- sdram_clk_locked,\r
- \r
- --SDRAM Signals\r
- dram_addr ,\r
- dram_bank ,\r
- dram_cas_n ,\r
- dram_cke ,\r
- dram_cs_n ,\r
- dram_dq ,\r
- dram_ldqm ,\r
- dram_udqm ,\r
- dram_ras_n ,\r
- dram_we_n ,\r
- \r
- -- Wishbone Slave signals to Read/Write interface\r
- wbs_adr_i ,\r
- wbs_dat_i ,\r
- wbs_we_i ,\r
- wbs_tga_i ,\r
- wbs_cyc_i ,\r
- wbs_stb_i ,\r
- wbs_dat_o ,\r
- wbs_stall_o ,\r
- wbs_err_o ,\r
- wbs_ack_o ,\r
-\r
- --Debug signals\r
- cmd_ack ,\r
- cmd_done ,\r
- init_st_o ,\r
- main_st_o \r
- ); \r
-
- dbg_cpu_clk <= cpu_clk;
- dbg_ppu_clk <= ppu_clk;
- dbg_mem_clk <= mem_clk;
- dbg_r_nw <= r_nw;
- dbg_addr <= addr;
- dbg_d_io <= d_io;
- dbg_vram_ad <= vram_ad ;
- dbg_vram_a <= vram_a ;
-
end rtl;
use ieee.std_logic_unsigned.conv_integer;
use ieee.std_logic_arith.conv_std_logic_vector;
use std.textio.all;
-use work.motonesfpga_common.all;\r
+use work.motonesfpga_common.all;
--asyncronous rom
entity chr_rom is
return ret(0);
end vmirror;
+--for GHDL environment
--itinialize with the rom_fill function.
-constant p_rom : rom_array := rom_fill;
+--signal p_rom : rom_array := rom_fill;
+
+--for Quartus II environment
+signal p_rom : rom_array;
+attribute ram_init_file : string;
+attribute ram_init_file of p_rom : signal is "sample1-chr.hex";
begin
- nt_v_mirror <= vmirror;
+ --nt_v_mirror <= vmirror;
+ nt_v_mirror <= '1';
p : process (clk)
begin
signal dbg_ppu_ctrl, dbg_ppu_mask, dbg_ppu_status : out std_logic_vector (7 downto 0);
signal dbg_ppu_addr : out std_logic_vector (13 downto 0);
signal dbg_ppu_data, dbg_ppu_scrl_x, dbg_ppu_scrl_y : out std_logic_vector (7 downto 0);
- signal dbg_disp_nt, dbg_disp_attr : out std_logic_vector (7 downto 0);
- signal dbg_disp_ptn_h, dbg_disp_ptn_l : out std_logic_vector (15 downto 0);
- signal dbg_ppu_addr_we_n : out std_logic;
- signal dbg_ppu_clk_cnt : out std_logic_vector(1 downto 0);
+
+ signal dbg_ppu_clk : out std_logic;
+ signal dbg_vga_clk : out std_logic;
+ signal dbg_nes_x : out std_logic_vector (8 downto 0);
+ signal dbg_vga_x : out std_logic_vector (9 downto 0);
+ signal dbg_disp_nt, dbg_disp_attr : out std_logic_vector (7 downto 0);
+ signal dbg_disp_ptn_h, dbg_disp_ptn_l : out std_logic_vector (15 downto 0);
+ signal dbg_plt_ce_rn_wn : out std_logic_vector (2 downto 0);
+ signal dbg_plt_addr : out std_logic_vector (4 downto 0);
+ signal dbg_plt_data : out std_logic_vector (7 downto 0);
+ signal dbg_p_oam_ce_rn_wn : out std_logic_vector (2 downto 0);
+ signal dbg_p_oam_addr : out std_logic_vector (7 downto 0);
+ signal dbg_p_oam_data : out std_logic_vector (7 downto 0);
+ signal dbg_s_oam_ce_rn_wn : out std_logic_vector (2 downto 0);
+ signal dbg_s_oam_addr : out std_logic_vector (4 downto 0);
+ signal dbg_s_oam_data : out std_logic_vector (7 downto 0);
+
+ signal dbg_ppu_addr_we_n : out std_logic;
+ signal dbg_ppu_clk_cnt : out std_logic_vector(1 downto 0);
- clk : in std_logic;
+ ppu_clk : in std_logic;
mem_clk : in std_logic;
- sdram_clk : in std_logic;
ce_n : in std_logic;
rst_n : in std_logic;
r_nw : in std_logic;
cpu_addr : in std_logic_vector (2 downto 0);
cpu_d : inout std_logic_vector (7 downto 0);
+
vblank_n : out std_logic;
rd_n : out std_logic;
wr_n : out std_logic;
ale : out std_logic;
vram_ad : inout std_logic_vector (7 downto 0);
vram_a : out std_logic_vector (13 downto 8);
+
vga_clk : in std_logic;
h_sync_n : out std_logic;
v_sync_n : out std_logic;
r : out std_logic_vector(3 downto 0);
g : out std_logic_vector(3 downto 0);
- b : out std_logic_vector(3 downto 0);
-
- --SDRAM Signals
- wbs_adr_i : out std_logic_vector (21 downto 0); --Address (Bank, Row, Col)
- wbs_dat_i : out std_logic_vector (15 downto 0); --Data In (16 bits)
- wbs_we_i : out std_logic; --Write Enable
- 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)
- wbs_cyc_i : out std_logic; --Cycle Command from interface
- wbs_stb_i : out std_logic; --Strobe Command from interface
- wbs_dat_o : in std_logic_vector (15 downto 0); --Data Out (16 bits)
- wbs_stall_o : in std_logic; --Slave is not ready to receive new data
- wbs_err_o : in std_logic; --Error flag: OOR Burst. Burst length is greater that 256-column address
- wbs_ack_o : in std_logic --When Read Burst: DATA bus must be valid in this cycle
+ b : out std_logic_vector(3 downto 0)
+
);
end ppu;
component ppu_render
port (
- signal dbg_disp_nt, dbg_disp_attr : out std_logic_vector (7 downto 0);
- signal dbg_disp_ptn_h, dbg_disp_ptn_l : out std_logic_vector (15 downto 0);
+ signal dbg_vga_clk : out std_logic;
+ signal dbg_nes_x : out std_logic_vector (8 downto 0);
+ signal dbg_vga_x : out std_logic_vector (9 downto 0);
+ signal dbg_disp_nt, dbg_disp_attr : out std_logic_vector (7 downto 0);
+ signal dbg_disp_ptn_h, dbg_disp_ptn_l : out std_logic_vector (15 downto 0);
+ signal dbg_plt_ce_rn_wn : out std_logic_vector (2 downto 0);
+ signal dbg_plt_addr : out std_logic_vector (4 downto 0);
+ signal dbg_plt_data : out std_logic_vector (7 downto 0);
+ signal dbg_p_oam_ce_rn_wn : out std_logic_vector (2 downto 0);
+ signal dbg_p_oam_addr : out std_logic_vector (7 downto 0);
+ signal dbg_p_oam_data : out std_logic_vector (7 downto 0);
+ signal dbg_s_oam_ce_rn_wn : out std_logic_vector (2 downto 0);
+ signal dbg_s_oam_addr : out std_logic_vector (4 downto 0);
+ signal dbg_s_oam_data : out std_logic_vector (7 downto 0);
- clk : in std_logic;
+ ppu_clk : in std_logic;
+ vga_clk : in std_logic;
mem_clk : in std_logic;
rst_n : in std_logic;
rd_n : out std_logic;
ale : out std_logic;
vram_ad : inout std_logic_vector (7 downto 0);
vram_a : out std_logic_vector (13 downto 8);
- pos_x : out std_logic_vector (8 downto 0);
- pos_y : out std_logic_vector (8 downto 0);
+
+ h_sync_n : out std_logic;
+ v_sync_n : out std_logic;
r : out std_logic_vector (3 downto 0);
g : out std_logic_vector (3 downto 0);
b : out std_logic_vector (3 downto 0);
+
ppu_ctrl : in std_logic_vector (7 downto 0);
ppu_mask : in std_logic_vector (7 downto 0);
read_status : in std_logic;
- ppu_status : out std_logic_vector (7 downto 0);
ppu_scroll_x : in std_logic_vector (7 downto 0);
ppu_scroll_y : in std_logic_vector (7 downto 0);
+ ppu_status : out std_logic_vector (7 downto 0);
+ v_bus_busy_n : out std_logic;
+
r_nw : in std_logic;
oam_bus_ce_n : in std_logic;
plt_bus_ce_n : in std_logic;
oam_plt_addr : in std_logic_vector (7 downto 0);
- oam_plt_data : inout std_logic_vector (7 downto 0);
- v_bus_busy_n : out std_logic
- );
-end component;
-
-component vga_ctl
- port ( ppu_clk : in std_logic;
- sdram_clk : in std_logic;
- vga_clk : in std_logic;
- rst_n : in std_logic;
- pos_x : in std_logic_vector (8 downto 0);
- pos_y : in std_logic_vector (8 downto 0);
- nes_r : in std_logic_vector (3 downto 0);
- nes_g : in std_logic_vector (3 downto 0);
- nes_b : in std_logic_vector (3 downto 0);
- h_sync_n : out std_logic;
- v_sync_n : out std_logic;
- r : out std_logic_vector(3 downto 0);
- g : out std_logic_vector(3 downto 0);
- b : out std_logic_vector(3 downto 0);
-
- --SDRAM Signals
- wbs_adr_i : out std_logic_vector (21 downto 0); --Address (Bank, Row, Col)
- wbs_dat_i : out std_logic_vector (15 downto 0); --Data In (16 bits)
- wbs_we_i : out std_logic; --Write Enable
- 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)
- wbs_cyc_i : out std_logic; --Cycle Command from interface
- wbs_stb_i : out std_logic; --Strobe Command from interface
- wbs_dat_o : in std_logic_vector (15 downto 0); --Data Out (16 bits)
- wbs_stall_o : in std_logic; --Slave is not ready to receive new data
- wbs_err_o : in std_logic; --Error flag: OOR Burst. Burst length is greater that 256-column address
- wbs_ack_o : in std_logic --When Read Burst: DATA bus must be valid in this cycle
+ oam_plt_data : inout std_logic_vector (7 downto 0)
);
end component;
);
end component;
-signal pos_x : std_logic_vector (8 downto 0);
-signal pos_y : std_logic_vector (8 downto 0);
-signal nes_r : std_logic_vector (3 downto 0);
-signal nes_g : std_logic_vector (3 downto 0);
-signal nes_b : std_logic_vector (3 downto 0);
-
constant dsize : integer := 8;
constant PPUCTRL : std_logic_vector(2 downto 0) := "000";
constant PPUADDR : std_logic_vector(2 downto 0) := "110";
constant PPUDATA : std_logic_vector(2 downto 0) := "111";
+constant PPUSBG : integer := 3; --show bg
+constant PPUSSP : integer := 4; --show sprie
+
constant PPUVAI : integer := 2; --vram address increment
constant PPUNEN : integer := 7; --nmi enable
constant ST_VBL : integer := 7; --vblank
-signal clk_n : std_logic;
+signal ppu_clk_n : std_logic;
signal ppu_clk_cnt_res_n : std_logic;
signal ppu_clk_cnt : std_logic_vector(1 downto 0);
begin
+ dbg_ppu_clk <= ppu_clk;
dbg_ppu_ce_n <= ce_n;
dbg_ppu_ctrl <= ppu_ctrl;
dbg_ppu_mask <= ppu_mask;
render_inst : ppu_render port map (
+ dbg_vga_clk ,
+ dbg_nes_x ,
+ dbg_vga_x ,
dbg_disp_nt, dbg_disp_attr, dbg_disp_ptn_h, dbg_disp_ptn_l,
+ dbg_plt_ce_rn_wn ,
+ dbg_plt_addr ,
+ dbg_plt_data ,
+ dbg_p_oam_ce_rn_wn ,
+ dbg_p_oam_addr ,
+ dbg_p_oam_data ,
+ dbg_s_oam_ce_rn_wn ,
+ dbg_s_oam_addr ,
+ dbg_s_oam_data ,
- clk, mem_clk, rst_n,
+ ppu_clk, vga_clk, mem_clk, rst_n,
rd_n, wr_n, ale, vram_ad, vram_a,
- pos_x, pos_y, nes_r, nes_g, nes_b,
- ppu_ctrl, ppu_mask, read_status, ppu_status, ppu_scroll_x, ppu_scroll_y,
+ h_sync_n, v_sync_n, r, g, b,
+ ppu_ctrl, ppu_mask, read_status, ppu_scroll_x, ppu_scroll_y,
+ ppu_status, v_bus_busy_n,
r_nw, oam_bus_ce_n, plt_bus_ce_n,
- oam_plt_addr, oam_plt_data, v_bus_busy_n);
-
- vga_ctl_inst : vga_ctl
- port map ( clk ,
- sdram_clk ,
- vga_clk ,
- rst_n ,
- pos_x ,
- pos_y ,
- nes_r ,
- nes_g ,
- nes_b ,
- h_sync_n ,
- v_sync_n ,
- r ,
- g ,
- b ,
-
- --SDRAM Signals
- wbs_adr_i ,
- wbs_dat_i ,
- wbs_we_i ,
- wbs_tga_i ,
- wbs_cyc_i ,
- wbs_stb_i ,
- wbs_dat_o ,
- wbs_stall_o ,
- wbs_err_o ,
- wbs_ack_o
- );
+ oam_plt_addr, oam_plt_data);
--PPU registers.
- clk_n <= not clk;
+ ppu_clk_n <= not ppu_clk;
ppu_clk_cnt_inst : counter_register generic map (2, 1)
- port map (clk_n, ppu_clk_cnt_res_n, '0', '1', (others => '0'), ppu_clk_cnt);
+ port map (ppu_clk_n, ppu_clk_cnt_res_n, '0', '1', (others => '0'), ppu_clk_cnt);
ppu_ctrl_inst : d_flip_flop generic map(dsize)
- port map (clk_n, rst_n, '1', ppu_ctrl_we_n, cpu_d, ppu_ctrl);
+ port map (ppu_clk_n, rst_n, '1', ppu_ctrl_we_n, cpu_d, ppu_ctrl);
ppu_mask_inst : d_flip_flop generic map(dsize)
- port map (clk_n, rst_n, '1', ppu_mask_we_n, cpu_d, ppu_mask);
+ port map (ppu_clk_n, rst_n, '1', ppu_mask_we_n, cpu_d, ppu_mask);
ppu_status_inst : d_flip_flop generic map(dsize)
port map (read_status, rst_n, '1', '0', ppu_status, ppu_stat_out);
oma_addr_inst : counter_register generic map(dsize, 1)
- port map (clk_n, rst_n, oam_addr_ce_n, oam_addr_we_n, cpu_d, oam_addr);
+ port map (ppu_clk_n, rst_n, oam_addr_ce_n, oam_addr_we_n, cpu_d, oam_addr);
oma_data_inst : d_flip_flop generic map(dsize)
- port map (clk_n, rst_n, '1', oam_data_we_n, cpu_d, oam_data);
+ port map (ppu_clk_n, rst_n, '1', oam_data_we_n, cpu_d, oam_data);
ppu_scroll_x_inst : d_flip_flop generic map(dsize)
- port map (clk_n, rst_n, '1', ppu_scroll_x_we_n, cpu_d, ppu_scroll_x);
+ port map (ppu_clk_n, rst_n, '1', ppu_scroll_x_we_n, cpu_d, ppu_scroll_x);
ppu_scroll_y_inst : d_flip_flop generic map(dsize)
- port map (clk_n, rst_n, '1', ppu_scroll_y_we_n, cpu_d, ppu_scroll_y);
+ port map (ppu_clk_n, rst_n, '1', ppu_scroll_y_we_n, cpu_d, ppu_scroll_y);
ppu_scroll_cnt_inst : counter_register generic map (1, 1)
- port map (clk_n, ppu_latch_rst_n, ppu_scroll_cnt_ce_n,
+ port map (ppu_clk_n, ppu_latch_rst_n, ppu_scroll_cnt_ce_n,
'1', (others => '0'), ppu_scroll_cnt);
+ ppu_addr_in <= cpu_d(5 downto 0) & ppu_addr(7 downto 0)
+ when ppu_addr_cnt(0) = '1' else
+ ppu_addr(13 downto 8) & cpu_d;
+
ppu_addr_inst_inc1 : counter_register generic map(14, 1)
- port map (clk_n, rst_n, ppu_data_we_n, ppu_addr_we_n, ppu_addr_in, ppu_addr_inc1);
+ port map (ppu_clk_n, rst_n, ppu_data_we_n, ppu_addr_we_n, ppu_addr_in, ppu_addr_inc1);
ppu_addr_inst_inc32 : counter_register generic map(14, 32)
- port map (clk_n, rst_n, ppu_data_we_n, ppu_addr_we_n, ppu_addr_in, ppu_addr_inc32);
+ port map (ppu_clk_n, rst_n, ppu_data_we_n, ppu_addr_we_n, ppu_addr_in, ppu_addr_inc32);
ppu_addr <= ppu_addr_inc32 when ppu_ctrl(PPUVAI) = '1' else
ppu_addr_inc1;
ppu_addr_cnt_inst : counter_register generic map (1, 1)
- port map (clk_n, ppu_latch_rst_n, ppu_addr_cnt_ce_n,
+ port map (ppu_clk_n, ppu_latch_rst_n, ppu_addr_cnt_ce_n,
'1', (others => '0'), ppu_addr_cnt);
ppu_data_inst : d_flip_flop generic map(dsize)
- port map (clk_n, rst_n, '1', ppu_data_we_n, cpu_d, ppu_data);
+ port map (ppu_clk_n, rst_n, '1', ppu_data_we_n, cpu_d, ppu_data);
ppu_data_in_inst : d_flip_flop generic map(dsize)
- port map (clk_n, rst_n, '1', ppu_data_we_n, vram_ad, ppu_data_in);
+ port map (ppu_clk_n, rst_n, '1', ppu_data_we_n, vram_ad, ppu_data_in);
ppu_data_out_inst : d_flip_flop generic map(dsize)
port map (read_data_n, rst_n, '1', '0', ppu_data_in, ppu_data_out);
plt_data_out_inst : d_flip_flop generic map(dsize)
- port map (clk_n, rst_n, '1', ppu_data_we_n, oam_plt_data, plt_data_out);
+ port map (ppu_clk_n, rst_n, '1', ppu_data_we_n, oam_plt_data, plt_data_out);
- reg_set_p : process (rst_n, ce_n, r_nw, cpu_addr, cpu_d,
+ reg_set_p : process (rst_n, ce_n, r_nw, cpu_addr,
ppu_status(ST_VBL), ppu_ctrl(PPUNEN))
begin
if (rst_n = '0') then
vblank_n <= '1';
+ ppu_ctrl_we_n <= '1';
+ ppu_mask_we_n <= '1';
+ oam_addr_we_n <= '1';
+ oam_data_we_n <= '1';
+ ppu_scroll_x_we_n <= '1';
+ ppu_scroll_y_we_n <= '1';
+ ppu_scroll_cnt_ce_n <= '1';
+ read_status <= '0';
+ read_data_n <= '1';
elsif (rst_n = '1' and ce_n = '0') then
--register set.
ppu_scroll_cnt_ce_n <= '1';
end if;
- if(cpu_addr = PPUADDR) then
- if (ppu_addr_cnt(0) = '0') then
- ppu_addr_in <= cpu_d(5 downto 0) & ppu_addr(7 downto 0);
- else
- ppu_addr_in <= ppu_addr(13 downto 8) & cpu_d;
- end if;
- end if;
-
if (cpu_addr = PPUDATA and r_nw = '1') then
read_data_n <= '0';
else
ppu_clk_cnt_res_n <= not ce_n;
--cpu and ppu clock timing adjustment...
- clk_cnt_set_p : process (rst_n, ce_n, r_nw, cpu_addr, cpu_d, clk,
- oam_plt_data, vram_ad, ppu_stat_out)
+ clk_cnt_set_p : process (rst_n, ce_n, r_nw, cpu_addr, ppu_clk)
begin
if (rst_n = '0') then
ppu_latch_rst_n <= '0';
ppu_addr_we_n <= '1';
+ oam_addr_ce_n <= '1';
+ ppu_addr_cnt_ce_n <= '1';
+ ppu_data_we_n <= '1';
+ plt_bus_ce_n <= '1';
+ oam_bus_ce_n <= '1';
rd_n <= 'Z';
wr_n <= 'Z';
ale <= 'Z';
-- end if;
--start counter.
- if (clk'event and clk = '0') then
+ if (ppu_clk'event and ppu_clk = '0') then
if (read_status = '1') then
--reading status resets ppu_addr/scroll cnt.
ppu_latch_rst_n <= '0';
--oam data set
if (cpu_addr = OAMDATA and ppu_clk_cnt = "00") then
oam_bus_ce_n <= '0';
- oam_plt_addr <= oam_addr;
- if (r_nw = '1') then
- oam_plt_data <= (others => 'Z');
- cpu_d <= oam_plt_data;
- else
- oam_plt_data <= cpu_d;
- end if;
- --address increment for burst write.
oam_addr_ce_n <= '0';
else
- cpu_d <= (others => 'Z');
- oam_addr_ce_n <= '1';
oam_bus_ce_n <= '1';
+ oam_addr_ce_n <= '1';
end if; --if (cpu_addr = OAMDATA and ppu_clk_cnt = "00") then
- --vram address access.
- if(cpu_addr = PPUADDR and ppu_clk_cnt = "00") then
- ppu_addr_we_n <= '0';
- else
- ppu_addr_we_n <= '1';
- end if;
-
if (cpu_addr = PPUADDR and ppu_clk_cnt = "00") then
ppu_addr_cnt_ce_n <= '0';
if (ppu_addr_cnt(0) = '0') then
ale <= '0';
else
--load addr low and output vram/plt bus.
-
--if address is 3fxx, set palette table.
if (ppu_addr(13 downto 8) = "111111") then
- oam_plt_addr <= cpu_d;
ale <= '0';
else
- vram_ad <= cpu_d;
- vram_a <= ppu_addr(13 downto 8);
ale <= '1';
end if;
end if;
ppu_addr_cnt_ce_n <= '1';
--for burst write.
if (ppu_addr(13 downto 8) = "111111") then
- oam_plt_addr <= ppu_addr(7 downto 0);
ale <= '0';
else
- vram_a <= ppu_addr(13 downto 8);
- vram_ad <= ppu_addr(7 downto 0);
ale <= '1';
end if;
else
ppu_addr_cnt_ce_n <= '1';
- ale <= 'Z';
+ ale <= '0';
end if; --if (cpu_addr = PPUADDR and ppu_clk_cnt = "00") then
+ if (cpu_addr = PPUADDR and ppu_clk_cnt = "01") then
+ ppu_addr_we_n <= '0';
+ elsif (cpu_addr = PPUDATA and ppu_clk_cnt = "10") then
+ ppu_addr_we_n <= '1';
+ else
+ ppu_addr_we_n <= '1';
+ end if; --if (cpu_addr = PPUADDR and ppu_clk_cnt = "01") then
+
if (cpu_addr = PPUDATA and ppu_clk_cnt = "00") then
ppu_data_we_n <= '0';
- vram_a <= ppu_addr(13 downto 8);
if (ppu_addr(13 downto 8) = "111111") then
--case palette tbl.
plt_bus_ce_n <= '0';
- if (r_nw = '0') then
- oam_plt_data <= cpu_d;
- else
- oam_plt_data <= (others => 'Z');
- cpu_d <= oam_plt_data;
- end if;
rd_n <= '1';
wr_n <= '1';
else
+ plt_bus_ce_n <= '1';
rd_n <= not r_nw;
wr_n <= r_nw;
- plt_bus_ce_n <= '1';
- if (r_nw = '0') then
- vram_ad <= cpu_d;
- else
- cpu_d <= ppu_data_out;
- end if;
end if;
else
- plt_bus_ce_n <= '1';
ppu_data_we_n <= '1';
+ plt_bus_ce_n <= '1';
rd_n <= 'Z';
wr_n <= 'Z';
end if; --if (cpu_addr = PPUDATA and ppu_clk_cnt = "00") then
- --sustain cpu output data when reading.
- if (cpu_addr = PPUDATA and r_nw = '1' and ppu_clk_cnt /= "00") then
+ --oam_plt_addr output...
+ if (cpu_addr = OAMDATA and ppu_clk_cnt = "00") then
+ oam_plt_addr <= oam_addr;
+ elsif (cpu_addr = PPUADDR and ppu_clk_cnt = "00") then
+ if (ppu_addr_cnt(0) = '1' and ppu_addr(13 downto 8) = "111111") then
+ oam_plt_addr <= cpu_d;
+ else
+ oam_plt_addr <= (others => 'Z');
+ end if;
+ elsif (cpu_addr = PPUDATA and ppu_clk_cnt = "01") then
if (ppu_addr(13 downto 8) = "111111") then
- cpu_d <= plt_data_out;
+ oam_plt_addr <= ppu_addr(7 downto 0);
else
- cpu_d <= ppu_data_out;
+ oam_plt_addr <= (others => 'Z');
end if;
- end if;
- if (cpu_addr = OAMDATA and r_nw = '1' and ppu_clk_cnt /= "00") then
- cpu_d <= oam_data;
- end if;
+ else
+ oam_plt_addr <= (others => 'Z');
+ end if; --if (cpu_addr = OAMDATA and ppu_clk_cnt = "00") then
- if(cpu_addr = PPUSTATUS and r_nw = '1') then
+ --oam_plt_data output...
+ if (cpu_addr = OAMDATA and ppu_clk_cnt = "00") then
+ if (r_nw = '0') then
+ oam_plt_data <= cpu_d;
+ else
+ oam_plt_data <= (others => 'Z');
+ end if;
+ elsif (cpu_addr = PPUDATA and ppu_clk_cnt = "00") then
+ if (ppu_addr(13 downto 8) = "111111") then
+ if (r_nw = '0') then
+ oam_plt_data <= cpu_d;
+ else
+ oam_plt_data <= (others => 'Z');
+ end if;
+ else
+ oam_plt_data <= (others => 'Z');
+ end if;
+ else
+ oam_plt_data <= (others => 'Z');
+ end if; --if (cpu_addr = OAMDATA and ppu_clk_cnt = "00") then
+
+ --cpu_d data set
+ if (cpu_addr = OAMDATA and r_nw = '1') then
+ if (ppu_clk_cnt = "00") then
+ cpu_d <= oam_plt_data;
+ else
+ cpu_d <= oam_data;
+ end if;
+ elsif (cpu_addr = PPUDATA and r_nw = '1' and ppu_clk_cnt = "00") then
+ if (ppu_clk_cnt = "00") then
+ if (ppu_addr(13 downto 8) = "111111") then
+ cpu_d <= oam_plt_data;
+ else
+ cpu_d <= ppu_data_out;
+ end if;
+ else
+ if (ppu_addr(13 downto 8) = "111111") then
+ cpu_d <= plt_data_out;
+ else
+ cpu_d <= ppu_data_out;
+ end if;
+ end if;
+ elsif (cpu_addr = PPUSTATUS and r_nw = '1') then
cpu_d <= ppu_stat_out;
- end if;
+ else
+ cpu_d <= (others => 'Z');
+ end if; --if (cpu_addr = OAMDATA and ppu_clk_cnt = "00") then
+
+
+
+ --vram_a/vram_ad data set
+ if (cpu_addr = PPUADDR and ppu_clk_cnt = "00" and ppu_addr_cnt(0) = '1') then
+ if (ppu_addr(13 downto 8) = "111111") then
+ vram_a <= (others => 'Z');
+ vram_ad <= (others => 'Z');
+ else
+ vram_a <= ppu_addr(13 downto 8);
+ vram_ad <= cpu_d;
+ end if;
+ elsif (cpu_addr = PPUDATA and ppu_clk_cnt = "01") then
+ if (ppu_addr(13 downto 8) = "111111") then
+ vram_a <= (others => 'Z');
+ vram_ad <= (others => 'Z');
+ else
+ vram_a <= ppu_addr(13 downto 8);
+ vram_ad <= ppu_addr(7 downto 0);
+ end if;
+ elsif (cpu_addr = PPUDATA and ppu_clk_cnt = "00") then
+ vram_a <= ppu_addr(13 downto 8);
+ if (ppu_addr(13 downto 8) = "111111") then
+ vram_ad <= (others => 'Z');
+ else
+ if (r_nw = '0') then
+ vram_ad <= cpu_d;
+ else
+ vram_ad <= (others => 'Z');
+ end if;
+ end if;
+ else
+ vram_a <= (others => 'Z');
+ vram_ad <= (others => 'Z');
+ end if; --if (cpu_addr = PPUADDR and ppu_clk_cnt = "00") then
+
+
+
+
+
else
ppu_addr_we_n <= '1';
rd_n <= 'Z';
wr_n <= 'Z';
- ale <= 'Z';
+ if ppu_mask(PPUSBG) = '1' or ppu_mask(PPUSSP) = '1' then
+ ale <= 'Z';
+ else
+ ale <= '0';
+ end if;
oam_plt_data <= (others => 'Z');
vram_ad <= (others => 'Z');
vram_a <= (others => 'Z');
dsize : integer := 8
);
port ( c : in std_logic;
- oc_n : in std_logic;
+ we_n : in std_logic;\r
+ oc_n : in std_logic;\r
d : in std_logic_vector(dsize - 1 downto 0);
q : out std_logic_vector(dsize - 1 downto 0)
);
architecture rtl of ls373 is
-component data_latch
- generic (
- dsize : integer := 8
- );
- port (
- clk : in std_logic;
- d : in std_logic_vector (dsize - 1 downto 0);
- q : out std_logic_vector (dsize - 1 downto 0)
- );
-end component;
+component d_flip_flop\r
+ generic (\r
+ dsize : integer := 8\r
+ );\r
+ port ( \r
+ clk : in std_logic;\r
+ res_n : in std_logic;\r
+ set_n : in std_logic;\r
+ we_n : in std_logic;\r
+ d : in std_logic_vector (dsize - 1 downto 0);\r
+ q : out std_logic_vector (dsize - 1 downto 0)\r
+ );\r
+end component;\r
component tri_state_buffer
generic (
signal q_out : std_logic_vector (dsize - 1 downto 0);
begin
- ls373_inst : data_latch generic map (dsize)
- port map (c, d, q_out);
+ out_reg_inst : d_flip_flop generic map (dsize)\r
+ port map (c, '1', '1', we_n, d, q_out);\r
tsb_inst : tri_state_buffer generic map (dsize)
port map (oc_n, q_out, q);
end rtl;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.conv_std_logic_vector;
-use ieee.std_logic_unsigned.all;
use work.motonesfpga_common.all;
entity ppu_render is
port (
- signal dbg_disp_nt, dbg_disp_attr : out std_logic_vector (7 downto 0);
- signal dbg_disp_ptn_h, dbg_disp_ptn_l : out std_logic_vector (15 downto 0);
+ signal dbg_vga_clk : out std_logic;
+ signal dbg_nes_x : out std_logic_vector (8 downto 0);
+ signal dbg_vga_x : out std_logic_vector (9 downto 0);
+ signal dbg_disp_nt, dbg_disp_attr : out std_logic_vector (7 downto 0);
+ signal dbg_disp_ptn_h, dbg_disp_ptn_l : out std_logic_vector (15 downto 0);
+ signal dbg_plt_ce_rn_wn : out std_logic_vector (2 downto 0);
+ signal dbg_plt_addr : out std_logic_vector (4 downto 0);
+ signal dbg_plt_data : out std_logic_vector (7 downto 0);
+ signal dbg_p_oam_ce_rn_wn : out std_logic_vector (2 downto 0);
+ signal dbg_p_oam_addr : out std_logic_vector (7 downto 0);
+ signal dbg_p_oam_data : out std_logic_vector (7 downto 0);
+ signal dbg_s_oam_ce_rn_wn : out std_logic_vector (2 downto 0);
+ signal dbg_s_oam_addr : out std_logic_vector (4 downto 0);
+ signal dbg_s_oam_data : out std_logic_vector (7 downto 0);
- clk : in std_logic;
+ ppu_clk : in std_logic;
+ vga_clk : in std_logic;
mem_clk : in std_logic;
rst_n : in std_logic;
+
+ --vram i/f
rd_n : out std_logic;
wr_n : out std_logic;
ale : out std_logic;
vram_ad : inout std_logic_vector (7 downto 0);
vram_a : out std_logic_vector (13 downto 8);
- pos_x : out std_logic_vector (8 downto 0);
- pos_y : out std_logic_vector (8 downto 0);
+
+ --vga output
+ h_sync_n : out std_logic;
+ v_sync_n : out std_logic;
r : out std_logic_vector (3 downto 0);
g : out std_logic_vector (3 downto 0);
b : out std_logic_vector (3 downto 0);
+
+ --upper ppu i/f
ppu_ctrl : in std_logic_vector (7 downto 0);
ppu_mask : in std_logic_vector (7 downto 0);
read_status : in std_logic;
- ppu_status : out std_logic_vector (7 downto 0);
ppu_scroll_x : in std_logic_vector (7 downto 0);
ppu_scroll_y : in std_logic_vector (7 downto 0);
+ ppu_status : out std_logic_vector (7 downto 0);
+ v_bus_busy_n : out std_logic;
+
+ --ppu internal ram access
r_nw : in std_logic;
oam_bus_ce_n : in std_logic;
plt_bus_ce_n : in std_logic;
oam_plt_addr : in std_logic_vector (7 downto 0);
- oam_plt_data : inout std_logic_vector (7 downto 0);
- v_bus_busy_n : out std_logic
+ oam_plt_data : inout std_logic_vector (7 downto 0)
);
end ppu_render;
);
end component;
-component shift_register
- generic (
- dsize : integer := 8;
- shift : integer := 1
- );
- port ( clk : in std_logic;
+component vga_ctl
+ port (
+ signal dbg_vga_clk : out std_logic;
+ signal dbg_nes_x : out std_logic_vector (8 downto 0);
+ signal dbg_vga_x : out std_logic_vector (9 downto 0);
+ signal dbg_disp_nt, dbg_disp_attr : out std_logic_vector (7 downto 0);
+ signal dbg_disp_ptn_h, dbg_disp_ptn_l : out std_logic_vector (15 downto 0);
+ signal dbg_plt_ce_rn_wn : out std_logic_vector (2 downto 0);
+ signal dbg_plt_addr : out std_logic_vector (4 downto 0);
+ signal dbg_plt_data : out std_logic_vector (7 downto 0);
+ signal dbg_p_oam_ce_rn_wn : out std_logic_vector (2 downto 0);
+ signal dbg_p_oam_addr : out std_logic_vector (7 downto 0);
+ signal dbg_p_oam_data : out std_logic_vector (7 downto 0);
+ signal dbg_s_oam_ce_rn_wn : out std_logic_vector (2 downto 0);
+ signal dbg_s_oam_addr : out std_logic_vector (4 downto 0);
+ signal dbg_s_oam_data : out std_logic_vector (7 downto 0);
+
+ vga_clk : in std_logic;
+ mem_clk : in std_logic;
rst_n : in std_logic;
- ce_n : in std_logic;
- we_n : in std_logic;
- d : in std_logic_vector(dsize - 1 downto 0);
- q : out std_logic_vector(dsize - 1 downto 0)
- );
-end component;
-component d_flip_flop
- generic (
- dsize : integer := 8
- );
- port (
- clk : in std_logic;
- res_n : in std_logic;
- set_n : in std_logic;
- we_n : in std_logic;
- d : in std_logic_vector (dsize - 1 downto 0);
- q : out std_logic_vector (dsize - 1 downto 0)
- );
-end component;
+ --vram i/f
+ rd_n : out std_logic;
+ wr_n : out std_logic;
+ ale : out std_logic;
+ vram_ad : inout std_logic_vector (7 downto 0);
+ vram_a : out std_logic_vector (13 downto 8);
-component tri_state_buffer
- generic (
- dsize : integer := 8
- );
- port (
- oe_n : in std_logic;
- d : in std_logic_vector (dsize - 1 downto 0);
- q : out std_logic_vector (dsize - 1 downto 0)
- );
-end component;
+ --vga output
+ h_sync_n : out std_logic;
+ v_sync_n : out std_logic;
+ r : out std_logic_vector (3 downto 0);
+ g : out std_logic_vector (3 downto 0);
+ b : out std_logic_vector (3 downto 0);
-component ram
- generic (abus_size : integer := 16; dbus_size : integer := 8);
- port (
- clk : in std_logic;
- ce_n, oe_n, we_n : in std_logic; --select pin active low.
- addr : in std_logic_vector (abus_size - 1 downto 0);
- d_io : inout std_logic_vector (dbus_size - 1 downto 0)
- );
-end component;
+ --upper ppu i/f
+ ppu_ctrl : in std_logic_vector (7 downto 0);
+ ppu_mask : in std_logic_vector (7 downto 0);
+ read_status : in std_logic;
+ ppu_scroll_x : in std_logic_vector (7 downto 0);
+ ppu_scroll_y : in std_logic_vector (7 downto 0);
-component palette_ram
- generic (abus_size : integer := 16; dbus_size : integer := 8);
- port (
- clk : in std_logic;
- ce_n, oe_n, we_n : in std_logic; --select pin active low.
- addr : in std_logic_vector (abus_size - 1 downto 0);
- d_io : inout std_logic_vector (dbus_size - 1 downto 0)
+ --ppu internal ram access
+ r_nw : in std_logic;
+ oam_bus_ce_n : in std_logic;
+ plt_bus_ce_n : in std_logic;
+ oam_plt_addr : in std_logic_vector (7 downto 0);
+ oam_plt_data : inout std_logic_vector (7 downto 0)
);
end component;
-component ram_ctrl
- port (
- clk : in std_logic;
- ce_n, oe_n, we_n : in std_logic;
- sync_ce_n : out std_logic
- );
-end component;
constant X_SIZE : integer := 9;
-constant dsize : integer := 8;
-constant asize : integer := 14;
constant HSCAN_MAX : integer := 341;
constant VSCAN_MAX : integer := 262;
constant HSCAN : integer := 256;
constant ST_SP0 : integer := 6; --sprite 0 hits
constant ST_VBL : integer := 7; --vblank
-subtype nes_color_data is std_logic_vector (11 downto 0);
-type nes_color_array is array (0 to 63) of nes_color_data;
---ref: http://hlc6502.web.fc2.com/NesPal2.htm
-constant nes_color_palette : nes_color_array := (
- conv_std_logic_vector(16#777#, 12),
- conv_std_logic_vector(16#20b#, 12),
- conv_std_logic_vector(16#20b#, 12),
- conv_std_logic_vector(16#61a#, 12),
- conv_std_logic_vector(16#927#, 12),
- conv_std_logic_vector(16#b13#, 12),
- conv_std_logic_vector(16#a30#, 12),
- conv_std_logic_vector(16#740#, 12),
- conv_std_logic_vector(16#450#, 12),
- conv_std_logic_vector(16#360#, 12),
- conv_std_logic_vector(16#360#, 12),
- conv_std_logic_vector(16#364#, 12),
- conv_std_logic_vector(16#358#, 12),
- conv_std_logic_vector(16#000#, 12),
- conv_std_logic_vector(16#000#, 12),
- conv_std_logic_vector(16#000#, 12),
- conv_std_logic_vector(16#bbb#, 12),
- conv_std_logic_vector(16#46f#, 12),
- conv_std_logic_vector(16#44f#, 12),
- conv_std_logic_vector(16#94f#, 12),
- conv_std_logic_vector(16#d4c#, 12),
- conv_std_logic_vector(16#d46#, 12),
- conv_std_logic_vector(16#e50#, 12),
- conv_std_logic_vector(16#c70#, 12),
- conv_std_logic_vector(16#880#, 12),
- conv_std_logic_vector(16#5a0#, 12),
- conv_std_logic_vector(16#4a1#, 12),
- conv_std_logic_vector(16#4a6#, 12),
- conv_std_logic_vector(16#49c#, 12),
- conv_std_logic_vector(16#000#, 12),
- conv_std_logic_vector(16#000#, 12),
- conv_std_logic_vector(16#000#, 12),
- conv_std_logic_vector(16#fff#, 12),
- conv_std_logic_vector(16#6af#, 12),
- conv_std_logic_vector(16#58f#, 12),
- conv_std_logic_vector(16#a7f#, 12),
- conv_std_logic_vector(16#f6f#, 12),
- conv_std_logic_vector(16#f6b#, 12),
- conv_std_logic_vector(16#f73#, 12),
- conv_std_logic_vector(16#fa0#, 12),
- conv_std_logic_vector(16#ed2#, 12),
- conv_std_logic_vector(16#9e0#, 12),
- conv_std_logic_vector(16#7f4#, 12),
- conv_std_logic_vector(16#7e9#, 12),
- conv_std_logic_vector(16#6de#, 12),
- conv_std_logic_vector(16#777#, 12),
- conv_std_logic_vector(16#000#, 12),
- conv_std_logic_vector(16#000#, 12),
- conv_std_logic_vector(16#fff#, 12),
- conv_std_logic_vector(16#9df#, 12),
- conv_std_logic_vector(16#abf#, 12),
- conv_std_logic_vector(16#cbf#, 12),
- conv_std_logic_vector(16#ebf#, 12),
- conv_std_logic_vector(16#fbe#, 12),
- conv_std_logic_vector(16#fcb#, 12),
- conv_std_logic_vector(16#fda#, 12),
- conv_std_logic_vector(16#ff9#, 12),
- conv_std_logic_vector(16#cf8#, 12),
- conv_std_logic_vector(16#afa#, 12),
- conv_std_logic_vector(16#afc#, 12),
- conv_std_logic_vector(16#aff#, 12),
- conv_std_logic_vector(16#aaa#, 12),
- conv_std_logic_vector(16#000#, 12),
- conv_std_logic_vector(16#000#, 12)
- );
-
-signal clk_n : std_logic;
-
---timing adjust
-signal bg_io_cnt : std_logic_vector(0 downto 0);
-signal spr_io_cnt : std_logic_vector(0 downto 0);
-
---vram i/o
-signal io_oe_n : std_logic;
-signal ah_oe_n : std_logic;
-
-signal cnt_x_res_n : std_logic;
-signal bg_cnt_res_n : std_logic;
-signal cnt_y_en_n : std_logic;
-signal cnt_y_res_n : std_logic;
-
--current drawing position 340 x 261
signal cur_x : std_logic_vector(X_SIZE - 1 downto 0);
signal cur_y : std_logic_vector(X_SIZE - 1 downto 0);
---bg prefetch position (scroll + 16 cycle ahead of current pos)
---511 x 239 (or 255 x 479)
-signal prf_x : std_logic_vector(X_SIZE - 1 downto 0);
-signal prf_y : std_logic_vector(X_SIZE - 1 downto 0);
-
-signal nt_we_n : std_logic;
-signal disp_nt : std_logic_vector (dsize - 1 downto 0);
-
-signal attr_ce_n : std_logic;
-signal attr_we_n : std_logic;
-signal attr_val : std_logic_vector (dsize - 1 downto 0);
-signal disp_attr_we_n : std_logic;
-signal disp_attr : std_logic_vector (dsize - 1 downto 0);
-
-signal ptn_l_we_n : std_logic;
-signal ptn_l_in : std_logic_vector (dsize - 1 downto 0);
-signal ptn_l_val : std_logic_vector (dsize - 1 downto 0);
-signal disp_ptn_l_in : std_logic_vector (dsize * 2 - 1 downto 0);
-signal disp_ptn_l : std_logic_vector (dsize * 2 - 1 downto 0);
-
-signal ptn_h_we_n : std_logic;
-signal ptn_h_in : std_logic_vector (dsize * 2 - 1 downto 0);
-signal disp_ptn_h : std_logic_vector (dsize * 2 - 1 downto 0);
-
---signals for palette / oam access from cpu
-signal r_n : std_logic;
-signal vram_addr : std_logic_vector (asize - 1 downto 0);
-
---palette
-signal plt_ram_ce_n_in : std_logic;
-signal plt_ram_ce_n : std_logic;
-signal plt_r_n : std_logic;
-signal plt_w_n : std_logic;
-signal plt_addr : std_logic_vector (4 downto 0);
-signal plt_data : std_logic_vector (dsize - 1 downto 0);
-
---primari / secondary oam
-signal p_oam_ram_ce_n_in : std_logic;
-signal p_oam_ram_ce_n : std_logic;
-signal p_oam_r_n : std_logic;
-signal p_oam_w_n : std_logic;
-signal p_oam_addr : std_logic_vector (dsize - 1 downto 0);
-signal p_oam_data : std_logic_vector (dsize - 1 downto 0);
-
-signal s_oam_ram_ce_n_in : std_logic;
-signal s_oam_ram_ce_n : std_logic;
-signal s_oam_r_n : std_logic;
-signal s_oam_w_n : std_logic;
-signal s_oam_addr_cpy_ce_n : std_logic;
-signal s_oam_addr_cpy_n : std_logic;
-signal s_oam_addr : std_logic_vector (4 downto 0);
-signal s_oam_addr_cpy : std_logic_vector (4 downto 0);
-signal s_oam_data : std_logic_vector (dsize - 1 downto 0);
-
-signal p_oam_cnt_res_n : std_logic;
-signal p_oam_cnt_ce_n : std_logic;
-signal p_oam_cnt_wrap_n : std_logic;
-signal p_oam_cnt : std_logic_vector (dsize - 1 downto 0);
-signal p_oam_addr_in : std_logic_vector (dsize - 1 downto 0);
-signal oam_ev_status : std_logic_vector (2 downto 0);
-
-signal s_oam_cnt_ce_n : std_logic;
-signal s_oam_cnt : std_logic_vector (4 downto 0);
-
---oam evaluation status
-constant EV_STAT_COMP : std_logic_vector (2 downto 0) := "000";
-constant EV_STAT_CP1 : std_logic_vector (2 downto 0) := "001";
-constant EV_STAT_CP2 : std_logic_vector (2 downto 0) := "010";
-constant EV_STAT_CP3 : std_logic_vector (2 downto 0) := "011";
-constant EV_STAT_PRE_COMP : std_logic_vector (2 downto 0) := "100";
-
-----------sprite registers.
-type oam_pin_array is array (0 to 7) of std_logic;
-type oam_reg_array is array (0 to 7) of std_logic_vector (dsize - 1 downto 0);
-
-signal spr_x_we_n : oam_pin_array;
-signal spr_x_ce_n : oam_pin_array;
-signal spr_attr_we_n : oam_pin_array;
-signal spr_ptn_l_we_n : oam_pin_array;
-signal spr_ptn_h_we_n : oam_pin_array;
-signal spr_ptn_ce_n : oam_pin_array;
-
-signal spr_x_cnt : oam_reg_array;
-signal spr_attr : oam_reg_array;
-signal spr_ptn_l : oam_reg_array;
-signal spr_ptn_h : oam_reg_array;
-
-signal spr_y_we_n : std_logic;
-signal spr_tile_we_n : std_logic;
-signal spr_y_tmp : std_logic_vector (dsize - 1 downto 0);
-signal spr_tile_tmp : std_logic_vector (dsize - 1 downto 0);
-signal spr_ptn_in : std_logic_vector (dsize - 1 downto 0);
-
+signal cnt_x_res_n : std_logic;
+signal cnt_y_en_n : std_logic;
+signal cnt_y_res_n : std_logic;
begin
- dbg_disp_nt <= disp_nt;
- dbg_disp_attr <= disp_attr;
- dbg_disp_ptn_h <= disp_ptn_h;
- dbg_disp_ptn_l <= disp_ptn_l;
-
-
- clk_n <= not clk;
-
- ale <= bg_io_cnt(0) when ppu_mask(PPUSBG) = '1' and
- (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or
- cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE)) and
- (cur_x <= conv_std_logic_vector(HSCAN, X_SIZE) or
- cur_x > conv_std_logic_vector(HSCAN_NEXT_START, X_SIZE)) else
- spr_io_cnt(0) when ppu_mask(PPUSSP) = '1' and
- (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or
- cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE)) and
- (cur_x > conv_std_logic_vector(256, X_SIZE) and
- cur_x <= conv_std_logic_vector(HSCAN_NEXT_START, X_SIZE)) else
- 'Z';
-
- rd_n <= bg_io_cnt(0) when ppu_mask(PPUSBG) = '1' and
- (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or
- cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE)) and
- (cur_x <= conv_std_logic_vector(HSCAN, X_SIZE) or
- cur_x > conv_std_logic_vector(HSCAN_NEXT_START, X_SIZE)) else
- spr_io_cnt(0) when ppu_mask(PPUSSP) = '1' and
- (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or
- cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE)) and
- (cur_x > conv_std_logic_vector(256, X_SIZE) and
- cur_x <= conv_std_logic_vector(HSCAN_NEXT_START, X_SIZE)) else
- 'Z';
- wr_n <= '1' when (ppu_mask(PPUSBG) = '1' or ppu_mask(PPUSSP) = '1') and
- (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or
- cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE)) else
- 'Z';
- io_oe_n <= not bg_io_cnt(0) when ppu_mask(PPUSBG) = '1' and
- (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or
- cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE)) and
- (cur_x <= conv_std_logic_vector(HSCAN, X_SIZE) or
- cur_x > conv_std_logic_vector(HSCAN_NEXT_START, X_SIZE)) else
- not spr_io_cnt(0) when ppu_mask(PPUSSP) = '1' and
- (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or
- cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE)) and
- (cur_x > conv_std_logic_vector(256, X_SIZE) and
- cur_x <= conv_std_logic_vector(HSCAN_NEXT_START, X_SIZE)) else
- '1';
- ah_oe_n <= '0' when (ppu_mask(PPUSBG) = '1' or ppu_mask(PPUSSP) = '1') and
- (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or
- cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE)) else
- '1';
- v_bus_busy_n <= ah_oe_n;
-
- bg_io_cnt_inst : counter_register generic map (1, 1)
- port map (clk, bg_cnt_res_n, '0', '1', (others => '0'), bg_io_cnt);
- spr_io_cnt_inst : counter_register generic map (1, 1)
- port map (clk, cnt_x_res_n, '0', '1', (others => '0'), spr_io_cnt);
-
- ---bg prefetch x pos is 16 + scroll cycle ahead of current pos.
- prf_x <= cur_x + ppu_scroll_x + "000010000"
- when cur_x < conv_std_logic_vector(HSCAN, X_SIZE) else
- cur_x + ppu_scroll_x + "010111011"; -- +16 -341
-
- prf_y <= cur_y + ppu_scroll_y
- when cur_x < conv_std_logic_vector(HSCAN, X_SIZE) and
- cur_y + ppu_scroll_y <
- conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE) else
- cur_y + ppu_scroll_y + "000000001"
- when cur_y + ppu_scroll_y <
- conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE) else
- "000000000";
-
- --current x,y pos
- cur_x_inst : counter_register generic map (X_SIZE, 1)
- port map (clk_n, cnt_x_res_n, '0', '1', (others => '0'), cur_x);
- cur_y_inst : counter_register generic map (X_SIZE, 1)
- port map (clk_n, cnt_y_res_n, cnt_y_en_n, '1', (others => '0'), cur_y);
-
- nt_inst : d_flip_flop generic map(dsize)
- port map (clk_n, rst_n, '1', nt_we_n, vram_ad, disp_nt);
-
- at_inst : d_flip_flop generic map(dsize)
- port map (clk_n, rst_n, '1', attr_we_n, vram_ad, attr_val);
-
- disp_at_inst : shift_register generic map(dsize, 2)
- port map (clk_n, rst_n, attr_ce_n, disp_attr_we_n, attr_val, disp_attr);
-
- --chr rom data's bit is stored in opposite direction.
- --reverse bit when loading...
- ptn_l_in <= (vram_ad(0) & vram_ad(1) & vram_ad(2) & vram_ad(3) &
- vram_ad(4) & vram_ad(5) & vram_ad(6) & vram_ad(7));
- ptn_h_in <= (vram_ad(0) & vram_ad(1) & vram_ad(2) & vram_ad(3) &
- vram_ad(4) & vram_ad(5) & vram_ad(6) & vram_ad(7)) &
- disp_ptn_h (dsize downto 1);
-
- ptn_l_inst : d_flip_flop generic map(dsize)
- port map (clk_n, rst_n, '1', ptn_l_we_n, ptn_l_in, ptn_l_val);
-
- disp_ptn_l_in <= ptn_l_val & disp_ptn_l (dsize downto 1);
- disp_ptn_l_inst : shift_register generic map(dsize * 2, 1)
- port map (clk_n, rst_n, '0', ptn_h_we_n, disp_ptn_l_in, disp_ptn_l);
-
- ptn_h_inst : shift_register generic map(dsize * 2, 1)
- port map (clk_n, rst_n, '0', ptn_h_we_n, ptn_h_in, disp_ptn_h);
-
- --vram i/o
- vram_io_buf : tri_state_buffer generic map (dsize)
- port map (io_oe_n, vram_addr(dsize - 1 downto 0), vram_ad);
-
- vram_a_buf : tri_state_buffer generic map (6)
- port map (ah_oe_n, vram_addr(asize - 1 downto dsize), vram_a);
-
- pos_x <= cur_x;
- pos_y <= cur_y;
-
- ---palette ram
- r_n <= not r_nw;
-
- plt_ram_ce_n_in <= clk when plt_bus_ce_n = '0' and r_nw = '0' else
- '0' when plt_bus_ce_n = '0' and r_nw = '1' else
- '0' when ppu_mask(PPUSBG) = '1' and
- (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and
- (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) else
- '1';
-
- plt_addr <= oam_plt_addr(4 downto 0) when plt_bus_ce_n = '0' else
- "1" & spr_attr(0)(1 downto 0) & spr_ptn_h(0)(0) & spr_ptn_l(0)(0)
- when ppu_mask(PPUSSP) = '1' and
- (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and
- (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) and
- spr_x_cnt(0) = "00000000" and
- (spr_ptn_h(0)(0) or spr_ptn_l(0)(0)) = '1' else
- "1" & spr_attr(1)(1 downto 0) & spr_ptn_h(1)(0) & spr_ptn_l(1)(0)
- when ppu_mask(PPUSSP) = '1' and
- (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and
- (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) and
- spr_x_cnt(1) = "00000000" and
- (spr_ptn_h(1)(0) or spr_ptn_l(1)(0)) = '1' else
- "1" & spr_attr(2)(1 downto 0) & spr_ptn_h(2)(0) & spr_ptn_l(2)(0)
- when ppu_mask(PPUSSP) = '1' and
- (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and
- (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) and
- spr_x_cnt(2) = "00000000" and
- (spr_ptn_h(2)(0) or spr_ptn_l(2)(0)) = '1' else
- "1" & spr_attr(3)(1 downto 0) & spr_ptn_h(3)(0) & spr_ptn_l(3)(0)
- when ppu_mask(PPUSSP) = '1' and
- (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and
- (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) and
- spr_x_cnt(3) = "00000000" and
- (spr_ptn_h(3)(0) or spr_ptn_l(3)(0)) = '1' else
- "1" & spr_attr(4)(1 downto 0) & spr_ptn_h(4)(0) & spr_ptn_l(4)(0)
- when ppu_mask(PPUSSP) = '1' and
- (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and
- (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) and
- spr_x_cnt(4) = "00000000" and
- (spr_ptn_h(4)(0) or spr_ptn_l(4)(0)) = '1' else
- "1" & spr_attr(5)(1 downto 0) & spr_ptn_h(5)(0) & spr_ptn_l(5)(0)
- when ppu_mask(PPUSSP) = '1' and
- (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and
- (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) and
- spr_x_cnt(5) = "00000000" and
- (spr_ptn_h(5)(0) or spr_ptn_l(5)(0)) = '1' else
- "1" & spr_attr(6)(1 downto 0) & spr_ptn_h(6)(0) & spr_ptn_l(6)(0)
- when ppu_mask(PPUSSP) = '1' and
- (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and
- (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) and
- spr_x_cnt(6) = "00000000" and
- (spr_ptn_h(6)(0) or spr_ptn_l(6)(0)) = '1' else
- "1" & spr_attr(7)(1 downto 0) & spr_ptn_h(7)(0) & spr_ptn_l(7)(0)
- when ppu_mask(PPUSSP) = '1' and
- (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and
- (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) and
- spr_x_cnt(7) = "00000000" and
- (spr_ptn_h(7)(0) or spr_ptn_l(7)(0)) = '1' else
- "0" & disp_attr(1 downto 0) & disp_ptn_h(0) & disp_ptn_l(0)
- when ppu_mask(PPUSBG) = '1' and cur_y(4) = '0' and
- ((disp_ptn_h(0) or disp_ptn_l(0)) = '1') and
- (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and
- (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) else
- "0" & disp_attr(5 downto 4) & disp_ptn_h(0) & disp_ptn_l(0)
- when ppu_mask(PPUSBG) = '1' and cur_y(4) = '1' and
- ((disp_ptn_h(0) or disp_ptn_l(0)) = '1') and
- (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and
- (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) else
- ---else: no output color >> universal bg color output.
- --0x3f00 is the universal bg palette.
- (others => '0');
- plt_r_n <= not r_nw when plt_bus_ce_n = '0' else
- '0' when ppu_mask(PPUSBG) = '1' else
- '1';
- plt_w_n <= r_nw when plt_bus_ce_n = '0' else
- '1';
- plt_d_buf_w : tri_state_buffer generic map (dsize)
- port map (r_nw, oam_plt_data, plt_data);
- plt_d_buf_r : tri_state_buffer generic map (dsize)
- port map (r_n, plt_data, oam_plt_data);
- plt_ram_ctl : ram_ctrl
- port map (mem_clk, plt_ram_ce_n_in, plt_r_n, plt_w_n, plt_ram_ce_n);
- palette_inst : palette_ram generic map (5, dsize)
- port map (mem_clk, plt_ram_ce_n, plt_r_n, plt_w_n, plt_addr, plt_data);
-
- ---primary oam
- p_oam_ram_ce_n_in <= clk when oam_bus_ce_n = '0' and r_nw = '0' else
- '0' when oam_bus_ce_n = '0' and r_nw = '1' else
- '0' when ppu_mask(PPUSSP) = '1' and
- cur_x > conv_std_logic_vector(64, X_SIZE) and
- cur_x <= conv_std_logic_vector(256, X_SIZE) and
- p_oam_cnt_wrap_n = '1' else
- '1';
- p_oam_addr <= oam_plt_addr when oam_bus_ce_n = '0' else
- p_oam_addr_in when ppu_mask(PPUSSP) = '1' and
- (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or
- cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE)) and
- cur_x > conv_std_logic_vector(64, X_SIZE) and
- cur_x <= conv_std_logic_vector(256, X_SIZE) else
- (others => 'Z');
- p_oam_r_n <= not r_nw when oam_bus_ce_n = '0' else
- '0' when ppu_mask(PPUSSP) = '1' and
- (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or
- cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE)) and
- cur_x > conv_std_logic_vector(64, X_SIZE) and
- cur_x <= conv_std_logic_vector(256, X_SIZE) else
- '1';
- p_oam_w_n <= r_nw when oam_bus_ce_n = '0' else
- '1';
- oam_d_buf_w : tri_state_buffer generic map (dsize)
- port map (r_nw, oam_plt_data, p_oam_data);
- oam_d_buf_r : tri_state_buffer generic map (dsize)
- port map (r_n, p_oam_data, oam_plt_data);
-
- p_oam_ram_ctl : ram_ctrl
- port map (mem_clk, p_oam_ram_ce_n_in, p_oam_r_n, p_oam_w_n, p_oam_ram_ce_n);
- primary_oam_inst : ram generic map (dsize, dsize)
- port map (mem_clk, p_oam_ram_ce_n, p_oam_r_n, p_oam_w_n, p_oam_addr, p_oam_data);
-
- ---secondary oam
- p_oam_cnt_inst : counter_register generic map (dsize, 4)
- port map (clk_n, p_oam_cnt_res_n, p_oam_cnt_ce_n, '1', (others => '0'), p_oam_cnt);
- s_oam_cnt_inst : counter_register generic map (5, 1)
- port map (clk_n, p_oam_cnt_res_n, s_oam_cnt_ce_n, '1', (others => '0'), s_oam_cnt);
- s_oam_addr_cpy_inst : counter_register generic map (5, 1)
- port map (clk_n, p_oam_cnt_res_n, s_oam_addr_cpy_ce_n,
- '1', (others => '0'), s_oam_addr_cpy);
-
- s_oam_ram_ce_n_in <= clk when ppu_mask(PPUSSP) = '1' and cur_x(0) = '1' and
- cur_x > "000000001" and
- cur_x <= conv_std_logic_vector(64, X_SIZE) else
- clk when ppu_mask(PPUSSP) = '1' and cur_x(0) = '1' and
- cur_x > conv_std_logic_vector(64, X_SIZE) and
- cur_x <= conv_std_logic_vector(256, X_SIZE) and
- p_oam_cnt_wrap_n = '1' else
- '0' when ppu_mask(PPUSSP) = '1' and
- cur_x > conv_std_logic_vector(256, X_SIZE) and
- cur_x <= conv_std_logic_vector(320, X_SIZE) and
- s_oam_addr_cpy_n = '0' else
- '1';
-
- s_oam_ram_ctl : ram_ctrl
- port map (mem_clk, s_oam_ram_ce_n_in, s_oam_r_n, s_oam_w_n, s_oam_ram_ce_n);
--- secondary_oam_inst : ram generic map (5, dsize)
--- port map (mem_clk, s_oam_ram_ce_n, s_oam_r_n, s_oam_w_n, s_oam_addr, s_oam_data);
-
- spr_y_inst : d_flip_flop generic map(dsize)
- port map (clk_n, p_oam_cnt_res_n, '1', spr_y_we_n, s_oam_data, spr_y_tmp);
- spr_tile_inst : d_flip_flop generic map(dsize)
- port map (clk_n, p_oam_cnt_res_n, '1', spr_tile_we_n, s_oam_data, spr_tile_tmp);
-
-
- --reverse bit when NOT SPRHFL is set (.nes file format bit endian).
- spr_ptn_in <= vram_ad when spr_attr(conv_integer(s_oam_addr_cpy(4 downto 2)))(SPRHFL) = '1' else
- (vram_ad(0) & vram_ad(1) & vram_ad(2) & vram_ad(3) &
- vram_ad(4) & vram_ad(5) & vram_ad(6) & vram_ad(7));
- --array instances...
- spr_inst : for i in 0 to 7 generate
- spr_x_inst : counter_register generic map(dsize, 16#ff#)
- port map (clk_n, rst_n, spr_x_ce_n(i), spr_x_we_n(i), s_oam_data, spr_x_cnt(i));
-
- spr_attr_inst : d_flip_flop generic map(dsize)
- port map (clk_n, rst_n, '1', spr_attr_we_n(i), s_oam_data, spr_attr(i));
-
- spr_ptn_l_inst : shift_register generic map(dsize, 1)
- port map (clk_n, rst_n, spr_ptn_ce_n(i), spr_ptn_l_we_n(i), spr_ptn_in, spr_ptn_l(i));
-
- spr_ptn_h_inst : shift_register generic map(dsize, 1)
- port map (clk_n, rst_n, spr_ptn_ce_n(i), spr_ptn_h_we_n(i), spr_ptn_in, spr_ptn_h(i));
- end generate;
+ --vga rendering module instance...
+ vga_render_inst : vga_ctl
+ port map (
+ dbg_vga_clk ,
+ dbg_nes_x ,
+ dbg_vga_x ,
+ dbg_disp_nt, dbg_disp_attr ,
+ dbg_disp_ptn_h, dbg_disp_ptn_l ,
+ dbg_plt_ce_rn_wn ,
+ dbg_plt_addr ,
+ dbg_plt_data ,
+ dbg_p_oam_ce_rn_wn ,
+ dbg_p_oam_addr ,
+ dbg_p_oam_data ,
+ dbg_s_oam_ce_rn_wn ,
+ dbg_s_oam_addr ,
+ dbg_s_oam_data ,
+ vga_clk ,
+ mem_clk ,
+ rst_n ,
+
+ rd_n ,
+ wr_n ,
+ ale ,
+ vram_ad ,
+ vram_a ,
+
+ h_sync_n ,
+ v_sync_n ,
+ r ,
+ g ,
+ b ,
+
+ ppu_ctrl ,
+ ppu_mask ,
+ read_status ,
+ ppu_scroll_x ,
+ ppu_scroll_y ,
+
+ r_nw ,
+ oam_bus_ce_n ,
+ plt_bus_ce_n ,
+ oam_plt_addr ,
+ oam_plt_data
+ );
- pos_p : process (rst_n, clk)
+ pos_p : process (rst_n, ppu_clk)
begin
if (rst_n = '0') then
cnt_x_res_n <= '0';
cnt_y_res_n <= '0';
- bg_cnt_res_n <= '0';
- elsif (clk'event and clk = '0') then
+ elsif (ppu_clk'event and ppu_clk = '0') then
if (cur_x = conv_std_logic_vector(HSCAN_MAX - 1, X_SIZE)) then
--x pos reset.
cnt_x_res_n <= '0';
cnt_y_res_n <= '1';
end if;
- if (ppu_scroll_x(0) = '0' and cur_x = conv_std_logic_vector(HSCAN, X_SIZE)) then
- bg_cnt_res_n <= '0';
- elsif (ppu_scroll_x(0) = '1' and cur_x = conv_std_logic_vector(HSCAN - 1, X_SIZE)) then
- bg_cnt_res_n <= '0';
+ --y pos increment.
+ if (cur_x = conv_std_logic_vector(HSCAN_MAX - 1, X_SIZE)) then
+ cnt_y_en_n <= '0';
else
- bg_cnt_res_n <= '1';
+ cnt_y_en_n <= '1';
end if;
end if; --if (rst_n = '0') then
end process;
- clk_p : process (rst_n, clk, read_status)
-
-procedure output_rgb is
-variable pl_addr : integer;
-variable pl_index : integer;
-variable dot_output : boolean;
-begin
- dot_output := false;
-
- --first show sprite.
- if (ppu_mask(PPUSSP) = '1') then
- for i in 0 to 7 loop
- if (spr_x_cnt(i) = "00000000") then
- if ((spr_ptn_h(i)(0) or spr_ptn_l(i)(0)) = '1') then
- dot_output := true;
- exit;
- end if;
- end if;
- end loop;
- end if;
-
- if (dot_output = true and ppu_mask(PPUSBG) = '1' and
- (disp_ptn_h(0) or disp_ptn_l(0)) = '1') then
- --raise sprite 0 hit.
- ppu_status(ST_SP0) <= '1';
- end if;
+ --manipulate ppu flag procedure.
+ v_bus_busy_n <= '0' when (ppu_mask(PPUSBG) = '1' or ppu_mask(PPUSSP) = '1') and
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or
+ cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE)) else
+ '1';
- --first color in the palette is transparent color.
- if (ppu_mask(PPUSBG) = '1' and dot_output = false and
- (disp_ptn_h(0) or disp_ptn_l(0)) = '1') then
- dot_output := true;
--- d_print("output_rgb");
--- d_print("pl_addr:" & conv_hex8(pl_addr));
--- d_print("pl_index:" & conv_hex8(pl_index));
- end if;
+ ppu_flag_p : process (rst_n, ppu_clk, read_status)
- --if or if not bg/sprite is shown, output color anyway
- --sinse universal bg color is included..
- pl_index := conv_integer(plt_data(5 downto 0));
- b <= nes_color_palette(pl_index) (11 downto 8);
- g <= nes_color_palette(pl_index) (7 downto 4);
- r <= nes_color_palette(pl_index) (3 downto 0);
--- d_print("rgb:" &
--- conv_hex8(nes_color_palette(pl_index) (11 downto 8)) &
--- conv_hex8(nes_color_palette(pl_index) (7 downto 4)) &
--- conv_hex8(nes_color_palette(pl_index) (3 downto 0)));
+procedure set_spr0_hit is
+begin
+ --not ready yet...
end;
begin
if (rst_n = '0') then
- nt_we_n <= '1';
-
ppu_status <= (others => '0');
-
- b <= (others => '0');
- g <= (others => '0');
- r <= (others => '0');
else
- if (clk'event and clk = '1') then
- --y pos increment.
- if (cur_x = conv_std_logic_vector(HSCAN_MAX - 1, X_SIZE)) then
- cnt_y_en_n <= '0';
- else
- cnt_y_en_n <= '1';
- end if;
- end if; --if (clk'event) then
-
- if (clk'event and clk = '0') then
- d_print("-");
- end if;
-
- if (clk'event and clk = '1') then
-
- --fetch bg pattern and display.
- if (ppu_mask(PPUSBG) = '1' and
- (cur_x <= conv_std_logic_vector(HSCAN, X_SIZE) or
- cur_x > conv_std_logic_vector(HSCAN_NEXT_START, X_SIZE)) and
- (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or
- cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE))) then
- --visible area bg image
-
- d_print("*");
- d_print("cur_x: " & conv_hex16(conv_integer(cur_x)));
- d_print("cur_y: " & conv_hex16(conv_integer(cur_y)));
-
- ----fetch next tile byte.
- if (prf_x (2 downto 0) = "001") then
- --vram addr is incremented every 8 cycle.
- --name table at 0x2000
- vram_addr(9 downto 0)
- <= prf_y(dsize - 1 downto 3)
- & prf_x(dsize - 1 downto 3);
- vram_addr(asize - 1 downto 10) <= "10" & ppu_ctrl(PPUBNA downto 0)
- + ("000" & prf_x(dsize));
- end if;
- if (prf_x (2 downto 0) = "010") then
- nt_we_n <= '0';
- else
- nt_we_n <= '1';
- end if;
-
- --TODO must load 8 cycle each for the first two tiles!!!
- ----fetch attr table byte.
- if (prf_x (4 downto 0) = "00011") then
- --attribute table is loaded every 32 cycle.
- --attr table at 0x23c0
- vram_addr(dsize - 1 downto 0) <= "11000000" +
- ("00" & prf_y(7 downto 5) & prf_x(7 downto 5));
- vram_addr(asize - 1 downto dsize) <= "10" &
- ppu_ctrl(PPUBNA downto 0) & "11"
- + ("000" & prf_x(dsize) & "00");
- end if;
- if (prf_x (4 downto 0) = "00100") then
- attr_we_n <= '0';
- else
- attr_we_n <= '1';
- end if;
- if (prf_x (4 downto 0) = "10000") then
- disp_attr_we_n <= '0';
- else
- disp_attr_we_n <= '1';
- end if;
- ---attribute is shifted every 16 bit.
- if (prf_x (3 downto 0) = "0000") then
- attr_ce_n <= '0';
- else
- attr_ce_n <= '1';
- end if;
-
- ----fetch pattern table low byte.
- if (prf_x (2 downto 0) = "101") then
- --vram addr is incremented every 8 cycle.
- vram_addr <= "0" & ppu_ctrl(PPUBPA) &
- disp_nt(dsize - 1 downto 0)
- & "0" & prf_y(2 downto 0);
- end if;
- if (prf_x (2 downto 0) = "110") then
- ptn_l_we_n <= '0';
- else
- ptn_l_we_n <= '1';
- end if;
-
- ----fetch pattern table high byte.
- if (prf_x (2 downto 0) = "111") then
- --vram addr is incremented every 8 cycle.
- vram_addr <= "0" & ppu_ctrl(PPUBPA) &
- disp_nt(dsize - 1 downto 0)
- & "0" & prf_y(2 downto 0) + "00000000001000";
- end if;
- if (prf_x (2 downto 0) = "000") then
- ptn_h_we_n <= '0';
- else
- ptn_h_we_n <= '1';
- end if;
-
- end if;--if (ppu_mask(PPUSBG) = '1') and
-
- --fetch sprite and display.
- if (ppu_mask(PPUSSP) = '1' and
- (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or
- cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE))) then
- --secondary oam clear
- if (cur_x /= "000000000" and cur_x <= conv_std_logic_vector(64, X_SIZE)) then
- if (cur_x(0) = '0') then
- --write secondary oam on even cycle
- s_oam_r_n <= '1';
- s_oam_w_n <= '0';
- s_oam_addr <= cur_x(5 downto 1);
- s_oam_data <= (others => '1');
- end if;
- p_oam_cnt_res_n <= '0';
- p_oam_cnt_ce_n <= '1';
- s_oam_cnt_ce_n <= '1';
- p_oam_cnt_wrap_n <= '1';
- oam_ev_status <= EV_STAT_COMP;
-
- --sprite evaluation and secondary oam copy.
- elsif (cur_x > conv_std_logic_vector(64, X_SIZE) and
- cur_x <= conv_std_logic_vector(256, X_SIZE)) then
- p_oam_cnt_res_n <= '1';
-
- --TODO: sprite evaluation is simplified!!
- --not complying the original NES spec at
- --http://wiki.nesdev.com/w/index.php/PPU_sprite_evaluation
- --e.g., when overflow happens, it just ignore subsequent entry.
- --old secondary sprite entry.
- if (p_oam_cnt = "00000000" and cur_x > conv_std_logic_vector(192, X_SIZE)) then
- p_oam_cnt_wrap_n <= '0';
- end if;
-
- --odd cycle copy from primary oam
- if (cur_x(0) = '1') then
- if (oam_ev_status = EV_STAT_COMP) then
- p_oam_addr_in <= p_oam_cnt;
- p_oam_cnt_ce_n <= '1';
- s_oam_cnt_ce_n <= '1';
- elsif (oam_ev_status = EV_STAT_CP1) then
- p_oam_addr_in <= p_oam_cnt + "00000001";
- s_oam_cnt_ce_n <= '1';
-
- elsif (oam_ev_status = EV_STAT_CP2) then
- p_oam_addr_in <= p_oam_cnt + "00000010";
- s_oam_cnt_ce_n <= '1';
-
- elsif (oam_ev_status = EV_STAT_CP3) then
- oam_ev_status <= EV_STAT_PRE_COMP;
- p_oam_addr_in <= p_oam_cnt + "00000011";
- s_oam_cnt_ce_n <= '1';
- end if;
- else
- --even cycle copy to secondary oam (if y is in range.)
- s_oam_r_n <= '1';
- s_oam_w_n <= '0';
- s_oam_addr <= s_oam_cnt;
- s_oam_data <= p_oam_data;
-
- if (oam_ev_status = EV_STAT_COMP) then
- --check y range.
- if (cur_y < "000000110" and p_oam_data <= cur_y + "000000001") or
- (cur_y >= "000000110" and p_oam_data <= cur_y + "000000001" and
- p_oam_data >= cur_y - "000000110") then
- oam_ev_status <= EV_STAT_CP1;
- s_oam_cnt_ce_n <= '0';
- --copy remaining oam entry.
- p_oam_cnt_ce_n <= '1';
- else
- --goto next entry
- p_oam_cnt_ce_n <= '0';
- end if;
- elsif (oam_ev_status = EV_STAT_CP1) then
- s_oam_cnt_ce_n <= '0';
- oam_ev_status <= EV_STAT_CP2;
- elsif (oam_ev_status = EV_STAT_CP2) then
- s_oam_cnt_ce_n <= '0';
- oam_ev_status <= EV_STAT_CP3;
- elsif (oam_ev_status = EV_STAT_CP3) then
- s_oam_cnt_ce_n <= '0';
- elsif (oam_ev_status = EV_STAT_PRE_COMP) then
- oam_ev_status <= EV_STAT_COMP;
- s_oam_cnt_ce_n <= '0';
- p_oam_cnt_ce_n <= '0';
- end if;
- end if;--if (cur_x(0) = '1') then
-
- --prepare for next step
- s_oam_addr_cpy_n <= '1';
- spr_y_we_n <= '1';
- spr_tile_we_n <= '1';
- spr_x_we_n <= "11111111";
- spr_attr_we_n <= "11111111";
- spr_ptn_l_we_n <= "11111111";
- spr_ptn_h_we_n <= "11111111";
-
- --sprite pattern fetch
- elsif (cur_x > conv_std_logic_vector(256, X_SIZE) and
- cur_x <= conv_std_logic_vector(HSCAN_NEXT_START, X_SIZE)) then
-
- s_oam_addr_cpy_n <= '0';
- s_oam_r_n <= '0';
- s_oam_w_n <= '1';
- s_oam_addr <= s_oam_addr_cpy;
-
- ----fetch y-cordinate from secondary oam
- if (cur_x (2 downto 0) = "001" ) then
- s_oam_addr_cpy_ce_n <= '0';
- spr_y_we_n <= '0';
- else
- spr_y_we_n <= '1';
- end if;
-
- ----fetch tile number
- if (cur_x (2 downto 0) = "010" ) then
- spr_tile_we_n <= '0';
- else
- spr_tile_we_n <= '1';
- end if;
-
- ----fetch attribute
- if (cur_x (2 downto 0) = "011" ) then
- spr_attr_we_n(conv_integer(s_oam_addr_cpy(4 downto 2))) <= '0';
- else
- spr_attr_we_n(conv_integer(s_oam_addr_cpy(4 downto 2))) <= '1';
- end if;--if (cur_x (2 downto 0) = "010" ) then
-
- ----fetch x-cordinate
- if (cur_x (2 downto 0) = "100" ) then
- s_oam_addr_cpy_ce_n <= '1';
- spr_x_we_n(conv_integer(s_oam_addr_cpy(4 downto 2))) <= '0';
- else
- spr_x_we_n(conv_integer(s_oam_addr_cpy(4 downto 2))) <= '1';
- end if;
-
- ----fetch pattern table low byte.
- if (cur_x (2 downto 0) = "101" ) then
- if (spr_attr(conv_integer(s_oam_addr_cpy(4 downto 2)))(SPRVFL) = '0') then
- vram_addr <= "0" & ppu_ctrl(PPUSPA) &
- spr_tile_tmp(dsize - 1 downto 0) & "0" &
- (cur_y(2 downto 0) + "001" - spr_y_tmp(2 downto 0));
- else
- --flip sprite vertically.
- vram_addr <= "0" & ppu_ctrl(PPUSPA) &
- spr_tile_tmp(dsize - 1 downto 0) & "0" &
- (spr_y_tmp(2 downto 0) - cur_y(2 downto 0) - "010");
- end if;
- end if;
-
- if (cur_x (2 downto 0) = "110" ) then
- spr_ptn_l_we_n(conv_integer(s_oam_addr_cpy(4 downto 2))) <= '0';
- else
- spr_ptn_l_we_n(conv_integer(s_oam_addr_cpy(4 downto 2))) <= '1';
- end if;
-
- ----fetch pattern table high byte.
- if (cur_x (2 downto 0) = "111" ) then
- if (spr_attr(conv_integer(s_oam_addr_cpy(4 downto 2)))(SPRVFL) = '0') then
- vram_addr <= "0" & ppu_ctrl(PPUSPA) &
- spr_tile_tmp(dsize - 1 downto 0) & "0" &
- (cur_y(2 downto 0) + "001" - spr_y_tmp(2 downto 0))
- + "00000000001000";
- else
- --flip sprite vertically.
- vram_addr <= "0" & ppu_ctrl(PPUSPA) &
- spr_tile_tmp(dsize - 1 downto 0) & "0" &
- (spr_y_tmp(2 downto 0) - cur_y(2 downto 0) - "010")
- + "00000000001000";
- end if;
- end if;
-
- if (cur_x (2 downto 0) = "000") then
- spr_ptn_h_we_n(conv_integer(s_oam_addr_cpy(4 downto 2))) <= '0';
- s_oam_addr_cpy_ce_n <= '0';
- else
- spr_ptn_h_we_n(conv_integer(s_oam_addr_cpy(4 downto 2) - "001")) <= '1';
- end if;
-
- elsif (cur_x > conv_std_logic_vector(320, X_SIZE)) then
- --clear last write enable.
- spr_ptn_h_we_n <= "11111111";
- end if;--if (cur_x /= "000000000" and cur_x <= conv_std_logic_vector(64, X_SIZE))
-
- --display sprite.
- if ((cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and
- (cur_y < conv_std_logic_vector(VSCAN, X_SIZE))) then
- --start counter.
- if (cur_x = "000000000") then
- spr_x_ce_n <= "00000000";
- end if;
-
- for i in 0 to 7 loop
- if (spr_x_cnt(i) = "00000000") then
- --active sprite, start shifting..
- spr_x_ce_n(i) <= '1';
- spr_ptn_ce_n(i) <= '0';
- end if;
- end loop;
- else
- spr_x_ce_n <= "11111111";
- spr_ptn_ce_n <= "11111111";
- end if; --if ((cur_x < conv_std_logic_vector(HSCAN, X_SIZE))
- end if; --if (ppu_mask(PPUSSP) = '1') then
-
- --output visible area only.
+ if (ppu_clk'event and ppu_clk = '1') then
if ((cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and
(cur_y < conv_std_logic_vector(VSCAN, X_SIZE))) then
- --output image.
- output_rgb;
+ --check if sprite 0 is hit.
+ set_spr0_hit;
end if;
--flag operation
ppu_status(ST_SOF) <= '0';
end if;
end if; --if (clk'event and clk = '1') then
-
--- if (read_status'event and read_status = '1') then
--- --reading ppu status clears vblank bit.
--- ppu_status(ST_VBL) <= '0';
--- end if;
-
end if;--if (rst_n = '0') then
end process;
-------------------------------------------------------------\r
-------------------------------------------------------------\r
--------------- VGA RGB Output Control w/ SDRAM --------------\r
+------------------- PPU VGA Output Control ------------------\r
-------------------------------------------------------------\r
-------------------------------------------------------------\r
\r
-
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.std_logic_unsigned.conv_integer;
-use ieee.std_logic_arith.conv_std_logic_vector;
-use work.motonesfpga_common.all;
-
-entity vga_ctl is
- port ( ppu_clk : in std_logic;
- sdram_clk : in std_logic;\r
- vga_clk : in std_logic;
- rst_n : in std_logic;
- pos_x : in std_logic_vector (8 downto 0);
- pos_y : in std_logic_vector (8 downto 0);
- nes_r : in std_logic_vector (3 downto 0);
- nes_g : in std_logic_vector (3 downto 0);
- nes_b : in std_logic_vector (3 downto 0);
- h_sync_n : out std_logic;
- v_sync_n : out std_logic;
- r : out std_logic_vector(3 downto 0);
- g : out std_logic_vector(3 downto 0);
- b : out std_logic_vector(3 downto 0);
-\r
- --SDRAM Signals\r
- wbs_adr_i : out std_logic_vector (21 downto 0); --Address (Bank, Row, Col)\r
- wbs_dat_i : out std_logic_vector (15 downto 0); --Data In (16 bits)\r
- wbs_we_i : out std_logic; --Write Enable\r
- 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
- wbs_cyc_i : out std_logic; --Cycle Command from interface\r
- wbs_stb_i : out std_logic; --Strobe Command from interface\r
- wbs_dat_o : in std_logic_vector (15 downto 0); --Data Out (16 bits)\r
- wbs_stall_o : in std_logic; --Slave is not ready to receive new data\r
- wbs_err_o : in std_logic; --Error flag: OOR Burst. Burst length is greater that 256-column address\r
- wbs_ack_o : in std_logic --When Read Burst: DATA bus must be valid in this cycle\r
- );
-end vga_ctl;
-
-architecture rtl of vga_ctl is
-
-component counter_register
- generic (
- dsize : integer := 8;
- inc : integer := 1
- );
- port ( clk : in std_logic;
- rst_n : in std_logic;
- ce_n : in std_logic;
- we_n : in std_logic;
- d : in std_logic_vector(dsize - 1 downto 0);
- q : out std_logic_vector(dsize - 1 downto 0)
- );
-end component;
+library ieee;\r
+use ieee.std_logic_1164.all;\r
+use ieee.std_logic_unsigned.conv_integer;\r
+use ieee.std_logic_arith.conv_std_logic_vector;\r
+use ieee.std_logic_unsigned.all;\r
+use work.motonesfpga_common.all;\r
\r
-component d_flip_flop\r
- generic (\r
- dsize : integer := 8\r
- );\r
+entity vga_ctl is \r
port ( \r
- clk : in std_logic;\r
- res_n : in std_logic;\r
- set_n : in std_logic;\r
- we_n : in std_logic;\r
- d : in std_logic_vector (dsize - 1 downto 0);\r
- q : out std_logic_vector (dsize - 1 downto 0)\r
- );\r
-end component;\r
+ signal dbg_vga_clk : out std_logic;\r
+ signal dbg_nes_x : out std_logic_vector (8 downto 0);\r
+ signal dbg_vga_x : out std_logic_vector (9 downto 0);\r
+ signal dbg_disp_nt, dbg_disp_attr : out std_logic_vector (7 downto 0);\r
+ signal dbg_disp_ptn_h, dbg_disp_ptn_l : out std_logic_vector (15 downto 0);\r
+ signal dbg_plt_ce_rn_wn : out std_logic_vector (2 downto 0);\r
+ signal dbg_plt_addr : out std_logic_vector (4 downto 0);\r
+ signal dbg_plt_data : out std_logic_vector (7 downto 0);\r
+ signal dbg_p_oam_ce_rn_wn : out std_logic_vector (2 downto 0);\r
+ signal dbg_p_oam_addr : out std_logic_vector (7 downto 0);\r
+ signal dbg_p_oam_data : out std_logic_vector (7 downto 0);\r
+ signal dbg_s_oam_ce_rn_wn : out std_logic_vector (2 downto 0);\r
+ signal dbg_s_oam_addr : out std_logic_vector (4 downto 0);\r
+ signal dbg_s_oam_data : out std_logic_vector (7 downto 0);\r
+\r
+ vga_clk : in std_logic;\r
+ mem_clk : in std_logic;\r
+ rst_n : in std_logic;\r
+\r
+ --vram i/f\r
+ rd_n : out std_logic;\r
+ wr_n : out std_logic;\r
+ ale : out std_logic;\r
+ vram_ad : inout std_logic_vector (7 downto 0);\r
+ vram_a : out std_logic_vector (13 downto 8);\r
+\r
+ --vga output\r
+ h_sync_n : out std_logic;\r
+ v_sync_n : out std_logic;\r
+ r : out std_logic_vector (3 downto 0);\r
+ g : out std_logic_vector (3 downto 0);\r
+ b : out std_logic_vector (3 downto 0);\r
\r
+ --upper ppu i/f\r
+ ppu_ctrl : in std_logic_vector (7 downto 0);\r
+ ppu_mask : in std_logic_vector (7 downto 0);\r
+ read_status : in std_logic;\r
+ ppu_scroll_x : in std_logic_vector (7 downto 0);\r
+ ppu_scroll_y : in std_logic_vector (7 downto 0);\r
\r
---------- screen constant -----------
-constant VGA_W : integer := 640;
-constant VGA_H : integer := 480;
-constant VGA_W_MAX : integer := 800;
-constant VGA_H_MAX : integer := 525;
-constant H_SP : integer := 95;
-constant H_BP : integer := 48;
-constant H_FP : integer := 15;
-constant V_SP : integer := 2;
-constant V_BP : integer := 33;
-constant V_FP : integer := 10;
+ --ppu internal ram access\r
+ r_nw : in std_logic;\r
+ oam_bus_ce_n : in std_logic;\r
+ plt_bus_ce_n : in std_logic;\r
+ oam_plt_addr : in std_logic_vector (7 downto 0);\r
+ oam_plt_data : inout std_logic_vector (7 downto 0)\r
+ );\r
+end vga_ctl;\r
+\r
+architecture rtl of vga_ctl is\r
\r
-constant NES_W : integer := 256;\r
-constant NES_H : integer := 240;\r
-
+component counter_register\r
+ generic (\r
+ dsize : integer := 8;\r
+ inc : integer := 1\r
+ );\r
+ port ( clk : in std_logic;\r
+ rst_n : in std_logic;\r
+ ce_n : in std_logic;\r
+ we_n : in std_logic;\r
+ d : in std_logic_vector(dsize - 1 downto 0);\r
+ q : out std_logic_vector(dsize - 1 downto 0)\r
+ );\r
+end component;\r
+\r
+component ppu_vga_render\r
+ port ( \r
+ signal dbg_vga_clk : out std_logic;\r
+ signal dbg_nes_x : out std_logic_vector (8 downto 0);\r
+ signal dbg_disp_nt, dbg_disp_attr : out std_logic_vector (7 downto 0);\r
+ signal dbg_disp_ptn_h, dbg_disp_ptn_l : out std_logic_vector (15 downto 0);\r
+ signal dbg_plt_ce_rn_wn : out std_logic_vector (2 downto 0);\r
+ signal dbg_plt_addr : out std_logic_vector (4 downto 0);\r
+ signal dbg_plt_data : out std_logic_vector (7 downto 0);\r
+ signal dbg_p_oam_ce_rn_wn : out std_logic_vector (2 downto 0);\r
+ signal dbg_p_oam_addr : out std_logic_vector (7 downto 0);\r
+ signal dbg_p_oam_data : out std_logic_vector (7 downto 0);\r
+ signal dbg_s_oam_ce_rn_wn : out std_logic_vector (2 downto 0);\r
+ signal dbg_s_oam_addr : out std_logic_vector (4 downto 0);\r
+ signal dbg_s_oam_data : out std_logic_vector (7 downto 0);\r
+ \r
+ vga_clk : in std_logic;\r
+ mem_clk : in std_logic;\r
+ rst_n : in std_logic;\r
+ rd_n : out std_logic;\r
+ wr_n : out std_logic;\r
+ ale : out std_logic;\r
+ vram_ad : inout std_logic_vector (7 downto 0);\r
+ vram_a : out std_logic_vector (13 downto 8);\r
+ cur_x : in std_logic_vector (8 downto 0);\r
+ cur_y : in std_logic_vector (8 downto 0);\r
+ r : out std_logic_vector (3 downto 0);\r
+ g : out std_logic_vector (3 downto 0);\r
+ b : out std_logic_vector (3 downto 0);\r
+ ppu_ctrl : in std_logic_vector (7 downto 0);\r
+ ppu_mask : in std_logic_vector (7 downto 0);\r
+ read_status : in std_logic;\r
+ ppu_status : out std_logic_vector (7 downto 0);\r
+ ppu_scroll_x : in std_logic_vector (7 downto 0);\r
+ ppu_scroll_y : in std_logic_vector (7 downto 0);\r
+ \r
+ r_nw : in std_logic;\r
+ oam_bus_ce_n : in std_logic;\r
+ plt_bus_ce_n : in std_logic;\r
+ oam_plt_addr : in std_logic_vector (7 downto 0);\r
+ oam_plt_data : inout std_logic_vector (7 downto 0);\r
+ v_bus_busy_n : out std_logic\r
+ );\r
+end component;\r
+\r
+--------- screen constant -----------\r
+constant VGA_W : integer := 640;\r
+constant VGA_H : integer := 480;\r
+constant VGA_W_MAX : integer := 800;\r
+constant VGA_H_MAX : integer := 525;\r
+constant H_SP : integer := 95;\r
+constant H_BP : integer := 48;\r
+constant H_FP : integer := 15;\r
+constant V_SP : integer := 2;\r
+constant V_BP : integer := 33;\r
+constant V_FP : integer := 10;\r
\r
--------- signal declaration -----------\r
-signal vga_x : std_logic_vector (9 downto 0);
-signal vga_y : std_logic_vector (9 downto 0);
+signal vga_x : std_logic_vector (9 downto 0);\r
+signal vga_y : std_logic_vector (9 downto 0);\r
signal x_res_n : std_logic;\r
signal y_res_n : std_logic;\r
signal y_en_n : std_logic;\r
+signal cnt_clk : std_logic;\r
\r
-signal cnt_clk : std_logic;
-signal mem_cnt : std_logic_vector (4 downto 0);\r
-\r
-signal count5_res_n : std_logic;\r
-signal count5 : std_logic_vector(2 downto 0);\r
-signal nes_x_en_n : std_logic;\r
-signal nes_x : std_logic_vector(7 downto 0);\r
-\r
-signal dram_col_we_n : std_logic;\r
-signal dram_col : std_logic_vector(15 downto 0);\r
+signal emu_ppu_clk : std_logic;\r
+signal emu_ppu_clk_n : std_logic;\r
+signal count5_res_n : std_logic;\r
+signal count5 : std_logic_vector(2 downto 0);\r
+signal nes_x : std_logic_vector (8 downto 0);\r
+signal nes_y : std_logic_vector (8 downto 0);\r
\r
-signal pos_x_we_n : std_logic;\r
-signal pos_x_old : std_logic_vector(8 downto 0);\r
-signal nes_x_we_n : std_logic;\r
-signal nes_x_old : std_logic_vector(7 downto 0);\r
\r
-type sdram_write_status is (sw_idle, sw_write, sw_write_ack);\r
-type sdram_read_status is (sr_idle, sr_read_wait, sr_read, sr_read_ack);\r
-\r
-signal sw_state : sdram_write_status;\r
-signal sr_state : sdram_read_status;\r
-constant SDRAM_READ_WAIT_CNT : integer := 10;\r
\r
+-----dummy signal\r
+signal v_bus_busy_n : std_logic;\r
+signal ppu_status : std_logic_vector (7 downto 0);\r
+signal rr : std_logic_vector (3 downto 0);\r
+signal gg : std_logic_vector (3 downto 0);\r
+signal bb : std_logic_vector (3 downto 0);\r
\r
---DE1 base clock 50 MHz\r
---motones sim project uses following clock.\r
--ppu clock = base clock / 8\r
--vga clock = base clock / 2\r
--sdram clock = 135 MHz\r
-
-begin
-
- cnt_clk <= not vga_clk;\r
- x_inst : counter_register generic map (10, 1)
- port map (cnt_clk , x_res_n, '0', '1', (others => '0'), vga_x);
-\r
- pos_x_old_inst: d_flip_flop generic map (9)\r
- port map (sdram_clk, rst_n, '1', pos_x_we_n, pos_x, pos_x_old);\r
-\r
- nes_x_old_inst: d_flip_flop generic map (8)\r
- port map (sdram_clk, rst_n, '1', nes_x_we_n, nes_x, nes_x_old);\r
- \r
- y_inst : counter_register generic map (10, 1)
- port map (cnt_clk , y_res_n, y_en_n, '1', (others => '0'), vga_y);
- mem_cnt_inst : counter_register generic map (5, 1)\r
- port map (sdram_clk , x_res_n, '0', '1', (others => '0'), mem_cnt);\r
\r
- count5_inst : counter_register generic map (3, 1)\r
- port map (cnt_clk, count5_res_n, '0', '1', (others => '0'), count5);\r
+begin\r
+ dbg_vga_x <= vga_x;\r
\r
- nes_x_inst : counter_register generic map (8, 1)\r
- port map (vga_clk, x_res_n, nes_x_en_n, '1', (others => '0'), nes_x);\r
- \r
- col_inst : d_flip_flop generic map (16)\r
- port map (sdram_clk, rst_n, '1', dram_col_we_n, wbs_dat_o, dram_col);\r
- \r
- dram_p : process (rst_n, sdram_clk)\r
-variable sr_read_ok : std_logic;\r
-variable wait_cnt : integer;\r
+ cnt_clk <= not vga_clk;\r
+ \r
+ --vga position counter\r
+ x_inst : counter_register generic map (10, 1)\r
+ port map (cnt_clk , x_res_n, '0', '1', (others => '0'), vga_x);\r
+ y_inst : counter_register generic map (10, 1)\r
+ port map (cnt_clk , y_res_n, y_en_n, '1', (others => '0'), vga_y);\r
+ vga_out_p : process (rst_n, vga_clk)\r
begin\r
if (rst_n = '0') then\r
- \r
- wbs_adr_i <= (others => '0');\r
- wbs_dat_i <= (others => '0');\r
- wbs_we_i <= '0';\r
- wbs_tga_i <= (others => '0');\r
- wbs_cyc_i <= '0';\r
- wbs_stb_i <= '0';\r
-\r
- sr_read_ok := '0';\r
- pos_x_we_n <= '1';\r
- nes_x_we_n <= '1';\r
- sw_state <= sw_idle;\r
- sr_state <= sr_idle;\r
- wait_cnt := SDRAM_READ_WAIT_CNT;\r
- \r
- elsif (rising_edge(sdram_clk)) then\r
- \r
- --write to sdram\r
- case sw_state is\r
- when sw_idle =>\r
- if (pos_x < conv_std_logic_vector(NES_W, 9) and \r
- pos_y < conv_std_logic_vector(NES_H, 9) and \r
- pos_x /= pos_x_old and sr_state = sr_idle) then\r
- --if (mem_cnt = conv_std_logic_vector(1, 5)) then\r
- sw_state <= sw_write;\r
- sr_read_ok := '0';\r
- pos_x_we_n <= '0';\r
-\r
- wbs_adr_i <= "000000" & pos_x(7 downto 0) & pos_y(7 downto 0);\r
- wbs_dat_i <= "0000" & nes_r & nes_g & nes_b;\r
- --wbs_dat_i <= (others => '1');\r
+ h_sync_n <= '0';\r
+ v_sync_n <= '0';\r
+ x_res_n <= '0';\r
+ y_res_n <= '0';\r
+ bb <= (others => '0');\r
+ gg <= (others => '0');\r
+ rr <= (others => '0');\r
+ elsif (rising_edge(vga_clk)) then\r
+ --xmax = 799\r
+ if (vga_x = conv_std_logic_vector(VGA_W_MAX, 10)) then\r
+ x_res_n <= '0';\r
+ y_en_n <= '0';\r
+ --ymax=524\r
+ if (vga_y = conv_std_logic_vector(VGA_H_MAX, 10)) then\r
+ y_res_n <= '0';\r
+ else\r
+ y_res_n <= '1';\r
end if;\r
-\r
- when sw_write =>\r
- pos_x_we_n <= '1';\r
- sw_state <= sw_write_ack;\r
-\r
- wbs_we_i <= '1';\r
- wbs_cyc_i <= '1';\r
- wbs_stb_i <= '1';\r
- wbs_tga_i <= conv_std_logic_vector(0, 8);\r
- when sw_write_ack =>\r
- sw_state <= sw_idle;\r
- sr_read_ok := '1';\r
- wait_cnt := SDRAM_READ_WAIT_CNT;\r
- end case;\r
- \r
--- --write to sdram\r
--- if (mem_cnt = conv_std_logic_vector(2, 4)) then\r
--- wbs_adr_i <= "000000" & pos_x(7 downto 0) & pos_y(7 downto 0);\r
--- wbs_dat_i <= "0000" & nes_r & nes_g & nes_b;\r
--- elsif (mem_cnt = conv_std_logic_vector(3, 4)) then\r
--- wbs_we_i <= '1';\r
--- wbs_cyc_i <= '1';\r
--- wbs_stb_i <= '1';\r
--- wbs_tga_i <= conv_std_logic_vector(0, 8);\r
---\r
--- elsif (mem_cnt = conv_std_logic_vector(4, 4)) then\r
--- --wbs_adr_i <= "0000" & pos_x & pos_y;\r
--- --wbs_dat_i <= "0000" & nes_r & nes_g & nes_b;\r
--- --wbs_dat_i <= "0000101000001111";\r
--- end if;\r
-\r
- --read from sdram\r
- if (vga_x <=conv_std_logic_vector(VGA_W , 10) \r
- and vga_y <=conv_std_logic_vector(VGA_H, 10)) then\r
-\r
- --read from sdram\r
- case sr_state is\r
- when sr_idle =>\r
- if (nes_x /= nes_x_old and sr_read_ok = '1') then\r
- --if (mem_cnt = conv_std_logic_vector(5, 5)) then\r
- if (wait_cnt = 0) then\r
- sr_state <= sr_read;\r
- else\r
- sr_state <= sr_read_wait;\r
- end if;\r
- wbs_adr_i <= "000000" & nes_x & vga_y(8 downto 1);\r
- wbs_cyc_i <= '0';\r
- wbs_stb_i <= '0';\r
- nes_x_we_n <= '0';\r
- end if;\r
- dram_col_we_n <= '1';\r
- when sr_read_wait =>\r
- wait_cnt := wait_cnt - 1;\r
- if (wait_cnt = 0) then\r
- sr_state <= sr_read;\r
- end if;\r
- when sr_read =>\r
- wbs_we_i <= '0';\r
- wbs_cyc_i <= '1';\r
- wbs_stb_i <= '1';\r
- wbs_tga_i <= conv_std_logic_vector(0, 8);\r
- nes_x_we_n <= '1';\r
- sr_state <= sr_read_ack;\r
- when sr_read_ack =>\r
- dram_col_we_n <= '0';\r
- sr_state <= sr_idle;\r
- end case;\r
- \r
--- if (mem_cnt > conv_std_logic_vector(4, 4) and \r
--- mem_cnt <= conv_std_logic_vector(15, 4)) then\r
--- --read wait cycle\r
--- wbs_adr_i <= "000000" & nes_x & vga_y(8 downto 1);\r
--- wbs_cyc_i <= '0';\r
--- wbs_stb_i <= '0';\r
--- elsif (mem_cnt <= conv_std_logic_vector(0, 4)) then\r
--- --read\r
--- wbs_we_i <= '0';\r
--- wbs_cyc_i <= '1';\r
--- wbs_stb_i <= '1';\r
--- wbs_tga_i <= conv_std_logic_vector(0, 8);\r
--- end if;\r
else\r
- sr_state <= sr_idle;\r
+ x_res_n <= '1';\r
+ y_en_n <= '1';\r
+ y_res_n <= '1';\r
end if;\r
\r
--- if (mem_cnt = conv_std_logic_vector(1, 4)) then\r
--- dram_col_we_n <= '0';\r
--- else\r
--- dram_col_we_n <= '1';\r
--- end if;\r
- \r
- end if;\r
- end process;\r
+ --sync signal assert.\r
+ if (vga_x >= conv_std_logic_vector((VGA_W + H_FP) , 10) and \r
+ vga_x < conv_std_logic_vector((VGA_W + H_FP + H_SP) , 10)) then\r
+ h_sync_n <= '0';\r
+ else\r
+ h_sync_n <= '1';\r
+ end if;\r
\r
- dram_latch_p : process (rst_n, vga_clk)\r
- begin\r
- if (rst_n = '0') then\r
- nes_x_en_n <= '1';\r
- \r
- elsif (falling_edge(vga_clk)) then\r
+ if (vga_y >= conv_std_logic_vector((VGA_H + V_FP) , 10) and \r
+ vga_y < conv_std_logic_vector((VGA_H + V_FP + V_SP) , 10)) then\r
+ v_sync_n <= '0';\r
+ else\r
+ v_sync_n <= '1';\r
+ end if;\r
\r
- if (count5 = "001" or count5 = "011") then\r
- nes_x_en_n <= '0';\r
+ if (vga_x <= conv_std_logic_vector((VGA_W) , 10) and \r
+ vga_y <= conv_std_logic_vector((VGA_H) , 10)) then\r
+ bb <= "0110";\r
+ gg <= (others => '1');\r
+ rr <= (others => '0');\r
else\r
- nes_x_en_n <= '1';\r
+ bb <= (others => '0');\r
+ gg <= (others => '0');\r
+ rr <= (others => '0');\r
end if;\r
end if;\r
end process;\r
\r
- vga_out_p : process (rst_n, vga_clk)
- begin
- if (rst_n = '0') then
- h_sync_n <= '0';
- v_sync_n <= '0';
- x_res_n <= '0';
- y_res_n <= '0';\r
- count5_res_n <= '0';
- \r
- r<=(others => '0');
- g<=(others => '0');
- b<=(others => '0');\r
- \r
- elsif (rising_edge(vga_clk)) then
- --xmax = 799
- if (vga_x = conv_std_logic_vector(VGA_W_MAX, 10)) then
- x_res_n <= '0';
- y_en_n <= '0';
- --ymax=524
- if (vga_y = conv_std_logic_vector(VGA_H_MAX, 10)) then
- y_res_n <= '0';
- else
- y_res_n <= '1';
- end if;
- else
- x_res_n <= '1';
- y_en_n <= '1';
- y_res_n <= '1';
- end if;
-
- --sync signal assert.
- if (vga_x >= conv_std_logic_vector((VGA_W + H_FP) , 10) and
- vga_x < conv_std_logic_vector((VGA_W + H_FP + H_SP) , 10)) then
- h_sync_n <= '0';
- else
- h_sync_n <= '1';
- end if;
-
- if (vga_y >= conv_std_logic_vector((VGA_H + V_FP) , 10) and
- vga_y < conv_std_logic_vector((VGA_H + V_FP + V_SP) , 10)) then
- v_sync_n <= '0';
- else
- v_sync_n <= '1';
- end if;
-
- if (vga_y <=conv_std_logic_vector((VGA_H) , 10)) then
- if (vga_x < conv_std_logic_vector((VGA_W) , 10)) then
- r<= dram_col(11 downto 8);
- g<= dram_col(7 downto 4);
- b<= dram_col(3 downto 0);\r
--- r<= "1111";\r
--- g<= "0000";\r
--- b<= "0000";\r
- else
- r<=(others => '0');
- g<=(others => '0');
- b<=(others => '0');
- end if;
- else
- r<=(others => '0');
- g<=(others => '0');
- b<=(others => '0');
- end if;\r
-
+ --emulate ppu clock that is synchronized with vga clock\r
+ count5_inst : counter_register generic map (3, 1)\r
+ port map (cnt_clk, count5_res_n, '0', '1', (others => '0'), count5);\r
+ nes_x_inst : counter_register generic map (9, 1)\r
+ port map (emu_ppu_clk , x_res_n, '0', '1', (others => '0'), nes_x);\r
+ nes_y <= vga_y(9 downto 1);\r
+ emu_clk_p : process (rst_n, vga_clk)\r
+ begin\r
+ if (rst_n = '0') then\r
+ emu_ppu_clk <= '0';\r
+ count5_res_n <= '0';\r
+ elsif (rising_edge(vga_clk)) then\r
if (vga_x = conv_std_logic_vector(VGA_W_MAX, 10)) then\r
count5_res_n <= '0';\r
elsif (count5 = "100") then\r
count5_res_n <= '1';\r
end if;\r
\r
- end if;
- end process;
-
-end rtl;
-
+ if (count5 = "001" or count5 = "011") then\r
+ emu_ppu_clk <= '0';\r
+ else\r
+ emu_ppu_clk <= '1';\r
+ end if;\r
+ end if;\r
+ end process;\r
\r
+ emu_ppu_clk_n <= not emu_ppu_clk;\r
+ vga_render_inst : ppu_vga_render\r
+ port map (\r
+ dbg_vga_clk ,\r
+ dbg_nes_x ,\r
+ dbg_disp_nt, dbg_disp_attr ,\r
+ dbg_disp_ptn_h, dbg_disp_ptn_l ,\r
+ dbg_plt_ce_rn_wn ,\r
+ dbg_plt_addr ,\r
+ dbg_plt_data ,\r
+ dbg_p_oam_ce_rn_wn ,\r
+ dbg_p_oam_addr ,\r
+ dbg_p_oam_data ,\r
+ dbg_s_oam_ce_rn_wn ,\r
+ dbg_s_oam_addr ,\r
+ dbg_s_oam_data ,\r
+ \r
+ emu_ppu_clk_n ,\r
+ mem_clk ,\r
+ rst_n ,\r
+ rd_n ,\r
+ wr_n ,\r
+ ale ,\r
+ vram_ad ,\r
+ vram_a ,\r
+ nes_x ,\r
+ nes_y ,\r
+ r ,\r
+ g ,\r
+ b ,\r
+ ppu_ctrl ,\r
+ ppu_mask ,\r
+ read_status ,\r
+ ppu_status ,\r
+ ppu_scroll_x ,\r
+ ppu_scroll_y ,\r
+ r_nw ,\r
+ oam_bus_ce_n ,\r
+ plt_bus_ce_n ,\r
+ oam_plt_addr ,\r
+ oam_plt_data ,\r
+ v_bus_busy_n \r
+ );\r
+\r
+end rtl;\r
\r
--------------------------------------------------------------\r
--------------------------------------------------------------\r
------------------ Dummy PPU image generator -----------------\r
--------------------------------------------------------------\r
--------------------------------------------------------------\r
\r
\r
+---------------------------------------------------------------\r
+---------------------------------------------------------------\r
+------------------------ PPU VGA Renderer ---------------------\r
+---------------------------------------------------------------\r
+---------------------------------------------------------------\r
+\r
library ieee;\r
use ieee.std_logic_1164.all;\r
-use ieee.std_logic_unsigned.all;\r
use ieee.std_logic_arith.conv_std_logic_vector;\r
+use ieee.std_logic_unsigned.all;\r
+use work.motonesfpga_common.all;\r
\r
-entity dummy_ppu is \r
- port ( ppu_clk : in std_logic;\r
+entity ppu_vga_render is \r
+ port ( \r
+ signal dbg_vga_clk : out std_logic;\r
+ signal dbg_nes_x : out std_logic_vector (8 downto 0);\r
+ signal dbg_disp_nt, dbg_disp_attr : out std_logic_vector (7 downto 0);\r
+ signal dbg_disp_ptn_h, dbg_disp_ptn_l : out std_logic_vector (15 downto 0);\r
+ signal dbg_plt_ce_rn_wn : out std_logic_vector (2 downto 0);\r
+ signal dbg_plt_addr : out std_logic_vector (4 downto 0);\r
+ signal dbg_plt_data : out std_logic_vector (7 downto 0);\r
+ signal dbg_p_oam_ce_rn_wn : out std_logic_vector (2 downto 0);\r
+ signal dbg_p_oam_addr : out std_logic_vector (7 downto 0);\r
+ signal dbg_p_oam_data : out std_logic_vector (7 downto 0);\r
+ signal dbg_s_oam_ce_rn_wn : out std_logic_vector (2 downto 0);\r
+ signal dbg_s_oam_addr : out std_logic_vector (4 downto 0);\r
+ signal dbg_s_oam_data : out std_logic_vector (7 downto 0);\r
+ \r
+ vga_clk : in std_logic;\r
+ mem_clk : in std_logic;\r
rst_n : in std_logic;\r
- pos_x : buffer std_logic_vector (8 downto 0);\r
- pos_y : buffer std_logic_vector (8 downto 0);\r
- nes_r : buffer std_logic_vector (3 downto 0);\r
- nes_g : buffer std_logic_vector (3 downto 0);\r
- nes_b : buffer std_logic_vector (3 downto 0)\r
- );\r
-end dummy_ppu;\r
\r
+ rd_n : out std_logic;\r
+ wr_n : out std_logic;\r
+ ale : out std_logic;\r
+ vram_ad : inout std_logic_vector (7 downto 0);\r
+ vram_a : out std_logic_vector (13 downto 8);\r
+\r
+ --current drawing position 340 x 261\r
+ cur_x : in std_logic_vector (8 downto 0);\r
+ cur_y : in std_logic_vector (8 downto 0);\r
+ r : out std_logic_vector (3 downto 0);\r
+ g : out std_logic_vector (3 downto 0);\r
+ b : out std_logic_vector (3 downto 0);\r
+\r
+ ppu_ctrl : in std_logic_vector (7 downto 0);\r
+ ppu_mask : in std_logic_vector (7 downto 0);\r
+ read_status : in std_logic;\r
+ ppu_status : out std_logic_vector (7 downto 0);\r
+ ppu_scroll_x : in std_logic_vector (7 downto 0);\r
+ ppu_scroll_y : in std_logic_vector (7 downto 0);\r
+\r
+ r_nw : in std_logic;\r
+ oam_bus_ce_n : in std_logic;\r
+ plt_bus_ce_n : in std_logic;\r
+ oam_plt_addr : in std_logic_vector (7 downto 0);\r
+ oam_plt_data : inout std_logic_vector (7 downto 0);\r
+ v_bus_busy_n : out std_logic\r
+ );\r
+end ppu_vga_render;\r
\r
-architecture rtl of dummy_ppu is\r
+architecture rtl of ppu_vga_render is\r
\r
component counter_register\r
generic (\r
);\r
end component;\r
\r
-signal x_res_n, y_res_n, y_en_n : std_logic;\r
-signal cnt_clk : std_logic;\r
-signal frame_en_n : std_logic;\r
+component shift_register\r
+ generic (\r
+ dsize : integer := 8;\r
+ shift : integer := 1\r
+ );\r
+ port ( clk : in std_logic;\r
+ rst_n : in std_logic;\r
+ ce_n : in std_logic;\r
+ we_n : in std_logic;\r
+ d : in std_logic_vector(dsize - 1 downto 0);\r
+ q : out std_logic_vector(dsize - 1 downto 0)\r
+ );\r
+end component;\r
+\r
+component d_flip_flop\r
+ generic (\r
+ dsize : integer := 8\r
+ );\r
+ port ( \r
+ clk : in std_logic;\r
+ res_n : in std_logic;\r
+ set_n : in std_logic;\r
+ we_n : in std_logic;\r
+ d : in std_logic_vector (dsize - 1 downto 0);\r
+ q : out std_logic_vector (dsize - 1 downto 0)\r
+ );\r
+end component;\r
+\r
+component tri_state_buffer\r
+ generic (\r
+ dsize : integer := 8\r
+ );\r
+ port ( \r
+ oe_n : in std_logic;\r
+ d : in std_logic_vector (dsize - 1 downto 0);\r
+ q : out std_logic_vector (dsize - 1 downto 0)\r
+ );\r
+end component;\r
+\r
+component ram\r
+ generic (abus_size : integer := 16; dbus_size : integer := 8);\r
+ port ( \r
+ clk : in std_logic;\r
+ ce_n, oe_n, we_n : in std_logic; --select pin active low.\r
+ addr : in std_logic_vector (abus_size - 1 downto 0);\r
+ d_io : inout std_logic_vector (dbus_size - 1 downto 0)\r
+ );\r
+end component;\r
+\r
+component palette_ram\r
+ generic (abus_size : integer := 16; dbus_size : integer := 8);\r
+ port ( \r
+ clk : in std_logic;\r
+ ce_n, oe_n, we_n : in std_logic; --select pin active low.\r
+ addr : in std_logic_vector (abus_size - 1 downto 0);\r
+ d_io : inout std_logic_vector (dbus_size - 1 downto 0)\r
+ );\r
+end component;\r
+\r
+component ram_ctrl\r
+ port ( \r
+ clk : in std_logic;\r
+ ce_n, oe_n, we_n : in std_logic;\r
+ sync_ce_n : out std_logic\r
+ );\r
+end component;\r
+\r
+--nes screen size is emulated to align with the vga timing...\r
+constant X_SIZE : integer := 9;\r
+constant dsize : integer := 8;\r
+constant asize : integer := 14;\r
+--constant HSCAN_MAX : integer := 341;\r
+constant HSCAN_MAX : integer := 321;\r
+constant VSCAN_MAX : integer := 262;\r
+constant HSCAN : integer := 257;\r
+constant VSCAN : integer := 240;\r
+--constant HSCAN_NEXT_START : integer := 320;\r
+--constant HSCAN_NEXT_EXTRA : integer := 336;\r
+constant HSCAN_NEXT_START : integer := 300;\r
+constant HSCAN_NEXT_EXTRA : integer := 316;\r
+\r
+\r
+constant PPUBNA : integer := 1; --base name address\r
+constant PPUVAI : integer := 2; --vram address increment\r
+constant PPUSPA : integer := 3; --sprite pattern table address\r
+constant PPUBPA : integer := 4; --background pattern table address\r
+constant PPUSPS : integer := 5; --sprite size\r
+constant PPUMS : integer := 6; --ppu master/slave\r
+constant PPUNEN : integer := 7; --nmi enable\r
+\r
+constant PPUGS : integer := 0; --grayscale\r
+constant PPUSBL : integer := 1; --show 8 left most bg pixel\r
+constant PPUSSL : integer := 2; --show 8 left most sprite pixel\r
+constant PPUSBG : integer := 3; --show bg\r
+constant PPUSSP : integer := 4; --show sprie\r
+constant PPUIR : integer := 5; --intensify red\r
+constant PPUIG : integer := 6; --intensify green\r
+constant PPUIB : integer := 7; --intensify blue\r
+\r
+constant SPRHFL : integer := 6; --flip sprigte horizontally\r
+constant SPRVFL : integer := 7; --flip sprigte vertically\r
+\r
+constant ST_SOF : integer := 5; --sprite overflow\r
+constant ST_SP0 : integer := 6; --sprite 0 hits\r
+constant ST_VBL : integer := 7; --vblank\r
+\r
+subtype nes_color_data is std_logic_vector (11 downto 0);\r
+type nes_color_array is array (0 to 63) of nes_color_data;\r
+--ref: http://hlc6502.web.fc2.com/NesPal2.htm\r
+constant nes_color_palette : nes_color_array := (\r
+ conv_std_logic_vector(16#777#, 12), \r
+ conv_std_logic_vector(16#20b#, 12), \r
+ conv_std_logic_vector(16#20b#, 12), \r
+ conv_std_logic_vector(16#61a#, 12), \r
+ conv_std_logic_vector(16#927#, 12), \r
+ conv_std_logic_vector(16#b13#, 12), \r
+ conv_std_logic_vector(16#a30#, 12), \r
+ conv_std_logic_vector(16#740#, 12), \r
+ conv_std_logic_vector(16#450#, 12), \r
+ conv_std_logic_vector(16#360#, 12), \r
+ conv_std_logic_vector(16#360#, 12), \r
+ conv_std_logic_vector(16#364#, 12), \r
+ conv_std_logic_vector(16#358#, 12), \r
+ conv_std_logic_vector(16#000#, 12), \r
+ conv_std_logic_vector(16#000#, 12), \r
+ conv_std_logic_vector(16#000#, 12),\r
+ conv_std_logic_vector(16#bbb#, 12), \r
+ conv_std_logic_vector(16#46f#, 12), \r
+ conv_std_logic_vector(16#44f#, 12), \r
+ conv_std_logic_vector(16#94f#, 12), \r
+ conv_std_logic_vector(16#d4c#, 12), \r
+ conv_std_logic_vector(16#d46#, 12), \r
+ conv_std_logic_vector(16#e50#, 12), \r
+ conv_std_logic_vector(16#c70#, 12), \r
+ conv_std_logic_vector(16#880#, 12), \r
+ conv_std_logic_vector(16#5a0#, 12), \r
+ conv_std_logic_vector(16#4a1#, 12), \r
+ conv_std_logic_vector(16#4a6#, 12), \r
+ conv_std_logic_vector(16#49c#, 12), \r
+ conv_std_logic_vector(16#000#, 12), \r
+ conv_std_logic_vector(16#000#, 12), \r
+ conv_std_logic_vector(16#000#, 12),\r
+ conv_std_logic_vector(16#fff#, 12), \r
+ conv_std_logic_vector(16#6af#, 12), \r
+ conv_std_logic_vector(16#58f#, 12), \r
+ conv_std_logic_vector(16#a7f#, 12), \r
+ conv_std_logic_vector(16#f6f#, 12), \r
+ conv_std_logic_vector(16#f6b#, 12), \r
+ conv_std_logic_vector(16#f73#, 12), \r
+ conv_std_logic_vector(16#fa0#, 12), \r
+ conv_std_logic_vector(16#ed2#, 12), \r
+ conv_std_logic_vector(16#9e0#, 12), \r
+ conv_std_logic_vector(16#7f4#, 12), \r
+ conv_std_logic_vector(16#7e9#, 12), \r
+ conv_std_logic_vector(16#6de#, 12), \r
+ conv_std_logic_vector(16#777#, 12), \r
+ conv_std_logic_vector(16#000#, 12), \r
+ conv_std_logic_vector(16#000#, 12),\r
+ conv_std_logic_vector(16#fff#, 12), \r
+ conv_std_logic_vector(16#9df#, 12), \r
+ conv_std_logic_vector(16#abf#, 12), \r
+ conv_std_logic_vector(16#cbf#, 12), \r
+ conv_std_logic_vector(16#ebf#, 12), \r
+ conv_std_logic_vector(16#fbe#, 12), \r
+ conv_std_logic_vector(16#fcb#, 12), \r
+ conv_std_logic_vector(16#fda#, 12), \r
+ conv_std_logic_vector(16#ff9#, 12), \r
+ conv_std_logic_vector(16#cf8#, 12), \r
+ conv_std_logic_vector(16#afa#, 12), \r
+ conv_std_logic_vector(16#afc#, 12), \r
+ conv_std_logic_vector(16#aff#, 12), \r
+ conv_std_logic_vector(16#aaa#, 12), \r
+ conv_std_logic_vector(16#000#, 12), \r
+ conv_std_logic_vector(16#000#, 12)\r
+ );\r
+\r
+signal vga_clk_n : std_logic;\r
+\r
+--timing adjust\r
+signal bg_io_cnt : std_logic_vector(0 downto 0);\r
+signal spr_io_cnt : std_logic_vector(0 downto 0);\r
+\r
+--vram i/o\r
+signal io_oe_n : std_logic;\r
+signal ah_oe_n : std_logic;\r
+\r
+signal cnt_x_res_n : std_logic;\r
+signal bg_cnt_res_n : std_logic;\r
+\r
+--bg prefetch position (scroll + 16 cycle ahead of current pos)\r
+--511 x 239 (or 255 x 479)\r
+signal prf_x : std_logic_vector(X_SIZE - 1 downto 0);\r
+signal prf_y : std_logic_vector(X_SIZE - 1 downto 0);\r
\r
+signal nt_we_n : std_logic;\r
+signal disp_nt : std_logic_vector (dsize - 1 downto 0);\r
+\r
+signal attr_ce_n : std_logic;\r
+signal attr_we_n : std_logic;\r
+signal attr_val : std_logic_vector (dsize - 1 downto 0);\r
+signal disp_attr_we_n : std_logic;\r
+signal disp_attr : std_logic_vector (dsize - 1 downto 0);\r
+\r
+signal ptn_l_we_n : std_logic;\r
+signal ptn_l_in : std_logic_vector (dsize - 1 downto 0);\r
+signal ptn_l_val : std_logic_vector (dsize - 1 downto 0);\r
+signal disp_ptn_l_in : std_logic_vector (dsize * 2 - 1 downto 0);\r
+signal disp_ptn_l : std_logic_vector (dsize * 2 - 1 downto 0);\r
+\r
+signal ptn_h_we_n : std_logic;\r
+signal ptn_h_in : std_logic_vector (dsize * 2 - 1 downto 0);\r
+signal disp_ptn_h : std_logic_vector (dsize * 2 - 1 downto 0);\r
+\r
+--signals for palette / oam access from cpu\r
+signal r_n : std_logic;\r
+signal vram_addr : std_logic_vector (asize - 1 downto 0);\r
+\r
+--palette\r
+signal plt_ram_ce_n_in : std_logic;\r
+signal plt_ram_ce_n : std_logic;\r
+signal plt_r_n : std_logic;\r
+signal plt_w_n : std_logic;\r
+signal plt_addr : std_logic_vector (4 downto 0);\r
+signal plt_data : std_logic_vector (dsize - 1 downto 0);\r
+\r
+--primari / secondary oam\r
+signal p_oam_ram_ce_n_in : std_logic;\r
+signal p_oam_ram_ce_n : std_logic;\r
+signal p_oam_r_n : std_logic;\r
+signal p_oam_w_n : std_logic;\r
+signal p_oam_addr : std_logic_vector (dsize - 1 downto 0);\r
+signal p_oam_data : std_logic_vector (dsize - 1 downto 0);\r
+\r
+signal s_oam_ram_ce_n_in : std_logic;\r
+signal s_oam_ram_ce_n : std_logic;\r
+signal s_oam_r_n : std_logic;\r
+signal s_oam_w_n : std_logic;\r
+signal s_oam_addr_cpy_ce_n : std_logic;\r
+signal s_oam_addr_cpy_n : std_logic;\r
+signal s_oam_addr : std_logic_vector (4 downto 0);\r
+signal s_oam_addr_cpy : std_logic_vector (4 downto 0);\r
+signal s_oam_data : std_logic_vector (dsize - 1 downto 0);\r
+\r
+signal p_oam_cnt_res_n : std_logic;\r
+signal p_oam_cnt_ce_n : std_logic;\r
+signal p_oam_cnt_wrap_n : std_logic;\r
+signal p_oam_cnt : std_logic_vector (dsize - 1 downto 0);\r
+signal p_oam_addr_in : std_logic_vector (dsize - 1 downto 0);\r
+signal oam_ev_status : std_logic_vector (2 downto 0);\r
+\r
+signal s_oam_cnt_ce_n : std_logic;\r
+signal s_oam_cnt : std_logic_vector (4 downto 0);\r
+\r
+--oam evaluation status\r
+constant EV_STAT_COMP : std_logic_vector (2 downto 0) := "000";\r
+constant EV_STAT_CP1 : std_logic_vector (2 downto 0) := "001";\r
+constant EV_STAT_CP2 : std_logic_vector (2 downto 0) := "010";\r
+constant EV_STAT_CP3 : std_logic_vector (2 downto 0) := "011";\r
+constant EV_STAT_PRE_COMP : std_logic_vector (2 downto 0) := "100";\r
+\r
+----------sprite registers.\r
+type oam_pin_array is array (0 to 7) of std_logic;\r
+type oam_reg_array is array (0 to 7) of std_logic_vector (dsize - 1 downto 0);\r
+\r
+signal spr_x_we_n : oam_pin_array;\r
+signal spr_x_ce_n : oam_pin_array;\r
+signal spr_attr_we_n : oam_pin_array;\r
+signal spr_ptn_l_we_n : oam_pin_array;\r
+signal spr_ptn_h_we_n : oam_pin_array;\r
+signal spr_ptn_ce_n : oam_pin_array;\r
+\r
+signal spr_x_cnt : oam_reg_array;\r
+signal spr_attr : oam_reg_array;\r
+signal spr_ptn_l : oam_reg_array;\r
+signal spr_ptn_h : oam_reg_array;\r
+\r
+signal spr_y_we_n : std_logic;\r
+signal spr_tile_we_n : std_logic;\r
+signal spr_y_tmp : std_logic_vector (dsize - 1 downto 0);\r
+signal spr_tile_tmp : std_logic_vector (dsize - 1 downto 0);\r
+signal spr_ptn_in : std_logic_vector (dsize - 1 downto 0);\r
\r
-signal frame_cnt : std_logic_vector(7 downto 0);\r
\r
begin\r
+ dbg_vga_clk <= vga_clk;\r
+ dbg_nes_x <= cur_x;\r
+ dbg_disp_nt <= disp_nt;\r
+ dbg_disp_attr <= disp_attr;\r
+ dbg_disp_ptn_h <= disp_ptn_h;\r
+ dbg_disp_ptn_l <= disp_ptn_l;\r
+ dbg_plt_addr <= plt_addr;\r
+ dbg_plt_data <= plt_data;\r
+ dbg_plt_ce_rn_wn <= plt_ram_ce_n & plt_r_n & plt_w_n;\r
+ dbg_p_oam_ce_rn_wn <= p_oam_ram_ce_n & p_oam_r_n & p_oam_w_n;\r
+ dbg_p_oam_addr <= p_oam_addr;\r
+ dbg_p_oam_data <= p_oam_data;\r
+ dbg_s_oam_ce_rn_wn <= s_oam_ram_ce_n & s_oam_r_n & s_oam_w_n;\r
+ dbg_s_oam_addr <= s_oam_addr;\r
+ dbg_s_oam_data <= p_oam_data;\r
\r
- cnt_clk <= not ppu_clk;\r
- x_inst : counter_register generic map (9, 1)\r
- port map (cnt_clk , x_res_n, '0', '1', (others => '0'), pos_x);\r
- y_inst : counter_register generic map (9, 1)\r
- port map (cnt_clk , y_res_n, y_en_n, '1', (others => '0'), pos_y);\r
\r
- frame_cnt_inst : counter_register generic map (8, 1)\r
- port map (cnt_clk , rst_n, frame_en_n, '1', (others => '0'), frame_cnt);\r
+ vga_clk_n <= not vga_clk;\r
\r
- \r
- p_write : process (rst_n, ppu_clk)\r
+ ale <= bg_io_cnt(0) when ppu_mask(PPUSBG) = '1' and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
+ cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE)) and\r
+ (cur_x <= conv_std_logic_vector(HSCAN, X_SIZE) or\r
+ cur_x > conv_std_logic_vector(HSCAN_NEXT_START, X_SIZE)) else\r
+ spr_io_cnt(0) when ppu_mask(PPUSSP) = '1' and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
+ cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE)) and\r
+ (cur_x > conv_std_logic_vector(256, X_SIZE) and \r
+ cur_x <= conv_std_logic_vector(HSCAN_NEXT_START, X_SIZE)) else\r
+ 'Z';\r
+\r
+ rd_n <= bg_io_cnt(0) when ppu_mask(PPUSBG) = '1' and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
+ cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE)) and\r
+ (cur_x <= conv_std_logic_vector(HSCAN, X_SIZE) or\r
+ cur_x > conv_std_logic_vector(HSCAN_NEXT_START, X_SIZE)) else\r
+ spr_io_cnt(0) when ppu_mask(PPUSSP) = '1' and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
+ cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE)) and\r
+ (cur_x > conv_std_logic_vector(256, X_SIZE) and \r
+ cur_x <= conv_std_logic_vector(HSCAN_NEXT_START, X_SIZE)) else\r
+ 'Z';\r
+ wr_n <= '1' when (ppu_mask(PPUSBG) = '1' or ppu_mask(PPUSSP) = '1') and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
+ cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE)) else\r
+ 'Z';\r
+ io_oe_n <= not bg_io_cnt(0) when ppu_mask(PPUSBG) = '1' and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
+ cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE)) and\r
+ (cur_x <= conv_std_logic_vector(HSCAN, X_SIZE) or\r
+ cur_x > conv_std_logic_vector(HSCAN_NEXT_START, X_SIZE)) else\r
+ not spr_io_cnt(0) when ppu_mask(PPUSSP) = '1' and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
+ cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE)) and\r
+ (cur_x > conv_std_logic_vector(256, X_SIZE) and \r
+ cur_x <= conv_std_logic_vector(HSCAN_NEXT_START, X_SIZE)) else\r
+ '1';\r
+ ah_oe_n <= '0' when (ppu_mask(PPUSBG) = '1' or ppu_mask(PPUSSP) = '1') and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
+ cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE)) else\r
+ '1';\r
+ v_bus_busy_n <= ah_oe_n;\r
+\r
+ bg_io_cnt_inst : counter_register generic map (1, 1)\r
+ port map (vga_clk, bg_cnt_res_n, '0', '1', (others => '0'), bg_io_cnt);\r
+ spr_io_cnt_inst : counter_register generic map (1, 1)\r
+ port map (vga_clk, cnt_x_res_n, '0', '1', (others => '0'), spr_io_cnt);\r
+\r
+ ---bg prefetch x pos is 16 + scroll cycle ahead of current pos.\r
+ prf_x <= cur_x + ppu_scroll_x + "000010000" \r
+ when cur_x < conv_std_logic_vector(HSCAN, X_SIZE) else\r
+ cur_x + ppu_scroll_x + "010111011"; -- +16 -341\r
+\r
+ prf_y <= cur_y + ppu_scroll_y\r
+ when cur_x < conv_std_logic_vector(HSCAN, X_SIZE) and\r
+ cur_y + ppu_scroll_y <\r
+ conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE) else\r
+ cur_y + ppu_scroll_y + "000000001" \r
+ when cur_y + ppu_scroll_y <\r
+ conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE) else\r
+ "000000000"; \r
+\r
+ nt_inst : d_flip_flop generic map(dsize)\r
+ port map (vga_clk_n, rst_n, '1', nt_we_n, vram_ad, disp_nt);\r
+\r
+ at_inst : d_flip_flop generic map(dsize)\r
+ port map (vga_clk_n, rst_n, '1', attr_we_n, vram_ad, attr_val);\r
+\r
+ disp_at_inst : shift_register generic map(dsize, 2)\r
+ port map (vga_clk_n, rst_n, attr_ce_n, disp_attr_we_n, attr_val, disp_attr);\r
+\r
+ --chr rom data's bit is stored in opposite direction.\r
+ --reverse bit when loading...\r
+ ptn_l_in <= (vram_ad(0) & vram_ad(1) & vram_ad(2) & vram_ad(3) & \r
+ vram_ad(4) & vram_ad(5) & vram_ad(6) & vram_ad(7));\r
+ ptn_h_in <= (vram_ad(0) & vram_ad(1) & vram_ad(2) & vram_ad(3) & \r
+ vram_ad(4) & vram_ad(5) & vram_ad(6) & vram_ad(7)) & \r
+ disp_ptn_h (dsize downto 1);\r
+\r
+ ptn_l_inst : d_flip_flop generic map(dsize)\r
+ port map (vga_clk_n, rst_n, '1', ptn_l_we_n, ptn_l_in, ptn_l_val);\r
+\r
+ disp_ptn_l_in <= ptn_l_val & disp_ptn_l (dsize downto 1);\r
+ disp_ptn_l_inst : shift_register generic map(dsize * 2, 1)\r
+ port map (vga_clk_n, rst_n, '0', ptn_h_we_n, disp_ptn_l_in, disp_ptn_l);\r
+\r
+ ptn_h_inst : shift_register generic map(dsize * 2, 1)\r
+ port map (vga_clk_n, rst_n, '0', ptn_h_we_n, ptn_h_in, disp_ptn_h);\r
+\r
+ --vram i/o\r
+ vram_io_buf : tri_state_buffer generic map (dsize)\r
+ port map (io_oe_n, vram_addr(dsize - 1 downto 0), vram_ad);\r
+\r
+ vram_a_buf : tri_state_buffer generic map (6)\r
+ port map (ah_oe_n, vram_addr(asize - 1 downto dsize), vram_a);\r
+\r
+ ---palette ram\r
+ r_n <= not r_nw;\r
+\r
+ plt_ram_ce_n_in <= vga_clk when plt_bus_ce_n = '0' and r_nw = '0' else \r
+ '0' when plt_bus_ce_n = '0' and r_nw = '1' else\r
+ '0' when ppu_mask(PPUSBG) = '1' and \r
+ (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and \r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) else\r
+ '1';\r
+\r
+ plt_addr <= oam_plt_addr(4 downto 0) when plt_bus_ce_n = '0' else\r
+ "1" & spr_attr(0)(1 downto 0) & spr_ptn_h(0)(0) & spr_ptn_l(0)(0)\r
+ when ppu_mask(PPUSSP) = '1' and\r
+ (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) and\r
+ spr_x_cnt(0) = "00000000" and \r
+ (spr_ptn_h(0)(0) or spr_ptn_l(0)(0)) = '1' else\r
+ "1" & spr_attr(1)(1 downto 0) & spr_ptn_h(1)(0) & spr_ptn_l(1)(0)\r
+ when ppu_mask(PPUSSP) = '1' and\r
+ (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) and\r
+ spr_x_cnt(1) = "00000000" and \r
+ (spr_ptn_h(1)(0) or spr_ptn_l(1)(0)) = '1' else\r
+ "1" & spr_attr(2)(1 downto 0) & spr_ptn_h(2)(0) & spr_ptn_l(2)(0)\r
+ when ppu_mask(PPUSSP) = '1' and \r
+ (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) and\r
+ spr_x_cnt(2) = "00000000" and\r
+ (spr_ptn_h(2)(0) or spr_ptn_l(2)(0)) = '1' else\r
+ "1" & spr_attr(3)(1 downto 0) & spr_ptn_h(3)(0) & spr_ptn_l(3)(0)\r
+ when ppu_mask(PPUSSP) = '1' and\r
+ (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) and\r
+ spr_x_cnt(3) = "00000000" and\r
+ (spr_ptn_h(3)(0) or spr_ptn_l(3)(0)) = '1' else\r
+ "1" & spr_attr(4)(1 downto 0) & spr_ptn_h(4)(0) & spr_ptn_l(4)(0)\r
+ when ppu_mask(PPUSSP) = '1' and\r
+ (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) and\r
+ spr_x_cnt(4) = "00000000" and\r
+ (spr_ptn_h(4)(0) or spr_ptn_l(4)(0)) = '1' else\r
+ "1" & spr_attr(5)(1 downto 0) & spr_ptn_h(5)(0) & spr_ptn_l(5)(0)\r
+ when ppu_mask(PPUSSP) = '1' and\r
+ (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) and\r
+ spr_x_cnt(5) = "00000000" and\r
+ (spr_ptn_h(5)(0) or spr_ptn_l(5)(0)) = '1' else\r
+ "1" & spr_attr(6)(1 downto 0) & spr_ptn_h(6)(0) & spr_ptn_l(6)(0)\r
+ when ppu_mask(PPUSSP) = '1' and\r
+ (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) and\r
+ spr_x_cnt(6) = "00000000" and\r
+ (spr_ptn_h(6)(0) or spr_ptn_l(6)(0)) = '1' else\r
+ "1" & spr_attr(7)(1 downto 0) & spr_ptn_h(7)(0) & spr_ptn_l(7)(0)\r
+ when ppu_mask(PPUSSP) = '1' and\r
+ (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) and\r
+ spr_x_cnt(7) = "00000000" and\r
+ (spr_ptn_h(7)(0) or spr_ptn_l(7)(0)) = '1' else\r
+ "0" & disp_attr(1 downto 0) & disp_ptn_h(0) & disp_ptn_l(0) \r
+ when ppu_mask(PPUSBG) = '1' and cur_y(4) = '0' and\r
+ ((disp_ptn_h(0) or disp_ptn_l(0)) = '1') and\r
+ (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) else\r
+ "0" & disp_attr(5 downto 4) & disp_ptn_h(0) & disp_ptn_l(0)\r
+ when ppu_mask(PPUSBG) = '1' and cur_y(4) = '1' and\r
+ ((disp_ptn_h(0) or disp_ptn_l(0)) = '1') and\r
+ (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) else\r
+ ---else: no output color >> universal bg color output.\r
+ --0x3f00 is the universal bg palette.\r
+ (others => '0'); \r
+\r
+ plt_r_n <= not r_nw when plt_bus_ce_n = '0' else\r
+ '0' when ppu_mask(PPUSBG) = '1' else\r
+ '1';\r
+ plt_w_n <= r_nw when plt_bus_ce_n = '0' else\r
+ '1';\r
+ plt_d_buf_w : tri_state_buffer generic map (dsize)\r
+ port map (plt_w_n, oam_plt_data, plt_data);\r
+ plt_d_buf_r : tri_state_buffer generic map (dsize)\r
+ port map (plt_r_n, plt_data, oam_plt_data);\r
+ plt_ram_ctl : ram_ctrl\r
+ port map (mem_clk, plt_ram_ce_n_in, plt_r_n, plt_w_n, plt_ram_ce_n);\r
+ palette_inst : palette_ram generic map (5, dsize)\r
+ port map (mem_clk, plt_ram_ce_n, plt_r_n, plt_w_n, plt_addr, plt_data);\r
+\r
+ ---primary oam\r
+ p_oam_ram_ce_n_in <= vga_clk when oam_bus_ce_n = '0' and r_nw = '0' else\r
+ '0' when oam_bus_ce_n = '0' and r_nw = '1' else\r
+ '0' when ppu_mask(PPUSSP) = '1' and\r
+ cur_x > conv_std_logic_vector(64, X_SIZE) and\r
+ cur_x <= conv_std_logic_vector(256, X_SIZE) and\r
+ p_oam_cnt_wrap_n = '1' else\r
+ '1';\r
+ p_oam_addr <= oam_plt_addr when oam_bus_ce_n = '0' else\r
+ p_oam_addr_in when ppu_mask(PPUSSP) = '1' and \r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
+ cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE)) and\r
+ cur_x > conv_std_logic_vector(64, X_SIZE) and \r
+ cur_x <= conv_std_logic_vector(256, X_SIZE) else\r
+ (others => 'Z');\r
+ p_oam_r_n <= not r_nw when oam_bus_ce_n = '0' else\r
+ '0' when ppu_mask(PPUSSP) = '1' and \r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
+ cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE)) and\r
+ cur_x > conv_std_logic_vector(64, X_SIZE) and \r
+ cur_x <= conv_std_logic_vector(256, X_SIZE) else\r
+ '1';\r
+ p_oam_w_n <= r_nw when oam_bus_ce_n = '0' else\r
+ '1';\r
+ oam_d_buf_w : tri_state_buffer generic map (dsize)\r
+ port map (p_oam_w_n, oam_plt_data, p_oam_data);\r
+ oam_d_buf_r : tri_state_buffer generic map (dsize)\r
+ port map (p_oam_r_n, p_oam_data, oam_plt_data);\r
+\r
+ p_oam_ram_ctl : ram_ctrl\r
+ port map (mem_clk, p_oam_ram_ce_n_in, p_oam_r_n, p_oam_w_n, p_oam_ram_ce_n);\r
+ primary_oam_inst : ram generic map (dsize, dsize)\r
+ port map (mem_clk, p_oam_ram_ce_n, p_oam_r_n, p_oam_w_n, p_oam_addr, p_oam_data);\r
+\r
+ ---secondary oam\r
+ p_oam_cnt_inst : counter_register generic map (dsize, 4)\r
+ port map (vga_clk_n, p_oam_cnt_res_n, p_oam_cnt_ce_n, '1', (others => '0'), p_oam_cnt);\r
+ s_oam_cnt_inst : counter_register generic map (5, 1)\r
+ port map (vga_clk_n, p_oam_cnt_res_n, s_oam_cnt_ce_n, '1', (others => '0'), s_oam_cnt);\r
+ s_oam_addr_cpy_inst : counter_register generic map (5, 1)\r
+ port map (vga_clk_n, p_oam_cnt_res_n, s_oam_addr_cpy_ce_n, \r
+ '1', (others => '0'), s_oam_addr_cpy);\r
+\r
+ s_oam_ram_ce_n_in <= vga_clk when ppu_mask(PPUSSP) = '1' and cur_x(0) = '1' and\r
+ cur_x > "000000001" and\r
+ cur_x <= conv_std_logic_vector(64, X_SIZE) else\r
+ vga_clk when ppu_mask(PPUSSP) = '1' and cur_x(0) = '1' and\r
+ cur_x > conv_std_logic_vector(64, X_SIZE) and\r
+ cur_x <= conv_std_logic_vector(256, X_SIZE) and\r
+ p_oam_cnt_wrap_n = '1' else\r
+ '0' when ppu_mask(PPUSSP) = '1' and\r
+ cur_x > conv_std_logic_vector(256, X_SIZE) and\r
+ cur_x <= conv_std_logic_vector(320, X_SIZE) and\r
+ s_oam_addr_cpy_n = '0' else\r
+ '1';\r
+\r
+ s_oam_ram_ctl : ram_ctrl\r
+ port map (mem_clk, s_oam_ram_ce_n_in, s_oam_r_n, s_oam_w_n, s_oam_ram_ce_n);\r
+ secondary_oam_inst : ram generic map (5, dsize)\r
+ port map (mem_clk, s_oam_ram_ce_n, s_oam_r_n, s_oam_w_n, s_oam_addr, s_oam_data);\r
+\r
+ spr_y_inst : d_flip_flop generic map(dsize)\r
+ port map (vga_clk_n, p_oam_cnt_res_n, '1', spr_y_we_n, s_oam_data, spr_y_tmp);\r
+ spr_tile_inst : d_flip_flop generic map(dsize)\r
+ port map (vga_clk_n, p_oam_cnt_res_n, '1', spr_tile_we_n, s_oam_data, spr_tile_tmp);\r
+\r
+\r
+ --reverse bit when NOT SPRHFL is set (.nes file format bit endian).\r
+ spr_ptn_in <= vram_ad when spr_attr(conv_integer(s_oam_addr_cpy(4 downto 2)))(SPRHFL) = '1' else\r
+ (vram_ad(0) & vram_ad(1) & vram_ad(2) & vram_ad(3) & \r
+ vram_ad(4) & vram_ad(5) & vram_ad(6) & vram_ad(7));\r
+ --array instances...\r
+ spr_inst : for i in 0 to 7 generate\r
+ spr_x_inst : counter_register generic map(dsize, 16#ff#)\r
+ port map (vga_clk_n, rst_n, spr_x_ce_n(i), spr_x_we_n(i), s_oam_data, spr_x_cnt(i));\r
+\r
+ spr_attr_inst : d_flip_flop generic map(dsize)\r
+ port map (vga_clk_n, rst_n, '1', spr_attr_we_n(i), s_oam_data, spr_attr(i));\r
+\r
+ spr_ptn_l_inst : shift_register generic map(dsize, 1)\r
+ port map (vga_clk_n, rst_n, spr_ptn_ce_n(i), spr_ptn_l_we_n(i), spr_ptn_in, spr_ptn_l(i));\r
+\r
+ spr_ptn_h_inst : shift_register generic map(dsize, 1)\r
+ port map (vga_clk_n, rst_n, spr_ptn_ce_n(i), spr_ptn_h_we_n(i), spr_ptn_in, spr_ptn_h(i));\r
+ end generate;\r
+\r
+ pos_p : process (rst_n, vga_clk)\r
begin\r
if (rst_n = '0') then\r
- x_res_n <= '0';\r
- y_res_n <= '0';\r
- frame_en_n <= '1';\r
- nes_r <= (others => '0');\r
- nes_g <= (others => '0');\r
- nes_b <= (others => '0');\r
- elsif (rising_edge(ppu_clk)) then\r
- --xmax = 340\r
- if (pos_x = conv_std_logic_vector(340, 9)) then\r
- x_res_n <= '0';\r
- y_en_n <= '0';\r
- --ymax=261\r
- if (pos_y = conv_std_logic_vector(261, 9)) then\r
- y_res_n <= '0';\r
- frame_en_n <= '0';\r
- else\r
- frame_en_n <= '1';\r
- y_res_n <= '1';\r
- end if;\r
+ cnt_x_res_n <= '0';\r
+ bg_cnt_res_n <= '0';\r
+ elsif (vga_clk'event and vga_clk = '0') then\r
+ if (cur_x = conv_std_logic_vector(HSCAN_MAX - 1, X_SIZE)) then\r
+ --x pos reset.\r
+ cnt_x_res_n <= '0';\r
else\r
- frame_en_n <= '1';\r
- x_res_n <= '1';\r
- y_en_n <= '1';\r
- y_res_n <= '1';\r
+ cnt_x_res_n <= '1';\r
end if;\r
- \r
--- nes_b <= pos_y (7 downto 4);\r
--- nes_g <= pos_x (5 downto 2);\r
--- nes_r <= pos_x(7 downto 4);\r
- --nes_r <= pos_x (3) & pos_x (3) & pos_x (3) & pos_x (3);\r
- if (pos_x <= conv_std_logic_vector(64, 9)) then\r
- nes_r <= "1111";\r
- nes_g <= "0000";\r
- nes_b <= "0000";\r
- elsif (pos_x <= conv_std_logic_vector(128, 9)) then\r
- nes_r <= "1100";\r
- nes_g <= "1111";\r
- nes_b <= "0000";\r
- elsif (pos_x <= conv_std_logic_vector(192, 9)) then\r
- nes_r <= "0011";\r
- nes_g <= "1111";\r
- nes_b <= "1111";\r
+\r
+ if (ppu_scroll_x(0) = '0' and cur_x = conv_std_logic_vector(HSCAN, X_SIZE)) then\r
+ bg_cnt_res_n <= '0';\r
+ elsif (ppu_scroll_x(0) = '1' and cur_x = conv_std_logic_vector(HSCAN - 1, X_SIZE)) then\r
+ bg_cnt_res_n <= '0';\r
else\r
- nes_r <= "1010";\r
- nes_g <= "0011";\r
- nes_b <= "1100";\r
+ bg_cnt_res_n <= '1';\r
end if;\r
- \r
- end if;\r
+ end if; --if (rst_n = '0') then\r
end process;\r
+\r
+ clk_p : process (rst_n, vga_clk, read_status)\r
+\r
+procedure output_rgb is\r
+variable pl_addr : integer;\r
+variable pl_index : integer;\r
+variable dot_output : boolean;\r
+begin\r
+ dot_output := false;\r
+\r
+ --first show sprite.\r
+ if (ppu_mask(PPUSSP) = '1') then\r
+ for i in 0 to 7 loop\r
+ if (spr_x_cnt(i) = "00000000") then\r
+ if ((spr_ptn_h(i)(0) or spr_ptn_l(i)(0)) = '1') then\r
+ dot_output := true;\r
+ exit;\r
+ end if;\r
+ end if;\r
+ end loop;\r
+ end if;\r
+\r
+ if (dot_output = true and ppu_mask(PPUSBG) = '1' and \r
+ (disp_ptn_h(0) or disp_ptn_l(0)) = '1') then\r
+ --raise sprite 0 hit.\r
+ ppu_status(ST_SP0) <= '1';\r
+ end if;\r
+\r
+ --first color in the palette is transparent color.\r
+ if (ppu_mask(PPUSBG) = '1' and dot_output = false and \r
+ (disp_ptn_h(0) or disp_ptn_l(0)) = '1') then\r
+ dot_output := true;\r
+-- d_print("output_rgb");\r
+-- d_print("pl_addr:" & conv_hex8(pl_addr));\r
+-- d_print("pl_index:" & conv_hex8(pl_index));\r
+ end if;\r
+\r
+ --if or if not bg/sprite is shown, output color anyway \r
+ --sinse universal bg color is included..\r
+ pl_index := conv_integer(plt_data(5 downto 0));\r
+ b <= nes_color_palette(pl_index) (11 downto 8);\r
+ g <= nes_color_palette(pl_index) (7 downto 4);\r
+ r <= nes_color_palette(pl_index) (3 downto 0);\r
+-- b <= nes_color_palette(1) (11 downto 8);\r
+-- g <= nes_color_palette(2) (7 downto 4);\r
+-- r <= nes_color_palette(3) (3 downto 0);\r
+end;\r
+procedure stop_rgb is\r
+begin\r
+ b <= (others => '0');\r
+ g <= (others => '0');\r
+ r <= (others => '0');\r
+end;\r
+\r
+ begin\r
+ if (rst_n = '0') then\r
+ nt_we_n <= '1';\r
+ ppu_status <= (others => '0');\r
+ s_oam_data <= (others => 'Z');\r
+ stop_rgb;\r
+ else\r
+\r
+ if (vga_clk'event and vga_clk = '1') then\r
+\r
+ --fetch bg pattern and display.\r
+ if (ppu_mask(PPUSBG) = '1' and \r
+ (cur_x <= conv_std_logic_vector(HSCAN, X_SIZE) or\r
+ cur_x > conv_std_logic_vector(HSCAN_NEXT_START, X_SIZE)) and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
+ cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE))) then\r
+ --visible area bg image\r
+\r
+ d_print("*");\r
+ d_print("cur_x: " & conv_hex16(conv_integer(cur_x)));\r
+ d_print("cur_y: " & conv_hex16(conv_integer(cur_y)));\r
+\r
+ ----fetch next tile byte.\r
+ if (prf_x (2 downto 0) = "001") then\r
+ --vram addr is incremented every 8 cycle.\r
+ --name table at 0x2000\r
+ vram_addr(9 downto 0) \r
+ <= prf_y(dsize - 1 downto 3) \r
+ & prf_x(dsize - 1 downto 3);\r
+ vram_addr(asize - 1 downto 10) <= "10" & ppu_ctrl(PPUBNA downto 0) \r
+ + ("000" & prf_x(dsize));\r
+ ----fetch attr table byte.\r
+ elsif (prf_x (4 downto 0) = "00011") then\r
+ --attribute table is loaded every 32 cycle.\r
+ --attr table at 0x23c0\r
+ vram_addr(dsize - 1 downto 0) <= "11000000" +\r
+ ("00" & prf_y(7 downto 5) & prf_x(7 downto 5));\r
+ vram_addr(asize - 1 downto dsize) <= "10" &\r
+ ppu_ctrl(PPUBNA downto 0) & "11"\r
+ + ("000" & prf_x(dsize) & "00");\r
+ ----fetch pattern table low byte.\r
+ elsif (prf_x (2 downto 0) = "101") then\r
+ --vram addr is incremented every 8 cycle.\r
+ vram_addr <= "0" & ppu_ctrl(PPUBPA) & \r
+ disp_nt(dsize - 1 downto 0) \r
+ & "0" & prf_y(2 downto 0);\r
+ ----fetch pattern table high byte.\r
+ elsif (prf_x (2 downto 0) = "111") then\r
+ --vram addr is incremented every 8 cycle.\r
+ vram_addr <= "0" & ppu_ctrl(PPUBPA) & \r
+ disp_nt(dsize - 1 downto 0) \r
+ & "0" & prf_y(2 downto 0) + "00000000001000";\r
+ end if;\r
+\r
+ ----fetch next tile byte.\r
+ if (prf_x (2 downto 0) = "010") then\r
+ nt_we_n <= '0';\r
+ else\r
+ nt_we_n <= '1';\r
+ end if;\r
+\r
+ ----fetch attr table byte.\r
+ if (prf_x (4 downto 0) = "00100") then\r
+ attr_we_n <= '0';\r
+ else\r
+ attr_we_n <= '1';\r
+ end if;\r
+ if (prf_x (4 downto 0) = "10000") then\r
+ disp_attr_we_n <= '0';\r
+ else\r
+ disp_attr_we_n <= '1';\r
+ end if;\r
+ ---attribute is shifted every 16 bit.\r
+ if (prf_x (3 downto 0) = "0000") then\r
+ attr_ce_n <= '0';\r
+ else\r
+ attr_ce_n <= '1';\r
+ end if;\r
+\r
+ ----fetch pattern table low byte.\r
+ if (prf_x (2 downto 0) = "110") then\r
+ ptn_l_we_n <= '0';\r
+ else\r
+ ptn_l_we_n <= '1';\r
+ end if;\r
+\r
+ ----fetch pattern table high byte.\r
+ if (prf_x (2 downto 0) = "000") then\r
+ ptn_h_we_n <= '0';\r
+ else\r
+ ptn_h_we_n <= '1';\r
+ end if;\r
+\r
+ end if;--if (ppu_mask(PPUSBG) = '1') and\r
+\r
+ --fetch sprite and display.\r
+ if (ppu_mask(PPUSSP) = '1' and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
+ cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE))) then\r
+ --secondary oam clear\r
+ if (cur_x /= "000000000" and cur_x <= conv_std_logic_vector(64, X_SIZE)) then\r
+ if (cur_x(0) = '0') then\r
+ --write secondary oam on even cycle\r
+ s_oam_r_n <= '1';\r
+ s_oam_w_n <= '0';\r
+ s_oam_addr <= cur_x(5 downto 1);\r
+ s_oam_data <= (others => '1');\r
+ end if;\r
+ p_oam_cnt_res_n <= '0';\r
+ p_oam_cnt_ce_n <= '1';\r
+ s_oam_cnt_ce_n <= '1';\r
+ p_oam_cnt_wrap_n <= '1';\r
+ oam_ev_status <= EV_STAT_COMP;\r
+\r
+ --sprite evaluation and secondary oam copy.\r
+ elsif (cur_x > conv_std_logic_vector(64, X_SIZE) and \r
+ cur_x <= conv_std_logic_vector(256, X_SIZE)) then\r
+ p_oam_cnt_res_n <= '1';\r
+\r
+ --TODO: sprite evaluation is simplified!!\r
+ --not complying the original NES spec at\r
+ --http://wiki.nesdev.com/w/index.php/PPU_sprite_evaluation\r
+ --e.g., when overflow happens, it just ignore subsequent entry.\r
+ --old secondary sprite entry.\r
+ if (p_oam_cnt = "00000000" and cur_x > conv_std_logic_vector(192, X_SIZE)) then\r
+ p_oam_cnt_wrap_n <= '0';\r
+ end if;\r
+\r
+ --odd cycle copy from primary oam\r
+ if (cur_x(0) = '1') then\r
+ if (oam_ev_status = EV_STAT_COMP) then\r
+ p_oam_addr_in <= p_oam_cnt;\r
+ p_oam_cnt_ce_n <= '1';\r
+ s_oam_cnt_ce_n <= '1';\r
+ elsif (oam_ev_status = EV_STAT_CP1) then\r
+ p_oam_addr_in <= p_oam_cnt + "00000001";\r
+ s_oam_cnt_ce_n <= '1';\r
+\r
+ elsif (oam_ev_status = EV_STAT_CP2) then\r
+ p_oam_addr_in <= p_oam_cnt + "00000010";\r
+ s_oam_cnt_ce_n <= '1';\r
+\r
+ elsif (oam_ev_status = EV_STAT_CP3) then\r
+ oam_ev_status <= EV_STAT_PRE_COMP;\r
+ p_oam_addr_in <= p_oam_cnt + "00000011";\r
+ s_oam_cnt_ce_n <= '1';\r
+ end if;\r
+ else\r
+ --even cycle copy to secondary oam (if y is in range.)\r
+ s_oam_r_n <= '1';\r
+ s_oam_w_n <= '0';\r
+ s_oam_addr <= s_oam_cnt;\r
+ s_oam_data <= p_oam_data;\r
+\r
+ if (oam_ev_status = EV_STAT_COMP) then\r
+ --check y range.\r
+ if (cur_y < "000000110" and p_oam_data <= cur_y + "000000001") or \r
+ (cur_y >= "000000110" and p_oam_data <= cur_y + "000000001" and \r
+ p_oam_data >= cur_y - "000000110") then\r
+ oam_ev_status <= EV_STAT_CP1;\r
+ s_oam_cnt_ce_n <= '0';\r
+ --copy remaining oam entry.\r
+ p_oam_cnt_ce_n <= '1';\r
+ else\r
+ --goto next entry\r
+ p_oam_cnt_ce_n <= '0';\r
+ end if;\r
+ elsif (oam_ev_status = EV_STAT_CP1) then\r
+ s_oam_cnt_ce_n <= '0';\r
+ oam_ev_status <= EV_STAT_CP2;\r
+ elsif (oam_ev_status = EV_STAT_CP2) then\r
+ s_oam_cnt_ce_n <= '0';\r
+ oam_ev_status <= EV_STAT_CP3;\r
+ elsif (oam_ev_status = EV_STAT_CP3) then\r
+ s_oam_cnt_ce_n <= '0';\r
+ elsif (oam_ev_status = EV_STAT_PRE_COMP) then\r
+ oam_ev_status <= EV_STAT_COMP;\r
+ s_oam_cnt_ce_n <= '0';\r
+ p_oam_cnt_ce_n <= '0';\r
+ end if;\r
+ end if;--if (cur_x(0) = '1') then\r
+\r
+ --prepare for next step\r
+ s_oam_addr_cpy_n <= '1';\r
+ spr_y_we_n <= '1';\r
+ spr_tile_we_n <= '1';\r
+ spr_x_we_n <= "11111111";\r
+ spr_attr_we_n <= "11111111";\r
+ spr_ptn_l_we_n <= "11111111";\r
+ spr_ptn_h_we_n <= "11111111";\r
+\r
+ --sprite pattern fetch\r
+ elsif (cur_x > conv_std_logic_vector(256, X_SIZE) and \r
+ cur_x <= conv_std_logic_vector(HSCAN_NEXT_START, X_SIZE)) then\r
+\r
+ s_oam_addr_cpy_n <= '0';\r
+ s_oam_r_n <= '0';\r
+ s_oam_w_n <= '1';\r
+ s_oam_addr <= s_oam_addr_cpy;\r
+\r
+ ----fetch y-cordinate from secondary oam\r
+ if (cur_x (2 downto 0) = "001" ) then\r
+ s_oam_addr_cpy_ce_n <= '0';\r
+ spr_y_we_n <= '0';\r
+ else\r
+ spr_y_we_n <= '1';\r
+ end if;\r
+\r
+ ----fetch tile number\r
+ if (cur_x (2 downto 0) = "010" ) then\r
+ spr_tile_we_n <= '0';\r
+ else\r
+ spr_tile_we_n <= '1';\r
+ end if;\r
+\r
+ ----fetch attribute\r
+ if (cur_x (2 downto 0) = "011" ) then\r
+ spr_attr_we_n(conv_integer(s_oam_addr_cpy(4 downto 2))) <= '0';\r
+ else\r
+ spr_attr_we_n(conv_integer(s_oam_addr_cpy(4 downto 2))) <= '1';\r
+ end if;--if (cur_x (2 downto 0) = "010" ) then\r
+\r
+ ----fetch x-cordinate\r
+ if (cur_x (2 downto 0) = "100" ) then\r
+ s_oam_addr_cpy_ce_n <= '1';\r
+ spr_x_we_n(conv_integer(s_oam_addr_cpy(4 downto 2))) <= '0';\r
+ else\r
+ spr_x_we_n(conv_integer(s_oam_addr_cpy(4 downto 2))) <= '1';\r
+ end if;\r
+\r
+ ----fetch pattern table low byte.\r
+ if (cur_x (2 downto 0) = "101" ) then\r
+ if (spr_attr(conv_integer(s_oam_addr_cpy(4 downto 2)))(SPRVFL) = '0') then\r
+ vram_addr <= "0" & ppu_ctrl(PPUSPA) & \r
+ spr_tile_tmp(dsize - 1 downto 0) & "0" & \r
+ (cur_y(2 downto 0) + "001" - spr_y_tmp(2 downto 0));\r
+ else\r
+ --flip sprite vertically.\r
+ vram_addr <= "0" & ppu_ctrl(PPUSPA) & \r
+ spr_tile_tmp(dsize - 1 downto 0) & "0" & \r
+ (spr_y_tmp(2 downto 0) - cur_y(2 downto 0) - "010");\r
+ end if;\r
+ end if;\r
+\r
+ if (cur_x (2 downto 0) = "110" ) then\r
+ spr_ptn_l_we_n(conv_integer(s_oam_addr_cpy(4 downto 2))) <= '0';\r
+ else\r
+ spr_ptn_l_we_n(conv_integer(s_oam_addr_cpy(4 downto 2))) <= '1';\r
+ end if;\r
+\r
+ ----fetch pattern table high byte.\r
+ if (cur_x (2 downto 0) = "111" ) then\r
+ if (spr_attr(conv_integer(s_oam_addr_cpy(4 downto 2)))(SPRVFL) = '0') then\r
+ vram_addr <= "0" & ppu_ctrl(PPUSPA) & \r
+ spr_tile_tmp(dsize - 1 downto 0) & "0" & \r
+ (cur_y(2 downto 0) + "001" - spr_y_tmp(2 downto 0))\r
+ + "00000000001000";\r
+ else\r
+ --flip sprite vertically.\r
+ vram_addr <= "0" & ppu_ctrl(PPUSPA) & \r
+ spr_tile_tmp(dsize - 1 downto 0) & "0" & \r
+ (spr_y_tmp(2 downto 0) - cur_y(2 downto 0) - "010")\r
+ + "00000000001000";\r
+ end if;\r
+ end if;\r
+\r
+ if (cur_x (2 downto 0) = "000") then\r
+ spr_ptn_h_we_n(conv_integer(s_oam_addr_cpy(4 downto 2))) <= '0';\r
+ s_oam_addr_cpy_ce_n <= '0';\r
+ else\r
+ spr_ptn_h_we_n(conv_integer(s_oam_addr_cpy(4 downto 2) - "001")) <= '1';\r
+ end if;\r
+\r
+ elsif (cur_x > conv_std_logic_vector(320, X_SIZE)) then\r
+ --clear last write enable.\r
+ spr_ptn_h_we_n <= "11111111";\r
+ end if;--if (cur_x /= "000000000" and cur_x <= conv_std_logic_vector(64, X_SIZE))\r
+\r
+ --display sprite.\r
+ if ((cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE))) then\r
+ --start counter.\r
+ if (cur_x = "000000000") then\r
+ spr_x_ce_n <= "00000000";\r
+ end if;\r
+\r
+ for i in 0 to 7 loop\r
+ if (spr_x_cnt(i) = "00000000") then\r
+ --active sprite, start shifting..\r
+ spr_x_ce_n(i) <= '1';\r
+ spr_ptn_ce_n(i) <= '0';\r
+ end if;\r
+ end loop;\r
+ else\r
+ spr_x_ce_n <= "11111111";\r
+ spr_ptn_ce_n <= "11111111";\r
+ end if; --if ((cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) \r
+ end if; --if (ppu_mask(PPUSSP) = '1') then\r
+\r
+ --output visible area only.\r
+ if ((cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE))) then\r
+ --output image.\r
+ output_rgb;\r
+ else\r
+ stop_rgb;\r
+ end if;\r
+\r
+ --flag operation\r
+ if ((cur_x = conv_std_logic_vector(1, X_SIZE)) and\r
+ (cur_y = conv_std_logic_vector(VSCAN + 1, X_SIZE))) then\r
+ --vblank start\r
+ ppu_status(ST_VBL) <= '1';\r
+ elsif ((cur_x = conv_std_logic_vector(1, X_SIZE)) and\r
+ (cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE))) then\r
+ ppu_status(ST_SP0) <= '0';\r
+ --vblank end\r
+ ppu_status(ST_VBL) <= '0';\r
+ --TODO: sprite overflow is not inplemented!\r
+ ppu_status(ST_SOF) <= '0';\r
+ end if;\r
+ end if; --if (clk'event and clk = '1') then\r
+\r
+-- if (read_status'event and read_status = '1') then\r
+-- --reading ppu status clears vblank bit.\r
+-- ppu_status(ST_VBL) <= '0';\r
+-- end if;\r
+\r
+ end if;--if (rst_n = '0') then\r
+ end process;\r
+\r
end rtl;\r
+\r
-:2000000078A2FF9A20258620E185AD40868500AD41868501206985204F80AD5B868500AD2D\r
-:200020005C8685012069854C4180AD3F86D005A900200000AD6F868500AD70868501206954\r
-:2000400085A91E8D0120A9808D00204C4B804020D985AD80868500AD81868501206985601B\r
-:20006000AD93868500AD94868501206985189003202A8038B003202A80A900F003202A804A\r
-:2000800018E9053003202A80D003202A801869061003202A8038A992E9467003202A803845\r
-:2000A000A992E9125003202A80A900A200F07B4C2A81EAEAEAEAEAEAEAEAEAEAEAEAEAEA74\r
-:2000C000EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAE0\r
-:2000E000EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAC0\r
-:20010000EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA9F\r
-:20012000EAEAEAEAEAEAEAEAEAEAE8E001F080A900A200F07B4CB081EAEAEAEAEAEAEAEADF\r
-:20014000EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA5F\r
-:20016000EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA3F\r
-:20018000EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA1F\r
-:2001A000EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAE8E001F08018A96420C281C9C8F00E202F\r
-:2001C0002A8020C6816020CA816069646038A9C84CDD8169324CE2814CD38169324CD88139\r
-:2001E0006932C9FBF003202A8038A9C36CEF810182F781FC8106826CF38169E669E66CF584\r
-:20020000816CF18169E6C9AAF003202A80A92348A94648A96E48380878081808A9FF08A91D\r
-:200220000008A9FF28F003202A80283003202A80289003202A802828B003202A805868C929\r
-:200240006EF003202A8068C946F003202A8068C923F003202A8060ADA5868500ADA6868513\r
-:2002600001206985A939856BA9A18DCC04A99F85FFA2FD066BA56BC972F003202A80CECC78\r
-:2002800004ADCC04C9A0F003202A805ECF03ADCC04C950F003202A80F602A5FFC9A0F0033C\r
-:2002A000202A801836023602A5FFC981F003202A803876027602A5FFC9E0F003202A8060AF\r
-:2002C000ADB7868500ADB8868501206985A97885A1A90585A2A9B7A2E1A08A85A98E990AA8\r
-:2002E0009D800D941F91A1C5A9F003202A80EC990AF003202A80CD610EF003202A80C400BB\r
-:20030000F003202A80CD0206F003202A8060ADC9868500ADCA86850120698518A90D69FAEB\r
-:20032000C907F003202A80A937855EA9C98571A9B6255E2471F003202A80A93B8D2104A992\r
-:20034000D78D1B05A9EB8DCC06AE2104E88A4D1B05A8CCCC06F003202A80A217A0A1A92F9F\r
-:200360008D5903A9909990018A19900138FD4203A8C068F003202A80A2CDA9F18535A9ACDE\r
-:2003800085BCA98D3568A09A592200AAE02DF003202A80A9388590A9088591A9D98D020949\r
-:2003A000A90AA0CA187190C9E3F003202A8060ADDB868500ADDC868501206985A980180ABD\r
-:2003C000F003202A80B003202A801003202A800AF003202A809003202A801003202A80A95C\r
-:2003E000400AD003202A809003202A803003202A80C980F003202A80A9A50AC94AF0032038\r
-:200400002A800AC994F003202A80A901084828B003202A80189003202A8028A94008482871\r
-:200420007003202A80B85003202A8028A203CAD003202A80E002F003202A801003202A80FA\r
-:20044000CAD003202A80E001F003202A801003202A80CAF003202A80E000F003202A801086\r
-:2004600003202A80CAD003202A803003202A80E0FFF003202A80A2803003202A80CA1003B3\r
-:20048000202A80E07FF003202A80A05088C04FF003202A8088C04EF003202A80C8C04FF018\r
-:2004A00003202A80E8E080F003202A80A901184AF003202A80B003202A804AF003202A801D\r
-:2004C0009003202A80A95A4AC92DF003202A80A9A5386AC9D2F003202A806A9003202A80B0\r
-:2004E000C9E9F003202A80182A2AC9A5F003202A80B003202A8008A90048289003202A80FB\r
-:2005000038B003202A807808682904D003202A805808682904F003202A8028A901AA100333\r
-:20052000202A80D003202A80E001F003202A80CA8A1003202A80F003202A80A901A8C8C8E6\r
-:2005400098C003F003202A80BA8600A2309AA9DD48BAE02FF003202A80A6009AA9EEAD30CF\r
-:2005600001C9DDF003202A806020D985AD00038D0620AD01038D0620A000B1008D0720F07D\r
-:2005800004C84C7A8598291FC91FF009A9008D0720C84C8585AD01038C01036D01038D01C8\r
-:2005A00003AAAD000390061869018D0003C923D00F8AC9C0D00AA9208D0003A9008D0103EB\r
-:2005C000AD02038D0520AD0303186908C9F0D002A9008D03038D052060AD3F86D00268688E\r
-:2005E0006020D985A9008D00208D0120A93F8D0620A9008D0620A200A020BD05868D0720C4\r
-:20060000E888D0F6600F0010200F0414240F0818280F0C1C2C0F0010200F0616260F081841\r
-:20062000280F0A1A2AAD3F86F014A9238D0003A9A08D0103A9008D0203A9E88D03036001C9\r
-:20064000428672656772657373696F6E20746573742073746172742E2E2E005D86746573AA\r
-:2006600074207375636365656465642E2E2E00718674657374206661696C65642121210018\r
-:20068000828670707520696E737420746573742E2E2E009586613520696E737420746573BA\r
-:2006A000742E2E2E00A786613420696E737420746573742E2E2E00B986613320696E737481\r
-:2006C00020746573742E2E2E00CB86613220696E737420746573742E2E2E00DD8673696ED7\r
-:2006E000676C65206279746520696E737420746573742E2E2E0000000000000000000000A6\r
+:2000000078A2FF9AA9008D00208D0120A93F8D0620A9008D0620A9118D0720A9018D072066\r
+:20002000A9038D0720A9138D0720A90F8D0720A9048D0720A9148D0720A9248D0720A90F79\r
+:200040008D0720A9088D0720A9188D0720A9288D0720A9058D0720A90C8D0720A91C8D0769\r
+:2000600020A92C8D0720A9008D0720A9248D0720A91B8D0720A9118D0720A9008D0720A90D\r
+:20008000328D0720A9168D0720A9208D0720A9008D0720A9268D0720A9018D0720A9318DE5\r
+:2000A0000720A9208D0620A9068D0620A9448D0720A9458D0720A9458D0720A9218D0620D9\r
+:2000C000A9E68D0620A9448D0720A9458D0720A9458D0720A9008D0720A9548D0720A945FD\r
+:2000E0008D0720A9538D0720A9548D0720A9218D0720A9238D0620A9C18D0620A9D88D07BC\r
+:2001000020A9008D0320A9028D0420A94D8D0420A9038D0420A9648D0420A9328D0420A913\r
+:200120004F8D0420A9018D0420A91E8D0420A93C8D0420A9508D0420A9018D0420A9218DFA\r
+:200140000420A93D8D0420A9518D0420A9028D0420A92D8D0420A91E8D0120A9808D00200B\r
+:200160004C6081400000000000000000000000000000000000000000000000000000000012\r
+:2001800000000000000000000000000000000000000000000000000000000000000000005F\r
+:2001A00000000000000000000000000000000000000000000000000000000000000000003F\r
+:2001C00000000000000000000000000000000000000000000000000000000000000000001F\r
+:2001E0000000000000000000000000000000000000000000000000000000000000000000FF\r
+:200200000000000000000000000000000000000000000000000000000000000000000000DE\r
+:200220000000000000000000000000000000000000000000000000000000000000000000BE\r
+:2002400000000000000000000000000000000000000000000000000000000000000000009E\r
+:2002600000000000000000000000000000000000000000000000000000000000000000007E\r
+:2002800000000000000000000000000000000000000000000000000000000000000000005E\r
+:2002A00000000000000000000000000000000000000000000000000000000000000000003E\r
+:2002C00000000000000000000000000000000000000000000000000000000000000000001E\r
+:2002E0000000000000000000000000000000000000000000000000000000000000000000FE\r
+:200300000000000000000000000000000000000000000000000000000000000000000000DD\r
+:200320000000000000000000000000000000000000000000000000000000000000000000BD\r
+:2003400000000000000000000000000000000000000000000000000000000000000000009D\r
+:2003600000000000000000000000000000000000000000000000000000000000000000007D\r
+:2003800000000000000000000000000000000000000000000000000000000000000000005D\r
+:2003A00000000000000000000000000000000000000000000000000000000000000000003D\r
+:2003C00000000000000000000000000000000000000000000000000000000000000000001D\r
+:2003E0000000000000000000000000000000000000000000000000000000000000000000FD\r
+:200400000000000000000000000000000000000000000000000000000000000000000000DC\r
+:200420000000000000000000000000000000000000000000000000000000000000000000BC\r
+:2004400000000000000000000000000000000000000000000000000000000000000000009C\r
+:2004600000000000000000000000000000000000000000000000000000000000000000007C\r
+:2004800000000000000000000000000000000000000000000000000000000000000000005C\r
+:2004A00000000000000000000000000000000000000000000000000000000000000000003C\r
+:2004C00000000000000000000000000000000000000000000000000000000000000000001C\r
+:2004E0000000000000000000000000000000000000000000000000000000000000000000FC\r
+:200500000000000000000000000000000000000000000000000000000000000000000000DB\r
+:200520000000000000000000000000000000000000000000000000000000000000000000BB\r
+:2005400000000000000000000000000000000000000000000000000000000000000000009B\r
+:2005600000000000000000000000000000000000000000000000000000000000000000007B\r
+:2005800000000000000000000000000000000000000000000000000000000000000000005B\r
+:2005A00000000000000000000000000000000000000000000000000000000000000000003B\r
+:2005C00000000000000000000000000000000000000000000000000000000000000000001B\r
+:2005E0000000000000000000000000000000000000000000000000000000000000000000FB\r
+:200600000000000000000000000000000000000000000000000000000000000000000000DA\r
+:200620000000000000000000000000000000000000000000000000000000000000000000BA\r
+:2006400000000000000000000000000000000000000000000000000000000000000000009A\r
+:2006600000000000000000000000000000000000000000000000000000000000000000007A\r
+:2006800000000000000000000000000000000000000000000000000000000000000000005A\r
+:2006A00000000000000000000000000000000000000000000000000000000000000000003A\r
+:2006C00000000000000000000000000000000000000000000000000000000000000000001A\r
+:2006E0000000000000000000000000000000000000000000000000000000000000000000FA\r
:200700000000000000000000000000000000000000000000000000000000000000000000D9\r
:200720000000000000000000000000000000000000000000000000000000000000000000B9\r
:20074000000000000000000000000000000000000000000000000000000000000000000099\r
:200F8000000000000000000000000000000000000000000000000000000000000000000051\r
:200FA000000000000000000000000000000000000000000000000000000000000000000031\r
:200FC000000000000000000000000000000000000000000000000000000000000000000011\r
-:200FE00000000000000000000000000000000000000000000000000000004E8000800000A3\r
+:200FE00000000000000000000000000000000000000000000000000000006381008000008D\r
:00000001FF\r
\r
#add wave *\r
\r
-add wave sim:/testbench_motones_sim/sim_board/rst_n\r
\r
add wave -divider cpu\r
+add wave -label rst_n sim:/testbench_motones_sim/sim_board/rst_n\r
+add wave -label cpu_clk sim:/testbench_motones_sim/sim_board/dbg_cpu_clk\r
+#add wave -label vga_clk sim:/testbench_motones_sim/sim_board/dbg_ppu_scrl_x(4)\r
+#add wave -label mem_clk sim:/testbench_motones_sim/sim_board/dbg_mem_clk\r
\r
-##add wave sim:/testbench_motones_sim/sim_board/dbg_mem_clk\r
\r
-add wave sim:/testbench_motones_sim/sim_board/dbg_r_nw\r
\r
-add wave sim:/testbench_motones_sim/sim_board/dbg_cpu_clk\r
+add wave -label r_nw sim:/testbench_motones_sim/sim_board/dbg_r_nw\r
+add wave -label addr -radix hex sim:/testbench_motones_sim/sim_board/dbg_addr\r
+add wave -label d_io -radix hex sim:/testbench_motones_sim/sim_board/dbg_d_io\r
+add wave -label instruction -radix hex sim:/testbench_motones_sim/sim_board/dbg_instruction\r
\r
-add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_addr\r
-add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_d_io\r
\r
-add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_instruction\r
-add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_int_d_bus\r
+add wave -divider ce-pins\r
+add wave -label rom_ce_n sim:/testbench_motones_sim/sim_board/dbg_ppu_scrl_x(5)\r
+add wave -label ram_ce_n sim:/testbench_motones_sim/sim_board/dbg_ppu_scrl_x(6)\r
\r
-add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_exec_cycle\r
+#add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_int_d_bus\r
+#add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_exec_cycle\r
+#add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_ea_carry \r
+#add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_wait_a58_branch_next \r
\r
-add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_ea_carry \r
-add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_wait_a58_branch_next \r
\r
+#add wave -divider regs\r
\r
-add wave -divider regs\r
-\r
-#add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_index_bus;\r
-#add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_acc_bus;\r
-## dbg_pcl, dbg_pch, \r
-\r
-add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_acc\r
-add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_sp\r
-add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_status\r
-add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_x\r
-add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_y\r
+#add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_acc\r
+#add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_sp\r
+#add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_status\r
+#add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_x\r
+#add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_y\r
\r
\r
add wave -divider ppu\r
+add wave -label ppu_clk sim:/testbench_motones_sim/sim_board/dbg_ppu_clk\r
+add wave -label ppu_ce_n sim:/testbench_motones_sim/sim_board/dbg_ppu_ce_n\r
+add wave -label ppu_ctrl -radix hex sim:/testbench_motones_sim/sim_board/dbg_ppu_ctrl\r
+add wave -label ppu_mask -radix hex sim:/testbench_motones_sim/sim_board/dbg_ppu_mask\r
+#add wave -label ppu_status -radix hex sim:/testbench_motones_sim/sim_board/dbg_ppu_status\r
+add wave -label ppu_addr -radix hex sim:/testbench_motones_sim/sim_board/dbg_ppu_addr\r
+add wave -label ppu_data -radix hex sim:/testbench_motones_sim/sim_board/dbg_ppu_data\r
\r
-add wave sim:/testbench_motones_sim/sim_board/dbg_ppu_ce_n\r
-add wave sim:/testbench_motones_sim/sim_board/dbg_ppu_clk\r
-\r
-add wave sim:/testbench_motones_sim/dbg_ppu_addr_we_n\r
-add wave -radix hex sim:/testbench_motones_sim/dbg_ppu_clk_cnt\r
-\r
-\r
-add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_ppu_ctrl\r
-add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_ppu_mask\r
-add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_ppu_status\r
-add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_ppu_addr \r
-add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_ppu_data\r
-add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_ppu_scrl_x\r
-add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_ppu_scrl_y\r
\r
+add wave -divider vga_pos\r
+#add wave -label nes_x -radix decimal -unsigned sim:/testbench_motones_sim/sim_board/dbg_ppu_addr\r
+add wave -label dbg_disp_nt -radix hex sim:/testbench_motones_sim/sim_board/dbg_disp_nt\r
+add wave -label dbg_disp_attr -radix hex sim:/testbench_motones_sim/sim_board/dbg_disp_attr\r
+#add wave -label dbg_disp_ptn_h -radix hex sim:/testbench_motones_sim/sim_board/dbg_disp_ptn_h\r
+#add wave -label dbg_disp_ptn_l -radix hex sim:/testbench_motones_sim/sim_board/dbg_disp_ptn_l\r
\r
-add wave -divider render\r
-#add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_disp_nt\r
-#add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_disp_attr \r
-#add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_disp_ptn_h\r
-#add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_disp_ptn_l\r
+add wave -divider vram\r
+add wave -label ale sim:/testbench_motones_sim/sim_board/dbg_ppu_scrl_x(0)\r
+add wave -label rd_n sim:/testbench_motones_sim/sim_board/dbg_ppu_scrl_x(1)\r
+add wave -label wr_n sim:/testbench_motones_sim/sim_board/dbg_ppu_scrl_x(2)\r
+add wave -label nt0_ce_n sim:/testbench_motones_sim/sim_board/dbg_ppu_scrl_x(3)\r
\r
+add wave -radix hex -label v_addr sim:/testbench_motones_sim/sim_board/dbg_disp_ptn_l\r
+add wave -radix hex -label vram_ad sim:/testbench_motones_sim/sim_board/dbg_vram_ad\r
\r
-add wave -divider debug\r
\r
-#add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_idl_h\r
-#add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_idl_l\r
-#add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_dbb_r\r
-#add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_dbb_w\r
+add wave -label plt_ce_n sim:/testbench_motones_sim/sim_board/dbg_ppu_scrl_y(5)\r
+add wave -label plt_r_n sim:/testbench_motones_sim/sim_board/dbg_ppu_scrl_y(4)\r
+add wave -label plt_w_n sim:/testbench_motones_sim/sim_board/dbg_ppu_scrl_y(3)\r
+add wave -radix hex -label plt_addr {sim:/testbench_motones_sim/sim_board/dbg_disp_ptn_h(12 downto 8)}\r
+add wave -radix hex -label plt_data {sim:/testbench_motones_sim/sim_board/dbg_disp_ptn_h(7 downto 0)}\r
\r
-#add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_dec_oe_n\r
-#add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_dec_val\r
-#add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_int_dbus\r
\r
-#add wave -divider debug2\r
\r
+add wave -divider vga_out\r
+add wave -label h_sync_n sim:/testbench_motones_sim/sim_board/v_sync_n\r
+add wave -label v_sync_n sim:/testbench_motones_sim/sim_board/h_sync_n\r
+add wave -label r -radix hex sim:/testbench_motones_sim/sim_board/r\r
+add wave -label g -radix hex sim:/testbench_motones_sim/sim_board/g\r
+add wave -label b -radix hex sim:/testbench_motones_sim/sim_board/b\r
\r
-#add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_status_val\r
-#add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_stat_we_n\r
\r
view structure\r
view signals\r
#run -all\r
-run 10 us\r
-run 60 us\r
+run 8 us\r
\r
#wave zoom range 3339700 ps 5138320 ps\r
wave zoom full\r
+##\r
+## run this script on modelsim\r
+## > do de1_nes_run_msim_rtl_vhdl.do\r
+##\r
+\r
+\r
transcript on\r
if {[file exists rtl_work]} {\r
vdel -lib rtl_work -all\r
\r
##add wave sim:/testbench_motones_sim/sim_board/ppu_clk\r
\r
-add wave sim:/testbench_motones_sim/sim_board/rst_n;\r
-add wave sim:/testbench_motones_sim/sim_board/r_nw;\r
-add wave sim:/testbench_motones_sim/sim_board/cpu_clk\r
-add wave -radix hex sim:/testbench_motones_sim/sim_board/addr\r
-add wave -radix hex sim:/testbench_motones_sim/sim_board/d_io\r
-add wave -radix hex sim:/testbench_motones_sim/sim_board/cpu_inst/instruction\r
-add wave -radix hex sim:/testbench_motones_sim/sim_board/cpu_inst/int_d_bus\r
-add wave -radix hex sim:/testbench_motones_sim/sim_board/cpu_inst/exec_cycle\r
+add wave -label rst_n sim:/testbench_motones_sim/sim_board/rst_n;\r
+add wave -label r_nw sim:/testbench_motones_sim/sim_board/r_nw;\r
+add wave -label cpu_clk sim:/testbench_motones_sim/sim_board/cpu_clk\r
+add wave -label addr -radix hex sim:/testbench_motones_sim/sim_board/addr\r
+add wave -label d_io -radix hex sim:/testbench_motones_sim/sim_board/d_io\r
+add wave -label instruction -radix hex sim:/testbench_motones_sim/sim_board/cpu_inst/instruction\r
+add wave -label int_d_bus -radix hex sim:/testbench_motones_sim/sim_board/cpu_inst/int_d_bus\r
+add wave -label exec_cycle -radix hex sim:/testbench_motones_sim/sim_board/cpu_inst/exec_cycle\r
\r
add wave -divider regs\r
-add wave -radix hex sim:/testbench_motones_sim/sim_board/cpu_inst/acc/q\r
-add wave -radix hex sim:/testbench_motones_sim/sim_board/cpu_inst/status_register/status_val\r
-add wave -radix hex sim:/testbench_motones_sim/sim_board/cpu_inst/sp/q\r
-add wave -radix hex sim:/testbench_motones_sim/sim_board/cpu_inst/x/q\r
-add wave -radix hex sim:/testbench_motones_sim/sim_board/cpu_inst/y/q\r
+add wave -label acc -radix hex sim:/testbench_motones_sim/sim_board/cpu_inst/acc/q\r
+add wave -label status_val -radix hex sim:/testbench_motones_sim/sim_board/cpu_inst/status_register/status_val\r
+add wave -label sp -radix hex sim:/testbench_motones_sim/sim_board/cpu_inst/sp/q\r
+add wave -label x -radix hex sim:/testbench_motones_sim/sim_board/cpu_inst/x/q\r
+add wave -label y -radix hex sim:/testbench_motones_sim/sim_board/cpu_inst/y/q\r
\r
\r
##add wave -radix hex sim:/testbench_motones_sim/sim_board/cpu_inst/status_reg\r
\r
add wave -divider ppu\r
\r
-add wave sim:/testbench_motones_sim/sim_board/dbg_ppu_ce_n\r
-add wave sim:/testbench_motones_sim/sim_board/dbg_ppu_clk\r
+add wave -label cpu_addr -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/cpu_addr\r
+add wave -label cpu_d -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/cpu_d\r
+\r
+add wave -label ppu_ce_n sim:/testbench_motones_sim/sim_board/ppu_inst/ce_n\r
+add wave -label ppu_clk sim:/testbench_motones_sim/sim_board/ppu_inst/clk\r
+\r
+add wave -label ppu_clk_cnt -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/ppu_clk_cnt\r
\r
-add wave -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/ppu_clk_cnt\r
+add wave -label ppu_ctl -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/ppu_ctrl\r
+add wave -label ppu_mask -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/ppu_mask\r
+add wave -label ppu_status -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/ppu_status\r
\r
-add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_ppu_ctrl\r
-add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_ppu_mask\r
-add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_ppu_status\r
-add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_ppu_addr \r
-add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_ppu_data\r
-add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_ppu_scrl_x\r
-add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_ppu_scrl_y\r
+\r
+#add wave -label ppu_addr_cnt -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/ppu_addr_cnt\r
+#add wave -label ppu_addr_we_n -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/ppu_addr_we_n\r
+#add wave -label ppu_addr_in -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/ppu_addr_in\r
+#add wave -label ppu_addr_inc1 -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/ppu_addr_inc1\r
+#add wave -label ppu_addr_inc32 -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/ppu_addr_inc32\r
+\r
+add wave -label ppu_addr -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/ppu_addr\r
+add wave -label ppu_data -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/ppu_data\r
+#add wave -label ppu_scr_x -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/ppu_scrl_x\r
+#add wave -label ppu_scr_y -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/ppu_scrl_y\r
\r
###add wave sim:/testbench_motones_sim/sim_board/cpu_inst/*\r
\r
add wave -divider render\r
\r
-add wave -radix decimal -unsigned sim:/testbench_motones_sim/sim_board/ppu_inst/pos_x \\r
-sim:/testbench_motones_sim/sim_board/ppu_inst/pos_y \r
+#add wave -radix decimal -unsigned sim:/testbench_motones_sim/sim_board/ppu_inst/pos_x \\r
+#sim:/testbench_motones_sim/sim_board/ppu_inst/pos_y \r
\r
-add wave -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/nes_r \\r
-sim:/testbench_motones_sim/sim_board/ppu_inst/nes_g \\r
-sim:/testbench_motones_sim/sim_board/ppu_inst/nes_b\r
+#add wave -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/nes_r \\r
+#sim:/testbench_motones_sim/sim_board/ppu_inst/nes_g \\r
+#sim:/testbench_motones_sim/sim_board/ppu_inst/nes_b\r
\r
-add wave sim:/testbench_motones_sim/sim_board/ppu_inst/h_sync_n \\r
-sim:/testbench_motones_sim/sim_board/ppu_inst/v_sync_n\r
+add wave -label h_sync_n sim:/testbench_motones_sim/sim_board/ppu_inst/h_sync_n\r
+add wave -label v_sync_n sim:/testbench_motones_sim/sim_board/ppu_inst/v_sync_n\r
\r
view structure\r
view signals\r
-#run 100 us\r
-run 80 us\r
+\r
+run 8 us\r
wave zoom full\r
\r
+#run 500 us\r
+#wave zoom full\r
+\r
+#run 1000 us\r
+#wave zoom full\r
architecture stimulus of testbench_motones_sim is
component de1_nes
- port (
+ port (
--debug signal
signal dbg_cpu_clk : out std_logic;
signal dbg_ppu_clk : out std_logic;
signal dbg_mem_clk : out std_logic;
- signal dbg_addr : out std_logic_vector( 16 - 1 downto 0);
- signal dbg_d_io : inout std_logic_vector( 8 - 1 downto 0);
+ signal dbg_r_nw : out std_logic;
+ signal dbg_addr : out std_logic_vector( 16 - 1 downto 0);
+ signal dbg_d_io : out std_logic_vector( 8 - 1 downto 0);
signal dbg_vram_ad : out std_logic_vector (7 downto 0);
signal dbg_vram_a : out std_logic_vector (13 downto 8);
---monitor inside cpu
signal dbg_instruction : out std_logic_vector(7 downto 0);
- signal dbg_int_d_bus : out std_logic_vector(7 downto 0);
+ signal dbg_int_d_bus : out std_logic_vector(7 downto 0);
signal dbg_exec_cycle : out std_logic_vector (5 downto 0);
signal dbg_ea_carry : out std_logic;
signal dbg_wait_a58_branch_next : out std_logic;
-- signal dbg_status_val : out std_logic_vector (7 downto 0);
-- signal dbg_stat_we_n : out std_logic;
-- signal dbg_idl_h, dbg_idl_l, dbg_dbb_r, dbg_dbb_w : out std_logic_vector (7 downto 0);
+
+--ppu debug pins
signal dbg_ppu_ce_n : out std_logic;
signal dbg_ppu_ctrl, dbg_ppu_mask, dbg_ppu_status : out std_logic_vector (7 downto 0);
signal dbg_ppu_addr : out std_logic_vector (13 downto 0);
signal dbg_ppu_data, dbg_ppu_scrl_x, dbg_ppu_scrl_y : out std_logic_vector (7 downto 0);
--- signal dbg_disp_nt, dbg_disp_attr : out std_logic_vector (7 downto 0);
--- signal dbg_disp_ptn_h, dbg_disp_ptn_l : out std_logic_vector (15 downto 0);
- signal dbg_ppu_addr_we_n : out std_logic;
- signal dbg_ppu_clk_cnt : out std_logic_vector(1 downto 0);
+ signal dbg_disp_nt, dbg_disp_attr : out std_logic_vector (7 downto 0);
+ signal dbg_disp_ptn_h, dbg_disp_ptn_l : out std_logic_vector (15 downto 0);
--NES instance
- base_clk : in std_logic;
- rst_n : in std_logic;
- joypad1 : in std_logic_vector(7 downto 0);
- joypad2 : in std_logic_vector(7 downto 0);
- vga_clk : out std_logic;
- h_sync_n : out std_logic;
- v_sync_n : out std_logic;
- r : out std_logic_vector(3 downto 0);
- g : out std_logic_vector(3 downto 0);
- b : out std_logic_vector(3 downto 0)
- );
- end component;
-
- component vga_device
- port ( vga_clk : in std_logic;
- rst_n : in std_logic;
- h_sync_n : in std_logic;
- v_sync_n : in std_logic;
- r : in std_logic_vector(3 downto 0);
- g : in std_logic_vector(3 downto 0);
- b : in std_logic_vector(3 downto 0)
- );
+ base_clk : in std_logic;
+ rst_n : in std_logic;
+ joypad1 : in std_logic_vector(7 downto 0);
+ joypad2 : in std_logic_vector(7 downto 0);
+ h_sync_n : out std_logic;
+ v_sync_n : out std_logic;
+ r : out std_logic_vector(3 downto 0);
+ g : out std_logic_vector(3 downto 0);
+ b : out std_logic_vector(3 downto 0)
+ );
end component;
signal base_clk : std_logic;
- signal vga_clk : std_logic;
signal reset_input : std_logic;
signal h_sync_n : std_logic;
signal dbg_cpu_clk : std_logic;
signal dbg_ppu_clk : std_logic;
signal dbg_mem_clk : std_logic;
+ signal dbg_r_nw : std_logic;
signal dbg_addr : std_logic_vector( 16 - 1 downto 0);
signal dbg_d_io : std_logic_vector( 8 - 1 downto 0);
signal dbg_vram_ad : std_logic_vector (7 downto 0);
dbg_cpu_clk,
dbg_ppu_clk,
dbg_mem_clk,
+dbg_r_nw,
dbg_addr,
dbg_d_io,
dbg_vram_ad,
dbg_ppu_ctrl, dbg_ppu_mask, dbg_ppu_status ,
dbg_ppu_addr ,
dbg_ppu_data, dbg_ppu_scrl_x, dbg_ppu_scrl_y,
---dbg_disp_nt, dbg_disp_attr ,
---dbg_disp_ptn_h, dbg_disp_ptn_l ,
-dbg_ppu_addr_we_n,
-dbg_ppu_clk_cnt ,
+dbg_disp_nt, dbg_disp_attr ,
+dbg_disp_ptn_h, dbg_disp_ptn_l ,
+--dbg_ppu_addr_we_n,
+--dbg_ppu_clk_cnt ,
base_clk, reset_input, joypad1, joypad2,
- vga_clk, h_sync_n, v_sync_n, r, g, b);
-
--- dummy_vga_disp : vga_device
--- port map (vga_clk, reset_input, h_sync_n, v_sync_n, r, g, b);
+ h_sync_n, v_sync_n, r, g, b);
--- input reset.
reset_p: process
*.qdf\r
*.jdi\r
*.pin\r
-*.hex\r
db/*\r
incremental_db/*\r
no-need/*\r
output_files/*\r
simulation/*\r
greybox_tmp/*\r
-old/*\r
undo_redo.txt\r
*.work\r
*.nes\r
set_location_assignment PIN_L1 -to base_clk\r
set_location_assignment PIN_R22 -to rst_n\r
set_location_assignment PIN_T18 -to dbg_addr[4]\r
-#set_location_assignment PIN_R20 -to dbg_addr[0]\r
+set_location_assignment PIN_R20 -to dbg_addr[0]\r
set_location_assignment PIN_R19 -to dbg_addr[1]\r
set_location_assignment PIN_U15 -to dbg_addr[2]\r
set_location_assignment PIN_Y19 -to dbg_addr[3]\r
-set_location_assignment PIN_A12 -to base_clk_24mhz\r
+set_location_assignment PIN_D12 -to base_clk_27mhz\r
\r
##DRAM\r
set_location_assignment PIN_W4 -to dram_addr[0]\r
set_location_assignment PIN_M5 -to dram_udqm\r
set_location_assignment PIN_R8 -to dram_we_n\r
\r
-###LED\r
-set_location_assignment PIN_R20 -to red_led\r
-set_location_assignment PIN_U22 -to green_led\r
-\r
-\r
-set_global_assignment -name ENABLE_SIGNALTAP OFF\r
-set_global_assignment -name USE_SIGNALTAP_FILE "sdram-test.stp"\r
-set_global_assignment -name VHDL_FILE vga_clk_gen.vhd\r
-set_global_assignment -name VHDL_FILE sdram_rw.vhd\r
-set_global_assignment -name VHDL_FILE sdram_controller.vhd\r
-set_global_assignment -name QIP_FILE sdram_write_fifo.qip\r
-set_global_assignment -name VHDL_FILE motonesfpga_common.vhd\r
-set_global_assignment -name VHDL_FILE cpu_registers.vhd\r
-set_global_assignment -name VHDL_FILE clock_divider.vhd\r
+set_global_assignment -name VHDL_FILE ../../de1_nes/mem/chr_rom.vhd\r
+set_global_assignment -name VHDL_FILE ../../de1_nes/address_decoder.vhd\r
+set_global_assignment -name VHDL_FILE ../../de1_nes/mem/ram.vhd\r
+set_global_assignment -name VHDL_FILE ../../de1_nes/motonesfpga_common.vhd\r
+set_global_assignment -name VHDL_FILE ../../de1_nes/ppu/ppu_registers.vhd\r
+set_global_assignment -name VHDL_FILE ../../de1_nes/clock/clock_divider.vhd\r
set_global_assignment -name VHDL_FILE vga.vhd\r
+set_global_assignment -name VHDL_FILE render.vhd\r
+set_global_assignment -name VHDL_FILE ppu.vhd\r
set_global_assignment -name VHDL_FILE qt_proj_test5.vhd\r
-set_global_assignment -name SIGNALTAP_FILE "sdram-test.stp"\r
-set_global_assignment -name SLD_FILE "D:/daisuke/nes/repo/motonesfpga/tools/qt_proj_test5/sdram-test_auto_stripped.stp"\r
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
\ No newline at end of file
--- \r
--- MOTO NES FPGA On GHDL Simulation Environment Virtual Cuicuit Board\r
--- All of the components are assembled and instanciated on this board.\r
--- \r
-\r
-library ieee;\r
-use ieee.std_logic_1164.all;\r
-use ieee.std_logic_unsigned.conv_integer;\r
-\r
-entity qt_proj_test5 is \r
- port (\r
-\r
- signal dbg_cpu_clk : out std_logic;\r
- signal dbg_ppu_clk : out std_logic;\r
- signal dbg_mem_clk : out std_logic;\r
- signal dbg_addr : out std_logic_vector( 16 - 1 downto 0);\r
- signal dbg_d_io : out std_logic_vector( 8 - 1 downto 0);\r
-\r
- signal dbg_pos_x : out std_logic_vector (8 downto 0);\r
- signal dbg_pos_y : out std_logic_vector (8 downto 0);\r
- signal dbg_nes_r : out std_logic_vector (3 downto 0);\r
- signal dbg_nes_g : out std_logic_vector (3 downto 0);\r
- signal dbg_nes_b : out std_logic_vector (3 downto 0);\r
-\r
- signal dbg_wbs_adr_i : out std_logic_vector (21 downto 0); --Address (Bank, Row, Col)\r
- signal dbg_wbs_dat_i : out std_logic_vector (15 downto 0); --Data In (16 bits)\r
- signal dbg_wbs_we_i : out std_logic; --Write Enable\r
- signal dbg_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
- signal dbg_wbs_cyc_i : out std_logic; --Cycle Command from interface\r
- signal dbg_wbs_stb_i : out std_logic; --Strobe Command from interface\r
-\r
- signal dbg_vga_x : out std_logic_vector (9 downto 0);\r
- signal dbg_vga_y : out std_logic_vector (9 downto 0);\r
- signal dbg_nes_x : out std_logic_vector(7 downto 0);\r
- signal dbg_nes_x_old : out std_logic_vector(7 downto 0);\r
- signal dbg_sw_state : out std_logic_vector(2 downto 0);\r
-\r
- signal dbg_f_in : out std_logic_vector(11 downto 0);\r
- signal dbg_f_out : out std_logic_vector(11 downto 0);\r
- signal dbg_f_cnt : out std_logic_vector(7 downto 0);\r
- signal dbg_f_rd, dbg_f_wr, dbg_f_emp, dbg_f_ful \r
- : out std_logic;\r
- signal dbg_bst_cnt : out std_logic_vector(7 downto 0);\r
- \r
- signal green_led : out std_logic; --Test passed\r
- signal red_led : out std_logic; --Test fail\r
-\r
- base_clk : in std_logic;\r
- base_clk_27mhz : in std_logic;\r
- rst_n : in std_logic;\r
- h_sync_n : out std_logic;\r
- v_sync_n : out std_logic;\r
- r : out std_logic_vector(3 downto 0);\r
- g : out std_logic_vector(3 downto 0);\r
- b : out std_logic_vector(3 downto 0);\r
-\r
- --SDRAM Signals\r
- dram_addr : out std_logic_vector (11 downto 0); --Address (12 bit)\r
- dram_bank : out std_logic_vector (1 downto 0); --Bank\r
- dram_cas_n : out std_logic; --Column Address is being transmitted\r
- dram_cke : out std_logic; --Clock Enable\r
- dram_clk : out std_logic; --Clock\r
- dram_cs_n : out std_logic; --Chip Select (Here - Mask commands)\r
- dram_dq : inout std_logic_vector (15 downto 0); --Data in / Data out\r
- dram_ldqm : out std_logic; --Byte masking\r
- dram_udqm : out std_logic; --Byte masking\r
- dram_ras_n : out std_logic; --Row Address is being transmitted\r
- dram_we_n : out std_logic --Write Enable\r
-\r
- );\r
-end qt_proj_test5;\r
-\r
-architecture rtl of qt_proj_test5 is\r
-\r
- component clock_divider\r
- port ( base_clk : in std_logic;\r
- reset_n : in std_logic;\r
- cpu_clk : out std_logic;\r
- ppu_clk : out std_logic;\r
- mem_clk : out std_logic;\r
- vga_clk : out std_logic\r
- );\r
- end component;\r
-\r
- component dummy_ppu\r
- port ( ppu_clk : in std_logic;\r
- rst_n : in std_logic;\r
- pos_x : out std_logic_vector (8 downto 0);\r
- pos_y : out std_logic_vector (8 downto 0);\r
- nes_r : out std_logic_vector (3 downto 0);\r
- nes_g : out std_logic_vector (3 downto 0);\r
- nes_b : out std_logic_vector (3 downto 0)\r
- );\r
- end component;\r
-\r
- component vga_clk_gen\r
- PORT\r
- (\r
- inclk0 : IN STD_LOGIC := '0';\r
- c0 : OUT STD_LOGIC ;\r
- locked : OUT STD_LOGIC \r
- );\r
- end component;\r
-\r
-signal pos_x : std_logic_vector (8 downto 0);\r
-signal pos_y : std_logic_vector (8 downto 0);\r
-signal nes_r : std_logic_vector (3 downto 0);\r
-signal nes_g : std_logic_vector (3 downto 0);\r
-signal nes_b : std_logic_vector (3 downto 0);\r
-\r
-component vga_ctl\r
- port ( \r
- signal dbg_vga_x : out std_logic_vector (9 downto 0);\r
- signal dbg_vga_y : out std_logic_vector (9 downto 0);\r
- signal dbg_nes_x : out std_logic_vector(7 downto 0);\r
- signal dbg_nes_x_old : out std_logic_vector(7 downto 0);\r
- signal dbg_sw_state : out std_logic_vector(2 downto 0);\r
- \r
- signal dbg_f_in : out std_logic_vector(11 downto 0);\r
- signal dbg_f_out : out std_logic_vector(11 downto 0);\r
- signal dbg_f_cnt : out std_logic_vector(7 downto 0);\r
- signal dbg_f_rd, dbg_f_wr, dbg_f_emp, dbg_f_ful \r
- : out std_logic;\r
- signal dbg_bst_cnt : out std_logic_vector(7 downto 0);\r
-\r
- ppu_clk : in std_logic;\r
- vga_clk : in std_logic;\r
- mem_clk : in std_logic;\r
- rst_n : in std_logic;\r
- pos_x : in std_logic_vector (8 downto 0);\r
- pos_y : in std_logic_vector (8 downto 0);\r
- nes_r : in std_logic_vector (3 downto 0);\r
- nes_g : in std_logic_vector (3 downto 0);\r
- nes_b : in std_logic_vector (3 downto 0);\r
- h_sync_n : out std_logic;\r
- v_sync_n : out std_logic;\r
- r : out std_logic_vector(3 downto 0);\r
- g : out std_logic_vector(3 downto 0);\r
- b : out std_logic_vector(3 downto 0);\r
- \r
- --SDRAM Signals\r
- wbs_adr_i : out std_logic_vector (21 downto 0); --Address (Bank, Row, Col)\r
- wbs_dat_i : out std_logic_vector (15 downto 0); --Data In (16 bits)\r
- wbs_we_i : out std_logic; --Write Enable\r
- 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
- wbs_cyc_i : out std_logic; --Cycle Command from interface\r
- wbs_stb_i : out std_logic; --Strobe Command from interface\r
- wbs_dat_o : in std_logic_vector (15 downto 0); --Data Out (16 bits)\r
- wbs_stall_o : in std_logic; --Slave is not ready to receive new data\r
- wbs_err_o : in std_logic; --Error flag: OOR Burst. Burst length is greater that 256-column address\r
- wbs_ack_o : in std_logic --When Read Burst: DATA bus must be valid in this cycle\r
- );\r
-end component;\r
-\r
-component sdram_controller\r
- generic\r
- (\r
- reset_polarity_g : std_logic := '0' --When rst = reset_polarity_g, system is in RESET mode\r
- );\r
- port (\r
- --Clocks and Reset \r
- clk_i : in std_logic; --Wishbone input clock\r
- rst : in std_logic; --Reset\r
- pll_locked : in std_logic; --PLL Locked indication, for CKE (Clock Enable) signal to SDRAM\r
- \r
- --SDRAM Signals\r
- dram_addr : out std_logic_vector (11 downto 0); --Address (12 bit)\r
- dram_bank : out std_logic_vector (1 downto 0); --Bank\r
- dram_cas_n : out std_logic; --Column Address is being transmitted\r
- dram_cke : out std_logic; --Clock Enable\r
- dram_cs_n : out std_logic; --Chip Select (Here - Mask commands)\r
- dram_dq : inout std_logic_vector (15 downto 0); --Data in / Data out\r
- dram_ldqm : out std_logic; --Byte masking\r
- dram_udqm : out std_logic; --Byte masking\r
- dram_ras_n : out std_logic; --Row Address is being transmitted\r
- dram_we_n : out std_logic; --Write Enable\r
- \r
- -- Wishbone Slave signals to Read/Write interface\r
- wbs_adr_i : in std_logic_vector (21 downto 0); --Address (Bank, Row, Col)\r
- wbs_dat_i : in std_logic_vector (15 downto 0); --Data In (16 bits)\r
- wbs_we_i : in std_logic; --Write Enable\r
- wbs_tga_i : in std_logic_vector (7 downto 0); --Address Tag : Read/write burst length-1 (0 represents 1 word, FF represents 256 words)\r
- wbs_cyc_i : in std_logic; --Cycle Command from interface\r
- wbs_stb_i : in std_logic; --Strobe Command from interface\r
- wbs_dat_o : out std_logic_vector (15 downto 0); --Data Out (16 bits)\r
- wbs_stall_o : out std_logic; --Slave is not ready to receive new data\r
- wbs_err_o : out std_logic; --Error flag: OOR Burst. Burst length is greater that 256-column address\r
- wbs_ack_o : out std_logic; --When Read Burst: DATA bus must be valid in this cycle\r
- --When Write Burst: Data has been read from SDRAM and is valid\r
-\r
- --Debug signals\r
- cmd_ack : out std_logic; --Command has been acknowledged\r
- cmd_done : out std_logic; --Command has finished (read/write)\r
- init_st_o : out std_logic_vector (3 downto 0); --Current init state\r
- main_st_o : out std_logic_vector (3 downto 0) --Current main state\r
- ); \r
-end component;\r
-\r
-\r
- constant data_size : integer := 8;\r
- constant addr_size : integer := 16;\r
- constant size14 : integer := 14;\r
-\r
- signal cpu_clk : std_logic;\r
- signal ppu_clk : std_logic;\r
- signal mem_clk : std_logic;\r
- signal vga_clk : std_logic;\r
- signal vga_clk_pll, sdram_clk : std_logic;\r
- signal pll_locked : std_logic;\r
-\r
- -- Wishbone Slave signals to Read/Write interface\r
- signal wbs_adr_i : std_logic_vector (21 downto 0); --Address (Bank, Row, Col)\r
- signal wbs_dat_i : std_logic_vector (15 downto 0); --Data In (16 bits)\r
- signal wbs_we_i : std_logic; --Write Enable\r
- signal wbs_tga_i : std_logic_vector (7 downto 0); --Address Tag : Read/write burst length-1 (0 represents 1 word, FF represents 256 words)\r
- signal wbs_cyc_i : std_logic; --Cycle Command from interface\r
- signal wbs_stb_i : std_logic; --Strobe Command from interface\r
- signal wbs_dat_o : std_logic_vector (15 downto 0); --Data Out (16 bits)\r
- signal wbs_stall_o : std_logic; --Slave is not ready to receive new data\r
- signal wbs_err_o : std_logic; --Error flag: OOR Burst. Burst length is greater that 256-column address\r
- signal wbs_ack_o : std_logic; --When Read Burst: DATA bus must be valid in this cycle\r
- --When Write Burst: Data has been read from SDRAM and is valid\r
-\r
- --Debug signals\r
- signal cmd_ack : std_logic; --Command has been acknowledged\r
- signal cmd_done : std_logic; --Command has finished (read/write)\r
- signal init_st_o : std_logic_vector (3 downto 0); --Current init state\r
- signal main_st_o : std_logic_vector (3 downto 0); --Current main state\r
-\r
- signal writing : std_logic; --'1' when writing, '0' when reading\r
- signal mem_val_o : std_logic_vector (15 downto 0); --Memory value written / compared to SDRAM\r
- signal sdram_val_o : std_logic_vector (15 downto 0); --Read value from SDRAM\r
- signal cur_st_o : std_logic_vector (3 downto 0); --Current state\r
- \r
-begin\r
-\r
-\r
- dbg_mem_clk <= mem_clk ;\r
- dbg_cpu_clk <= cpu_clk;\r
- dbg_ppu_clk <= ppu_clk;\r
-\r
- dbg_pos_x <= pos_x ;\r
- dbg_pos_y <= pos_y ;\r
- dbg_nes_r <= nes_r ;\r
- dbg_nes_g <= nes_g ;\r
- dbg_nes_b <= nes_b ;\r
-\r
- dbg_wbs_adr_i <= wbs_adr_i ;\r
- dbg_wbs_dat_i <= wbs_dat_i ;\r
- dbg_wbs_we_i <= wbs_we_i ;\r
- dbg_wbs_tga_i <= wbs_tga_i ;\r
- dbg_wbs_cyc_i <= wbs_cyc_i ;\r
- dbg_wbs_stb_i <= wbs_stb_i ;\r
-\r
-\r
-\r
- --ppu/cpu clock generator\r
- clock_inst : clock_divider port map \r
- (base_clk, rst_n, cpu_clk, ppu_clk, mem_clk, vga_clk);\r
-\r
- ppu_inst: dummy_ppu \r
- port map ( ppu_clk ,\r
- rst_n ,\r
- pos_x ,\r
- pos_y ,\r
- nes_r ,\r
- nes_g ,\r
- nes_b \r
- );\r
-\r
--- vga_clk_gen_inst : vga_clk_gen\r
--- PORT map\r
--- (\r
--- --mem_clk_pll = 133.333 MHz.\r
--- base_clk, vga_clk_pll, sdram_clk, pll_locked\r
--- );\r
- --- testbench pll clock..\r
--- dummy_clock_p: process\r
--- begin\r
--- sdram_clk <= '1';\r
--- wait for 6250 ps / 2;\r
--- sdram_clk <= '0';\r
--- wait for 6250 ps / 2;\r
--- end process;\r
-\r
- \r
- vga_ctl_inst : vga_ctl\r
- port map ( \r
- dbg_vga_x ,\r
- dbg_vga_y ,\r
- dbg_nes_x ,\r
- dbg_nes_x_old ,\r
- dbg_sw_state ,\r
- \r
- dbg_f_in ,\r
- dbg_f_out ,\r
- dbg_f_cnt ,\r
- dbg_f_rd, dbg_f_wr, dbg_f_emp, dbg_f_ful ,\r
- dbg_bst_cnt ,\r
-\r
- ppu_clk ,\r
- --vga_clk_pll, \r
- --ppu_clk ,\r
- vga_clk ,\r
- mem_clk ,\r
- rst_n ,\r
- pos_x ,\r
- pos_y ,\r
- nes_r ,\r
- nes_g ,\r
- nes_b ,\r
- h_sync_n ,\r
- v_sync_n ,\r
- r ,\r
- g ,\r
- b ,\r
- \r
- --SDRAM Signals\r
- wbs_adr_i ,\r
- wbs_dat_i ,\r
- wbs_we_i ,\r
- wbs_tga_i ,\r
- wbs_cyc_i ,\r
- wbs_stb_i ,\r
- wbs_dat_o ,\r
- wbs_stall_o ,\r
- wbs_err_o ,\r
- wbs_ack_o \r
- );\r
-\r
- dram_clk <= not mem_clk;\r
- sdram_clk <= not mem_clk;\r
-sdram_ctl_inst : sdram_controller\r
- port map (\r
- --Clocks and Reset \r
- sdram_clk, \r
- rst_n, \r
- '0',\r
- \r
- --SDRAM Signals\r
- dram_addr ,\r
- dram_bank ,\r
- dram_cas_n ,\r
- dram_cke ,\r
- dram_cs_n ,\r
- dram_dq ,\r
- dram_ldqm ,\r
- dram_udqm ,\r
- dram_ras_n ,\r
- dram_we_n ,\r
- \r
- -- Wishbone Slave signals to Read/Write interface\r
- wbs_adr_i ,\r
- wbs_dat_i ,\r
- wbs_we_i ,\r
- wbs_tga_i ,\r
- wbs_cyc_i ,\r
- wbs_stb_i ,\r
- wbs_dat_o ,\r
- wbs_stall_o ,\r
- wbs_err_o ,\r
- wbs_ack_o ,\r
-\r
- --Debug signals\r
- cmd_ack ,\r
- cmd_done ,\r
- init_st_o ,\r
- main_st_o \r
- ); \r
- \r
-end rtl;\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
----------------------------------------------------------------\r
----------------------------------------------------------------\r
----------------------------------------------------------------\r
-------------- SDRAM TEST IMAGE ---------------\r
----------------------------------------------------------------\r
----------------------------------------------------------------\r
----------------------------------------------------------------\r
-\r
-\r
-library ieee;\r
-use ieee.std_logic_1164.all;\r
-use ieee.std_logic_unsigned.conv_integer;\r
-\r
-entity sdram_test is \r
- port (\r
-\r
- signal dbg_cpu_clk : out std_logic;\r
- signal dbg_ppu_clk : out std_logic;\r
- signal dbg_mem_clk : out std_logic;\r
- signal dbg_addr : out std_logic_vector( 16 - 1 downto 0);\r
- signal dbg_d_io : out std_logic_vector( 8 - 1 downto 0);\r
-\r
- signal dbg_pos_x : out std_logic_vector (8 downto 0);\r
- signal dbg_pos_y : out std_logic_vector (8 downto 0);\r
- signal dbg_nes_r : out std_logic_vector (3 downto 0);\r
- signal dbg_nes_g : out std_logic_vector (3 downto 0);\r
- signal dbg_nes_b : out std_logic_vector (3 downto 0);\r
-\r
- signal dbg_wbs_adr_i : out std_logic_vector (21 downto 0); --Address (Bank, Row, Col)\r
- signal dbg_wbs_dat_i : out std_logic_vector (15 downto 0); --Data In (16 bits)\r
- signal dbg_wbs_we_i : out std_logic; --Write Enable\r
- signal dbg_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
- signal dbg_wbs_cyc_i : out std_logic; --Cycle Command from interface\r
- signal dbg_wbs_stb_i : out std_logic; --Strobe Command from interface\r
-\r
- signal dbg_vga_x : out std_logic_vector (9 downto 0);\r
- signal dbg_vga_y : out std_logic_vector (9 downto 0);\r
- signal dbg_nes_x : out std_logic_vector(7 downto 0);\r
- signal dbg_nes_x_old : out std_logic_vector(7 downto 0);\r
- signal dbg_sw_state : out std_logic_vector(2 downto 0);\r
-\r
- signal dbg_f_in : out std_logic_vector(11 downto 0);\r
- signal dbg_f_out : out std_logic_vector(11 downto 0);\r
- signal dbg_f_cnt : out std_logic_vector(7 downto 0);\r
- signal dbg_f_rd, dbg_f_wr, dbg_f_emp, dbg_f_ful \r
- : out std_logic;\r
- signal dbg_bst_cnt : out std_logic_vector(7 downto 0);\r
- \r
- signal green_led : out std_logic; --Test passed\r
- signal red_led : out std_logic; --Test fail\r
-\r
- base_clk : in std_logic;\r
- base_clk_24mhz : in std_logic;\r
- rst_n : in std_logic;\r
- h_sync_n : out std_logic;\r
- v_sync_n : out std_logic;\r
- r : out std_logic_vector(3 downto 0);\r
- g : out std_logic_vector(3 downto 0);\r
- b : out std_logic_vector(3 downto 0);\r
-\r
- --SDRAM Signals\r
- dram_addr : out std_logic_vector (11 downto 0); --Address (12 bit)\r
- dram_bank : out std_logic_vector (1 downto 0); --Bank\r
- dram_cas_n : out std_logic; --Column Address is being transmitted\r
- dram_cke : out std_logic; --Clock Enable\r
- dram_clk : out std_logic; --Clock\r
- dram_cs_n : out std_logic; --Chip Select (Here - Mask commands)\r
- dram_dq : inout std_logic_vector (15 downto 0); --Data in / Data out\r
- dram_ldqm : out std_logic; --Byte masking\r
- dram_udqm : out std_logic; --Byte masking\r
- dram_ras_n : out std_logic; --Row Address is being transmitted\r
- dram_we_n : out std_logic --Write Enable\r
-\r
- );\r
-end sdram_test;\r
-\r
-architecture rtl of sdram_test is\r
-\r
-component sdram_controller \r
- generic\r
- (\r
- reset_polarity_g : std_logic := '0' --When rst = reset_polarity_g, system is in RESET mode\r
- );\r
- port (\r
- --Clocks and Reset \r
- clk_i : in std_logic; --Wishbone input clock\r
- rst : in std_logic; --Reset\r
- pll_locked : in std_logic; --PLL Locked indication, for CKE (Clock Enable) signal to SDRAM\r
- \r
- --SDRAM Signals\r
- dram_addr : out std_logic_vector (11 downto 0); --Address (12 bit)\r
- dram_bank : out std_logic_vector (1 downto 0); --Bank\r
- dram_cas_n : out std_logic; --Column Address is being transmitted\r
- dram_cke : out std_logic; --Clock Enable\r
- dram_cs_n : out std_logic; --Chip Select (Here - Mask commands)\r
- dram_dq : inout std_logic_vector (15 downto 0); --Data in / Data out\r
- dram_ldqm : out std_logic; --Byte masking\r
- dram_udqm : out std_logic; --Byte masking\r
- dram_ras_n : out std_logic; --Row Address is being transmitted\r
- dram_we_n : out std_logic; --Write Enable\r
- \r
- -- Wishbone Slave signals to Read/Write interface\r
- wbs_adr_i : in std_logic_vector (21 downto 0); --Address (Bank, Row, Col)\r
- wbs_dat_i : in std_logic_vector (15 downto 0); --Data In (16 bits)\r
- wbs_we_i : in std_logic; --Write Enable\r
- wbs_tga_i : in std_logic_vector (7 downto 0); --Address Tag : Read/write burst length-1 (0 represents 1 word, FF represents 256 words)\r
- wbs_cyc_i : in std_logic; --Cycle Command from interface\r
- wbs_stb_i : in std_logic; --Strobe Command from interface\r
- wbs_dat_o : out std_logic_vector (15 downto 0); --Data Out (16 bits)\r
- wbs_stall_o : out std_logic; --Slave is not ready to receive new data\r
- wbs_err_o : out std_logic; --Error flag: OOR Burst. Burst length is greater that 256-column address\r
- wbs_ack_o : out std_logic; --When Read Burst: DATA bus must be valid in this cycle\r
- --When Write Burst: Data has been read from SDRAM and is valid\r
-\r
- --Debug signals\r
- cmd_ack : out std_logic; --Command has been acknowledged\r
- cmd_done : out std_logic; --Command has finished (read/write)\r
- init_st_o : out std_logic_vector (3 downto 0); --Current init state\r
- main_st_o : out std_logic_vector (3 downto 0) --Current main state\r
- );\r
-end component;\r
-\r
-component sdram_rw \r
- generic(\r
- reset_polarity : std_logic := '0' --When rst = reset_polarity, system at RESET\r
- );\r
- port(\r
- --Clock and Reset\r
- clk_i : in std_logic; --WISHBONE Clock\r
- rst : in std_logic; --RESET\r
- \r
- --Signals to SDRAM controller\r
- wbm_adr_o : out std_logic_vector (21 downto 0); --Address to read from / write to\r
- wbm_dat_i : in std_logic_vector (15 downto 0); --Data out (to SDRAM)\r
- wbm_dat_o : out std_logic_vector (15 downto 0); --Data in (from SDRAM)\r
- wbm_we_i : out std_logic; --'1' - Write, '0' - Read\r
- wbm_tga_o : out std_logic_vector (7 downto 0); --Read/write burst length-1 (0 represents 1 word, FF represents 256 words)\r
- wbm_cyc_o : out std_logic; --Transmit command to SDRAM controller\r
- wbm_stb_o : out std_logic; --Transmit command to SDRAM controller\r
- wbm_stall_i : in std_logic; --When '1', write data to SDRAM\r
- wbm_ack_i : in std_logic; --when '1', data is ready to be read from SDRAM\r
- \r
- --Debug and test signals\r
- cmd_ack : in std_logic; --Command has been acknowledged by SDRAM controller\r
- cmd_done : in std_logic; --Command has finished (read/write)\r
- green_led : out std_logic; --Test passed\r
- red_led : out std_logic; --Test fail\r
- writing : out std_logic; --'1' when writing, '0' when reading\r
- mem_val_o : out std_logic_vector (15 downto 0); --Memory value written / compared to SDRAM\r
- sdram_val_o : out std_logic_vector (15 downto 0); --Read value from SDRAM\r
- cur_st_o : out std_logic_vector (3 downto 0) --Current state\r
- );\r
-end component;\r
-\r
-component vga_clk_gen\r
- PORT\r
- (\r
- inclk0 : IN STD_LOGIC := '0';\r
- c0 : OUT STD_LOGIC ;\r
- locked : OUT STD_LOGIC \r
- );\r
-end component;\r
-\r
---Clock and Reset\r
-signal clk_133 : std_logic := '0'; --133 MHz\r
-signal rst : std_logic := '0'; --Reset\r
-\r
---Read / Write signals to SDRAM\r
-signal addr : std_logic_vector (21 downto 0);\r
-signal dat_tb2ram : std_logic_vector (15 downto 0);\r
-signal dat_ram2tb : std_logic_vector (15 downto 0);\r
-signal we_i : std_logic;\r
-signal stall_i : std_logic;\r
-signal cyc_o : std_logic;\r
-signal err_o : std_logic;\r
-signal ack_i : std_logic;\r
-signal stb_o : std_logic;\r
-signal burst_len : std_logic_vector (7 downto 0);\r
-signal cmd_ack : std_logic;\r
-signal cmd_done : std_logic;\r
-\r
---LEDs\r
-signal writing : std_logic;\r
-\r
---States\r
-signal init_st_o : std_logic_vector (3 downto 0);\r
-signal main_st_o : std_logic_vector (3 downto 0);\r
-\r
---Debug\r
-signal cur_st_o : std_logic_vector (3 downto 0);\r
-\r
-signal sdram_clk, pll_locked : std_logic;\r
-\r
-begin\r
- --Clock process\r
- vga_clk_gen_inst : vga_clk_gen\r
- PORT map\r
- (\r
- --sdram_clk = 133.3333 MHz.\r
- base_clk, sdram_clk, pll_locked\r
- );\r
- clk_proc:\r
- clk_133 <= sdram_clk;\r
- dram_clk <= sdram_clk;\r
- dbg_mem_clk <= sdram_clk;\r
- \r
- rst_proc:\r
- rst <= rst_n;\r
- \r
- --Componenets:\r
- sdr_ctrl : sdram_controller generic map (\r
- reset_polarity_g => '0'\r
- )\r
- port map(\r
- clk_i => clk_133,\r
- rst => rst,\r
- pll_locked => pll_locked,\r
- \r
- dram_addr => dram_addr, \r
- dram_bank => dram_bank, \r
- dram_cas_n => dram_cas_n, \r
- dram_cke => dram_cke, \r
- dram_cs_n => dram_cs_n, \r
- dram_dq => dram_dq, \r
- dram_ldqm => dram_ldqm, \r
- dram_udqm => dram_udqm, \r
- dram_ras_n => dram_ras_n, \r
- dram_we_n => dram_we_n, \r
- \r
- wbs_adr_i => addr, \r
- wbs_dat_i => dat_tb2ram, \r
- wbs_we_i => we_i, \r
- wbs_tga_i => burst_len, \r
- wbs_cyc_i => cyc_o,\r
- wbs_stb_i => stb_o, \r
- wbs_dat_o => dat_ram2tb,\r
- wbs_stall_o => stall_i,\r
- wbs_err_o => err_o,\r
- wbs_ack_o => ack_i,\r
- \r
- cmd_ack => cmd_ack,\r
- cmd_done => cmd_done,\r
- init_st_o => init_st_o,\r
- main_st_o => main_st_o\r
- );\r
- \r
- sdr_rw : sdram_rw port map (\r
- clk_i => clk_133,\r
- rst => rst,\r
- \r
- wbm_adr_o => addr,\r
- wbm_dat_i => dat_ram2tb,\r
- wbm_dat_o => dat_tb2ram,\r
- wbm_we_i => we_i,\r
- wbm_tga_o => burst_len,\r
- wbm_cyc_o => cyc_o,\r
- wbm_stb_o => stb_o,\r
- wbm_stall_i => stall_i,\r
- wbm_ack_i => ack_i,\r
-\r
- cmd_ack => cmd_ack,\r
- cmd_done => cmd_done,\r
- green_led => green_led,\r
- red_led => red_led,\r
- writing => writing\r
- );\r
- \r
-end architecture rtl;\r
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_unsigned.conv_integer;
+
+--
+-- MOTO NES FPGA On GHDL Simulation Environment Virtual Cuicuit Board
+-- All of the components are assembled and instanciated on this board.
+--
+
+entity qt_proj_test5 is
+ port (
+
+ signal dbg_cpu_clk : out std_logic;
+ signal dbg_ppu_clk : out std_logic;
+ signal dbg_vga_clk : out std_logic;
+ signal dbg_addr : out std_logic_vector( 16 - 1 downto 0);
+ signal dbg_d_io : out std_logic_vector( 8 - 1 downto 0);
+
+ signal dbg_ppu_ce_n : out std_logic;
+ signal dbg_ppu_ctrl, dbg_ppu_mask, dbg_ppu_status : out std_logic_vector (7 downto 0);
+ signal dbg_ppu_addr : out std_logic_vector (13 downto 0);
+ signal dbg_ppu_data, dbg_ppu_scrl_x, dbg_ppu_scrl_y : out std_logic_vector (7 downto 0);
+ signal dbg_disp_nt, dbg_disp_attr : out std_logic_vector (7 downto 0);
+ signal dbg_disp_ptn_h, dbg_disp_ptn_l : out std_logic_vector (15 downto 0);
+
+ signal dbg_ppu_addr_we_n : out std_logic;
+ signal dbg_ppu_clk_cnt : out std_logic_vector(1 downto 0);
+
+
+
+ base_clk : in std_logic;
+ base_clk_27mhz : in std_logic;
+ rst_n : in std_logic;
+ h_sync_n : out std_logic;
+ v_sync_n : out std_logic;
+ r : out std_logic_vector(3 downto 0);
+ g : out std_logic_vector(3 downto 0);
+ b : out std_logic_vector(3 downto 0)
+
+ );
+end qt_proj_test5;
+
+architecture rtl of qt_proj_test5 is
+
+ component clock_divider
+ port ( base_clk : in std_logic;
+ reset_n : in std_logic;
+ cpu_clk : out std_logic;
+ ppu_clk : out std_logic;
+ mem_clk : out std_logic;
+ vga_clk : out std_logic
+ );
+ end component;
+
+ component ram
+ generic (abus_size : integer := 16; dbus_size : integer := 8);
+ port (
+ clk : in std_logic;
+ ce_n, oe_n, we_n : in std_logic; --select pin active low.
+ addr : in std_logic_vector (abus_size - 1 downto 0);
+ d_io : inout std_logic_vector (dbus_size - 1 downto 0)
+ );
+ end component;
+
+ component ppu port (
+ signal dbg_ppu_ce_n : out std_logic;
+ signal dbg_ppu_ctrl, dbg_ppu_mask, dbg_ppu_status : out std_logic_vector (7 downto 0);
+ signal dbg_ppu_addr : out std_logic_vector (13 downto 0);
+ signal dbg_ppu_data, dbg_ppu_scrl_x, dbg_ppu_scrl_y : out std_logic_vector (7 downto 0);
+
+ signal dbg_ppu_clk : out std_logic;
+ signal dbg_vga_clk : out std_logic;
+ signal dbg_nes_x : out std_logic_vector (8 downto 0);
+ signal dbg_vga_x : out std_logic_vector (9 downto 0);
+ signal dbg_disp_nt, dbg_disp_attr : out std_logic_vector (7 downto 0);
+ signal dbg_disp_ptn_h, dbg_disp_ptn_l : out std_logic_vector (15 downto 0);
+ signal dbg_plt_addr : out std_logic_vector (4 downto 0);
+ signal dbg_plt_data : out std_logic_vector (7 downto 0);
+ signal dbg_p_oam_ce_rn_wn : out std_logic_vector (2 downto 0);
+ signal dbg_p_oam_addr : out std_logic_vector (7 downto 0);
+ signal dbg_p_oam_data : out std_logic_vector (7 downto 0);
+ signal dbg_s_oam_ce_rn_wn : out std_logic_vector (2 downto 0);
+ signal dbg_s_oam_addr : out std_logic_vector (4 downto 0);
+ signal dbg_s_oam_data : out std_logic_vector (7 downto 0);
+
+ signal dbg_ppu_addr_we_n : out std_logic;
+ signal dbg_ppu_clk_cnt : out std_logic_vector(1 downto 0);
+
+ ppu_clk : in std_logic;
+ mem_clk : in std_logic;
+ ce_n : in std_logic;
+ rst_n : in std_logic;
+ r_nw : in std_logic;
+ cpu_addr : in std_logic_vector (2 downto 0);
+ cpu_d : inout std_logic_vector (7 downto 0);
+
+ vblank_n : out std_logic;
+ rd_n : out std_logic;
+ wr_n : out std_logic;
+ ale : out std_logic;
+ vram_ad : inout std_logic_vector (7 downto 0);
+ vram_a : out std_logic_vector (13 downto 8);
+
+ vga_clk : in std_logic;
+ h_sync_n : out std_logic;
+ v_sync_n : out std_logic;
+ r : out std_logic_vector(3 downto 0);
+ g : out std_logic_vector(3 downto 0);
+ b : out std_logic_vector(3 downto 0)
+ );
+ end component;
+
+ component v_address_decoder
+ generic (abus_size : integer := 14; dbus_size : integer := 8);
+ port ( clk : in std_logic;
+ mem_clk : in std_logic;
+ rd_n : in std_logic;
+ wr_n : in std_logic;
+ ale : in std_logic;
+ v_addr : in std_logic_vector (13 downto 0);
+ v_data : in std_logic_vector (7 downto 0);
+ nt_v_mirror : in std_logic;
+ pt_ce_n : out std_logic;
+ nt0_ce_n : out std_logic;
+ nt1_ce_n : out std_logic
+ );
+ end component;
+
+ component chr_rom
+ generic (abus_size : integer := 13; dbus_size : integer := 8);
+ port (
+ clk : in std_logic;
+ ce_n : in std_logic; --active low.
+ addr : in std_logic_vector (abus_size - 1 downto 0);
+ data : out std_logic_vector (dbus_size - 1 downto 0);
+ nt_v_mirror : out std_logic
+ );
+ end component;
+
+ component ls373
+ generic (
+ dsize : integer := 8
+ );
+ port ( c : in std_logic;
+ we_n : in std_logic;
+ oc_n : in std_logic;
+ d : in std_logic_vector(dsize - 1 downto 0);
+ q : out std_logic_vector(dsize - 1 downto 0)
+ );
+ end component;
+
+
+
+ constant data_size : integer := 8;
+ constant addr_size : integer := 16;
+ constant vram_size14 : integer := 14;
+
+ constant ram_2k : integer := 11; --2k = 11 bit width.
+ constant rom_32k : integer := 15; --32k = 15 bit width.
+ constant rom_4k : integer := 12; --4k = 12 bit width. (for test use)
+ constant vram_1k : integer := 10; --1k = 10 bit width.
+ constant chr_rom_8k : integer := 13; --32k = 15 bit width.
+
+ signal cpu_clk : std_logic;
+ signal ppu_clk : std_logic;
+ signal mem_clk : std_logic;
+ signal vga_clk : std_logic;
+
+ signal ppu_ce_n : std_logic;
+ signal r_nw : std_logic;
+ signal addr : std_logic_vector (2 downto 0);
+ signal d_io : std_logic_vector (7 downto 0);
+ signal vblank_n : std_logic;
+ signal rd_n : std_logic;
+ signal wr_n : std_logic;
+ signal ale : std_logic;
+ signal vram_ad : std_logic_vector (7 downto 0);
+ signal vram_a : std_logic_vector (13 downto 8);
+ signal v_addr : std_logic_vector (13 downto 0);
+ signal nt_v_mirror : std_logic;
+ signal pt_ce_n : std_logic;
+ signal nt0_ce_n : std_logic;
+ signal nt1_ce_n : std_logic;
+
+ signal ale_n : std_logic;
+ signal vga_clk_n : std_logic;
+
+ signal dbg_ppu_addr_dummy : std_logic_vector (13 downto 0);
+ signal dbg_nes_x : std_logic_vector (8 downto 0);
+ signal dbg_vga_x : std_logic_vector (9 downto 0);
+ signal dbg_plt_addr : std_logic_vector (4 downto 0);
+ signal dbg_plt_data : std_logic_vector (7 downto 0);
+ signal dbg_p_oam_ce_rn_wn : std_logic_vector (2 downto 0);
+ signal dbg_p_oam_addr : std_logic_vector (7 downto 0);
+ signal dbg_p_oam_data : std_logic_vector (7 downto 0);
+ signal dbg_s_oam_ce_rn_wn : std_logic_vector (2 downto 0);
+ signal dbg_s_oam_addr : std_logic_vector (4 downto 0);
+ signal dbg_s_oam_data : std_logic_vector (7 downto 0);
+ signal dbg_ppu_data_dummy : std_logic_vector (7 downto 0);
+ signal dbg_ppu_status_dummy : std_logic_vector (7 downto 0);
+ signal dbg_ppu_scrl_x_dummy : std_logic_vector (7 downto 0);
+ signal dbg_ppu_scrl_y_dummy : std_logic_vector (7 downto 0);
+ signal dbg_disp_ptn_h_dummy, dbg_disp_ptn_l_dummy : std_logic_vector (15 downto 0);
+
+
+
+begin
+ --ppu/cpu clock generator
+ clock_inst : clock_divider port map
+ (base_clk, rst_n, cpu_clk, ppu_clk, mem_clk, vga_clk);
+
+ dbg_cpu_clk <= cpu_clk;
+ --dbg_ppu_addr <= "00000" & dbg_nes_x;
+ dbg_d_io <= "000" & dbg_plt_addr;
+ --dbg_ppu_data <= dbg_plt_data;
+ dbg_addr <= "00" & v_addr;
+ dbg_ppu_status <= vram_ad;
+ dbg_ppu_scrl_x(0) <= ale;
+ dbg_ppu_scrl_x(1) <= rd_n;
+ dbg_ppu_scrl_x(2) <= wr_n;
+ dbg_ppu_scrl_x(3) <= nt0_ce_n;
+ dbg_ppu_scrl_x(4) <= vga_clk_n;
+ dbg_ppu_scrl_y(2 downto 0) <= dbg_p_oam_ce_rn_wn(2 downto 0);
+ dbg_disp_ptn_l (7 downto 0) <= dbg_p_oam_addr;
+ dbg_disp_ptn_l (15 downto 8) <= dbg_p_oam_data;
+
+ ppu_inst: ppu port map (
+ dbg_ppu_ce_n ,
+ dbg_ppu_ctrl, dbg_ppu_mask, dbg_ppu_status_dummy ,
+ dbg_ppu_addr ,
+ dbg_ppu_data, dbg_ppu_scrl_x_dummy, dbg_ppu_scrl_y_dummy ,
+
+ dbg_ppu_clk ,
+ dbg_vga_clk ,
+ dbg_nes_x ,
+ dbg_vga_x ,
+ dbg_disp_nt, dbg_disp_attr ,
+ dbg_disp_ptn_h, dbg_disp_ptn_l_dummy ,
+ dbg_plt_addr ,
+ dbg_plt_data ,
+ dbg_p_oam_ce_rn_wn ,
+ dbg_p_oam_addr ,
+ dbg_p_oam_data ,
+ dbg_s_oam_ce_rn_wn ,
+ dbg_s_oam_addr ,
+ dbg_s_oam_data ,
+ dbg_ppu_addr_we_n ,
+ dbg_ppu_clk_cnt ,
+
+ ppu_clk ,
+ mem_clk ,
+ ppu_ce_n ,
+ rst_n ,
+ r_nw ,
+ addr ,
+ d_io ,
+
+ vblank_n ,
+ rd_n ,
+ wr_n ,
+ ale ,
+ vram_ad ,
+ vram_a ,
+
+ vga_clk ,
+ h_sync_n ,
+ v_sync_n ,
+ r ,
+ g ,
+ b
+
+ );
+
+ ppu_addr_decoder : v_address_decoder generic map (vram_size14, data_size)
+ port map (ppu_clk, mem_clk, rd_n, wr_n, ale, v_addr, vram_ad,
+ nt_v_mirror, pt_ce_n, nt0_ce_n, nt1_ce_n);
+
+ ---VRAM/CHR ROM instances
+ v_addr (13 downto 8) <= vram_a;
+
+ --transparent d-latch
+ ale_n <= not ale;
+ vga_clk_n <= not vga_clk;
+ vram_latch : ls373 generic map (data_size)
+ port map(vga_clk, ale_n, ale, vram_ad, v_addr(7 downto 0));
+
+ vchr_rom : chr_rom generic map (chr_rom_8k, data_size)
+ port map (mem_clk, pt_ce_n, v_addr(chr_rom_8k - 1 downto 0), vram_ad, nt_v_mirror);
+
+ --name table/attr table
+ vram_nt0 : ram generic map (vram_1k, data_size)
+ port map (mem_clk, nt0_ce_n, rd_n, wr_n, v_addr(vram_1k - 1 downto 0), vram_ad);
+
+ vram_nt1 : ram generic map (vram_1k, data_size)
+ port map (mem_clk, nt1_ce_n, rd_n, wr_n, v_addr(vram_1k - 1 downto 0), vram_ad);
+
+ --set initial vram value...
+ vram_p : process (cpu_clk, rst_n)
+use ieee.std_logic_arith.conv_std_logic_vector;
+ variable init_step_cnt, plt_step_cnt,
+ nt_step_cnt, spr_step_cnt, enable_ppu_step_cnt : integer;
+ variable init_done : std_logic;
+ variable global_step_cnt : integer;
+ variable cpu_cnt : integer;
+
+procedure ppu_set (ad: in integer; dt : in integer) is
+begin
+ r_nw <= '0';
+ ppu_ce_n <= '0';
+ addr(2 downto 0) <= conv_std_logic_vector(ad, 16)(2 downto 0);
+ d_io <= conv_std_logic_vector(dt, 8);
+end;
+procedure ppu_clr is
+begin
+ addr <= (others => 'Z');
+ d_io <= (others => 'Z');
+ r_nw <= '1';
+ ppu_ce_n <= '1';
+end;
+
+ begin
+ if (rst_n = '0') then
+
+ r_nw <= 'Z';
+ ppu_ce_n <= 'Z';
+ addr <= (others => 'Z');
+ d_io <= (others => 'Z');
+
+ init_done := '0';
+ global_step_cnt := 0;
+ init_step_cnt := 0;
+ plt_step_cnt := 0;
+ nt_step_cnt := 0;
+ spr_step_cnt := 0;
+ enable_ppu_step_cnt := 0;
+ cpu_cnt := 0;
+
+ elsif (rising_edge(cpu_clk)) then
+ cpu_cnt := cpu_cnt + 1;
+
+ if (init_done = '0') then
+ if (global_step_cnt = 0) then
+ --step0.0 = init ppu.
+ if (init_step_cnt = 0) then
+ --PPUCTRL=00
+ ppu_set(16#2000#, 16#00#);
+ elsif (init_step_cnt = 2) then
+ --PPUMASK=00
+ ppu_set(16#2001#, 16#00#);
+ else
+ ppu_clr;
+ if (init_step_cnt > 3) then
+ global_step_cnt := global_step_cnt + 1;
+ end if;
+ end if;
+ if (cpu_cnt mod 18 <= 1) then
+ init_step_cnt := init_step_cnt + 1;
+ end if;
+
+ elsif (global_step_cnt = 1) then
+ --step0.1 = palette set.
+--palettes:
+--;;;bg palette
+-- .byte $0f, $00, $10, $20
+-- .byte $0f, $04, $14, $24
+-- .byte $0f, $08, $18, $28
+-- .byte $0f, $0c, $1c, $2c
+--;;;spr palette
+-- .byte $0f, $00, $10, $20
+-- .byte $0f, $06, $16, $26
+-- .byte $0f, $08, $18, $28
+-- .byte $0f, $0a, $1a, $2a
+
+
+ if (plt_step_cnt = 0) then
+ --set vram addr 3f00
+ ppu_set(16#2006#, 16#3f#);
+ elsif (plt_step_cnt = 2) then
+ ppu_set(16#2006#, 16#00#);
+
+ elsif (plt_step_cnt = 4) then
+ --set palette bg data
+ ppu_set(16#2007#, 16#11#);
+ elsif (plt_step_cnt = 6) then
+ ppu_set(16#2007#, 16#01#);
+ elsif (plt_step_cnt = 8) then
+ ppu_set(16#2007#, 16#03#);
+ elsif (plt_step_cnt = 10) then
+ ppu_set(16#2007#, 16#13#);
+
+ elsif (plt_step_cnt = 12) then
+ ppu_set(16#2007#, 16#0f#);
+ elsif (plt_step_cnt = 14) then
+ ppu_set(16#2007#, 16#04#);
+ elsif (plt_step_cnt = 16) then
+ ppu_set(16#2007#, 16#14#);
+ elsif (plt_step_cnt = 18) then
+ ppu_set(16#2007#, 16#24#);
+
+ elsif (plt_step_cnt = 20) then
+ ppu_set(16#2007#, 16#0f#);
+ elsif (plt_step_cnt = 22) then
+ ppu_set(16#2007#, 16#08#);
+ elsif (plt_step_cnt = 24) then
+ ppu_set(16#2007#, 16#18#);
+ elsif (plt_step_cnt = 26) then
+ ppu_set(16#2007#, 16#28#);
+
+ elsif (plt_step_cnt = 28) then
+ ppu_set(16#2007#, 16#05#);
+ elsif (plt_step_cnt = 30) then
+ ppu_set(16#2007#, 16#0c#);
+ elsif (plt_step_cnt = 32) then
+ ppu_set(16#2007#, 16#1c#);
+ elsif (plt_step_cnt = 34) then
+ ppu_set(16#2007#, 16#2c#);
+
+ elsif (plt_step_cnt = 36) then
+ --below is sprite pallete
+ ppu_set(16#2007#, 16#00#);
+ elsif (plt_step_cnt = 38) then
+ ppu_set(16#2007#, 16#24#);
+ elsif (plt_step_cnt = 40) then
+ ppu_set(16#2007#, 16#1b#);
+ elsif (plt_step_cnt = 42) then
+ ppu_set(16#2007#, 16#11#);
+
+ elsif (plt_step_cnt = 44) then
+ ppu_set(16#2007#, 16#00#);
+ elsif (plt_step_cnt = 46) then
+ ppu_set(16#2007#, 16#32#);
+ elsif (plt_step_cnt = 48) then
+ ppu_set(16#2007#, 16#16#);
+ elsif (plt_step_cnt = 50) then
+ ppu_set(16#2007#, 16#20#);
+
+ elsif (plt_step_cnt = 52) then
+ ppu_set(16#2007#, 16#00#);
+ elsif (plt_step_cnt = 54) then
+ ppu_set(16#2007#, 16#26#);
+ elsif (plt_step_cnt = 56) then
+ ppu_set(16#2007#, 16#01#);
+ elsif (plt_step_cnt = 58) then
+ ppu_set(16#2007#, 16#31#);
+
+ else
+ ppu_clr;
+ if (plt_step_cnt > 59) then
+ global_step_cnt := global_step_cnt + 1;
+ end if;
+ end if;
+ if (cpu_cnt mod 18 >= 1 and cpu_cnt mod 18 <= 2) then
+ plt_step_cnt := plt_step_cnt + 1;
+ end if;
+
+ elsif (global_step_cnt = 2) then
+ --step1 = name table set.
+ if (nt_step_cnt = 0) then
+ --set vram addr 2005 (first row, 6th col)
+ ppu_set(16#2006#, 16#20#);
+ elsif (nt_step_cnt = 2) then
+ ppu_set(16#2006#, 16#06#);
+ elsif (nt_step_cnt = 4) then
+ --set name tbl data
+ --0x44, 45, 45 = DEE
+ ppu_set(16#2007#, 16#44#);
+ elsif (nt_step_cnt = 6) then
+ ppu_set(16#2007#, 16#45#);
+ elsif (nt_step_cnt = 8) then
+ ppu_set(16#2007#, 16#45#);
+
+ elsif (nt_step_cnt = 10) then
+ --set vram addr 21d1
+ ppu_set(16#2006#, 16#21#);
+ elsif (nt_step_cnt = 12) then
+ ppu_set(16#2006#, 16#E6#);
+ elsif (nt_step_cnt = 14) then
+ --msg=DEE TEST !!!
+ ppu_set(16#2007#, 16#44#);
+ elsif (nt_step_cnt = 16) then
+ ppu_set(16#2007#, 16#45#);
+ elsif (nt_step_cnt = 18) then
+ ppu_set(16#2007#, 16#45#);
+ elsif (nt_step_cnt = 20) then
+ ppu_set(16#2007#, 16#00#);
+ elsif (nt_step_cnt = 22) then
+ ppu_set(16#2007#, 16#54#);
+ elsif (nt_step_cnt = 24) then
+ ppu_set(16#2007#, 16#45#);
+ elsif (nt_step_cnt = 26) then
+ ppu_set(16#2007#, 16#53#);
+ elsif (nt_step_cnt = 28) then
+ ppu_set(16#2007#, 16#54#);
+ elsif (nt_step_cnt = 30) then
+ ppu_set(16#2007#, 16#21#);
+
+ elsif (nt_step_cnt = 32) then
+ --set vram addr 23c1 (attribute)
+ ppu_set(16#2006#, 16#23#);
+ elsif (nt_step_cnt = 34) then
+ ppu_set(16#2006#, 16#c1#);
+ elsif (nt_step_cnt = 36) then
+ --attr=11011000
+ ppu_set(16#2007#, 16#d8#);
+
+ else
+ ppu_clr;
+ if (nt_step_cnt > 37) then
+ global_step_cnt := global_step_cnt + 1;
+ end if;
+ end if;
+
+ if (cpu_cnt mod 18 >= 2 and cpu_cnt mod 18 <= 3) then
+ nt_step_cnt := nt_step_cnt + 1;
+ end if;
+
+ elsif (global_step_cnt = 3) then
+ --step2 = sprite set.
+ if (spr_step_cnt = 0) then
+ --set sprite addr=00 (first sprite)
+ ppu_set(16#2003#, 16#00#);
+ elsif (spr_step_cnt = 2) then
+ --set sprite data: y=02
+ ppu_set(16#2004#, 16#02#);
+ elsif (spr_step_cnt = 4) then
+ --tile=0x4d (ascii 'M')
+ ppu_set(16#2004#, 16#4d#);
+ elsif (spr_step_cnt = 6) then
+ --set sprite attr=03 (palette 03)
+ ppu_set(16#2004#, 16#03#);
+ elsif (spr_step_cnt = 8) then
+ --set sprite data: x=100
+ ppu_set(16#2004#, 16#64#);
+
+ elsif (spr_step_cnt = 10) then
+ --set sprite data: y=50
+ ppu_set(16#2004#, 16#32#);
+ elsif (spr_step_cnt = 12) then
+ --tile=0x4d (ascii 'O')
+ ppu_set(16#2004#, 16#4f#);
+ elsif (spr_step_cnt = 14) then
+ --set sprite attr=01
+ ppu_set(16#2004#, 16#01#);
+ elsif (spr_step_cnt = 16) then
+ --set sprite data: x=30
+ ppu_set(16#2004#, 16#1e#);
+
+ elsif (spr_step_cnt = 18) then
+ --set sprite data: y=60
+ ppu_set(16#2004#, 60);
+ elsif (spr_step_cnt = 20) then
+ --tile=0x4d (ascii 'P')
+ ppu_set(16#2004#, 16#50#);
+ elsif (spr_step_cnt = 22) then
+ --set sprite attr=01
+ ppu_set(16#2004#, 16#01#);
+ elsif (spr_step_cnt = 24) then
+ --set sprite data: x=33
+ ppu_set(16#2004#, 16#21#);
+
+ elsif (spr_step_cnt = 26) then
+ --set sprite data: y=61
+ ppu_set(16#2004#, 16#3d#);
+ elsif (spr_step_cnt = 28) then
+ --tile=0x4d (ascii 'Q')
+ ppu_set(16#2004#, 16#51#);
+ elsif (spr_step_cnt = 30) then
+ --set sprite attr=02
+ ppu_set(16#2004#, 16#02#);
+ elsif (spr_step_cnt = 32) then
+ --set sprite data: x=45
+ ppu_set(16#2004#, 45);
+
+ else
+ ppu_clr;
+ if (spr_step_cnt > 33) then
+ global_step_cnt := global_step_cnt + 1;
+ end if;
+ end if;
+ if (cpu_cnt mod 18 >= 3 and cpu_cnt mod 18 <= 4) then
+ spr_step_cnt := spr_step_cnt + 1;
+ end if;
+
+ elsif (global_step_cnt = 4) then
+ --final step = enable ppu.
+ if (enable_ppu_step_cnt = 0) then
+ --show bg
+ --PPUMASK=1e (show bg and sprite)
+ --PPUMASK=0e (show bg only)
+ ppu_set(16#2001#, 16#1e#);
+ elsif (enable_ppu_step_cnt = 2) then
+ --enable nmi
+ --PPUCTRL=80
+ ppu_set(16#2000#, 16#80#);
+ else
+ ppu_clr;
+ if (enable_ppu_step_cnt > 2) then
+ global_step_cnt := global_step_cnt + 1;
+ end if;
+ end if;
+ if (cpu_cnt mod 18 >= 4 and cpu_cnt mod 18 <= 5) then
+ enable_ppu_step_cnt := enable_ppu_step_cnt + 1;
+ end if;
+
+ else
+ ppu_clr;
+ init_done := '1';
+ end if;
+ end if;
+
+ end if;
+ end process;
+
+-- signal addr : std_logic_vector( addr_size - 1 downto 0);
+-- signal d_io : std_logic_vector( data_size - 1 downto 0);
+--
+--component counter_register
+-- generic (
+-- dsize : integer := 8;
+-- inc : integer := 1
+-- );
+-- port ( clk : in std_logic;
+-- rst_n : in std_logic;
+-- ce_n : in std_logic;
+-- we_n : in std_logic;
+-- d : in std_logic_vector(dsize - 1 downto 0);
+-- q : out std_logic_vector(dsize - 1 downto 0)
+-- );
+--end component;
+--
+--component prg_rom
+-- generic (abus_size : integer := 15; dbus_size : integer := 8);
+-- port ( clk : in std_logic;
+-- ce_n : in std_logic; --select pin active low.
+-- addr : in std_logic_vector (abus_size - 1 downto 0);
+-- data : inout std_logic_vector (dbus_size - 1 downto 0)
+-- );
+--end component;
+--
+--component processor_status
+-- generic (
+-- dsize : integer := 8
+-- );
+-- port (
+-- signal dbg_dec_oe_n : out std_logic;
+-- signal dbg_dec_val : out std_logic_vector (dsize - 1 downto 0);
+-- signal dbg_int_dbus : out std_logic_vector (dsize - 1 downto 0);
+-- signal dbg_status_val : out std_logic_vector (7 downto 0);
+-- signal dbg_stat_we_n : out std_logic;
+--
+-- clk : in std_logic;
+-- res_n : in std_logic;
+-- dec_oe_n : in std_logic;
+-- bus_oe_n : in std_logic;
+-- set_flg_n : in std_logic;
+-- flg_val : in std_logic;
+-- load_bus_all_n : in std_logic;
+-- load_bus_nz_n : in std_logic;
+-- set_from_alu_n : in std_logic;
+-- alu_n : in std_logic;
+-- alu_v : in std_logic;
+-- alu_z : in std_logic;
+-- alu_c : in std_logic;
+-- stat_c : out std_logic;
+-- dec_val : inout std_logic_vector (dsize - 1 downto 0);
+-- int_dbus : inout std_logic_vector (dsize - 1 downto 0)
+-- );
+--end component;
+--
+-- ---status register
+-- signal status_reg, int_d_bus : std_logic_vector (7 downto 0);
+-- signal stat_dec_oe_n : std_logic;
+-- signal stat_bus_oe_n : std_logic;
+-- signal stat_set_flg_n : std_logic;
+-- signal stat_flg : std_logic;
+-- signal stat_bus_all_n : std_logic;
+-- signal stat_bus_nz_n : std_logic;
+-- signal stat_alu_we_n : std_logic;
+-- signal alu_n : std_logic;
+-- signal alu_z : std_logic;
+-- signal alu_c : std_logic;
+-- signal alu_v : std_logic;
+-- signal stat_c : std_logic;
+-- signal trig_clk : std_logic;
+--
+--
+--
+-- component alu_test
+-- port (
+-- d1 : in std_logic_vector(7 downto 0);
+-- d2 : in std_logic_vector(7 downto 0);
+-- d_out : out std_logic_vector(7 downto 0);
+-- carry_clr_n : in std_logic;
+-- ea_carry : out std_logic
+-- );
+--end component;
+--
+-- signal d1, d2, d_out : std_logic_vector (7 downto 0);
+-- signal ea_carry, gate_n : std_logic;
+-- signal carry_clr_n : std_logic;
+
+
+
+
+-- trig_clk <= not cpu_clk;
+--
+-- pcl_inst : counter_register generic map (16) port map
+-- (cpu_clk, rst_n, '0', '1', (others => '0'), addr(15 downto 0));
+--
+-- rom_inst : prg_rom generic map (12, 8) port map
+-- (base_clk, '0', addr(11 downto 0), d_io);
+--
+-- dbg_addr <= addr;
+-- dbg_d_io <= d_io;
+--
+-- dbg_cpu_clk <= cpu_clk;
+-- dbg_ppu_clk <= ppu_clk;
+--
+-- dbg_d1 <= d1;
+-- dbg_d2 <= d2;
+-- dbg_d_out <= d_out;
+-- dbg_ea_carry <= ea_carry;
+-- dbg_carry_clr_n <= carry_clr_n;
+-- dbg_gate_n <= gate_n;
+--
+-- dummy_alu : alu_test
+-- port map (
+-- d1, d2, d_out, carry_clr_n , ea_carry
+-- );
+--
+-- gate_n <= not ea_carry;
+-- dec_test_p : process (rst_n, ea_carry, trig_clk)
+-- begin
+-- if (rst_n = '0') then
+-- d1 <= "00000000";
+-- d2 <= "00000000";
+-- carry_clr_n <= '0';
+-- --gate_n <= '1';
+---- elsif (ea_carry = '1') then
+---- gate_n <= '0';
+---- carry_clr_n <= '0';
+-- elsif (rising_edge(trig_clk)) then
+-- if (addr(5 downto 0) = "000001") then
+-- --addr=01
+-- carry_clr_n <= '1';
+-- d1 <= "00010011";
+-- d2 <= "01000111";
+-- --gate_n <= '1';
+-- elsif (addr(5 downto 0) = "000010") then
+-- --addr=02
+-- carry_clr_n <= '1';
+-- d1 <= "00110011";
+-- d2 <= "11001111";
+-- --gate_n <= '1';
+-- elsif (addr(5 downto 0) = "000011") then
+-- --addr=03
+-- carry_clr_n <= '1';
+-- d1 <= "00001010";
+-- d2 <= "01011001";
+-- --gate_n <= '1';
+-- elsif (addr(5 downto 0) = "000100") then
+-- --addr=04
+-- carry_clr_n <= '1';
+-- d1 <= "10001010";
+-- d2 <= "10011001";
+-- --gate_n <= '1';
+-- else
+-- carry_clr_n <= '1';
+-- d1 <= "00000000";
+-- d2 <= "00000000";
+-- --gate_n <= '1';
+-- end if;
+-- end if;
+-- end process;
+--
+--
+-- --status register
+-- status_register : processor_status generic map (8)
+-- port map (
+-- dbg_dec_oe_n,
+-- dbg_dec_val,
+-- dbg_int_dbus,
+-- dbg_status_val,
+-- dbg_stat_we_n ,
+-- trig_clk , rst_n,
+-- stat_dec_oe_n, stat_bus_oe_n,
+-- stat_set_flg_n, stat_flg, stat_bus_all_n, stat_bus_nz_n,
+-- stat_alu_we_n, alu_n, alu_v, alu_z, alu_c, stat_c,
+-- status_reg, int_d_bus);
+--
+-- dbg_status <= status_reg;
+-- status_test_p : process (addr)
+-- begin
+-- if (addr(5 downto 0) = "000010") then
+-- --addr=02
+-- --set status(7) = '1'
+-- stat_dec_oe_n <= '1';
+-- stat_bus_oe_n <= '1';
+-- stat_set_flg_n <= '0';
+-- stat_flg <= '1';
+-- stat_bus_all_n <= '1';
+-- stat_bus_nz_n <= '1';
+-- stat_alu_we_n <= '1';
+-- status_reg <= "01000000";
+-- int_d_bus <= "00000000";
+--
+-- elsif (addr(5 downto 0) = "000100") then
+-- --addr=04
+-- --set status(2) = '0'
+-- stat_dec_oe_n <= '1';
+-- stat_bus_oe_n <= '1';
+-- stat_set_flg_n <= '0';
+-- stat_flg <= '0';
+-- stat_bus_all_n <= '1';
+-- stat_bus_nz_n <= '1';
+-- stat_alu_we_n <= '1';
+-- status_reg <= "00000100";
+-- int_d_bus <= "00000000";
+--
+-- elsif (addr(5 downto 0) = "000110") then
+-- --addr=06
+-- --set nz from bus, n=1
+-- stat_dec_oe_n <= '1';
+-- stat_bus_oe_n <= '1';
+-- stat_set_flg_n <= '1';
+-- stat_flg <= '0';
+-- stat_bus_all_n <= '1';
+-- stat_bus_nz_n <= '0';
+-- stat_alu_we_n <= '1';
+-- status_reg <= (others => 'Z');
+-- int_d_bus <= "10000000";
+--
+-- elsif (addr(5 downto 0) = "001000") then
+-- --addr=08
+-- --set nz from bus, z=1
+-- stat_dec_oe_n <= '1';
+-- stat_bus_oe_n <= '1';
+-- stat_set_flg_n <= '1';
+-- stat_flg <= '0';
+-- stat_bus_all_n <= '1';
+-- stat_bus_nz_n <= '0';
+-- stat_alu_we_n <= '1';
+-- status_reg <= (others => 'Z');
+-- int_d_bus <= "00000000";
+--
+-- else
+-- stat_dec_oe_n <= '0';
+-- stat_bus_oe_n <= '1';
+-- stat_set_flg_n <= '1';
+-- stat_flg <= '1';
+-- stat_bus_all_n <= '1';
+-- stat_bus_nz_n <= '1';
+-- stat_alu_we_n <= '1';
+-- status_reg <= (others => 'Z');
+-- int_d_bus <= (others => 'Z');
+-- end if;
+-- end process;
+
+end rtl;
+
end testbench_qt_proj_test5;
architecture stimulus of testbench_qt_proj_test5 is
+
component qt_proj_test5
- port (
+ port (
+
signal dbg_cpu_clk : out std_logic;
signal dbg_ppu_clk : out std_logic;
- signal dbg_mem_clk : out std_logic;
-
+ signal dbg_vga_clk : out std_logic;
signal dbg_addr : out std_logic_vector( 16 - 1 downto 0);
signal dbg_d_io : out std_logic_vector( 8 - 1 downto 0);
--- signal dbg_status : out std_logic_vector(7 downto 0);
--- signal dbg_dec_oe_n : out std_logic;
--- signal dbg_dec_val : out std_logic_vector (7 downto 0);
--- signal dbg_int_dbus : out std_logic_vector (7 downto 0);
--- signal dbg_status_val : out std_logic_vector (7 downto 0);
--- signal dbg_stat_we_n : out std_logic;
-
----monitor inside cpu
--- signal dbg_d1, dbg_d2, dbg_d_out: out std_logic_vector (7 downto 0);
--- signal dbg_ea_carry, dbg_carry_clr_n : out std_logic;
--- signal dbg_gate_n : out std_logic;
-
- signal dbg_pos_x : out std_logic_vector (8 downto 0);
- signal dbg_pos_y : out std_logic_vector (8 downto 0);
- signal dbg_nes_r : out std_logic_vector (3 downto 0);
- signal dbg_nes_g : out std_logic_vector (3 downto 0);
- signal dbg_nes_b : out std_logic_vector (3 downto 0);
-
- signal dbg_wbs_adr_i : out std_logic_vector (21 downto 0); --Address (Bank, Row, Col)
- signal dbg_wbs_dat_i : out std_logic_vector (15 downto 0); --Data In (16 bits)
- signal dbg_wbs_we_i : out std_logic; --Write Enable
- signal dbg_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)
- signal dbg_wbs_cyc_i : out std_logic; --Cycle Command from interface
- signal dbg_wbs_stb_i : out std_logic; --Strobe Command from interface
-
- signal dbg_vga_x : out std_logic_vector (9 downto 0);
- signal dbg_vga_y : out std_logic_vector (9 downto 0);
- signal dbg_nes_x : out std_logic_vector(7 downto 0);
- signal dbg_nes_x_old : out std_logic_vector(7 downto 0);
- signal dbg_sw_state : out std_logic_vector(2 downto 0);
-
- signal dbg_f_in : out std_logic_vector(11 downto 0);
- signal dbg_f_out : out std_logic_vector(11 downto 0);
- signal dbg_f_cnt : out std_logic_vector(7 downto 0);
- signal dbg_f_rd, dbg_f_wr, dbg_f_emp, dbg_f_ful
- : out std_logic;
- signal dbg_bst_cnt : out std_logic_vector(7 downto 0);
+ signal dbg_ppu_ce_n : out std_logic;
+ signal dbg_ppu_ctrl, dbg_ppu_mask, dbg_ppu_status : out std_logic_vector (7 downto 0);
+ signal dbg_ppu_addr : out std_logic_vector (13 downto 0);
+ signal dbg_ppu_data, dbg_ppu_scrl_x, dbg_ppu_scrl_y : out std_logic_vector (7 downto 0);
+ signal dbg_disp_nt, dbg_disp_attr : out std_logic_vector (7 downto 0);
+ signal dbg_disp_ptn_h, dbg_disp_ptn_l : out std_logic_vector (15 downto 0);
+
+ signal dbg_ppu_addr_we_n : out std_logic;
+ signal dbg_ppu_clk_cnt : out std_logic_vector(1 downto 0);
+
+
base_clk : in std_logic;
base_clk_27mhz : in std_logic;
v_sync_n : out std_logic;
r : out std_logic_vector(3 downto 0);
g : out std_logic_vector(3 downto 0);
- b : out std_logic_vector(3 downto 0);
-
- --SDRAM Signals
- dram_addr : out std_logic_vector (11 downto 0); --Address (12 bit)
- dram_bank : out std_logic_vector (1 downto 0); --Bank
- dram_cas_n : out std_logic; --Column Address is being transmitted
- dram_cke : out std_logic; --Clock Enable
- dram_clk : out std_logic; --Clock
- dram_cs_n : out std_logic; --Chip Select (Here - Mask commands)
- dram_dq : inout std_logic_vector (15 downto 0); --Data in / Data out
- dram_ldqm : out std_logic; --Byte masking
- dram_udqm : out std_logic; --Byte masking
- dram_ras_n : out std_logic; --Row Address is being transmitted
- dram_we_n : out std_logic --Write Enable
- );
+ b : out std_logic_vector(3 downto 0)
+
+ );
end component;
+
signal base_clk : std_logic;
- signal base_clk_27mhz : std_logic;
- signal vga_clk : std_logic;
signal reset_input : std_logic;
+ signal base_clk_27mhz : std_logic;
+
signal h_sync_n : std_logic;
signal v_sync_n : std_logic;
signal joypad1 : std_logic_vector(7 downto 0);
signal joypad2 : std_logic_vector(7 downto 0);
- signal dram_addr : std_logic_vector (11 downto 0); --Address (12 bit)
- signal dram_bank : std_logic_vector (1 downto 0); --Bank
- signal dram_cas_n : std_logic; --Column Address is being transmitted
- signal dram_cke : std_logic; --Clock Enable
- signal dram_clk : std_logic; --Clock
- signal dram_cs_n : std_logic; --Chip Select (Here - Mask commands)
- signal dram_dq : std_logic_vector (15 downto 0); --Data in / Data out
- signal dram_ldqm : std_logic; --Byte masking
- signal dram_udqm : std_logic; --Byte masking
- signal dram_ras_n : std_logic; --Row Address is being transmitted
- signal dram_we_n : std_logic; --Write Enable
-
- constant powerup_time : time := 50 ns;
- constant reset_time : time := 200 ns;
+ constant powerup_time : time := 2 us;
+ constant reset_time : time := 890 ns;
---clock frequency = 21,477,270 (21 MHz)
--constant base_clock_time : time := 46 ns;
- --base clock frequency = 50 MHz.
- constant base_clock_time : time := 20 ns;
-
- constant base_clock_27mhz_time : time := 37 ns;
-
+ --DE1 base clock = 50 MHz
+ constant base_clock_time : time := 20 ns;
signal dbg_cpu_clk : std_logic;
signal dbg_ppu_clk : std_logic;
- signal dbg_mem_clk : std_logic;
+ signal dbg_vga_clk : std_logic;
+ signal dbg_mem_clk : std_logic;
+ signal dbg_r_nw : std_logic;
signal dbg_addr : std_logic_vector( 16 - 1 downto 0);
signal dbg_d_io : std_logic_vector( 8 - 1 downto 0);
signal dbg_vram_ad : std_logic_vector (7 downto 0);
signal dbg_vram_a : std_logic_vector (13 downto 8);
-
-
+ signal dbg_instruction : std_logic_vector(7 downto 0);
+ signal dbg_int_d_bus : std_logic_vector(7 downto 0);
+ signal dbg_exec_cycle : std_logic_vector (5 downto 0);
+ signal dbg_ea_carry : std_logic;
+ signal dbg_wait_a58_branch_next : std_logic;
+-- signal dbg_index_bus : std_logic_vector(7 downto 0);
+-- signal dbg_acc_bus : std_logic_vector(7 downto 0);
signal dbg_status : std_logic_vector(7 downto 0);
+ signal dbg_pcl, dbg_pch, dbg_sp, dbg_x, dbg_y, dbg_acc : std_logic_vector(7 downto 0);
signal dbg_dec_oe_n : std_logic;
signal dbg_dec_val : std_logic_vector (7 downto 0);
signal dbg_int_dbus : std_logic_vector (7 downto 0);
- signal dbg_status_val : std_logic_vector (7 downto 0);
+-- signal dbg_status_val : std_logic_vector (7 downto 0);
signal dbg_stat_we_n : std_logic;
-
- signal dbg_d1, dbg_d2, dbg_d_out: std_logic_vector (7 downto 0);
- signal dbg_ea_carry, dbg_carry_clr_n : std_logic;
- signal dbg_gate_n : std_logic;
-
- signal dbg_pos_x : std_logic_vector (8 downto 0);
- signal dbg_pos_y : std_logic_vector (8 downto 0);
- signal dbg_nes_r : std_logic_vector (3 downto 0);
- signal dbg_nes_g : std_logic_vector (3 downto 0);
- signal dbg_nes_b : std_logic_vector (3 downto 0);
-
- signal dbg_wbs_adr_i : std_logic_vector (21 downto 0); --Address (Bank, Row, Col)
- signal dbg_wbs_dat_i : std_logic_vector (15 downto 0); --Data In (16 bits)
- signal dbg_wbs_we_i : std_logic; --Write Enable
- signal dbg_wbs_tga_i : std_logic_vector (7 downto 0); --Address Tag : Read/write burst length-1 (0 represents 1 word, FF represents 256 words)
- signal dbg_wbs_cyc_i : std_logic; --Cycle Command from interface
- signal dbg_wbs_stb_i : std_logic; --Strobe Command from interface
-
- signal dbg_vga_x : std_logic_vector (9 downto 0);
- signal dbg_vga_y : std_logic_vector (9 downto 0);
- signal dbg_nes_x : std_logic_vector(7 downto 0);
- signal dbg_nes_x_old : std_logic_vector(7 downto 0);
- signal dbg_sw_state : std_logic_vector(2 downto 0);
-
- signal dbg_f_in : std_logic_vector(11 downto 0);
- signal dbg_f_out : std_logic_vector(11 downto 0);
- signal dbg_f_cnt : std_logic_vector(7 downto 0);
- signal dbg_f_rd, dbg_f_wr, dbg_f_emp, dbg_f_ful
- : std_logic;
- signal dbg_bst_cnt : std_logic_vector(7 downto 0);
+ signal dbg_idl_h, dbg_idl_l, dbg_dbb_r, dbg_dbb_w : std_logic_vector (7 downto 0);
+ signal dbg_ppu_ce_n : std_logic;
+ signal dbg_ppu_ctrl, dbg_ppu_mask, dbg_ppu_status : std_logic_vector (7 downto 0);
+ signal dbg_ppu_addr : std_logic_vector (13 downto 0);
+ signal dbg_ppu_data, dbg_ppu_scrl_x, dbg_ppu_scrl_y : std_logic_vector (7 downto 0);
+ signal dbg_disp_nt, dbg_disp_attr : std_logic_vector (7 downto 0);
+ signal dbg_disp_ptn_h, dbg_disp_ptn_l : std_logic_vector (15 downto 0);
+ signal dbg_ppu_addr_we_n : std_logic;
+ signal dbg_ppu_clk_cnt : std_logic_vector(1 downto 0);
begin
sim_board : qt_proj_test5 port map (
- dbg_cpu_clk ,
- dbg_ppu_clk ,
- dbg_mem_clk ,
- dbg_addr ,
- dbg_d_io ,
-
--- dbg_status ,
--- dbg_dec_oe_n ,
--- dbg_dec_val ,
--- dbg_int_dbus ,
--- dbg_status_val ,
--- dbg_stat_we_n ,
-
--- dbg_d1, dbg_d2, dbg_d_out,
--- dbg_ea_carry ,dbg_carry_clr_n ,
--- dbg_gate_n ,
-
- dbg_pos_x ,
- dbg_pos_y ,
- dbg_nes_r ,
- dbg_nes_g ,
- dbg_nes_b ,
-
- dbg_wbs_adr_i ,
- dbg_wbs_dat_i ,
- dbg_wbs_we_i ,
- dbg_wbs_tga_i ,
- dbg_wbs_cyc_i ,
- dbg_wbs_stb_i ,
-
- dbg_vga_x ,
- dbg_vga_y ,
- dbg_nes_x ,
- dbg_nes_x_old ,
- dbg_sw_state ,
-
- dbg_f_in ,
- dbg_f_out ,
- dbg_f_cnt ,
- dbg_f_rd, dbg_f_wr, dbg_f_emp, dbg_f_ful ,
- dbg_bst_cnt ,
-
- base_clk, base_clk_27mhz, reset_input,
+ dbg_cpu_clk ,
+ dbg_ppu_clk ,
+ dbg_vga_clk ,
+ dbg_addr ,
+ dbg_d_io ,
+
+ dbg_ppu_ce_n ,
+ dbg_ppu_ctrl, dbg_ppu_mask, dbg_ppu_status ,
+ dbg_ppu_addr ,
+ dbg_ppu_data, dbg_ppu_scrl_x, dbg_ppu_scrl_y ,
+ dbg_disp_nt, dbg_disp_attr ,
+ dbg_disp_ptn_h, dbg_disp_ptn_l ,
+
+ dbg_ppu_addr_we_n ,
+ dbg_ppu_clk_cnt ,
+
+
+
+ base_clk ,
+ base_clk_27mhz ,
+ reset_input ,
h_sync_n ,
v_sync_n ,
r ,
g ,
- b ,
-
- dram_addr ,
- dram_bank ,
- dram_cas_n ,
- dram_cke ,
- dram_clk ,
- dram_cs_n ,
- dram_dq ,
- dram_ldqm ,
- dram_udqm ,
- dram_ras_n ,
- dram_we_n
-);
-
--- dummy_vga_disp : vga_device
--- port map (vga_clk, reset_input, h_sync_n, v_sync_n, r, g, b);
+ b
+
+ );
--- input reset.
reset_p: process
begin
+ reset_input <= '1';
wait for powerup_time;
- reset_input <= '0';
+ reset_input <= '0';
wait for reset_time;
- reset_input <= '1';
+ reset_input <= '1';
wait;
end process;
wait for base_clock_time / 2;
end process;
- clock27mhz_p: process
- begin
- base_clk_27mhz <= '1';
- wait for base_clock_27mhz_time / 2;
- base_clk_27mhz <= '0';
- wait for base_clock_27mhz_time / 2;
- end process;
end stimulus;
-------------------------------------------------------------\r
-------------------------------------------------------------\r
--------------- VGA RGB Output Control w/ SDRAM --------------\r
+------------------- PPU VGA Output Control ------------------\r
-------------------------------------------------------------\r
-------------------------------------------------------------\r
\r
-
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.std_logic_unsigned.conv_integer;
-use ieee.std_logic_arith.conv_std_logic_vector;
-use work.motonesfpga_common.all;
+library ieee;\r
+use ieee.std_logic_1164.all;\r
+use ieee.std_logic_unsigned.conv_integer;\r
+use ieee.std_logic_arith.conv_std_logic_vector;\r
use ieee.std_logic_unsigned.all;\r
-
-entity vga_ctl is
+use work.motonesfpga_common.all;\r
+\r
+entity vga_ctl is \r
port ( \r
- signal dbg_vga_x : out std_logic_vector (9 downto 0);\r
- signal dbg_vga_y : out std_logic_vector (9 downto 0);\r
- signal dbg_nes_x : out std_logic_vector(7 downto 0);\r
- signal dbg_nes_x_old : out std_logic_vector(7 downto 0);\r
- signal dbg_sw_state : out std_logic_vector(2 downto 0);\r
-\r
- signal dbg_f_in : out std_logic_vector(11 downto 0);\r
- signal dbg_f_out : out std_logic_vector(11 downto 0);\r
- signal dbg_f_cnt : out std_logic_vector(7 downto 0);\r
- signal dbg_f_rd, dbg_f_wr, dbg_f_emp, dbg_f_ful \r
- : out std_logic;\r
- signal dbg_bst_cnt : out std_logic_vector(7 downto 0);\r
- \r
- ppu_clk : in std_logic;
+ signal dbg_vga_clk : out std_logic;\r
+ signal dbg_nes_x : out std_logic_vector (8 downto 0);\r
+ signal dbg_vga_x : out std_logic_vector (9 downto 0);\r
+ signal dbg_disp_nt, dbg_disp_attr : out std_logic_vector (7 downto 0);\r
+ signal dbg_disp_ptn_h, dbg_disp_ptn_l : out std_logic_vector (15 downto 0);\r
+ signal dbg_plt_ce_rn_wn : out std_logic_vector (2 downto 0);\r
+ signal dbg_plt_addr : out std_logic_vector (4 downto 0);\r
+ signal dbg_plt_data : out std_logic_vector (7 downto 0);\r
+ signal dbg_p_oam_ce_rn_wn : out std_logic_vector (2 downto 0);\r
+ signal dbg_p_oam_addr : out std_logic_vector (7 downto 0);\r
+ signal dbg_p_oam_data : out std_logic_vector (7 downto 0);\r
+ signal dbg_s_oam_ce_rn_wn : out std_logic_vector (2 downto 0);\r
+ signal dbg_s_oam_addr : out std_logic_vector (4 downto 0);\r
+ signal dbg_s_oam_data : out std_logic_vector (7 downto 0);\r
+\r
vga_clk : in std_logic;\r
mem_clk : in std_logic;\r
- rst_n : in std_logic;
- pos_x : in std_logic_vector (8 downto 0);
- pos_y : in std_logic_vector (8 downto 0);
- nes_r : in std_logic_vector (3 downto 0);
- nes_g : in std_logic_vector (3 downto 0);
- nes_b : in std_logic_vector (3 downto 0);
- h_sync_n : out std_logic;
- v_sync_n : out std_logic;
- r : out std_logic_vector(3 downto 0);
- g : out std_logic_vector(3 downto 0);
- b : out std_logic_vector(3 downto 0);
-\r
- --SDRAM Signals\r
- wbs_adr_i : out std_logic_vector (21 downto 0); --Address (Bank, Row, Col)\r
- wbs_dat_i : out std_logic_vector (15 downto 0); --Data In (16 bits)\r
- wbs_we_i : out std_logic; --Write Enable\r
- 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
- wbs_cyc_i : out std_logic; --Cycle Command from interface\r
- wbs_stb_i : out std_logic; --Strobe Command from interface\r
- wbs_dat_o : in std_logic_vector (15 downto 0); --Data Out (16 bits)\r
- wbs_stall_o : in std_logic; --Slave is not ready to receive new data\r
- wbs_err_o : in std_logic; --Error flag: OOR Burst. Burst length is greater that 256-column address\r
- wbs_ack_o : in std_logic --When Read Burst: DATA bus must be valid in this cycle\r
- );
-end vga_ctl;
-
-architecture rtl of vga_ctl is
-
-component counter_register
- generic (
- dsize : integer := 8;
- inc : integer := 1
- );
- port ( clk : in std_logic;
- rst_n : in std_logic;
- ce_n : in std_logic;
- we_n : in std_logic;
- d : in std_logic_vector(dsize - 1 downto 0);
- q : out std_logic_vector(dsize - 1 downto 0)
- );
-end component;
+ rst_n : in std_logic;\r
\r
-component d_flip_flop\r
+ --vram i/f\r
+ rd_n : out std_logic;\r
+ wr_n : out std_logic;\r
+ ale : out std_logic;\r
+ vram_ad : inout std_logic_vector (7 downto 0);\r
+ vram_a : out std_logic_vector (13 downto 8);\r
+\r
+ --vga output\r
+ h_sync_n : out std_logic;\r
+ v_sync_n : out std_logic;\r
+ r : out std_logic_vector (3 downto 0);\r
+ g : out std_logic_vector (3 downto 0);\r
+ b : out std_logic_vector (3 downto 0);\r
+\r
+ --upper ppu i/f\r
+ ppu_ctrl : in std_logic_vector (7 downto 0);\r
+ ppu_mask : in std_logic_vector (7 downto 0);\r
+ read_status : in std_logic;\r
+ ppu_scroll_x : in std_logic_vector (7 downto 0);\r
+ ppu_scroll_y : in std_logic_vector (7 downto 0);\r
+\r
+ --ppu internal ram access\r
+ r_nw : in std_logic;\r
+ oam_bus_ce_n : in std_logic;\r
+ plt_bus_ce_n : in std_logic;\r
+ oam_plt_addr : in std_logic_vector (7 downto 0);\r
+ oam_plt_data : inout std_logic_vector (7 downto 0)\r
+ );\r
+end vga_ctl;\r
+\r
+architecture rtl of vga_ctl is\r
+\r
+component counter_register\r
generic (\r
- dsize : integer := 8\r
- );\r
- port ( \r
- clk : in std_logic;\r
- res_n : in std_logic;\r
- set_n : in std_logic;\r
- we_n : in std_logic;\r
- d : in std_logic_vector (dsize - 1 downto 0);\r
- q : out std_logic_vector (dsize - 1 downto 0)\r
- );\r
+ dsize : integer := 8;\r
+ inc : integer := 1\r
+ );\r
+ port ( clk : in std_logic;\r
+ rst_n : in std_logic;\r
+ ce_n : in std_logic;\r
+ we_n : in std_logic;\r
+ d : in std_logic_vector(dsize - 1 downto 0);\r
+ q : out std_logic_vector(dsize - 1 downto 0)\r
+ );\r
end component;\r
\r
-component sdram_write_fifo\r
- PORT\r
- (\r
- aclr : IN STD_LOGIC ;\r
- clock : IN STD_LOGIC ;\r
- data : IN STD_LOGIC_VECTOR (11 DOWNTO 0);\r
- rdreq : IN STD_LOGIC ;\r
- wrreq : IN STD_LOGIC ;\r
- empty : OUT STD_LOGIC ;\r
- full : OUT STD_LOGIC ;\r
- q : OUT STD_LOGIC_VECTOR (11 DOWNTO 0);\r
- usedw : OUT STD_LOGIC_VECTOR (7 DOWNTO 0)\r
- );\r
+component ppu_vga_render\r
+ port ( \r
+ signal dbg_vga_clk : out std_logic;\r
+ signal dbg_nes_x : out std_logic_vector (8 downto 0);\r
+ signal dbg_disp_nt, dbg_disp_attr : out std_logic_vector (7 downto 0);\r
+ signal dbg_disp_ptn_h, dbg_disp_ptn_l : out std_logic_vector (15 downto 0);\r
+ signal dbg_plt_ce_rn_wn : out std_logic_vector (2 downto 0);\r
+ signal dbg_plt_addr : out std_logic_vector (4 downto 0);\r
+ signal dbg_plt_data : out std_logic_vector (7 downto 0);\r
+ signal dbg_p_oam_ce_rn_wn : out std_logic_vector (2 downto 0);\r
+ signal dbg_p_oam_addr : out std_logic_vector (7 downto 0);\r
+ signal dbg_p_oam_data : out std_logic_vector (7 downto 0);\r
+ signal dbg_s_oam_ce_rn_wn : out std_logic_vector (2 downto 0);\r
+ signal dbg_s_oam_addr : out std_logic_vector (4 downto 0);\r
+ signal dbg_s_oam_data : out std_logic_vector (7 downto 0);\r
+ \r
+ vga_clk : in std_logic;\r
+ mem_clk : in std_logic;\r
+ rst_n : in std_logic;\r
+ rd_n : out std_logic;\r
+ wr_n : out std_logic;\r
+ ale : out std_logic;\r
+ vram_ad : inout std_logic_vector (7 downto 0);\r
+ vram_a : out std_logic_vector (13 downto 8);\r
+ cur_x : in std_logic_vector (8 downto 0);\r
+ cur_y : in std_logic_vector (8 downto 0);\r
+ r : out std_logic_vector (3 downto 0);\r
+ g : out std_logic_vector (3 downto 0);\r
+ b : out std_logic_vector (3 downto 0);\r
+ ppu_ctrl : in std_logic_vector (7 downto 0);\r
+ ppu_mask : in std_logic_vector (7 downto 0);\r
+ read_status : in std_logic;\r
+ ppu_status : out std_logic_vector (7 downto 0);\r
+ ppu_scroll_x : in std_logic_vector (7 downto 0);\r
+ ppu_scroll_y : in std_logic_vector (7 downto 0);\r
+ \r
+ r_nw : in std_logic;\r
+ oam_bus_ce_n : in std_logic;\r
+ plt_bus_ce_n : in std_logic;\r
+ oam_plt_addr : in std_logic_vector (7 downto 0);\r
+ oam_plt_data : inout std_logic_vector (7 downto 0);\r
+ v_bus_busy_n : out std_logic\r
+ );\r
end component;\r
\r
---------- screen constant -----------
-constant VGA_W : integer := 640;
-constant VGA_H : integer := 480;
-constant VGA_W_MAX : integer := 800;
-constant VGA_H_MAX : integer := 525;
-constant H_SP : integer := 95;
-constant H_BP : integer := 48;
-constant H_FP : integer := 15;
-constant V_SP : integer := 2;
-constant V_BP : integer := 33;
-constant V_FP : integer := 10;
-\r
-constant NES_W : integer := 256;\r
-constant NES_H : integer := 240;\r
-
+--------- screen constant -----------\r
+constant VGA_W : integer := 640;\r
+constant VGA_H : integer := 480;\r
+constant VGA_W_MAX : integer := 800;\r
+constant VGA_H_MAX : integer := 525;\r
+constant H_SP : integer := 95;\r
+constant H_BP : integer := 48;\r
+constant H_FP : integer := 15;\r
+constant V_SP : integer := 2;\r
+constant V_BP : integer := 33;\r
+constant V_FP : integer := 10;\r
\r
--------- signal declaration -----------\r
-signal vga_x : std_logic_vector (9 downto 0);
-signal vga_y : std_logic_vector (9 downto 0);
+signal vga_x : std_logic_vector (9 downto 0);\r
+signal vga_y : std_logic_vector (9 downto 0);\r
signal x_res_n : std_logic;\r
signal y_res_n : std_logic;\r
signal y_en_n : std_logic;\r
-\r
signal cnt_clk : std_logic;\r
-signal mem_clk_n : std_logic;\r
-
---signal mem_cnt : std_logic_vector (4 downto 0);\r
-\r
-signal count5_res_n : std_logic;\r
-signal count5 : std_logic_vector(2 downto 0);\r
-signal nes_x_en_n : std_logic;\r
-signal nes_x : std_logic_vector(7 downto 0);\r
-\r
-signal dram_col_we_n : std_logic;\r
-signal dram_col : std_logic_vector(15 downto 0);\r
-\r
-signal pos_x_we_n : std_logic;\r
-signal pos_x_old : std_logic_vector(8 downto 0);\r
-signal nes_x_we_n : std_logic;\r
-signal nes_x_old : std_logic_vector(7 downto 0);\r
-\r
\r
-signal rst : std_logic;\r
-signal f_in : std_logic_vector(11 downto 0);\r
-signal f_out : std_logic_vector(11 downto 0);\r
-signal f_val : std_logic_vector(11 downto 0);\r
-signal f_cnt : std_logic_vector(7 downto 0);\r
-signal f_val_we_n : std_logic;\r
+signal emu_ppu_clk : std_logic;\r
+signal emu_ppu_clk_n : std_logic;\r
+signal count5_res_n : std_logic;\r
+signal count5 : std_logic_vector(2 downto 0);\r
+signal nes_x : std_logic_vector (8 downto 0);\r
+signal nes_y : std_logic_vector (8 downto 0);\r
\r
\r
-signal sdram_write_addr : std_logic_vector (21 downto 0);\r
-signal sdram_addr_inc_n : std_logic;\r
-signal sdram_addr_res_n : std_logic;\r
-signal bst_wr_cnt : std_logic_vector (7 downto 0);\r
-signal bst_wr_cnt_we_n : std_logic;\r
-\r
-signal f_rd, f_wr, f_emp, f_ful \r
- : std_logic;\r
-\r
-constant sw_idle : std_logic_vector(2 downto 0) := "000";\r
-constant sw_pop_fifo : std_logic_vector(2 downto 0) := "001";\r
-constant sw_write : std_logic_vector(2 downto 0) := "010";\r
-constant sw_write_ack : std_logic_vector(2 downto 0) := "011";\r
-constant sw_write_burst : std_logic_vector(2 downto 0) := "100";\r
-constant sw_write_burst_last : std_logic_vector(2 downto 0) := "101";\r
-\r
-signal sw_state : std_logic_vector(2 downto 0);\r
-\r
-constant SDRAM_READ_WAIT_CNT : integer := 10;\r
\r
+-----dummy signal\r
+signal v_bus_busy_n : std_logic;\r
+signal ppu_status : std_logic_vector (7 downto 0);\r
+signal rr : std_logic_vector (3 downto 0);\r
+signal gg : std_logic_vector (3 downto 0);\r
+signal bb : std_logic_vector (3 downto 0);\r
\r
---DE1 base clock 50 MHz\r
---motones sim project uses following clock.\r
--cpu clock = base clock / 24 = 2.08 MHz (480 ns / cycle)\r
--ppu clock = base clock / 8\r
--vga clock = base clock / 2\r
---sdram clock = 133.333 MHz\r
-
-begin
- dbg_vga_x <= vga_x ;\r
- --dbg_vga_y <= "0" & pos_x_old;\r
- dbg_vga_y <= vga_y ;\r
- dbg_nes_x <= nes_x ;\r
- dbg_nes_x_old <= nes_x_old;\r
- dbg_sw_state <= sw_state ;\r
-\r
- dbg_f_in <= f_in ;\r
- dbg_f_out <= f_out ;\r
- dbg_f_cnt <= f_cnt ;\r
- dbg_bst_cnt <= bst_wr_cnt ;\r
- dbg_f_rd <= f_rd ;\r
- dbg_f_wr <= f_wr ;\r
- dbg_f_emp <= f_emp ;\r
- dbg_f_ful <= f_ful ;\r
-\r
-\r
-
+--sdram clock = 135 MHz\r
+\r
+begin\r
+ dbg_vga_x <= vga_x;\r
+\r
cnt_clk <= not vga_clk;\r
- mem_clk_n <= not mem_clk;\r
- rst <= not rst_n;\r
\r
- x_inst : counter_register generic map (10, 1)
- port map (cnt_clk , x_res_n, '0', '1', (others => '0'), vga_x);
-\r
+ --vga position counter\r
+ x_inst : counter_register generic map (10, 1)\r
+ port map (cnt_clk , x_res_n, '0', '1', (others => '0'), vga_x);\r
y_inst : counter_register generic map (10, 1)\r
port map (cnt_clk , y_res_n, y_en_n, '1', (others => '0'), vga_y);\r
-\r
- nes_x_inst : counter_register generic map (8, 1)\r
- port map (vga_clk, x_res_n, nes_x_en_n, '1', (others => '0'), nes_x);\r
- \r
- nes_x_old_inst: d_flip_flop generic map (8)\r
- port map (mem_clk_n, rst_n, '1', nes_x_we_n, nes_x, nes_x_old);\r
- \r
- count5_inst : counter_register generic map (3, 1)\r
- port map (cnt_clk, count5_res_n, '0', '1', (others => '0'), count5);\r
-\r
- pos_x_old_inst: d_flip_flop generic map (9)\r
- port map (mem_clk_n, rst_n, '1', pos_x_we_n, pos_x, pos_x_old);\r
-\r
- fifo_inst : sdram_write_fifo port map\r
- (rst, mem_clk_n, f_in, f_rd, f_wr, f_emp, f_ful, f_out, f_cnt);\r
- \r
- sdram_wr_addr_inst : counter_register generic map (22, 1)\r
- port map (mem_clk, sdram_addr_res_n, sdram_addr_inc_n, '1', (others => '0'), sdram_write_addr);\r
-\r
- fifo_bst_wr_cnt : counter_register generic map (8, 255)\r
- port map (mem_clk, sdram_addr_res_n, sdram_addr_inc_n, bst_wr_cnt_we_n, f_cnt, bst_wr_cnt);\r
-\r
- fifo_data_inst: d_flip_flop generic map (12)\r
- port map (mem_clk, rst_n, '1', f_val_we_n, f_out, f_val);\r
-\r
--- dram_rd_inst : d_flip_flop generic map (16)\r
--- port map (mem_clk, rst_n, '1', dram_col_we_n, wbs_dat_o, dram_col);\r
-\r
- pos_x_p : process (rst_n, mem_clk)\r
+ vga_out_p : process (rst_n, vga_clk)\r
begin\r
if (rst_n = '0') then\r
- pos_x_we_n <= '1';\r
- elsif (rising_edge(mem_clk)) then\r
- if (pos_x /= pos_x_old) then\r
- pos_x_we_n <= '0';\r
+ h_sync_n <= '0';\r
+ v_sync_n <= '0';\r
+ x_res_n <= '0';\r
+ y_res_n <= '0';\r
+ bb <= (others => '0');\r
+ gg <= (others => '0');\r
+ rr <= (others => '0');\r
+ elsif (rising_edge(vga_clk)) then\r
+ --xmax = 799\r
+ if (vga_x = conv_std_logic_vector(VGA_W_MAX, 10)) then\r
+ x_res_n <= '0';\r
+ y_en_n <= '0';\r
+ --ymax=524\r
+ if (vga_y = conv_std_logic_vector(VGA_H_MAX, 10)) then\r
+ y_res_n <= '0';\r
+ else\r
+ y_res_n <= '1';\r
+ end if;\r
else\r
- pos_x_we_n <= '1';\r
+ x_res_n <= '1';\r
+ y_en_n <= '1';\r
+ y_res_n <= '1';\r
end if;\r
- end if;\r
- end process;\r
- \r
- nes_x_p : process (rst_n, mem_clk)\r
- begin\r
- if (rst_n = '0') then\r
- nes_x_we_n <= '1';\r
- elsif (rising_edge(mem_clk)) then\r
- if (nes_x /= nes_x_old) then\r
- nes_x_we_n <= '0';\r
+\r
+ --sync signal assert.\r
+ if (vga_x >= conv_std_logic_vector((VGA_W + H_FP) , 10) and \r
+ vga_x < conv_std_logic_vector((VGA_W + H_FP + H_SP) , 10)) then\r
+ h_sync_n <= '0';\r
else\r
- nes_x_we_n <= '1';\r
+ h_sync_n <= '1';\r
end if;\r
- end if;\r
- end process;\r
\r
- f_in <= nes_r & nes_g & nes_b;\r
- fifo_w_p : process (rst_n, mem_clk)\r
- begin\r
- if (rst_n = '0') then\r
- f_wr <= '0';\r
- elsif (rising_edge(mem_clk)) then\r
- --fifo data push\r
- if (pos_x < conv_std_logic_vector(NES_W, 9) and\r
- pos_y < conv_std_logic_vector(NES_H, 9)) then\r
- if (pos_x /= pos_x_old) then\r
- --add data to fifo when pos_x is changed.\r
- f_wr <= '1';\r
- else\r
- f_wr <= '0';\r
- end if;\r
+ if (vga_y >= conv_std_logic_vector((VGA_H + V_FP) , 10) and \r
+ vga_y < conv_std_logic_vector((VGA_H + V_FP + V_SP) , 10)) then\r
+ v_sync_n <= '0';\r
else\r
- f_wr <= '0';\r
- end if; --pos_x < conv_std_logic_vector(NES_W, 9) and pos_y < conv_std_logic_vector(NES_H, 9)\r
- end if;\r
- end process;\r
-\r
- sw_state_p : process (rst_n, mem_clk)\r
- begin\r
- if (rst_n = '0') then\r
- sw_state <= sw_idle;\r
- elsif (rising_edge(mem_clk)) then\r
- if (vga_x >= conv_std_logic_vector(VGA_W , 10) \r
- or vga_y >= conv_std_logic_vector(VGA_H, 10)) then\r
- --write to sdram status\r
- case sw_state is\r
- when sw_idle => --0: idle...\r
- if (f_cnt < "00001000") then --wait until fifo > 8\r
- sw_state <= sw_idle;\r
- else\r
- sw_state <= sw_pop_fifo;\r
- end if;\r
- \r
- when sw_pop_fifo => --1: initialize writing...\r
- sw_state <= sw_write;\r
-\r
- when sw_write => --2: start writing\r
- sw_state <= sw_write_ack;\r
- \r
- when sw_write_ack => --3: push first data\r
- sw_state <= sw_write_burst;\r
-\r
- when sw_write_burst => --4: repeat...\r
- if (bst_wr_cnt > "00000001") then -- busrt write\r
- sw_state <= sw_write_burst;\r
- else\r
- sw_state <= sw_write_burst_last;\r
- end if;\r
+ v_sync_n <= '1';\r
+ end if;\r
\r
- when others => --other and burst last...\r
- sw_state <= sw_idle;\r
- end case;\r
- \r
+ if (vga_x <= conv_std_logic_vector((VGA_W) , 10) and \r
+ vga_y <= conv_std_logic_vector((VGA_H) , 10)) then\r
+ bb <= "0110";\r
+ gg <= (others => '1');\r
+ rr <= (others => '0');\r
else\r
- sw_state <= sw_idle;\r
- end if; --if (vga_x >=conv_std_\r
+ bb <= (others => '0');\r
+ gg <= (others => '0');\r
+ rr <= (others => '0');\r
+ end if;\r
end if;\r
end process;\r
\r
- f_rd <= '0' when rst_n = '0' else\r
- '1' when (sw_state = sw_pop_fifo) else\r
- '1' when (sw_state = sw_write_burst) else\r
- '0';\r
- f_val_we_n <= not f_rd;\r
- sdram_addr_inc_n <= not f_rd;\r
-\r
- sdram_addr_res_n <= rst_n;\r
- bst_wr_cnt_we_n <= '1' when rst_n = '0' else\r
- '0' when sw_state = sw_idle else\r
- '1';\r
- wbs_adr_i <= sdram_write_addr - 1;\r
- wbs_dat_i <= "0000" & f_val;\r
- wbs_tga_i <= bst_wr_cnt + 1;\r
- wbs_cyc_i <= '0' when rst_n = '0' else\r
- '1' when sw_state >= sw_write else\r
- '0';\r
- wbs_stb_i <= '0' when rst_n = '0' else\r
- '1' when sw_state >= sw_write else\r
- '0';\r
- wbs_we_i <= '0' when rst_n = '0' else\r
- '1' when sw_state >= sw_write else\r
- '0';\r
-\r
- ----------- vga position conversion 640 to 256\r
- dram_latch_p : process (rst_n, vga_clk)\r
+ --emulate ppu clock that is synchronized with vga clock\r
+ count5_inst : counter_register generic map (3, 1)\r
+ port map (cnt_clk, count5_res_n, '0', '1', (others => '0'), count5);\r
+ nes_x_inst : counter_register generic map (9, 1)\r
+ port map (emu_ppu_clk , x_res_n, '0', '1', (others => '0'), nes_x);\r
+ nes_y <= vga_y(9 downto 1);\r
+ emu_clk_p : process (rst_n, vga_clk)\r
begin\r
if (rst_n = '0') then\r
- nes_x_en_n <= '1';\r
- \r
- elsif (falling_edge(vga_clk)) then\r
-\r
- if (count5 = "001" or count5 = "011") then\r
- nes_x_en_n <= '0';\r
- else\r
- nes_x_en_n <= '1';\r
- end if;\r
- end if;\r
- end process;\r
-\r
- vga_out_p : process (rst_n, vga_clk)
- begin
- if (rst_n = '0') then
- h_sync_n <= '0';
- v_sync_n <= '0';
- x_res_n <= '0';
- y_res_n <= '0';\r
- count5_res_n <= '0';
- \r
- r<=(others => '0');
- g<=(others => '0');
- b<=(others => '0');\r
- \r
- elsif (rising_edge(vga_clk)) then
- --xmax = 799
- if (vga_x = conv_std_logic_vector(VGA_W_MAX, 10)) then
- x_res_n <= '0';
- y_en_n <= '0';
- --ymax=524
- if (vga_y = conv_std_logic_vector(VGA_H_MAX, 10)) then
- y_res_n <= '0';
- else
- y_res_n <= '1';
- end if;
- else
- x_res_n <= '1';
- y_en_n <= '1';
- y_res_n <= '1';
- end if;
-
- --sync signal assert.
- if (vga_x >= conv_std_logic_vector((VGA_W + H_FP) , 10) and
- vga_x < conv_std_logic_vector((VGA_W + H_FP + H_SP) , 10)) then
- h_sync_n <= '0';
- else
- h_sync_n <= '1';
- end if;
-
- if (vga_y >= conv_std_logic_vector((VGA_H + V_FP) , 10) and
- vga_y < conv_std_logic_vector((VGA_H + V_FP + V_SP) , 10)) then
- v_sync_n <= '0';
- else
- v_sync_n <= '1';
- end if;
-
- if (vga_y <=conv_std_logic_vector((VGA_H) , 10)) then
- if (vga_x < conv_std_logic_vector((VGA_W) , 10)) then
- r<= dram_col(11 downto 8);
- g<= dram_col(7 downto 4);
- b<= dram_col(3 downto 0);\r
- else
- r<=(others => '0');
- g<=(others => '0');
- b<=(others => '0');
- end if;
- else
- r<=(others => '0');
- g<=(others => '0');
- b<=(others => '0');
- end if;\r
-
+ emu_ppu_clk <= '0';\r
+ count5_res_n <= '0';\r
+ elsif (rising_edge(vga_clk)) then\r
if (vga_x = conv_std_logic_vector(VGA_W_MAX, 10)) then\r
count5_res_n <= '0';\r
elsif (count5 = "100") then\r
count5_res_n <= '1';\r
end if;\r
\r
- end if;
- end process;
-
-end rtl;
-
+ if (count5 = "001" or count5 = "011") then\r
+ emu_ppu_clk <= '0';\r
+ else\r
+ emu_ppu_clk <= '1';\r
+ end if;\r
+ end if;\r
+ end process;\r
+\r
+ emu_ppu_clk_n <= not emu_ppu_clk;\r
+ vga_render_inst : ppu_vga_render\r
+ port map (\r
+ dbg_vga_clk ,\r
+ dbg_nes_x ,\r
+ dbg_disp_nt, dbg_disp_attr ,\r
+ dbg_disp_ptn_h, dbg_disp_ptn_l ,\r
+ dbg_plt_ce_rn_wn ,\r
+ dbg_plt_addr ,\r
+ dbg_plt_data ,\r
+ dbg_p_oam_ce_rn_wn ,\r
+ dbg_p_oam_addr ,\r
+ dbg_p_oam_data ,\r
+ dbg_s_oam_ce_rn_wn ,\r
+ dbg_s_oam_addr ,\r
+ dbg_s_oam_data ,\r
+ \r
+ emu_ppu_clk_n ,\r
+ mem_clk ,\r
+ rst_n ,\r
+ rd_n ,\r
+ wr_n ,\r
+ ale ,\r
+ vram_ad ,\r
+ vram_a ,\r
+ nes_x ,\r
+ nes_y ,\r
+ r ,\r
+ g ,\r
+ b ,\r
+ ppu_ctrl ,\r
+ ppu_mask ,\r
+ read_status ,\r
+ ppu_status ,\r
+ ppu_scroll_x ,\r
+ ppu_scroll_y ,\r
+ r_nw ,\r
+ oam_bus_ce_n ,\r
+ plt_bus_ce_n ,\r
+ oam_plt_addr ,\r
+ oam_plt_data ,\r
+ v_bus_busy_n \r
+ );\r
+\r
+end rtl;\r
\r
\r
--------------------------------------------------------------\r
--------------------------------------------------------------\r
------------------ Dummy PPU image generator -----------------\r
--------------------------------------------------------------\r
--------------------------------------------------------------\r
\r
+---------------------------------------------------------------\r
+---------------------------------------------------------------\r
+------------------------ PPU VGA Renderer ---------------------\r
+---------------------------------------------------------------\r
+---------------------------------------------------------------\r
\r
library ieee;\r
use ieee.std_logic_1164.all;\r
-use ieee.std_logic_unsigned.all;\r
use ieee.std_logic_arith.conv_std_logic_vector;\r
+use ieee.std_logic_unsigned.all;\r
+use work.motonesfpga_common.all;\r
\r
-entity dummy_ppu is \r
- port ( ppu_clk : in std_logic;\r
+entity ppu_vga_render is \r
+ port ( \r
+ signal dbg_vga_clk : out std_logic;\r
+ signal dbg_nes_x : out std_logic_vector (8 downto 0);\r
+ signal dbg_disp_nt, dbg_disp_attr : out std_logic_vector (7 downto 0);\r
+ signal dbg_disp_ptn_h, dbg_disp_ptn_l : out std_logic_vector (15 downto 0);\r
+ signal dbg_plt_ce_rn_wn : out std_logic_vector (2 downto 0);\r
+ signal dbg_plt_addr : out std_logic_vector (4 downto 0);\r
+ signal dbg_plt_data : out std_logic_vector (7 downto 0);\r
+ signal dbg_p_oam_ce_rn_wn : out std_logic_vector (2 downto 0);\r
+ signal dbg_p_oam_addr : out std_logic_vector (7 downto 0);\r
+ signal dbg_p_oam_data : out std_logic_vector (7 downto 0);\r
+ signal dbg_s_oam_ce_rn_wn : out std_logic_vector (2 downto 0);\r
+ signal dbg_s_oam_addr : out std_logic_vector (4 downto 0);\r
+ signal dbg_s_oam_data : out std_logic_vector (7 downto 0);\r
+ \r
+ vga_clk : in std_logic;\r
+ mem_clk : in std_logic;\r
rst_n : in std_logic;\r
- pos_x : buffer std_logic_vector (8 downto 0);\r
- pos_y : buffer std_logic_vector (8 downto 0);\r
- nes_r : buffer std_logic_vector (3 downto 0);\r
- nes_g : buffer std_logic_vector (3 downto 0);\r
- nes_b : buffer std_logic_vector (3 downto 0)\r
- );\r
-end dummy_ppu;\r
\r
+ rd_n : out std_logic;\r
+ wr_n : out std_logic;\r
+ ale : out std_logic;\r
+ vram_ad : inout std_logic_vector (7 downto 0);\r
+ vram_a : out std_logic_vector (13 downto 8);\r
\r
-architecture rtl of dummy_ppu is\r
+ --current drawing position 340 x 261\r
+ cur_x : in std_logic_vector (8 downto 0);\r
+ cur_y : in std_logic_vector (8 downto 0);\r
+ r : out std_logic_vector (3 downto 0);\r
+ g : out std_logic_vector (3 downto 0);\r
+ b : out std_logic_vector (3 downto 0);\r
+\r
+ ppu_ctrl : in std_logic_vector (7 downto 0);\r
+ ppu_mask : in std_logic_vector (7 downto 0);\r
+ read_status : in std_logic;\r
+ ppu_status : out std_logic_vector (7 downto 0);\r
+ ppu_scroll_x : in std_logic_vector (7 downto 0);\r
+ ppu_scroll_y : in std_logic_vector (7 downto 0);\r
+\r
+ r_nw : in std_logic;\r
+ oam_bus_ce_n : in std_logic;\r
+ plt_bus_ce_n : in std_logic;\r
+ oam_plt_addr : in std_logic_vector (7 downto 0);\r
+ oam_plt_data : inout std_logic_vector (7 downto 0);\r
+ v_bus_busy_n : out std_logic\r
+ );\r
+end ppu_vga_render;\r
+\r
+architecture rtl of ppu_vga_render is\r
\r
component counter_register\r
generic (\r
);\r
end component;\r
\r
-signal x_res_n, y_res_n, y_en_n : std_logic;\r
-signal cnt_clk : std_logic;\r
-signal frame_en_n : std_logic;\r
+component shift_register\r
+ generic (\r
+ dsize : integer := 8;\r
+ shift : integer := 1\r
+ );\r
+ port ( clk : in std_logic;\r
+ rst_n : in std_logic;\r
+ ce_n : in std_logic;\r
+ we_n : in std_logic;\r
+ d : in std_logic_vector(dsize - 1 downto 0);\r
+ q : out std_logic_vector(dsize - 1 downto 0)\r
+ );\r
+end component;\r
+\r
+component d_flip_flop\r
+ generic (\r
+ dsize : integer := 8\r
+ );\r
+ port ( \r
+ clk : in std_logic;\r
+ res_n : in std_logic;\r
+ set_n : in std_logic;\r
+ we_n : in std_logic;\r
+ d : in std_logic_vector (dsize - 1 downto 0);\r
+ q : out std_logic_vector (dsize - 1 downto 0)\r
+ );\r
+end component;\r
+\r
+component tri_state_buffer\r
+ generic (\r
+ dsize : integer := 8\r
+ );\r
+ port ( \r
+ oe_n : in std_logic;\r
+ d : in std_logic_vector (dsize - 1 downto 0);\r
+ q : out std_logic_vector (dsize - 1 downto 0)\r
+ );\r
+end component;\r
+\r
+component ram\r
+ generic (abus_size : integer := 16; dbus_size : integer := 8);\r
+ port ( \r
+ clk : in std_logic;\r
+ ce_n, oe_n, we_n : in std_logic; --select pin active low.\r
+ addr : in std_logic_vector (abus_size - 1 downto 0);\r
+ d_io : inout std_logic_vector (dbus_size - 1 downto 0)\r
+ );\r
+end component;\r
+\r
+component palette_ram\r
+ generic (abus_size : integer := 16; dbus_size : integer := 8);\r
+ port ( \r
+ clk : in std_logic;\r
+ ce_n, oe_n, we_n : in std_logic; --select pin active low.\r
+ addr : in std_logic_vector (abus_size - 1 downto 0);\r
+ d_io : inout std_logic_vector (dbus_size - 1 downto 0)\r
+ );\r
+end component;\r
+\r
+component ram_ctrl\r
+ port ( \r
+ clk : in std_logic;\r
+ ce_n, oe_n, we_n : in std_logic;\r
+ sync_ce_n : out std_logic\r
+ );\r
+end component;\r
+\r
+--nes screen size is emulated to align with the vga timing...\r
+constant X_SIZE : integer := 9;\r
+constant dsize : integer := 8;\r
+constant asize : integer := 14;\r
+--constant HSCAN_MAX : integer := 341;\r
+constant HSCAN_MAX : integer := 321;\r
+constant VSCAN_MAX : integer := 262;\r
+constant HSCAN : integer := 257;\r
+constant VSCAN : integer := 240;\r
+--constant HSCAN_NEXT_START : integer := 320;\r
+--constant HSCAN_NEXT_EXTRA : integer := 336;\r
+constant HSCAN_NEXT_START : integer := 300;\r
+constant HSCAN_NEXT_EXTRA : integer := 316;\r
+\r
+\r
+constant PPUBNA : integer := 1; --base name address\r
+constant PPUVAI : integer := 2; --vram address increment\r
+constant PPUSPA : integer := 3; --sprite pattern table address\r
+constant PPUBPA : integer := 4; --background pattern table address\r
+constant PPUSPS : integer := 5; --sprite size\r
+constant PPUMS : integer := 6; --ppu master/slave\r
+constant PPUNEN : integer := 7; --nmi enable\r
+\r
+constant PPUGS : integer := 0; --grayscale\r
+constant PPUSBL : integer := 1; --show 8 left most bg pixel\r
+constant PPUSSL : integer := 2; --show 8 left most sprite pixel\r
+constant PPUSBG : integer := 3; --show bg\r
+constant PPUSSP : integer := 4; --show sprie\r
+constant PPUIR : integer := 5; --intensify red\r
+constant PPUIG : integer := 6; --intensify green\r
+constant PPUIB : integer := 7; --intensify blue\r
+\r
+constant SPRHFL : integer := 6; --flip sprigte horizontally\r
+constant SPRVFL : integer := 7; --flip sprigte vertically\r
+\r
+constant ST_SOF : integer := 5; --sprite overflow\r
+constant ST_SP0 : integer := 6; --sprite 0 hits\r
+constant ST_VBL : integer := 7; --vblank\r
+\r
+subtype nes_color_data is std_logic_vector (11 downto 0);\r
+type nes_color_array is array (0 to 63) of nes_color_data;\r
+--ref: http://hlc6502.web.fc2.com/NesPal2.htm\r
+constant nes_color_palette : nes_color_array := (\r
+ conv_std_logic_vector(16#777#, 12), \r
+ conv_std_logic_vector(16#20b#, 12), \r
+ conv_std_logic_vector(16#20b#, 12), \r
+ conv_std_logic_vector(16#61a#, 12), \r
+ conv_std_logic_vector(16#927#, 12), \r
+ conv_std_logic_vector(16#b13#, 12), \r
+ conv_std_logic_vector(16#a30#, 12), \r
+ conv_std_logic_vector(16#740#, 12), \r
+ conv_std_logic_vector(16#450#, 12), \r
+ conv_std_logic_vector(16#360#, 12), \r
+ conv_std_logic_vector(16#360#, 12), \r
+ conv_std_logic_vector(16#364#, 12), \r
+ conv_std_logic_vector(16#358#, 12), \r
+ conv_std_logic_vector(16#000#, 12), \r
+ conv_std_logic_vector(16#000#, 12), \r
+ conv_std_logic_vector(16#000#, 12),\r
+ conv_std_logic_vector(16#bbb#, 12), \r
+ conv_std_logic_vector(16#46f#, 12), \r
+ conv_std_logic_vector(16#44f#, 12), \r
+ conv_std_logic_vector(16#94f#, 12), \r
+ conv_std_logic_vector(16#d4c#, 12), \r
+ conv_std_logic_vector(16#d46#, 12), \r
+ conv_std_logic_vector(16#e50#, 12), \r
+ conv_std_logic_vector(16#c70#, 12), \r
+ conv_std_logic_vector(16#880#, 12), \r
+ conv_std_logic_vector(16#5a0#, 12), \r
+ conv_std_logic_vector(16#4a1#, 12), \r
+ conv_std_logic_vector(16#4a6#, 12), \r
+ conv_std_logic_vector(16#49c#, 12), \r
+ conv_std_logic_vector(16#000#, 12), \r
+ conv_std_logic_vector(16#000#, 12), \r
+ conv_std_logic_vector(16#000#, 12),\r
+ conv_std_logic_vector(16#fff#, 12), \r
+ conv_std_logic_vector(16#6af#, 12), \r
+ conv_std_logic_vector(16#58f#, 12), \r
+ conv_std_logic_vector(16#a7f#, 12), \r
+ conv_std_logic_vector(16#f6f#, 12), \r
+ conv_std_logic_vector(16#f6b#, 12), \r
+ conv_std_logic_vector(16#f73#, 12), \r
+ conv_std_logic_vector(16#fa0#, 12), \r
+ conv_std_logic_vector(16#ed2#, 12), \r
+ conv_std_logic_vector(16#9e0#, 12), \r
+ conv_std_logic_vector(16#7f4#, 12), \r
+ conv_std_logic_vector(16#7e9#, 12), \r
+ conv_std_logic_vector(16#6de#, 12), \r
+ conv_std_logic_vector(16#777#, 12), \r
+ conv_std_logic_vector(16#000#, 12), \r
+ conv_std_logic_vector(16#000#, 12),\r
+ conv_std_logic_vector(16#fff#, 12), \r
+ conv_std_logic_vector(16#9df#, 12), \r
+ conv_std_logic_vector(16#abf#, 12), \r
+ conv_std_logic_vector(16#cbf#, 12), \r
+ conv_std_logic_vector(16#ebf#, 12), \r
+ conv_std_logic_vector(16#fbe#, 12), \r
+ conv_std_logic_vector(16#fcb#, 12), \r
+ conv_std_logic_vector(16#fda#, 12), \r
+ conv_std_logic_vector(16#ff9#, 12), \r
+ conv_std_logic_vector(16#cf8#, 12), \r
+ conv_std_logic_vector(16#afa#, 12), \r
+ conv_std_logic_vector(16#afc#, 12), \r
+ conv_std_logic_vector(16#aff#, 12), \r
+ conv_std_logic_vector(16#aaa#, 12), \r
+ conv_std_logic_vector(16#000#, 12), \r
+ conv_std_logic_vector(16#000#, 12)\r
+ );\r
+\r
+signal vga_clk_n : std_logic;\r
+\r
+--timing adjust\r
+signal bg_io_cnt : std_logic_vector(0 downto 0);\r
+signal spr_io_cnt : std_logic_vector(0 downto 0);\r
+\r
+--vram i/o\r
+signal io_oe_n : std_logic;\r
+signal ah_oe_n : std_logic;\r
+\r
+signal cnt_x_res_n : std_logic;\r
+signal bg_cnt_res_n : std_logic;\r
+\r
+--bg prefetch position (scroll + 16 cycle ahead of current pos)\r
+--511 x 239 (or 255 x 479)\r
+signal prf_x : std_logic_vector(X_SIZE - 1 downto 0);\r
+signal prf_y : std_logic_vector(X_SIZE - 1 downto 0);\r
+\r
+signal nt_we_n : std_logic;\r
+signal disp_nt : std_logic_vector (dsize - 1 downto 0);\r
+\r
+signal attr_ce_n : std_logic;\r
+signal attr_we_n : std_logic;\r
+signal attr_val : std_logic_vector (dsize - 1 downto 0);\r
+signal disp_attr_we_n : std_logic;\r
+signal disp_attr : std_logic_vector (dsize - 1 downto 0);\r
+\r
+signal ptn_l_we_n : std_logic;\r
+signal ptn_l_in : std_logic_vector (dsize - 1 downto 0);\r
+signal ptn_l_val : std_logic_vector (dsize - 1 downto 0);\r
+signal disp_ptn_l_in : std_logic_vector (dsize * 2 - 1 downto 0);\r
+signal disp_ptn_l : std_logic_vector (dsize * 2 - 1 downto 0);\r
+\r
+signal ptn_h_we_n : std_logic;\r
+signal ptn_h_in : std_logic_vector (dsize * 2 - 1 downto 0);\r
+signal disp_ptn_h : std_logic_vector (dsize * 2 - 1 downto 0);\r
\r
+--signals for palette / oam access from cpu\r
+signal r_n : std_logic;\r
+signal vram_addr : std_logic_vector (asize - 1 downto 0);\r
+\r
+--palette\r
+signal plt_ram_ce_n_in : std_logic;\r
+signal plt_ram_ce_n : std_logic;\r
+signal plt_r_n : std_logic;\r
+signal plt_w_n : std_logic;\r
+signal plt_addr : std_logic_vector (4 downto 0);\r
+signal plt_data : std_logic_vector (dsize - 1 downto 0);\r
+\r
+--primari / secondary oam\r
+signal p_oam_ram_ce_n_in : std_logic;\r
+signal p_oam_ram_ce_n : std_logic;\r
+signal p_oam_r_n : std_logic;\r
+signal p_oam_w_n : std_logic;\r
+signal p_oam_addr : std_logic_vector (dsize - 1 downto 0);\r
+signal p_oam_data : std_logic_vector (dsize - 1 downto 0);\r
+\r
+signal s_oam_ram_ce_n_in : std_logic;\r
+signal s_oam_ram_ce_n : std_logic;\r
+signal s_oam_r_n : std_logic;\r
+signal s_oam_w_n : std_logic;\r
+signal s_oam_addr_cpy_ce_n : std_logic;\r
+signal s_oam_addr_cpy_n : std_logic;\r
+signal s_oam_addr : std_logic_vector (4 downto 0);\r
+signal s_oam_addr_cpy : std_logic_vector (4 downto 0);\r
+signal s_oam_data : std_logic_vector (dsize - 1 downto 0);\r
+\r
+signal p_oam_cnt_res_n : std_logic;\r
+signal p_oam_cnt_ce_n : std_logic;\r
+signal p_oam_cnt_wrap_n : std_logic;\r
+signal p_oam_cnt : std_logic_vector (dsize - 1 downto 0);\r
+signal p_oam_addr_in : std_logic_vector (dsize - 1 downto 0);\r
+signal oam_ev_status : std_logic_vector (2 downto 0);\r
+\r
+signal s_oam_cnt_ce_n : std_logic;\r
+signal s_oam_cnt : std_logic_vector (4 downto 0);\r
+\r
+--oam evaluation status\r
+constant EV_STAT_COMP : std_logic_vector (2 downto 0) := "000";\r
+constant EV_STAT_CP1 : std_logic_vector (2 downto 0) := "001";\r
+constant EV_STAT_CP2 : std_logic_vector (2 downto 0) := "010";\r
+constant EV_STAT_CP3 : std_logic_vector (2 downto 0) := "011";\r
+constant EV_STAT_PRE_COMP : std_logic_vector (2 downto 0) := "100";\r
+\r
+----------sprite registers.\r
+type oam_pin_array is array (0 to 7) of std_logic;\r
+type oam_reg_array is array (0 to 7) of std_logic_vector (dsize - 1 downto 0);\r
+\r
+signal spr_x_we_n : oam_pin_array;\r
+signal spr_x_ce_n : oam_pin_array;\r
+signal spr_attr_we_n : oam_pin_array;\r
+signal spr_ptn_l_we_n : oam_pin_array;\r
+signal spr_ptn_h_we_n : oam_pin_array;\r
+signal spr_ptn_ce_n : oam_pin_array;\r
+\r
+signal spr_x_cnt : oam_reg_array;\r
+signal spr_attr : oam_reg_array;\r
+signal spr_ptn_l : oam_reg_array;\r
+signal spr_ptn_h : oam_reg_array;\r
+\r
+signal spr_y_we_n : std_logic;\r
+signal spr_tile_we_n : std_logic;\r
+signal spr_y_tmp : std_logic_vector (dsize - 1 downto 0);\r
+signal spr_tile_tmp : std_logic_vector (dsize - 1 downto 0);\r
+signal spr_ptn_in : std_logic_vector (dsize - 1 downto 0);\r
\r
-signal frame_cnt : std_logic_vector(7 downto 0);\r
\r
begin\r
+ dbg_vga_clk <= vga_clk;\r
+ dbg_nes_x <= cur_x;\r
+ dbg_disp_nt <= disp_nt;\r
+ dbg_disp_attr <= disp_attr;\r
+ dbg_disp_ptn_h <= disp_ptn_h;\r
+ dbg_disp_ptn_l <= disp_ptn_l;\r
+ dbg_plt_addr <= plt_addr;\r
+ dbg_plt_data <= plt_data;\r
+ dbg_plt_ce_rn_wn <= plt_ram_ce_n & plt_r_n & plt_w_n;\r
+ dbg_p_oam_ce_rn_wn <= p_oam_ram_ce_n & p_oam_r_n & p_oam_w_n;\r
+ dbg_p_oam_addr <= p_oam_addr;\r
+ dbg_p_oam_data <= p_oam_data;\r
+ dbg_s_oam_ce_rn_wn <= s_oam_ram_ce_n & s_oam_r_n & s_oam_w_n;\r
+ dbg_s_oam_addr <= s_oam_addr;\r
+ dbg_s_oam_data <= p_oam_data;\r
\r
- cnt_clk <= not ppu_clk;\r
- x_inst : counter_register generic map (9, 1)\r
- port map (cnt_clk , x_res_n, '0', '1', (others => '0'), pos_x);\r
- y_inst : counter_register generic map (9, 1)\r
- port map (cnt_clk , y_res_n, y_en_n, '1', (others => '0'), pos_y);\r
\r
- frame_cnt_inst : counter_register generic map (8, 1)\r
- port map (cnt_clk , rst_n, frame_en_n, '1', (others => '0'), frame_cnt);\r
+ vga_clk_n <= not vga_clk;\r
\r
- \r
- p_write : process (rst_n, ppu_clk)\r
+ ale <= bg_io_cnt(0) when ppu_mask(PPUSBG) = '1' and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
+ cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE)) and\r
+ (cur_x <= conv_std_logic_vector(HSCAN, X_SIZE) or\r
+ cur_x > conv_std_logic_vector(HSCAN_NEXT_START, X_SIZE)) else\r
+ spr_io_cnt(0) when ppu_mask(PPUSSP) = '1' and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
+ cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE)) and\r
+ (cur_x > conv_std_logic_vector(256, X_SIZE) and \r
+ cur_x <= conv_std_logic_vector(HSCAN_NEXT_START, X_SIZE)) else\r
+ 'Z';\r
+\r
+ rd_n <= bg_io_cnt(0) when ppu_mask(PPUSBG) = '1' and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
+ cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE)) and\r
+ (cur_x <= conv_std_logic_vector(HSCAN, X_SIZE) or\r
+ cur_x > conv_std_logic_vector(HSCAN_NEXT_START, X_SIZE)) else\r
+ spr_io_cnt(0) when ppu_mask(PPUSSP) = '1' and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
+ cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE)) and\r
+ (cur_x > conv_std_logic_vector(256, X_SIZE) and \r
+ cur_x <= conv_std_logic_vector(HSCAN_NEXT_START, X_SIZE)) else\r
+ 'Z';\r
+ wr_n <= '1' when (ppu_mask(PPUSBG) = '1' or ppu_mask(PPUSSP) = '1') and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
+ cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE)) else\r
+ 'Z';\r
+ io_oe_n <= not bg_io_cnt(0) when ppu_mask(PPUSBG) = '1' and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
+ cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE)) and\r
+ (cur_x <= conv_std_logic_vector(HSCAN, X_SIZE) or\r
+ cur_x > conv_std_logic_vector(HSCAN_NEXT_START, X_SIZE)) else\r
+ not spr_io_cnt(0) when ppu_mask(PPUSSP) = '1' and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
+ cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE)) and\r
+ (cur_x > conv_std_logic_vector(256, X_SIZE) and \r
+ cur_x <= conv_std_logic_vector(HSCAN_NEXT_START, X_SIZE)) else\r
+ '1';\r
+ ah_oe_n <= '0' when (ppu_mask(PPUSBG) = '1' or ppu_mask(PPUSSP) = '1') and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
+ cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE)) else\r
+ '1';\r
+ v_bus_busy_n <= ah_oe_n;\r
+\r
+ bg_io_cnt_inst : counter_register generic map (1, 1)\r
+ port map (vga_clk, bg_cnt_res_n, '0', '1', (others => '0'), bg_io_cnt);\r
+ spr_io_cnt_inst : counter_register generic map (1, 1)\r
+ port map (vga_clk, cnt_x_res_n, '0', '1', (others => '0'), spr_io_cnt);\r
+\r
+ ---bg prefetch x pos is 16 + scroll cycle ahead of current pos.\r
+ prf_x <= cur_x + ppu_scroll_x + "000010000" \r
+ when cur_x < conv_std_logic_vector(HSCAN, X_SIZE) else\r
+ cur_x + ppu_scroll_x + "010111011"; -- +16 -341\r
+\r
+ prf_y <= cur_y + ppu_scroll_y\r
+ when cur_x < conv_std_logic_vector(HSCAN, X_SIZE) and\r
+ cur_y + ppu_scroll_y <\r
+ conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE) else\r
+ cur_y + ppu_scroll_y + "000000001" \r
+ when cur_y + ppu_scroll_y <\r
+ conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE) else\r
+ "000000000"; \r
+\r
+ nt_inst : d_flip_flop generic map(dsize)\r
+ port map (vga_clk_n, rst_n, '1', nt_we_n, vram_ad, disp_nt);\r
+\r
+ at_inst : d_flip_flop generic map(dsize)\r
+ port map (vga_clk_n, rst_n, '1', attr_we_n, vram_ad, attr_val);\r
+\r
+ disp_at_inst : shift_register generic map(dsize, 2)\r
+ port map (vga_clk_n, rst_n, attr_ce_n, disp_attr_we_n, attr_val, disp_attr);\r
+\r
+ --chr rom data's bit is stored in opposite direction.\r
+ --reverse bit when loading...\r
+ ptn_l_in <= (vram_ad(0) & vram_ad(1) & vram_ad(2) & vram_ad(3) & \r
+ vram_ad(4) & vram_ad(5) & vram_ad(6) & vram_ad(7));\r
+ ptn_h_in <= (vram_ad(0) & vram_ad(1) & vram_ad(2) & vram_ad(3) & \r
+ vram_ad(4) & vram_ad(5) & vram_ad(6) & vram_ad(7)) & \r
+ disp_ptn_h (dsize downto 1);\r
+\r
+ ptn_l_inst : d_flip_flop generic map(dsize)\r
+ port map (vga_clk_n, rst_n, '1', ptn_l_we_n, ptn_l_in, ptn_l_val);\r
+\r
+ disp_ptn_l_in <= ptn_l_val & disp_ptn_l (dsize downto 1);\r
+ disp_ptn_l_inst : shift_register generic map(dsize * 2, 1)\r
+ port map (vga_clk_n, rst_n, '0', ptn_h_we_n, disp_ptn_l_in, disp_ptn_l);\r
+\r
+ ptn_h_inst : shift_register generic map(dsize * 2, 1)\r
+ port map (vga_clk_n, rst_n, '0', ptn_h_we_n, ptn_h_in, disp_ptn_h);\r
+\r
+ --vram i/o\r
+ vram_io_buf : tri_state_buffer generic map (dsize)\r
+ port map (io_oe_n, vram_addr(dsize - 1 downto 0), vram_ad);\r
+\r
+ vram_a_buf : tri_state_buffer generic map (6)\r
+ port map (ah_oe_n, vram_addr(asize - 1 downto dsize), vram_a);\r
+\r
+ ---palette ram\r
+ r_n <= not r_nw;\r
+\r
+ plt_ram_ce_n_in <= vga_clk when plt_bus_ce_n = '0' and r_nw = '0' else \r
+ '0' when plt_bus_ce_n = '0' and r_nw = '1' else\r
+ '0' when ppu_mask(PPUSBG) = '1' and \r
+ (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and \r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) else\r
+ '1';\r
+\r
+ plt_addr <= oam_plt_addr(4 downto 0) when plt_bus_ce_n = '0' else\r
+ "1" & spr_attr(0)(1 downto 0) & spr_ptn_h(0)(0) & spr_ptn_l(0)(0)\r
+ when ppu_mask(PPUSSP) = '1' and\r
+ (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) and\r
+ spr_x_cnt(0) = "00000000" and \r
+ (spr_ptn_h(0)(0) or spr_ptn_l(0)(0)) = '1' else\r
+ "1" & spr_attr(1)(1 downto 0) & spr_ptn_h(1)(0) & spr_ptn_l(1)(0)\r
+ when ppu_mask(PPUSSP) = '1' and\r
+ (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) and\r
+ spr_x_cnt(1) = "00000000" and \r
+ (spr_ptn_h(1)(0) or spr_ptn_l(1)(0)) = '1' else\r
+ "1" & spr_attr(2)(1 downto 0) & spr_ptn_h(2)(0) & spr_ptn_l(2)(0)\r
+ when ppu_mask(PPUSSP) = '1' and \r
+ (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) and\r
+ spr_x_cnt(2) = "00000000" and\r
+ (spr_ptn_h(2)(0) or spr_ptn_l(2)(0)) = '1' else\r
+ "1" & spr_attr(3)(1 downto 0) & spr_ptn_h(3)(0) & spr_ptn_l(3)(0)\r
+ when ppu_mask(PPUSSP) = '1' and\r
+ (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) and\r
+ spr_x_cnt(3) = "00000000" and\r
+ (spr_ptn_h(3)(0) or spr_ptn_l(3)(0)) = '1' else\r
+ "1" & spr_attr(4)(1 downto 0) & spr_ptn_h(4)(0) & spr_ptn_l(4)(0)\r
+ when ppu_mask(PPUSSP) = '1' and\r
+ (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) and\r
+ spr_x_cnt(4) = "00000000" and\r
+ (spr_ptn_h(4)(0) or spr_ptn_l(4)(0)) = '1' else\r
+ "1" & spr_attr(5)(1 downto 0) & spr_ptn_h(5)(0) & spr_ptn_l(5)(0)\r
+ when ppu_mask(PPUSSP) = '1' and\r
+ (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) and\r
+ spr_x_cnt(5) = "00000000" and\r
+ (spr_ptn_h(5)(0) or spr_ptn_l(5)(0)) = '1' else\r
+ "1" & spr_attr(6)(1 downto 0) & spr_ptn_h(6)(0) & spr_ptn_l(6)(0)\r
+ when ppu_mask(PPUSSP) = '1' and\r
+ (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) and\r
+ spr_x_cnt(6) = "00000000" and\r
+ (spr_ptn_h(6)(0) or spr_ptn_l(6)(0)) = '1' else\r
+ "1" & spr_attr(7)(1 downto 0) & spr_ptn_h(7)(0) & spr_ptn_l(7)(0)\r
+ when ppu_mask(PPUSSP) = '1' and\r
+ (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) and\r
+ spr_x_cnt(7) = "00000000" and\r
+ (spr_ptn_h(7)(0) or spr_ptn_l(7)(0)) = '1' else\r
+ "0" & disp_attr(1 downto 0) & disp_ptn_h(0) & disp_ptn_l(0) \r
+ when ppu_mask(PPUSBG) = '1' and cur_y(4) = '0' and\r
+ ((disp_ptn_h(0) or disp_ptn_l(0)) = '1') and\r
+ (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) else\r
+ "0" & disp_attr(5 downto 4) & disp_ptn_h(0) & disp_ptn_l(0)\r
+ when ppu_mask(PPUSBG) = '1' and cur_y(4) = '1' and\r
+ ((disp_ptn_h(0) or disp_ptn_l(0)) = '1') and\r
+ (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) else\r
+ ---else: no output color >> universal bg color output.\r
+ --0x3f00 is the universal bg palette.\r
+ (others => '0'); \r
+\r
+ plt_r_n <= not r_nw when plt_bus_ce_n = '0' else\r
+ '0' when ppu_mask(PPUSBG) = '1' else\r
+ '1';\r
+ plt_w_n <= r_nw when plt_bus_ce_n = '0' else\r
+ '1';\r
+ plt_d_buf_w : tri_state_buffer generic map (dsize)\r
+ port map (plt_w_n, oam_plt_data, plt_data);\r
+ plt_d_buf_r : tri_state_buffer generic map (dsize)\r
+ port map (plt_r_n, plt_data, oam_plt_data);\r
+ plt_ram_ctl : ram_ctrl\r
+ port map (mem_clk, plt_ram_ce_n_in, plt_r_n, plt_w_n, plt_ram_ce_n);\r
+ palette_inst : palette_ram generic map (5, dsize)\r
+ port map (mem_clk, plt_ram_ce_n, plt_r_n, plt_w_n, plt_addr, plt_data);\r
+\r
+ ---primary oam\r
+ p_oam_ram_ce_n_in <= vga_clk when oam_bus_ce_n = '0' and r_nw = '0' else\r
+ '0' when oam_bus_ce_n = '0' and r_nw = '1' else\r
+ '0' when ppu_mask(PPUSSP) = '1' and\r
+ cur_x > conv_std_logic_vector(64, X_SIZE) and\r
+ cur_x <= conv_std_logic_vector(256, X_SIZE) and\r
+ p_oam_cnt_wrap_n = '1' else\r
+ '1';\r
+ p_oam_addr <= oam_plt_addr when oam_bus_ce_n = '0' else\r
+ p_oam_addr_in when ppu_mask(PPUSSP) = '1' and \r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
+ cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE)) and\r
+ cur_x > conv_std_logic_vector(64, X_SIZE) and \r
+ cur_x <= conv_std_logic_vector(256, X_SIZE) else\r
+ (others => 'Z');\r
+ p_oam_r_n <= not r_nw when oam_bus_ce_n = '0' else\r
+ '0' when ppu_mask(PPUSSP) = '1' and \r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
+ cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE)) and\r
+ cur_x > conv_std_logic_vector(64, X_SIZE) and \r
+ cur_x <= conv_std_logic_vector(256, X_SIZE) else\r
+ '1';\r
+ p_oam_w_n <= r_nw when oam_bus_ce_n = '0' else\r
+ '1';\r
+ oam_d_buf_w : tri_state_buffer generic map (dsize)\r
+ port map (p_oam_w_n, oam_plt_data, p_oam_data);\r
+ oam_d_buf_r : tri_state_buffer generic map (dsize)\r
+ port map (p_oam_r_n, p_oam_data, oam_plt_data);\r
+\r
+ p_oam_ram_ctl : ram_ctrl\r
+ port map (mem_clk, p_oam_ram_ce_n_in, p_oam_r_n, p_oam_w_n, p_oam_ram_ce_n);\r
+ primary_oam_inst : ram generic map (dsize, dsize)\r
+ port map (mem_clk, p_oam_ram_ce_n, p_oam_r_n, p_oam_w_n, p_oam_addr, p_oam_data);\r
+\r
+ ---secondary oam\r
+ p_oam_cnt_inst : counter_register generic map (dsize, 4)\r
+ port map (vga_clk_n, p_oam_cnt_res_n, p_oam_cnt_ce_n, '1', (others => '0'), p_oam_cnt);\r
+ s_oam_cnt_inst : counter_register generic map (5, 1)\r
+ port map (vga_clk_n, p_oam_cnt_res_n, s_oam_cnt_ce_n, '1', (others => '0'), s_oam_cnt);\r
+ s_oam_addr_cpy_inst : counter_register generic map (5, 1)\r
+ port map (vga_clk_n, p_oam_cnt_res_n, s_oam_addr_cpy_ce_n, \r
+ '1', (others => '0'), s_oam_addr_cpy);\r
+\r
+ s_oam_ram_ce_n_in <= vga_clk when ppu_mask(PPUSSP) = '1' and cur_x(0) = '1' and\r
+ cur_x > "000000001" and\r
+ cur_x <= conv_std_logic_vector(64, X_SIZE) else\r
+ vga_clk when ppu_mask(PPUSSP) = '1' and cur_x(0) = '1' and\r
+ cur_x > conv_std_logic_vector(64, X_SIZE) and\r
+ cur_x <= conv_std_logic_vector(256, X_SIZE) and\r
+ p_oam_cnt_wrap_n = '1' else\r
+ '0' when ppu_mask(PPUSSP) = '1' and\r
+ cur_x > conv_std_logic_vector(256, X_SIZE) and\r
+ cur_x <= conv_std_logic_vector(320, X_SIZE) and\r
+ s_oam_addr_cpy_n = '0' else\r
+ '1';\r
+\r
+ s_oam_ram_ctl : ram_ctrl\r
+ port map (mem_clk, s_oam_ram_ce_n_in, s_oam_r_n, s_oam_w_n, s_oam_ram_ce_n);\r
+ secondary_oam_inst : ram generic map (5, dsize)\r
+ port map (mem_clk, s_oam_ram_ce_n, s_oam_r_n, s_oam_w_n, s_oam_addr, s_oam_data);\r
+\r
+ spr_y_inst : d_flip_flop generic map(dsize)\r
+ port map (vga_clk_n, p_oam_cnt_res_n, '1', spr_y_we_n, s_oam_data, spr_y_tmp);\r
+ spr_tile_inst : d_flip_flop generic map(dsize)\r
+ port map (vga_clk_n, p_oam_cnt_res_n, '1', spr_tile_we_n, s_oam_data, spr_tile_tmp);\r
+\r
+\r
+ --reverse bit when NOT SPRHFL is set (.nes file format bit endian).\r
+ spr_ptn_in <= vram_ad when spr_attr(conv_integer(s_oam_addr_cpy(4 downto 2)))(SPRHFL) = '1' else\r
+ (vram_ad(0) & vram_ad(1) & vram_ad(2) & vram_ad(3) & \r
+ vram_ad(4) & vram_ad(5) & vram_ad(6) & vram_ad(7));\r
+ --array instances...\r
+ spr_inst : for i in 0 to 7 generate\r
+ spr_x_inst : counter_register generic map(dsize, 16#ff#)\r
+ port map (vga_clk_n, rst_n, spr_x_ce_n(i), spr_x_we_n(i), s_oam_data, spr_x_cnt(i));\r
+\r
+ spr_attr_inst : d_flip_flop generic map(dsize)\r
+ port map (vga_clk_n, rst_n, '1', spr_attr_we_n(i), s_oam_data, spr_attr(i));\r
+\r
+ spr_ptn_l_inst : shift_register generic map(dsize, 1)\r
+ port map (vga_clk_n, rst_n, spr_ptn_ce_n(i), spr_ptn_l_we_n(i), spr_ptn_in, spr_ptn_l(i));\r
+\r
+ spr_ptn_h_inst : shift_register generic map(dsize, 1)\r
+ port map (vga_clk_n, rst_n, spr_ptn_ce_n(i), spr_ptn_h_we_n(i), spr_ptn_in, spr_ptn_h(i));\r
+ end generate;\r
+\r
+ pos_p : process (rst_n, vga_clk)\r
begin\r
if (rst_n = '0') then\r
- x_res_n <= '0';\r
- y_res_n <= '0';\r
- frame_en_n <= '1';\r
- nes_r <= (others => '0');\r
- nes_g <= (others => '0');\r
- nes_b <= (others => '0');\r
- elsif (rising_edge(ppu_clk)) then\r
- --xmax = 340\r
- if (pos_x = conv_std_logic_vector(340, 9)) then\r
- x_res_n <= '0';\r
- y_en_n <= '0';\r
- --ymax=261\r
- if (pos_y = conv_std_logic_vector(261, 9)) then\r
- y_res_n <= '0';\r
- frame_en_n <= '0';\r
- else\r
- frame_en_n <= '1';\r
- y_res_n <= '1';\r
- end if;\r
+ cnt_x_res_n <= '0';\r
+ bg_cnt_res_n <= '0';\r
+ elsif (vga_clk'event and vga_clk = '0') then\r
+ if (cur_x = conv_std_logic_vector(HSCAN_MAX - 1, X_SIZE)) then\r
+ --x pos reset.\r
+ cnt_x_res_n <= '0';\r
else\r
- frame_en_n <= '1';\r
- x_res_n <= '1';\r
- y_en_n <= '1';\r
- y_res_n <= '1';\r
+ cnt_x_res_n <= '1';\r
end if;\r
- \r
- nes_b <= pos_x(3 downto 0);\r
- nes_g <= pos_x(7 downto 4);\r
- if (pos_x <= conv_std_logic_vector(64, 9)) then\r
- nes_r <= "1111";\r
- elsif (pos_x <= conv_std_logic_vector(128, 9)) then\r
- nes_r <= "0000";\r
- elsif (pos_x <= conv_std_logic_vector(192, 9)) then\r
- nes_r <= "1010";\r
+\r
+ if (ppu_scroll_x(0) = '0' and cur_x = conv_std_logic_vector(HSCAN, X_SIZE)) then\r
+ bg_cnt_res_n <= '0';\r
+ elsif (ppu_scroll_x(0) = '1' and cur_x = conv_std_logic_vector(HSCAN - 1, X_SIZE)) then\r
+ bg_cnt_res_n <= '0';\r
else\r
- nes_r <= "0101";\r
+ bg_cnt_res_n <= '1';\r
end if;\r
- \r
- end if;\r
+ end if; --if (rst_n = '0') then\r
end process;\r
+\r
+ clk_p : process (rst_n, vga_clk, read_status)\r
+\r
+procedure output_rgb is\r
+variable pl_addr : integer;\r
+variable pl_index : integer;\r
+variable dot_output : boolean;\r
+begin\r
+ dot_output := false;\r
+\r
+ --first show sprite.\r
+ if (ppu_mask(PPUSSP) = '1') then\r
+ for i in 0 to 7 loop\r
+ if (spr_x_cnt(i) = "00000000") then\r
+ if ((spr_ptn_h(i)(0) or spr_ptn_l(i)(0)) = '1') then\r
+ dot_output := true;\r
+ exit;\r
+ end if;\r
+ end if;\r
+ end loop;\r
+ end if;\r
+\r
+ if (dot_output = true and ppu_mask(PPUSBG) = '1' and \r
+ (disp_ptn_h(0) or disp_ptn_l(0)) = '1') then\r
+ --raise sprite 0 hit.\r
+ ppu_status(ST_SP0) <= '1';\r
+ end if;\r
+\r
+ --first color in the palette is transparent color.\r
+ if (ppu_mask(PPUSBG) = '1' and dot_output = false and \r
+ (disp_ptn_h(0) or disp_ptn_l(0)) = '1') then\r
+ dot_output := true;\r
+-- d_print("output_rgb");\r
+-- d_print("pl_addr:" & conv_hex8(pl_addr));\r
+-- d_print("pl_index:" & conv_hex8(pl_index));\r
+ end if;\r
+\r
+ --if or if not bg/sprite is shown, output color anyway \r
+ --sinse universal bg color is included..\r
+ pl_index := conv_integer(plt_data(5 downto 0));\r
+ b <= nes_color_palette(pl_index) (11 downto 8);\r
+ g <= nes_color_palette(pl_index) (7 downto 4);\r
+ r <= nes_color_palette(pl_index) (3 downto 0);\r
+-- b <= nes_color_palette(1) (11 downto 8);\r
+-- g <= nes_color_palette(2) (7 downto 4);\r
+-- r <= nes_color_palette(3) (3 downto 0);\r
+end;\r
+procedure stop_rgb is\r
+begin\r
+ b <= (others => '0');\r
+ g <= (others => '0');\r
+ r <= (others => '0');\r
+end;\r
+\r
+ begin\r
+ if (rst_n = '0') then\r
+ nt_we_n <= '1';\r
+ ppu_status <= (others => '0');\r
+ s_oam_data <= (others => 'Z');\r
+ stop_rgb;\r
+ else\r
+\r
+ if (vga_clk'event and vga_clk = '1') then\r
+\r
+ --fetch bg pattern and display.\r
+ if (ppu_mask(PPUSBG) = '1' and \r
+ (cur_x <= conv_std_logic_vector(HSCAN, X_SIZE) or\r
+ cur_x > conv_std_logic_vector(HSCAN_NEXT_START, X_SIZE)) and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
+ cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE))) then\r
+ --visible area bg image\r
+\r
+ d_print("*");\r
+ d_print("cur_x: " & conv_hex16(conv_integer(cur_x)));\r
+ d_print("cur_y: " & conv_hex16(conv_integer(cur_y)));\r
+\r
+ ----fetch next tile byte.\r
+ if (prf_x (2 downto 0) = "001") then\r
+ --vram addr is incremented every 8 cycle.\r
+ --name table at 0x2000\r
+ vram_addr(9 downto 0) \r
+ <= prf_y(dsize - 1 downto 3) \r
+ & prf_x(dsize - 1 downto 3);\r
+ vram_addr(asize - 1 downto 10) <= "10" & ppu_ctrl(PPUBNA downto 0) \r
+ + ("000" & prf_x(dsize));\r
+ ----fetch attr table byte.\r
+ elsif (prf_x (4 downto 0) = "00011") then\r
+ --attribute table is loaded every 32 cycle.\r
+ --attr table at 0x23c0\r
+ vram_addr(dsize - 1 downto 0) <= "11000000" +\r
+ ("00" & prf_y(7 downto 5) & prf_x(7 downto 5));\r
+ vram_addr(asize - 1 downto dsize) <= "10" &\r
+ ppu_ctrl(PPUBNA downto 0) & "11"\r
+ + ("000" & prf_x(dsize) & "00");\r
+ ----fetch pattern table low byte.\r
+ elsif (prf_x (2 downto 0) = "101") then\r
+ --vram addr is incremented every 8 cycle.\r
+ vram_addr <= "0" & ppu_ctrl(PPUBPA) & \r
+ disp_nt(dsize - 1 downto 0) \r
+ & "0" & prf_y(2 downto 0);\r
+ ----fetch pattern table high byte.\r
+ elsif (prf_x (2 downto 0) = "111") then\r
+ --vram addr is incremented every 8 cycle.\r
+ vram_addr <= "0" & ppu_ctrl(PPUBPA) & \r
+ disp_nt(dsize - 1 downto 0) \r
+ & "0" & prf_y(2 downto 0) + "00000000001000";\r
+ end if;\r
+\r
+ ----fetch next tile byte.\r
+ if (prf_x (2 downto 0) = "010") then\r
+ nt_we_n <= '0';\r
+ else\r
+ nt_we_n <= '1';\r
+ end if;\r
+\r
+ ----fetch attr table byte.\r
+ if (prf_x (4 downto 0) = "00100") then\r
+ attr_we_n <= '0';\r
+ else\r
+ attr_we_n <= '1';\r
+ end if;\r
+ if (prf_x (4 downto 0) = "10000") then\r
+ disp_attr_we_n <= '0';\r
+ else\r
+ disp_attr_we_n <= '1';\r
+ end if;\r
+ ---attribute is shifted every 16 bit.\r
+ if (prf_x (3 downto 0) = "0000") then\r
+ attr_ce_n <= '0';\r
+ else\r
+ attr_ce_n <= '1';\r
+ end if;\r
+\r
+ ----fetch pattern table low byte.\r
+ if (prf_x (2 downto 0) = "110") then\r
+ ptn_l_we_n <= '0';\r
+ else\r
+ ptn_l_we_n <= '1';\r
+ end if;\r
+\r
+ ----fetch pattern table high byte.\r
+ if (prf_x (2 downto 0) = "000") then\r
+ ptn_h_we_n <= '0';\r
+ else\r
+ ptn_h_we_n <= '1';\r
+ end if;\r
+\r
+ end if;--if (ppu_mask(PPUSBG) = '1') and\r
+\r
+ --fetch sprite and display.\r
+ if (ppu_mask(PPUSSP) = '1' and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
+ cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE))) then\r
+ --secondary oam clear\r
+ if (cur_x /= "000000000" and cur_x <= conv_std_logic_vector(64, X_SIZE)) then\r
+ if (cur_x(0) = '0') then\r
+ --write secondary oam on even cycle\r
+ s_oam_r_n <= '1';\r
+ s_oam_w_n <= '0';\r
+ s_oam_addr <= cur_x(5 downto 1);\r
+ s_oam_data <= (others => '1');\r
+ end if;\r
+ p_oam_cnt_res_n <= '0';\r
+ p_oam_cnt_ce_n <= '1';\r
+ s_oam_cnt_ce_n <= '1';\r
+ p_oam_cnt_wrap_n <= '1';\r
+ oam_ev_status <= EV_STAT_COMP;\r
+\r
+ --sprite evaluation and secondary oam copy.\r
+ elsif (cur_x > conv_std_logic_vector(64, X_SIZE) and \r
+ cur_x <= conv_std_logic_vector(256, X_SIZE)) then\r
+ p_oam_cnt_res_n <= '1';\r
+\r
+ --TODO: sprite evaluation is simplified!!\r
+ --not complying the original NES spec at\r
+ --http://wiki.nesdev.com/w/index.php/PPU_sprite_evaluation\r
+ --e.g., when overflow happens, it just ignore subsequent entry.\r
+ --old secondary sprite entry.\r
+ if (p_oam_cnt = "00000000" and cur_x > conv_std_logic_vector(192, X_SIZE)) then\r
+ p_oam_cnt_wrap_n <= '0';\r
+ end if;\r
+\r
+ --odd cycle copy from primary oam\r
+ if (cur_x(0) = '1') then\r
+ if (oam_ev_status = EV_STAT_COMP) then\r
+ p_oam_addr_in <= p_oam_cnt;\r
+ p_oam_cnt_ce_n <= '1';\r
+ s_oam_cnt_ce_n <= '1';\r
+ elsif (oam_ev_status = EV_STAT_CP1) then\r
+ p_oam_addr_in <= p_oam_cnt + "00000001";\r
+ s_oam_cnt_ce_n <= '1';\r
+\r
+ elsif (oam_ev_status = EV_STAT_CP2) then\r
+ p_oam_addr_in <= p_oam_cnt + "00000010";\r
+ s_oam_cnt_ce_n <= '1';\r
+\r
+ elsif (oam_ev_status = EV_STAT_CP3) then\r
+ oam_ev_status <= EV_STAT_PRE_COMP;\r
+ p_oam_addr_in <= p_oam_cnt + "00000011";\r
+ s_oam_cnt_ce_n <= '1';\r
+ end if;\r
+ else\r
+ --even cycle copy to secondary oam (if y is in range.)\r
+ s_oam_r_n <= '1';\r
+ s_oam_w_n <= '0';\r
+ s_oam_addr <= s_oam_cnt;\r
+ s_oam_data <= p_oam_data;\r
+\r
+ if (oam_ev_status = EV_STAT_COMP) then\r
+ --check y range.\r
+ if (cur_y < "000000110" and p_oam_data <= cur_y + "000000001") or \r
+ (cur_y >= "000000110" and p_oam_data <= cur_y + "000000001" and \r
+ p_oam_data >= cur_y - "000000110") then\r
+ oam_ev_status <= EV_STAT_CP1;\r
+ s_oam_cnt_ce_n <= '0';\r
+ --copy remaining oam entry.\r
+ p_oam_cnt_ce_n <= '1';\r
+ else\r
+ --goto next entry\r
+ p_oam_cnt_ce_n <= '0';\r
+ end if;\r
+ elsif (oam_ev_status = EV_STAT_CP1) then\r
+ s_oam_cnt_ce_n <= '0';\r
+ oam_ev_status <= EV_STAT_CP2;\r
+ elsif (oam_ev_status = EV_STAT_CP2) then\r
+ s_oam_cnt_ce_n <= '0';\r
+ oam_ev_status <= EV_STAT_CP3;\r
+ elsif (oam_ev_status = EV_STAT_CP3) then\r
+ s_oam_cnt_ce_n <= '0';\r
+ elsif (oam_ev_status = EV_STAT_PRE_COMP) then\r
+ oam_ev_status <= EV_STAT_COMP;\r
+ s_oam_cnt_ce_n <= '0';\r
+ p_oam_cnt_ce_n <= '0';\r
+ end if;\r
+ end if;--if (cur_x(0) = '1') then\r
+\r
+ --prepare for next step\r
+ s_oam_addr_cpy_n <= '1';\r
+ spr_y_we_n <= '1';\r
+ spr_tile_we_n <= '1';\r
+ spr_x_we_n <= "11111111";\r
+ spr_attr_we_n <= "11111111";\r
+ spr_ptn_l_we_n <= "11111111";\r
+ spr_ptn_h_we_n <= "11111111";\r
+\r
+ --sprite pattern fetch\r
+ elsif (cur_x > conv_std_logic_vector(256, X_SIZE) and \r
+ cur_x <= conv_std_logic_vector(HSCAN_NEXT_START, X_SIZE)) then\r
+\r
+ s_oam_addr_cpy_n <= '0';\r
+ s_oam_r_n <= '0';\r
+ s_oam_w_n <= '1';\r
+ s_oam_addr <= s_oam_addr_cpy;\r
+\r
+ ----fetch y-cordinate from secondary oam\r
+ if (cur_x (2 downto 0) = "001" ) then\r
+ s_oam_addr_cpy_ce_n <= '0';\r
+ spr_y_we_n <= '0';\r
+ else\r
+ spr_y_we_n <= '1';\r
+ end if;\r
+\r
+ ----fetch tile number\r
+ if (cur_x (2 downto 0) = "010" ) then\r
+ spr_tile_we_n <= '0';\r
+ else\r
+ spr_tile_we_n <= '1';\r
+ end if;\r
+\r
+ ----fetch attribute\r
+ if (cur_x (2 downto 0) = "011" ) then\r
+ spr_attr_we_n(conv_integer(s_oam_addr_cpy(4 downto 2))) <= '0';\r
+ else\r
+ spr_attr_we_n(conv_integer(s_oam_addr_cpy(4 downto 2))) <= '1';\r
+ end if;--if (cur_x (2 downto 0) = "010" ) then\r
+\r
+ ----fetch x-cordinate\r
+ if (cur_x (2 downto 0) = "100" ) then\r
+ s_oam_addr_cpy_ce_n <= '1';\r
+ spr_x_we_n(conv_integer(s_oam_addr_cpy(4 downto 2))) <= '0';\r
+ else\r
+ spr_x_we_n(conv_integer(s_oam_addr_cpy(4 downto 2))) <= '1';\r
+ end if;\r
+\r
+ ----fetch pattern table low byte.\r
+ if (cur_x (2 downto 0) = "101" ) then\r
+ if (spr_attr(conv_integer(s_oam_addr_cpy(4 downto 2)))(SPRVFL) = '0') then\r
+ vram_addr <= "0" & ppu_ctrl(PPUSPA) & \r
+ spr_tile_tmp(dsize - 1 downto 0) & "0" & \r
+ (cur_y(2 downto 0) + "001" - spr_y_tmp(2 downto 0));\r
+ else\r
+ --flip sprite vertically.\r
+ vram_addr <= "0" & ppu_ctrl(PPUSPA) & \r
+ spr_tile_tmp(dsize - 1 downto 0) & "0" & \r
+ (spr_y_tmp(2 downto 0) - cur_y(2 downto 0) - "010");\r
+ end if;\r
+ end if;\r
+\r
+ if (cur_x (2 downto 0) = "110" ) then\r
+ spr_ptn_l_we_n(conv_integer(s_oam_addr_cpy(4 downto 2))) <= '0';\r
+ else\r
+ spr_ptn_l_we_n(conv_integer(s_oam_addr_cpy(4 downto 2))) <= '1';\r
+ end if;\r
+\r
+ ----fetch pattern table high byte.\r
+ if (cur_x (2 downto 0) = "111" ) then\r
+ if (spr_attr(conv_integer(s_oam_addr_cpy(4 downto 2)))(SPRVFL) = '0') then\r
+ vram_addr <= "0" & ppu_ctrl(PPUSPA) & \r
+ spr_tile_tmp(dsize - 1 downto 0) & "0" & \r
+ (cur_y(2 downto 0) + "001" - spr_y_tmp(2 downto 0))\r
+ + "00000000001000";\r
+ else\r
+ --flip sprite vertically.\r
+ vram_addr <= "0" & ppu_ctrl(PPUSPA) & \r
+ spr_tile_tmp(dsize - 1 downto 0) & "0" & \r
+ (spr_y_tmp(2 downto 0) - cur_y(2 downto 0) - "010")\r
+ + "00000000001000";\r
+ end if;\r
+ end if;\r
+\r
+ if (cur_x (2 downto 0) = "000") then\r
+ spr_ptn_h_we_n(conv_integer(s_oam_addr_cpy(4 downto 2))) <= '0';\r
+ s_oam_addr_cpy_ce_n <= '0';\r
+ else\r
+ spr_ptn_h_we_n(conv_integer(s_oam_addr_cpy(4 downto 2) - "001")) <= '1';\r
+ end if;\r
+\r
+ elsif (cur_x > conv_std_logic_vector(320, X_SIZE)) then\r
+ --clear last write enable.\r
+ spr_ptn_h_we_n <= "11111111";\r
+ end if;--if (cur_x /= "000000000" and cur_x <= conv_std_logic_vector(64, X_SIZE))\r
+\r
+ --display sprite.\r
+ if ((cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE))) then\r
+ --start counter.\r
+ if (cur_x = "000000000") then\r
+ spr_x_ce_n <= "00000000";\r
+ end if;\r
+\r
+ for i in 0 to 7 loop\r
+ if (spr_x_cnt(i) = "00000000") then\r
+ --active sprite, start shifting..\r
+ spr_x_ce_n(i) <= '1';\r
+ spr_ptn_ce_n(i) <= '0';\r
+ end if;\r
+ end loop;\r
+ else\r
+ spr_x_ce_n <= "11111111";\r
+ spr_ptn_ce_n <= "11111111";\r
+ end if; --if ((cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) \r
+ end if; --if (ppu_mask(PPUSSP) = '1') then\r
+\r
+ --output visible area only.\r
+ if ((cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
+ (cur_y < conv_std_logic_vector(VSCAN, X_SIZE))) then\r
+ --output image.\r
+ output_rgb;\r
+ else\r
+ stop_rgb;\r
+ end if;\r
+\r
+ --flag operation\r
+ if ((cur_x = conv_std_logic_vector(1, X_SIZE)) and\r
+ (cur_y = conv_std_logic_vector(VSCAN + 1, X_SIZE))) then\r
+ --vblank start\r
+ ppu_status(ST_VBL) <= '1';\r
+ elsif ((cur_x = conv_std_logic_vector(1, X_SIZE)) and\r
+ (cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE))) then\r
+ ppu_status(ST_SP0) <= '0';\r
+ --vblank end\r
+ ppu_status(ST_VBL) <= '0';\r
+ --TODO: sprite overflow is not inplemented!\r
+ ppu_status(ST_SOF) <= '0';\r
+ end if;\r
+ end if; --if (clk'event and clk = '1') then\r
+\r
+-- if (read_status'event and read_status = '1') then\r
+-- --reading ppu status clears vblank bit.\r
+-- ppu_status(ST_VBL) <= '0';\r
+-- end if;\r
+\r
+ end if;--if (rst_n = '0') then\r
+ end process;\r
+\r
end rtl;\r
+\r