-- readoutHist.vhd - writes histogram data to the transmit buffer. -- August 2009 -- Alexander Law (atlaw@lbl.gov) -- Lawrence Berkeley National Laboratory library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_ARITH.all; use IEEE.STD_LOGIC_UNSIGNED.all; use ieee.numeric_std.all; library UNISIM; use UNISIM.VComponents.all; entity readoutHist_sctdaq is port( clock : in std_logic; -- reset : in std_logic; -- trigger_i : in std_logic; ready_out : out std_logic; -- chipType : in std_logic; hst_rdPtr_out : out std_logic_vector(10 downto 0); -- hst_rdData : in std_logic_vector(15 downto 0); -- hst_wrPtr_out : out std_logic_vector(10 downto 0); hst_wrData_out : out std_logic_vector(15 downto 0); hst_wrEn_out : out std_logic; xmt_wrPtr_out : out std_logic_vector(12 downto 0); -- xmt_wrData_out : out std_logic_vector(7 downto 0); -- xmt_wrEn_out : out std_logic := '0'; -- xmt_dataLen_out : out std_logic_vector(12 downto 0); -- -- xmt_waiting_out : out std_logic := '0'; -- xmt_ready : in std_logic; -- xmt_trigger_out : out std_logic := '0'; -- sctdaq_mode_i : in std_logic; -- ll_sof_o : out std_logic; ll_eof_o : out std_logic; ll_src_rdy_o : out std_logic; ll_dst_rdy_i : in std_logic; ll_data_o : out std_logic_vector(15 downto 0); ll_data_len_o : out std_logic_vector(15 downto 0) ); end readoutHist_sctdaq; architecture Behavioral of readoutHist_sctdaq is signal histogramLen : integer range 0 to 2047 := 0; -- clean this up later signal hst_rdPtr : integer range 0 to 2047 := 0; signal hst_rdPtr_next : integer range 0 to 2047 := 0; signal hst_wrPtr : integer range 0 to 2047 := 0; -- only want 0 to 767/1280, but range will relfect read bit field range. signal hst_wrPtr_next : integer range 0 to 2047 := 0; -- only want 0 to 767/1280, but range will relfect read bit field range. -- hst_wrData is constant 0x0000, used to clear the data after readout. signal hst_wrEn : std_logic := '0'; signal hst_wrEn_next : std_logic := '0'; signal xmt_wrPtr : integer range 0 to 8191 := 0; -- signal xmt_wrPtr_next : integer range 0 to 8191 := 0; -- xmt_wrPtr synchronous-assignment signal signal xmt_wrEn : std_logic := '0'; -- signal xmt_wrEn_next : std_logic := '0'; -- xmt_wrEn synchronous-assignment signal signal xmt_trigger : std_logic := '0'; -- signal xmt_trigger_next : std_logic := '0'; -- xmt_trigger synchronous-assignment signal type states is (waiting, byte0, byte1, clearLastByte, done, sd_channel, sd_size, sd_seqnum, sd_readoutdata, sd_opcode); signal state : states := waiting; signal nextState : states := waiting; signal readoutCount : integer range 0 to 1281 := 0; signal readoutCount_next : integer range 0 to 1281 := 0; signal byteSelect : integer range 0 to 1 := 0; signal byteselect_next : integer range 0 to 1 := 0; signal ready : std_logic := '0'; signal ll_sof : std_logic; signal ll_eof : std_logic; signal ll_src_rdy : std_logic; signal sctdaq_header : std_logic; signal header_data : std_logic_vector(15 downto 0); signal trigger : std_logic; signal trigger_q : std_logic; signal seqnum : std_logic_vector(15 downto 0); begin ----------- persistent assignments -------------- hst_rdPtr_out <= std_logic_vector(to_unsigned(hst_rdPtr, 11)); hst_wrPtr_out <= std_logic_vector(to_unsigned(hst_wrPtr, 11)); hst_wrData_out <= "0000000000000000"; hst_wrEn_out <= hst_wrEn; xmt_wrPtr_out <= std_logic_vector(to_unsigned(xmt_wrPtr, 13)); xmt_wrEn_out <= xmt_wrEn; xmt_dataLen_out <= std_logic_vector(to_unsigned(histogramLen*2, 13)); xmt_trigger_out <= xmt_trigger; xmt_wrData_out <= hst_rdData(byteSelect*8 +7 downto byteSelect*8); ready_out <= ready; with chipType select histogramLen <= 768 when '0', 128 when others; --1280 ll_data_len_o <= x"0110"; ------------------------------------------------- ---------- synchronous assignments -------------- process(clock, reset) begin if (reset = '1') then state <= done; hst_rdPtr <= 0; hst_wrPtr <= 0; hst_wrEn <= '0'; xmt_wrPtr <= 0; xmt_wrEn <= '0'; -- xmt_waiting <= '0'; xmt_trigger <= '0'; readoutCount <= 0; byteSelect <= 1; ll_data_o <= x"0000"; elsif (clock'event and clock = '1') then state <= nextState; hst_rdPtr <= hst_rdPtr_next; hst_wrPtr <= hst_wrPtr_next; hst_wrEn <= hst_wrEn_next; xmt_wrPtr <= xmt_wrPtr_next; xmt_wrEn <= xmt_wrEn_next; -- xmt_waiting <= xmt_waiting_next; xmt_trigger <= xmt_trigger_next; readoutCount <= readoutCount_next; -- xmt_waiting <= xmt_waiting_next; byteSelect <= byteSelect_next; if (sctdaq_header = '1') then ll_data_o <= header_data; else ll_data_o <= hst_rdData; end if; ll_sof_o <= ll_sof; ll_eof_o <= ll_eof; ll_src_rdy_o <= ll_src_rdy; end if; end process; ------------------------------------------------- ----- ready flag ----- with state select ready <= '1' when done, '0' when others; ----------------------- process( histogramLen, state, readoutCount, byteSelect, hst_rdData, hst_rdPtr, hst_wrPtr, xmt_wrPtr, xmt_ready, trigger ) begin -- defaults ll_sof <= '0'; ll_eof <= '0'; ll_src_rdy <= '0'; sctdaq_header <= '0'; case state is when waiting => readoutCount_next <= readoutCount; xmt_wrPtr_next <= 0; xmt_trigger_next <= '0'; byteSelect_next <= 1; -- 15 downto 0 hst_rdPtr_next <= 0; hst_wrPtr_next <= 0; hst_wrEn_next <= '0'; xmt_wrEn_next <= '0'; --if (xmt_ready = '1') then if (sctdaq_mode_i = '1') then nextState <= sd_opcode; else nextState <= byte0; xmt_wrEn_next <= '1'; end if; --end if; when byte1 => xmt_trigger_next <= '0'; nextState <= byte0; hst_rdPtr_next <= hst_rdPtr+1; xmt_wrPtr_next <= xmt_wrPtr +1; xmt_wrEn_next <= '1'; hst_wrPtr_next <= hst_rdPtr; hst_wrEn_next <= '0'; byteSelect_next <= 0; readoutCount_next <= readoutCount +1; when byte0 => readoutCount_next <= readoutCount; byteSelect_next <= 1; hst_wrPtr_next <= hst_wrPtr; hst_wrEn_next <= '1'; if (readoutCount < histogramLen) then nextState <= byte1; hst_rdPtr_next <= hst_rdPtr; xmt_wrEn_next <= '1'; xmt_wrPtr_next <= xmt_wrPtr +1; xmt_trigger_next <= '0'; else nextState <= clearLastByte; hst_rdPtr_next <= 0; xmt_wrEn_next <= '0'; xmt_wrPtr_next <= xmt_wrPtr; xmt_trigger_next <= '1'; end if; when clearLastByte => -- crude, should be able to sneak this into the main two states. nextState <= done; byteSelect_next <= byteSelect; hst_wrPtr_next <= hst_wrPtr+1; hst_wrEn_next <= '1'; hst_rdPtr_next <= hst_rdPtr; xmt_wrPtr_next <= xmt_wrPtr; xmt_wrEn_next <= '0'; xmt_trigger_next <= '0'; readoutCount_next <= readoutCount; when done => xmt_trigger_next <= '0'; xmt_wrEn_next <= '0'; xmt_wrPtr_next <= xmt_wrPtr; byteSelect_next <= 1; -- 15 downto 8 hst_wrPtr_next <= 0; hst_wrEn_next <= '0'; if (trigger = '1') then nextState <= waiting; hst_rdPtr_next <= 0; readoutCount_next <= 0; else nextState <= done; hst_rdPtr_next <= hst_rdPtr; readoutCount_next <= readoutCount; end if; ------------------------------------------- when sd_opcode => sctdaq_header <= '1'; ll_src_rdy <= '1'; ll_sof <= '1'; header_data <= x"D001"; if (ll_dst_rdy_i <= '1') then nextState <= sd_seqnum; else nextState <= sd_opcode; end if; when sd_seqnum => ll_src_rdy <= '1'; sctdaq_header <= '1'; header_data <= seqnum; if (ll_dst_rdy_i <= '1') then nextState <= sd_size; else nextState <= sd_seqnum; end if; when sd_size => ll_src_rdy <= '1'; sctdaq_header <= '1'; header_data <= x"0110"; --2x128+16= x"0A10"; --2*1280+16=2576 if (ll_dst_rdy_i <= '1') then nextState <= sd_channel; else nextState <= sd_size; end if; when sd_channel => ll_src_rdy <= '1'; sctdaq_header <= '1'; header_data <= x"F100"; if (ll_dst_rdy_i <= '1') then nextState <= sd_readoutdata; else nextState <= sd_channel; end if; when sd_readoutdata => ll_src_rdy <= '1'; if (ll_dst_rdy_i <= '1') then readoutCount_next <= readoutCount + 1; hst_wrPtr_next <= hst_wrPtr + 1; hst_wrEn_next <= '1'; if (readoutCount < histogramLen) then hst_rdPtr_next <= hst_rdPtr_next + 1; nextState <= sd_readoutdata; else ll_eof <= '1'; nextState <= clearLastByte; hst_rdPtr_next <= 0; end if; else nextState <= sd_readoutdata; end if; when others => null; end case; end process; prc_sequence_number : process (clock) begin if rising_edge(clock) then if (reset = '1') then trigger <= '0'; trigger_q <= '0'; seqnum <= x"0000"; else trigger <= '0'; trigger_q <= trigger_i; if (trigger_q = '0') and (trigger_i = '1') then --rising trigger <= '1'; end if; if (trigger = '1') then seqnum <= seqnum + '1'; end if; end if; end if; end process; end Behavioral;