Belle II KLM Scint Firmware  1
KLMReadoutCtrl.vhd
1 library ieee;
2  use ieee.std_logic_1164.all;
3  use ieee.numeric_std.all;
4  use ieee.std_logic_unsigned.all;
5  use ieee.std_logic_misc.all;
6 library unisim;
7  use unisim.vcomponents.all;
8 library work;
9  use work.conc_intfc_pkg.all;
10  use work.klm_scint_pkg.all;
11  use work.klm_scrod_pkg.all;
12  use work.tdc_pkg.all;
13 
29 
30 
31 entity KLMReadoutCtrl is
32  generic (
33  T_DELAY_SELF_TRIG : integer := 4;
34  FORCE_TRIG_BUF_DEPTH_g : integer := 5;
35  FORCE_TRIG_WIDTH_g: integer := 8;
36  POST_MUX_TRIG_BIT_BUFF_DEPTH_g : integer := 3
37  );
38  port (
39  clk : in std_logic := '0';
40  rst : in std_logic := '0';
41 
43  trg : in std_logic := '0';
44  trgtag : in std_logic_vector(31 downto 0) := (others=>'0');
45  ctime : in std_logic_vector(26 downto 0) := (others=>'0');
46 
47 
49  vectrgbits : in tb_vec_type := (others => (others => '0')); -- array of trigger bits from TargetX
50 
52  qt_fifo_rd_en : in std_logic := '0';
53  qt_fifo_dout : out std_logic_vector (17 downto 0) := (others=>'0');
54  qt_fifo_empty : out std_logic := '1';
55  qt_fifo_evt_rdy : out std_logic := '0';
56 
57  ScrodConfig : in KlmScrodConfigType := KlmScrodConfigZero;
58  force_trig : in std_logic;
59  sps_reset : in std_logic;
60 
62  scalers_reset : in std_logic := '0';
63 
65  scalers_busy : out std_logic;
66  scalers_ch_arr : out slv32(9 downto 0) := (others => (others => '0')); -- one scaler per ASIC for given channel number
68  qt_fifo_err_cnt : out std_logic_vector(15 downto 0); -- counter for daq data fifo overflows
69  tbfifo_err_cnt : out slv16(9 downto 0); -- counter for trigger bits fifo overflows
70  trg_cnt : out std_logic_vector(15 downto 0) := (others => '0'); -- number of triggers received
71  full_proc_cnt : out std_logic_vector(15 downto 0) := (others => '0'); -- number of triggers processed
72  simp_proc_cnt : out std_logic_vector(15 downto 0) := (others => '0'); -- number of triggers processed
73  null_proc_cnt : out std_logic_vector(15 downto 0) := (others => '0'); -- number of triggers processed
74  -- occ_err_cnt : out std_logic_vector(15 downto 0) := (others => '0'); -- number of hits overflow counter
75  -- status registers
76  wave_stat : out waveform_stat_t;
77  debug_wave_we : out std_logic_vector(1 downto 0) := (others => '0');
78  debug_wave_din : out slv12(1 downto 0) := (others => (others => '0'));
79  SPS_hist_rd_data : out slv16(1 downto 0) := (others => (others => '0'));
80 
82  -- ctime_max : out std_logic_vector(26 downto 0) := (others => '1'); -- where ctime acually wraps around
83 
85  RAM_IO : inout std_logic_vector(7 downto 0) := (others => '0');
86  RAM_WEb : out std_logic := '1';
87  RAM_OEb : out std_logic := '1';
88  RAM_ADDR : out std_logic_vector(21 downto 0) := (others => '1');
89 
91  BUSA_WR_ADDRCLR : out std_logic;
92  BUSA_DO : in std_logic_vector(14 downto 0) := (others => '0');
93  BUSA_RAMP : out std_logic := '0';
94  BUSA_CLR : out std_logic := '0';
95  BUSA_RD_COLSEL : out std_logic_vector(5 downto 0) := (others => '0');
96  BUSA_RD_ENA : out std_logic := '0';
97  BUSA_RD_ROWSEL : out std_logic_vector(2 downto 0) := (others => '0');
98  BUSA_SAMPLESEL : out std_logic_vector(4 downto 0) := (others => '0');
99  BUSA_SR_CLEAR : out std_logic := '0';
100  BUSA_SR_SEL : out std_logic := '0';
101 
102 
104  BUSB_WR_ADDRCLR : out std_logic;
105  BUSB_DO : in std_logic_vector(14 downto 0) := (others => '0');
106  BUSB_RAMP : out std_logic := '0';
107  BUSB_CLR : out std_logic := '0';
108  BUSB_RD_COLSEL : out std_logic_vector(5 downto 0) := (others => '0');
109  BUSB_RD_ENA : out std_logic := '0';
110  BUSB_RD_ROWSEL : out std_logic_vector(2 downto 0) := (others => '0');
111  BUSB_SAMPLESEL : out std_logic_vector(4 downto 0) := (others => '0');
112  BUSB_SR_CLEAR : out std_logic := '0';
113  BUSB_SR_SEL : out std_logic := '0';
114 
115 
117  WR1_ENA : out std_logic_vector(9 downto 0);
118  WR2_ENA : out std_logic_vector(9 downto 0);
119  SSTIN_N : out std_logic_vector(9 downto 0);
120  SSTIN_P : out std_logic_vector(9 downto 0);
121  -- TDC_DONE : in std_logic_vector(9 downto 0) := (others => '0');
122  SAMPLESEL_ANY : out std_logic_vector(9 downto 0) := (others => '0');
123  SR_CLOCK : out std_logic_vector(9 downto 0) := (others => '0');
124 
125  busy : out std_logic := '0'
126  );
127 end KLMReadoutCtrl;
128 
129 
130 
131 
132 architecture behavioral of KLMReadoutCtrl is
133 
134 -- SYNCHRONOUS SIGNALS BY PROCESS WHICH DRIVES THEM
136  signal i_trg : std_logic := '0';
137  signal i_trgtag : std_logic_vector(4 downto 0) := (others => '0');
138  signal i_ctime : std_logic_vector(26 downto 0) := (others => '0');
139  signal i_ScrodConfig : KlmScrodConfigType := KlmScrodConfigZero;
140  signal i_scalers_reset : std_logic := '0';
141 
143  signal i_ctime_max : std_logic_vector(26 downto 0) := (others => '1');
144  constant ctime_zero : std_logic_vector(26 downto 0) := (others => '0');
145 
147  signal wave_proc_rst : std_logic := '0';
148  signal sampling_lgc_rst : std_logic := '0';
149  signal tb_proc_rst : std_logic := '0';
150  signal ro_trg_rst : std_logic := '0';
151 
153  type arr_tb_vec_type is array (natural range <>) of tb_vec_type;
154  signal i_vectrgbits : arr_tb_vec_type(POST_MUX_TRIG_BIT_BUFF_DEPTH_g - 1 downto 0) := (others=>(others => (others => '0')));
155  signal force_trig_sr : std_logic_vector(FORCE_TRIG_BUF_DEPTH_g + FORCE_TRIG_WIDTH_g - 1 downto 0) := (others=>'0');
156  signal use_force_trig_sr : std_logic_vector(FORCE_TRIG_BUF_DEPTH_g - 1 downto 0) := (others=>'0');
157 
159  type SELF_TRIG_STATE_t is (IDLE, TRIGGERING);
160  signal self_trig_state : SELF_TRIG_STATE_t := IDLE;
161  signal self_trig : std_logic := '0';
162 
164  signal ii_trg : std_logic := '0';
165  signal ii_trgtag : std_logic_vector(4 downto 0) := (others => '0');
166  signal ii_ctime : std_logic_vector(26 downto 0) := (others => '0');
167 
168 
169 
170 -- SIGNALS DRIVEN BY INSTANTIATED ENTITIES
171  -- TrigBitsProc_10x_i :
172  signal trig : trig_info_type_0 := null_trig_info_t0;
173  signal self_trig_asic : std_logic_vector(9 downto 0) := (others => '0');
174  signal i_sca_busy : std_logic_vector(9 downto 0) := (others => '0');
175 
176 
177  -- WaveformReadout_i :
178  signal ro_busy_full : std_logic := '0';
179  signal i_trg_proc_full_cnt : std_logic_vector (15 downto 0) := (others => '0');
180  signal i_evt_rdy_full : std_logic := '0';
181  signal ana_wr_ena_mask : TARGETX_analong_wr_ena_mask_t := null_TX_ana_wr_ena_mask;
182 
183 
184  -- ReadoutTrg_i :
185  signal localtrg : std_logic := '0';
186  signal ctime_trg : std_logic_vector(26 downto 0) := (others => '0');
187 
188  -- TargetX_SamplingLgc_i :
189  signal cur_win : std_logic_vector(8 downto 0) := (others => '0');
190 
191 
192 -- ASYNCHRONOUSLY DRIVEN SIGNALS
193 
194 
195 begin
196 
197 
198 
199 
200 --------------------- ASYNCHRONOUS LOGIC ---------------------------------------------
201  scalers_busy <= or_reduce(i_sca_busy);
202  busy <= ro_busy_full;
203  trig.ctime <= ctime_trg(15 downto 0);
204 
205 
206 
207 
208 --------------------- SYNCHRONOUS LOGIC ---------------------------------------------
209  latch_input_data: process(clk, trg, trgtag, ctime, ScrodConfig, scalers_reset)
210  begin
211  if rising_edge(clk) then
212  i_trg <= trg;
213  i_trgtag <= trgtag(4 downto 0);
214  i_ctime <= ctime;
215  i_ScrodConfig <= ScrodConfig;
216  i_scalers_reset <= scalers_reset;
217  end if;
218  end process;
219 
220 
221 
222  determine_where_ctime_wraps_around: process(clk, rst, ctime, i_ctime, i_ctime_max)
223  begin
224  if rising_edge(clk) then
225  if rst = '1' then
226  i_ctime_max <= (others => '1');
227  else
228  if ctime = ctime_zero and i_ctime > ctime_zero then
229  i_ctime_max <= i_ctime;
230  end if;
231  -- ctime_max <= i_ctime_max;
232  end if;
233  end if;
234  end process;
235 
236 
237 
238  buffer_the_reset_signal: process(clk, rst)
239  begin
240  if rising_edge(clk) then
241  wave_proc_rst <= rst;
242  sampling_lgc_rst <= rst;
243  tb_proc_rst <= rst;
244  ro_trg_rst <= rst;
245  end if;
246  end process;
247 
248 
249  TB_mode_mux: process(clk, vectrgbits, force_trig,
250  i_ScrodConfig.wave_config.use_force_trig,
251  i_ScrodConfig.wave_config.force_trig_bits,
252  i_ScrodConfig.wave_config.force_trig_asic,
253  force_trig_sr, use_force_trig_sr)
254  begin
255  if rising_edge(clk) then
256  if force_trig = '1' then
257  force_trig_sr(force_trig_sr'left downto FORCE_TRIG_WIDTH_g) <= (others=>'0');
258  force_trig_sr(FORCE_TRIG_WIDTH_g - 1 downto 0) <= (others=>'1');
259  else
260  force_trig_sr <= force_trig_sr(force_trig_sr'left - 1 downto 0) & '0';
261  end if;
262  use_force_trig_sr <= use_force_trig_sr(use_force_trig_sr'left - 1 downto 0) & i_ScrodConfig.wave_config.use_force_trig;
263  i_vectrgbits(i_vectrgbits'left downto 1) <= i_vectrgbits(i_vectrgbits'left - 1 downto 0);
264  if use_force_trig_sr(use_force_trig_sr'left) = '1' then
265  if force_trig_sr(force_trig_sr'left) = '1' then
266  i_vectrgbits(0)(i_ScrodConfig.wave_config.force_trig_asic(0) + 1) <= i_ScrodConfig.wave_config.force_trig_bits;
267  i_vectrgbits(0)(i_ScrodConfig.wave_config.force_trig_asic(1) + 6) <= i_ScrodConfig.wave_config.force_trig_bits;
268  else
269  i_vectrgbits(0) <= (others=>(others=>'0'));
270  end if;
271  else
272  i_vectrgbits(0) <= vectrgbits;
273  end if;
274  end if;
275  end process;
276 
277 
278 
279  self_trig_fsm: process(clk, self_trig_asic)
280  variable count : integer range 0 to T_DELAY_SELF_TRIG := 0;
281  begin
282  if rising_edge(clk) then
283  case self_trig_state is
284  when IDLE =>
285  self_trig <= '0';
286  count := 0;
287  if or_reduce(self_trig_asic) = '1' then
288  self_trig_state <= TRIGGERING;
289  end if;
290 
291  when TRIGGERING =>
292  if count = T_DELAY_SELF_TRIG then
293  self_trig <= not i_ScrodConfig.wave_config.use_ftsw_trig;
294  self_trig_state <= IDLE;
295  else
296  count := count + 1;
297  self_trig_state <= TRIGGERING;
298  end if;
299 
300  end case;
301  end if;
302  end process;
303 
304 
305 
306  KLMReadoutTrg_trig_mode_multiplexer: process(clk, i_ScrodConfig.wave_config.use_ftsw_trig,
307  i_trg, i_ctime, i_trgtag, self_trig)
308  begin
309  if rising_edge(clk) then
310 
311  ii_ctime <= i_ctime;
312  ii_trgtag <= i_trgtag;
313  if i_ScrodConfig.wave_config.use_ftsw_trig = '1' then
314  ii_trg <= i_trg;
315  else
316  ii_trg <= self_trig;
317  end if;
318  end if;
319  end process;
320 
321 
322 
323 
324  --------------------- MODULE INSTANTIATIONS ---------------------------------------------
325 
326  TrigBitsProc_10x_i: for iAsic in 1 to 10 generate
327  KLMTrigBitsProc_i : entity work.KLMTrigBitsProc
328  port map(
329  clk => clk,
330  rst => tb_proc_rst,
331 
332  -- inputs
333  tb => i_vectrgbits(i_vectrgbits'left)(iAsic),
334 
335  ctime => i_ctime,
336  cur_win => cur_win,
337  -- ro_busy => ro_busy_full,
338 
339  localtrg => localtrg,
340  ctime_trg => ctime_trg,
341 
342  -- hit_ren => i_hit_ren(iAsic-1), -- hit read enable
343  sca_rst => i_scalers_reset,
344  sca_cnt_max => i_ScrodConfig.TBScalersPeriod,
345 
346  -- configuration
347  asic_on => i_ScrodConfig.TxProcMask(iAsic-1),
348  lookback => i_ScrodConfig.TBLookBack,
349  lookback_width => i_ScrodConfig.TBLookBackWidth,
350  ctime_max => i_ctime_max,
351 
352  -- outputs
353  hit_bits => trig.bits(iAsic-1),
354  hit_win => trig.wr_time(iAsic-1),
355  is_hit => trig.mask(iAsic-1),
356  -- tbfifo_drdy => tbfifo_drdy(iAsic-1),
357  self_trig => self_trig_asic(iAsic-1),
358 
359  -- status
360  sca_busy => i_sca_busy(iAsic-1),
361  -- fifo_cnt => i_tbfifo_cnt(iAsic-1),
362  scalers_cnt => scalers_ch_arr(iAsic-1),
363  fifo_full_cnt => tbfifo_err_cnt(iAsic-1)
364  );
365  end generate;
366 
367 
368  WaveformReadout_i : entity work.WaveformReadout
369  port map (
370  clk => clk,
371  busy => ro_busy_full,
372  b2tt_runreset => wave_proc_rst,
373  trig => trig,
374  ana_wr_ena_mask => ana_wr_ena_mask,
375  localtrg => localtrg,
376  force_trig => force_trig,
377  sps_reset => sps_reset,
378  cur_win => cur_win,
380  qt_fifo_dout => qt_fifo_dout,
381  qt_fifo_empty => qt_fifo_empty,
382  qt_fifo_err_cnt => qt_fifo_err_cnt,
383  qt_fifo_evt_rdy => qt_fifo_evt_rdy,
384  full_proc_cnt => full_proc_cnt,
385  simp_proc_cnt => simp_proc_cnt,
386  null_proc_cnt => null_proc_cnt,
387  RAM_IO => RAM_IO,
388  RAM_WEb => RAM_WEb,
389  RAM_OEb => RAM_OEb,
390  RAM_ADDR => RAM_ADDR,
391  BUSA_DO => BUSA_DO,
392  BUSA_RAMP => BUSA_RAMP,
393  BUSA_CLR => BUSA_CLR,
394  BUSA_RD_COLSEL => BUSA_RD_COLSEL,
395  BUSA_RD_ENA => BUSA_RD_ENA,
396  BUSA_RD_ROWSEL => BUSA_RD_ROWSEL,
397  BUSA_SAMPLESEL => BUSA_SAMPLESEL,
398  BUSA_SR_CLEAR => BUSA_SR_CLEAR,
399  BUSA_SR_SEL => BUSA_SR_SEL,
400  BUSB_DO => BUSB_DO,
401  BUSB_RAMP => BUSB_RAMP,
402  BUSB_CLR => BUSB_CLR,
403  BUSB_RD_COLSEL => BUSB_RD_COLSEL,
404  BUSB_RD_ENA => BUSB_RD_ENA,
405  BUSB_RD_ROWSEL => BUSB_RD_ROWSEL,
406  BUSB_SAMPLESEL => BUSB_SAMPLESEL,
407  BUSB_SR_CLEAR => BUSB_SR_CLEAR,
408  BUSB_SR_SEL => BUSB_SR_SEL,
409  SAMPLESEL_ANY => SAMPLESEL_ANY,
410  SR_CLOCK => SR_CLOCK,
411  wave_config => i_ScrodConfig.wave_config,
412  wave_stat => wave_stat,
413  debug_wave_we => debug_wave_we,
414  debug_wave_din => debug_wave_din,
415  SPS_hist_rd_data => SPS_hist_rd_data
416  );
417 
418 
419  ReadoutTrg_i : entity work.KLMReadoutTrg
420  port map(
421  clk => clk,
422  rst => ro_trg_rst,
423 
424  trg => ii_trg,
425  ctime => ii_ctime,
426  trgtag => ii_trgtag,
427  readout_busy => ro_busy_full,
428 
429  localtrg => localtrg,
430  ctime_trg => ctime_trg,
431  -- trgtag_trg => trgtag_trg,
432 
433  trg_cnt => trg_cnt
434  );
435 
436 
437 
438  TargetX_SamplingLgc_i : entity work.SamplingLgc
439  port map (
440  clk => clk,
441  reset => sampling_lgc_rst,
442  ana_wr_ena_mask => ana_wr_ena_mask,
443  cur_win => cur_win,
444  BUSA_WR_ADDRCLR => BUSA_WR_ADDRCLR,
445  BUSB_WR_ADDRCLR => BUSB_WR_ADDRCLR,
446  WR1_ENA => WR1_ENA,
447  WR2_ENA => WR2_ENA,
448  SSTIN_N => SSTIN_N,
449  SSTIN_P => SSTIN_P
450  );
451 
452 
453 
454 
455 end behavioral;
out BUSB_WR_ADDRCLRstd_logic
BusB signals.
std_logic := '0' ii_trg
KLMReadoutTrg_trig_mode_multiplexer:
out qt_fifo_err_cntstd_logic_vector( 15 downto 0)
tbfifo_cnt : out slv16(9 downto 0) := (others => (others => &#39;0&#39;)); – debug
in qt_fifo_rd_enstd_logic := '0'
daq data ports
array(natural range <> ) of tb_vec_type arr_tb_vec_type
TB_mode_mux:
out BUSA_WR_ADDRCLRstd_logic
BusA signals.
in trgstd_logic := '0'
b2tt signals
in vectrgbitstb_vec_type :=( others =>( others => '0'))
trigger bits from all asics
out scalers_busystd_logic
status ports TODO : pack it into a record e.g. ReadoutStatus
(IDLE,TRIGGERING) SELF_TRIG_STATE_t
self_trig_fsm:
std_logic_vector( 26 downto 0) :=( others => '1') i_ctime_max
determine_where_ctime_wraps_around:
in scalers_resetstd_logic := '0'
reset scalers for trigger bits
std_logic := '0' i_trg
latch_input_data:
std_logic := '0' wave_proc_rst
buffer_the_reset_signal:
in qt_fifo_rd_enstd_logic := '0'
daq data ports
inout RAM_IOstd_logic_vector( 7 downto 0) :=( others => '0')
debug FIXME : remove pedestal RAM access
out WR1_ENAstd_logic_vector( 9 downto 0)
TargetX DC signals.