URL
https://opencores.org/ocsvn/core1990_interlaken/core1990_interlaken/trunk
Subversion Repositories core1990_interlaken
[/] [core1990_interlaken/] [trunk/] [gateware/] [sources/] [interlaken/] [receiver/] [descrambler.vhd] - Rev 11
Compare with Previous | Blame | View Log
library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.numeric_std.ALL; entity Descrambler is generic ( PacketLength : positive ); port ( Clk : in std_logic; -- System clock Reset : in std_logic; -- Descrambler reset, use for initialization Data_In : in std_logic_vector (66 downto 0); -- Data input Data_Out : out std_logic_vector (66 downto 0); -- Data output Lane_Number : in std_logic_vector (3 downto 0); -- Each lane number starts with different scrambler word Data_Valid_In : in std_logic; -- Data_Valid_Out : out std_logic; -- Output data is valid for the next component/in lock Lock : out std_logic; Error_BadSync : out std_logic; -- Bad sync words after being in lock Error_StateMismatch : out std_logic; -- Scrambler state mismatches occured more than three times Error_NoSync : out std_logic -- Bad sync and not been in lock ); end Descrambler; architecture behavior of Descrambler is type state_type is (IDLE, SYNC, LOCKED); signal pres_state : state_type; signal MetaCounter : integer range 0 to PacketLength; signal Sync_Word_Detected : std_logic; signal Sync_Words : integer range 0 to 3; signal ScramblerSyncMismatch : std_logic; signal Data_Valid_P1, Data_Valid_P2, Data_Valid : std_logic; signal Data_P1, Data_Descrambled : std_logic_vector(63 downto 0); signal Data_In_P1 : std_logic_vector(66 downto 0); --- signal scram_state_word_detected : std_logic; --- signal Scrambler_State_Mismatch : integer range 0 to 3; signal Sync_Word_Mismatch : integer range 0 to 4; signal Poly : std_logic_vector (57 downto 0); signal Shiftreg : std_logic_vector (63 downto 0); signal Data_HDR_P1, Data_HDR : std_logic_vector(2 downto 0); -- Constants constant SYNCHRONIZATION : std_logic_vector(63 downto 0) := X"78f6_78f6_78f6_78f6"; -- synchronization framing layer control word constant SCRAM_STATE_INIT_VALUE : std_logic_vector(63 downto 0) := X"2800_0000_0000_0000"; -- Starting value of scrambler constant META_TYPE_SYNCHRONIZATION_P: std_logic_vector(4 downto 0) := "11110"; constant META_TYPE_SCRAM_STATE_P: std_logic_vector(4 downto 0) := "01010"; constant META_TYPE_SYNCHRONIZATION_N: std_logic_vector(4 downto 0) := "00001"; constant META_TYPE_SCRAM_STATE_N: std_logic_vector(4 downto 0) := "10101"; begin shiftreg(63) <= Poly(57) xor Poly(38); shiftreg(62) <= Poly(56) xor Poly(37); shiftreg(61) <= Poly(55) xor Poly(36); shiftreg(60) <= Poly(54) xor Poly(35); shiftreg(59) <= Poly(53) xor Poly(34); shiftreg(58) <= Poly(52) xor Poly(33); shiftreg(57) <= Poly(51) xor Poly(32); shiftreg(56) <= Poly(50) xor Poly(31); shiftreg(55) <= Poly(49) xor Poly(30); shiftreg(54) <= Poly(48) xor Poly(29); shiftreg(53) <= Poly(47) xor Poly(28); shiftreg(52) <= Poly(46) xor Poly(27); shiftreg(51) <= Poly(45) xor Poly(26); shiftreg(50) <= Poly(44) xor Poly(25); shiftreg(49) <= Poly(43) xor Poly(24); shiftreg(48) <= Poly(42) xor Poly(23); shiftreg(47) <= Poly(41) xor Poly(22); shiftreg(46) <= Poly(40) xor Poly(21); shiftreg(45) <= Poly(39) xor Poly(20); shiftreg(44) <= Poly(38) xor Poly(19); shiftreg(43) <= Poly(37) xor Poly(18); shiftreg(42) <= Poly(36) xor Poly(17); shiftreg(41) <= Poly(35) xor Poly(16); shiftreg(40) <= Poly(34) xor Poly(15); shiftreg(39) <= Poly(33) xor Poly(14); shiftreg(38) <= Poly(32) xor Poly(13); shiftreg(37) <= Poly(31) xor Poly(12); shiftreg(36) <= Poly(30) xor Poly(11); shiftreg(35) <= Poly(29) xor Poly(10); shiftreg(34) <= Poly(28) xor Poly(9); shiftreg(33) <= Poly(27) xor Poly(8); shiftreg(32) <= Poly(26) xor Poly(7); shiftreg(31) <= Poly(25) xor Poly(6); shiftreg(30) <= Poly(24) xor Poly(5); shiftreg(29) <= Poly(23) xor Poly(4); shiftreg(28) <= Poly(22) xor Poly(3); shiftreg(27) <= Poly(21) xor Poly(2); shiftreg(26) <= Poly(20) xor Poly(1); shiftreg(25) <= Poly(19) xor Poly(0); shiftreg(24) <= Poly(57) xor Poly(38) xor Poly(18); shiftreg(23) <= Poly(56) xor Poly(37) xor Poly(17); shiftreg(22) <= Poly(55) xor Poly(36) xor Poly(16); shiftreg(21) <= Poly(54) xor Poly(35) xor Poly(15); shiftreg(20) <= Poly(53) xor Poly(34) xor Poly(14); shiftreg(19) <= Poly(52) xor Poly(33) xor Poly(13); shiftreg(18) <= Poly(51) xor Poly(32) xor Poly(12); shiftreg(17) <= Poly(50) xor Poly(31) xor Poly(11); shiftreg(16) <= Poly(49) xor Poly(30) xor Poly(10); shiftreg(15) <= Poly(48) xor Poly(29) xor Poly(9); shiftreg(14) <= Poly(47) xor Poly(28) xor Poly(8); shiftreg(13) <= Poly(46) xor Poly(27) xor Poly(7); shiftreg(12) <= Poly(45) xor Poly(26) xor Poly(6); shiftreg(11) <= Poly(44) xor Poly(25) xor Poly(5); shiftreg(10) <= Poly(43) xor Poly(24) xor Poly(4); shiftreg(9) <= Poly(42) xor Poly(23) xor Poly(3); shiftreg(8) <= Poly(41) xor Poly(22) xor Poly(2); shiftreg(7) <= Poly(40) xor Poly(21) xor Poly(1); shiftreg(6) <= Poly(39) xor Poly(20) xor Poly(0); shiftreg(5) <= Poly(57) xor Poly(19); shiftreg(4) <= Poly(56) xor Poly(18); shiftreg(3) <= Poly(55) xor Poly(17); shiftreg(2) <= Poly(54) xor Poly(16); shiftreg(1) <= Poly(53) xor Poly(15); shiftreg(0) <= Poly(52) xor Poly(14); detection : process (Clk, Reset) is begin if(Reset = '1') then Sync_Word_Detected <= '0'; elsif (rising_edge(clk)) then if (Data_In(65 downto 64) = "10") and (Data_In(63 downto 0) = SYNCHRONIZATION) then Sync_Word_Detected <= '1'; else Sync_Word_Detected <= '0'; end if; end if; end process detection; data : process (clk, reset) is begin if (reset = '1') then Data_Out <= (others => '0'); elsif (rising_edge(clk)) then Data_Out <= Data_HDR_P1 & Data_P1; Data_Valid_Out <= Data_Valid_P1; Data_Valid_P1<= Data_Valid; end if; end process data; -- state_register : process (clk) is -- begin -- if (rising_edge(clk)) then -- pres_state <= next_state; -- end if; -- end process state_register; -- state_decoder : process (pres_state, Sync_Word_Detected, MetaCounter, Sync_words, ScramblerSyncMismatch) is -- begin -- case pres_state is -- when IDLE => -- if(Sync_Word_Detected = '1') then -- next_state <= SYNC; -- else -- next_state <= IDLE; -- end if; -- when SYNC => -- if(Sync_Words = 3 and Sync_Word_Detected = '1') then -- next_state <= LOCKED; -- elsif(Sync_Words = 0) then -- next_state <= IDLE; -- else -- next_state <= SYNC; -- end if; -- when LOCKED => -- if(ScramblerSyncMismatch = '1') then -- next_state <= IDLE; -- else -- next_state <= LOCKED; -- end if; -- when others => -- next_state <= IDLE; -- end case; -- end process state_decoder; output : process (clk) is begin if rising_edge(clk) then lock <= '0'; case pres_state is when IDLE => Data_P1 <= (others => '0'); -- Reset data registers and polynomial Data_Descrambled <= (others => '0'); Poly <= (others => '1'); Poly(57 downto 54) <= Lane_Number(3 downto 0); Error_StateMismatch <= '0'; -- Reset error conditions Error_NoSync <= '0'; Error_BadSync <= '0'; MetaCounter <= 0; -- Reset other values Data_HDR <= Data_In(66)&"10"; Data_HDR_P1 <= Data_In(66)&"10"; ScramblerSyncMismatch <= '0'; Scrambler_State_Mismatch <= 0; Sync_Word_Mismatch <= 0; Data_Valid <= '0'; if(Sync_Word_Detected = '1') then MetaCounter <= 1; Sync_Words <= Sync_Words + 1; pres_state <= SYNC; end if; when SYNC => if (Data_Valid_In = '1') then MetaCounter <= MetaCounter + 1; if(MetaCounter = 0) then --if Data_In(63 downto 0) = SYNCHRONIZATION then if(Sync_Word_Detected = '1') then --First position in metaframe should contain sync Sync_Words <= Sync_Words + 1; if(Sync_Words = 3) then Sync_Words <= 0; Data_Descrambled <= SCRAM_STATE_INIT_VALUE;--X"2800_0000_0000_0000"; Data_P1 <= SYNCHRONIZATION; Data_HDR <= Data_In(66)&"10"; Data_HDR_P1 <= Data_In(66)&"10"; Poly <= Data_In(57 downto 0); -- Scrambler state in poly pres_state <= LOCKED; end if; else Error_NoSync <= '1'; pres_state <= IDLE; end if; end if; if(MetaCounter = (PacketLength-1)) then MetaCounter <= 0; end if; end if; if Sync_Words = 0 then pres_state <= IDLE; end if; when LOCKED => Lock <= '1'; Data_Valid <= '0'; Data_P1 <= Data_Descrambled; Data_HDR_P1 <= Data_HDR; scram_state_word_detected <= '0'; if (Data_Valid_In = '1') then Data_Valid <= '1'; MetaCounter <= MetaCounter + 1; Data_HDR <= Data_In(66 downto 64); --Data_In_P1 <= Data_In; --- if (Data_in(65 downto 64) = "10" and Data_In(63) = '0' and MetaCounter = 0 and ((Data_In(62 downto 58) = META_TYPE_SCRAM_STATE_P ) or (Data_In(62 downto 58) = META_TYPE_SCRAM_STATE_N )) ) then scram_state_word_detected <= '1'; Poly <= Data_In(57 downto 0); Data_Descrambled <= Data_In(63 downto 0); if(Data_In(57 downto 0) /= Poly) then --if(Data_In_P1(57 downto 0) /= Poly) then --- Scrambler_State_Mismatch <= Scrambler_State_Mismatch + 1; if(Scrambler_State_Mismatch = 2) then ScramblerSyncMismatch <= '1'; Error_StateMismatch <= '1'; Scrambler_State_Mismatch <= 0; Sync_Words <= 0; pres_state <= IDLE; end if; end if; elsif (Data_in(65 downto 64) = "10" and Data_In(63) = '0' and Data_In(63 downto 0) = SYNCHRONIZATION ) then --((Data_In(62 downto 58) = META_TYPE_SYNCHRONIZATION_P and Data_In(66) = '0') or --(Data_In(62 downto 58) = META_TYPE_SYNCHRONIZATION_N and Data_In(66) = '1')) --) then MetaCounter <= 0; if(MetaCounter /= (PacketLength-1)) then Sync_Word_Mismatch <= Sync_Word_Mismatch + 1; if(Sync_Word_Mismatch = 3) then Error_BadSync <= '1'; Sync_Word_Mismatch <= 0; ScramblerSyncMismatch <= '1'; pres_state <= IDLE; end if; end if; Data_Descrambled <= Data_in(63 downto 0); else -- No Synchronization or scrambler state detected, apply descrambler to data and update Poly Poly <= shiftreg(57 downto 0); Data_Descrambled <= Data_In(63 downto 0) xor (Poly(57 downto 0) & Shiftreg(63 downto 58)); end if; end if; when others => pres_state <= IDLE; end case; end if; end process output; end architecture behavior;