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