-- SG-StrobeDelay.vhd -- ABCD-3T Threshold Scan Generator (light) -- August 2009 -- Ana Ovcharova -- Lawrence Berkeley National Laboratory library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity ThresholdScanGenerator is Port ( clk : in std_logic; reset : in std_logic; dg_wrEn : in std_logic; hro_ready : in std_logic; hro_trigger : out std_logic; com0 : out std_logic; IssueComFlag : out std_logic; FSMstate : out std_logic_vector(3 downto 0) ); end ThresholdScanGenerator; architecture Behavioral of ThresholdScanGenerator is --******************************************************* -- Adjust to modify the scan constant CalAmplitudeInt : integer := 24; constant ModPosition : integer := 1; constant TotalNumberL1Triggers : integer := 1000; constant ScanParInitVal : integer := 20; constant ScanParFinVal : integer := 80; constant ScanParStep : integer := 1; --******************************************************* -- constants constant SlowCommand : std_logic_vector(6 downto 0):="1010111"; constant AllChips : std_logic_vector(5 downto 0):="111111"; constant SoftReset: std_logic_vector (6 downto 0):="1010100"; constant L1Delay : integer := 126; constant StrobeDelayReg : std_logic_vector(15 downto 0) := x"0010"; constant BiasDACReg : std_logic_vector(15 downto 0) :="0001100100011000"; --Parameters signal Threshold, CalAmplitude : std_logic_vector(7 downto 0); signal ConfigReg : std_logic_vector(15 downto 0); signal MaskReg : std_logic_vector(127 downto 0); signal RegAddress : std_logic_vector(5 downto 0); signal RegLength : std_logic_vector(7 downto 0); signal ActiveModules : std_logic_vector(4 downto 0); signal IsEndMaster : std_logic_vector(1 downto 0); -- signal ShaperCurrent, BiasCurrent : std_logic_vector(4 downto 0); --Counters signal Count155, Count155_next : std_logic_vector(8 downto 0); signal ScanPar, ScanPar_next : integer; signal L1TriggerCounter, L1TriggerCounter_next : std_logic_vector(15 downto 0); signal CalMode, CalMode_next : std_logic_vector(1 downto 0); signal ChipAddress, ChipAddress_next, MinChipAddress, MaxChipAddress : integer range 0 to 30; signal ChannelAddress, ChannelAddress_next : integer range 0 to 127; --Miscellaneous signal IssueComFlagint : std_logic; signal com0int : std_logic; signal InitializeConfig : std_logic; signal CommandOut : std_logic_vector(154 downto 0); -- FSM states type state_type is ( st_Reset, st_LoadConfigRegs, st_LoadMaskRegs, st_LoadThreshRegs, st_LoadBiasDACs, st_LoadStrobeDelay, st_LoadTrimDACs, st_EnDTM, st_IssueCalPulse, st_SendL1Trigger, st_hroTrigger, st_Done, st_Wait, st_IssueCommand, st_waitForReadout0, st_waitForReadout1 ); signal state, next_state, potential_state : state_type; signal hro_ready_reg : std_logic := '0'; signal hro_ready_reg_next : std_logic := '0'; signal hro_trigger_next : std_logic := '0'; begin com0<= com0int; IssueComFlag <= IssueComFlagint; hro_ready_reg_next <= hro_ready; with potential_state select RegAddress <= "000000" when st_LoadConfigRegs, "001000" when st_LoadMaskRegs, "010000" when st_LoadStrobeDelay, "011000" when st_LoadThreshRegs, "101000" when st_EnDTM, "110000" when st_IssueCalPulse, "111000" when st_LoadBiasDACs, "000100" when st_LoadTrimDACs, "000000" when others; --purposefully set to the same as config reg in order to cause detectable result if out of range RegLength <= "00011100" when potential_state=st_LoadConfigRegs or potential_state=st_LoadStrobeDelay or potential_state=st_LoadThreshRegs or potential_state=st_LoadBiasDACs or potential_state=st_LoadTrimDACs else "10001100" when potential_state=st_LoadMaskRegs else "00001100" when potential_state=st_EnDTM or potential_state=st_IssueCalPulse else "00000000"; with ModPosition select MinChipAddress <= 0 when 0, 6 when 1, 12 when 2, 19 when 3, 25 when 4, 0 when others; MaxChipAddress<= MinChipAddress+6 when ModPosition=2 else MinChipAddress+5; Threshold <= conv_std_logic_vector(ScanPar,8); CalAmplitude <= conv_std_logic_vector(CalAmplitudeInt,8); MaskReg <= (others=>'1'); IsEndMaster <= "00" when (ChipAddress=0 or ChipAddress=6 or ChipAddress=12 or ChipAddress=19 or ChipAddress=25) else "11" when (ChipAddress=5 or ChipAddress=11 or ChipAddress=18 or ChipAddress=24 or ChipAddress=30) else "01"; ConfigReg(15 downto 0)<= "001" & IsEndMaster & "0000001" & CalMode (0) & CalMode(1) & "01"; SYNC_PROC: process (clk,reset) begin if (reset = '1') then state <= st_Reset; com0int<='0'; InitializeConfig<='1'; -- once 1st EnDTM is sent goes low else if rising_edge(clk) then hro_ready_reg <= hro_ready_reg_next; hro_trigger <= hro_trigger_next; state <= next_state; --issue commands if Count155_next>0 then com0int <= CommandOut(155 - conv_integer(Count155_next)); IssueComFlagint<='1'; else com0int <='0'; IssueComFlagint<='0'; end if; --synchronize counters L1TriggerCounter<=L1TriggerCounter_next; Count155<=Count155_next; CalMode<=CalMode_next; ScanPar<=ScanPar_next; ChipAddress<=ChipAddress_next; ChannelAddress<=ChannelAddress_next; if next_state=st_EnDTM then InitializeConfig<='0'; else InitializeConfig <= InitializeConfig; end if; end if; end if; end process; process(state,CalMode,L1TriggerCounter, ScanPar, Count155) begin if falling_edge(clk) then --synchronize counters L1TriggerCounter_next<=L1TriggerCounter; Count155_next<=Count155; CalMode_next<=CalMode; ScanPar_next<=ScanPar; if (state = st_Reset) then ScanPar_next <= ScanParInitVal; --reinitialize all counters and miscellaneous signals CommandOut <= (others => '0'); CalMode_next <= "00"; L1TriggerCounter_next <= (others => '0'); Count155_next<=(others => '0'); ChipAddress_next<= MinChipAddress; ChannelAddress_next<= 0; potential_state<=st_LoadConfigRegs; next_state<=st_LoadConfigRegs; elsif (state = st_LoadConfigRegs) then CommandOut(154 downto 112)<= SlowCommand & RegLength & '1' & conv_std_logic_vector(ChipAddress,5) & RegAddress & ConfigReg; CommandOut(111 downto 0) <= (others=>'0'); if ChipAddress'0'); potential_state<=st_LoadTrimDACs; next_state<=st_IssueCommand; elsif (state=st_LoadTrimDACs) then CommandOut(154 downto 112) <= SlowCommand & RegLength & '1' & conv_std_logic_vector(ChipAddress,5) & RegAddress & "00000" & conv_std_logic_vector(ChannelAddress,7) & "0000"; CommandOut(111 downto 0) <= (others=>'0'); if ChannelAddress<127 then ChannelAddress_next<=ChannelAddress+1; potential_state<=st_LoadTrimDACs; else ChannelAddress_next<=0; if ChipAddress'0'); potential_state<=st_LoadStrobeDelay; next_state<=st_IssueCommand; elsif (state=st_LoadStrobeDelay) then CommandOut(154 downto 112) <= SlowCommand & RegLength & AllChips & RegAddress & StrobeDelayReg; -- bits 15:6 unsused CommandOut(111 downto 0) <= (others=>'0'); potential_state<=st_EnDTM; next_state<=st_IssueCommand; elsif (state=st_EnDTM) then CommandOut(154 downto 148) <= SoftReset; CommandOut(147 downto 121) <= SlowCommand & RegLength & AllChips & RegAddress; CommandOut(120 downto 0) <= (others=>'0'); potential_state<=st_IssueCalPulse; next_state<=st_IssueCommand; elsif (state = st_IssueCalPulse) then CommandOut(154 downto 27) <=(others=>'0'); CommandOut(26 downto 0) <=SlowCommand & RegLength & AllChips & RegAddress; potential_state<=st_SendL1Trigger; next_state<=st_IssueCommand; elsif (state = st_SendL1Trigger) then CommandOut(154 downto 154-L1Delay) <= (others=>'0'); CommandOut(154-(L1Delay+1) downto 154-(L1Delay+3)) <= "110"; --L1Trigger CommandOut(154-(L1Delay+4) downto 0)<= (others=>'0'); if (L1TriggerCounter = TotalNumberL1Triggers -1) then L1TriggerCounter_next<=(others=>'0'); -- potential_state<=st_Done; if (CalMode = 3) then CalMode_next<="00"; potential_state <= st_hroTrigger; else CalMode_next <= CalMode+1; potential_state <=st_LoadConfigRegs; end if; else L1TriggerCounter_next <= L1TriggerCounter + 1; potential_state<=st_IssueCalPulse; end if; next_state <= st_IssueCommand; elsif (state = st_hroTrigger) then hro_trigger_next <= '1'; next_state <= st_waitForReadout1; if (ScanPar >= ScanParFinVal) then potential_state <= st_Done; ScanPar_next <= ScanPar; else potential_state <= st_loadConfigRegs; ScanPar_next <= ScanPar+ScanParStep; end if; elsif (state=st_IssueCommand) then if (Count155=155) then Count155_next<=(others=>'0'); next_state <= st_Wait; else Count155_next<=Count155+1; next_state <= st_IssueCommand; end if; potential_state<=potential_state; elsif (state=st_Wait) then if (dg_wrEn ='0') then next_state <= potential_state; else next_state <= st_Wait; end if; potential_state<=potential_state; elsif (state = st_waitForReadout1) then hro_trigger_next <= '0'; if ( hro_ready = '1' AND hro_ready_reg = '0' ) then -- rising edge on hro_ready next_state <= potential_state; else next_state <= st_waitForReadout1; end if; potential_state <= potential_state; end if; end if; end process; FSMstate <="0000" when potential_state = st_Done else "0001" when potential_state = st_LoadConfigRegs else "0010" when potential_state = st_LoadMaskRegs else "0011" when potential_state = st_LoadBiasDACs else "0100" when potential_state = st_LoadTrimDACs else "0101" when potential_state = st_EnDTM else "0110" when potential_state = st_SendL1Trigger or potential_state = st_IssueCalPulse else "0111" when potential_state = st_Wait else "1000" when potential_state = st_IssueCommand else "1111"; end Behavioral;