-- -- CMOS H35 Deserialiser -- Very much like the ABC130 version -- -- Deserialises 160Mb streams. Operates at 80MHz so -- data arrives in on 2 streams and is then combined. -- Packet detection operates as byte>0 -- Alignment is vi delays -- -- -- Log: -- 13/10/2014 - File re-born! -- 30/1/2015 -- Type field changed from 4 to 8 library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; library utils; use utils.pkg_types.all; library hsio; use hsio.pkg_core_globals.all; entity h35_deser is -- generic( -- LINK_ID : integer := 0 -- ); port( ts_count_i : std_logic_vector(39 downto 0); bco_mode20_i : std_logic; s20_i : std_logic; s40_i : std_logic; delay160_i : std_logic_vector(2 downto 0); mode_i : std_logic_vector(1 downto 0); -- In link4x_i : in slv4; -- Pkt Out packet_o : out std_logic_vector(63 downto 0); --t_packet; pkt_valid_o : out std_logic; pkt_rdack_i : in std_logic; -- dropped_pkts_o : out std_logic_vector(7 downto 0); capture_mode_i : in std_logic; capture_start_i : in std_logic; capture_len_i : in std_logic_vector(9 downto 0); -- infra en : in std_logic; clk : in std_logic; rst : in std_logic ); -- Declarations end h35_deser; -- architecture rtl of h35_deser is constant BCOUNT_MAX : integer := 31; constant BCOUNT_MAX_M1 : integer:= BCOUNT_MAX-1; constant BCOUNT_MAX_M2 : integer := BCOUNT_MAX-2; constant BCCAP_MAX : integer := 59; constant BCCAP_MAX_M1 : integer:= BCOUNT_MAX-1; constant BCCAP_MAX_M2 : integer := BCOUNT_MAX-2; constant OS : integer := 4; signal si : slv8_array(1 downto 0); signal pre_ser_in : slv2; signal ser_in : slv68; signal sdet : slv64_array(1 downto 0); signal pkt_valid : std_logic; signal pkt_we : std_logic; signal packet01 : slv64_array(1 downto 0); signal packet : slv64; signal pkt_dbg : slv64_array(1 downto 0); signal bcid : slv20; signal byte_data : slv8; signal byte_strb : std_logic; signal byte_data_strobed : slv8; signal delay80 : integer range 0 to 7; signal bcount : integer range 0 to 63; signal bcount_clr : std_logic; signal dropped_pkts_count : slv8; signal dropped_pkts_inc : sl; signal cap_count : slv10; signal cap_count_max : slv10; signal cap_count_inc : sl; signal cap_count_clr : sl; signal sublink : slv2; type states is ( PacketRdy, Wait_Packet, Idle_Cap, Wait_End_Cap, Idle ); signal state, nstate : states; begin bcid <= ts_count_i(20 downto 1) when (bco_mode20_i = '1') else ts_count_i(19 downto 0); -- *** this should be mode_i related ... byte_strb <= s20_i when (bco_mode20_i = '1') else s40_i; prc_link_mode : process (mode_i, link4x_i) begin case mode_i is when M320 => null; -- more work needed. when others => -- M160 is the default, no M80 sublink(0) <= link4x_i(0); sublink(1) <= link4x_i(2); end case; end process; si(0)(0) <= sublink(0); si(1)(0) <= sublink(1); prc_pre_ser_in : process (clk) begin if rising_edge(clk) then if (rst = '1') then si(0)(7 downto 1) <= (others => '0'); si(1)(7 downto 1) <= (others => '0'); else si(0)(7 downto 1) <= si(0)(6 downto 0); si(1)(7 downto 1) <= si(1)(6 downto 0); end if; end if; end process; delay80 <= conv_integer(delay160_i(2 downto 1)); pre_ser_in(0) <= si(0)(delay80); pre_ser_in(1) <= si(1)(delay80); prc_ser_in : process (clk) begin if rising_edge(clk) then if (rst = '1') then ser_in <= (others => '0'); else if (en = '1') then -- *** I'm sure 0 then 1 is wrong! Also see swap for iserdes out -- ser_in <= ser_in(65 downto 0) & pre_ser_in(0) & pre_ser_in(1); ser_in <= ser_in(65 downto 0) & pre_ser_in(1) & pre_ser_in(0); -- ***note swapped end if; end if; end if; end process; -- Deserialise ------------------------------------------------------------------------- -- Generate 160Mb offset packets for use by delay lsb -- Will have 4 streams for 320Mb gen_pkt_ser_in : for n in 0 to 1 generate begin pkt_dbg(n) <= x"8" & ser_in(59+OS-n downto 0+OS-n) when (capture_mode_i = '1') else x"8" & bcid & ser_in(39+OS-n downto 0+OS-n); packet01(n)(63 downto 0) <= x"8" & ser_in(59+OS-n downto 0+OS-n) when (capture_mode_i = '1') else x"8" & bcid & ser_in(39+OS-n downto 0+OS-n); end generate; packet <= packet01(0) when (delay160_i(0) = '1') else packet01(1); byte_data <= packet(31 downto 24); byte_data_strobed <= byte_data when (rising_edge(clk) and (byte_strb='1')); --------------------------------------------------------------- -- Deser Machine --------------------------------------------------------------- prc_sm_deser_sync : process (clk) begin if rising_edge(clk) then if (rst = '1') then state <= Idle; else state <= nstate; end if; end if; end process; prc_sm_deser_async : process (en, bcount, byte_strb, byte_data, capture_mode_i, capture_start_i, cap_count, cap_count_max, state) begin -- defaults bcount_clr <= '0'; pkt_we <= '0'; cap_count_clr <= '0'; cap_count_inc <= '0'; case state is when Idle => nstate <= Idle; bcount_clr <= '1'; if (capture_mode_i = '1') then nstate <= Idle_Cap; else if (en = '1') then if (byte_strb = '1') then if (byte_data /= x"00") then nstate <= PacketRdy; end if; end if; end if; end if; when PacketRdy => pkt_we <= '1'; nstate <= Wait_Packet; when Wait_Packet => nstate <= Wait_Packet; if (bcount = BCOUNT_MAX) then nstate <= Idle; end if; -- Capture Mode ---------------------------------------------- when Idle_Cap => nstate <= Idle_Cap; cap_count_clr <= '1'; bcount_clr <= '1'; if (capture_mode_i = '0') then nstate <= Idle; elsif (capture_start_i = '1') and (en = '1') then nstate <= Wait_End_Cap; end if; when Wait_End_Cap => nstate <= Wait_End_Cap; if (bcount = BCCAP_MAX_M2) then --if (bcount = BCCAP_MAX_M1) then --if (bcount = BCCAP_MAX) then pkt_we <= '1'; bcount_clr <= '1'; cap_count_inc <= '1'; if (cap_count = cap_count_max) then nstate <= Idle_Cap; end if; end if; end case; end process; -- Packet output interface ------------------------------------------------------------------------- prc_packet_out : process(clk) begin if rising_edge(clk) then if (rst = '1') then packet_o <= (others => '0'); pkt_valid <= '0'; else -- default dropped_pkts_inc <= '0'; if (pkt_we = '1') then packet_o <= packet; end if; if (pkt_we = '1') then pkt_valid <= '1'; --check if last one was read if (pkt_valid = '1') then dropped_pkts_inc <= '0'; end if; elsif (pkt_rdack_i = '1') then pkt_valid <= '0'; end if; end if; end if; end process; pkt_valid_o <= pkt_valid; -- Bit counter (2 bits per tick) ------------------------------------------------- prc_bcount : process (clk) begin if rising_edge(clk) then if (rst = '1') then bcount <= 0; elsif (bcount_clr = '1') then bcount <= 0; elsif (capture_mode_i = '0') and (bcount = BCOUNT_MAX) then bcount <= 0; elsif (capture_mode_i = '1') and (bcount = BCCAP_MAX) then bcount <= 0; else bcount <= bcount + 1; end if; end if; end process; -- Dropped packet counter ----------------------------------------------------- prc_dropped_pks_count : process (clk) begin if rising_edge(clk) then if (rst = '1') then dropped_pkts_count <= (others => '0'); elsif (dropped_pkts_count < x"ff") and (dropped_pkts_inc = '1') then dropped_pkts_count <= dropped_pkts_count + '1'; end if; end if; end process; dropped_pkts_o <= dropped_pkts_count; -- Capture mode len counter ----------------------------------------------------- cap_count_max <= capture_len_i; -- byte val converted to 64b words prc_capture_count : process (clk) begin if rising_edge(clk) then if (rst = '1') then cap_count <= (others => '0'); else if (cap_count_clr = '1') then cap_count <= (others => '0'); elsif (cap_count_inc = '1') then cap_count <= cap_count + '1'; end if; end if; end if; end process; end architecture rtl;