------------------------------------------------------------------------------- -- Coincidence Counter -- address 00: control (0: stop, 1:run, 2:clr, 4 enable by soreor, 8: start gated count) -- 01: read value bits 31 .. 0 -- 10 read value bits 47 .. 32 -- 11: 32 Bit gate value ------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_ARITH.all; use IEEE.STD_LOGIC_UNSIGNED.all; entity coinc_counter is generic ( use_asy : boolean := true); port ( cntclk : in std_logic; cpuclk : in std_logic; reset_n : in std_logic; we : in std_logic; soreor : in std_logic; address : in std_logic_vector(2 downto 0); ccnt_IBO : in std_logic_vector(31 downto 0); ccnt_OBI : out std_logic_vector(31 downto 0); T : in std_logic ); end coinc_counter; architecture behv of coinc_counter is component rate_counter generic ( gate_time : integer; fcnt : integer); port ( cntclk : in std_logic; cpuclk : in std_logic; reset_n : in std_logic; address : in std_logic_vector(1 downto 0); ratecnt_OBI : out std_logic_vector(31 downto 0); T : in std_logic); end component; component asyncin generic ( oreg : boolean); port ( clk40 : in std_logic; clk120 : in std_logic; reset_n : in std_logic; ain : in std_logic; s40out : out std_logic); end component; signal counter : std_logic_vector(47 downto 0); signal cnt_en, cnt_clr : std_logic; signal Tsync : std_logic; signal gatecount_regcpu : std_logic_vector(31 downto 0); -- scsn written value signal gatecount_cnt : std_logic_vector(31 downto 0); -- counter signal gate_start_comb : std_logic; signal gate_start_cpuclk : std_logic; signal gate_start : std_logic; signal gate_en : std_logic; signal soreor_en : std_logic; signal en : std_logic; signal ratecnt_OBI : std_logic_vector(31 downto 0); -- ratecnt_OBI begin -- behv cntctrl_p : process (cpuclk, reset_n) begin -- process cntctrl_p if reset_n = '0' then -- asynchronous reset (active low) cnt_en <= '0'; cnt_clr <= '0'; soreor_en <= '0'; elsif cpuclk'event and cpuclk = '1' then -- rising clock edge if address = "00" and we = '1' then cnt_en <= ccnt_IBO(0); cnt_clr <= ccnt_IBO(1); soreor_en <= ccnt_IBO(2); end if; end if; end process cntctrl_p; -- if use_asy set, instantiate the asynchronous event syncer asyncin_gen : if use_asy generate asyncin_1 : asyncin generic map ( oreg => true) port map ( clk40 => cntclk, clk120 => cpuclk, reset_n => reset_n, ain => T, s40out => Tsync); end generate asyncin_gen; -- if use_asy not set, sync directrly to 40MHz clock syncin_gen : if not use_asy generate tsyncp : process (cntclk) begin -- process tsyncp if cntclk'event and cntclk = '1' then -- rising clock edge Tsync <= T; end if; end process tsyncp; end generate syncin_gen; en <= cnt_en or gate_en or (soreor_en and soreor); counter_p : process (cntclk, reset_n) begin -- process counter_p if reset_n = '0' then -- asynchronous reset (active low) counter <= (others => '0'); elsif cntclk'event and cntclk = '1' then -- rising clock edge if cnt_clr = '1' then counter <= (others => '0'); elsif en = '1' then if Tsync = '1' then counter <= counter + 1; end if; end if; end if; end process counter_p; -- ******************************************************************* -- Address 11: Gated count -- register holding gate timer value in 25ns steps gatecount_regcpu_p : process (cpuclk, reset_n) begin -- process gatecount_regcpu_p if reset_n = '0' then -- asynchronous reset (active low) gatecount_regcpu <= (others => '0'); elsif cpuclk'event and cpuclk = '1' then -- rising clock edge if address = "11" and we = '1' then gatecount_regcpu <= ccnt_IBO; end if; end if; end process gatecount_regcpu_p; -- bit 3 of "00" is gate start gate_start_comb <= '1' when address = "00" and we = '1' and ccnt_IBO(3) = '1' else '0'; gs_cpuclk_p : process (cpuclk, reset_n) begin -- process gs_cpuclk_p if reset_n = '0' then -- asynchronous reset (active low) gate_start_cpuclk <= '0'; elsif cpuclk'event and cpuclk = '1' then -- rising clock edge gate_start_cpuclk <= (gate_start_cpuclk or gate_start_comb) and not gate_start; end if; end process gs_cpuclk_p; -- sync to 40 MHz clock and generate feed abck for process above gs_p : process (cntclk, reset_n) begin -- process gs_p if reset_n = '0' then -- asynchronous reset (active low) gate_start <= '0'; elsif cntclk'event and cntclk = '1' then -- rising clock edge gate_start <= gate_start_cpuclk; end if; end process gs_p; -- *** Counter sync to 40 MHz clk gatecounter_p : process (cntclk, reset_n) begin -- process gatecounter_p if reset_n = '0' then -- asynchronous reset (active low) gatecount_cnt <= (others => '0'); gate_en <= '0'; elsif cntclk'event and cntclk = '1' then -- rising clock edge if gate_start = '1' then gate_en <= '1'; elsif gatecount_cnt = gatecount_regcpu then gate_en <= '0'; end if; if gate_en = '1' then gatecount_cnt <= gatecount_cnt + 1; else gatecount_cnt <= (others => '0'); end if; end if; end process gatecounter_p; -- rate counter rate_counter_1 : rate_counter generic map ( gate_time => 1, fcnt => 40000000) port map ( cntclk => cntclk, cpuclk => cpuclk, reset_n => reset_n, address => "00", ratecnt_OBI => ratecnt_OBI, T => T); -- addressdemux with address select ccnt_OBI <= ((31 downto 2 => '0') & cnt_clr & cnt_en) when "000", counter(31 downto 0) when "001", ((31 downto 16 => '0') & counter(47 downto 32)) when "010", gatecount_regcpu when "011", ratecnt_OBI when "100", (31 downto 0 => '0') when others; end behv;