Belle II KLM Scint Firmware
1
KLMHitBuilder.vhd
1
----------------------------------------------------------------------------------
2
-- The module to build hits in the "simple" mode.
3
-- Simple mode is a mode when only trigger bits from TargerX are processed without feature extraction.
4
--
5
--
6
-- * DAQ data format:
7
-- * ------------------------------------------------------
8
-- * word1 : | type(2:0) | lane(4:0) | axis(0) | chnl(6:0) |
9
-- * word2 : | ctime(15 : 0) |
10
-- * word3 : | TRGBITS(4:0) | TDC(10:0) |
11
-- * word4 : | TBD(3:0) | chg(11:0) |
12
-- * ------------------------------------------------------
13
--
14
-- In the simple mode chg = 0, TDC = ctime(10:0)
15
----------------------------------------------------------------------------------
16
17
library
ieee
;
18
use
ieee.std_logic_1164.
all
;
19
use
ieee.numeric_std.
all
;
20
use
ieee.std_logic_unsigned.
all
;
21
library
unisim
;
22
use
unisim.vcomponents.
all
;
23
library
work
;
24
use
work.
conc_intfc_pkg
.
all
;
25
use
work.
klm_scint_pkg
.
all
;
26
use
work.
klm_scrod_pkg
.
all
;
27
use
work.tdc_pkg.
all
;
28
29
30
entity
KlmHitBuilderSimple
is
31
port
(
32
clk
:
in
std_logic
;
33
rst
:
in
std_logic
;
34
35
enable :
in
std_logic
; -- enable
to
switch between different readout modes (dummy, simple, full)
36
37
hit_num_max
:
in
std_logic_vector
(
15
downto
0
)
;
-- maximum number of hits to be processed
38
39
trgbit_hit_arr
:
in
slv41
(
9
downto
0
)
;
-- timestamped hit data from KLMTrigBitsProc
40
hits_valid
:
in
std_logic_vector
(
9
downto
0
)
;
-- corresponding ASIC has valid hits
41
tbfifo_drdy
:
in
std_logic_vector
(
9
downto
0
)
;
-- data is ready on the tb processing side
42
43
localtrg :
in
std_logic
; -- trigger
after
trigger buffering
44
ctime_trg
:
in
std_logic_vector
(
15
downto
0
)
;
-- trigger timestamp
45
46
ser_busy
:
in
std_logic
;
-- serialization is in progress
47
nxt
:
in
std_logic
;
-- input from serializer which say that it's ready to accept next hit
48
49
ser_run
:
out
std_logic
;
-- start serialization
50
51
hit_read
:
out
std_logic_vector
(
9
downto
0
)
;
-- read enable to KLMTrigBitProc
52
53
-- hit data out
54
HitData
:
out
KlmScrodHitDataType
;
-- hit data in DAQ data format
55
56
occ_err_cnt
:
out
std_logic_vector
(
15
downto
0
)
;
-- number of hits overflow counter
57
58
59
evt_rdy
:
out
std_logic
;
-- event is ready to be sent to the DAQ
60
trg_proc_cnt
:
out
std_logic_vector
(
15
downto
0
)
;
61
62
busy
:
out
std_logic
-- event is being processed
63
)
;
64
end
KlmHitBuilderSimple
;
65
66
architecture
behavioral
of
KlmHitBuilderSimple
is
67
68
type
ro_states
is
69
(
70
IDLE
,
WAIT_VALID
,
PREPARE
,
SEND_HITS
,
NEXT_HIT
,
WAIT_SENT
,
STOP
71
)
;
72
signal
ro_state
:
ro_states
:=
idle
;
73
74
type
modes_t
is
75
(
76
DUMMY
,
DAQ_OR_TEST
,
NONE
77
)
;
78
79
80
signal
hit_num
:
natural
;
81
82
signal
run
:
std_logic
;
83
84
--number of asic being analyzed
85
signal
i_asic
:
integer
range
0
to
9
:=
0
;
86
signal
i_asic_next
:
integer
range
0
to
9
:=
0
;
87
88
-- all asics are processed
89
-- signal i_asic_finished : std_logic;
90
91
-- maximum number of hits in the event
92
signal
i_hit_num_max
:
std_logic_vector
(
15
downto
0
)
:=
(
others
=
>
'
0
'
)
;
93
signal
hit_num_max_dummy
:
std_logic_vector
(
15
downto
0
)
:=
(
others
=
>
'
0
'
)
;
94
95
signal
i_hit_ren
:
std_logic_vector
(
9
downto
0
)
:=
(
others
=
>
'
0
'
)
;
96
97
signal
axis
:
std_logic
;
98
signal
chn
:
integer
;
99
-- signal chn_r : integer;
100
signal
asic_chn
:
integer
;
101
102
-- hit data words
103
signal
null_hit_daq
:
std_logic
:=
'
0
'
;
104
signal
last_hit_daq
:
std_logic
:=
'
0
'
;
105
signal
word1_daq
:
std_logic_vector
(
15
downto
0
)
;
106
signal
word2_daq
:
std_logic_vector
(
15
downto
0
)
;
107
signal
word3_daq
:
std_logic_vector
(
15
downto
0
)
;
108
signal
word4_daq
:
std_logic_vector
(
15
downto
0
)
;
109
110
signal
i_trg_proc_cnt
:
std_logic_vector
(
15
downto
0
)
:=
(
others
=
>
'
0
'
)
;
111
112
signal
i_occ_err_cnt
:
std_logic_vector
(
15
downto
0
)
:=
(
others
=
>
'
0
'
)
;
113
signal
i_ro_mode
:
std_logic_vector
(
3
downto
0
)
:=
(
others
=
>
'
0
'
)
;
114
115
begin
116
117
process
(clk)
118
begin
119
if
rising_edge
(
clk
)
then
120
i_hit_num_max
<=
hit_num_max
;
121
end
if
;
122
end
process
;
123
124
------------------------------------------------
125
-- determine asic number to process next
126
------------------------------------------------
127
process
(clk)
128
begin
129
if
rising_edge
(
clk
)
then
130
i_asic_next_loop
:
for
i
in
0
to
9
loop
131
if
i
/=
i_asic
and
hits_valid
(
i
)
=
'
1
'
then
132
i_asic_next
<=
i
;
133
exit
i_asic_next_loop
;
134
end
if
;
135
end
loop
;
136
-- if i_asic < 9 and hits_valid(i_asic + 1) = '1' then
137
-- i_asic_finished <= '0';
138
-- i_asic_next <= i_asic + 1;
139
-- elsif i_asic < 8 and hits_valid(i_asic+2) = '1' then
140
-- i_asic_finished <= '0';
141
-- i_asic_next <= i_asic + 2;
142
-- elsif i_asic < 7 and hits_valid(i_asic+3) = '1' then
143
-- i_asic_finished <= '0';
144
-- i_asic_next <= i_asic + 3;
145
-- elsif i_asic < 6 and hits_valid(i_asic+4) = '1' then
146
-- i_asic_finished <= '0';
147
-- i_asic_next <= i_asic + 4;
148
-- elsif i_asic < 5 and hits_valid(i_asic+5) = '1' then
149
-- i_asic_finished <= '0';
150
-- i_asic_next <= i_asic + 5;
151
-- elsif i_asic < 4 and hits_valid(i_asic+6) = '1' then
152
-- i_asic_finished <= '0';
153
-- i_asic_next <= i_asic + 6;
154
-- elsif i_asic < 3 and hits_valid(i_asic+7) = '1' then
155
-- i_asic_finished <= '0';
156
-- i_asic_next <= i_asic + 7;
157
-- elsif i_asic < 2 and hits_valid(i_asic+8) = '1' then
158
-- i_asic_finished <= '0';
159
-- i_asic_next <= i_asic + 8;
160
-- elsif i_asic < 1 and hits_valid(i_asic+9) = '1' then
161
-- i_asic_finished <= '0';
162
-- i_asic_next <= i_asic + 9;
163
-- else
164
-- i_asic_next <= i_asic;
165
-- i_asic_finished <= '1';
166
-- end if;
167
end
if
;
168
end
process
;
169
------------------------------------------------
170
171
172
------------------------------------------------
173
-- read enable for trg bit hits
174
------------------------------------------------
175
process
(nxt, i_asic, localtrg)
176
begin
177
i_hit_ren
<=
(
others
=
>
'
0
'
)
;
178
i_hit_ren
(
i_asic
)
<=
nxt
;
179
end
process
;
180
hit_read
<=
i_hit_ren
;
181
------------------------------------------------
182
183
184
------------------------------------------------
185
--- state machine for readout
186
------------------------------------------------
187
process
(clk)
188
begin
189
if
rst
=
'
1
'
then
190
ro_state
<=
IDLE
;
191
i_trg_proc_cnt
<=
(
others
=
>
'
0
'
)
;
192
hit_num
<=
0
;
193
run
<=
'
0
'
;
194
evt_rdy
<=
'
0
'
;
195
i_asic
<=
0
;
196
i_occ_err_cnt
<=
(
others
=
>
'
0
'
)
;
197
elsif
rising_edge
(
clk
)
then
198
199
200
case
ro_state
is
201
202
when
IDLE
=
>
203
hit_num
<=
0
;
204
run
<=
'
0
'
;
205
evt_rdy
<=
'
0
'
;
206
busy
<=
'
0
'
;
207
i_asic
<=
0
;
208
209
-- check trg fifo empty flag
210
if
enable
=
'
1
'
and
localtrg
=
'
1
'
then
211
busy
<=
'
1
'
;
212
-- increment counter for processed triggers
213
i_trg_proc_cnt
<=
i_trg_proc_cnt
+
'
1
'
;
214
-- change state
215
ro_state
<=
WAIT_VALID
;
216
end
if
;
217
218
-- wait until event data is valid
219
when
WAIT_VALID
=
>
220
if
tbfifo_drdy
=
B
"1111111111"
then
221
ro_state
<=
PREPARE
;
222
end
if
;
223
224
when
PREPARE
=
>
225
-- determine first asic to be processed
226
set_i_asic_loop :
for
i
in
0
to
9
loop
227
if
hits_valid
(
i
)
=
'
1
'
then
228
i_asic
<=
i
;
229
exit
set_i_asic_loop
;
230
end
if
;
231
end
loop
;
232
-- if hits_valid(0) = '1' then
233
-- i_asic <= 0;
234
-- elsif hits_valid(1) = '1' then
235
-- i_asic <= 1;
236
-- elsif hits_valid(2) = '1' then
237
-- i_asic <= 2;
238
-- elsif hits_valid(3) = '1' then
239
-- i_asic <= 3;
240
-- elsif hits_valid(4) = '1' then
241
-- i_asic <= 4;
242
-- elsif hits_valid(5) = '1' then
243
-- i_asic <= 5;
244
-- elsif hits_valid(6) = '1' then
245
-- i_asic <= 6;
246
-- elsif hits_valid(7) = '1' then
247
-- i_asic <= 7;
248
-- elsif hits_valid(8) = '1' then
249
-- i_asic <= 8;
250
-- elsif hits_valid(9) = '1' then
251
-- i_asic <= 9;
252
-- end if;
253
ro_state
<=
SEND_HITS
;
254
255
when
SEND_HITS
=
>
256
-- initiate transaction
257
run
<=
'
1
'
;
258
ro_state
<=
WAIT_SENT
;
259
evt_rdy
<=
'
1
'
;
260
261
when
NEXT_HIT
=
>
262
ro_state
<=
WAIT_SENT
;
263
264
-- wait until hit data is sent
265
when
WAIT_SENT
=
>
266
evt_rdy
<=
'
0
'
;
267
268
-- ready to serialize next hit data
269
if
hits_valid
(
i_asic
)
=
'
0
'
then
270
i_asic
<=
i_asic_next
;
271
end
if
;
272
if
nxt
=
'
1
'
then
273
hit_num
<=
hit_num
+
1
;
274
--if last_hit_daq = '0' then
275
--ro_state <= NEXT_HIT;
276
--end if;
277
end
if
;
278
279
if
last_hit_daq
=
'
1
'
then
280
ro_state
<=
STOP
;
281
end
if
;
282
283
when
STOP
=
>
284
run
<=
'
0
'
;
285
evt_rdy
<=
'
0
'
;
286
if
ser_busy
=
'
0
'
then
287
ro_state
<=
idle
;
288
if
hit_num
=
i_hit_num_max
then
289
i_occ_err_cnt
<=
i_occ_err_cnt
+
1
;
290
end
if
;
291
end
if
;
292
end
case
;
293
294
end
if
;
295
296
end
process
;
297
298
trg_proc_cnt
<=
i_trg_proc_cnt
;
299
300
ser_run
<=
run
;
301
302
-- hit data
303
axis
<=
'
0
'
when
i_asic
<=
4
else
'
1
'
;
304
asic_chn
<=
to_integer
(
unsigned
(
trgbit_hit_arr
(
i_asic
)
(
30
downto
27
)
)
)
;
305
306
-- calculate channel number
307
with
i_asic
select
chn
<=
308
-- axis = 0
309
asic_chn
when
0
,
310
asic_chn
+
15
*
1
when
1
,
311
asic_chn
+
15
*
2
when
2
,
312
asic_chn
+
15
*
3
when
3
,
313
asic_chn
+
15
*
4
when
4
,
314
-- axis = 1
315
asic_chn
+
0
when
5
,
316
asic_chn
+
15
*
1
when
6
,
317
asic_chn
+
15
*
2
when
7
,
318
asic_chn
+
15
*
3
when
8
,
319
asic_chn
+
15
*
4
when
9
;
320
321
-- process(clk)
322
-- begin
323
-- if rising_edge(clk) then
324
-- chn_r <= chn;
325
-- end if;
326
-- end process;
327
328
-- mark first hit in the packet
329
HitData
.
first_hit
<=
'
1
'
when
hit_num
=
0
else
'
0
'
;
330
331
word1_daq
<=
X
"80"
&
axis
&
std_logic_vector
(
to_unsigned
(
chn
,
7
)
)
;
-- X"80" marks scintillators hits for DataConcentrator
332
-------------------------------------------------------------------------
333
-- make hit data for DAQ/TEST modes
334
-------------------------------------------------------------------------
335
process
(trgbit_hit_arr, hits_valid, ctime_trg, hit_num, i_asic, null_hit_daq, last_hit_daq)
336
begin
337
word2_daq
<=
trgbit_hit_arr
(
i_asic
)
(
15
downto
0
)
;
-- ctime
338
word3_daq
<=
trgbit_hit_arr
(
i_asic
)
(
31
downto
27
)
&
trgbit_hit_arr
(
i_asic
)
(
10
downto
0
)
;
-- trg bits & ctime
339
word4_daq
<=
B
"0000_0000_0000_0000"
;
340
341
-- send null hit if there is no triggered channels
342
if
hits_valid
=
B
"0000_0000_0000_00"
then
343
null_hit_daq
<=
'
1
'
;
344
else
345
null_hit_daq
<=
'
0
'
;
346
end
if
;
347
348
-- mark last hit in the packet
349
if
hits_valid
=
B
"0000_0000_00"
or
hit_num
=
i_hit_num_max
then
350
last_hit_daq
<=
'
1
'
;
351
else
352
last_hit_daq
<=
'
0
'
;
353
end
if
;
354
355
356
end
process
;
357
occ_err_cnt
<=
i_occ_err_cnt
;
358
-------------------------------------------------------------------------
359
360
HitData
.
word1
<=
word1_daq
;
361
HitData
.
word2
<=
word2_daq
;
362
HitData
.
word3
<=
word3_daq
;
363
HitData
.
word4
<=
word4_daq
;
364
365
HitData
.
null_hit
<=
null_hit_daq
;
366
HitData
.
last_hit
<=
last_hit_daq
;
367
368
369
370
end
behavioral
;
conc_intfc_pkg
Definition:
conc_intfc_pkg.vhd:24
klm_scint_pkg
Definition:
klm_scint_pkg.vhd:7
klm_scrod_pkg
Definition:
klm_scrod_pkg.vhd:22
KlmHitBuilderSimple
Definition:
KLMHitBuilder.vhd:30
klm_scint
source
KLMHitBuilder.vhd
Generated by
1.8.13