-- indi16 vhdl -- Altera MAXII UFM -- (C)2007 K Ring Technologies Semiconductor -- designed for 66MHz operation LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_unsigned.all; LIBRARY altera_mf; USE altera_mf.altera_mf_components.all; -- the wishbone bus in this implementation uses sustained STB and sustained ACK -- for maximal throughput (processor waits by STB delay, not ACK ignoring) -- this works same as classic for classic masters that respond to ACK in cycle -- but allows sustained transfer without dropping STB. -- i don't seem to be using the CYC_I input or SEL_I for that matter -- also must use HLT_I to prevent missed ACK on bus HLT ENTITY ufm IS PORT ( -- Slave WISHBONE Classic interface (STB_I decoded) HLT_I : IN STD_LOGIC; RST_I : IN STD_LOGIC; CLK_I : IN STD_LOGIC; ADR_I : IN 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_I : IN STD_LOGIC; SEL_I : IN STD_LOGIC; STB_I : IN STD_LOGIC; ACK_O : OUT STD_LOGIC; CYC_I : IN STD_LOGIC; -- 3.33MHz OSC out WDT_O : OUT STD_LOGIC ); END ufm; ARCHITECTURE a OF ufm IS SIGNAL NotBusy, Read, Done : STD_LOGIC; COMPONENT altufm_parallel GENERIC (ACCESS_MODE : STRING; ERASE_TIME : NATURAL := 500000000; LPM_FILE : STRING := "UNUSED"; OSC_FREQUENCY : NATURAL := 180000; PROGRAM_TIME : NATURAL := 1600000; WIDTH_ADDRESS : NATURAL := 9; WIDTH_DATA : NATURAL := 16; WIDTH_UFM_ADDRESS : NATURAL := 9; LPM_TYPE : STRING := "ALTUFM_PARALLEL" ); PORT (addr : IN STD_LOGIC_VECTOR(WIDTH_ADDRESS-1 DOWNTO 0); data_valid, nbusy, osc : OUT STD_LOGIC; di : IN STD_LOGIC_VECTOR(WIDTH_DATA-1 DOWNTO 0); do : OUT STD_LOGIC_VECTOR(WIDTH_DATA-1 DOWNTO 0); nerase, nread, nwrite : IN STD_LOGIC ); END COMPONENT; BEGIN x : altufm_parallel GENERIC MAP(ACCESS_MODE => "READ_ONLY") PORT MAP( addr => ADR_I(8 DOWNTO 0), data_valid => NotBusy, osc => WDT_O, do => DAT_O, nread => Read ); PROCESS(CLK_I) BEGIN IF STB_I = '1' AND Done = '0' THEN Read <= '0'; ELSE Read <= '1'; END IF; ACK_O <= Done AND STB_I; IF RST_I = '1' THEN Done <= '0'; ELSIF rising_edge(CLK_I) AND HLT_I = '0' THEN Done <= NotBusy AND STB_I AND NOT Done; -- ACK 1 cycle for two reads in row END IF; END PROCESS; END a;