-- indi16 vhdl -- Memory Driver (Bus Controller) -- Uses two address sequencing to obtain interleave of writes with reads -- (C)2007 K Ring Technologies Semiconductor -- designed for 66MHz operation LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_unsigned.all; ENTITY memdrv IS GENERIC ( Mem : STRING := "MAXIIDevKit" ); PORT ( -- External Bus Interface -- DRAM refreash on PNUL cycles -- Hilo byte select Hilo: BUFFER STD_LOGIC; -- Address Bus A : BUFFER STD_LOGIC_VECTOR(15 DOWNTO 0); -- Data Bus (Multiplexed Address?) D : INOUT STD_LOGIC_VECTOR(15 DOWNTO 0); -- Read/Write Cycle RW : OUT STD_LOGIC; -- Internal Bus Interface -- Cycle Control to execution unit (also pix clock) CYC : OUT STD_LOGIC; -- Address Buses AR, ARW : IN STD_LOGIC_VECTOR(15 DOWNTO 0); -- Read Bus DR : OUT STD_LOGIC_VECTOR(15 DOWNTO 0); -- Read of Write Bus DRW : OUT STD_LOGIC_VECTOR(15 DOWNTO 0); -- Write of Write Bus (also wisbone out data) DWW : IN STD_LOGIC_VECTOR(15 DOWNTO 0); -- Read or Write on Read/Write Bus RWRW : IN STD_LOGIC; -- Direct (Bus Free Helper) DRT : IN STD_LOGIC; -- Source or Destination (bus cycle) SD : IN STD_LOGIC; -- P Refresh PRF : IN STD_LOGIC; -- SoC WISHBONE Classic Interface for all on chip ports -- No RMW cycle ever generated, this leaves execution vector callback semaphores -- Wishbone decode to start wishbone cycle(i.e. on chip access) WBD_I : IN STD_LOGIC; -- Lets include a halt as we can always not halt if not present HLT_I : IN STD_LOGIC; RST_I : IN STD_LOGIC; CLK_I : IN STD_LOGIC; ADR_O : OUT STD_LOGIC_VECTOR(15 DOWNTO 0); DAT_I : IN STD_LOGIC_VECTOR(15 DOWNTO 0); DAT_O : OUT STD_LOGIC_VECTOR(15 DOWNTO 0); WE_O : OUT STD_LOGIC; SEL_O : OUT STD_LOGIC; STB_O : BUFFER STD_LOGIC; ACK_I : IN STD_LOGIC; CYC_O : OUT STD_LOGIC ); END memdrv; ARCHITECTURE a OF memdrv IS -- maximum 8 clock bus cycle (2 rw) (4 gives 256 pix res) CONSTANT HiZ : STD_LOGIC_VECTOR(15 DOWNTO 0) := "ZZZZZZZZZZZZZZZZ"; SIGNAL Seq : STD_LOGIC_VECTOR(2 DOWNTO 0); SIGNAL Mode : STD_LOGIC_VECTOR(2 DOWNTO 0); SIGNAL DR_en, DRW_en : STD_LOGIC; SIGNAL T1, T2, T3 : STD_LOGIC; BEGIN PROCESS(CLK_I, RST_I) BEGIN IF RST_I = '1' THEN Seq <= "000"; -- also included below is wishbone wait ELSIF rising_edge(CLK_I) AND HLT_I = '0' AND NOT(WBD_I = '1' AND STB_O = '1' AND ACK_I = '0') THEN IF DR_en = '1' THEN IF Hilo = '1' AND WBD_I = '0' THEN DR(15 DOWNTO 8) <= D(7 DOWNTO 0); ELSE IF WBD_I = '1' THEN -- internal read DR <= DAT_I; ELSE DR <= D; END IF; END IF; END IF; IF DRW_en = '1' THEN IF Hilo = '1' AND WBD_I = '0' THEN DRW(15 DOWNTO 8) <= D(7 DOWNTO 0); ELSE IF WBD_I = '1' THEN -- internal read DRW <= DAT_I; ELSE DRW <= D; END IF; END IF; END IF; Seq <= Seq + 1; END IF; END PROCESS; -- Wishbone mangling DAT_O <= DWW; ADR_O <= A; CYC_O <= STB_O; SEL_O <= '1'; MAXIIDevKit:IF Mem = "MAXIIDevKit" GENERATE -- MAX II devkit static ram seperate address and 8 bit PROCESS(Seq) BEGIN T1 <= NOT Seq(0) AND NOT Seq(1); -- ALE CAS etc T2 <= NOT seq(1); --RAS etc T3 <= NOT Seq(0) AND NOT Seq(1); -- OE etc CASE(Seq(0)) IS WHEN '0' => -- read cycle A <= AR; RW <= '1'; D <= HiZ; Hilo <= NOT T2; DR_en <= '1'; DRW_en <= '0'; CYC <= '0'; -- wishbone stobe on low byte STB_O <= NOT (DRT AND SD) AND WBD_I AND NOT Hilo; WE_O <= '0'; WHEN '1' => -- write cycle A <= ARW; IF RWRW = '1' OR (PRF = '1' AND SD = '0' AND DRT = '0') OR (SD = '0' AND DRT = '1') THEN RW <= '1'; -- refresh cycle or direct cycle D <= HiZ; WE_O <= '0'; ELSE IF Hilo = '1' THEN WE_O <= '0'; RW <= '0'; D(7 DOWNTO 0) <= DWW(15 DOWNTO 8); ELSE -- wishbone write WE_O <= '1'; RW <= '0'; D <= DWW; END IF; END IF; Hilo <= NOT T2; DR_en <= '0'; DRW_en <= '1'; CYC <= Seq(1); -- 4 cycle cheat STB_O <= NOT (DRT AND NOT SD) AND WBD_I AND NOT Hilo; END CASE; END PROCESS; END GENERATE; Template:IF Mem = "Template" GENERATE PROCESS(Seq) BEGIN CASE(Seq) IS WHEN "000" => -- read cycle WHEN "001" => WHEN "010" => WHEN "011" => WHEN "100" => WHEN "101" => WHEN "110" => WHEN "111" => END CASE; END PROCESS; END GENERATE; END a;