Skip to content

Commit

Permalink
More accurat INT/NMI in CPU, fixed problem with NTSC-Mode using a Eve…
Browse files Browse the repository at this point in the history
…rDrive N8, more VBL tests working
  • Loading branch information
Feuerwerk committed Apr 9, 2017
1 parent 79f1bc7 commit 809c79c
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 194 deletions.
53 changes: 37 additions & 16 deletions cpu.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -751,7 +751,8 @@ entity cpu is
port
(
i_clk : in std_logic;
i_clk_enable : in std_logic := '1';
i_clk_p_enable : in std_logic := '1';
i_clk_n_enable : in std_logic := '0';
i_ready : in std_logic := '1';
i_reset_n : in std_logic := '1';
i_int_n : in std_logic := '1';
Expand Down Expand Up @@ -811,9 +812,6 @@ architecture behavioral of cpu is
end component;

constant BRK_OPCODE : std_logic_vector(7 downto 0) := x"00";
constant RST_OPCODE : std_logic_vector(7 downto 0) := x"02";
constant INT_OPCODE : std_logic_vector(7 downto 0) := x"03";
constant NMI_OPCODE : std_logic_vector(7 downto 0) := x"04";

type opcode_override_t is (nop, rst, int, nmi);

Expand Down Expand Up @@ -856,9 +854,13 @@ architecture behavioral of cpu is
signal s_ctrl_op : ctrl_op_t;
signal s_alu_a_op : alu_inp_t;
signal s_alu_b_op : alu_inp_t;
signal s_int_active : boolean;
signal s_int_active : boolean := false;
signal s_nmi_active : boolean := false;
signal s_nmi_last : std_logic := '1';
signal s_nmi_trigger : std_logic;
signal s_nmi_delay : std_logic_vector(1 downto 0);
signal s_int_trigger : std_logic;
signal s_int_delay : std_logic_vector(2 downto 0);
signal s_clk_enable : std_logic;
signal s_ready_d : std_logic := '1';
signal s_sync_edge : std_logic;
Expand Down Expand Up @@ -903,7 +905,7 @@ begin

-- Clock Divider & Internal Clock

s_clk_enable <= i_clk_enable and i_ready;
s_clk_enable <= i_clk_p_enable and i_ready;

-- Memory-Access
-- Last read memory value is stored if ready-signal drop to 0 and is available until ready returns to 1
Expand All @@ -913,7 +915,7 @@ begin
if rising_edge(i_clk) then
if i_reset_n = '0' then
s_mem_q_d <= x"00";
elsif (i_clk_enable = '1') and (s_ready_d = '1') then
elsif (i_clk_p_enable = '1') and (s_ready_d = '1') then
s_mem_q_d <= i_mem_q;
end if;
end if;
Expand All @@ -928,7 +930,7 @@ begin
if rising_edge(i_clk) then
if i_reset_n = '0' then
s_ready_d <= '1';
elsif i_clk_enable = '1' then
elsif i_clk_p_enable = '1' then
s_ready_d <= i_ready;
end if;
end if;
Expand Down Expand Up @@ -986,21 +988,40 @@ begin
process (i_clk)
begin
if rising_edge(i_clk) then
if s_clk_enable = '1' then
if i_reset_n = '0' then
if i_reset_n = '0' then
s_nmi_active <= false;
s_nmi_delay <= (others => '0');
s_nmi_active <= false;
s_nmi_last <= '1';
elsif s_clk_enable = '1' then
if (s_opcode_override = nmi) then
s_nmi_active <= false;
elsif (s_nmi_last = '1') and (i_nmi_n = '0') then
end if;
elsif i_clk_n_enable = '1' then
if s_nmi_delay(1) = '1' then
s_nmi_active <= true;
elsif (s_opcode_override = nmi) then
s_nmi_active <= false;
end if;

s_nmi_last <= i_nmi_n;

s_nmi_delay <= s_nmi_delay(0) & s_nmi_trigger;
s_nmi_last <= i_nmi_n;
end if;
end if;
end process;

process (i_clk)
begin
if rising_edge(i_clk) then
if i_reset_n = '0' then
s_int_delay <= (others => '0');
elsif i_clk_n_enable = '1' then
s_int_delay <= s_int_delay(1 downto 0) & s_int_trigger;
end if;
end if;
end process;

s_int_active <= (i_int_n = '0') and (s_flags.i = '0');
s_int_active <= s_int_delay(2) = '1';
s_int_trigger <= not i_int_n and not s_flags.i;
s_nmi_trigger <= s_nmi_last and not i_nmi_n;

-- Cycle

Expand Down
8 changes: 4 additions & 4 deletions nes.qsf
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS ON
# Analysis & Synthesis Assignments
# ================================
set_global_assignment -name FAMILY "Cyclone V"
set_global_assignment -name TOP_LEVEL_ENTITY nestest
set_global_assignment -name TOP_LEVEL_ENTITY nes
set_global_assignment -name VHDL_INPUT_VERSION VHDL_2008
set_global_assignment -name VHDL_SHOW_LMF_MAPPING_MESSAGES OFF
set_global_assignment -name PROJECT_IP_REGENERATION_POLICY ALWAYS_REGENERATE_IP
Expand Down Expand Up @@ -402,9 +402,6 @@ set_global_assignment -name QIP_FILE master_reconfig.qip
set_global_assignment -name SIP_FILE master_reconfig.sip
set_global_assignment -name HEX_FILE test_videorom.hex
set_global_assignment -name HEX_FILE test_progmem.hex
set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
set_instance_assignment -name IO_STANDARD "2.5 V" -to UART_TX
set_instance_assignment -name IO_STANDARD "2.5 V" -to UART_RX
set_instance_assignment -name IO_STANDARD "2.5 V" -to PPU_ADDR[12]
Expand Down Expand Up @@ -610,4 +607,7 @@ set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to GPIO[18]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to GPIO[19]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to GPIO[20]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to GPIO[21]
set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
22 changes: 15 additions & 7 deletions nes.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -578,7 +578,8 @@ architecture behavioral of nescore is
port
(
i_clk : in std_logic;
i_clk_enable : in std_logic := '1';
i_clk_p_enable : in std_logic := '1';
i_clk_n_enable : in std_logic := '0';
i_ready : in std_logic := '1';
i_reset_n : in std_logic := '1';
i_int_n : in std_logic := '1';
Expand Down Expand Up @@ -693,7 +694,8 @@ architecture behavioral of nescore is
);
end component;

signal s_cpu_clk_enable : std_logic;
signal s_cpu_clk_p_enable : std_logic;
signal s_cpu_clk_n_enable : std_logic;
signal s_cpu_sync : std_logic;
signal s_ppu_q : std_logic_vector(7 downto 0);
signal s_ppu_addr : std_logic_vector(2 downto 0);
Expand Down Expand Up @@ -731,6 +733,7 @@ architecture behavioral of nescore is
signal s_prg_latch : std_logic_vector(7 downto 0) := (others => '0');
signal s_cpu_divider : natural range 0 to 31 := 31;
signal s_ppu_divider : natural range 0 to 31 := 31;
signal s_cpu_middle : natural range 0 to 31 := 31;
signal s_cpu_counter : natural range 0 to 31 := 0;
signal s_ppu_counter : natural range 0 to 31 := 0;
signal s_sync_start : natural range 0 to 31 := 0;
Expand All @@ -740,6 +743,7 @@ architecture behavioral of nescore is
signal s_next_sync_start : natural range 0 to 31;
signal s_next_sync_stop : natural range 0 to 31;
signal s_last_cpu_cycle : boolean;
signal s_mid_cpu_cycle : boolean;
signal s_last_ppu_cycle : boolean;
signal s_pio_q : std_logic_vector(7 downto 0);
signal s_pio_addr : std_logic_vector(2 downto 0);
Expand All @@ -750,7 +754,8 @@ begin
cpu_core : cpu port map
(
i_clk => i_clk,
i_clk_enable => s_cpu_clk_enable,
i_clk_p_enable => s_cpu_clk_p_enable,
i_clk_n_enable => s_cpu_clk_n_enable,
i_ready => s_dma_ready and i_ready,
i_reset_n => i_reset_n,
i_nmi_n => s_nmi_n,
Expand Down Expand Up @@ -784,7 +789,7 @@ begin
apu_core : apu port map
(
i_clk => i_clk,
i_clk_enable => s_cpu_clk_enable,
i_clk_enable => s_cpu_clk_p_enable,
i_reset_n => i_reset_n,
i_addr => s_apu_addr,
i_data => s_eff_data,
Expand Down Expand Up @@ -825,7 +830,7 @@ begin
dpath : data_path port map
(
i_clk => i_clk,
i_clk_enable => s_cpu_clk_enable,
i_clk_enable => s_cpu_clk_p_enable,
i_sync => s_cpu_sync,
i_reset_n => i_reset_n,
i_addr => s_eff_addr,
Expand Down Expand Up @@ -880,6 +885,7 @@ begin
if rising_edge(i_clk) then
if (i_reset_n = '0') or (s_last_cpu_cycle and s_last_ppu_cycle) then
s_cpu_divider <= s_next_cpu_divider;
s_cpu_middle <= s_next_cpu_divider / 2;
s_ppu_divider <= s_next_ppu_divider;
s_sync_start <= s_next_sync_start;
s_sync_stop <= s_next_sync_stop;
Expand Down Expand Up @@ -978,9 +984,11 @@ begin
end process;

s_last_cpu_cycle <= s_cpu_counter = s_cpu_divider - 1;
s_mid_cpu_cycle <= s_cpu_counter = s_cpu_middle - 1;
s_last_ppu_cycle <= s_ppu_counter = s_ppu_divider - 1;

s_cpu_clk_enable <= '1' when s_last_cpu_cycle else '0';
s_cpu_clk_p_enable <= '1' when s_last_cpu_cycle else '0';
s_cpu_clk_n_enable <= '1' when s_mid_cpu_cycle else '0';
s_ppu_clk_enable <= '1' when s_last_ppu_cycle else '0';

s_eff_write_enable <= s_dma_write_enable when s_dma_active = '1' else s_mem_write_enable;
Expand All @@ -990,7 +998,7 @@ begin
s_int_n <= s_apu_int_n and i_irq_n;
s_chr_q <= s_ciram_q when s_ciram_ce_d(1) = '1' else s_chr_latch;

o_cpu_clk_enable <= s_cpu_clk_enable;
o_cpu_clk_enable <= s_cpu_clk_p_enable;
o_cpu_sync <= s_cpu_sync;
o_vga_clk_enable <= s_ppu_clk_enable;
o_chr_addr <= s_chr_addr;
Expand Down
Loading

0 comments on commit 809c79c

Please sign in to comment.