LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; USE IEEE.STD_LOGIC_ARITH.all; USE IEEE.STD_LOGIC_UNSIGNED.all; -- Offset -- reading -- 0 Pretrigger counters 0 -- 1 Pretrigger counters 1 -- 2 Pretrigger counters 2 -- 3 Pretrigger counters 3 -- Bits 31..28 27..24 23..20 19..16 15..12 11..8 7..4 3..0 -- func7 func6 func5 func4 func3 func2 func1 unknown -- 4 4 clock counters x 8 bits. The internal counter (running with the internal clock) -- starts after reading, then resets and enables the 4 counters for 200 internal clocks. -- Bits 31..24 23..16 15..8 7..0 -- counter 3 2 1 0 -- 5 dut_pre (7..4) -- 5 dut_clk (3..0) -- writing -- 0..3 reset all pretrigger counters -- 6 reset NI (not used yet) -- 8 pretrigger encoder -- The pretrigger functions are -- 0 nothing -- 1 pretrigger -- 2 clear -- 3 reserved -- 4 go to low power mode -- 5 go to acquisition mode -- 6 go to test mode -- 7 start test pulse in PASA entity top_pre is port ( clk : in std_logic; reset_n : in std_logic; ce : in std_logic; -- SCSN bus_addr : in std_logic_vector( 7 downto 0); bus_we : in std_logic; -- write enable bus_din : in std_logic_vector(31 downto 0); bus_dout : out std_logic_vector(31 downto 0); -- user IO PRE_SCSN : in std_logic; DUT_CLK : in std_logic_vector(3 downto 0); DUT_PRE : in std_logic_vector(3 downto 0); AD_SYNC_OUT : out std_logic; AD_SYNC_IN : in std_logic; ctrl_ni : out std_logic; NI_PRE : out std_logic ); end top_pre; architecture a of top_pre is COMPONENT pre_dec IS PORT( CLK : IN STD_LOGIC; -- fast clock 120MHz RSTn : IN STD_LOGIC; -- global reset (active low) PRETRIGG : IN STD_LOGIC; -- pre-trigger input -- decoded outputs PTRGG : OUT STD_LOGIC; -- pre-trigger detected CLEAR : OUT STD_LOGIC; -- clear detected RESRV : OUT STD_LOGIC; -- reserve function FUNC : OUT STD_LOGIC_VECTOR(3 downto 0); -- global functions 0..3 UNKNOWN : OUT STD_LOGIC -- reserve function ); END COMPONENT; COMPONENT pre_enc IS PORT( CLK : IN STD_LOGIC; -- fast clock 120MHz RSTn : IN STD_LOGIC; -- global reset (active low) WR : IN STD_LOGIC; -- write clock WE : IN STD_LOGIC; FUNC : IN STD_LOGIC_VECTOR(2 downto 0); -- PRE : OUT STD_LOGIC -- pre-trigger input ); END COMPONENT; COMPONENT pre_dir IS PORT( CLK : IN STD_LOGIC; -- fast clock 120MHz RSTn : IN STD_LOGIC; -- global reset (active low) start : IN STD_LOGIC; PRE : OUT STD_LOGIC -- pre-trigger input ); END COMPONENT; signal PRE_ad : std_logic; signal PRE_io : std_logic; signal WE_pre : std_logic; signal WE_sm : std_logic; signal sreset_pcnt : std_logic; signal ce_ccnt : std_logic; signal NI_PRE_i : std_logic; signal p_sm : std_logic; signal p_sm1 : std_logic; signal p_sm2 : std_logic; signal PTRGG : std_logic; signal L0time : std_logic_vector(13 downto 0); signal L1time : std_logic_vector(13 downto 0); signal L2time : std_logic_vector(13 downto 0); signal c_time : std_logic_vector(13 downto 0); signal ptimer : std_logic_vector(13 downto 0); signal ptimer_full : std_logic_vector(13 downto 0) := (others => '1'); signal func_dec : std_logic_vector( 3 downto 0); begin WE_sm <= bus_we and ce when bus_addr(3 downto 2)="11" else '0'; -- address 12-15 WE_pre <= bus_we and ce when bus_addr(3 downto 2)="10" else '0'; -- address 8-11 sreset_pcnt <= bus_we and ce when bus_addr(3 downto 2)="00" else '0'; -- addresses 0..3 ce_ccnt <= ce when bus_addr(3 downto 0)="0100" else '0'; -- address 4 pdir: pre_dir PORT map( CLK => CLK, RSTn => reset_n, start => AD_SYNC_IN, PRE => PRE_ad ); pend: pre_enc PORT map( CLK => CLK, RSTn => reset_n, WR => CLK, WE => WE_pre, FUNC => bus_din(2 downto 0), PRE => PRE_io ); NI_PRE_i <= PRE_io or PRE_SCSN; -- or PRE_ad; NI_PRE <= NI_PRE_i or p_sm; AD_SYNC_OUT <= PRE_io or PRE_SCSN; -- but not from the SM pdec: pre_dec PORT map( CLK => CLK, RSTn => reset_n, PRETRIGG => NI_PRE_i, -- decoded outputs PTRGG => PTRGG, CLEAR => open, RESRV => open, FUNC => func_dec, UNKNOWN => open ); pcnt0: pre_counter port map( clk => clk, reset_n => reset_n, sreset => sreset_pcnt, dout => dout0pcnt, pre_in => DUT_PRE(0) ); pcnt1: pre_counter port map( clk => clk, reset_n => reset_n, sreset => sreset_pcnt, dout => dout1pcnt, pre_in => DUT_PRE(1) ); pcnt2: pre_counter port map( clk => clk, reset_n => reset_n, sreset => sreset_pcnt, dout => dout2pcnt, pre_in => DUT_PRE(2) ); pcnt3: pre_counter port map( clk => clk, reset_n => reset_n, sreset => sreset_pcnt, dout => dout3pcnt, pre_in => DUT_PRE(3) ); process(clk, reset_n) begin if reset_n = '0' then L0time <= (others => '0'); L1time <= (others => '0'); L2time <= (others => '0'); c_time <= (others => '0'); elsif clk'event and clk= '1' then if WE_sm='1' then case bus_addr(1 downto 0) is when "00" => L0time <= bus_din(L0time'range); when "01" => L1time <= bus_din(L1time'range); when "10" => L2time <= bus_din(L2time'range); when "11" => c_time <= bus_din(c_time'range); when others => NULL; end case; end if; end if; end process; process(clk, reset_n) begin if reset_n = '0' then ptimer <= (2 => '1', others => '0'); p_sm <= '0'; p_sm1 <= '0'; p_sm2 <= '0'; ctrl_ni <= '1'; elsif clk'event and clk= '1' then if PTRGG='1' or func_dec(3) ='1' then ptimer <= (2 downto 0 => '1', others => '0'); ctrl_ni <= '1'; elsif ptimer /= ptimer_full then ptimer <= ptimer + 1; else ctrl_ni <= '1'; end if; if ptimer = L0time then p_sm <= '1'; end if; if ptimer = L1time then p_sm <= '1'; end if; if ptimer = L2time then p_sm <= '1'; end if; if ptimer = c_time then ctrl_ni <= '0'; end if; p_sm1 <= p_sm; p_sm2 <= p_sm1; if p_sm2='1' then p_sm <= '0'; end if; -- clear the pretrigger end if; end process; process(bus_addr, dout0pcnt, dout1pcnt, dout2pcnt, dout3pcnt, dout_ccnt, dut_clk, dut_pre, L0time, L1time, L2time, c_time) begin bus_dout <= (others => '0'); case bus_addr(3 downto 0) is when "0000" => bus_dout <= dout0pcnt; when "0001" => bus_dout <= dout1pcnt; when "0010" => bus_dout <= dout2pcnt; when "0011" => bus_dout <= dout3pcnt; when "0100" => bus_dout <= dout_ccnt; when "0101" => bus_dout(7 downto 0) <= dut_pre & dut_clk; when "1100" => bus_dout(L0time'range) <= L0time; when "1101" => bus_dout(L1time'range) <= L1time; when "1110" => bus_dout(L2time'range) <= L2time; when "1111" => bus_dout(c_time'range) <= c_time; when others => bus_dout <= (others => '-'); end case; end process; end;