library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_ARITH.all; use IEEE.STD_LOGIC_UNSIGNED.all; library work; use work.tlmupack.all; entity rate_counter is generic ( gate_time : integer := 1; -- time to count in seconds fcnt : integer := 40000000); -- Frequency of cntclk 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 rate_counter; architecture behv of rate_counter is constant maxcount : positive := gate_time*fcnt-1; constant width : positive :=required_bits(maxcount) ; signal gat_cnt_reg : integer range 0 to maxcount; signal gat_exp : std_logic; signal evecnt : std_logic_vector(width-1 downto 0); signal evecnt_reg : std_logic_vector(width-1 downto 0); signal evecnt_cpu : std_logic_vector(width-1 downto 0); begin -- behv assert width < 31 report "gate_time or frequency too high" severity failure; -- gate counter process, gat_exp is one cycle high when counter reaches maxcount gate_p : process (cntclk, reset_n) begin -- process gate_p if reset_n = '0' then -- asynchronous reset (active low) gat_cnt_reg <= 0; gat_exp <= '0'; elsif cntclk'event and cntclk = '1' then -- rising clock edge if gat_cnt_reg = maxcount then gat_cnt_reg <= 0; gat_exp <= '1'; else gat_cnt_reg <= gat_cnt_reg + 1; gat_exp <= '0'; end if; end if; end process gate_p; -- event counter, counter is enabled by "T" input and resetted by gat_exp, -- last value is stored in evecnt_reg evecnt_p : process (cntclk, reset_n) begin -- process evecnt_p if reset_n = '0' then -- asynchronous reset (active low) evecnt <= (others => '0'); evecnt_reg <= (others => '0'); elsif cntclk'event and cntclk = '1' then -- rising clock edge if gat_exp = '1' then evecnt <= (others => '0'); evecnt_reg <= evecnt; elsif T = '1' then evecnt <= evecnt + 1; end if; end if; end process evecnt_p; -- sync to 120MHZ clock evecpu_p : process (cpuclk) begin -- process evecpu_p if cpuclk'event and cpuclk = '1' then -- rising clock edge evecnt_cpu <= evecnt_reg; end if; end process evecpu_p; ratecnt_OBI <= (31 downto width => '0') & evecnt_cpu; end behv;