;****************************************************************************** ; di2462.txt ; ; LISTING 1 ; ; "Manchester co-decoder fits into 32-macrocell PLD," EDN, Jan 6, 2000, pg 122 ; http://www.ednmag.com/ednmag/reg/2000/010600/designideas.htm#01di2 ;****************************************************************************** List 1: --- AUTHOR : Di Rocco A. --- FUNCTION : co-decoder manchester, data throuthput 10 Mb/s , system clock 80 MHz" LIBRARY ieee ; USE ieee.std_logic_1164.ALL ; USE ieee.std_logic_arith.ALL ; USE ieee.std_logic_unsigned.ALL ; ENTITY manch IS PORT ( mr : IN STD_LOGIC; clk_80 : IN STD_LOGIC; lan_in : IN STD_LOGIC; data_in : IN STD_LOGIC; ten : IN STD_LOGIC; ------ lan_out : OUT STD_LOGIC; clk_10_out : OUT STD_LOGIC; ck_data_out : OUT STD_LOGIC; cd : OUT STD_LOGIC; data_out : OUT STD_LOGIC); END manch; ARCHITECTURE rtl OF manch IS SIGNAL clk_10 :STD_LOGIC; SIGNAL lan_out_sys :STD_LOGIC; SIGNAL data_in_sync :STD_LOGIC; SIGNAL in_trans :STD_LOGIC; SIGNAL lan_in_hi2lo :STD_LOGIC; SIGNAL lan_in_lo2hi :STD_LOGIC; SIGNAL lan_in_hi2lo_shift :STD_LOGIC_VECTOR(1 DOWNTO 0):="00"; SIGNAL filter :STD_LOGIC; SIGNAL filter_lo2hi :STD_LOGIC; SIGNAL filter_hi2lo :STD_LOGIC; SIGNAL filter_hi2lo_shift :STD_LOGIC_VECTOR(1 DOWNTO 0):="00"; SIGNAL mr_and_ten :STD_LOGIC; SIGNAL mr_and_filter_hi2lo :STD_LOGIC; SIGNAL mr_and_filter :STD_LOGIC; SIGNAL cd_sys :STD_LOGIC; SIGNAL ck_data_out_sys :STD_LOGIC; SIGNAL cd_shift :STD_LOGIC_VECTOR(5 DOWNTO 0):="000000"; SIGNAL mux_sel_ck :STD_LOGIC; SIGNAL cont_8 :STD_LOGIC_VECTOR(2 DOWNTO 0):="000"; SIGNAL cont_6 :STD_LOGIC_VECTOR(2 DOWNTO 0):="000"; SIGNAL cont_5 :STD_LOGIC_VECTOR(2 DOWNTO 0):="000"; SIGNAL cont_4 :STD_LOGIC_VECTOR(1 DOWNTO 0):="00"; BEGIN clk_80_divider : PROCESS (clk_80) BEGIN IF (clk_80'EVENT and clk_80 = '1') THEN cont_8 <= cont_8 + "001" ; clk_10 <= NOT (cont_8(2)) ; END IF ; END PROCESS clk_80_divider; --------- manchester coder -------------- mr_and_ten <= mr AND ten ; data_in_sampler : PROCESS(mr_and_ten,clk_10) BEGIN IF (mr_and_ten = '0') THEN data_in_sync<= '1'; ELSIF ((clk_10 = '1') AND (clk_10'EVENT)) THEN data_in_sync <= data_in; END IF; END PROCESS data_in_sampler; lan_out_sys <= clk_10 XOR data_in_sync ; lan_out_sys_sampler : PROCESS(mr_and_ten,clk_80) BEGIN IF (mr_and_ten = '0') THEN lan_out <= '1'; ELSIF ((clk_80 = '1') AND (clk_80'EVENT)) THEN lan_out <= lan_out_sys; END IF; END PROCESS lan_out_sys_sampler; --------- manchester decoder -------------- in_hi_2_lo_gen : PROCESS (mr,clk_80) -- "lan_in" transactions -- BEGIN IF (mr = '0') THEN lan_in_hi2lo_shift <= "00"; ELSIF (clk_80 = '1' AND clk_80'EVENT) THEN lan_in_hi2lo_shift <= lan_in_hi2lo_shift(0) & lan_in; END IF; END PROCESS in_hi_2_lo_gen; lan_in_hi2lo <= (NOT lan_in_hi2lo_shift(0)) AND lan_in_hi2lo_shift(1); lan_in_lo2hi <= lan_in_hi2lo_shift(0) AND (NOT lan_in_hi2lo_shift(1)); in_trans <= lan_in_hi2lo OR lan_in_lo2hi ; --in_trans=1 when "lan_in" commutes -- samp_filter_gen: PROCESS (mr,clk_80) -- mask for "in_trans" pulses -- BEGIN IF (mr = '0') THEN cont_6 <= "000"; filter <= '0'; ELSIF (clk_80 = '1' AND clk_80'EVENT) THEN IF (filter = '1') THEN -- during counting -- IF cont_6 = "101" THEN -- end counting -- cont_6 <= "000"; filter <= '0'; ELSE cont_6 <= cont_6 + "001"; filter <= '1'; END IF; ELSE -- during not counting -- IF (in_trans = '1') THEN -- start counting -- filter <= '1'; cont_6 <= cont_6 + "001"; ELSE filter <= '0'; cont_6 <= "000"; END IF; END IF; END IF; END PROCESS samp_filter_gen; filter_hi_2_lo_gen : PROCESS (mr,clk_80) -- "filter" transactions -- BEGIN IF (mr = '0') THEN filter_hi2lo_shift <= "00"; ELSIF (clk_80 = '1' AND clk_80'EVENT) THEN filter_hi2lo_shift <= filter_hi2lo_shift(0) & filter; END IF; END PROCESS filter_hi_2_lo_gen; filter_lo2hi <= filter_hi2lo_shift(0) AND (NOT filter_hi2lo_shift(1)); data_out_gen: PROCESS (mr,clk_80) BEGIN IF (mr = '0') THEN data_out <= '1'; ELSIF (clk_80 = '1' AND clk_80'EVENT) THEN IF (filter_lo2hi = '1') THEN data_out <= lan_in; -- resta al valore campionato fino al prossimo in_trans valido -- -- in questo modo si porta dietro il jitter della lina_in -- END IF; END IF; END PROCESS data_out_gen; filter_hi2lo <= (NOT filter_hi2lo_shift(0)) AND filter_hi2lo_shift(1); mr_and_filter_hi2lo <= mr AND (NOT filter_hi2lo); clock_data_out_gen: PROCESS (mr_and_filter_hi2lo,clk_80) -- 10 MHz clok recovery -- BEGIN IF (mr_and_filter_hi2lo = '0') THEN ck_data_out_sys <= '1'; cont_4 <= "00"; ELSIF (clk_80 = '1' AND clk_80'EVENT) THEN IF (cont_4 = "10") THEN ck_data_out_sys <= '0'; ELSE cont_4 <= cont_4 + "01"; ck_data_out_sys <= '1'; END IF; END IF; END PROCESS clock_data_out_gen; mr_and_filter <= mr AND (NOT filter); -- carrier detect generation -- carrier_detect_gen: PROCESS (mr_and_filter,clk_80) BEGIN IF (mr_and_filter = '0') THEN cont_5 <= "000"; cd_sys <= '1'; ELSIF (clk_80 = '1' AND clk_80'EVENT) THEN IF (cont_5 = "110") THEN cd_sys <= '0'; ELSE cont_5 <= cont_5 + "001"; cd_sys <= '1'; END IF; END IF; END PROCESS carrier_detect_gen; cd <= cd_sys; -- carrier detect = receiver enable -- carrier_detect_shift_gen : PROCESS (mr,clk_10) BEGIN IF (mr = '0') THEN cd_shift <= "000000"; ELSIF (clk_10 = '1' AND clk_10'EVENT) THEN cd_shift <= cd_shift(4 DOWNTO 0) & cd_sys; END IF; END PROCESS carrier_detect_shift_gen; mux_sel_ck <= cd_shift(5) AND (NOT cd_sys); ck_data_out <= clk_10 WHEN mux_sel_ck = '1' ELSE ck_data_out_sys; END rtl;