Refactored AtomFast6502 to use new MOS6502CpuMonCore - works in new Atom at 4MHz and with tube

Change-Id: I73c769919e2634a4656a6edec2c5a1100bd70083
This commit is contained in:
David Banks 2015-11-15 11:50:06 +00:00
parent ffdd038a8b
commit a785d7e73f
4 changed files with 174 additions and 219 deletions

View File

@ -20,7 +20,7 @@
</file>
<file xil_pn:name="src/AtomFast6502.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="2"/>
<association xil_pn:name="Implementation" xil_pn:seqID="60"/>
<association xil_pn:name="Implementation" xil_pn:seqID="62"/>
</file>
<file xil_pn:name="src/T6502/T65_ALU.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="3"/>
@ -36,7 +36,7 @@
</file>
<file xil_pn:name="src/T6502/T65.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="6"/>
<association xil_pn:name="Implementation" xil_pn:seqID="57"/>
<association xil_pn:name="Implementation" xil_pn:seqID="56"/>
</file>
<file xil_pn:name="src/oho_dy1/Oho_Dy1.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="7"/>
@ -216,7 +216,7 @@
</file>
<file xil_pn:name="src/AVR8/uC/AVR8.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="117"/>
<association xil_pn:name="Implementation" xil_pn:seqID="55"/>
<association xil_pn:name="Implementation" xil_pn:seqID="54"/>
</file>
<file xil_pn:name="src/AVR8/uC/external_mux.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="119"/>
@ -236,22 +236,22 @@
</file>
<file xil_pn:name="src/DCM/DCM0.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="124"/>
<association xil_pn:name="Implementation" xil_pn:seqID="54"/>
<association xil_pn:name="Implementation" xil_pn:seqID="61"/>
</file>
<file xil_pn:name="ipcore_dir/WatchEvents.xco" xil_pn:type="FILE_COREGEN">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="125"/>
<association xil_pn:name="Implementation" xil_pn:seqID="56"/>
<association xil_pn:name="Implementation" xil_pn:seqID="55"/>
</file>
<file xil_pn:name="src/AtomFast6502.bmm" xil_pn:type="FILE_BMM">
<association xil_pn:name="Implementation" xil_pn:seqID="0"/>
</file>
<file xil_pn:name="src/BusMonCore.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="123"/>
<association xil_pn:name="Implementation" xil_pn:seqID="58"/>
<association xil_pn:name="Implementation" xil_pn:seqID="57"/>
</file>
<file xil_pn:name="src/AlanD/R65Cx2.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="123"/>
<association xil_pn:name="Implementation" xil_pn:seqID="59"/>
<association xil_pn:name="Implementation" xil_pn:seqID="58"/>
</file>
<file xil_pn:name="src/AVR8/Memory/XDM2Kx8.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="120"/>
@ -261,6 +261,14 @@
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="121"/>
<association xil_pn:name="Implementation" xil_pn:seqID="41"/>
</file>
<file xil_pn:name="src/MOS6502CpuMonCore.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="121"/>
<association xil_pn:name="Implementation" xil_pn:seqID="59"/>
</file>
<file xil_pn:name="src/DCM/DCM2.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="122"/>
<association xil_pn:name="Implementation" xil_pn:seqID="60"/>
</file>
<file xil_pn:name="ipcore_dir/WatchEvents.xise" xil_pn:type="FILE_COREGENISE">
<association xil_pn:name="Implementation" xil_pn:seqID="0"/>
</file>

View File

@ -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;

View File

@ -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

View File

@ -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;