00001 --**************************************************************
00002 --* *
00003 --* The source code for the ATLAS BCM "AAA" FPGA is made *
00004 --* available via the GNU General Public License (GPL) *
00005 --* unless otherwise stated below. *
00006 --* *
00007 --* In case of problems/questions/bug reports etc. please *
00008 --* contact michael.niegl@cern.ch *
00009 --* *
00010 --**************************************************************
00011
00012 --**************************************************************
00013 --* *
00014 --* $Source: /local/reps/bcmfpga/bcm_aaa/bcm_aaa/coin/statistics.vhd,v $
00015 --* $Revision: 1.2.2.3 $ *
00016 --* $Name: dev $ *
00017 --* $Author: mniegl $ *
00018 --* $Date: 2008/11/03 17:57:43 $ *
00019
00020
00021 --* *
00022 --**************************************************************
00023
00024 library ieee;
00025
00026 use ieee.std_logic_1164.all;
00027
00028 use ieee.numeric_std.all;
00029
00030
00031
00032
00033
00034 entity statistics is
00035
00036 generic (
00037 SERIES_LENGTH : := 4096);
00038
00039 port (
00040 CLK : in ;
00041 RES : in ;
00042 VAL : in (15 downto 0);
00043 MNM : out (15 downto 0);
00044 MAX : out (15 downto 0);
00045 AVG : out (15 downto 0)
00046 );
00047
00048 end statistics;
00049
00050
00051
00052
00053
00054 architecture statistics_arc of statistics is
00055
00056
00057 component division
00058 generic (
00059 DIVISOR : );
00060 port (
00061 CLK : in ;
00062 RES : in ;
00063 A : in (15 downto 0);
00064 C : out (15 downto 0));
00065 end component;
00066
00067
00068 function safe_div (
00069 A : )
00070 return is
00071 variable Ai : ;
00072 variable ret : := 2;
00073 begin -- safe_div
00074 Ai := A;
00075 while 0 < 1 loop
00076 if Ai < 2 then
00077 ret := 2;
00078 exit;
00079 else
00080 if Ai mod 2 /= 0 then
00081 Ai := Ai - 1;
00082 else
00083 ret := Ai;
00084 exit;
00085 end if;
00086 end if;
00087 end loop;
00088 return ret;
00089 end safe_div;
00090
00091
00092 constant c_len : := safe_div(SERIES_LENGTH);
00093
00094 signal ser_end : := '0';
00095 signal res_int : := '0';
00096 signal minimum_reg : (15 downto 0) := (others => '0');
00097 signal maximum_reg : (15 downto 0) := (others => '0');
00098 signal average_reg : (15 downto 0) := (others => '0');
00099 signal accu_reg : (15 downto 0) := (others => '0');
00100 signal avg_in : (15 downto 0) := (others => '0');
00101 signal avg_out : (15 downto 0) := (others => '0');
00102
00103 begin -- statistics_arc
00104
00105 res_int <= RES or ser_end;
00106
00107
00108 series_cnt : process (CLK)
00109 variable cnt : := 0;
00110 begin -- process series_cnt
00111 if CLK'event and CLK = '1' then -- rising clock edge
00112 if RES = '1' then
00113 cnt := 0;
00114 ser_end <= '0';
00115 else
00116 ser_end <= '0';
00117 cnt := cnt + 1;
00118 if cnt = c_len then
00119 ser_end <= '1';
00120 cnt := 0;
00121 end if;
00122 end if;
00123 end if;
00124 end process series_cnt;
00125
00126
00127 minimum_cal : process (CLK)
00128 begin -- process minimum
00129 if CLK'event and CLK = '1' then -- rising clock edge
00130 if res_int = '1' then
00131 minimum_reg <= (VAL);
00132 elsif (VAL) <= minimum_reg then
00133 minimum_reg <= (VAL);
00134 else
00135 minimum_reg <= minimum_reg;
00136 end if;
00137 end if;
00138 end process minimum_cal;
00139
00140 MNM <= (minimum_reg);
00141
00142
00143 maximum_cal : process (CLK)
00144 begin -- process minimum
00145 if CLK'event and CLK = '1' then -- rising clock edge
00146 if res_int = '1' then
00147 maximum_reg <= (VAL);
00148 elsif (VAL) > maximum_reg then
00149 maximum_reg <= (VAL);
00150 else
00151 maximum_reg <= maximum_reg;
00152 end if;
00153 end if;
00154 end process maximum_cal;
00155
00156 MAX <= (maximum_reg);
00157
00158 avg_acc : process (CLK)
00159 begin -- process avg_acc
00160 if CLK'event and CLK = '1' then -- rising clock edge
00161 if res_int = '1' then
00162 accu_reg <= (others => '0');
00163 if ser_end = '1' then
00164 average_reg <= accu_reg + (VAL);
00165 else
00166 average_reg <= (others => '0');
00167 end if;
00168 else
00169 accu_reg <= accu_reg + (VAL);
00170 end if;
00171 end if;
00172 end process avg_acc;
00173
00174 avg_in <= average_reg;
00175
00176
00177 average_cal : division
00178 generic map (
00179 DIVISOR => c_len)
00180 port map (
00181 CLK => CLK ,
00182 RES => RES ,
00183 A => avg_in ,
00184 C => avg_out
00185 );
00186
00187 AVG <= (avg_out);
00188
00189 end statistics_arc;