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/div/abort_controller.vhd,v $
00015 --* $Revision: 1.6.2.3 $ *
00016 --* $Name: dev $ *
00017 --* $Author: mniegl $ *
00018 --* $Date: 2008/11/03 17:57:45 $ *
00019
00020
00021 --* *
00022 --**************************************************************
00023
00024
00025 library ieee;
00026
00027 use ieee.std_logic_1164.all;
00028
00029 use ieee.std_logic_arith.all;
00030
00031 use ieee.std_logic_unsigned.all;
00032
00033
00034
00035 entity abort_controller is
00036 port (
00037 CLK : in ;
00038 RES : in ;
00039 WR_EN : in ;
00040 BCID : in (11 downto 0);
00041 HIGH_GAIN : in (3 downto 0);
00042 LOW_GAIN : in (3 downto 0);
00043 CHECK_EN : in ;
00044 BCID_R : in (11 downto 0);
00045 HIGH_GAIN_R : in (3 downto 0);
00046 LOW_GAIN_R : in (3 downto 0);
00047 ABORT : out
00048 );
00049 end abort_controller;
00050
00051
00052
00053 architecture abort_controller_arc of abort_controller is
00054
00055 signal fire_abort : := '0';
00056 signal we : := '0';
00057 signal compare1 : := '0';
00058 signal compare2 : := '0';
00059 signal compare : := '0';
00060 signal abort_middle : := '0';
00061 signal abort_above : := '0';
00062 signal abort_below : := '0';
00063 signal rdvld : := '0';
00064 signal rden : := '0';
00065 signal bcid_i : (11 downto 0) := (others => '0');
00066 signal cnt_a : (11 downto 0) := (others => '0');
00067 signal cnt_b : (11 downto 0) := (others => '0');
00068 signal rdbid : (11 downto 0) := (others => '0');
00069 signal data_i : (5 downto 0) := (others => '0');
00070 signal data_out_i : (5 downto 0) := (others => '0');
00071 signal low_hits : (2 downto 0) := (others => '0');
00072 signal high_hits : (2 downto 0) := (others => '0');
00073 signal rlow_hits : (2 downto 0) := (others => '0');
00074 signal rhigh_hits : (2 downto 0) := (others => '0');
00075 signal rlow_hits2 : (2 downto 0) := (others => '0');
00076 signal rhigh_hits2 : (2 downto 0) := (others => '0');
00077 signal rlow_hits3 : (2 downto 0) := (others => '0');
00078 signal rhigh_hits3 : (2 downto 0) := (others => '0');
00079 signal read_low_hits : (2 downto 0) := (others => '0');
00080 signal read_high_hits : (2 downto 0) := (others => '0');
00081 signal read_low_hits2 : (2 downto 0) := (others => '0');
00082 signal read_high_hits2 : (2 downto 0) := (others => '0');
00083 signal read_low_hits3 : (2 downto 0) := (others => '0');
00084 signal read_high_hits3 : (2 downto 0) := (others => '0');
00085 signal mid_high_cnt : (4 downto 0) := (others => '0');
00086 signal mid_low_cnt : (4 downto 0) := (others => '0');
00087 signal blw_high_cnt : (4 downto 0) := (others => '0');
00088 signal blw_low_cnt : (4 downto 0) := (others => '0');
00089 signal abv_high_cnt : (4 downto 0) := (others => '0');
00090 signal abv_low_cnt : (4 downto 0) := (others => '0');
00091
00092 alias RESET is RES;
00093
00094
00095 component abort_buffer
00096 port (
00097 addra : in (11 downto 0);
00098 addrb : in (11 downto 0);
00099 clka : in ;
00100 clkb : in ;
00101 dina : in (5 downto 0);
00102 doutb : out (5 downto 0);
00103 ena : in ;
00104 enb : in ;
00105 wea : in );
00106 end component;
00107
00108 begin -- abort_controller_arc
00109
00110 ABORT <= fire_abort or abort_middle; -- or abort_above or abort_below;
00111
00112
00113 fire : process (CLK, RES)
00114 variable lowcnt : (2 downto 0) := "000";
00115 begin -- process fire
00116 if RES = '1' then -- asynchronous reset (active high)
00117 fire_abort <= '0';
00118 lowcnt := "000";
00119 elsif CLK'event and CLK = '1' then -- rising clock edge
00120 fire_abort <= '0';
00121 lowcnt := "000";
00122 if (HIGH_GAIN(0) and HIGH_GAIN(1) and HIGH_GAIN(2) and HIGH_GAIN(3)) = '1' then
00123 lowcnt := conv_std_logic_vector(conv_integer(LOW_GAIN(0)) + conv_integer(LOW_GAIN(1)) + conv_integer(LOW_GAIN(2)) + conv_integer(LOW_GAIN(3)), 3);
00124 if lowcnt >= 3 then
00125 fire_abort <= '1';
00126 else
00127 lowcnt := "000";
00128 fire_abort <= '0';
00129 end if;
00130 else
00131 lowcnt := "000";
00132 fire_abort <= '0';
00133 end if;
00134 end if;
00135 end process fire;
00136
00137 we <= not RES and WR_EN;
00138
00139
00140 buf_i : abort_buffer
00141 port map
00142 (
00143 addra => cnt_a,
00144 addrb => cnt_b,
00145 clka => CLK ,
00146 clkb => CLK ,
00147 dina => data_i,
00148 doutb => data_out_i,
00149 ena => '1' ,
00150 enb => rden,
00151 wea => we
00152 );
00153
00154
00155 addr_gen_a : process(CLK)
00156 begin
00157 if CLK'event and CLK = '1' then
00158 if RES = '1' then
00159 cnt_a <= (others => '0');
00160 data_i <= (others => '0');
00161 bcid_i <= (others => '0');
00162 else
00163 if WR_EN = '1' then
00164 bcid_i <= BCID;
00165 cnt_a <= bcid_i;
00166 data_i <= high_hits & low_hits;
00167 end if;
00168 end if;
00169 end if;
00170 end process addr_gen_a;
00171
00172
00173 low_cnt : process (CLK, RESET)
00174 begin -- process low_cnt
00175 if RESET = '1' then -- asynchronous reset (active high)
00176 low_hits <= "000";
00177 elsif CLK'event and CLK = '1' then -- rising clock edge
00178 if WR_EN = '1' then
00179 low_hits <= conv_std_logic_vector(conv_integer(LOW_GAIN(0)) + conv_integer(LOW_GAIN(1)) + conv_integer(LOW_GAIN(2)) + conv_integer(LOW_GAIN(3)), 3);
00180 end if;
00181 end if;
00182 end process low_cnt;
00183
00184
00185 high_cnt : process (CLK, RESET)
00186 begin -- process high_cnt
00187 if RESET = '1' then -- asynchronous reset (active high)
00188 high_hits <= "000";
00189 elsif CLK'event and CLK = '1' then -- rising clock edge
00190 if WR_EN = '1' then
00191 high_hits <= conv_std_logic_vector(conv_integer(HIGH_GAIN(0)) + conv_integer(HIGH_GAIN(1)) + conv_integer(HIGH_GAIN(2)) + conv_integer(HIGH_GAIN(3)), 3);
00192 end if;
00193 end if;
00194 end process high_cnt;
00195
00196
00197 rlow_cnt : process (CLK, RESET)
00198 begin -- process rlow_cnt
00199 if RESET = '1' then -- asynchronous reset (active high)
00200 rlow_hits <= (others => '0');
00201 elsif CLK'event and CLK = '1' then -- rising clock edge
00202 if CHECK_EN = '1' then
00203 rlow_hits <= conv_std_logic_vector(conv_integer(LOW_GAIN_R(0)) + conv_integer(LOW_GAIN_R(1)) + conv_integer(LOW_GAIN_R(2)) + conv_integer(LOW_GAIN_R(3)), 3);
00204 end if;
00205 end if;
00206 end process rlow_cnt;
00207
00208
00209 rhigh_cnt : process (CLK, RESET)
00210 begin -- process rhigh_cnt
00211 if RESET = '1' then -- asynchronous reset (active high)
00212 rhigh_hits <= (others => '0');
00213 elsif CLK'event and CLK = '1' then -- rising clock edge
00214 if CHECK_EN = '1' then
00215 rhigh_hits <= conv_std_logic_vector(conv_integer(HIGH_GAIN_R(0)) + conv_integer(HIGH_GAIN_R(1)) + conv_integer(HIGH_GAIN_R(2)) + conv_integer(HIGH_GAIN_R(3)), 3);
00216 end if;
00217 end if;
00218 end process rhigh_cnt;
00219
00220 rlow_hits2 <= rlow_hits when rising_edge(CLK); -- below
00221 rlow_hits3 <= rlow_hits2 when rising_edge(CLK); -- above
00222 rhigh_hits2 <= rhigh_hits when rising_edge(CLK); -- below
00223 rhigh_hits3 <= rhigh_hits2 when rising_edge(CLK); -- above
00224 compare1 <= CHECK_EN when rising_edge(CLK); -- enable middle
00225 compare2 <= compare1 when rising_edge(CLK); -- enable below
00226 compare <= compare2 when rising_edge(CLK); -- enable above
00227 read_high_hits2 <= read_high_hits when rising_edge(CLK); -- below
00228 read_low_hits2 <= read_low_hits when rising_edge(CLK); -- below
00229 read_high_hits3 <= read_high_hits2 when rising_edge(CLK); -- above
00230 read_low_hits3 <= read_low_hits2 when rising_edge(CLK); -- above
00231 read_high_hits <= data_out_i(5 downto 3) when rdvld = '1' else "000"; -- middle
00232 read_low_hits <= data_out_i(2 downto 0) when rdvld = '1' else "000"; -- middle
00233
00234 rden <= not RES and (CHECK_EN or compare1 or compare2);
00235 rdvld <= rden when rising_edge(CLK);
00236 rdbid <= BCID_R when CHECK_EN = '1' else
00237 BCID_R-1 when compare1 = '1' else
00238 BCID_R+1 when compare2 = '1' else
00239 (others => '0');
00240 cnt_b <= rdbid when RES = '0' else (others => '0');
00241
00242
00243 comp_mid : process (CLK, RESET)
00244 begin -- process comp_mid
00245 if RESET = '1' then -- asynchronous reset (active high)
00246 abort_middle <= '0';
00247 mid_high_cnt <= (others => '0');
00248 mid_low_cnt <= (others => '0');
00249 elsif CLK'event and CLK = '1' then -- rising clock edge
00250 abort_middle <= '0';
00251 if compare1 = '1' then
00252 mid_high_cnt <= conv_std_logic_vector(conv_integer(rhigh_hits) + conv_integer(read_high_hits), 5);
00253 mid_low_cnt <= conv_std_logic_vector(conv_integer(rlow_hits) + conv_integer(read_low_hits), 5);
00254 else
00255 mid_high_cnt <= (others => '0');
00256 mid_low_cnt <= (others => '0');
00257 end if;
00258 if mid_low_cnt >= 3 and mid_high_cnt >= 4 then
00259 abort_middle <= '1';
00260 else
00261 abort_middle <= '0';
00262 end if;
00263 end if;
00264 end process comp_mid;
00265
00266
00267 comp_blw : process (CLK, RESET)
00268 begin -- process comp_blw
00269 if RESET = '1' then -- asynchronous reset (active high)
00270 abort_below <= '0';
00271 elsif CLK'event and CLK = '1' then -- rising clock edge
00272 if compare2 = '1' then
00273 blw_high_cnt <= conv_std_logic_vector(conv_integer(rhigh_hits2) + conv_integer(read_high_hits2), 5);
00274 blw_low_cnt <= conv_std_logic_vector(conv_integer(rlow_hits2) + conv_integer(read_low_hits2), 5);
00275 else
00276 blw_high_cnt <= (others => '0');
00277 blw_low_cnt <= (others => '0');
00278 end if;
00279 if blw_low_cnt >= 3 and blw_high_cnt >= 4 then
00280 abort_below <= '1';
00281 else
00282 abort_below <= '0';
00283 end if;
00284 end if;
00285 end process comp_blw;
00286
00287
00288 comp_abv : process (CLK, RESET)
00289 begin -- process comp_abv
00290 if RESET = '1' then -- asynchronous reset (active high)
00291 abort_above <= '0';
00292 elsif CLK'event and CLK = '1' then -- rising clock edge
00293 if compare = '1' then
00294 abv_high_cnt <= conv_std_logic_vector(conv_integer(rhigh_hits3) + conv_integer(read_high_hits3), 5);
00295 abv_low_cnt <= conv_std_logic_vector(conv_integer(rlow_hits3) + conv_integer(read_low_hits3), 5);
00296 else
00297 abv_high_cnt <= (others => '0');
00298 abv_low_cnt <= (others => '0');
00299 end if;
00300 if abv_low_cnt >= 3 and abv_high_cnt >= 4 then
00301 abort_above <= '1';
00302 else
00303 abort_above <= '0';
00304 end if;
00305 end if;
00306 end process comp_abv;
00307
00308 end abort_controller_arc;