Project
Loading...
Searching...
No Matches
EncoderImplHelper.cxx
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
12#include "Assertions.h"
13#include "EncoderImplHelper.h"
16#include "NofBits.h"
17
18namespace o2::mch::raw::impl
19{
20
21uint16_t computeChipAddress(uint8_t elinkId, DualSampaChannelId chId)
22{
23 auto opt = o2::mch::raw::indexFromElinkId(elinkId);
24 if (!opt.has_value()) {
25 throw std::invalid_argument(fmt::format("elinkId {} is not valid", elinkId));
26 }
27 return opt.value() * 2 + (chId > 31);
28}
29
34SampaHeader buildSampaHeader(uint8_t elinkId, DualSampaChannelId chId, gsl::span<const SampaCluster> data)
35{
36 assertIsInRange("chId", chId, 0, 63);
37
38 SampaHeader header;
40
41 uint16_t n10{0};
42 for (const auto& s : data) {
43 n10 += s.nof10BitWords();
44 }
45 uint32_t bunchCrossingCounter{0};
46 if (data.size()) {
47 bunchCrossingCounter = data[0].bunchCrossing;
48 }
49 assertNofBits("nof10BitWords", n10, 10);
50 header.nof10BitWords(n10);
51 header.chipAddress(computeChipAddress(elinkId, chId));
52 header.channelAddress(chId % 32);
53 assertNofBits("bunchCrossingCounter", bunchCrossingCounter, 20);
54 header.bunchCrossingCounter(bunchCrossingCounter);
55 // compute the hamming code and parity at last
56 header.headerParity(computeHeaderParity(header.uint64()));
57 header.hammingCode(computeHammingCode(header.uint64()));
58 return header;
59}
60
61uint64_t build64(uint16_t a10, uint16_t b10 = 0, uint16_t c10 = 0, uint16_t d10 = 0, uint16_t e10 = 0)
62{
63 impl::assertIsInRange("a10", a10, 0, 1023);
64 impl::assertIsInRange("b10", a10, 0, 1023);
65 impl::assertIsInRange("c10", a10, 0, 1023);
66 impl::assertIsInRange("d10", a10, 0, 1023);
67 impl::assertIsInRange("e10", a10, 0, 1023);
68 return (static_cast<uint64_t>(a10) << 40) |
69 (static_cast<uint64_t>(b10) << 30) |
70 (static_cast<uint64_t>(c10) << 20) |
71 (static_cast<uint64_t>(d10) << 10) |
72 (static_cast<uint64_t>(e10));
73}
74
75void addPadding(std::vector<uint10_t>& b10)
76{
77 while (b10.size() % 5) {
78 b10.emplace_back(0);
79 }
80}
81
82void b10to64(std::vector<uint10_t> b10, std::vector<uint64_t>& b64, uint16_t prefix14)
83{
84 uint64_t prefix = prefix14;
85 prefix <<= 50;
86
87 addPadding(b10);
88
89 for (auto i = 0; i < b10.size(); i += 5) {
90 uint64_t v = build64(b10[i + 4], b10[i + 3], b10[i + 2], b10[i + 1], b10[i + 0]);
91 b64.emplace_back(v | prefix);
92 }
93}
94
95void bufferizeClusters(gsl::span<const SampaCluster> clusters, std::vector<uint10_t>& b10)
96{
97 for (auto& c : clusters) {
98 b10.emplace_back(c.nofSamples());
99 b10.emplace_back(c.sampaTime);
100 if (c.isClusterSum()) {
101 b10.emplace_back(c.chargeSum & 0x3FF);
102 b10.emplace_back((c.chargeSum & 0xFFC00) >> 10);
103 } else {
104 for (auto& s : c.samples) {
105 b10.emplace_back(s);
106 }
107 }
108 }
109}
110
111void append(std::vector<uint10_t>& b10, uint50_t value)
112{
113 b10.emplace_back((value & 0x3FF));
114 b10.emplace_back((value & 0xFFC00) >> 10);
115 b10.emplace_back((value & 0x3FF00000) >> 20);
116 b10.emplace_back((value & 0xFFC0000000) >> 30);
117 b10.emplace_back((value & 0x3FF0000000000) >> 40);
118}
119
120void appendSync(std::vector<uint10_t>& b10)
121{
122 addPadding(b10);
123 append(b10, sampaSyncWord);
124}
125
126void fillUserLogicBuffer10(std::vector<uint10_t>& b10,
127 gsl::span<const SampaCluster> clusters,
128 uint8_t elinkId,
130 bool addSync)
131{
132 auto sh = buildSampaHeader(elinkId, chId, clusters);
133 if (addSync) {
134 appendSync(b10);
135 }
136 append(b10, sh.uint64());
138}
139
140} // namespace o2::mch::raw::impl
int32_t i
uint32_t c
Definition RawData.h:2
SampaHeader is the 50-bits header word used in Sampa data transmission protocol.
Definition SampaHeader.h:51
SampaChannelAddress channelAddress() const
uint16_t nof10BitWords() const
uint8_t chipAddress() const
uint32_t bunchCrossingCounter() const
constexpr uint64_t uint64() const
return the header as a 64-bits integer
SampaPacketType packetType() const
uint8_t hammingCode() const
const GLdouble * v
Definition glcorearb.h:832
GLsizei const GLfloat * value
Definition glcorearb.h:819
GLboolean * data
Definition glcorearb.h:298
uint64_t build64(uint16_t a10, uint16_t b10=0, uint16_t c10=0, uint16_t d10=0, uint16_t e10=0)
void addPadding(std::vector< uint10_t > &b10)
void fillUserLogicBuffer10(std::vector< uint10_t > &b10, gsl::span< const SampaCluster > clusters, uint8_t elinkId, DualSampaChannelId chId, bool addSync)
uint16_t computeChipAddress(uint8_t elinkId, DualSampaChannelId chId)
void assertNofBits(std::string_view msg, T value, int n)
Definition NofBits.h:29
void append(std::vector< uint10_t > &b10, uint50_t value)
SampaHeader buildSampaHeader(uint8_t elinkId, DualSampaChannelId chId, gsl::span< const SampaCluster > data)
int assertIsInRange(std::string what, uint64_t value, uint64_t min, uint64_t max)
Definition Assertions.h:20
void appendSync(std::vector< uint10_t > &b10)
void b10to64(std::vector< uint10_t > b10, std::vector< uint64_t > &b64, uint16_t prefix14)
void bufferizeClusters(gsl::span< const SampaCluster > clusters, std::vector< uint10_t > &b10)
int computeHeaderParity(uint64_t value)
std::optional< uint8_t > indexFromElinkId(uint8_t elinkId)
Extracts the index from the elinkId.
Definition DsElecId.cxx:132
constexpr uint64_t sampaSyncWord
uint6_t DualSampaChannelId
Definition DataFormats.h:65
uint64_t uint50_t
Definition DataFormats.h:69
int computeHammingCode(uint64_t value)
std::vector< Cluster > clusters