diff --git a/AtomFast6502.xise b/AtomFast6502.xise
index 07884d0..b1f9bbf 100644
--- a/AtomFast6502.xise
+++ b/AtomFast6502.xise
@@ -20,7 +20,7 @@
-
+
@@ -36,7 +36,7 @@
-
+
@@ -216,7 +216,7 @@
-
+
@@ -236,22 +236,22 @@
-
+
-
+
-
+
-
+
@@ -261,6 +261,14 @@
+
+
+
+
+
+
+
+
diff --git a/src/AtomFast6502.bmm b/src/AtomFast6502.bmm
index f4b771d..1e2be6a 100644
--- a/src/AtomFast6502.bmm
+++ b/src/AtomFast6502.bmm
@@ -2,39 +2,39 @@ ADDRESS_MAP avrmap PPC405 0
ADDRESS_SPACE rom_code RAMB16 [0x00000000:0x000047ff]
BUS_BLOCK
- mon/Inst_AVR8/PM_Inst/RAM_Word0 [15:0];
+ core/mon/Inst_AVR8/PM_Inst/RAM_Word0 [15:0];
END_BUS_BLOCK;
BUS_BLOCK
- mon/Inst_AVR8/PM_Inst/RAM_Word1 [15:0];
+ core/mon/Inst_AVR8/PM_Inst/RAM_Word1 [15:0];
END_BUS_BLOCK;
BUS_BLOCK
- mon/Inst_AVR8/PM_Inst/RAM_Word2 [15:0];
+ core/mon/Inst_AVR8/PM_Inst/RAM_Word2 [15:0];
END_BUS_BLOCK;
BUS_BLOCK
- mon/Inst_AVR8/PM_Inst/RAM_Word3 [15:0];
+ core/mon/Inst_AVR8/PM_Inst/RAM_Word3 [15:0];
END_BUS_BLOCK;
BUS_BLOCK
- mon/Inst_AVR8/PM_Inst/RAM_Word4 [15:0];
+ core/mon/Inst_AVR8/PM_Inst/RAM_Word4 [15:0];
END_BUS_BLOCK;
BUS_BLOCK
- mon/Inst_AVR8/PM_Inst/RAM_Word5 [15:0];
+ core/mon/Inst_AVR8/PM_Inst/RAM_Word5 [15:0];
END_BUS_BLOCK;
BUS_BLOCK
- mon/Inst_AVR8/PM_Inst/RAM_Word6 [15:0];
+ core/mon/Inst_AVR8/PM_Inst/RAM_Word6 [15:0];
END_BUS_BLOCK;
BUS_BLOCK
- mon/Inst_AVR8/PM_Inst/RAM_Word7 [15:0];
+ core/mon/Inst_AVR8/PM_Inst/RAM_Word7 [15:0];
END_BUS_BLOCK;
BUS_BLOCK
- mon/Inst_AVR8/PM_Inst/RAM_Word8 [15:0];
+ core/mon/Inst_AVR8/PM_Inst/RAM_Word8 [15:0];
END_BUS_BLOCK;
END_ADDRESS_SPACE;
diff --git a/src/AtomFast6502.ucf b/src/AtomFast6502.ucf
index ecd084e..76d7335 100644
--- a/src/AtomFast6502.ucf
+++ b/src/AtomFast6502.ucf
@@ -2,7 +2,9 @@
NET "clock49" LOC="P89" | IOSTANDARD = LVCMOS33 | PERIOD = 20.35ns ; # 49.152 MHz Oscillator
NET "clock49" CLOCK_DEDICATED_ROUTE = FALSE;
-PIN "mon/inst_dcm0/DCM_INST.CLKIN" CLOCK_DEDICATED_ROUTE = FALSE;
+PIN "inst_dcm0/DCM_INST.CLKIN" CLOCK_DEDICATED_ROUTE = FALSE;
+NET "Phi0" CLOCK_DEDICATED_ROUTE = FALSE;
+PIN "inst_dcm2/DCM_INST.CLKIN" CLOCK_DEDICATED_ROUTE = FALSE;
#NET "VSS" LOC="P16" | IOSTANDARD = LVCMOS33 ; # 6502 pin 1
#NET "Rdy" LOC="P95" | IOSTANDARD = LVCMOS33 ; # 6502 pin 2
@@ -67,7 +69,7 @@ NET "avr_RxD" LOC="P15" | IOSTANDARD = LVCMOS33 ;
NET "trig<0>" LOC="P62" | IOSTANDARD = LVCMOS33 ;
NET "trig<1>" LOC="P63" | IOSTANDARD = LVCMOS33 ;
-NET "fakeTube_n" LOC="P65" | IOSTANDARD = LVCMOS33 ;
+#NET "fakeTube_n" LOC="P65" | IOSTANDARD = LVCMOS33 ;
# NET "" LOC="P48" | IOSTANDARD = LVCMOS33 ; # connector pin E2
# NET "" LOC="P49" | IOSTANDARD = LVCMOS33 ; # connector pin E3
diff --git a/src/AtomFast6502.vhd b/src/AtomFast6502.vhd
index e3b3d77..014f226 100644
--- a/src/AtomFast6502.vhd
+++ b/src/AtomFast6502.vhd
@@ -14,6 +14,22 @@
--
--Design Name: AtomBusMon
--Device: XC3S250E
+--
+-- This desing uses a DCM to generate a 16x internal clock from Phi0
+-- Output signals can be placed in units of 1/16th Phi0
+--
+-- There are two constraints to be aware of:
+--
+-- 1. There is no defined phase relationship between Phi0 and Phi1/2
+-- This is because Phi is typically too slow for a Spartan -6 DLL
+-- If the host system also uses Phi0, then this may cause problems.
+--
+-- 2. Phi0 must be a single frequency clock, or the DCM will not lock
+-- This will not, therefore, work in a Beeb because of the clock
+-- stretching when IO devices are accessed.
+--
+-- The Atom satisfies both of these constraints.
+--
library ieee;
use ieee.std_logic_1164.all;
@@ -21,7 +37,6 @@ use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
use work.OhoPack.all ;
-
entity AtomFast6502 is
generic (
UseT65Core : boolean := true;
@@ -47,9 +62,6 @@ entity AtomFast6502 is
-- External trigger inputs
trig : in std_logic_vector(1 downto 0);
- -- Jumpers
- fakeTube_n : in std_logic;
-
-- Serial Console
avr_RxD : in std_logic;
avr_TxD : out std_logic;
@@ -72,168 +84,156 @@ entity AtomFast6502 is
end AtomFast6502;
architecture behavioral of AtomFast6502 is
-
- signal Din : std_logic_vector(7 downto 0);
-
- -- Signal from the internal core
- signal Dout0 : std_logic_vector(7 downto 0);
- signal Addr0 : std_logic_vector(15 downto 0);
- signal R_W_n0 : std_logic;
- signal Sync0 : std_logic;
-
- -- Delayed signals for the outside world
- signal Dout1 : std_logic_vector(7 downto 0);
- signal Addr1 : std_logic_vector(15 downto 0);
- signal R_W_n1 : std_logic;
- signal Sync1 : std_logic;
- signal Rdy_int : std_logic;
-
- signal cpu_addr_us: unsigned (15 downto 0);
- signal cpu_dout_us: unsigned (7 downto 0);
-
- signal clock_16x : std_logic;
- signal cpu_clk : std_logic;
- signal busmon_clk : std_logic;
- signal R_W_n_int : std_logic;
-
+
+ -- Clocking
+ signal clock_avr : std_logic;
+ signal clock_16x : std_logic;
+ signal clk_div : std_logic_vector(3 downto 0);
signal cpu_clken : std_logic;
signal cpu_dataen : std_logic;
-
- signal clk_div : std_logic_vector(3 downto 0);
+ signal busmon_clken : std_logic;
- signal Phi1_int : std_logic;
- signal Phi2_int : std_logic;
+ -- DCM watchdog
signal dcm_reset : std_logic;
- signal dcm_count : std_logic_vector(9 downto 0);
signal dcm_locked : std_logic;
+ signal dcm_count : std_logic_vector(9 downto 0);
signal edge0 : std_logic;
signal edge1 : std_logic;
-
- signal Regs : std_logic_vector(63 downto 0);
- signal Regs1 : std_logic_vector(255 downto 0);
- signal memory_rd : std_logic;
- signal memory_wr : std_logic;
- signal memory_addr : std_logic_vector(15 downto 0);
- signal memory_dout : std_logic_vector(7 downto 0);
- signal memory_din : std_logic_vector(7 downto 0);
- signal memory_done : std_logic;
+ signal Din : std_logic_vector(7 downto 0);
+
+ signal Addr0 : std_logic_vector(15 downto 0);
+ signal R_W_n0 : std_logic;
+ signal Sync0 : std_logic;
+ signal Dout0 : std_logic_vector(7 downto 0);
+
+ signal Addr1 : std_logic_vector(15 downto 0);
+ signal R_W_n1 : std_logic;
+ signal Sync1 : std_logic;
+ signal Dout1 : std_logic_vector(7 downto 0);
+
+ signal IRQ_n_sync : std_logic;
+ signal NMI_n_sync : std_logic;
+
+ signal Res_n_in : std_logic;
+ signal Res_n_out : std_logic;
begin
- mon : entity work.BusMonCore port map (
- clock49 => clock49,
- Addr => Addr1,
- Data => Data,
- Phi2 => busmon_clk,
- Rd_n => not R_W_n1,
- Wr_n => R_W_n1,
- RdIO_n => '1',
- WrIO_n => '1',
- Sync => Sync1,
- Rdy => Rdy_int,
- nRSTin => Res_n,
- nRSTout => Res_n,
- CountCycle => Rdy_int,
- trig => trig,
- lcd_rs => open,
- lcd_rw => open,
- lcd_e => open,
- lcd_db => open,
- avr_RxD => avr_RxD,
- avr_TxD => avr_TxD,
- sw1 => sw1,
- nsw2 => nsw2,
- led3 => led3,
- led6 => led6,
- led8 => led8,
- tmosi => tmosi,
- tdin => tdin,
- tcclk => tcclk,
- Regs => Regs1,
- RdMemOut=> memory_rd,
- WrMemOut=> memory_wr,
- RdIOOut => open,
- WrIOOut => open,
- AddrOut => memory_addr,
- DataOut => memory_dout,
- DataIn => memory_din,
- Done => memory_done,
- SS_Step => open,
- SS_Single => open
+ inst_dcm0 : entity work.DCM0 port map(
+ CLKIN_IN => clock49,
+ CLK0_OUT => clock_avr,
+ CLK0_OUT1 => open,
+ CLK2X_OUT => open
);
- Regs1(63 downto 0) <= Regs;
- Regs1(255 downto 64) <= (others => '0');
- GenT65Core: if UseT65Core generate
- inst_t65: entity work.T65 port map (
- mode => "00",
- Abort_n => '1',
- SO_n => SO_n,
- Res_n => Res_n,
- Enable => cpu_clken,
- Clk => clock_16x,
- Rdy => Rdy_int,
- IRQ_n => IRQ_n,
- NMI_n => NMI_n,
- R_W_n => R_W_n0,
- Sync => Sync0,
- A(23 downto 16) => open,
- A(15 downto 0) => Addr0,
- DI => Din,
- DO => Dout0,
- Regs => Regs
- );
- end generate;
-
- GenAlanDCore: if UseAlanDCore generate
- inst_r65c02: entity work.r65c02 port map (
- reset => RES_n,
- clk => clock_16x,
- enable => cpu_clken,
- nmi_n => NMI_n,
- irq_n => IRQ_n,
- di => unsigned(Din),
- do => cpu_dout_us,
- addr => cpu_addr_us,
- nwe => R_W_n0,
- sync => Sync0,
- sync_irq => open,
- Regs => Regs
- );
- Dout0 <= std_logic_vector(cpu_dout_us);
- Addr0 <= std_logic_vector(cpu_addr_us);
- end generate;
-
-
-
-
- Phi1 <= Phi1_int;
- Phi2 <= Phi2_int;
- busmon_clk <= Phi2_int;
- Din <= Data;
-
-
- Addr <= memory_addr when (memory_rd = '1' or memory_wr = '1') else Addr1;
- R_W_n <= '1' when memory_rd = '1' else '0' when memory_wr = '1' else R_W_n1;
- Sync <= Sync1;
-
- Data <= memory_dout when cpu_dataen = '1' and memory_wr = '1' else
- Dout1 when cpu_dataen = '1' and R_W_n1 = '0' and memory_rd = '0' else
- (others => 'Z');
-
- memory_done <= memory_rd or memory_wr;
-
-
-
-
inst_dcm2 : entity work.DCM2 port map(
CLKIN_IN => Phi0,
CLKFX_OUT => clock_16x,
LOCKED => dcm_locked,
RESET => dcm_reset
);
+
+ core : entity work.MOS6502CpuMonCore
+ generic map (
+ UseT65Core => UseT65Core,
+ UseAlanDCore => UseAlanDCore
+ )
+ port map (
+ clock_avr => clock_avr,
+ busmon_clk => clock_16x,
+ busmon_clken => busmon_clken,
+ cpu_clk => clock_16x,
+ cpu_clken => cpu_clken,
+ IRQ_n => IRQ_n_sync,
+ NMI_n => NMI_n_sync,
+ Sync => Sync0,
+ Addr => Addr0,
+ R_W_n => R_W_n0,
+ Din => Din,
+ Dout => Dout0,
+ SO_n => SO_n,
+ Res_n_in => Res_n_in,
+ Res_n_out => Res_n_out,
+ Rdy => '1',
+ trig => trig,
+ avr_RxD => avr_RxD,
+ avr_TxD => avr_TxD,
+ sw1 => sw1,
+ nsw2 => nsw2,
+ led3 => led3,
+ led6 => led6,
+ led8 => led8,
+ tmosi => tmosi,
+ tdin => tdin,
+ tcclk => tcclk
+ );
+ -- Tristate buffer driving reset back out
+ Res_n_in <= Res_n;
+ Res_n <= '0' when Res_n_out <= '0' else 'Z';
+
+ sync_gen : process(clock_16x)
+ begin
+ if rising_edge(clock_16x) then
+ NMI_n_sync <= NMI_n;
+ IRQ_n_sync <= IRQ_n;
+ end if;
+ end process;
+
+ Addr <= Addr1;
+ R_W_n <= R_W_n1;
+ Sync <= Sync1;
+ Data <= Dout1 when cpu_dataen = '1' and R_W_n1 = '0' else (others => 'Z');
+
+ -- Din is registered in cpu_clken in BusMonCore
+ Din <= Data;
+
+ process(clock_16x)
+ begin
+ if rising_edge(clock_16x) then
+ -- internal clock running 16x Phi0
+ clk_div <= clk_div + 1;
+ -- clock the CPU on cycle 0
+ if (clk_div = "1111") then
+ cpu_clken <= '1';
+ else
+ cpu_clken <= '0';
+ end if;
+ -- clock the Busmon out of phase with the cpu
+ -- exactly which cycle is not critical
+ if (clk_div = "0111") then
+ busmon_clken <= '1';
+ else
+ busmon_clken <= '0';
+ end if;
+ -- toggle Phi1/2 on cycles 0 and 8
+ if (clk_div = "0000") then
+ Phi1 <= '1';
+ Phi2 <= '0';
+ elsif (clk_div = "1000") then
+ Phi1 <= '0';
+ Phi2 <= '1';
+ end if;
+ -- Skew address by one cycle wrt Phi1/2
+ -- and hold for a complete cycle
+ if (clk_div = "0001") then
+ Addr1 <= Addr0;
+ R_W_n1 <= R_W_n0;
+ Sync1 <= Sync0;
+ end if;
+ -- Skew data release by one cycle wrt Phi1/2
+ if (clk_div = "1000") then
+ cpu_dataen <= '1';
+ Dout1 <= Dout0;
+ elsif (clk_div = "0001") then
+ cpu_dataen <= '0';
+ Dout1 <= (others => '1');
+ end if;
+ end if;
+ end process;
+
+ -- This reset the DCM if is seems to have stopped outputting a clock
process(clock49)
begin
if rising_edge(clock49) then
@@ -252,61 +252,6 @@ begin
end if;
end if;
end process;
-
--- -- for some reason this did not work reliably....
--- process(clock49)
--- begin
--- if rising_edge(clock49) then
--- edge0 <= dcm_locked;
--- edge1 <= edge0;
--- if (dcm_count = "0000000000") then
--- dcm_reset <= '0';
--- if (edge0 = '0' and edge1 = '1') then
--- dcm_count <= dcm_count + 1;
--- end if;
--- else
--- dcm_reset <= '1';
--- dcm_count <= dcm_count + 1;
--- end if;
--- end if;
--- end process;
-
- process(clock_16x)
- begin
- if rising_edge(clock_16x) then
- -- internal clock running 16x Phi0
- clk_div <= clk_div + 1;
- -- clock the CPU on cycle 0
- if (clk_div = "1111") then
- cpu_clken <= '1';
- else
- cpu_clken <= '0';
- end if;
- -- toggle Phi1/2 on cycles 0 and 8
- if (clk_div = "0000") then
- Phi1_int <= '1';
- Phi2_int <= '0';
- memory_din <= Data;
- elsif (clk_div = "1000") then
- Phi1_int <= '0';
- Phi2_int <= '1';
- end if;
- -- Skew address by one cycles, and hold for a complete cycle
- if (clk_div = "0001") then
- Addr1 <= Addr0;
- R_W_n1 <= R_W_n0;
- Sync1 <= Sync0;
- end if;
- -- Skew data by one cycle
- if (clk_div = "1000") then
- cpu_dataen <= '1';
- Dout1 <= Dout0;
- elsif (clk_div = "0001") then
- cpu_dataen <= '0';
- Dout1 <= (others => '1');
- end if;
- end if;
- end process;
end behavioral;