Project
Loading...
Searching...
No Matches
ZeroSuppressionLinkBased.h
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
15
16#ifndef ALICEO2_DATAFORMATSTPC_ZeroSuppressionLinkBased_H
17#define ALICEO2_DATAFORMATSTPC_ZeroSuppressionLinkBased_H
18
19#include "GPUCommonDef.h"
20
21#ifndef GPUCA_GPUCODE
22#include <cstdint>
23#include <bitset>
24#endif
25
26namespace o2
27{
28namespace tpc
29{
30namespace zerosupp_link_based
31{
32
33static constexpr uint32_t DataWordSizeBits = 128;
34static constexpr uint32_t DataWordSizeBytes = DataWordSizeBits / 8;
35static constexpr uint32_t ChannelPerTBHeader = 80;
36
39 static constexpr uint32_t MagicWordLinkZS = 0xFC;
40 static constexpr uint32_t MagicWordLinkZSMetaHeader = 0xFD;
41 static constexpr uint32_t MagicWordTrigger = 0xAA;
42 static constexpr uint32_t MagicWordTriggerV2 = 0xAB;
43
44 union {
45 uint64_t word0 = 0;
46 struct {
47 uint64_t bitMaskLow : 64;
48 };
49 };
51 union {
52 uint64_t word1 = 0;
53 struct {
54 uint64_t bitMaskHigh : 16;
55 uint32_t bunchCrossing : 12;
56 uint32_t numWordsPayload : 4;
57 uint32_t syncOffsetBC : 8;
58 uint32_t fecInPartition : 8;
59 uint32_t CMC : 8;
60 uint32_t magicWord : 8;
61 };
62 };
63
65 bool isLinkZS() const { return (magicWord == MagicWordLinkZS); }
66 bool isMetaHeader() const { return (magicWord == MagicWordLinkZSMetaHeader); }
67 bool isTriggerInfo() const { return (magicWord == MagicWordTrigger); }
68 bool isTriggerInfoV2() const { return (magicWord == MagicWordTriggerV2); }
69};
70
71// GPU Code only requires header definition
72#ifndef GPUCA_GPUCODE
73
75struct Header final : public CommonHeader {
76
77 std::bitset<80> getChannelBits() const
78 {
79 return std::bitset<80>((std::bitset<80>(bitMaskHigh) << 64) | std::bitset<80>(bitMaskLow));
80 }
81
82 bool isFillWord() const { return ((word0 == 0xffffffffffffffff) && (word1 == 0xffffffffffffffff)); }
83};
84
95template <uint32_t DataBitSizeT = 12, uint32_t SignificantBitsT = 2>
96struct Data {
97 static constexpr uint32_t ChannelsPerWord = DataWordSizeBits / DataBitSizeT;
98 static constexpr uint32_t ChannelsPerHalfWord = ChannelsPerWord / 2;
99 static constexpr uint32_t DataBitSize = DataBitSizeT;
100 static constexpr uint32_t SignificantBits = SignificantBitsT;
101 static constexpr uint64_t BitMask = ((uint64_t(1) << DataBitSize) - 1);
102 static constexpr float FloatConversion = 1.f / float(1 << SignificantBits);
103
104 uint64_t adcValues[2]{};
105
107 void setADCValue(uint32_t pos, uint64_t value)
108 {
109 const uint32_t word = pos / ChannelsPerHalfWord;
110 const uint32_t posInWord = pos % ChannelsPerHalfWord;
111
112 const uint64_t set = (value & BitMask) << (posInWord * DataBitSize);
113 const uint64_t mask = (0xFFFFFFFFFFFFFFFF ^ (BitMask << (posInWord * DataBitSize)));
114
115 adcValues[word] &= mask;
116 adcValues[word] |= set;
117 }
118
120 void setADCValueFloat(uint32_t pos, float value)
121 {
122 setADCValue(pos, uint64_t((value + 0.5f * FloatConversion) / FloatConversion));
123 }
124
126 uint32_t getADCValue(uint32_t pos) const
127 {
128 const uint32_t word = pos / ChannelsPerHalfWord;
129 const uint32_t posInWord = pos % ChannelsPerHalfWord;
130
131 return (adcValues[word] >> (posInWord * DataBitSize)) & BitMask;
132 }
133
135 float getADCValueFloat(uint32_t pos) const
136 {
137 return float(getADCValue(pos)) * FloatConversion;
138 }
139
141 void reset()
142 {
143 adcValues[0] = 0;
144 adcValues[1] = 0;
145 }
146};
147
148template <uint32_t DataBitSizeT, uint32_t SignificantBitsT, bool HasHeaderT>
150
151template <uint32_t DataBitSizeT, uint32_t SignificantBitsT>
152struct ContainerT<DataBitSizeT, SignificantBitsT, true> {
155
157 uint32_t getBunchCrossing() const { return header.bunchCrossing; }
158
160 uint32_t getDataWords() const { return header.numWordsPayload; }
161
163 uint32_t getTotalWords() const { return header.numWordsPayload + 1; }
164
166 std::bitset<80> getChannelBits() const { return header.getChannelBits(); }
167};
168
169template <uint32_t DataBitSizeT, uint32_t SignificantBitsT>
170struct ContainerT<DataBitSizeT, SignificantBitsT, false> {
172
174 uint32_t getBunchCrossing() const { return 0; }
175
177 uint32_t getDataWords() const { return 7; }
178
180 uint32_t getTotalWords() const { return 7; }
181
183 std::bitset<80> getChannelBits() const { return std::bitset<80>().set(); }
184};
185
189template <uint32_t DataBitSizeT = 12, uint32_t SignificantBitsT = 2, bool HasHeaderT = true>
190struct Container {
191 static constexpr uint32_t ChannelsPerWord = DataWordSizeBits / DataBitSizeT;
192
194
196 uint32_t getADCValue(uint32_t word) { return cont.data[word / ChannelsPerWord].getADCValue(word % ChannelsPerWord); }
197
199 float getADCValueFloat(uint32_t word) { return cont.data[word / ChannelsPerWord].getADCValueFloat(word % ChannelsPerWord); }
200
202 void setADCValue(uint32_t word, uint64_t value) { cont.data[word / ChannelsPerWord].setADCValue(word % ChannelsPerWord, value); }
203
205 void setADCValueFloat(uint32_t word, float value) { cont.data[word / ChannelsPerWord].setADCValueFloat(word % ChannelsPerWord, value); }
206
208 void reset()
209 {
210 for (int i = 0; i < cont.getDataWords(); ++i) {
211 cont.data[i].reset();
212 }
213 }
214
215 uint32_t getBunchCrossing() const { return cont.getBunchCrossing(); }
216 uint32_t getDataWords() const { return cont.getDataWords(); }
217 uint32_t getTotalWords() const { return cont.getTotalWords(); }
218 std::bitset<80> getChannelBits() const { return cont.getChannelBits(); }
219
221 size_t getTotalSizeBytes() const { return getTotalWords() * DataWordSizeBytes; }
222
225 {
226 return (Container*)((const char*)this + getTotalWords() * DataWordSizeBytes);
227 }
228
229}; // namespace zerosupp_link_based
230
233
236 union {
237 uint64_t word0 = 0;
238 struct {
239 uint16_t bunchCrossing : 12;
240 uint64_t orbit : 32;
241 uint32_t triggerTypeLow : 20;
242 };
243 };
245 union {
246 uint64_t word1 = 0;
247 struct {
248 uint32_t triggerTypeHigh : 12;
249 uint64_t empty : 50;
250 };
251 };
252
253 uint32_t getOrbit() const { return (uint32_t)orbit; }
254 uint32_t getTriggerType() const { return (triggerTypeHigh << 20) + triggerTypeLow; }
255};
256
259 union {
260 uint64_t word0 = 0;
261 struct {
262 uint32_t triggerType;
263 uint32_t orbit;
264 };
265 };
267 union {
268 uint64_t word1 = 0;
269 struct {
270 uint32_t bunchCrossing : 12;
271 uint32_t empty1_0 : 16;
272 uint32_t numWordsPayload : 4;
273 uint32_t empty1_1 : 24;
274 uint32_t magicWord : 8;
275 };
276 };
277};
278
286
289 static constexpr uint16_t HasTrigger = 0x8;
290 static constexpr uint16_t LaserTriggerMask = 0x4;
291 static constexpr uint16_t PulserTriggerMask = 0x2;
292 static constexpr uint16_t PhysicsTriggerMask = 0x1;
293
294 union {
295 uint16_t word = 0;
296 struct {
297 uint16_t bunchCrossing : 12;
298 uint16_t triggerType : 4;
299 };
300 };
301
302 bool hasTrigger() const { return triggerType & HasTrigger; }
306};
307
312 uint64_t word0 = 0;
313 uint64_t word1 = 0;
314
315 bool hasTrigger() const { return word0 != 0x0; }
316 uint16_t getFirstBC() const { return word0 & 0xFFF; }
317};
318#endif // !defined(GPUCA_GPUCODE)
319
320} // namespace zerosupp_link_based
321} // namespace tpc
322} // namespace o2
323
324#endif
int32_t i
uint16_t pos
Definition RawData.h:3
GLsizei const GLfloat * value
Definition glcorearb.h:819
GLboolean * data
Definition glcorearb.h:298
GLint GLuint mask
Definition glcorearb.h:291
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...