-------------------------------------------------------------------------------- -- -- PROJECT: D0 Run IIb Trigger L1 Calorimeter upgrade -- -- MODULE: -- -- ELEMENT: gen_ctrl -- -- DESCRIPTION: Sequencer for tester -- -- The state machine can have the following state: -- . RESET: waiting for configuration -- . ARMED: trigger armed -- . RUNNING: capturing data -- . STOPPED: data captured -- -- Typical transitions are: -- -- -- AUTHOR: D. Calvet calvet@hep.saclay.cea.fr -- -- DATE AND HISTORY: -- June 2003: created -- -- September 2004: added 13 clock ticks pipeline delay on ERR_DETECTED. -- When the tester is configured to stop recording data when a bit error -- is found, it can be difficult to diagnose the problem if data recording -- is stopped as soon as the error is encountered. By delaying the ERR_DETECTED -- signal we allow 16 frames to be recorded (including the one in error) so that -- it is easier to see where the transmission went wrong after de-serialization -- in 8-bit words. -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; --use work.utility_pkg.all; -------------------------------------------------------------------------------- -- -- General Control State Machine -- entity gen_ctrl is port ( RESET : in std_logic; -- Reset MODE : in std_logic; -- Mode of Tester STOP_CTRL : in std_logic; -- Control mode for stop CLK : in std_logic; -- Clock CAPTURE_COUNT : in std_logic_vector(11 downto 0); -- Number of words to capture after trigger ARM_TRIGGER : in std_logic; -- Pulse to arm trigger TRIGGER : in std_logic; -- Pulse to trigger ABORT_RUN : in std_logic; -- Pulse to abort run ERR_DETECTED : in std_logic; -- Receive Bit Error detected RAM_ADDR : out std_logic_vector(10 downto 0); -- RAM address STATE_RESET : out std_logic; -- Internal state STATE_ARMED : out std_logic; -- Internal state STATE_RUNNING : out std_logic; -- Internal state STATE_STOPPED : out std_logic -- Internal state ); end gen_ctrl; architecture behavior of gen_ctrl is -- -- State of state machine -- signal q_RE: std_logic; signal q_AR: std_logic; signal q_RU: std_logic; signal q_ST: std_logic; -- -- Next state of state machine -- signal qn_RE: std_logic; signal qn_AR: std_logic; signal qn_RU: std_logic; signal qn_ST: std_logic; signal cnt_word_cap : std_logic_vector(11 downto 0); signal cnt_word_cap_reached : std_logic; signal ram_wr_addr : std_logic_vector(10 downto 0); signal ram_wr_addr_we : std_logic; signal abort : std_logic; -- detect when to abort signal err_detect_delay : std_logic_vector(12 downto 0); begin -- -- Abort logic -- abort <= ABORT_RUN -- Forced Abort by User or ( (not MODE) and cnt_word_cap_reached) -- Desired number of words received in data capture mode or ( MODE and STOP_CTRL and err_detect_delay(12) ); -- Error detected in error count mode with stop on bit error enabled -- -- Pipeline delay for ERR_DETECTED -- Delay_Err : process(RESET, CLK) begin if RESET = '1' then err_detect_delay <= (others => '0') ; elsif (CLK'event and CLK = '1') then err_detect_delay <= err_detect_delay(11 downto 0) & ERR_DETECTED; end if; end process; -- -- The counter for the number of words to record after trigger -- This counter is preset to CAPTURE_COUNT when state is ARMED -- It is decremeted on every tick when state is RUNNING -- Cnt_captured : process(RESET, q_AR, CAPTURE_COUNT, CLK) begin if (q_AR = '1' or RESET = '1') then cnt_word_cap <= CAPTURE_COUNT ; elsif (CLK'event and CLK = '1') then if q_RU = '1' then cnt_word_cap <= cnt_word_cap - "000000000001"; end if; end if; end process; -- -- Logic to determine when the number of words to capture has been reached -- With the current logic it is when 2 is reached cnt_word_cap_reached <= (not cnt_word_cap(11)) and (not cnt_word_cap(10)) and (not cnt_word_cap(9)) and (not cnt_word_cap(8)) and (not cnt_word_cap(7)) and (not cnt_word_cap(6)) and (not cnt_word_cap(5)) and (not cnt_word_cap(4)) and (not cnt_word_cap(3)) and (not cnt_word_cap(2)) and ( cnt_word_cap(1)) and (not cnt_word_cap(0)); -- -- The RAM address counter -- RAM_Addr_Cnt : process(RESET, CLK) begin if RESET = '1' then ram_wr_addr <= "00000000000"; elsif CLK'event and CLK = '1' then if ram_wr_addr_we = '1' then ram_wr_addr <= ram_wr_addr + 1; end if; end if; end process; RAM_ADDR <= ram_wr_addr; ram_wr_addr_we <= q_AR or q_RU; -- -- A State Machine - Sequential part -- Sequencer: process(RESET, CLK) begin if (RESET = '1') then q_RE <= '1'; q_AR <= '0'; q_RU <= '0'; q_ST <= '0'; elsif (CLK'event and CLK = '1') then q_RE <= qn_RE; q_AR <= qn_AR; q_RU <= qn_RU; q_ST <= qn_ST; end if; end process; -- -- Combinatorial part of the state machine -- qn_RE <= (q_RE or RESET) and (not ARM_TRIGGER); qn_AR <= (q_AR and (not TRIGGER) and (not abort)) or (q_RE and ARM_TRIGGER); qn_RU <= (q_RU and (not abort)) or (q_AR and TRIGGER); qn_ST <= (q_AR and abort) or (q_RU and abort) or (q_ST and (not RESET)); -- -- Combinatorial outputs -- STATE_RESET <= q_RE; STATE_ARMED <= q_AR; STATE_RUNNING <= q_RU; STATE_STOPPED <= q_ST; end behavior;