-- 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 is port( clock : in std_logic; -- reset : in std_logic; -- trigger : 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' -- ); end readoutHist; architecture Behavioral of readoutHist 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); signal state : states := waiting; signal nextState : states := waiting; signal readoutCount : integer range 0 to 1023 := 0; signal readoutCount_next : integer range 0 to 1023 := 0; signal byteSelect : integer range 0 to 1 := 0; signal byteselect_next : integer range 0 to 1 := 0; signal ready : std_logic := '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', 1280 when others; ------------------------------------------------- ---------- 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; 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; 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 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'; if (xmt_ready = '1') then nextState <= byte1; xmt_wrEn_next <= '1'; else nextState <= waiting; xmt_wrEn_next <= '0'; 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; end case; end process; end Behavioral;