---------------------------------------------------------------------------------- -- Company: -- Engineer: -- -- Create Date: 11:26:30 01/23/2013 -- Design Name: -- Module Name: evt_bldr - 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_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 evt_bldr is Port ( clk : in STD_LOGIC; reset : in STD_LOGIC; fifo_rst : in STD_LOGIC; fifo_en : in STD_LOGIC; en_inject_err : in STD_LOGIC; OneSFP : in STD_LOGIC; Source_ID : in STD_LOGIC_VECTOR (7 downto 0); block_wc : in STD_LOGIC_VECTOR (15 downto 0); block_wc_we : in STD_LOGIC; AMC_wc : in STD_LOGIC_VECTOR (17 downto 0); -- bit 12-0 64bit word count, bit 16-13 is AMC channel number bit 17 marks this is the last block of an event AMC_wc_we : in STD_LOGIC; AMC_wc_end : in STD_LOGIC; bldr_fifo_full : out STD_LOGIC; AMC_header : in STD_LOGIC_VECTOR (65 downto 0); AMC_header_we : in STD_LOGIC; AMC_DATA : in array12X64; AMC_DATA_re : out STD_LOGIC_VECTOR (11 downto 0); AMCCRC_bad : out STD_LOGIC_VECTOR (11 downto 0); evt_data : out STD_LOGIC_VECTOR (66 downto 0); evt_data_we : out STD_LOGIC; evt_buf_full : in STD_LOGIC; evt_data_re : in STD_LOGIC; evt_data_rdy : out STD_LOGIC; debug : out STD_LOGIC_VECTOR (255 downto 0); EventBuilt : out STD_LOGIC); end evt_bldr; architecture Behavioral of evt_bldr is COMPONENT EthernetCRCD64 PORT( clk : IN std_logic; init : IN std_logic; init_crc : IN std_logic_vector(31 downto 0); ce : IN std_logic; trailer : IN std_logic; d : IN std_logic_vector(63 downto 0); crc : OUT std_logic_vector(31 downto 0); bad_crc : OUT std_logic ); END COMPONENT; COMPONENT cmsCRC64 PORT( clk : IN std_logic; reset : IN std_logic; crc_init : IN std_logic; inject_err : IN std_logic; trailer : IN std_logic; crc_d : IN std_logic_vector(63 downto 0); crc_ce : IN std_logic; crc : OUT std_logic_vector(15 downto 0); crc_err : OUT std_logic; dout : OUT std_logic_vector(63 downto 0); dout_vld : OUT std_logic ); END COMPONENT; COMPONENT RAM32x6Db PORT( wclk : IN std_logic; di : IN std_logic_vector(5 downto 0); we : IN std_logic; wa : IN std_logic_vector(4 downto 0); ra : IN std_logic_vector(4 downto 0); do : OUT std_logic_vector(5 downto 0) ); END COMPONENT; signal fifo_we : std_logic := '0'; signal fifo_re : std_logic := '0'; --signal fifo_empty : std_logic_vector(7 downto 0) := (others => '1'); signal fifo_empty : std_logic := '1'; signal fifo_full : std_logic := '0'; signal FIFO_di : std_logic_vector(66 downto 0) := (others => '0'); signal FIFO_do : std_logic_vector(66 downto 0) := (others => '0'); signal channel : std_logic_vector(3 downto 0) := (others => '0'); signal evt_data_we_i : std_logic := '0'; signal en_output : std_logic := '0'; signal evt_data_vld : std_logic := '0'; signal evt_buf_do_vld : std_logic := '0'; signal evt_buf_re : std_logic := '0'; signal evt_cnt : std_logic_vector(3 downto 0) := (others => '0'); signal evt_buf_regce : std_logic := '0'; signal evt_buf_we : std_logic_vector(0 downto 0) := (others => '0'); signal buf_full : std_logic := '0'; signal AMC_DATA_re_i : std_logic := '0'; signal AMC_header_avl : std_logic := '0'; signal AMC_header_re : std_logic := '0'; signal header_ra_selected : std_logic := '0'; signal AMC_header_vld : std_logic := '0'; --signal ec_header_wa : std_logic := '0'; signal evt_buf_avl : std_logic := '0'; signal FIFO_Di_vld : std_logic := '0'; signal evt_buf_wc : std_logic_vector(11 downto 0) := (others => '0'); signal evt_buf_wa : std_logic_vector(11 downto 0) := (others => '0'); signal FIFO_data_wa : std_logic_vector(11 downto 0) := (others => '0'); signal FIFO_data_wa_q : std_logic_vector(11 downto 0) := (others => '0'); signal header_fifo_wc : std_logic_vector(6 downto 0) := (others => '0'); signal header_wa : std_logic_vector(6 downto 0) := (others => '0'); signal header_ra : std_logic_vector(6 downto 0) := (others => '0'); signal evt_buf_din : std_logic_vector(66 downto 0) := (others => '0'); signal evt_buf_doa : std_logic_vector(66 downto 0) := (others => '0'); signal evt_buf_ra : std_logic_vector(11 downto 0) := (others => '0'); signal evt_buf_dout : std_logic_vector(66 downto 0) := (others => '0'); signal wc_fifo_wa : std_logic_vector(5 downto 0) := (others => '0'); signal wc_fifo_ra : std_logic_vector(5 downto 0) := (others => '0'); signal wc_fifo_di : std_logic_vector(18 downto 0) := (others => '0'); signal wc_fifo_do : std_logic_vector(18 downto 0) := (others => '0'); signal wc_fifo_we : std_logic := '0'; signal wc_fifo_full : std_logic := '0'; signal header_full : std_logic := '0'; signal HeaderWC_full : std_logic := '0'; signal wc_fifo_empty : std_logic := '0'; signal wc_fifo_di_vld : std_logic := '0'; signal NoAMCenabled : std_logic := '1'; signal idle : std_logic := '1'; --signal first_hw : std_logic := '1'; signal read_AMC : std_logic := '0'; signal read_AMC_q : std_logic := '0'; signal last_channel : std_logic := '0'; signal wc : std_logic_vector(12 downto 0) := (others => '0'); signal HeaderWC : std_logic_vector(3 downto 0) := (others => '0'); signal HeaderWC_i : std_logic_vector(3 downto 0) := (others => '0'); signal HeaderWC_o : std_logic_vector(3 downto 0) := (others => '0'); signal HeaderWC_a : std_logic_vector(3 downto 0) := (others => '0'); signal HeaderWC_we : std_logic := '0'; signal HeaderWC_re : std_logic := '0'; signal crc_init : std_logic := '0'; signal crc_ce : std_logic := '0'; signal rd_last_header : std_logic := '0'; signal rd_last_header_q : std_logic := '0'; signal crc_data : std_logic_vector(63 downto 0) := (others => '0'); signal BlockCRC_init : std_logic := '0'; signal BlockCRC_ce : std_logic := '0'; signal BlockCRC_ce_q : std_logic := '0'; signal BlockCRC : std_logic_vector(31 downto 0) := (others => '0'); signal BlockCRC_data : std_logic_vector(63 downto 0) := (others => '0'); signal BlockCRC_data_r : std_logic_vector(63 downto 0) := (others => '0'); signal block_num : std_logic_vector(11 downto 0) := (others => '0'); signal Lv1bx : std_logic_vector(19 downto 0) := (others => '0'); signal trailer_we : std_logic := '0'; signal inject_err : std_logic := '0'; signal first_block : std_logic := '0'; signal last_block : std_logic := '0'; signal block_wc_a : std_logic_vector(3 downto 0) := (others => '1'); signal block_wc_o : std_logic_vector(15 downto 0) := (others => '0'); signal block_trailer : std_logic := '0'; signal block_trailer_dl : std_logic_vector(4 downto 0) := (others => '0'); signal trailer : std_logic_vector(63 downto 0) := (others => '0'); signal trailer_dl : std_logic_vector(2 downto 0) := (others => '0'); type array8X12 is array (0 to 7) of std_logic_vector(11 downto 0); signal rdcount : array8X12 := (others => (others => '0')); signal wrcount : array8X12 := (others => (others => '0')); signal evt_data_rdy_i : std_logic := '0'; signal AMCCRC_init : std_logic := '0'; signal init_AMCCRC : std_logic := '0'; signal AMCCRC_ce : std_logic := '0'; signal AMC_trailer : std_logic := '0'; signal AMClastWord : std_logic := '0'; signal bad_AMCCRC : std_logic := '0'; signal chk_AMCCRC : std_logic := '0'; signal bad_AMCCRC_l : std_logic_vector(11 downto 0) := (others => '0'); signal AMCCRC : std_logic_vector(31 downto 0) := (others => '0'); signal saved_AMCCRC : std_logic_vector(31 downto 0) := (others => '0'); signal saved_AMCCRC_di : std_logic_vector(31 downto 0) := (others => '0'); signal saved_AMCCRC_do : std_logic_vector(31 downto 0) := (others => '0'); signal saved_AMCCRC_a : std_logic_vector(4 downto 0) := (others => '0'); begin debug(255 downto 236) <= (others => '0'); debug(235 downto 224) <= evt_buf_wc; debug(223 downto 212) <= evt_buf_ra; debug(211 downto 200) <= evt_buf_wa; debug(199) <= AMC_DATA_re_i; debug(198) <= evt_data_vld; debug(197) <= evt_buf_regce; debug(196) <= evt_buf_re; debug(195) <= evt_buf_we(0); debug(194 downto 131) <= crc_data; debug(130 downto 66) <= evt_buf_din(64 downto 0); debug(65) <= AMC_DATA_re_i; debug(63 downto 0) <= BlockCRC_data; --debug(82 downto 64) <= wc_fifo_do; --debug(60) <= evt_data_rdy_i; --debug(59) <= evt_data_re; --debug(58) <= FIFO_empty; --debug(57) <= evt_buf_full; --debug(56) <= en_output; --debug(55) <= evt_data_we_i; --debug(54) <= evt_buf_avl; --debug(53) <= AMC_DATA_re_i; --debug(52) <= idle; --debug(51) <= wc_fifo_empty; --debug(50) <= fifo_full; --debug(49 downto 44) <= wc_fifo_a; --debug(43 downto 32) <= evt_buf_wc; --debug(31 downto 28) <= channel; --debug(27 downto 16) <= evt_buf_wa; --debug(15 downto 12) <= evt_cnt; --debug(11 downto 0) <= evt_buf_ra; evt_data <= evt_buf_dout(66 downto 0); evt_data_we <= evt_data_we_i; evt_data_rdy <= evt_data_rdy_i; EventBuilt <= trailer_we; g_wc_fifo: for i in 0 to 18 generate i_wc_fifo : RAM64X1D port map ( DPO => wc_fifo_do(i), -- Read-only 1-bit data output SPO => open, -- R/W 1-bit data output A0 => wc_fifo_wa(0), -- R/W address[0] input bit A1 => wc_fifo_wa(1), -- R/W address[1] input bit A2 => wc_fifo_wa(2), -- R/W address[2] input bit A3 => wc_fifo_wa(3), -- R/W address[3] input bit A4 => wc_fifo_wa(4), -- R/W address[4] input bit A5 => wc_fifo_wa(5), -- R/W address[5] input bit D => wc_fifo_di(i), -- Write 1-bit data input DPRA0 => wc_fifo_ra(0), -- Read-only address[0] input bit DPRA1 => wc_fifo_ra(1), -- Read-only address[1] input bit DPRA2 => wc_fifo_ra(2), -- Read-only address[2] input bit DPRA3 => wc_fifo_ra(3), -- Read-only address[3] input bit DPRA4 => wc_fifo_ra(4), -- Read-only address[4] input bit DPRA5 => wc_fifo_ra(5), -- Read-only address[5] input bit WCLK => clk, -- Write clock input WE => wc_fifo_we -- Write enable input ); end generate; wc_fifo_di(18) <= AMC_wc_end; wc_fifo_we <= wc_fifo_di_vld and (AMC_wc_we or AMC_wc_end); g_HeaderWC: for i in 0 to 3 generate i_HeaderWC : SRL16E port map ( Q => HeaderWC_o(i), -- SRL data output A0 => HeaderWC_a(0), -- Select[0] input A1 => HeaderWC_a(1), -- Select[1] input A2 => HeaderWC_a(2), -- Select[2] input A3 => HeaderWC_a(3), -- Select[3] input CE => HeaderWC_we, -- Clock enable input CLK => clk, -- Clock input D => HeaderWC_i(i) -- SRL data input ); end generate; HeaderWC_re <= block_trailer; g_block_wc: for i in 0 to 15 generate i_block_wc : SRL16E port map ( Q => block_wc_o(i), -- SRL data output A0 => block_wc_a(0), -- Select[0] input A1 => block_wc_a(1), -- Select[1] input A2 => block_wc_a(2), -- Select[2] input A3 => block_wc_a(3), -- Select[3] input CE => block_wc_we, -- Clock enable input CLK => clk, -- Clock input D => block_wc(i) -- SRL data input ); end generate; process(clk) begin if(clk'event and clk = '1')then if(reset = '1')then HeaderWC_a <= (others => '1'); elsif(HeaderWC_we = '1' and HeaderWC_re = '0')then HeaderWC_a <= HeaderWC_a + 1; elsif(HeaderWC_we = '0' and HeaderWC_re = '1')then HeaderWC_a <= HeaderWC_a - 1; end if; if(reset = '1' or HeaderWC_we = '1')then HeaderWC_i <= (others => '0'); elsif(AMC_header_we = '1')then HeaderWC_i <= HeaderWC_i + 1; end if; HeaderWC_we <= AMC_wc_end and or_reduce(HeaderWC_i); if(reset = '1')then block_wc_a <= (others => '1'); elsif(block_wc_we = '1' and block_trailer = '0')then block_wc_a <= block_wc_a + 1; elsif(block_wc_we = '0' and block_trailer = '1')then block_wc_a <= block_wc_a - 1; end if; end if; end process; process(clk) begin if(clk'event and clk = '1')then if(AMC_wc_we = '1')then wc_fifo_di(17 downto 0) <= AMC_wc; end if; if(reset = '1')then NoAMCenabled <= '0'; elsif(AMC_wc_end = '1')then NoAMCenabled <= not wc_fifo_di_vld; end if; if(reset = '1' or AMC_wc_end = '1')then wc_fifo_di_vld <= '0'; elsif(AMC_wc_we = '1')then wc_fifo_di_vld <= '1'; end if; if(AMC_header_we = '1')then evt_buf_din(66) <= '0'; evt_buf_din(65 downto 0) <= AMC_header; else evt_buf_din <= FIFO_do; end if; if(reset = '1')then evt_buf_wa <= (others => '0'); elsif(AMC_header_we = '1')then evt_buf_wa <= "11111" & header_wa; elsif(AMC_header_re = '1')then evt_buf_wa <= "11111" & header_ra; else evt_buf_wa <= FIFO_data_wa; end if; if(reset = '1')then FIFO_data_wa <= (others => '0'); elsif(FIFO_re = '1')then if(FIFO_data_wa = x"f7f")then FIFO_data_wa <= (others => '0'); else FIFO_data_wa <= FIFO_data_wa + 1; end if; end if; if(reset = '1')then FIFO_data_wa_q <= (others => '0'); else FIFO_data_wa_q <= FIFO_data_wa; end if; evt_buf_we(0) <= not reset and (FIFO_re or AMC_header_we); if(reset = '1' or (evt_buf_wc(11 downto 8) = x"f" and evt_buf_wc(6 downto 3) = x"f"))then evt_buf_avl <= '0'; else evt_buf_avl <= '1'; end if; if(reset = '1')then header_wa <= (others => '0'); elsif(AMC_header_we = '1')then header_wa <= header_wa + 1; end if; if(reset = '1' or and_reduce(HeaderWC_a) = '1')then AMC_header_avl <= '0'; else AMC_header_avl <= '1'; end if; header_ra_selected <= not reset and AMC_header_re and not AMC_header_we; AMC_header_vld <= not reset and header_ra_selected; if(AMC_header_vld = '1')then FIFO_di(66) <= not evt_buf_doa(64); end if; BlockCRC_ce <= not reset and (AMC_header_vld or AMC_DATA_re_i or block_trailer); if(AMC_DATA_re_i = '1')then BlockCRC_data <= AMC_DATA(CONV_INTEGER(channel)); elsif(block_trailer = '1')then BlockCRC_data <= x"00000000" & block_num & Lv1Bx; elsif(evt_buf_doa(65) = '1')then BlockCRC_data <= evt_buf_doa(63 downto 52) & block_wc_o & evt_buf_doa(35 downto 0); else BlockCRC_data <= evt_buf_doa(63 downto 0); end if; if(reset = '1')then block_trailer_dl(2 downto 0) <= (others => '0'); else block_trailer_dl(2 downto 0) <= block_trailer_dl(1 downto 0) & block_trailer; end if; if(block_trailer = '1')then inject_err <= en_inject_err and last_block and and_reduce(Lv1Bx(19 downto 12)); -- one in 256 events end if; if(block_trailer_dl(1) = '0')then BlockCRC_data_r <= BlockCRC_data; elsif(inject_err = '0')then BlockCRC_data_r <= BlockCRC & BlockCRC_data_r(31 downto 0); end if; BlockCRC_init <= reset or block_trailer_dl(0); if(trailer_we = '1')then crc_data <= trailer; else crc_data <= BlockCRC_data_r; end if; BlockCRC_ce_q <= not reset and ((BlockCRC_ce and not block_trailer_dl(0)) or block_trailer_dl(1)); crc_ce <= not reset and (trailer_we or BlockCRC_ce_q); crc_init <= reset or trailer_dl(0); header_fifo_wc <= header_wa - header_ra; if(header_fifo_wc(6 downto 4) = "111")then header_full <= '1'; else header_full <= '0'; end if; if(HeaderWC_a = x"e")then HeaderWC_full <= '1'; else HeaderWC_full <= '0'; end if; bldr_fifo_full <= reset or wc_fifo_full or header_full or HeaderWC_full; end if; end process; process(clk) variable wc_fifo_wc : std_logic_vector(5 downto 0); begin wc_fifo_wc := wc_fifo_wa - wc_fifo_ra; if(clk'event and clk = '1')then if(reset = '1')then wc_fifo_wa <= (others => '0'); elsif(wc_fifo_we = '1')then wc_fifo_wa <= wc_fifo_wa + 1; end if; if(reset = '1')then wc_fifo_ra <= (others => '0'); elsif(read_AMC = '1')then wc_fifo_ra <= wc_fifo_ra + 1; end if; if(wc_fifo_wc(5 downto 4) = "11")then wc_fifo_full <= '1'; elsif(OneSFP = '0' and wc_fifo_wc(5 downto 3) = "111")then wc_fifo_full <= '1'; else wc_fifo_full <= '0'; end if; if(reset = '1' or wc_fifo_wa = wc_fifo_ra)then wc_fifo_empty <= '1'; else wc_fifo_empty <= '0'; end if; end if; end process; i_BlockCRC: EthernetCRCD64 PORT MAP( clk => clk, init => BlockCRC_init, init_crc => (others => '1'), ce => BlockCRC_ce, trailer => block_trailer_dl(0), d => BlockCRC_data, crc => BlockCRC, bad_crc => open ); i_EventCRC: cmsCRC64 PORT MAP( clk => clk, reset => reset, crc_init => crc_init, inject_err => inject_err, trailer => trailer_dl(0), crc_d => crc_data, crc_ce => crc_ce, crc => open, crc_err => open, dout => FIFO_di(63 downto 0), dout_vld => FIFO_di_vld ); g_evt_FIFO: for i in 0 to 6 generate i_evt_FIFO : FIFO_DUALCLOCK_MACRO generic map ( DEVICE => "7SERIES", -- Target Device: "VIRTEX5", "VIRTEX6", "7SERIES" ALMOST_FULL_OFFSET => X"0010", -- Sets almost full threshold ALMOST_EMPTY_OFFSET => X"0080", -- Sets the almost empty threshold DATA_WIDTH => 9, -- Valid values are 1-72 (37-72 only valid when FIFO_SIZE="36Kb") FIFO_SIZE => "36Kb", -- Target BRAM, "18Kb" or "36Kb" FIRST_WORD_FALL_THROUGH => TRUE) -- Sets the FIFO FWFT to TRUE or FALSE port map ( ALMOSTEMPTY => open, -- 1-bit output almost empty ALMOSTFULL => open, -- 1-bit output almost full DO => FIFO_do(i*9+8 downto i*9), -- Output data, width defined by DATA_WIDTH parameter EMPTY => open, -- 1-bit output empty FULL => open, -- 1-bit output full RDCOUNT => rdcount(i), -- Output read count, width determined by FIFO depth RDERR => open, -- 1-bit output read error WRCOUNT => wrcount(i), -- Output write count, width determined by FIFO depth WRERR => open, -- 1-bit output write error DI => FIFO_di(i*9+8 downto i*9), -- Input data, width defined by DATA_WIDTH parameter RDCLK => clk, -- 1-bit input read clock RDEN => FIFO_re, -- 1-bit input read enable RST => fifo_rst, -- 1-bit input reset WRCLK => clk, -- 1-bit input write clock WREN => FIFO_we -- 1-bit input write enable ); end generate; i_evt_FIFO_MSB : FIFO_DUALCLOCK_MACRO generic map ( DEVICE => "7SERIES", -- Target Device: "VIRTEX5", "VIRTEX6", "7SERIES" ALMOST_FULL_OFFSET => X"0020", -- Sets almost full threshold ALMOST_EMPTY_OFFSET => X"0080", -- Sets the almost empty threshold DATA_WIDTH => 4, -- Valid values are 1-72 (37-72 only valid when FIFO_SIZE="36Kb") FIFO_SIZE => "18Kb", -- Target BRAM, "18Kb" or "36Kb" FIRST_WORD_FALL_THROUGH => TRUE) -- Sets the FIFO FWFT to TRUE or FALSE port map ( ALMOSTEMPTY => open, -- 1-bit output almost empty ALMOSTFULL => fifo_full, -- 1-bit output almost full DO => FIFO_do(66 downto 63), -- Output data, width defined by DATA_WIDTH parameter EMPTY => FIFO_empty, -- 1-bit output empty FULL => open, -- 1-bit output full RDCOUNT => rdcount(7), -- Output read count, width determined by FIFO depth RDERR => open, -- 1-bit output read error WRCOUNT => wrcount(7), -- Output write count, width determined by FIFO depth WRERR => open, -- 1-bit output write error DI => FIFO_di(66 downto 63), -- Input data, width defined by DATA_WIDTH parameter RDCLK => clk, -- 1-bit input read clock RDEN => FIFO_re, -- 1-bit input read enable RST => fifo_rst, -- 1-bit input reset WRCLK => clk, -- 1-bit input write clock WREN => FIFO_we -- 1-bit input write enable ); FIFO_di(65) <= trailer_dl(2); --FIFO_re <= fifo_en and evt_buf_avl and not or_reduce(FIFO_empty) and not AMC_header_we and not AMC_header_re; FIFO_re <= fifo_en and evt_buf_avl and not FIFO_empty and not AMC_header_we and not AMC_header_re; FIFO_we <= fifo_en and FIFO_Di_vld; process(clk) begin if(clk'event and clk = '1')then if(reset = '1')then en_output <= '0'; -- elsif(evt_data_re = '1' and evt_data_rdy_i = '1')then elsif(evt_data_re = '1')then en_output <= '1'; elsif(evt_data_we_i = '1' and evt_buf_dout(64) = '1')then en_output <= '0'; end if; if(reset = '1' or (evt_data_we_i = '1' and evt_buf_dout(64) = '1') or evt_data_vld = '0' or (evt_data_we_i = '1' and evt_buf_do_vld = '0'))then evt_data_we_i <= '0'; else evt_data_we_i <= en_output and not evt_buf_full; end if; if(reset = '1')then evt_data_vld <= '0'; elsif(evt_buf_do_vld = '1')then evt_data_vld <= '1'; elsif(evt_data_we_i = '1')then evt_data_vld <= '0'; end if; if(reset = '1')then evt_buf_do_vld <= '0'; elsif(FIFO_data_wa_q /= evt_buf_ra)then evt_buf_do_vld <= '1'; elsif(evt_data_vld = '0' or evt_data_we_i = '1')then evt_buf_do_vld <= '0'; end if; if(reset = '1')then evt_buf_ra <= (others => '0'); elsif(FIFO_data_wa_q /= evt_buf_ra and evt_buf_re = '1')then if(evt_buf_ra = x"f7f")then evt_buf_ra <= (others => '0'); else evt_buf_ra <= evt_buf_ra + 1; end if; end if; if(reset = '1')then trailer_dl <= (others => '0'); else trailer_dl <= trailer_dl(1 downto 0) & trailer_we; end if; if(reset = '1')then evt_cnt <= (others => '0'); elsif(trailer_we = '1' and (evt_buf_dout(65) = '0' or evt_data_we_i = '0'))then evt_cnt <= evt_cnt + 1; elsif(trailer_we = '0' and evt_buf_dout(65) = '1' and evt_data_we_i = '1')then evt_cnt <= evt_cnt - 1; end if; if(reset = '1' or evt_data_we_i = '1' or evt_data_vld = '0')then evt_data_rdy_i <= '0'; else evt_data_rdy_i <= or_reduce(evt_cnt) or or_reduce(evt_buf_wc(11 downto 8)); end if; if(reset = '1')then evt_buf_wc <= (others => '0'); -- elsif(evt_data_we_i = '0' and FIFO_re = '1')then elsif((or_reduce(evt_buf_wc) = '0' or evt_buf_re = '0') and FIFO_re = '1')then evt_buf_wc <= evt_buf_wc + 1; -- elsif(evt_data_we_i = '1' and FIFO_re = '0')then elsif(or_reduce(evt_buf_wc) = '1' and evt_buf_re = '1' and FIFO_re = '0')then evt_buf_wc <= evt_buf_wc - 1; end if; end if; end process; g_evt_buf: for i in 0 to 6 generate i_evt_buf : BRAM_TDP_MACRO generic map ( BRAM_SIZE => "36Kb", -- Target BRAM, "18Kb" or "36Kb" DEVICE => "7SERIES", -- Target Device: "VIRTEX5", "VIRTEX6", "7SERIES", "SPARTAN6" DOA_REG => 0, -- Optional port A output register (0 or 1) DOB_REG => 1, -- Optional port B output register (0 or 1) INIT_A => X"000000000", -- Initial values on A output port INIT_B => X"000000000", -- Initial values on B output port INIT_FILE => "NONE", READ_WIDTH_A => 9, -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb") READ_WIDTH_B => 9, -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb") SIM_COLLISION_CHECK => "NONE", -- Collision check enable "ALL", "WARNING_ONLY", -- "GENERATE_X_ONLY" or "NONE" SRVAL_A => X"000000000", -- Set/Reset value for A port output SRVAL_B => X"000000000", -- Set/Reset value for B port output WRITE_MODE_A => "WRITE_FIRST", -- "WRITE_FIRST", "READ_FIRST" or "NO_CHANGE" WRITE_MODE_B => "WRITE_FIRST", -- "WRITE_FIRST", "READ_FIRST" or "NO_CHANGE" WRITE_WIDTH_A => 9, -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb") WRITE_WIDTH_B => 9) -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb") port map ( DOA => evt_buf_doA(i*9+8 downto i*9), -- Output port-A data, width defined by READ_WIDTH_A parameter DOB => evt_buf_dout(i*9+8 downto i*9), -- Output port-B data, width defined by READ_WIDTH_B parameter ADDRA => evt_buf_wa, -- Input port-A address, width defined by Port A depth ADDRB => evt_buf_ra, -- Input port-B address, width defined by Port B depth CLKA => clk, -- 1-bit input port-A clock CLKB => clk, -- 1-bit input port-B clock DIA => evt_buf_din(i*9+8 downto i*9), -- Input port-A data, width defined by WRITE_WIDTH_A parameter DIB => (others => '0'), -- Input port-B data, width defined by WRITE_WIDTH_B parameter ENA => '1', -- 1-bit input port-A enable ENB => evt_buf_re, -- 1-bit input port-B enable REGCEA => '1', -- 1-bit input port-A output register enable REGCEB => evt_buf_regce, -- 1-bit input port-B output register enable RSTA => '0', -- 1-bit input port-A reset RSTB => '0', -- 1-bit input port-B reset WEA => evt_buf_we, -- Input port-A write enable, width defined by Port A depth WEB => "0" -- Input port-B write enable, width defined by Port B depth ); end generate; i_evt_buf_MSB : BRAM_TDP_MACRO generic map ( BRAM_SIZE => "18Kb", -- Target BRAM, "18Kb" or "36Kb" DEVICE => "7SERIES", -- Target Device: "VIRTEX5", "VIRTEX6", "7SERIES", "SPARTAN6" DOA_REG => 0, -- Optional port A output register (0 or 1) DOB_REG => 1, -- Optional port B output register (0 or 1) INIT_A => X"000000000", -- Initial values on A output port INIT_B => X"000000000", -- Initial values on B output port INIT_FILE => "NONE", READ_WIDTH_A => 4, -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb") READ_WIDTH_B => 4, -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb") SIM_COLLISION_CHECK => "NONE", -- Collision check enable "ALL", "WARNING_ONLY", -- "GENERATE_X_ONLY" or "NONE" SRVAL_A => X"000000000", -- Set/Reset value for A port output SRVAL_B => X"000000000", -- Set/Reset value for B port output WRITE_MODE_A => "WRITE_FIRST", -- "WRITE_FIRST", "READ_FIRST" or "NO_CHANGE" WRITE_MODE_B => "WRITE_FIRST", -- "WRITE_FIRST", "READ_FIRST" or "NO_CHANGE" WRITE_WIDTH_A => 4, -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb") WRITE_WIDTH_B => 4) -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb") port map ( DOA => evt_buf_doA(66 downto 63), -- Output port-A data, width defined by READ_WIDTH_A parameter DOB => evt_buf_dout(66 downto 63), -- Output port-B data, width defined by READ_WIDTH_B parameter ADDRA => evt_buf_wa, -- Input port-A address, width defined by Port A depth ADDRB => evt_buf_ra, -- Input port-B address, width defined by Port B depth CLKA => clk, -- 1-bit input port-A clock CLKB => clk, -- 1-bit input port-B clock DIA => evt_buf_din(66 downto 63), -- Input port-A data, width defined by WRITE_WIDTH_A parameter DIB => (others => '0'), -- Input port-B data, width defined by WRITE_WIDTH_B parameter ENA => '1', -- 1-bit input port-A enable ENB => evt_buf_re, -- 1-bit input port-B enable REGCEA => '1', -- 1-bit input port-A output register enable REGCEB => evt_buf_regce, -- 1-bit input port-B output register enable RSTA => '0', -- 1-bit input port-A reset RSTB => '0', -- 1-bit input port-B reset WEA => evt_buf_we, -- Input port-A write enable, width defined by Port A depth WEB => "0" -- Input port-B write enable, width defined by Port B depth ); evt_buf_regce <= not evt_data_vld or evt_data_we_i; evt_buf_re <= not evt_buf_do_vld or not evt_data_vld or evt_data_we_i; -- event word count and trailer process(clk) begin if(clk'event and clk = '1')then rd_last_header_q <= not reset and rd_last_header; if(reset = '0' and block_trailer = '0' and ((last_channel = '1' and or_reduce(wc(12 downto 1)) = '0' and AMC_DATA_re_i = '1') or (rd_last_header_q = '1' and NoAMCenabled = '1')))then block_trailer <= '1'; else block_trailer <= '0'; end if; if(reset = '0' and block_trailer_dl(2) = '1' and last_block = '1')then trailer_we <= '1'; else trailer_we <= '0'; end if; block_trailer_dl(3) <= block_trailer_dl(2) and not last_block; block_trailer_dl(4) <= block_trailer_dl(3); if(trailer_dl(1) = '1' or block_trailer_dl(4) = '1')then FIFO_di(64) <= '1'; else FIFO_di(64) <= '0'; end if; if(reset = '1' or trailer_we = '1')then block_num <= (others => '0'); elsif(block_trailer = '1')then block_num <= block_num + 1; end if; if(reset = '1' or trailer_we = '1')then trailer(55 downto 32) <= x"000001"; elsif(BlockCRC_ce = '1')then trailer(55 downto 32) <= trailer(55 downto 32) + 1; end if; end if; end process; trailer(63 downto 56) <= x"a0"; trailer(31 downto 16) <= x"0000"; trailer(15 downto 8) <= Source_ID; trailer(7 downto 0) <= x"00"; process(clk) begin if(clk'event and clk = '1')then if(reset = '1' or block_trailer_dl(2) = '1')then idle <= '1'; elsif(AMC_header_re = '1')then idle <= '0'; end if; if(reset = '1')then HeaderWC <= (others => '0'); elsif(idle = '1' and AMC_header_re = '0')then HeaderWC <= HeaderWC_o; elsif(AMC_header_we = '0' and AMC_header_re = '1')then HeaderWC <= HeaderWC - 1; end if; if(reset = '1' or (HeaderWC = x"1" and AMC_header_we = '0' and AMC_header_re = '1'))then AMC_header_re <= '0'; elsif(idle = '1' and AMC_header_avl = '1' and (wc_fifo_empty = '0' or NoAMCenabled = '1') and fifo_full = '0' and and_reduce(evt_cnt) = '0')then AMC_header_re <= '1'; end if; if(reset = '1')then header_ra <= (others => '0'); elsif(AMC_header_we = '0' and AMC_header_re = '1')then header_ra <= header_ra + 1; end if; if(reset = '0' and HeaderWC = x"1" and AMC_header_re = '1' and AMC_header_we = '0')then rd_last_header <= '1'; else rd_last_header <= '0'; end if; if(reset = '1' or read_AMC = '1')then read_AMC <= '0'; elsif((last_channel = '0' and or_reduce(wc(12 downto 1)) = '0' and AMC_DATA_re_i = '1') or (rd_last_header = '1' and NoAMCenabled = '0'))then read_AMC <= '1'; end if; if(reset = '1' or fifo_full = '1' or (or_reduce(wc(12 downto 1)) = '0' and (AMC_DATA_re_i = '1' or wc(0) = '0')))then AMC_DATA_re_i <= '0'; AMC_DATA_re <= (others => '0'); else AMC_DATA_re_i <= '1'; for i in 0 to 11 loop if(i = channel)then AMC_DATA_re(i) <= '1'; else AMC_DATA_re(i) <= '0'; end if; end loop; end if; if(AMC_header_vld = '1' and first_block = '1')then Lv1bx <= evt_buf_doa(39 downto 20); end if; if(reset = '1' or trailer_we = '1')then first_block <= '1'; elsif(AMC_header_vld = '1')then first_block <= '0'; end if; if(reset = '1')then last_channel <= '0'; last_block <= '0'; elsif(AMC_header_re = '1')then last_channel <= '0'; last_block <= first_block and NoAMCenabled; elsif(read_AMC = '1')then last_channel <= wc_fifo_do(18); last_block <= wc_fifo_do(17); end if; if(reset = '1')then channel <= (others => '0'); wc <= (others => '0'); elsif(read_AMC = '1')then channel <= wc_fifo_do(16 downto 13); wc <= wc_fifo_do(12 downto 0); elsif(AMC_DATA_re_i = '1')then wc <= wc - 1; end if; end if; end process; -- check AMC event CRC g_saved_AMCCRC: for i in 0 to 3 generate i_saved_AMCCRC : RAM32M port map ( DOA => saved_AMCCRC_do(i*8+1 downto i*8), -- Read port A 2-bit output DOB => saved_AMCCRC_do(i*8+3 downto i*8+2), -- Read port B 2-bit output DOC => saved_AMCCRC_do(i*8+5 downto i*8+4), -- Read port C 2-bit output DOD => saved_AMCCRC_do(i*8+7 downto i*8+6), -- Read/Write port D 2-bit output ADDRA => saved_AMCCRC_a, -- Read port A 5-bit address input ADDRB => saved_AMCCRC_a, -- Read port B 5-bit address input ADDRC => saved_AMCCRC_a, -- Read port C 5-bit address input ADDRD => saved_AMCCRC_a, -- Read/Write port D 5-bit address input DIA => saved_AMCCRC_di(i*8+1 downto i*8), -- RAM 2-bit data write input addressed by ADDRD, -- read addressed by ADDRA DIB => saved_AMCCRC_di(i*8+3 downto i*8+2), -- RAM 2-bit data write input addressed by ADDRD, -- read addressed by ADDRB DIC => saved_AMCCRC_di(i*8+5 downto i*8+4), -- RAM 2-bit data write input addressed by ADDRD, -- read addressed by ADDRC DID => saved_AMCCRC_di(i*8+7 downto i*8+6), -- RAM 2-bit data write input addressed by ADDRD, -- read addressed by ADDRD WCLK => clk, -- Write clock input WE => chk_AMCCRC -- Write enable input ); end generate; g_saved_AMCCRC_di: for i in 0 to 31 generate saved_AMCCRC_di(i) <= not AMCCRC(31-i); end generate; process(clk) begin if(clk'event and clk = '1')then if(reset = '1')then AMCCRC_bad <= (others => '0'); elsif(trailer_we = '1')then AMCCRC_bad <= bad_AMCCRC_l; else AMCCRC_bad <= (others => '0'); end if; if(reset = '1' or trailer_we = '1')then init_AMCCRC <= '1'; elsif(last_channel = '1' and AMCCRC_init = '1')then init_AMCCRC <= '0'; end if; AMCCRC_ce <= AMC_DATA_re_i; if(or_reduce(wc(12 downto 1)) = '0' and AMC_DATA_re_i = '1')then AMClastWord <= '1'; else AMClastWord <= '0'; end if; chk_AMCCRC <= AMClastWord; saved_AMCCRC_a(3 downto 0) <= channel; read_AMC_q <= read_AMC; AMCCRC_init <= read_AMC_q; if(first_block = '1')then bad_AMCCRC_l <= (others => '0'); elsif(chk_AMCCRC = '1')then bad_AMCCRC_l(conv_integer(saved_AMCCRC_a(3 downto 0))) <= bad_AMCCRC; end if; end if; end process; i_AMCCRC: EthernetCRCD64 PORT MAP( clk => clk, init => AMCCRC_init, init_crc => saved_AMCCRC, ce => AMCCRC_ce, trailer => AMC_trailer, d => BlockCRC_data, crc => AMCCRC, bad_crc => bad_AMCCRC ); saved_AMCCRC <= (others => '1') when init_AMCCRC = '1' else saved_AMCCRC_do(31 downto 0); end Behavioral;