]>
Commit | Line | Data |
---|---|---|
c012881c | 1 | //**************************************************************************** |
2 | //* This file is property of and copyright by the ALICE HLT Project * | |
3 | //* ALICE Experiment at CERN, All rights reserved. * | |
4 | //* * | |
5 | //* Primary Authors: Sergey Gorbunov, Torsten Alt * | |
6 | //* Developers: Sergey Gorbunov <sergey.gorbunov@fias.uni-frankfurt.de> * | |
7 | //* Torsten Alt <talt@cern.ch> * | |
8 | //* for The ALICE HLT Project. * | |
9 | //* * | |
10 | //* Permission to use, copy, modify and distribute this software and its * | |
11 | //* documentation strictly for non-commercial purposes is hereby granted * | |
12 | //* without fee, provided that the above copyright notice appears in all * | |
13 | //* copies and that both the copyright notice and this permission notice * | |
14 | //* appear in the supporting documentation. The authors make no claims * | |
15 | //* about the suitability of this software for any purpose. It is * | |
16 | //* provided "as is" without express or implied warranty. * | |
17 | //**************************************************************************** | |
18 | ||
19 | // @file AliHLTTPCHWCFExtractorUnit.cxx | |
20 | // @author Sergey Gorbunov <sergey.gorbunov@fias.uni-frankfurt.de> | |
21 | // @author Torsten Alt <talt@cern.ch> | |
22 | // @date | |
23 | // @brief Channel Extractor unit of FPGA ClusterFinder Emulator for TPC | |
24 | // @brief ( see AliHLTTPCHWCFEmulator class ) | |
25 | // @note | |
26 | ||
27 | #include "AliHLTTPCHWCFExtractorUnit.h" | |
28 | ||
29 | AliHLTTPCHWCFExtractorUnit::AliHLTTPCHWCFExtractorUnit() | |
30 | : | |
31 | fStatus(kReadingData), | |
32 | fInput(0), | |
33 | fInputStatus(kEmpty), | |
34 | fkMapping(0), | |
35 | fBunch(fMemory), | |
36 | fPendingOutput(0), | |
37 | fChannelNumWordsLeft(0), | |
38 | fBunchNumWordsLeft(0), | |
39 | fkMCLabels(0), | |
40 | fNMCLabels(0), | |
41 | fCurrentMCLabel(0) | |
42 | { | |
43 | //constructor | |
44 | fBunch->fFlag = 0; // wait for the next channel | |
45 | } | |
46 | ||
47 | ||
48 | AliHLTTPCHWCFExtractorUnit::~AliHLTTPCHWCFExtractorUnit() | |
49 | { | |
50 | //destructor | |
51 | } | |
52 | ||
53 | AliHLTTPCHWCFExtractorUnit::AliHLTTPCHWCFExtractorUnit(const AliHLTTPCHWCFExtractorUnit&) | |
54 | : | |
55 | fStatus(kReadingData), | |
56 | fInput(0), | |
57 | fInputStatus(kEmpty), | |
58 | fkMapping(0), | |
59 | fBunch(fMemory), | |
60 | fPendingOutput(0), | |
61 | fChannelNumWordsLeft(0), | |
62 | fBunchNumWordsLeft(0), | |
63 | fkMCLabels(0), | |
64 | fNMCLabels(0), | |
65 | fCurrentMCLabel(0) | |
66 | { | |
67 | // dummy | |
68 | } | |
69 | ||
70 | AliHLTTPCHWCFExtractorUnit& AliHLTTPCHWCFExtractorUnit::operator=(const AliHLTTPCHWCFExtractorUnit&) | |
71 | { | |
72 | // dummy | |
73 | return *this; | |
74 | } | |
75 | ||
76 | int AliHLTTPCHWCFExtractorUnit::Init( const AliHLTUInt32_t *mapping, const AliHLTTPCClusterMCLabel *mcLabels, AliHLTUInt32_t nMCLables ) | |
77 | { | |
78 | // initialisation | |
79 | ||
80 | fStatus = kReadingData; | |
81 | fInput = 0; | |
82 | fInputStatus = kEmpty; | |
83 | fkMapping = mapping; | |
84 | fBunch->fFlag = 0; // wait for the next channel | |
85 | fBunch->fData.clear(); | |
86 | fBunch->fMC.clear(); | |
87 | fPendingOutput = 0; | |
88 | fkMCLabels = mcLabels; | |
89 | fNMCLabels = nMCLables; | |
90 | fCurrentMCLabel = 0; | |
91 | if( !fkMapping ) return -1; | |
92 | return 0; | |
93 | } | |
94 | ||
95 | int AliHLTTPCHWCFExtractorUnit::InputEndOfData() | |
96 | { | |
97 | // input "end of data" signal | |
98 | ||
99 | int ret = 0; | |
100 | if( fInputStatus != kEmpty ) ret = -1; | |
101 | fInputStatus = kEndOfData; | |
102 | return ret; | |
103 | } | |
104 | ||
105 | int AliHLTTPCHWCFExtractorUnit::InputStream( AliHLTUInt32_t word ) | |
106 | { | |
107 | // input stream of data | |
108 | ||
109 | int ret = 0; | |
110 | if( fInputStatus != kEmpty ) ret = -1; | |
111 | fInputStatus = kData; | |
112 | fInput = word; | |
113 | return ret; | |
114 | } | |
115 | ||
116 | const AliHLTTPCHWCFBunch *AliHLTTPCHWCFExtractorUnit::OutputStream() | |
117 | { | |
118 | // output stream of data | |
119 | ||
120 | AliHLTTPCHWCFExtractorInputStatus inpStatus = fInputStatus; | |
121 | fInputStatus = kEmpty; | |
122 | ||
123 | if( fPendingOutput ){ | |
124 | fPendingOutput = 0; | |
125 | return fBunch; | |
126 | } | |
127 | ||
128 | if( fStatus == kStop ) return 0; | |
129 | ||
130 | if( !fkMapping ) inpStatus = kEndOfData; | |
131 | ||
132 | AliHLTTPCHWCFBunch *oldBunch = fBunch; | |
133 | AliHLTTPCHWCFBunch *newBunch = ( fBunch == fMemory ) ?fMemory+1 :fMemory; | |
134 | ||
135 | if( fStatus == kFinishing || inpStatus == kEndOfData){ | |
136 | if( fBunch->fFlag == 1 ){ | |
137 | fBunch = newBunch; | |
138 | fPendingOutput = 1; | |
139 | } | |
140 | fBunch->fData.clear(); | |
141 | fBunch->fMC.clear(); | |
142 | fBunch->fFlag = 3; // end of data | |
143 | fStatus = kStop; | |
144 | return oldBunch; | |
145 | } | |
146 | ||
147 | if( inpStatus == kEmpty ) return 0; | |
148 | ||
149 | AliHLTUInt32_t flag = (fInput >> 30); | |
150 | ||
151 | if( flag >= 0x2 ){ // RCU trailer | |
152 | if( fBunch->fFlag == 1 ){ | |
153 | fBunch = newBunch; | |
154 | fPendingOutput = 1; | |
155 | } | |
156 | fBunch->fData.clear(); | |
157 | fBunch->fMC.clear(); | |
158 | fBunch->fFlag = 2; // rcu | |
159 | fBunch->fData.push_back(fInput); | |
160 | fStatus = ( flag == 0x2 ) ?kReadingRCU :kFinishing; | |
161 | return oldBunch; | |
162 | } | |
163 | ||
164 | if( fStatus!=kReadingData ) return 0; | |
165 | ||
166 | if( flag==0x1 ){ // header of a new channel | |
167 | ||
168 | if( fBunch->fFlag==1 ){ | |
169 | //cout<<"Extractor: Bunch finished: "<<fBunch->fFlag | |
170 | //<<" R "<<fBunch->fRow<<" P "<<fBunch->fPad<<" T "<<fBunch->fTime<<" NS "<<fBunch->fNSignals<<endl; | |
171 | fBunch = newBunch; | |
172 | } | |
173 | AliHLTUInt32_t hwAddress = fInput & 0xFFF; | |
174 | ||
175 | fBunch->fFlag = 1; | |
176 | fBunch->fBranch = (hwAddress >> 11) & 0x1; | |
177 | if( hwAddress>=fkMapping[0] ) fBunch->fFlag = 0; //readout errors | |
178 | else{ | |
179 | AliHLTUInt32_t configWord = fkMapping[hwAddress+1]; | |
180 | fBunch->fRow = (configWord>>8) & 0x3F; | |
181 | fBunch->fPad = configWord & 0xFF; | |
182 | fBunch->fBorder = (configWord>>14) & 0x1; | |
183 | if( !( (configWord>>15) & 0x1 ) ) fBunch->fFlag = 0;// channel not active | |
184 | fBunch->fGain = (configWord>>16 ) & 0x1FFF; | |
185 | } | |
186 | fBunch->fData.clear(); | |
187 | fBunch->fMC.clear(); | |
188 | fBunch->fTime = 0xFFFFFFFF; | |
189 | fChannelNumWordsLeft= (fInput >> 16) & 0x3FF; // payload size in 10-bit words | |
190 | fBunchNumWordsLeft = 0; | |
191 | ||
192 | if( (fInput >> 29) & 0x1 ) fBunch->fFlag = 0; // there were readout errors | |
193 | ||
194 | //cout<<"Extractor: Header of new channel F "<<fBunch->fFlag | |
195 | //<<" R "<<fBunch->fRow<<" P "<<fBunch->fPad<<" NWords10 "<<fChannelNumWordsLeft<<endl; | |
196 | ||
197 | } else if( flag==0x0 ){ | |
198 | ||
199 | // bunch data, read three 10-bit words | |
200 | ||
201 | for( int ishift=20; fBunch->fFlag==1 && ishift>=0; ishift-=10 ){ | |
202 | ||
203 | AliHLTUInt32_t word10 = (fInput >> ishift) & 0x3FF; | |
204 | ||
205 | if( fChannelNumWordsLeft <= 0 || fBunchNumWordsLeft <= 0 ){ // bunch finished | |
206 | //cout<<"Extractor: Bunch finished: "<<fBunch->fFlag | |
207 | //<<" R "<<fBunch->fRow<<" P "<<fBunch->fPad<<" T "<<fBunch->fTime<<" NS "<<fBunch->fNSignals<<endl; | |
208 | fBunch = newBunch; // push to the output | |
209 | ||
210 | if( fChannelNumWordsLeft <= 0 ){ // wait for the next channel | |
211 | fBunch->fFlag = 0; | |
212 | } else { | |
213 | fBunch->fFlag = 1; | |
214 | fBunch->fRow = oldBunch->fRow; | |
215 | fBunch->fPad = oldBunch->fPad; | |
216 | fBunch->fBranch = oldBunch->fBranch; | |
217 | fBunch->fBorder = oldBunch->fBorder; | |
218 | fBunch->fGain = oldBunch->fGain; | |
219 | fBunch->fData.clear(); | |
220 | fBunch->fMC.clear(); | |
221 | fBunch->fTime = 0xFFFFFFFF; | |
222 | fBunchNumWordsLeft = word10; | |
223 | } | |
224 | } else { // continue the brunch | |
225 | if( fBunch->fTime > AliHLTTPCHWCFDefinitions::kMaxNTimeBins ){ // time has not been read so far | |
226 | fBunch->fTime = word10; | |
227 | //cout<<"Extractor: Bunch time: "<<fBunch->fTime<<endl; | |
228 | } else { // read the signal | |
229 | fBunch->fData.push_back(word10); | |
230 | if( fkMCLabels && fCurrentMCLabel<=fNMCLabels ){ | |
b7ea7fe9 | 231 | fBunch->fMC.push_back( fkMCLabels[fCurrentMCLabel] ); |
c012881c | 232 | fCurrentMCLabel++; |
233 | } | |
234 | //cout<<"Extractor: Bunch signal["<<fBunch->fNSignals<<"]: "<<word10<<endl; | |
235 | } | |
236 | } | |
237 | fChannelNumWordsLeft--; | |
238 | fBunchNumWordsLeft--; | |
239 | } | |
240 | } | |
241 | ||
242 | if( fBunch==newBunch && oldBunch->fFlag==1 && oldBunch->fData.size()>0 ){ | |
243 | return oldBunch; | |
244 | } | |
245 | return 0; | |
246 | } |