-- Simplex G-LINK S-LINK LDC -- Created on 07. Oct. 1998 -- Developers: Zoltan Meggyesi & Erik van der Bij -- Pinout and logic options in LDC.acf file -- LD (Data) bits in data mode (UTDO_N high) -- 31, 30, 29, 28, 27..24, 23..20, 19..0 -- CAV_N, DAV, ERR, FLG, URL[3..0], Reserved, Data[19..0] -- In 16 bit mode LD[19..16] is low -- Jumpers: TP(n) signal is '0' when the TP(n) jumper is plugged (on) -- TP1 off: no flag; on: flag mode -- TP2 off: 16 bit mode; on: 20 bit; -- TP3 off: Locking "2"; on: Locking "3" -- HP_SMRST0_N must be soLDered to HP_SMRST1_N pin on HP chip (It's a bug on PCB) -- Last modification: 14.12.98 -- Change made: Active low signals: xxx_N, init_machine: HP reset @ LDOWN -- HP_SMRST1_N Disabled (always '1') ---------------------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; entity LDC is port( QCLK : in std_logic; -- 40 Mhz from Quartz TP : in std_logic_vector(5 downto 1); -- Jumpers AD_OTI : in std_logic; AD_DIO : in std_logic; HP_STRBOUT : in std_logic; -- RX clock from HP HP_LINKRDY_N : in std_logic; -- High when link is active HP_CAV_N : in std_logic; -- G control word HP_DAV_N : in std_logic; -- G data word HP_ERROR : in std_logic; -- Error flag HP_FF : in std_logic; -- Fill Frame HP_FLAG : in std_logic; HP_STAT1 : in std_logic; -- HP State Machine Output HP_STAT0 : in std_logic; HP_SMRST0_N : in std_logic; -- A bug, wired to global pin HP_D : in std_logic_vector(19 downto 0); URL : in std_logic_vector(3 downto 0); URESET_N : in std_logic; UXOFF_N : in std_logic; UTDO_N : in std_logic; UDW : in std_logic_vector(1 downto 0); fr_rxsigdet : in std_logic; fr_rxsys : in std_logic_vector(1 downto 0); AD_CONVST_N : out std_logic; AD_SCLK : out std_logic; AD_RDWR : out std_logic; HP_EQEN : out std_logic; -- Cable equalization HP_FLAGSEL : out std_logic; -- Flag Mode Select HP_LOOPEN : out std_logic; -- Loopback control HP_M20SEL : out std_logic; -- 20/16 bit mode HP_SMRST1_N : out std_logic; -- State m. reset -- HP_SMRST0_N : out std_logic; -- State m. reset HP_TCLK : out std_logic; -- External test CLK HP_TCLKsel : out std_logic; -- Enable TCLK Input HP_DIV : out std_logic_vector(1 downto 0); -- Baud rate LD : out std_logic_vector(31 downto 0); LCLK : out std_logic; -- S-Link Signals LCTRL_N : out std_logic; LWEN_N : out std_logic; LDOWN_N : out std_logic; LDERR_N : out std_logic; G : out std_logic_vector(26 downto 0); -- Unused Pins are connected to ground to improvee gnd-bounce CK40TTL : out std_logic; TESTLED_N : out std_logic; -- Leds, lights when 0 DERRLED_N : out std_logic; LUPLED_N : out std_logic; FLOWCTLED_N : out std_logic); end LDC; ARCHITECTURE behavioural OF LDC IS TYPE init_state is (DOWN, UP, RES1, RES2, RES3, LERR); --attribute TYPE_ENCODING_STYLE of init_state:type is ONEHOT; TYPE reset_state is (OK, RSTNOW, WAITST); signal curr_reset, next_reset: reset_state; -- Reset machine signal curr_init, next_init: init_state; -- Link init machine signal inreg: std_logic_vector(19 downto 0); -- Input register (.q) signal rl: std_logic_vector(3 downto 0); signal errled, fled, linkrdy, cav, dav, err, flag, sys_res: std_logic; signal hpdown: std_logic; -- Registered HP_LINKRDY_N begin -- Non-registered OUTPUTS ----------------------------------------------- HP_EQEN <= '0'; -- Cable equalization disabled HP_FLAGSEL <= not TP(1); -- TP1 = vcc without jumper HP_LOOPEN <= (not HP_STAT1) and (not TP(3)); -- Simplex Method 2 if TP3='1' (off), S.M 3 if TP3 is on HP_M20SEL <= not TP(2); -- 20 bit mode with TP2 jumper HP_TCLK <= '0'; -- Not used HP_TCLKsel <= '0'; -- Test Clock input Disabled HP_DIV <= "00"; -- 700-1500 MBaud/sec -- LCLK isInverted for correct timing, check Tsu/Th on Simulator! LCLK <= not HP_STRBOUT; LCTRL_N <= '1'; -- No control words in this version TESTLED_N <= UTDO_N; -- Will indicate laser/temp measurement AD_CONVST_N <= '1'; -- active low AD_SCLK <= '0'; -- don't use A/D device now AD_RDWR <= '1'; -- Read -- gnd ouTPuts against gnd-bounce (page 532 in 1998 ALTERA data book) G <= (others => '0'); -- EDGE SENSITIVE RESET: Generates a pulse on negative URESET_N edge ---- reset_reg :process(HP_STRBOUT) begin if (HP_STRBOUT'event and HP_STRBOUT ='1') then curr_reset <= next_reset; end if; end process reset_reg; reset_machine :process(curr_reset, URESET_N) begin case curr_reset is when OK => -- No reset, URESET_N is high if (URESET_N ='0') then next_reset <= RSTNOW; else next_reset <= OK; end if; when RSTNOW => -- Reset pulse next_reset <= WAITST; when WAITST => -- Wait while URESET_N is low; if (URESET_N ='1') then next_reset <= OK; else next_reset <= WAITST; end if; when others => next_reset <= WAITST; end case; end process reset_machine; reset_out: process (curr_reset) begin case curr_reset is when RSTNOW => sys_res <= '1'; -- Active high system reset when others => sys_res <= '0'; end case; end process reset_out; -- Synchronised HPREADY (hpdown signal) ---------------------------- linkready :process(HP_STRBOUT) begin -- Synchronised HP_READY if (HP_STRBOUT'event and HP_STRBOUT='1') then hpdown <= HP_LINKRDY_N; end if; end process linkready; -- LINK INIT STATE MACHINE ----------------------------------------- init_reg :process(HP_STRBOUT) begin if (HP_STRBOUT'event and HP_STRBOUT='1') then curr_init <= next_init; end if; end process init_reg; init_machine: process (curr_init, sys_res) begin case curr_init is when DOWN => -- Wait for LINKRDY; Power-On state if (hpdown = '0') then next_init <= UP; -- Link UP if LINKRDY elsif (sys_res = '1') then next_init <= RES1; -- HP reset possible in DOWN state else next_init <= DOWN; end if; when UP => -- when LINK UP if (sys_res = '1') then next_init <= RES1; elsif (hpdown = '1') then next_init <= LERR; else next_init <= UP; end if; when RES1 => -- HP Reset Pulse Here! next_init <= RES2; -- As in S-LINK spec. when RES2 => -- LDOWN Period for 4 LCLK if (hpdown = '1') then next_init <= RES3; -- Wait fot HP-Down else NEXT_INIT <= RES2; end if; when RES3 => next_init <= DOWN; when LERR => -- Link error, quit with URESET# case sys_res is when '1' => next_init <= RES1; -- Reset HP when others => next_init <= LERR; end case; when others => -- Same as LERR (Link Error) case sys_res is when '1' => next_init <= RES1; when others => next_init <= LERR; end case; end case; end process init_machine; init_out: process (HP_STRBOUT) begin if (HP_STRBOUT'event and HP_STRBOUT='1') then case curr_init is when UP => LDOWN_N <= '1'; -- Link is active in UP state LUPLED_N <= '0'; HP_SMRST1_N <= '1'; when RES1 => LDOWN_N <= '0'; LUPLED_N <= '1'; HP_SMRST1_N <= '0'; -- Reset HP Here! when others => LDOWN_N <= '0'; LUPLED_N <= '1'; HP_SMRST1_N <= '1'; end case; end if; end process init_out; -- HP_SMRST0_N <= '1'; -- Can't be controlled because of PCB bug refclock: process (curr_init, TP(3)) begin case TP(3) is when '1' => CK40TTL <= '0'; -- TP3 off, Lock Methode "2" when others => -- TP3 on, Lock Methode "3" case curr_init is when UP => CK40TTL <= '0'; -- Disabled when link is UP when others => CK40TTL <= QCLK; end case; end case; end process refclock; -- DATA ERROR and FLOWCTRL LEDS --------------------------------- e_led: process (HP_STRBOUT) begin if (HP_STRBOUT'event and HP_STRBOUT='1') then if (err ='1') then errled <= '0'; -- Goes on on error elsif (sys_res = '1') then errled <= '1'; -- Goes off on URESET# else errled <= errled; end if; end if; DERRLED_N <= errled; end process e_led; f_led: process (HP_STRBOUT) begin -- Goes off on URESET_N#; async.preset if (HP_STRBOUT'event and HP_STRBOUT='1') then if (UXOFF_N = '0') then fled <= '0'; -- Goes on on UXOFF_N# elsif (sys_res ='1') then fled <= '1'; -- Off on URESET# else fled <= fled; end if; end if; FLOWCTLED_N <= fled; end process f_led; -- INPUT REGISTER ---------------------------------------------- inputreg: process (HP_STRBOUT) begin if (HP_STRBOUT'event and HP_STRBOUT='1') then inreg(19 downto 0) <= HP_D(19 downto 0); dav <= HP_DAV_N; -- Inverted! cav <= HP_CAV_N; -- Inverted! err <= HP_ERROR; flag <= HP_FLAG; rl(3 downto 0) <= URL(3 downto 0); end if; end process inputreg; -- OUTPUT REGISTER (pipeline) ---------------------------------- outputreg: process (HP_STRBOUT) begin if (HP_STRBOUT'event and HP_STRBOUT='1') then LD(31) <= cav; LD(30) <= dav; LD(29) <= err; LD(28) <= flag; LD(27 downto 24) <= rl(3 downto 0); LD(23 downto 20) <= ('0','0','0','0'); LD(15 downto 0) <= inreg(15 downto 0); case TP(2) is -- not HP_M20SEL when '0' => LD(19 downto 16) <= inreg(19 downto 16); -- Jumper when others => LD(19 downto 16) <= ('0','0','0','0'); -- No jumper end case; -- LWEN_N# signal is active on DAV# and CAV# ---------------------- if ((curr_init = UP) and ((dav = '0') or (cav = '0'))) then LWEN_N <= '0'; else LWEN_N <= '1'; -- LWEN_N is active low end if; LDERR_N <= '1'; --not err; -- Not used in this version end if; end process outputreg; end behavioural;