---------------------------------- -- Bi-Directional Pass Transistor -- ---------------------------------- LIBRARY std; USE std.standard.ALL; USE work.std_logic.ALL; ENTITY bxfr IS GENERIC ( gdelay : time := 3 ps; -- delay on the gate G MaxStrength : t_strength := 'R'); -- Max output strength on Src and Drn. -- Use to model resistance. PORT ( g : IN t_wlogic; -- Gate src, drn : INOUT t_wlogic); -- Src and Drn are symmetric END bxfr; ARCHITECTURE bxfr_behave OF bxfr IS SIGNAL wakeup : boolean := false; SIGNAL gd : t_wlogic; BEGIN gd <= g after gdelay; PROCESS ( gd, src'TRANSACTION, drn'TRANSACTION) VARIABLE psrc, pdrn : t_logic; -- to store old contribution VARIABLE vsrc, vdrn : t_logic; -- to store next contribution VARIABLE init : boolean := true; BEGIN ------------------------ IF NOT wakeup THEN ----- disconnected ----- IF init THEN ------------------------ src <= D; drn <= D; init := false; ELSIF (gd'EVENT OR (f_state(gd) /= '0')) THEN wakeup <= true; psrc := f_convz(src); pdrn := f_convz(drn); src <= psrc; drn <= pdrn; ELSE -- no event on gate, and gate is off IF src'ACTIVE THEN -- evaluate src vsrc := f_convz(src); IF psrc /= vsrc THEN -- update when change psrc := vsrc; IF f_strength(src) /= 'F' THEN src <= vsrc; END IF; END IF; END IF; IF drn'ACTIVE THEN -- evaluate drn vdrn := f_convz(drn); IF pdrn /= vdrn THEN -- update when change pdrn := vdrn; IF f_strength(drn) /= 'F' THEN drn <= vdrn; END IF; END IF; END IF; END IF; ELSE --------------------- CASE f_state(gd) IS ----- reconnect ----- WHEN '0' => --------------------- -- f_convz computes tristate value vsrc := f_convz(src); vdrn := f_convz(drn); WHEN '1' => -- compute brf of src and drn -- f_ceil computes the resistance -- f_busres computes resolved value vsrc := f_ceil(f_busres(src)(drn), MaxStrength); vdrn := f_ceil(f_busres(src)(drn), MaxStrength); WHEN 'X' => -- compute range between tristate and brf of src and drn -- f_uxfr is the function for unidirectional transistor -- use f_uxfr to compute the range between tristate -- and resolved value vsrc := f_ceil(f_uxfr(FX, f_busres(src)(drn), f_convz(src)), MaxStrength); vdrn := f_ceil(f_uxfr(FX, f_busres(src)(drn), f_convz(drn)), MaxStrength); END CASE; IF (psrc=vsrc) AND (pdrn=vdrn) THEN -- wakeup in 1 fs, if nothing changes wakeup <= false after 1 fs; ELSE IF psrc /= vsrc THEN -- update when change psrc := vsrc; IF f_strength(src) /= 'F' THEN src <= vsrc; END IF; END IF; IF pdrn /= vdrn THEN -- update when change pdrn := vdrn; IF f_strength(drn) /= 'F' THEN drn <= vdrn; END IF; END IF; END IF; END IF; END PROCESS; END bxfr_behave;