Project

General

Profile

« Previous | Next » 

Revision 446

Added by markw about 9 years ago

70ns accuracy is not enough for reliable Atari bus sampling, use faster clock we are already using for sram

View differences:

ultimate_cart/veronica/memory_timing_bridge.vhd
LIBRARY ieee;
USE ieee.std_logic_1164.all;
use ieee.numeric_std.all;
ENTITY memory_timing_bridge IS
PORT
(
clk : in std_logic;
clk7x : in std_logic;
reset_n : in std_logic;
fast_memory_request : in std_logic;
registered_read_data : out std_logic_vector(7 downto 0);
memory_request : out std_logic;
read_data : in std_logic_vector(7 downto 0)
);
END memory_timing_bridge;
ARCHITECTURE vhdl OF memory_timing_bridge IS
signal memory_next : std_logic_vector(7 downto 0);
signal memory_reg : std_logic_vector(7 downto 0);
signal fast_request_toggle_next : std_logic;
signal fast_request_toggle_reg : std_logic;
signal slow_request_toggle_next : std_logic;
signal slow_request_toggle_reg : std_logic;
signal make_request_next : std_logic;
signal make_request_reg : std_logic;
begin
-- register
process(clk)
begin
if (reset_n='0') then
memory_reg <= (others=>'0');
slow_request_toggle_reg <= '0';
make_request_reg <= '0';
elsif (clk'event and clk='1') then
memory_reg <= memory_next;
slow_request_toggle_reg <= slow_request_toggle_next;
make_request_reg <= make_request_next;
end if;
end process;
process(clk7x)
begin
if (reset_n='0') then
fast_request_toggle_reg <= '0';
elsif (clk'event and clk='1') then
fast_request_toggle_reg <= fast_request_toggle_next;
end if;
end process;
fast_request_toggle_next <= fast_request_toggle_reg xor fast_memory_request;
process(memory_reg,read_data,make_request_reg)
begin
memory_next <= memory_reg;
if (make_request_reg = '1') then
memory_next <= read_data;
end if;
end process;
make_request_next <= slow_request_toggle_reg xor fast_request_toggle_reg;
registered_read_data <= memory_reg;
memory_request <= make_request_reg;
end vhdl;
ultimate_cart/veronica/slave_timing_6502.vhd
ENTITY slave_timing_6502 IS
PORT (
CLK: in std_logic;
CLK7x: in std_logic;
RESET_N: in std_logic;
PHI2 : in std_logic; -- async to our clk:-(
PHI2 : in std_logic; -- async to our clk7x:-(
bus_addr : in std_logic_vector(12 downto 0);
bus_data : in std_logic_vector(7 downto 0);
bus_ctl_n : in std_logic;
......
DATA_IN: out std_logic_vector(7 downto 0);
DATA_OUT: in std_logic_vector(7 downto 0);
RW_N: out std_logic;
BUS_REQUEST: out std_logic;
INTERNAL_MEMORY_REQUEST: out std_logic;
S4_N : out std_logic;
s5_N : out std_logic;
ctl_n : out std_logic
......
signal phi_edge_prev_next : std_logic;
signal phi_edge_prev_reg: std_logic;
signal delay_next : std_logic_vector(4 downto 0);
signal delay_reg : std_logic_vector(4 downto 0);
signal delay_next : std_logic_vector(30 downto 0);
signal delay_reg : std_logic_vector(30 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_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";
signal state_reg : std_logic_vector(2 downto 0);
signal state_next : std_logic_vector(2 downto 0);
constant state_phi : std_logic_vector(2 downto 0) := "000";
constant state_write_request : std_logic_vector(2 downto 0) := "001";
constant state_read_request : std_logic_vector(2 downto 0) := "010";
constant state_read_output_start : std_logic_vector(2 downto 0) := "011";
constant state_read_output_end : std_logic_vector(2 downto 0) := "100";
begin
process(clk,reset_n)
process(clk7x,reset_n)
begin
if (reset_n='0') then
phi_edge_prev_reg <= '1';
......
bus_ctl_n_reg <= '1';
state_reg <= state_phi;
elsif (clk'event and clk='1') then
elsif (clk7x'event and clk7x='1') then
phi_edge_prev_reg <= phi_edge_prev_next;
delay_reg <= delay_next;
bus_data_out_reg <= bus_data_out_next;
......
end process;
synchronizer_phi : entity work.synchronizer
port map (clk=>clk, raw=>PHI2, sync=>PHI2_SYNC);
port map (clk=>clk7x, raw=>PHI2, sync=>PHI2_SYNC);
phi_edge_prev_next <= phi2_sync;
......
bus_s5_n_next <= bus_s5_n_reg;
bus_ctl_n_next <= bus_ctl_n_reg;
bus_request <= '0';
delay_next <= delay_reg(3 downto 0)&'0';
internal_memory_request <= '0';
delay_next <= delay_reg(29 downto 0)&'0';
bus_data_out_next <= bus_data_out_reg;
bus_drive_next <= bus_drive_reg;
......
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)
if (phi2_sync = '1' and phi_edge_prev_reg='0') then -- falling edge (3 cycles delayed)
delay_next(0) <= '1';
-- snap control signals, should be stable by now
......
bus_ctl_n_next <= bus_ctl_n;
if (bus_rw_n='1') then -- read
state_next <= state_read_start;
state_next <= state_read_request;
else
state_next <= state_write;
state_next <= state_write_request;
end if;
end if;
when state_write =>
if (delay_reg(2)='1') then -- n+4 cycles
when state_write_request =>
if (delay_reg(19)='1') then -- n+4 cycles
bus_data_in_next <= bus_data;
end if;
if (delay_reg(3)='1') then -- n+4 cycles
bus_request <= '1';
if (delay_reg(20)='1') then -- n+4 cycles
internal_memory_request <= '1';
state_next <= state_phi;
end if;
when state_read_start =>
when state_read_request =>
if (delay_reg(0)='1') then -- n+4 cycles
state_next <= state_read_output_start;
internal_memory_request <= '1';
end if;
when state_read_output_start =>
if (delay_reg(16)='1') then -- n+4 cycles
bus_data_out_next <= data_out;
bus_drive_next <= '1';
state_next <= state_read_end;
bus_request <= '1';
state_next <= state_read_output_start;
end if;
when state_read_end =>
if (delay_reg(4)='1') then -- n+4 cycles
when state_read_output_end =>
if (delay_reg(30)='1') then -- n+4 cycles
bus_drive_next <= '0';
state_next <= state_phi;
end if;
ultimate_cart/veronica/veronica.vhd
signal atari_s5_n : std_logic;
signal atari_ctl_n : std_logic;
signal atari_bus_request_fast : std_logic;
signal atari_read_data_reg : std_logic_vector(7 downto 0);
-- address decode
signal veronica_config_select : std_logic;
signal veronica_sram_select : std_logic;
......
glue3: entity work.slave_timing_6502
port map
(
clk => clk_adj,
clk7x => clk_adj7x,
reset_n => reset_n,
phi2 => CART_PHI2,
bus_addr => CART_ADDR,
......
ctl_n => atari_ctl_n,
addr_in => atari_address,
data_in => atari_write_data,
data_out => atari_read_data,
rw_n => atari_w_n,
bus_request => atari_bus_request
internal_memory_request => atari_bus_request_fast,
data_out => atari_read_data_reg
);
CART_DATA <= cart_bus_data_out when cart_bus_drive='1' else (others=>'Z');
glue3a: entity work.memory_timing_bridge
port map
(
clk => clk_adj,
clk7x => clk_adj7x,
reset_n => reset_n,
fast_memory_request => atari_bus_request_fast,
registered_read_data => atari_read_data_reg,
memory_request => atari_bus_request,
read_data => atari_read_data
);
glue4: entity work.atari_address_decoder
port map
(

Also available in: Unified diff