---------------------------------------------------------------------------------- -- Company: ETH Zurich, Institute for Particle Physics -- Engineer: Q. Weitzel, P. Vogler -- -- Create Date: 10:38:40 08/18/2010 -- Design Name: -- Module Name: FTU_rate_counter - Behavioral -- Project Name: -- Target Devices: -- Tool versions: -- Description: Entity to count trigger and sum patch rates of FTU board -- -- Dependencies: -- -- Revision: -- Revision 0.01 - File Created -- Revision 0.02 - counter range changed from 16 to 30 bit, 19.10.2010, Q. Weitzel -- Revision 0.03 - no local clock division anymore, 20.10.2010, Q. Weitzel -- Additional Comments: -- ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; library ftu_definitions; USE ftu_definitions.ftu_array_types.all; USE ftu_definitions.ftu_constants.all; ---- Uncomment the following library declaration if instantiating ---- any Xilinx primitives in this code. --library UNISIM; --use UNISIM.VComponents.all; entity FTU_rate_counter is port( clk : in std_logic; cntr_reset : in std_logic; trigger : in std_logic; prescaling : in std_logic_vector(7 downto 0); counts : out integer range 0 to 2**30 - 1 := 0; overflow : out std_logic := '0'; new_rate : out std_logic ); end FTU_rate_counter; architecture Behavioral of FTU_rate_counter is signal counting_period : integer range 0 to 128*COUNTER_FREQUENCY := 128*COUNTER_FREQUENCY; signal period_finished : std_logic := '0'; signal trigger_counts : integer range 0 to 2**30 - 1 := 0; signal overflow_sig : std_logic := '0'; signal new_rate_sig : std_logic := '0'; begin process(cntr_reset, clk) variable clk_cntr : integer range 0 to 128*COUNTER_FREQUENCY := 0; begin if cntr_reset = '1' then clk_cntr := 0; period_finished <= '1'; new_rate_sig <= '0'; counts <= 0; overflow <= '0'; elsif rising_edge(clk) then if (clk_cntr < counting_period - 1) then clk_cntr := clk_cntr + 1; period_finished <= '0'; new_rate_sig <= '0'; else clk_cntr := 0; period_finished <= '1'; new_rate_sig <= '1'; counts <= trigger_counts; overflow <= overflow_sig; end if; end if; end process; process(trigger, period_finished) begin if period_finished = '1' then trigger_counts <= 0; overflow_sig <= '0'; else if rising_edge(trigger) then if (trigger_counts < 2**30 - 1) then trigger_counts <= trigger_counts + 1; else trigger_counts <= 0; overflow_sig <= '1'; end if; end if; end if; end process; process(cntr_reset, prescaling) begin if rising_edge(cntr_reset) then --calculate counting period from prescaling value --default is 0.5s - 128s if CNTR_FREQ_DIVIDER = 1 --if (prescaling = "00000000") then --counting_period <= COUNTER_FREQUENCY / (2 * CNTR_FREQ_DIVIDER); --elsif (prescaling = "11111111") then --counting_period <= 128 * (COUNTER_FREQUENCY / CNTR_FREQ_DIVIDER); --else --counting_period <= ((conv_integer(unsigned(prescaling)) + 1) / 2) * (COUNTER_FREQUENCY / CNTR_FREQ_DIVIDER); --end if; if ((conv_integer(unsigned(prescaling))) mod 2 = 0) then counting_period <= ((((conv_integer(unsigned(prescaling)) / 2)) * (COUNTER_FREQUENCY / CNTR_FREQ_DIVIDER)) + (COUNTER_FREQUENCY / (2 * CNTR_FREQ_DIVIDER))); else counting_period <= (((conv_integer(unsigned(prescaling)) - 1) / 2) + 1) * (COUNTER_FREQUENCY / CNTR_FREQ_DIVIDER); end if; end if; end process; new_rate <= new_rate_sig; end Behavioral;