TITLE "VME_Interface"; FUNCTION lpm_decode (data[LPM_WIDTH-1..0], enable, clock, aclr) WITH (LPM_WIDTH, LPM_DECODES, LPM_PIPELINE) RETURNS (eq[LPM_DECODES-1..0]); FUNCTION lpm_compare (dataa[LPM_WIDTH-1..0], datab[LPM_WIDTH-1..0], clock, aclr) WITH (LPM_WIDTH, LPM_REPRESENTATION, LPM_PIPELINE, CHAIN_SIZE, ONE_INPUT_IS_CONSTANT) RETURNS (alb, aeb, agb, ageb, aneb, aleb); FUNCTION lpm_counter (data[LPM_WIDTH-1..0], clock, clk_en, cnt_en, updown, aclr, aset, aconst, aload, sclr, sset, sconst, sload) WITH (LPM_WIDTH, LPM_DIRECTION, LPM_MODULUS, LPM_AVALUE, LPM_SVALUE) RETURNS (q[LPM_WIDTH-1..0], eq[15..0]); SUBDESIGN vme_interface ( Address[31..2] : INPUT; _GA[4..0] : INPUT; _LWORD : INPUT; _vme_write : INPUT; AM[5..0]: INPUT; % address modifier % _AS : INPUT; % address strobe % _IACK : INPUT; % Interrupt Acknowledge % _DS[1..0] : INPUT; % Data Strobes % _ACK : INPUT; % Data acknowledge from slave % _vme_err : INPUT; % vme transaction error from slave % _delayed_modsel : INPUT; _DTACK : BIDIR; % Data Acknowledge % _BERR : BIDIR; % bus error % _MODSEL : OUTPUT; % Module select % _vme_data_str : OUTPUT; % Data strobe (active low) % _delayed_DS : INPUT; % Delayed data strobe % vme_write : OUTPUT; dir_trans : OUTPUT; % goes to the DIR pin of the transceivers % vme_address[26..2] : OUTPUT; GA[4..0] : OUTPUT; ) VARIABLE _data_str : NODE; MODSEL : NODE; comp : lpm_compare WITH (LPM_WIDTH=10, ONE_INPUT_IS_CONSTANT = "NO"); valid_addr : DFF; % the result of masking AM and GA is latched into this register with !_AS % address_cnt : lpm_counter WITH (LPM_WIDTH=6); vme_addr[26..8] : DFF; BLT : DFF; % Block Transfer bit % BEGIN DEFAULTS _MODSEL = VCC; _vme_data_str = VCC; END DEFAULTS; GA[] = !_GA[]; vme_write = !_vme_write; dir_trans = _vme_write; _data_str = _DS0 & _DS1; % Preliminary Address & Address Modifier decoding % comp.dataa0 = AM0; comp.dataa[3..1] = AM[5..3]; comp.dataa4 = _LWORD; comp.datab[4..0] = B"00011"; comp.dataa[9..5] = Address[31..27]; comp.datab[9..5] = GA[]; valid_addr.clk = !_AS; valid_addr.d = comp.aeb; valid_addr.clrn = (_delayed_modsel # !_AS); % WJA 1999-04-16 % % ex-VME2000 part % _MODSEL = (!valid_addr.q # _AS # !_IACK) & (_MODSEL # _data_str); % hold until data_str negated % _vme_data_str = (_MODSEL # !_DTACK # !_BERR # _data_str) & (_vme_data_str # _data_str); % hold until data_str negated % _DTACK = OPNDRN(_ACK # !_vme_err # !_BERR # _vme_data_str); _BERR = OPNDRN((_vme_err # _vme_data_str) & (_BERR # _ACK)); % hold until ACK negated % MODSEL = !_MODSEL; % Local vme_address initialization % vme_addr[].clk = MODSEL; vme_addr[].d = Address[26..8]; vme_address[26..8] = vme_addr[].q; % Local vme_address incrementation in case of a Block Transfer % BLT.clk = MODSEL; BLT.d = AM1; address_cnt.data[] = Address[7..2]; address_cnt.aload = MODSEL & _delayed_modsel; address_cnt.cnt_en = BLT.q; address_cnt.clock = _delayed_DS; vme_address[7..2] = address_cnt.q[]; END;