library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; -- TB 26122003 entity Glue is port ( adrin: in std_logic_vector(15 downto 0); --Plus/4 Address bus phi2: in std_logic; --Phi2 RW: in std_logic; reset: in std_logic; colorclk: in std_logic; -- 17.7MHz input clkset: in std_logic; regclk: out std_logic; --Clk for data register SIDcs: out std_logic; --SID Chipselect SIDclk: out std_logic; --SID Clk SIDadr: out std_logic_vector(4 downto 0); --SID Adress -- flash control C1low: in std_logic; C1high: in std_logic; oe: out std_logic; ce: out std_logic; we: out std_logic ); end; -- PLUS/4 BUS: -- A15-A0 Adresses -- D7-D0 Data -- R/W 0=Write 1=Read -- -- Phi2: rising edge:Address valid, falling edge: Data valid -- falling edge: Address update, rising edge: data update -- reset: low active -- mux: 1.7MHz clock, not in sync with PHI2! architecture GlueArch of Glue is signal siden: std_logic; signal adrreg: std_logic_vector(4 downto 0); signal wrsig: std_logic; signal ack: std_logic; signal sidclkint: std_logic; signal frqdiv: std_logic_vector(3 downto 0); -- configuration signal clock: std_logic_vector(2 downto 0); signal confreg: std_logic_vector(1 downto 0); -- flash signal wlock: std_logic; signal cbank: std_logic_vector(4 downto 0); begin -- address decoder process(adrin) begin if ( adrin(15 downto 5)= "11111101010" ) or -- $FD40 ( adrin(15 downto 5)= "11010100000" ) then -- $D400 siden <= '1'; else siden <= '0'; end if; end process; -- clock sync state machine -- Pipelined writes are not possible when both clocks are not in sync.. bad luck, but since a STA takes at least 4 fast clock cycles, -- there will never be writes in two consecutive SID cycles. process(phi2,reset,siden) begin if reset='0' then wrsig <= '0'; adrreg <= "11111"; -- make sure initial access goes to invalid register! elsif falling_edge(phi2) then if wrsig = '1' AND ack = '1' then wrsig <= '0'; elsif RW='0' AND siden='1' AND ack ='0'then adrreg <= adrin(4 downto 0); wrsig <= '1'; end if; end if; end process; -- handshaking process on the SID side process(sidclkint,reset) begin if reset='0' then ack <= '0'; elsif rising_edge(sidclkint) then ack <= wrsig; end if; end process; -- frequency divider for colorclk, generate Sidclk -- for 17.7MHz input clock -- use assymetric divider for 8.83MHz input clock? process(colorclk,reset) begin if reset='0' then frqdiv <= "1111"; sidclkint <= '1'; elsif rising_edge(colorclk) then if frqdiv = "0000" then sidclkint <= NOT sidclkint; if clkset = '1' then frqdiv <= "1000"; -- divide by 9 (18 total) else frqdiv <= "1001"; -- divide by 10 (20 total) end if; else sidclkint <= sidclkint; frqdiv <= frqdiv - 1; end if; end if; end process; -- configuration access control -- -- configuration unlock at $FD60 -- configuration registers at $FD80 -- flash rom control -- -- just one bank taken, as we do the bankswitching byself -- -- internal state: current bank -- write enable -- -- inputs: 2 c1low, c1high: chipselects for both banks -- r/w -- A0-A15 -- output: 3 CS for flash -- A14-A18 for flash (same as A0-A4 for SID!, take care of write collisions? -> impossible due to 4 cycle rule) -- OE, WE process(phi2,reset) begin if reset='0' then cbank <= "00000"; elsif rising_edge(phi2) then if adrin(15 downto 5)="11111101100" then -- $FD80 cbank <= adrin(4 downto 0); end if; end if; end process; oe <= '0' when (c1low='0' OR c1high='0') else '1'; ce <= '0' when (c1low='0' OR c1high='0') else '1'; we <= '1'; SIDclk <= sidclkint; SIDcs <= NOT ack; -- SIDadr <= adrreg; SIDadr <= cbank when c1low='0' else (cbank + 1) when c1high='0' else adrreg; regclk <= wrsig; end GlueArch;