---------------------------------------------------------------------------------- -- Company: -- Engineer: -- -- Create Date: 15:55:15 07/09/2010 -- Design Name: -- Module Name: AMC_Link - Behavioral -- Project Name: -- Target Devices: -- Tool versions: -- Description: -- -- Dependencies: -- -- Revision: -- Revision 0.01 - File Created -- Additional Comments: ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; use IEEE.std_logic_misc.all; use work.amc13_pack.all; -- Uncomment the following library declaration if using -- arithmetic functions with Signed or Unsigned values --use IEEE.NUMERIC_STD.ALL; -- Uncomment the following library declaration if instantiating -- any Xilinx primitives in this code. library UNISIM; use UNISIM.VComponents.all; Library UNIMACRO; use UNIMACRO.vcomponents.all; entity AMC_Link is generic(N : integer := 14; simulation : boolean := false); -- M controls FIFO size, N controls timeout port( sysclk : in std_logic; -- 200MHz reset : in std_logic; resetCntr : in std_logic; fifo_rst : in std_logic; fifo_en : in std_logic; test : in std_logic; strobe2ms : in std_logic; NoReSyncFake : in std_logic; UsrClk : in std_logic; Ready : out std_logic; -- Link to AMC established AMC_ID : in STD_LOGIC_VECTOR(3 downto 0); txfsmresetdone : in std_logic; RxResetDone : in std_logic; qpll_lock : in std_logic; rxcommaalignen : out std_logic; DATA_VALID : out std_logic; RXDATA : in std_logic_vector(15 downto 0); RXCHARISCOMMA : in std_logic_vector(1 downto 0); RXCHARISK : in std_logic_vector(1 downto 0); RXNOTINTABLE : in std_logic_vector(1 downto 0); TXDATA : out std_logic_vector(15 downto 0); TXCHARISK : out std_logic_vector(1 downto 0); ------------- AMCinfo : out std_logic_vector(15 downto 0); EventInfo : out std_logic_vector(31 downto 0); EventInfo_dav : out std_logic; AMC_en : in std_logic; AMC_DATA_RdEn : in std_logic; -- enable reading AMC event EventInfoRdDone : in std_logic; -- end of reading AMC event AMC_DATA : out std_logic_vector(63 downto 0); L1A_DATA : in std_logic_vector(15 downto 0); L1A_WrEn : in std_logic; fake_header : in std_logic; fake_CRC : in std_logic; fake_DATA : in std_logic_vector(15 downto 0); -- fake_evn : in std_logic_vector(3 downto 0); fake_WrEn : in std_logic; fake_full : out std_logic; -- fake_accept : in std_logic; bad_AMC : out std_logic; AMC_OK : out std_logic; -- scan counters -- Cntr_RdEn : in std_logic; -- Cntr_RdEnp : in std_logic; Cntr_ADDR : in std_logic_vector(11 downto 0); Cntr_DATA : out std_logic_vector(15 downto 0); -- ipbus read signals -- ipb_addr : in std_logic_vector(15 downto 0); -- ipb_rdata : out std_logic_vector(31 downto 0); debug_out : out std_logic_vector(255 downto 0); -- TTC & TTS signals TTCclk : in std_logic; BC0 : in std_logic; -- AMC13 BC0 delayed by four TTC_clk cycles TTC_LOS : in std_logic; TTS_disable : in std_logic; TTC_status : out std_logic_vector(127 downto 0); TrigData : out std_logic_vector(7 downto 0); -- TTS is in the UsrClk domain TTS_RQST : out std_logic_vector(2 downto 0); TTS_coded : out std_logic_vector(4 downto 0)-- Disconnected, Error, Sync Lost, Busy and Overflow Warning ); end AMC_Link; architecture Behavioral of AMC_Link is COMPONENT HammingDecode PORT( clk : IN std_logic; din_valid : IN std_logic; din : IN std_logic_vector(23 downto 0); dout_valid : OUT std_logic; dout : OUT std_logic_vector(17 downto 0); sgl_err : OUT std_logic; dbl_err : OUT std_logic ); END COMPONENT; COMPONENT crc16D16 PORT( clk : IN std_logic; init_crc : IN std_logic; we_crc : IN std_logic; d : IN std_logic_vector(15 downto 0); crc : OUT std_logic_vector(15 downto 0) ); END COMPONENT; COMPONENT EthernetCRCD16B PORT( clk : IN std_logic; init : IN std_logic; save : IN std_logic; restore : IN std_logic; ce : IN std_logic; d : IN std_logic_vector(15 downto 0); crc : OUT std_logic_vector(31 downto 0); bad_crc : OUT std_logic ); END COMPONENT; COMPONENT AMC_DATA_FIFO PORT( wclk : IN std_logic; rclk : IN std_logic; reset : IN std_logic; fifo_en : IN std_logic; we : IN std_logic; re : IN std_logic; Di : IN std_logic_vector(63 downto 0); Do : OUT std_logic_vector(63 downto 0); WRERR_OUT : OUT std_logic_vector(7 downto 0); RDERR_OUT : OUT std_logic_vector(7 downto 0); full : OUT std_logic ); END COMPONENT; COMPONENT TTC_trigger generic(simulation : boolean := false); PORT( reset : IN std_logic; UsrClk : IN std_logic; TTCclk : IN std_logic; HammingData_in : IN std_logic_vector(17 downto 0); HammingDataValid : IN std_logic; BC0 : IN std_logic; BcntMm : OUT std_logic; TTC_lock : OUT std_logic; BC0_lock : OUT std_logic; TrigData : OUT std_logic_vector(7 downto 0) ); END COMPONENT; constant Acknowledge : std_logic_vector(7 downto 0) := x"12"; constant data : std_logic_vector(7 downto 0) := x"34"; constant InitRqst : std_logic_vector(7 downto 0) := x"56"; constant Counter : std_logic_vector(7 downto 0) := x"78"; constant K_word : std_logic_vector(15 downto 0) := x"3cbc"; -- sequence K28.5 K28.1 constant R_word : std_logic_vector(15 downto 0) := x"dcfb"; -- sequence K27.7 K28.6 constant eof_word : std_logic_vector(15 downto 0) := x"5cf7"; -- sequence K23.7 K28.2 constant IDLE : std_logic_vector(3 downto 0) := x"0"; -- TxState constant SendK : std_logic_vector(3 downto 0) := x"1"; -- TxState sending comma constant SendType : std_logic_vector(3 downto 0) := x"2"; -- TxState sending event data words constant SendSEQ : std_logic_vector(3 downto 0) := x"3"; -- TxState sending sequence number constant SendWC : std_logic_vector(3 downto 0) := x"4"; -- TxState sending payload word count constant WaitCRC : std_logic_vector(3 downto 0) := x"5"; -- TxState same as IDLE constant SendCRC : std_logic_vector(3 downto 0) := x"6"; -- TxState sending CRC constant SendData : std_logic_vector(3 downto 0) := x"7"; -- TxState sending event data words signal AMCRdy : std_logic := '0'; signal AMC_IDp1: std_logic_vector(3 downto 0) := (others => '0'); signal AMC_IDp4: std_logic_vector(3 downto 0) := (others => '0'); signal TxState: std_logic_vector(3 downto 0) := (others => '0'); signal InitLink : std_logic := '0'; signal RxResetDoneSyncRegs : std_logic_vector(2 downto 0) := (others => '0'); signal RXDATA_q : std_logic_vector(15 downto 0) := (others => '0'); signal TXDATA_i : std_logic_vector(15 downto 0) := (others => '0'); signal reset_SyncRegs : std_logic_vector(3 downto 0) := (others => '0'); signal fake_evn : std_logic_vector(3 downto 0) := (others => '0'); signal sgl_err : std_logic := '0'; signal dbl_err : std_logic := '0'; signal sel_TTC : std_logic := '0'; signal is_TTS : std_logic := '0'; signal update_TTS : std_logic := '0'; signal SendTTS : std_logic := '0'; signal TTS_in : std_logic_vector(3 downto 0) := (others => '0'); signal TTS_tmp : std_logic_vector(7 downto 0) := (others => '0'); signal TTS : std_logic_vector(7 downto 0) := (others => '0'); signal TTS_coded_i : std_logic_vector(4 downto 0) := (others => '0'); signal TTS_valid : std_logic := '0'; signal TTC_lock : std_logic := '0'; signal BC0_lock : std_logic := '0'; signal BcntMm : std_logic := '0'; signal BC0_link : std_logic := '0'; signal BC0_matchCntr : std_logic_vector(8 downto 0) := (others => '0'); signal TTC_missingCntr : std_logic_vector(3 downto 0) := (others => '0'); signal HammingOutValid : std_logic := '0'; signal bcnt_link : std_logic_vector(11 downto 0) := (others => '0'); signal ec_delta_BC0 : std_logic := '0'; signal delta_BC0 : std_logic_vector(3 downto 0) := (others => '0'); signal MmCntr : std_logic_vector(3 downto 0) := (others => '0'); signal TTC_DataValid : std_logic := '0'; signal TTC_Data : std_logic_vector(23 downto 0) := (others => '0'); signal TTC_FIFO_we : std_logic := '0'; signal HammingOut : std_logic_vector(17 downto 0) := (others => '0'); signal TTC_FIFO_Di : std_logic_vector(11 downto 0) := (others => '0'); signal TTC_FIFO_Do : std_logic_vector(11 downto 0) := (others => '0'); signal TTC_FIFO_Do_dl : std_logic_vector(8 downto 0) := (others => '0'); signal TTC_FIFO_DoValid : std_logic := '0'; signal TTC_FIFO_wa : std_logic_vector(4 downto 0) := (others => '0'); signal TTC_FIFO_wa0_SyncRegs : std_logic_vector(2 downto 0) := (others => '0'); signal TTC_FIFO_ra : std_logic_vector(4 downto 0) := (others => '0'); signal BC0_offset : std_logic_vector(3 downto 0) := (others => '0'); signal check_packet : std_logic := '0'; signal ACK : std_logic := '0'; signal Abort : std_logic := '0'; signal CntrAbort : std_logic := '0'; signal bad_K : std_logic := '0'; signal SEQ_OK : std_logic := '0'; signal CRC_OK : std_logic := '0'; signal frame_OK : std_logic := '0'; signal ACK_OK : std_logic := '0'; signal WC_OKp : std_logic := '0'; signal WC_OK : std_logic := '0'; signal TypeInit : std_logic := '0'; signal TypeACK : std_logic := '0'; signal TypeData : std_logic := '0'; signal TypeData_q : std_logic := '0'; signal TypeCntr : std_logic := '0'; signal Receiving : std_logic := '0'; signal Receiving_q : std_logic := '0'; signal Header2 : std_logic := '0'; signal IsACK : std_logic := '0'; signal ACKNUM_full : std_logic := '0'; signal ACKNUM_empty : std_logic := '0'; signal ACKNUM_IN : std_logic_vector(7 downto 0) := (others => '0'); signal RxSEQNUM : std_logic_vector(7 downto 0) :=(others => '0'); signal SEQNUM : std_logic_vector(7 downto 0) :=(others => '0'); signal NextSEQNUM : std_logic_vector(7 downto 0) :=(others => '0'); signal ACKNUM : std_logic_vector(7 downto 0) := (others => '0'); signal CntrACKNUM : std_logic_vector(7 downto 0) := (others => '0'); signal ACKNUM_MUX : std_logic_vector(7 downto 0) := (others => '0'); signal ACKNUM_l : std_logic_vector(7 downto 0) := (others => '0'); signal ACKNUM_a : std_logic_vector(1 downto 0) := (others => '1'); signal RxType : std_logic_vector(15 downto 0) := (others => '0'); signal RxWC : std_logic_vector(11 downto 0) := (others => '0'); signal AMC_TTS : std_logic_vector(3 downto 0) := (others => '0'); signal LinkVersion : std_logic_vector(7 downto 0) := (others => '0'); signal accept : std_logic := '0'; signal CntrAccept : std_logic := '0'; signal we_ACKNUM : std_logic := '0'; signal save_start_addr : std_logic := '0'; signal eof : std_logic := '0'; signal got_eof : std_logic := '0'; signal fake_got_eof : std_logic := '0'; signal BOE : std_logic := '0'; signal AMCinfo_word : std_logic := '0'; signal saved_BOE : std_logic := '0'; signal dl_cntr : std_logic_vector(2 downto 0) := (others => '0'); signal we_rfifo : std_logic := '0'; signal rfifo : std_logic_vector(15 downto 0) := (others => '0'); signal rfifo_a : std_logic_vector(1 downto 0) := (others => '1'); signal EventBuf_ovf : std_logic := '0'; signal EventBuf_full : std_logic := '0'; signal ec_EventBuf_ra : std_logic := '0'; signal ec_EventBuf_ra_q : std_logic := '0'; signal evn_word : std_logic_vector(2 downto 0) := (others => '0'); signal get_evn : std_logic := '0'; signal evn_OK : std_logic_vector(5 downto 0) := (others => '0'); signal evn : std_logic_vector(7 downto 0) := (others => '0'); signal LengthMatch : std_logic := '0'; signal UnknownLength : std_logic := '0'; signal bad_EventLength : std_logic := '0'; signal bad_AMCCRC : std_logic := '0'; signal InitAMCCRC : std_logic := '0'; signal AMCCRC : std_logic_vector(31 downto 0) := (others => '0'); signal EventBuf_we : std_logic_vector(0 downto 0) := (others => '0'); signal EventBuf_start : std_logic_vector(12 downto 0) := (others => '0'); signal EventBuf_wa : std_logic_vector(12 downto 0) := (others => '0'); signal EventBuf_ra : std_logic_vector(10 downto 0) := (others => '0'); signal EventBuf_wc : std_logic_vector(10 downto 0) := (others => '0'); signal EventBuf_space : std_logic_vector(10 downto 0) := (others => '0'); signal EventBuf_Di : std_logic_vector(15 downto 0) := (others => '0'); signal EventBuf_Do : std_logic_vector(63 downto 0) := (others => '0'); signal EventWC : std_logic_vector(19 downto 0) := (others => '0'); signal EventWC_tmp : std_logic_vector(19 downto 0) := (others => '0'); signal AMCinfoDi : std_logic_vector(15 downto 0) := (others => '0'); signal EventInfoDi : std_logic_vector(31 downto 0) := (others => '0'); signal EventInfoDo : std_logic_vector(31 downto 0) := (others => '0'); signal EventInfo_a : std_logic_vector(3 downto 0) := (others => '1'); signal EventInfo_ovfl : std_logic_vector(1 downto 0) := (others => '1'); signal EventInfoToggleSyncRegs : std_logic_vector(3 downto 0) := (others => '0'); signal EventInfo_full : std_logic := '0'; signal EventInfo_dav_i : std_logic := '0'; signal we_EventInfo : std_logic := '0'; signal end_of_block : std_logic := '0'; signal end_of_event : std_logic := '0'; signal EventInfoToggle : std_logic := '0'; signal EventInfoToggle_q : std_logic := '0'; signal re_EventInfo : std_logic := '0'; signal EventInfoRdDoneToggle : std_logic := '0'; signal EventInfoRdDoneToggleSyncRegs : std_logic_vector(3 downto 0) := (others => '0'); signal we_RxCRC : std_logic := '0'; signal Init_RxCRC : std_logic := '0'; signal RxCRC : std_logic_vector(15 downto 0) := (others => '0'); signal L1Ainfo_we : std_logic_vector(0 downto 0) := (others => '0'); signal L1Ainfo_wa : std_logic_vector(9 downto 0) := (others => '0'); signal L1Ainfo_ra : std_logic_vector(9 downto 0) := (others => '0'); signal L1Ainfo_start : std_logic_vector(7 downto 0) := (others => '0'); signal L1AinfoDo : std_logic_vector(15 downto 0) := (others => '0'); signal L1Ainfo_wa2SyncRegs : std_logic_vector(3 downto 0) := (others => '0'); signal L1Ainfo_wap : std_logic_vector(7 downto 0) := (others => '0'); signal ec_L1Ainfo_ra : std_logic := '0'; signal re_L1AinfoDo : std_logic := '0'; signal L1Ainfo_empty : std_logic := '0'; signal timer : std_logic_vector(N downto 0) := (others => '0'); signal ReSend : std_logic := '0'; signal ReSend_l : std_logic := '0'; signal ReSendQueIn : std_logic_vector(15 downto 0) := (others => '0'); signal ReSendQueOut : std_logic_vector(15 downto 0) := (others => '0'); signal we_ReSendQue : std_logic := '0'; signal ReSendQue_a : std_logic_vector(1 downto 0) := (others => '1'); signal ReSendQue_empty : std_logic := '0'; signal ReSendQue_full : std_logic := '0'; signal got_comma : std_logic := '0'; signal GotCntr : std_logic := '0'; signal L1Asent : std_logic := '0'; signal TxType : std_logic_vector(7 downto 0) := (others => '0'); signal packet_wc : std_logic_vector(1 downto 0) := (others => '0'); signal we_TxCRC : std_logic := '0'; signal Init_TxCRC : std_logic := '0'; signal TxCRC : std_logic_vector(15 downto 0) := (others => '0'); signal TxIsK : std_logic := '0'; signal Cntr_RdEn : std_logic := '0'; signal we_CntrBuf : std_logic := '0'; signal CntrBuf_Di : std_logic_vector(15 downto 0) := (others => '0'); signal CntrBuf_Do : std_logic_vector(15 downto 0) := (others => '0'); signal CntrBuf_wa : std_logic_vector(5 downto 0) := (others => '0'); signal CntrBuf_ra : std_logic_vector(5 downto 0) := (others => '0'); signal we_CntrBuf2p : std_logic := '0'; signal we_CntrBuf2 : std_logic := '0'; signal CntrBuf2_Di : std_logic_vector(15 downto 0) := (others => '0'); signal CntrBuf2_SPO : std_logic_vector(15 downto 0) := (others => '0'); signal CntrBuf2_SPO_q : std_logic_vector(15 downto 0) := (others => '0'); signal CntrBuf2_Do : std_logic_vector(15 downto 0) := (others => '0'); signal CntrBuf2_wa : std_logic_vector(5 downto 0) := (others => '0'); signal resetCntrCycle : std_logic := '0'; signal CntrBuf_valid : std_logic := '0'; signal cntrs : std_logic_vector(6 downto 0) := (others => '0'); signal sglErrCntr : std_logic_vector(6 downto 0) := (others => '0'); signal dblErrCntr : std_logic_vector(6 downto 0) := (others => '0'); signal BC0mmCntr : std_logic_vector(6 downto 0) := (others => '0'); signal BcntMmCntr : std_logic_vector(6 downto 0) := (others => '0'); signal ResendCntr : std_logic_vector(6 downto 0) := (others => '0'); signal AcceptCntr : std_logic_vector(6 downto 0) := (others => '0'); signal CntrAcceptCntr : std_logic_vector(6 downto 0) := (others => '0'); signal TotalWordCntr : std_logic_vector(15 downto 0) := (others => '0'); signal ACKcntr : std_logic_vector(6 downto 0) := (others => '0'); signal AbortCntr : std_logic_vector(6 downto 0) := (others => '0'); signal RxEventCntr : std_logic_vector(6 downto 0) := (others => '0'); signal RdEventCntr : std_logic_vector(6 downto 0) := (others => '0'); signal DataAbortCntr : std_logic_vector(6 downto 0) := (others => '0'); signal CntrAbortCntr : std_logic_vector(6 downto 0) := (others => '0'); signal BUSYCntr : std_logic_vector(6 downto 0) := (others => '0'); signal EvtEVNmmCntr : std_logic_vector(6 downto 0) := (others => '0'); signal EvtBCNmmCntr : std_logic_vector(6 downto 0) := (others => '0'); signal EvtOCNmmCntr : std_logic_vector(6 downto 0) := (others => '0'); signal ACKNUM_fullAbortCntr : std_logic_vector(6 downto 0) := (others => '0'); signal EventInfo_fullAbortCntr : std_logic_vector(6 downto 0) := (others => '0'); signal EventBuf_fullAbortCntr : std_logic_vector(6 downto 0) := (others => '0'); signal SEQAbortCntr : std_logic_vector(6 downto 0) := (others => '0'); signal CRCAbortCntr : std_logic_vector(6 downto 0) := (others => '0'); signal frameAbortCntr : std_logic_vector(6 downto 0) := (others => '0'); signal bad_KAbortCntr : std_logic_vector(6 downto 0) := (others => '0'); signal bad_EventLengthCntr : std_logic_vector(6 downto 0) := (others => '0'); signal BlockCntr : std_logic_vector(6 downto 0) := (others => '0'); signal badCRCCntr : std_logic_vector(6 downto 0) := (others => '0'); signal TTSCntr : std_logic_vector(6 downto 0) := (others => '0'); signal TTCCntr : std_logic_vector(6 downto 0) := (others => '0'); signal TTS_ERRcntr : std_logic_vector(6 downto 0) := (others => '0'); signal TTS_DCcntr : std_logic_vector(6 downto 0) := (others => '0'); signal TTS_OOScntr : std_logic_vector(6 downto 0) := (others => '0'); signal TTS_BSYcntr : std_logic_vector(6 downto 0) := (others => '0'); signal TTS_OFWcntr : std_logic_vector(6 downto 0) := (others => '0'); signal WordCntr : std_logic_vector(15 downto 0) := (others => '0'); signal WordCntr_q : std_logic_vector(15 downto 0) := (others => '0'); signal AllZero : std_logic := '0'; signal zeroWordCntr : std_logic_vector(15 downto 0) := (others => '0'); signal Cntr_ra : std_logic_vector(8 downto 0) := (others => '0'); signal TTS_wa : std_logic_vector(1 downto 0) := (others =>'0'); signal TTS_wa0_SyncRegs : std_logic_vector(1 downto 0) := (others =>'0'); signal TTS_wa1_SyncRegs : std_logic_vector(1 downto 0) := (others =>'0'); signal TTS_InvalidCntr : std_logic_vector(15 downto 0) := (others =>'0'); signal TTS_UpdateCntr : std_logic_vector(15 downto 0) := (others =>'0'); signal RxNotInTableCntr : std_logic_vector(15 downto 0) := (others =>'0'); signal EofMissingCntr : std_logic_vector(15 downto 0) := (others =>'0'); signal WC11p : std_logic := '0'; signal WC11 : std_logic := '0'; signal RxNotInTableErr : std_logic := '0'; signal fake_CRC_q : std_logic := '0'; signal fake_CRC_q2 : std_logic := '0'; signal AMCCRC_q : std_logic_vector(15 downto 0) := (others => '0'); signal AMC_DATA_full : std_logic := '0'; signal AMC_DATA_WrEn : std_logic := '0'; signal AMC_DATA_Di : std_logic_vector(63 downto 0) := (others => '0'); signal WRERR : std_logic_vector(7 downto 0) := (others => '0'); signal RDERR : std_logic_vector(7 downto 0) := (others => '0'); signal RDCOUNT : array8x12; signal WRCOUNT : array8x12; signal block32K : std_logic := '0'; signal EventWC_carry : std_logic := '0'; signal LengthInHeader : std_logic_vector(19 downto 0) := (others => '0'); signal LengthInTrailer : std_logic_vector(19 downto 0) := (others => '0'); signal Ready_i : std_logic := '0'; signal TTS_wait : std_logic_vector(7 downto 0) := (others => '0'); signal TTS_DC_cntr : std_logic_vector(6 downto 0) := (others => '0'); signal TTS_SL_cntr : std_logic_vector(6 downto 0) := (others => '0'); signal TTS_ERR_cntr : std_logic_vector(6 downto 0) := (others => '0'); signal critical_TTS : std_logic_vector(1 downto 0) := (others =>'0'); signal critical_TTS_cntr : std_logic_vector(1 downto 0) := (others =>'0'); signal GotMismatch : std_logic := '0'; signal FirstMismatch : std_logic_vector(31 downto 0) := (others => '0'); signal LiveTime : std_logic_vector(7 downto 0) := (others => '0'); signal LiveTimeCntr : std_logic_vector(18 downto 0) := (others => '0'); begin --debug_out(255 downto 83) <= (others => '0'); --debug_out(82) <= L1ASent; --debug_out(81) <= AMC_DATA_WrEn; --debug_out(80 downto 17) <= AMC_DATA_Di; --debug_out(16) <= EventBuf_we(0); --debug_out(15 downto 0) <= EventBuf_Di; rxcommaalignen <= RxResetDoneSyncRegs(2); TXDATA <= TXDATA_i; EventInfo_dav <= EventInfo_dav_i; AMC_OK <= AMCRdy; Ready <= Ready_i; TTC_status(0) <= BC0_lock when flavor = "HCAL" else '0'; TTC_status(1) <= TTC_lock when flavor = "HCAL" else '0'; --TTC_status(5 downto 2) <= TTC_FIFO_ra(3 downto 0); --TTC_status(14 downto 6) <= TTC_FIFO_Di(8 downto 0); --TTC_status(18 downto 15) <= TTC_FIFO_wa(3 downto 0); --TTC_status(27 downto 19) <= TTC_FIFO_Do(8 downto 0); --TTC_status(45 downto 28) <= HammingOut when HammingOutValid = '1' else (others => '0'); --TTC_status(49 downto 46) <= delta_BC0; --TTC_status(53 downto 50) <= MmCntr; --TTC_status(54) <= TTC_DataValid; --TTC_status(78 downto 55) <= TTC_Data; --TTC_status(79) <= TTC_FIFO_we; --TTC_status(80) <= sgl_err; --TTC_status(81) <= dbl_err; --TTC_status(127 downto 82) <= (others => '0'); debug_out(0) <= EventInfoDi(21); debug_out(6 downto 1) <= evn_OK; debug_out(14 downto 7) <= evn; debug_out(30 downto 15) <= RXDATA; debug_out(32 downto 31) <= RXCHARISK; debug_out(34 downto 33) <= RXCHARISCOMMA; debug_out(35) <= check_packet; debug_out(36) <= accept; debug_out(37) <= eof; debug_out(38) <= got_eof; debug_out(39) <= get_evn; debug_out(40) <= header2; debug_out(41) <= end_of_event; debug_out(42) <= end_of_block; debug_out(43) <= we_EventInfo; debug_out(44) <= TypeDATA; debug_out(45) <= sel_TTC; debug_out(46) <= Receiving; debug_out(49 downto 47) <= evn_word; debug_out(61 downto 50) <= RxWC; debug_out(255 downto 62) <= (others => '0'); TTS_coded <= TTS_coded_i; process(UsrClk) variable c : std_logic_vector(3 downto 0); variable s : std_logic_vector(3 downto 0); begin c(0) := RXDATA(8) xor RXDATA(9) xor RXDATA(11) xor RXDATA(12); c(1) := RXDATA(8) xor RXDATA(10) xor RXDATA(11) xor RXDATA(13); c(2) := RXDATA(9) xor RXDATA(10) xor RXDATA(11) xor RXDATA(14); c(3) := not RXDATA(11) xor RXDATA(12) xor RXDATA(13) xor RXDATA(14) xor RXDATA(15); s(0) := TTS_in(0) xor TTS_in(1) xor TTS_in(3); s(1) := TTS_in(0) xor TTS_in(2) xor TTS_in(3); s(2) := TTS_in(1) xor TTS_in(2) xor TTS_in(3); s(3) := not TTS_in(0) xor TTS_in(1) xor TTS_in(2); if(UsrClk'event and UsrClk = '1')then if(AMC_en = '0' or TTS_disable = '1' or test = '1')then TTS_coded_i <= "00000"; -- default is Ready TTS_RQST <= "000"; elsif(Ready_i = '0')then TTS_coded_i <= "00010"; -- default is Busy TTS_RQST <= "000"; else case TTS(3 downto 0) is when x"0" | x"f" => TTS_coded_i(4 downto 0) <= "10000"; -- disconnected when x"1" => TTS_coded_i <= "00001"; -- Overflow warning when x"2" => TTS_coded_i <= "00100"; -- Out of Sync when x"4" => TTS_coded_i <= "00010"; -- Busy when x"c" => TTS_coded_i <= "01000"; -- error when x"8" | x"9" | x"a" | x"b" => TTS_coded_i <= "00000"; -- ready when others => null; end case; if(flavor /= "G2" and TTS(3 downto 2) = "10")then TTS_RQST(2) <= TTS(1) and TTS(0); TTS_RQST(1) <= TTS(1) and not TTS(0); TTS_RQST(0) <= not TTS(1) and TTS(0); else TTS_RQST <= "000"; end if; end if; -- if(flavor /= "HCAL" and RXCHARISK = "01" and RXDATA(7 downto 0) = x"5c")then if(RXCHARISK = "01" and RXDATA(7 downto 0) = x"5c")then is_TTS <= '1'; else is_TTS <= '0'; end if; if(c(3) = '1' and or_reduce(c(2 downto 0)) = '1')then TTS_valid <= '0'; else TTS_valid <= '1'; end if; if(c = x"3")then TTS_in(0) <= not RXDATA(8); else TTS_in(0) <= RXDATA(8); end if; if(c = x"5")then TTS_in(1) <= not RXDATA(9); else TTS_in(1) <= RXDATA(9); end if; if(c = x"6")then TTS_in(2) <= not RXDATA(10); else TTS_in(2) <= RXDATA(10); end if; if(c = x"7")then TTS_in(3) <= not RXDATA(11); else TTS_in(3) <= RXDATA(11); end if; if(is_TTS = '1' and TTS_valid = '1')then case TTS_in is when x"0" | x"2" | x"c" | x"f" => critical_TTS(0) <= '1'; when others => critical_TTS(0) <= '0'; end case; else critical_TTS(0) <= '0'; end if; if(InitLink = '1' or Ready_i = '0')then critical_TTS_cntr <= "00"; elsif(update_TTS = '1')then if(critical_TTS = "00")then critical_TTS_cntr <= "00"; else critical_TTS_cntr <= critical_TTS_cntr + 1; end if; end if; if(HammingOutValid = '1')then case HammingOut(11 downto 8) is when x"0" | x"2" | x"c" | x"f" => critical_TTS(1) <= '1'; when others => critical_TTS(1) <= '0'; end case; else critical_TTS(1) <= '0'; end if; if((is_TTS = '1' and TTS_valid = '1') or HammingOutValid = '1')then update_TTS <= '1'; else update_TTS <= '0'; end if; if(InitLink = '1' or Ready_i = '0')then TTS <= x"64"; elsif(update_TTS = '1' and (critical_TTS = "00" or critical_TTS_cntr = "11"))then TTS <= TTS_tmp; end if; if(is_TTS = '1' and TTS_valid = '1')then TTS_tmp <= s & TTS_in; elsif(HammingOutValid = '1')then TTS_tmp(3 downto 0) <= HammingOut(11 downto 8); end if; if(strobe2ms = '1')then LiveTime <= '0' & LiveTimeCntr(18 downto 12); LiveTimeCntr <= (others => '0'); elsif(TTS_coded_i = "00000")then LiveTimeCntr <= LiveTimeCntr + 1; end if; end if; end process; process(UsrClk,BC0_lock) begin if(BC0_lock = '0')then BcntMmCntr <= (others => '0'); elsif(UsrClk'event and UsrClk = '1')then if(resetCntr = '1')then BcntMmCntr <= (others => '0'); elsif(BcntMm = '1')then BcntMmCntr <= BcntMmCntr + 1; end if; end if; end process; AMC_IDp1 <= AMC_ID + 1; AMC_IDp4(3) <= AMC_ID(3) or AMC_ID(2); AMC_IDp4(2) <= not AMC_ID(2); AMC_IDp4(1 downto 0) <= AMC_ID(1 downto 0); process(UsrClk) begin if(UsrClk'event and UsrClk = '1')then if(resetCntr = '1')then BC0mmCntr <= (others => '0'); elsif(HammingOutValid = '1' and HammingOut(17) /= HammingOut(16))then BC0mmCntr <= BC0mmCntr + 1; end if; if(AMC_en = '0')then Cntr_RdEn <= '0'; elsif(Cntr_ADDR(11 downto 8) = AMC_ID or (Cntr_ADDR(11 downto 10) = "11" and Cntr_ADDR(8 downto 5) = AMC_IDp4))then Cntr_RdEn <= '1'; else Cntr_RdEn <= '0'; end if; if(Cntr_ADDR(11 downto 8) /= AMC_ID and (Cntr_ADDR(11 downto 10) /= "11" or Cntr_ADDR(8 downto 5) /= AMC_IDp4))then Cntr_ra <= (others => '0'); elsif(Cntr_ADDR(11 downto 10) = "11")then Cntr_ra <= '1' & Cntr_ADDR(9) & "11" & Cntr_ADDR(4 downto 0); else Cntr_ra <= '0' & Cntr_ADDR(7 downto 2) & "00"; end if; if(resetCntrCycle = '1' or Cntr_RdEn = '0')then Cntr_DATA <= (others => '0'); elsif(Cntr_ra(8 downto 7) = "00")then if(CntrBuf_valid = '1')then Cntr_DATA <= CntrBuf_Do; else Cntr_DATA <= (others => '0'); end if; elsif(Cntr_ra(8 downto 2) = "0100000")then Cntr_DATA <= TotalWordCntr; elsif(Cntr_ra(8 downto 7) = "10")then case Cntr_ra(4 downto 0) is when "00000" => Cntr_DATA <= "000" & EventBuf_wa; when "00001" => Cntr_DATA <= "000" & EventBuf_ra & "00"; when "00010" => Cntr_DATA <= "000000" & L1Ainfo_wa; when "00011" => Cntr_DATA <= "000000" & L1Ainfo_ra; when "00100" => Cntr_DATA <= x"00" & L1Ainfo_wap; when "00101" => Cntr_DATA <= ReSendQue_a & rfifo_a & ACKNUM_a & reset_SyncRegs(3) & AMCRdy & txfsmresetdone & RxResetDone & qpll_lock & InitLink & TxState; when "00110" => Cntr_DATA <= EventInfo_a & "00000" & AMCRdy & EventInfo_ovfl & TTC_lock & BC0_lock & EventInfoRdDoneToggle & EventInfoToggle; when "01000" => Cntr_DATA <= EventWC(15 downto 0); when "01001" => Cntr_DATA <= block32K & AMC_DATA_full & "0000000000" & EventWC(19 downto 16); when "01010" => Cntr_DATA <= WordCntr_q; when "01011" => Cntr_DATA <= zeroWordCntr; when "01100" => Cntr_DATA <= "000" & EventBuf_start; when "01101" => Cntr_DATA <= "000" & EventBuf_wc & "00"; when "01110" => Cntr_DATA <= x"000" & TTS_tmp(3 downto 0); when "10000" => Cntr_DATA <= AMC_TTS & x"0" & LinkVersion; when "10001" => Cntr_DATA <= x"00" & CTRversion; when "10010" => Cntr_DATA <= FirstMismatch(15 downto 0); when "10011" => Cntr_DATA <= FirstMismatch(31 downto 16); when "10100" => Cntr_DATA <= x"00" & WRERR; when "10110" => Cntr_DATA <= x"00" & RDERR; when "11000" => Cntr_DATA <= TTS_InvalidCntr; when "11001" => Cntr_DATA <= TTS_UpdateCntr; when "11010" => Cntr_DATA <= RxNotInTableCntr; when "11011" => Cntr_DATA <= EofMissingCntr; when "11100" => Cntr_DATA <= x"00" & LiveTime; when others => Cntr_DATA <= x"0000"; end case; else Cntr_DATA <= CntrBuf2_Do; end if; if(resetCntr = '1')then sglErrCntr <= (others => '0'); elsif(sgl_err = '1')then sglErrCntr <= sglErrCntr + 1; end if; if(resetCntr = '1')then dblErrCntr <= (others => '0'); elsif(dbl_err = '1')then dblErrCntr <= dblErrCntr + 1; end if; if(resetCntr = '1')then ResendCntr <= (others => '0'); elsif(Resend = '1')then ResendCntr <= ResendCntr + 1; end if; if(resetCntr = '1')then AcceptCntr <= (others => '0'); elsif(accept = '1')then AcceptCntr <= AcceptCntr + 1; end if; if(resetCntr = '1')then CntrAcceptCntr <= (others => '0'); elsif(CntrAccept = '1')then CntrAcceptCntr <= CntrAcceptCntr + 1; end if; if(resetCntr = '1')then ACKcntr <= (others => '0'); elsif(ACK = '1')then ACKcntr <= ACKcntr + 1; end if; if(resetCntr = '1')then TotalWordcntr <= (others => '0'); elsif(accept = '1')then if(EventWC_carry = '1')then TotalWordcntr <= TotalWordcntr + x"0200"; else TotalWordcntr <= TotalWordcntr + EventWC(8 downto 0); end if; end if; if(resetCntr = '1')then RxEventCntr <= (others => '0'); elsif(end_of_event = '1')then RxEventCntr <= RxEventCntr + 1; end if; if(resetCntr = '1')then RdEventCntr <= (others => '0'); elsif(re_EventInfo = '1' and EventInfoDo(25) = '0')then RdEventCntr <= RdEventCntr + 1; end if; TypeData_q <= TypeData; if(resetCntr = '1')then DataAbortCntr <= (others => '0'); elsif(Abort = '1')then DataAbortCntr <= DataAbortCntr + 1; end if; if(resetCntr = '1')then CntrAbortCntr <= (others => '0'); elsif(CntrAbort = '1')then CntrAbortCntr <= CntrAbortCntr + 1; end if; if(resetCntr = '1')then ACKNUM_fullAbortCntr <= (others => '0'); elsif(Abort = '1' and ACKNUM_full = '1')then ACKNUM_fullAbortCntr <= ACKNUM_fullAbortCntr + 1; end if; if(resetCntr = '1')then EventInfo_fullAbortCntr <= (others => '0'); elsif(Abort = '1' and EventInfo_full = '1')then EventInfo_fullAbortCntr <= EventInfo_fullAbortCntr + 1; end if; if(resetCntr = '1')then EventBuf_fullAbortCntr <= (others => '0'); elsif(Abort = '1' and EventBuf_full = '1')then EventBuf_fullAbortCntr <= EventBuf_fullAbortCntr + 1; end if; if(resetCntr = '1')then SEQAbortCntr <= (others => '0'); elsif((Abort = '1' or CntrAbort = '1') and SEQ_OK = '0')then SEQAbortCntr <= SEQAbortCntr + 1; end if; if(resetCntr = '1')then CRCAbortCntr <= (others => '0'); elsif((Abort = '1' or CntrAbort = '1') and CRC_OK = '0')then CRCAbortCntr <= CRCAbortCntr + 1; end if; if(resetCntr = '1')then frameAbortCntr <= (others => '0'); elsif((Abort = '1' or CntrAbort = '1') and frame_OK = '0')then frameAbortCntr <= frameAbortCntr + 1; end if; if(resetCntr = '1')then bad_KAbortCntr <= (others => '0'); elsif((Abort = '1' or CntrAbort = '1') and bad_K = '1')then bad_KAbortCntr <= bad_KAbortCntr + 1; end if; if(resetCntr = '1')then BlockCntr <= (others => '0'); elsif(we_EventInfo = '1')then BlockCntr <= BlockCntr + 1; end if; if(resetCntr = '1')then badCRCCntr <= (others => '0'); elsif(end_of_event = '1' and bad_AMCCRC = '1' and test = '0' and AMC_en = '1')then badCRCCntr <= badCRCCntr + 1; end if; if(resetCntr = '1')then TTSCntr <= (others => '0'); elsif(is_TTS = '1')then TTSCntr <= TTSCntr + 1; end if; if(resetCntr = '1')then TTS_DCcntr <= (others => '0'); TTS_ERRcntr <= (others => '0'); TTS_OOScntr <= (others => '0'); TTS_BSYcntr <= (others => '0'); TTS_OFWcntr <= (others => '0'); elsif(Ready_i = '1')then if(TTS_coded_i(4) = '1')then TTS_DCcntr <= TTS_DCcntr + 1; end if; if(TTS_coded_i(3) = '1')then TTS_ERRcntr <= TTS_ERRcntr + 1; end if; if(TTS_coded_i(2) = '1')then TTS_OOScntr <= TTS_OOScntr + 1; end if; if(TTS_coded_i(1) = '1')then TTS_BSYcntr <= TTS_BSYcntr + 1; end if; if(TTS_coded_i(0) = '1')then TTS_OFWcntr <= TTS_OFWcntr + 1; end if; end if; if(resetCntr = '1')then TTCCntr <= (others => '0'); elsif(TTC_DataValid = '1')then TTCCntr <= TTCCntr + 1; end if; if(resetCntr = '1')then bad_EventLengthCntr <= (others => '0'); elsif(end_of_event = '1' and bad_EventLength = '1')then bad_EventLengthCntr <= bad_EventLengthCntr + 1; end if; if(resetCntr = '1' or test = '1' or AMC_en = '0')then EvtEVNmmCntr <= (others => '0'); elsif(end_of_event = '1' and RxType(0) = '0')then EvtEVNmmCntr <= EvtEVNmmCntr + 1; end if; if(resetCntr = '1' or test = '1' or AMC_en = '0')then EvtBCNmmCntr <= (others => '0'); elsif(end_of_event = '1' and RxType(2) = '0')then EvtBCNmmCntr <= EvtBCNmmCntr + 1; end if; if(resetCntr = '1' or test = '1' or AMC_en = '0')then EvtOCNmmCntr <= (others => '0'); elsif(end_of_event = '1' and RxType(1) = '0')then EvtOCNmmCntr <= EvtOCNmmCntr + 1; end if; if(reset = '1' or test = '1' or AMC_en = '0')then FirstMismatch <= (others => '0'); GotMismatch <= '0'; elsif(end_of_event = '1' and GotMismatch = '0')then FirstMismatch(31 downto 28) <= TTS(3 downto 0); FirstMismatch(27 downto 25) <= RxType(2 downto 0); FirstMismatch(24 downto 0) <= FirstMismatch(24 downto 0) + 1; if(RxType(2 downto 0) /= "000")then GotMismatch <= '1'; end if; end if; if(resetCntr = '1' or InitLink = '1')then TTS_InvalidCntr <= (others => '0'); elsif(is_TTS = '1' and TTS_valid = '0')then TTS_InvalidCntr <= TTS_InvalidCntr + 1; end if; if(resetCntr = '1' or InitLink = '1')then TTS_UpdateCntr <= (others => '0'); elsif(update_TTS = '1')then TTS_UpdateCntr <= TTS_UpdateCntr + 1; end if; if(Receiving = '1' and RxNotInTable /= "00")then RxNotInTableErr <= '1'; else RxNotInTableErr <= '0'; end if; if(resetCntr = '1' or InitLink = '1')then RxNotInTableCntr <= (others => '0'); elsif(RxNotInTableErr = '1')then RxNotInTableCntr <= RxNotInTableCntr + 1; end if; if(resetCntr = '1' or InitLink = '1')then EofMissingCntr <= (others => '0'); elsif(check_packet = '1' and eof = '0' and WC11 = '0')then EofMissingCntr <= EofMissingCntr + 1; end if; if(resetCntr = '1' or Ready_i = '0')then TTS_SL_cntr <= (others => '0'); elsif(update_TTS = '1' and TTS_tmp(3 downto 0) = x"2")then TTS_SL_cntr <= TTS_SL_cntr + 1; end if; if(resetCntr = '1' or Ready_i = '0')then TTS_DC_cntr <= (others => '0'); elsif(update_TTS = '1' and (TTS_tmp(3 downto 0) = x"0" or TTS_tmp(3 downto 0) = x"f"))then TTS_DC_cntr <= TTS_DC_cntr + 1; end if; if(resetCntr = '1' or Ready_i = '0')then TTS_ERR_cntr <= (others => '0'); elsif(update_TTS = '1' and TTS_tmp(3 downto 0) = x"c")then TTS_ERR_cntr <= TTS_ERR_cntr + 1; end if; end if; end process; process(UsrClk) begin if(UsrClk'event and UsrClk = '1')then -- if(flavor /= "HCAL" or RXCHARISK = "00")then if(RXCHARISK = "00")then sel_TTC <= '0'; elsif(RXCHARISK = "01" and RXDATA(7 downto 0) = x"bc")then sel_TTC <= '1'; end if; if(RXCHARISK(1) = '0')then TTC_Data(23 downto 8) <= RXDATA; TTC_Data(7 downto 0) <= TTC_Data(23 downto 16); end if; if(sel_TTC = '1' and RXCHARISK = "00" and AMCRdy = '1')then TTC_DataValid <= '1'; else TTC_DataValid <= '0'; end if; end if; end process; i_TTC_trigger: TTC_trigger generic map(simulation => simulation) PORT MAP( reset => reset, UsrClk => UsrClk, TTCclk => TTCclk, HammingData_in => HammingOut, HammingDataValid => HammingOutValid, BC0 => BC0, BcntMm => BcntMm, TTC_lock => TTC_lock, BC0_lock => BC0_lock, TrigData => TrigData ); i_HammingDecode: HammingDecode PORT MAP( clk => UsrClk, din_valid => TTC_DataValid, din => TTC_Data, dout_valid => HammingOutValid, dout => HammingOut, sgl_err => sgl_err, dbl_err => dbl_err ); process(UsrClk,RxResetDone) begin if(RxResetDone = '0')then RxResetDoneSyncRegs <= (others => '0'); AMCRdy <= '0'; elsif(UsrClk'event and UsrClk = '1')then RxResetDoneSyncRegs <= RxResetDoneSyncRegs(1 downto 0) & '1'; if(txfsmresetdone = '1')then AMCRdy <= '1'; end if; end if; end process; process(UsrClk,reset,RxResetDone,txfsmresetdone,qpll_lock) begin if(reset = '1' or (test = '0' and (RxResetDone = '0' or txfsmresetdone = '0' or qpll_lock = '0')))then reset_SyncRegs <= (others => '1'); EventInfoToggle <= '0'; EventInfoToggle_q <= '0'; elsif(UsrClk'event and UsrClk = '1')then reset_SyncRegs <= reset_SyncRegs(2 downto 0) & '0'; if((we_EventInfo = '1' and EventInfo_a = x"f") or (re_EventInfo = '1' and (EventInfo_a /= x"0" or we_EventInfo = '1')))then EventInfoToggle <= not EventInfoToggle; end if; EventInfoToggle_q <= EventInfoToggle; end if; end process; process(UsrClk) begin if(UsrClk'event and UsrClk = '1')then if(AMC_en = '0')then EventInfo <= (others => '0'); else EventInfo <= EventInfoDo; end if; if(RxResetDoneSyncRegs(2) = '0' or or_reduce(RxNotInTable) = '1' or bad_K = '1')then DATA_VALID <= '0'; elsif(RXCHARISK(0) = '1' and RXDATA(7 downto 0) = x"bc")then DATA_VALID <= '1'; end if; if(InitLink = '1' or AMC_en = '0')then Ready_i <= '0'; elsif(update_TTS = '1' or test = '1')then Ready_i <= '1'; end if; if(InitLink = '1' or Ready_i = '1' or TTS_wait(7) = '1')then TTS_wait <= x"00"; else TTS_wait <= TTS_wait + 1; end if; end if; end process; ReSend <= timer(N); process(UsrClk) begin if(UsrClk'event and UsrClk = '1')then if(timer(N) = '1' or ACK = '1' or (ReSendQue_empty = '1' and (got_comma = '0' or InitLink = '0')))then timer <= (others => '0'); else timer <= timer + 1; end if; if(ReSend = '1')then ReSend_l <= '1'; elsif(TxState = SendSEQ)then ReSend_l <= '0'; end if; -- Comma ends a packet and after that, any D-word marks the beginning of a packet if((RXCHARISCOMMA = "11" and RXDATA /= R_word) or test = '1' or AMCRdy = '0')then Receiving <= '0'; elsif(sel_TTC = '0' and RXCHARISK = "00")then Receiving <= '1'; end if; if(sel_TTC = '0')then if(RxNotInTable /= "00")then bad_K <= '1'; elsif(RXCHARISK = "00")then RXDATA_q <= RXDATA; if(Receiving = '0')then bad_K <= '0'; RxSEQNUM <= RXDATA(15 downto 8); if(RXDATA(7 downto 0) = InitRqst and InitLink = '1')then TypeInit <= '1'; else TypeInit <= '0'; end if; if(RXDATA(7 downto 0) = Acknowledge)then TypeACK <= '1'; else TypeACK <= '0'; end if; if(RXDATA(7 downto 0) = data)then TypeData <= '1'; else TypeData <= '0'; end if; if(RXDATA(7 downto 0) = Counter)then TypeCntr <= '1'; else TypeCntr <= '0'; end if; Header2 <= '1'; else Header2 <= '0'; evn_word <= evn_word(1 downto 0) & Header2; if(evn_word(2) = '1' and get_evn = '1' and TypeData = '1')then evn <= RxData(7 downto 0); end if; if(Header2 = '1')then RxWC <= (others => '0'); RxType <= RXDATA; else RxWC <= RxWC + 1; end if; if(RxWC(11 downto 2) = RxData(11 downto 2) and RxWC(1 downto 0) = "00")then WC_OKp <= '1'; else WC_OKp <= '0'; end if; WC_OK <= WC_OKp; WC11p <= RxData(11); WC11 <= WC11p; if(evn = RxData(15 downto 8))then evn_OK(0) <= '1'; else evn_OK(0) <= '0'; end if; evn_OK(4 downto 1) <= evn_OK(3 downto 0); end if; elsif(RXCHARISK = "10" or (RXCHARISK = "11" and RXDATA /= R_word and RXDATA /= eof_word and RXCHARISCOMMA /= "11") or (RXCHARISK = "01" and RXDATA(7 downto 0) /= x"5c" and RXDATA(7 downto 0) /= x"bc"))then bad_K <= '1'; end if; end if; if((TypeACK = '1' or TypeInit = '1') and RXType(15 downto 8) = ReSendQueOut(15 downto 8) and ReSendQue_empty = '0' and ReSend = '0')then -- incoming acknowledge number is what waited for ACK_OK <= '1'; else ACK_OK <= '0'; end if; if(Receiving = '0')then ACKNUM_IN <= RxSEQNUM; end if; if(RxSEQNUM = NextSEQNUM)then -- incoming sequence number is what waited for SEQ_OK <= '1'; else SEQ_OK <= '0'; end if; if(or_reduce(RxCRC) = '0')then CRC_OK <= '1'; else CRC_OK <= '0'; end if; if(WC_OK = '1' and (((TypeData = '1' or TypeCntr = '1' or TypeACK = '1') and InitLink = '0') or (TypeInit = '1' and InitLink = '1')))then frame_OK <= '1'; else frame_OK <= '0'; end if; if(RXCHARISCOMMA = "11" and RXDATA /= R_word and Receiving = '1')then check_packet <= '1'; else check_packet <= '0'; end if; accept <= check_packet and SEQ_OK and CRC_OK and frame_OK and not EventInfo_full and not EventBuf_ovf and not bad_K and not ACKNUM_full and (eof or WC11) and TypeData; CntrAccept <= check_packet and SEQ_OK and CRC_OK and frame_OK and not bad_K and TypeCntr; we_ACKNUM <= check_packet and CRC_OK and frame_OK and not bad_K and not ACKNUM_full and not EventInfo_full and not EventBuf_ovf and (eof or WC11) and TypeData; ACK <= check_packet and ACK_OK and CRC_OK and frame_OK and not bad_K; -- Abort <= check_packet and (TypeData or TypeCntr) and not(SEQ_OK and CRC_OK and frame_OK and not bad_K and not((ACKNUM_full or EventInfo_full or EventBuf_ovf) and TypeData)); -- Abort <= check_packet and (TypeData or TypeCntr) and not(SEQ_OK and CRC_OK and frame_OK and not bad_K and -- not((ACKNUM_full or EventInfo_full or EventBuf_ovf or (not eof and not WC11)) and TypeData)); Abort <= check_packet and TypeData and not(SEQ_OK and CRC_OK and frame_OK and not bad_K and not ACKNUM_full and not EventInfo_full and not EventBuf_ovf and (eof or WC11)); CntrAbort <= check_packet and TypeCntr and not(SEQ_OK and CRC_OK and frame_OK and not bad_K); if(InitLink = '1')then get_evn <= '1'; elsif(accept = '1')then get_evn <= got_eof; end if; if(test = '1')then EventInfoDi(30 downto 27) <= fake_evn; elsif(accept = '1')then EventInfoDi(30 downto 27) <= evn(3 downto 0); end if; if(InitLink = '1' or (TxState = SendCRC and TxType = Counter))then GotCntr <= '0'; elsif(CntrAccept = '1')then GotCntr <= '1'; end if; if(InitLink = '1')then CntrACKNUM <= x"00"; elsif(CntrAccept = '1')then CntrACKNUM <= RxSEQNUM; end if; -- if(reset_SyncRegs(3) = '1')then if(InitLink = '1')then ACKNUM_a <= (others => '1'); elsif(we_ACKNUM = '1' and (TxState /= SendCRC or SendTTS = '1' or IsACK = '0'))then ACKNUM_a <= ACKNUM_a + 1; elsif(we_ACKNUM = '0' and TxState = SendCRC and IsACK = '1' and SendTTS = '0')then ACKNUM_a <= ACKNUM_a - 1; end if; if(ACKNUM_a = "11")then ACKNUM_empty <= '1'; else ACKNUM_empty <= '0'; end if; if(ACKNUM_a = "10")then ACKNUM_full <= '1'; else ACKNUM_full <= '0'; end if; if(InitLink = '1')then ACKNUM_l <= x"00"; elsif(ACKNUM_a /= "11")then ACKNUM_l <= ACKNUM; end if; if(reset_SyncRegs(3) = '1')then NextSEQNUM <= x"00"; elsif(accept = '1')then NextSEQNUM <= NextSEQNUM(6 downto 0) & not(NextSEQNUM(7) xor NextSEQNUM(5) xor NextSEQNUM(4) xor NextSEQNUM(3)); end if; -- Receiving of eof K-word in a packet marks the end of the event -- if(Receiving = '0' or InitLink = '1')then if(check_packet = '1' or InitLink = '1')then eof <= '0'; elsif(Receiving = '1' and RXCHARISK = "11" and RXDATA = eof_word)then eof <= '1'; end if; -- latches eof signal if(check_packet = '1')then got_eof <= eof; end if; -- if buffer is getting full during packet receiving, buffer overflow error is set if(Receiving = '0')then EventBuf_ovf <= '0'; elsif(EventBuf_full = '1')then EventBuf_ovf <= '1'; end if; Receiving_q <= Receiving; if(InitLink = '1')then EventBuf_wa <= (others => '0'); elsif(abort = '1')then EventBuf_wa <= EventBuf_start; elsif(EventBuf_we(0) = '1')then EventBuf_wa <= EventBuf_wa + 1; end if; if(InitLink = '1')then EventBuf_ra <= (others => '0'); elsif(ec_EventBuf_ra = '1')then EventBuf_ra <= EventBuf_ra + 1; end if; -- packet starting write address is recorded before the first data is written to the buffer if(InitLink = '1')then EventBuf_start <= (others => '0'); elsif(save_start_addr = '1')then EventBuf_start <= EventBuf_wa; end if; -- accepted data in EventBuf available for read out if(InitLink = '1')then EventBuf_wc <= (others => '0'); elsif(ec_EventBuf_ra = '1')then EventBuf_wc <= EventBuf_wc - 1; else EventBuf_wc <= EventBuf_start(12 downto 2) - EventBuf_ra; end if; EventBuf_space <= EventBuf_wa(12 downto 2) - EventBuf_ra; -- buffer almost full if(and_reduce(EventBuf_space(10 downto 5)) = '1')then EventBuf_full <= '1'; else EventBuf_full <= '0'; end if; fake_full <= EventBuf_full or EventInfo_full; end if; end process; i_RxCRC: crc16D16 PORT MAP( clk => UsrClk, init_crc => Init_RxCRC, we_crc => we_RxCRC, d => RXDATA, crc => RxCRC ); we_RxCRC <= '1' when RXCHARISK = "00" and sel_TTC = '0' else '0'; Init_RxCRC <= '1' when RXCHARISCOMMA = "11" else '0'; i_AMCCRC: EthernetCRCD16B PORT MAP( clk => UsrClk, init => InitAMCCRC, save => accept, restore => abort, ce => EventBuf_we(0), d => EventBuf_Di, crc => AMCCRC, bad_crc => bad_AMCCRC ); process(UsrClk) begin if(UsrClk'event and UsrClk = '1')then if(InitLink = '1' or end_of_event = '1')then InitAMCCRC <= '1'; else InitAMCCRC <= '0'; end if; end if; end process; g_ACKNUM : for i in 0 to 7 generate i_ACKNUM : SRL16E port map ( Q => ACKNUM(i), -- SRL data output A0 => ACKNUM_a(0), -- Select[0] input A1 => ACKNUM_a(1), -- Select[1] input A2 => '0', -- Select[2] input A3 => '0', -- Select[3] input CE => we_ACKNUM, -- Clock enable input CLK => UsrClk, -- Clock input D => ACKNUM_IN(i) -- SRL data input ); end generate; -- this fifo is used to hold the last couple of received data words before writing to the data buffer. -- this is because 1. word count and CRC of the packet should not be written to the buffer and more importantly, -- if the packet is the last packet of the event, the last data word must be properly marked with the LinkCtrl -- before being written to the buffer. 3. next packet data may arrive before a decision being made to accept or reject a packet. g_rfifo: for i in 0 to 15 generate i_rfifo : SRL16E port map ( Q => rfifo(i), -- SRL data output A0 => '1', -- Select[0] input A1 => '0', -- Select[1] input A2 => '0', -- Select[2] input A3 => '0', -- Select[3] input CE => we_rfifo, -- Clock enable input CLK => UsrClk, -- Clock input D => RXDATA_q(i) -- SRL data input ); end generate; process(UsrClk) begin if(UsrClk'event and UsrClk = '1')then if(sel_TTC = '0' and RXCHARISK = "00")then we_rfifo <= '1'; else we_rfifo <= '0'; end if; if(InitLink = '1' or check_packet = '1')then dl_cntr <= "000"; elsif(we_rfifo = '1')then dl_cntr(2) <= dl_cntr(2) or (dl_cntr(1) and dl_cntr(0)); dl_cntr(1) <= dl_cntr(1) xor dl_cntr(0); dl_cntr(0) <= not dl_cntr(2) and not dl_cntr(0); end if; end if; end process; g_EventBuffer : for i in 0 to 3 generate i_EventBuffer : BRAM_SDP_MACRO generic map ( BRAM_SIZE => "36Kb", -- Target BRAM, "18Kb" or "36Kb" DEVICE => "7SERIES", -- Target device: "VIRTEX5", "VIRTEX6", "7SERIES", "SPARTAN6" WRITE_WIDTH => 4, -- Valid values are 1-72 (37-72 only valid when BRAM_SIZE="36Kb") READ_WIDTH => 16, -- Valid values are 1-72 (37-72 only valid when BRAM_SIZE="36Kb") DO_REG => 1, -- Optional output register (0 or 1) SIM_COLLISION_CHECK => "NONE") -- Collision check enable "ALL", "WARNING_ONLY", -- "GENERATE_X_ONLY" or "NONE" port map ( DO => EventBuf_Do(i*16+15 downto i*16), -- Output read data port, width defined by READ_WIDTH parameter DI => EventBuf_Di(i*4+3 downto i*4), -- Input write data port, width defined by WRITE_WIDTH parameter RDADDR => EventBuf_ra, -- Input read address, width defined by read port depth RDCLK => UsrClk, -- 1-bit input read clock RDEN => '1', -- 1-bit input read port enable REGCE => '1', -- 1-bit input read output register enable RST => '0', -- 1-bit input reset WE => "1", -- Input write enable, width defined by write port depth WRADDR => EventBuf_wa, -- Input write address, width defined by write port depth WRCLK => UsrClk, -- 1-bit input write clock WREN => EventBuf_we(0) -- 1-bit input write port enable ); end generate; g_MC_DATA_Di : for i in 0 to 3 generate g_AMC_DATA_Dij: for j in 0 to 3 generate AMC_DATA_Di(i*16+j*4+3 downto i*16+j*4) <= EventBuf_Do(i*4+j*16+3 downto i*4+j*16); end generate; end generate; i_AMC_DATA: AMC_DATA_FIFO PORT MAP( wclk => UsrClk, rclk => sysclk, reset => fifo_rst, fifo_en => fifo_en, we => AMC_DATA_WrEn, re => AMC_DATA_RdEn, Di => AMC_DATA_Di, Do => AMC_DATA, WRERR_OUT => WRERR, RDERR_OUT => RDERR, full => AMC_DATA_full ); --AMC_DATA_WrEn <= fifo_en and not AMC_DATA_full(0) and AMC_DATA_Di_vld; process(UsrClk) begin if(UsrClk'event and UsrClk = '1')then if(reset_SyncRegs(3) = '1' or fifo_en = '0' or AMC_DATA_full = '1')then ec_EventBuf_ra <= '0'; elsif(or_reduce(EventBuf_wc(10 downto 1)) = '0' and (EventBuf_wc(0) = '0' or ec_EventBuf_ra = '1'))then ec_EventBuf_ra <= '0'; else ec_EventBuf_ra <= '1'; end if; ec_EventBuf_ra_q <= fifo_en and ec_EventBuf_ra; AMC_DATA_WrEn <= fifo_en and ec_EventBuf_ra_q; end if; end process; process(UsrClk) begin if(UsrClk'event and UsrClk = '1')then if(InitLink = '1' or (test = '1' and fake_got_eof = '1') or (test = '0' and ((abort = '1' and saved_BOE = '1') or (accept = '1' and got_eof = '1'))))then BOE <= '1'; elsif(EventBuf_we(0) = '1' and EventBuf_wa(0) = '1')then BOE <= '0'; end if; if(InitLink = '1' or accept = '1')then saved_BOE <= '0'; elsif(BOE = '1')then saved_BOE <= '1'; end if; if(BOE = '1')then AMCinfo_word <= '1'; elsif(AMCinfo_word = '1' and EventBuf_we(0) = '1' and EventBuf_wa(1 downto 0) = "00")then AMCinfo_word <= '0'; AMCinfoDi <= EventBuf_Di; end if; -- if(InitLink = '1' or end_of_block = '1' or end_of_event = '1')then if(InitLink = '1' or ((accept = '1' or test = '1') and end_of_block = '1') or end_of_event = '1')then block32K <= '0'; elsif(EventWC_carry = '1' and EventWC(11 downto 9) = "111" and(test = '1' or accept = '1'))then block32K <= '1'; end if; -- if(InitLink = '0' and AMC_en = '1' and block32K = '1' and end_of_block = '0' and and_reduce(EventWC(9 downto 1)) = '1' and EventBuf_we(0) = '1')then -- end_of_block <= '1'; -- else -- end_of_block <= '0'; -- end if; if(block32K = '0' or (test = '1' and end_of_block = '1'))then end_of_block <= '0'; elsif(EventBuf_we(0) = '1' and and_reduce(EventWC(9 downto 1)) = '1')then end_of_block <= '1'; end if; if(InitLink = '0' and ((test = '1' and fake_got_eof = '1') or (test = '0' and accept = '1' and got_eof = '1')))then end_of_event <= '1'; else end_of_event <= '0'; end if; -- we_EventInfo <= not InitLink and not(NoReSyncFake and EventInfoDi(31)) and (end_of_block or end_of_event); if(InitLink = '1' or (NoReSyncFake = '1' and EventInfoDi(31) = '1') or AMC_en = '0')then we_EventInfo <= '0'; elsif((accept = '1' or test = '1') and end_of_block = '1')then we_EventInfo <= '1'; elsif(end_of_event = '1')then we_EventInfo <= '1'; else we_EventInfo <= '0'; end if; if(InitLink = '1' or (test = '0' and abort = '1') or end_of_event = '1')then EventWC(8 downto 0) <= (others => '0'); elsif(EventBuf_we(0) = '1' and EventBuf_wa(1 downto 0) = "11")then EventWC(8 downto 0) <= EventWC(8 downto 0) + 1; end if; if(InitLink = '1' or (test = '0' and (abort = '1' or accept = '1')) or (test = '1' and EventWC_carry = '1'))then EventWC_carry <= '0'; elsif(EventBuf_we(0) = '1' and EventBuf_wa(1 downto 0) = "11" and and_reduce(EventWC(8 downto 0)) = '1')then EventWC_carry <= '1'; end if; if(InitLink = '1' or end_of_event = '1')then EventWC_tmp(19 downto 9) <= (others => '0'); elsif(EventBuf_we(0) = '1' and EventBuf_wa(1 downto 0) = "11")then if(and_reduce(EventWC(8 downto 0)) = '1')then EventWC_tmp(19 downto 9) <= EventWC(19 downto 9) + 1; else EventWC_tmp(19 downto 9) <= EventWC(19 downto 9); end if; end if; if(EventBuf_we(0) = '1' and EventBuf_wa(1 downto 0) = "00")then LengthInTrailer(15 downto 0) <= EventBuf_Di; end if; if(EventBuf_we(0) = '1' and EventBuf_wa(1 downto 0) = "01")then LengthInTrailer(19 downto 16) <= EventBuf_Di(3 downto 0); end if; if(InitLink = '1' or end_of_event = '1')then EventWC(19 downto 9) <= (others => '0'); -- elsif(EventWC_carry = '1' and(test = '1' or accept = '1'))then -- EventWC(19 downto 9) <= EventWC(19 downto 9) + 1; elsif(test = '1' or accept = '1')then EventWC(19 downto 9) <= EventWC_tmp(19 downto 9); end if; UnknownLength <= and_reduce(LengthInHeader); if(LengthInHeader = LengthInTrailer or UnknownLength = '1')then LengthMatch <= '1'; else LengthMatch <= '0'; end if; if(EventWC_tmp = LengthInTrailer and LengthMatch = '1')then bad_EventLength <= '0'; else bad_EventLength <= '1'; end if; if(end_of_event = '1')then EventInfoDi(19 downto 0) <= "0000000" & block32K & EventWC(11 downto 0); EventInfoDi(25) <= '0';-- M bit EventInfoDi(26) <= bad_EventLength;-- EventLengthErr elsif(BOE = '1' and EventBuf_we(0) = '1')then if(EventBuf_wa(0) = '0')then EventInfoDi(15 downto 0) <= EventBuf_Di; LengthInHeader(15 downto 0) <= EventBuf_Di; else EventInfoDi(19 downto 16) <= EventBuf_Di(3 downto 0); LengthInHeader(19 downto 16) <= EventBuf_Di(3 downto 0); end if; EventInfoDi(24) <= '0';-- S bit EventInfoDi(25) <= '1';-- M bit EventInfoDi(26) <= '0';-- EventLengthErr elsif(we_EventInfo = '1')then EventInfoDi(19 downto 0) <= x"01000"; EventInfoDi(24) <= '1';-- S bit EventInfoDi(25) <= '1';-- M bit end if; -- if(InitLink = '1' or we_EventInfo = '1')then -- EventInfoDi(20) <= '0'; -- elsif(end_of_event = '1')then -- EventInfoDi(20) <= (not bad_AMCCRC or test) and AMC_en; -- end if; if(end_of_event = '1')then EventInfoDi(20) <= (not bad_AMCCRC or test) and AMC_en; else EventInfoDi(20) <= '0'; end if; if(AMC_en = '0' or test = '1')then bad_AMC <= '0'; LinkVersion <= x"00"; elsif(InitLink = '1')then if(ACK = '1' and CTRversion = RxType(7 downto 0))then bad_AMC <= '0'; else bad_AMC <= '1'; end if; if(ACK = '1')then AMC_TTS <= RxType(15 downto 12); LinkVersion <= RxType(7 downto 0); end if; end if; if(check_packet = '1')then evn_OK(5) <= evn_OK(4) or not eof; end if; -- EventInfoDi(21) <= not(RxType(2) and RxType(1) and RxType(0)) and not test and AMC_en; EventInfoDi(31) <= RxType(3) and AMC_en and not test; -- got faked data during ReSync EventInfoDi(21) <= ((RxType(2) and RxType(1) and RxType(0) and evn_OK(5)) or test) and AMC_en; EventInfoDi(22) <= AMC_en; EventInfoDi(23) <= AMC_en; fake_CRC_q <= not InitLink and AMC_en and fake_CRC; fake_CRC_q2 <= not InitLink and fake_CRC_q; AMCCRC_q <= AMCCRC(31 downto 16); if(test = '1')then if(fake_header = '1')then EventBuf_Di <= x"0" & AMC_IDp1 & fake_DATA(7 downto 0); fake_evn <= fake_DATA(3 downto 0); elsif(fake_CRC_q = '1')then EventBuf_Di <= AMCCRC(15 downto 0); elsif(fake_CRC_q2 = '1')then EventBuf_Di <= AMCCRC_q; else EventBuf_Di <= fake_DATA; end if; else EventBuf_Di <= rfifo; end if; if(test = '1')then EventBuf_we(0) <= (fake_WrEn or fake_CRC_q2) and not fake_CRC and AMC_en; elsif(we_rfifo = '1' and dl_cntr(2) = '1' and TypeData = '1' and abort = '0' and EventBuf_full = '0')then EventBuf_we(0) <= '1'; else EventBuf_we(0) <= '0'; end if; if(test = '1' or (InitLink = '0' and accept = '1'))then save_start_addr <= '1'; else save_start_addr <= '0'; end if; if(InitLink = '1')then EventInfo_a <= (others => '1'); EventInfo_ovfl <= (others => '0'); elsif(we_EventInfo = '1' and re_EventInfo = '0')then EventInfo_a <= EventInfo_a + 1; if(EventInfo_a = x"e")then EventInfo_ovfl(0) <= '1'; end if; elsif(we_EventInfo = '0' and re_EventInfo = '1')then EventInfo_a <= EventInfo_a - 1; if(EventInfo_a = x"f")then EventInfo_ovfl(1) <= '1'; end if; end if; if(EventInfo_a = x"d" or EventInfo_a = x"e" or (test = '1' and EventInfo_a(3) = '1' and EventInfo_a(2 downto 0) /= "111"))then EventInfo_full <= '1'; else EventInfo_full <= '0'; end if; re_EventInfo <= not InitLink and (EventInfoRdDoneToggleSyncRegs(3) xor EventInfoRdDoneToggleSyncRegs(2)); if(InitLink = '1')then EventInfoRdDoneToggleSyncRegs <= (others => '0'); else EventInfoRdDoneToggleSyncRegs <= EventInfoRdDoneToggleSyncRegs(2 downto 0) & EventInfoRdDoneToggle; end if; if(resetCntrCycle = '1')then CntrBuf_Di <= (others => '0'); we_CntrBuf <= '1'; else CntrBuf_Di <= rfifo; we_CntrBuf <= we_rfifo and dl_cntr(2) and TypeCntr and not Cntrabort; end if; if(Receiving = '0')then CntrBuf_wa(4 downto 0) <= (others => '0'); elsif(we_CntrBuf = '1')then CntrBuf_wa(4 downto 0) <= CntrBuf_wa(4 downto 0) + 1; end if; if(InitLink = '1')then CntrBuf_wa(5) <= '0'; elsif(CntrAccept = '1')then CntrBuf_wa(5) <= not CntrBuf_wa(5); end if; if(InitLink = '1' or resetCntr = '1')then CntrBuf_valid <= '0'; elsif(CntrAccept = '1')then CntrBuf_valid <= '1'; end if; end if; end process; EventWC_tmp(8 downto 0) <= EventWC(8 downto 0); i_fake_got_eof : SRL16E port map ( Q => fake_got_eof, -- SRL data output A0 => '0', -- Select[0] input A1 => '1', -- Select[1] input A2 => '0', -- Select[2] input A3 => '0', -- Select[3] input CE => '1', -- Clock enable input CLK => UsrClk, -- Clock input D => fake_CRC_q -- SRL data input ); g_AMCinfo : for i in 0 to 15 generate i_AMCinfo : SRL16E port map ( Q => AMCinfo(i), -- SRL data output A0 => EventInfo_a(0), -- Select[0] input A1 => EventInfo_a(1), -- Select[1] input A2 => EventInfo_a(2), -- Select[2] input A3 => EventInfo_a(3), -- Select[3] input CE => we_EventInfo, -- Clock enable input CLK => UsrClk, -- Clock input D => AMCinfoDi(i) -- SRL data input ); end generate; g_EventInfo : for i in 0 to 31 generate i_EventInfo : SRL16E port map ( Q => EventInfoDo(i), -- SRL data output A0 => EventInfo_a(0), -- Select[0] input A1 => EventInfo_a(1), -- Select[1] input A2 => EventInfo_a(2), -- Select[2] input A3 => EventInfo_a(3), -- Select[3] input CE => we_EventInfo, -- Clock enable input CLK => UsrClk, -- Clock input D => EventInfoDi(i) -- SRL data input ); end generate; g_CntrBuf : for i in 0 to 15 generate i_CntrBuf : RAM64X1D port map ( DPO => CntrBuf_Do(i), -- Read-only 1-bit data output SPO => open, -- R/W 1-bit data output A0 => CntrBuf_wa(0), -- R/W address[0] input bit A1 => CntrBuf_wa(1), -- R/W address[1] input bit A2 => CntrBuf_wa(2), -- R/W address[2] input bit A3 => CntrBuf_wa(3), -- R/W address[3] input bit A4 => CntrBuf_wa(4), -- R/W address[4] input bit A5 => CntrBuf_wa(5), -- R/W address[5] input bit D => CntrBuf_Di(i), -- Write 1-bit data input DPRA0 => CntrBuf_ra(0), -- Read-only address[0] input bit DPRA1 => CntrBuf_ra(1), -- Read-only address[1] input bit DPRA2 => CntrBuf_ra(2), -- Read-only address[2] input bit DPRA3 => CntrBuf_ra(3), -- Read-only address[3] input bit DPRA4 => CntrBuf_ra(4), -- Read-only address[4] input bit DPRA5 => CntrBuf_ra(5), -- Read-only address[5] input bit WCLK => UsrClk, -- Write clock input WE => we_CntrBuf -- Write enable input ); end generate; CntrBuf_ra <= not CntrBuf_wa(5) & Cntr_ra(6 downto 2); g_CntrBuf2 : for i in 0 to 15 generate i_CntrBuf2 : RAM64X1D port map ( DPO => CntrBuf2_Do(i), -- Read-only 1-bit data output SPO => CntrBuf2_SPO(i), -- R/W 1-bit data output A0 => CntrBuf2_wa(0), -- R/W address[0] input bit A1 => CntrBuf2_wa(1), -- R/W address[1] input bit A2 => CntrBuf2_wa(2), -- R/W address[2] input bit A3 => CntrBuf2_wa(3), -- R/W address[3] input bit A4 => CntrBuf2_wa(4), -- R/W address[4] input bit A5 => CntrBuf2_wa(5), -- R/W address[5] input bit D => CntrBuf2_Di(i), -- Write 1-bit data input DPRA0 => Cntr_ra(2), -- Read-only address[0] input bit DPRA1 => Cntr_ra(3), -- Read-only address[1] input bit DPRA2 => Cntr_ra(4), -- Read-only address[2] input bit DPRA3 => Cntr_ra(5), -- Read-only address[3] input bit DPRA4 => Cntr_ra(6), -- Read-only address[4] input bit DPRA5 => Cntr_ra(8), -- Read-only address[5] input bit WCLK => UsrClk, -- Write clock input WE => we_CntrBuf2 -- Write enable input ); end generate; process(UsrClk) begin if(UsrClk'event and UsrClk = '1')then if(resetCntr = '1')then zeroWordCntr <= (others => '0'); elsif(or_reduce(EventBuf_Di) = '0' and EventBuf_wa(1 downto 0) = "11" and AllZero = '1' and EventBuf_we(0) = '1')then zeroWordCntr <= zeroWordCntr + 1; end if; if(resetCntr = '1')then AllZero <= '1'; elsif(EventBuf_we(0) = '1')then if(EventBuf_wa(1 downto 0) = "11")then AllZero <= '1'; elsif(or_reduce(EventBuf_Di) = '1')then AllZero <= '0'; end if; end if; we_CntrBuf2p <= not we_CntrBuf2; we_CntrBuf2 <= we_CntrBuf2p and not we_CntrBuf2; if(resetCntr = '1')then CntrBuf2_wa <= "111000"; elsif(we_CntrBuf2 = '1')then if(CntrBuf2_wa = "011111")then -- 40 counters time 3 is 120 < 128 and 7 bit counters won't overflow CntrBuf2_wa <= "111000"; else CntrBuf2_wa <= CntrBuf2_wa + 1; end if; end if; if(resetCntr = '1')then resetCntrCycle <= '1'; elsif(we_CntrBuf2 = '1' and CntrBuf2_wa = "011111")then resetCntrCycle <= '0'; end if; if(CntrBuf2_wa(5) = '1')then case CntrBuf2_wa(2 downto 0) is when "000" => Cntrs <= TTS_OFWcntr; when "001" => Cntrs <= TTS_BSYcntr; when "010" => Cntrs <= TTS_OOScntr; when "011" => Cntrs <= TTS_ERRcntr; when "100" => Cntrs <= TTS_DCcntr; when others => Cntrs <= (others=> '0'); end case; elsif(CntrBuf2_wa(4) = '0')then case CntrBuf2_wa(3 downto 0) is when x"1" => Cntrs <= sglErrCntr; when x"2" => Cntrs <= dblErrCntr; when x"3" => Cntrs <= BC0mmCntr; when x"4" => Cntrs <= BcntMmCntr; when x"5" => Cntrs <= ResendCntr; when x"6" => Cntrs <= AcceptCntr; when x"7" => Cntrs <= CntrAcceptCntr; when x"8" => Cntrs <= ACKcntr; when x"9" => Cntrs <= RxEventCntr; when x"a" => Cntrs <= RdEventCntr; when x"b" => Cntrs <= DataAbortCntr; when x"c" => Cntrs <= CntrAbortCntr; when x"d" => Cntrs <= ACKNUM_fullAbortCntr; when x"e" => Cntrs <= EventBuf_fullAbortCntr; when others => Cntrs <= EventInfo_fullAbortCntr; end case; else case CntrBuf2_wa(3 downto 0) is when x"0" => Cntrs <= SEQAbortCntr; when x"1" => Cntrs <= CRCAbortCntr; when x"2" => Cntrs <= frameAbortCntr; when x"3" => Cntrs <= bad_KAbortCntr; when x"4" => Cntrs <= BUSYCntr; when x"5" => Cntrs <= EvtEVNmmCntr; when x"6" => Cntrs <= EvtBCNmmCntr; when x"7" => Cntrs <= EvtOCNmmCntr; when x"8" => Cntrs <= bad_EventLengthCntr; when x"9" => Cntrs <= BlockCntr; -- we_EventInfo count when x"a" => Cntrs <= TTSCntr; -- IS_TTS count when x"b" => Cntrs <= TTCCntr; -- TTC_DataValid count when x"c" => Cntrs <= badCRCCntr; -- bad AMC event CRC count when x"d" => Cntrs <= TTS_ERR_cntr; -- TTC_DataValid count when x"e" => Cntrs <= TTS_SL_cntr; -- bad AMC event CRC count when others => Cntrs <= TTS_DC_cntr; end case; end if; CntrBuf2_SPO_q <= CntrBuf2_SPO; if(resetCntrCycle = '1')then CntrBuf2_Di(15 downto 7) <= (others => '0'); elsif(Cntrs < CntrBuf2_SPO_q(6 downto 0))then CntrBuf2_Di(15 downto 7) <= CntrBuf2_SPO_q(15 downto 7) + 1; else CntrBuf2_Di(15 downto 7) <= CntrBuf2_SPO_q(15 downto 7); end if; if(resetCntrCycle = '1')then CntrBuf2_Di(6 downto 0) <= (others => '0'); else CntrBuf2_Di(6 downto 0) <= Cntrs; end if; end if; end process; process(sysclk,resetCntr) begin if(resetCntr = '1')then WordCntr <= (others => '0'); WordCntr_q <= (others => '0'); elsif(sysclk'event and sysclk = '1')then if(AMC_DATA_RdEn = '1')then WordCntr <= WordCntr + 1; end if; if(Cntr_RdEn = '0' or Cntr_ra(8 downto 7) /= "10")then WordCntr_q <= WordCntr; end if; end if; end process; process(sysclk,InitLink) begin if(InitLink = '1')then EventInfoRdDoneToggle <= '0'; EventInfo_dav_i <= '0'; EventInfoToggleSyncRegs <= (others => '0'); L1Ainfo_wa <= (others => '0'); elsif(sysclk'event and sysclk = '1')then if(reset = '1')then EventInfoRdDoneToggle <= '0'; EventInfo_dav_i <= '0'; EventInfoToggleSyncRegs <= (others => '0'); L1Ainfo_wa <= (others => '0'); else if(EventInfoRdDone = '1')then EventInfoRdDoneToggle <= not EventInfoRdDoneToggle; end if; if(AMC_en = '0' or EventInfoRdDone = '1')then EventInfo_dav_i <= '0'; elsif(EventInfoToggleSyncRegs(3) /= EventInfoToggleSyncRegs(2))then EventInfo_dav_i <= '1'; end if; EventInfoToggleSyncRegs <= EventInfoToggleSyncRegs(2 downto 0) & EventInfoToggle; if(L1A_WrEn = '1' and AMC_en = '1')then L1Ainfo_wa <= L1Ainfo_wa + 1; end if; end if; end if; end process; i_L1Ainfo : BRAM_SDP_MACRO generic map ( BRAM_SIZE => "18Kb", -- Target BRAM, "18Kb" or "36Kb" DEVICE => "7SERIES", -- Target device: "VIRTEX5", "VIRTEX6", "7SERIES", "SPARTAN6" WRITE_WIDTH => 16, -- Valid values are 1-72 (37-72 only valid when BRAM_SIZE="36Kb") READ_WIDTH => 16, -- Valid values are 1-72 (37-72 only valid when BRAM_SIZE="36Kb") DO_REG => 1, -- Optional output register (0 or 1) SIM_COLLISION_CHECK => "NONE", -- Collision check enable "ALL", "WARNING_ONLY", -- "GENERATE_X_ONLY" or "NONE" WRITE_MODE => "WRITE_FIRST", -- Specify "READ_FIRST" for same clock or synchronous clocks -- Specify "WRITE_FIRST for asynchrononous clocks on ports INIT => X"000000000000000000") -- Initial values on output port port map ( DO => L1AinfoDo, -- Output read data port, width defined by READ_WIDTH parameter DI => L1A_DATA, -- Input write data port, width defined by WRITE_WIDTH parameter RDADDR => L1Ainfo_ra, -- Input read address, width defined by read port depth RDCLK => UsrClk, -- 1-bit input read clock RDEN => re_L1AinfoDo, -- 1-bit input read port enable REGCE => re_L1AinfoDo, -- 1-bit input read output register enable RST => '0', -- 1-bit input reset WE => "11", -- Input write enable, width defined by write port depth WRADDR => L1Ainfo_wa, -- Input write address, width defined by write port depth WRCLK => sysclk, -- 1-bit input write clock WREN => L1A_WrEn -- 1-bit input write port enable ); re_L1AinfoDo <= not SendTTS; g_ReSendQueue : for i in 0 to 15 generate i_ReSendQueue : SRL16E port map ( Q => ReSendQueOut(i), -- SRL data output A0 => ReSendQue_a(0), -- Select[0] input A1 => ReSendQue_a(1), -- Select[1] input A2 => '0', -- Select[2] input A3 => '0', -- Select[3] input CE => we_ReSendQue, -- Clock enable input CLK => UsrClk, -- Clock input D => ReSendQueIn(i) -- SRL data input ); end generate; ReSendQueIn <= SEQNUM & L1Ainfo_start; -- Tx logic process(UsrClk) begin if(UsrClk'event and UsrClk = '1')then if(InitLink = '1')then L1Ainfo_ra <= (others => '0'); elsif(ReSend = '1')then L1Ainfo_ra <= ReSendQueOut(7 downto 0) & "00"; elsif(ec_L1Ainfo_ra = '1' and SendTTS = '0')then L1Ainfo_ra <= L1Ainfo_ra + 1; end if; if(InitLink = '1')then L1Ainfo_start <= (others => '0'); elsif(ReSend = '1')then L1Ainfo_start <= ReSendQueOut(7 downto 0); elsif(we_ReSendQue = '1')then L1Ainfo_start <= L1Ainfo_ra(9 downto 2); end if; if(InitLink = '1')then L1Ainfo_wa2SyncRegs <= (others => '0'); else L1Ainfo_wa2SyncRegs <= L1Ainfo_wa2SyncRegs(2 downto 0) & L1Ainfo_wa(2); end if; if(InitLink = '1')then L1Ainfo_wap <= (others => '0'); elsif(L1Ainfo_wa2SyncRegs(3) /= L1Ainfo_wa2SyncRegs(2))then L1Ainfo_wap <= L1Ainfo_wap + 1; end if; if(InitLink = '1' or L1Ainfo_wap = L1Ainfo_ra(9 downto 2))then L1Ainfo_empty <= '1'; else L1Ainfo_empty <= '0'; end if; if(reset_SyncRegs(3) = '1')then InitLink <= '1'; elsif(ACK = '1' or test = '1')then InitLink <= '0'; end if; if(reset_SyncRegs(3) = '1' or ReSend = '1')then ReSendQue_a <= (others => '1'); elsif(we_ReSendQue = '1' and ACK = '0')then ReSendQue_a <= ReSendQue_a + 1; elsif(we_ReSendQue = '0' and ACK = '1' and ReSendQue_a /= "11")then ReSendQue_a <= ReSendQue_a - 1; end if; if(TxState = SendWC and Resend = '0'and SendTTS = '0' and (L1ASent = '1' or InitLink = '1'))then we_ReSendQue <= '1'; else we_ReSendQue <= '0'; end if; if(ReSendQue_a = "10")then ReSendQue_full <= '1'; else ReSendQue_full <= '0'; end if; if(reset_SyncRegs(3) = '1' or ReSend = '1')then ReSendQue_empty <= '1'; elsif(we_ReSendQue = '1')then ReSendQue_empty <= '0'; elsif(ACK = '1' and ReSendQue_a = "00")then ReSendQue_empty <= '1'; end if; if(InitLink = '1')then SEQNUM <= x"01"; elsif(ReSend = '1')then SEQNUM <= ReSendQueOut(15 downto 8); elsif(we_ReSendQue = '1')then SEQNUM <= SEQNUM(6 downto 0) & not(SEQNUM(7) xor SEQNUM(5) xor SEQNUM(4) xor SEQNUM(3)); end if; if(reset_SyncRegs(3) = '1')then got_comma <= '0'; elsif(RXCHARISCOMMA = "11")then got_comma <= '1'; end if; if(AMCRdy = '0' or reset_SyncRegs(3) = '1' or ReSend = '1')then TxState <= IDLE; ec_L1Ainfo_ra <= '0'; elsif(SendTTS = '0')then case TxState is when IDLE => -- send R_word (idle) TxState <= SendK; ec_L1Ainfo_ra <= '0'; when SendK => -- send K_word if((ReSend_l = '1' and InitLink = '1') or (ReSendQue_full = '0' and L1Ainfo_empty = '0') or ACKNUM_empty = '0' or GotCntr = '1')then TxState <= SendSEQ; else TxState <= IDLE; end if; if(InitLink = '1')then L1ASent <= '0'; IsACK <= '0'; TxType <= InitRqst; elsif(GotCntr = '1')then L1ASent <= '0'; IsACK <= '0'; TxType <= Counter; elsif(ReSendQue_full = '0' and L1Ainfo_empty = '0')then L1ASent <= '1'; ec_L1Ainfo_ra <= '1'; IsACK <= '0'; TxType <= data; else L1ASent <= '0'; IsACK <= '1'; TxType <= Acknowledge; end if; when SendSEQ => -- send packet type TxState <= SendType; if(IsACK = '0')then ACKNUM_MUX <= CntrACKNUM; else ACKNUM_MUX <= ACKNUM_l; end if; when SendType => -- send packet_seq if(L1Asent = '0')then TxState <= SendWC; else TxState <= SendData; end if; when SendWC => -- send packet_wc TxState <= WaitCRC; when WaitCRC => -- wait for CRC TxState <= SendCRC; when SendData => -- send L1A info if(packet_wc = "11")then TxState <= SendWC; end if; if(packet_wc = "01")then ec_L1Ainfo_ra <= '0'; end if; when others => TxState <= IDLE; end case; end if; if(TxState = SendK)then packet_wc <= (others => '0'); elsif(TxState = SendData and SendTTS = '0')then packet_wc(1) <= packet_wc(1) xor packet_wc(0); packet_wc(0) <= not packet_wc(0); end if; if(is_TTS = '1' or TTS_wait(7) = '1' or (InitLink = '1' and ACK = '1'))then SendTTS <= '1'; else SendTTS <= '0'; end if; if(SendTTS = '1')then TXDATA_i <= TTS & x"5c"; TxIsK <= '1'; TXCHARISK <= "01"; else case TxState is when SendK => TXDATA_i <= K_word; when SendData => TXDATA_i <= L1AinfoDo; when SendSEQ => TXDATA_i <= SEQNUM & TxType; when SendType => TXDATA_i <= ACKNUM_MUX & x"0" & AMC_IDp1; when SendWC => TXDATA_i <= x"000" & '0' & L1Asent & "00"; when SendCRC => TXDATA_i <= TxCRC; when others => TXDATA_i <= R_word; end case; case TxState is when IDLE | SendK | WaitCRC => TxIsK <= '1'; TXCHARISK <= "11"; when others => TxIsK <= '0'; TXCHARISK <= "00"; end case; end if; if(TxState = IDLE or TxState = SendK)then Init_TxCRC <= '1'; else Init_TxCRC <= '0'; end if; end if; end process; i_TxCRC: crc16D16 PORT MAP( clk => UsrClk, init_crc => Init_TxCRC, we_crc => we_TxCRC, d => TXDATA_i, crc => TxCRC ); we_TxCRC <= not TxIsK; end Behavioral;