Revision 443
Added by markw over 9 years ago
ultimate_cart/veronica/atari_address_decoder.vhd | ||
---|---|---|
|
||
ENTITY atari_address_decoder IS
|
||
PORT (
|
||
s4 : in std_logic;
|
||
s5 : in std_logic;
|
||
ctl : in std_logic;
|
||
s4_n : in std_logic;
|
||
s5_n : in std_logic;
|
||
ctl_n : in std_logic;
|
||
addr_in: in std_logic_vector(12 downto 0);
|
||
bus_request: in std_logic;
|
||
|
||
... | ... | |
|
||
sram_address(16) <= '1';
|
||
sram_address(15 downto 14) <= bank_select&bank_half_select;
|
||
sram_address(13) <= not(s4) and s5;
|
||
sram_address(13) <= s4_n and not(s5_n);
|
||
sram_address(12 downto 0) <= addr_in;
|
||
|
||
sram_select <= bus_request and (s4 or s5);
|
||
config_select <= bus_request and ctl and or_reduce(addr_in(7 downto 6)¬(addr_in(5 downto 0)));
|
||
sram_select <= bus_request and not(s4_n and s5_n);
|
||
config_select <= bus_request and not(ctl_n) and or_reduce(addr_in(7 downto 6)¬(addr_in(5 downto 0)));
|
||
|
||
end vhdl;
|
ultimate_cart/veronica/simulate_sram.sh | ||
---|---|---|
|
||
|
||
|
||
#. /home/markw/fpga/xilinx/14.7/ISE_DS/settings64.sh
|
||
export XILINX=C:\Xilinx\14.7\ISE_DS\ISE
|
||
. /home/markw/fpga/xilinx/14.7/ISE_DS/settings32.sh
|
||
|
||
mkdir -p sim
|
||
pushd sim
|
||
... | ... | |
# verbose & no multthreading - fallback in case of problems
|
||
# fuse -v 1 -mt off -incremental -prj %name%.prj -o %name%.exe -t %name%
|
||
|
||
/drives/c/Xilinx/14.7/ISE_DS/ISE/bin/nt64/fuse.exe -timeprecision_vhdl 1fs -incremental -prj $name.prj -o $name.exe -t ${name}_tb || exit 1
|
||
fuse -timeprecision_vhdl 1fs -incremental -prj $name.prj -o $name.exe -t ${name}_tb || exit 1
|
||
# fuse --mt off -prj %name%.prj -o %name%.exe -t %name%_tb
|
||
|
||
# Check for the EXE again, independent of the errorlevel of fuse...
|
ultimate_cart/veronica/slave_timing_6502.vhd | ||
---|---|---|
PHI2 : in std_logic; -- async to our clk:-(
|
||
bus_addr : in std_logic_vector(12 downto 0);
|
||
bus_data : in std_logic_vector(7 downto 0);
|
||
bus_ctl : in std_logic;
|
||
bus_rw : in std_logic;
|
||
bus_s4 : in std_logic;
|
||
bus_s5 : in std_logic;
|
||
bus_ctl_n : in std_logic;
|
||
bus_rw_n : in std_logic;
|
||
bus_s4_n : in std_logic;
|
||
bus_s5_n : in std_logic;
|
||
|
||
bus_data_out : out std_logic_vector(7 downto 0);
|
||
bus_drive : out std_logic;
|
||
... | ... | |
DATA_OUT: in std_logic_vector(7 downto 0);
|
||
RW_N: out std_logic;
|
||
BUS_REQUEST: out std_logic;
|
||
S4 : out std_logic;
|
||
s5 : out std_logic;
|
||
ctl : out std_logic
|
||
S4_N : out std_logic;
|
||
s5_N : out std_logic;
|
||
ctl_n : out std_logic
|
||
);
|
||
END slave_timing_6502;
|
||
|
||
ARCHITECTURE vhdl OF slave_timing_6502 IS
|
||
|
||
signal PHI2_sync : std_logic;
|
||
signal bus_addr_sync : std_logic_vector(12 downto 0);
|
||
signal bus_data_sync : std_logic_vector(7 downto 0);
|
||
signal bus_ctl_sync : std_logic;
|
||
signal bus_rw_sync : std_logic;
|
||
signal bus_s4_sync : std_logic;
|
||
signal bus_s5_sync : std_logic;
|
||
signal bus_misc_sync : std_logic_vector(3 downto 0);
|
||
|
||
signal phi_edge_prev_next : std_logic;
|
||
signal phi_edge_prev_reg: std_logic;
|
||
|
||
signal drive_bus_shift_next : std_logic_vector(3 downto 0);
|
||
signal drive_bus_shift_reg : std_logic_vector(3 downto 0);
|
||
signal delay_next : std_logic_vector(4 downto 0);
|
||
signal delay_reg : std_logic_vector(4 downto 0);
|
||
|
||
signal bus_data_out_next : std_logic_vector(7 downto 0);
|
||
signal bus_data_out_reg : std_logic_vector(7 downto 0);
|
||
|
||
signal bus_drive_next : std_logic;
|
||
signal bus_drive_reg : std_logic;
|
||
|
||
signal bus_data_in_next : std_logic_vector(7 downto 0);
|
||
signal bus_data_in_reg : std_logic_vector(7 downto 0);
|
||
signal bus_addr_in_next : std_logic_vector(12 downto 0);
|
||
signal bus_addr_in_reg : std_logic_vector(12 downto 0);
|
||
signal bus_rw_n_next : std_logic;
|
||
signal bus_rw_n_reg : std_logic;
|
||
signal bus_s4_n_next : std_logic;
|
||
signal bus_s4_n_reg : std_logic;
|
||
signal bus_s5_n_next : std_logic;
|
||
signal bus_s5_n_reg : std_logic;
|
||
signal bus_ctl_n_next : std_logic;
|
||
signal bus_ctl_n_reg : std_logic;
|
||
|
||
signal state_reg : std_logic_vector(1 downto 0);
|
||
signal state_next : std_logic_vector(1 downto 0);
|
||
constant state_phi : std_logic_vector(1 downto 0) := "00";
|
||
constant state_write : std_logic_vector(1 downto 0) := "01";
|
||
constant state_read_start : std_logic_vector(1 downto 0) := "10";
|
||
constant state_read_end : std_logic_vector(1 downto 0) := "11";
|
||
|
||
begin
|
||
process(clk,reset_n)
|
||
begin
|
||
if (reset_n='0') then
|
||
phi_edge_prev_reg <= '1';
|
||
drive_bus_shift_reg <= (others=>'0');
|
||
delay_reg <= (others=>'0');
|
||
bus_data_out_reg <= (others=>'0');
|
||
bus_drive_reg <= '0';
|
||
|
||
bus_rw_n_reg <= '1';
|
||
bus_data_in_reg <= (others=>'0');
|
||
bus_addr_in_reg <= (others=>'0');
|
||
bus_s4_n_reg <= '1';
|
||
bus_s5_n_reg <= '1';
|
||
bus_ctl_n_reg <= '1';
|
||
|
||
state_reg <= state_phi;
|
||
elsif (clk'event and clk='1') then
|
||
phi_edge_prev_reg <= phi_edge_prev_next;
|
||
drive_bus_shift_reg <= drive_bus_shift_next;
|
||
delay_reg <= delay_next;
|
||
bus_data_out_reg <= bus_data_out_next;
|
||
bus_drive_reg <= bus_drive_next;
|
||
|
||
bus_rw_n_reg <= bus_rw_n_next;
|
||
bus_data_in_reg <= bus_data_in_next;
|
||
bus_addr_in_reg <= bus_addr_in_next;
|
||
bus_s4_n_reg <= bus_s4_n_next;
|
||
bus_s5_n_reg <= bus_s5_n_next;
|
||
bus_ctl_n_reg <= bus_ctl_n_next;
|
||
|
||
state_reg <= state_next;
|
||
end if;
|
||
end process;
|
||
|
||
synchronizer_phi : entity work.synchronizer
|
||
port map (clk=>clk, raw=>PHI2, sync=>PHI2_SYNC);
|
||
synchronizer_addr : entity work.synchronizer_vector
|
||
generic map(BITS=>13)
|
||
port map (clk=>clk, raw=>bus_addr, sync=>bus_addr_sync);
|
||
synchronizer_data : entity work.synchronizer_vector
|
||
generic map(BITS=>8)
|
||
port map (clk=>clk, raw=>bus_data, sync=>bus_data_sync);
|
||
synchronizer_ctl : entity work.synchronizer_vector
|
||
generic map(BITS=>4)
|
||
port map (clk=>clk, raw=>bus_ctl&bus_rw&bus_s4&bus_s5, sync=>bus_misc_sync);
|
||
|
||
bus_ctl_sync<=bus_misc_sync(3);
|
||
bus_rw_sync<=bus_misc_sync(2);
|
||
bus_s4_sync<=bus_misc_sync(1);
|
||
bus_s5_sync<=bus_misc_sync(0);
|
||
|
||
phi_edge_prev_next <= phi2_sync;
|
||
|
||
addr_in <= bus_addr_sync;
|
||
data_in <= bus_data_sync;
|
||
rw_n <= bus_rw_sync;
|
||
s4 <= bus_s4_sync;
|
||
s5 <= bus_s5_sync;
|
||
ctl <= bus_ctl_sync;
|
||
addr_in <= bus_addr_in_reg;
|
||
data_in <= bus_data_in_reg;
|
||
rw_n <= bus_rw_n_reg;
|
||
s4_n <= bus_s4_n_reg;
|
||
s5_n <= bus_s5_n_reg;
|
||
ctl_n <= bus_ctl_n_reg;
|
||
|
||
process(data_out, phi2_sync, phi_edge_prev_reg, drive_bus_shift_reg, bus_data_out_reg, bus_rw_sync)
|
||
process(data_out, phi2_sync, phi_edge_prev_reg, delay_reg, bus_data_out_reg,
|
||
bus_rw_n_reg,bus_addr_in_reg,bus_data_in_reg,
|
||
bus_s4_n_reg,bus_s5_n_reg,bus_ctl_n_reg,
|
||
bus_data,bus_addr,
|
||
state_reg)
|
||
begin
|
||
-- maintain snap (only read bus when safe!)
|
||
bus_addr_in_next <= bus_addr_in_reg;
|
||
bus_data_in_next <= bus_data_in_reg;
|
||
bus_rw_n_next <= bus_rw_n_reg;
|
||
bus_s4_n_next <= bus_s4_n_reg;
|
||
bus_s5_n_next <= bus_s5_n_reg;
|
||
bus_ctl_n_next <= bus_ctl_n_reg;
|
||
|
||
bus_request <= '0';
|
||
drive_bus_shift_next <= drive_bus_shift_reg(2 downto 0)&'0';
|
||
delay_next <= delay_reg(3 downto 0)&'0';
|
||
bus_data_out_next <= bus_data_out_reg;
|
||
if (phi2_sync = '1' and phi_edge_prev_reg='0') then -- rising edge (delayed 3 cycles - we have 7 to do our output...)
|
||
bus_request <= '1';
|
||
drive_bus_shift_next(0) <= not(bus_rw_sync); -- driven for 4 cycles
|
||
bus_data_out_next <= data_out;
|
||
end if;
|
||
bus_drive <= or_reduce(drive_bus_shift_reg(3 downto 0));
|
||
bus_drive_next <= bus_drive_reg;
|
||
|
||
|
||
-- LLLLLLLHHHHHHH
|
||
-- XXAAAAAAAAAAAA
|
||
-- XXXXXXXXXXDDDD
|
||
state_next <= state_reg;
|
||
case (state_reg) is
|
||
when state_phi =>
|
||
if (phi2_sync = '0' and phi_edge_prev_reg='1') then -- falling edge (delayed 3 cycles by sync)
|
||
delay_next(0) <= '1';
|
||
|
||
-- snap control signals, should be stable by now
|
||
bus_addr_in_next <= bus_addr;
|
||
bus_rw_n_next <= bus_rw_n;
|
||
bus_s4_n_next <= bus_s4_n;
|
||
bus_s5_n_next <= bus_s5_n;
|
||
bus_ctl_n_next <= bus_ctl_n;
|
||
|
||
if (bus_rw_n='1') then -- read
|
||
state_next <= state_read_start;
|
||
else
|
||
state_next <= state_write;
|
||
end if;
|
||
end if;
|
||
when state_write =>
|
||
if (delay_reg(2)='1') then -- n+4 cycles
|
||
bus_data_in_next <= bus_data;
|
||
state_next <= state_phi;
|
||
bus_request <= '1';
|
||
end if;
|
||
when state_read_start =>
|
||
if (delay_reg(0)='1') then -- n+4 cycles
|
||
bus_data_out_next <= data_out;
|
||
bus_drive_next <= '1';
|
||
state_next <= state_read_end;
|
||
bus_request <= '1';
|
||
end if;
|
||
when state_read_end =>
|
||
if (delay_reg(4)='1') then -- n+4 cycles
|
||
bus_drive_next <= '0';
|
||
state_next <= state_phi;
|
||
end if;
|
||
when others =>
|
||
end case;
|
||
|
||
end process;
|
||
|
||
bus_data_out <= bus_data_out_reg;
|
||
bus_drive <= bus_drive_reg;
|
||
|
||
end vhdl;
|
ultimate_cart/veronica/veronica.vhd | ||
---|---|---|
signal atari_write_data : std_logic_vector(7 downto 0);
|
||
signal atari_w_n : std_logic;
|
||
signal atari_config_w_n : std_logic;
|
||
signal atari_s4 : std_logic;
|
||
signal atari_s5 : std_logic;
|
||
signal atari_ctl : std_logic;
|
||
signal atari_s4_n : std_logic;
|
||
signal atari_s5_n : std_logic;
|
||
signal atari_ctl_n : std_logic;
|
||
|
||
-- address decode
|
||
signal veronica_config_select : std_logic;
|
||
... | ... | |
begin
|
||
|
||
|
||
pll1:work.pll_veronica
|
||
pll1:entity work.pll_veronica
|
||
PORT map
|
||
(
|
||
inclk0 => clk,
|
||
c0 => clk_adj, -- 14MHz (>70ns/cycle)
|
||
c1 => clk_adj7x, -- 70MHz
|
||
c1 => clk_adj7x, -- 98MHz
|
||
locked => reset_n
|
||
);
|
||
|
||
... | ... | |
phi2 => CART_PHI2,
|
||
bus_addr => CART_ADDR,
|
||
bus_data => CART_DATA,
|
||
bus_ctl => CART_CTL,
|
||
bus_rw => CART_RW,
|
||
bus_s4 => CART_S4,
|
||
bus_s5 => CART_S5,
|
||
bus_ctl_n => CART_CTL,
|
||
bus_rw_n => CART_RW,
|
||
bus_s4_n => CART_S4,
|
||
bus_s5_n => CART_S5,
|
||
|
||
bus_data_out => cart_bus_data_out,
|
||
bus_drive => cart_bus_drive,
|
||
|
||
s4 => atari_s4,
|
||
s5 => atari_s5,
|
||
ctl => atari_ctl,
|
||
s4_n => atari_s4_n,
|
||
s5_n => atari_s5_n,
|
||
ctl_n => atari_ctl_n,
|
||
addr_in => atari_address,
|
||
data_in => atari_write_data,
|
||
data_out => atari_read_data,
|
||
... | ... | |
glue4: entity work.atari_address_decoder
|
||
port map
|
||
(
|
||
s4 => atari_s4,
|
||
s5 => atari_s5,
|
||
ctl => atari_ctl,
|
||
s4_n => atari_s4_n,
|
||
s5_n => atari_s5_n,
|
||
ctl_n => atari_ctl_n,
|
||
addr_in => atari_address,
|
||
bus_request => atari_bus_request,
|
||
|
Also available in: Unified diff
Simulated and repaired 6502 bus and sram bus