Project

General

Profile

« Previous | Next » 

Revision 443

Added by markw over 9 years ago

Simulated and repaired 6502 bus and sram bus

View differences:

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)&not(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)&not(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