1 //****************************************************************************
2 //* This file is property of and copyright by the ALICE HLT Project *
3 //* ALICE Experiment at CERN, All rights reserved. *
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. *
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 //****************************************************************************
19 // @file AliHLTTPCHWCFExtractorUnit.cxx
20 // @author Sergey Gorbunov <sergey.gorbunov@fias.uni-frankfurt.de>
21 // @author Torsten Alt <talt@cern.ch>
23 // @brief Channel Extractor unit of FPGA ClusterFinder Emulator for TPC
24 // @brief ( see AliHLTTPCHWCFEmulator class )
27 #include "AliHLTTPCHWCFExtractorUnit.h"
29 AliHLTTPCHWCFExtractorUnit::AliHLTTPCHWCFExtractorUnit()
31 fStatus(kReadingData),
37 fChannelNumWordsLeft(0),
38 fBunchNumWordsLeft(0),
44 fBunch->fFlag = 0; // wait for the next channel
48 AliHLTTPCHWCFExtractorUnit::~AliHLTTPCHWCFExtractorUnit()
53 AliHLTTPCHWCFExtractorUnit::AliHLTTPCHWCFExtractorUnit(const AliHLTTPCHWCFExtractorUnit&)
55 fStatus(kReadingData),
61 fChannelNumWordsLeft(0),
62 fBunchNumWordsLeft(0),
70 AliHLTTPCHWCFExtractorUnit& AliHLTTPCHWCFExtractorUnit::operator=(const AliHLTTPCHWCFExtractorUnit&)
76 int AliHLTTPCHWCFExtractorUnit::Init( const AliHLTUInt32_t *mapping, const AliHLTTPCClusterMCLabel *mcLabels, AliHLTUInt32_t nMCLables )
80 fStatus = kReadingData;
82 fInputStatus = kEmpty;
84 fBunch->fFlag = 0; // wait for the next channel
85 fBunch->fData.clear();
88 fkMCLabels = mcLabels;
89 fNMCLabels = nMCLables;
91 if( !fkMapping ) return -1;
95 int AliHLTTPCHWCFExtractorUnit::InputEndOfData()
97 // input "end of data" signal
100 if( fInputStatus != kEmpty ) ret = -1;
101 fInputStatus = kEndOfData;
105 int AliHLTTPCHWCFExtractorUnit::InputStream( AliHLTUInt32_t word )
107 // input stream of data
110 if( fInputStatus != kEmpty ) ret = -1;
111 fInputStatus = kData;
116 const AliHLTTPCHWCFBunch *AliHLTTPCHWCFExtractorUnit::OutputStream()
118 // output stream of data
120 AliHLTTPCHWCFExtractorInputStatus inpStatus = fInputStatus;
121 fInputStatus = kEmpty;
123 if( fPendingOutput ){
128 if( fStatus == kStop ) return 0;
130 if( !fkMapping ) inpStatus = kEndOfData;
132 AliHLTTPCHWCFBunch *oldBunch = fBunch;
133 AliHLTTPCHWCFBunch *newBunch = ( fBunch == fMemory ) ?fMemory+1 :fMemory;
135 if( fStatus == kFinishing || inpStatus == kEndOfData){
136 if( fBunch->fFlag == 1 ){
140 fBunch->fData.clear();
142 fBunch->fFlag = 3; // end of data
147 if( inpStatus == kEmpty ) return 0;
149 AliHLTUInt32_t flag = (fInput >> 30);
151 if( flag >= 0x2 ){ // RCU trailer
152 if( fBunch->fFlag == 1 ){
156 fBunch->fData.clear();
158 fBunch->fFlag = 2; // rcu
159 fBunch->fData.push_back(fInput);
160 fStatus = ( flag == 0x2 ) ?kReadingRCU :kFinishing;
164 if( fStatus!=kReadingData ) return 0;
166 if( flag==0x1 ){ // header of a new channel
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;
173 AliHLTUInt32_t hwAddress = fInput & 0xFFF;
176 fBunch->fBranch = (hwAddress >> 11) & 0x1;
177 if( hwAddress>=fkMapping[0] ) fBunch->fFlag = 0; //readout errors
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;
186 fBunch->fData.clear();
188 fBunch->fTime = 0xFFFFFFFF;
189 fChannelNumWordsLeft= (fInput >> 16) & 0x3FF; // payload size in 10-bit words
190 fBunchNumWordsLeft = 0;
192 if( (fInput >> 29) & 0x1 ) fBunch->fFlag = 0; // there were readout errors
194 //cout<<"Extractor: Header of new channel F "<<fBunch->fFlag
195 //<<" R "<<fBunch->fRow<<" P "<<fBunch->fPad<<" NWords10 "<<fChannelNumWordsLeft<<endl;
197 } else if( flag==0x0 ){
199 // bunch data, read three 10-bit words
201 for( int ishift=20; fBunch->fFlag==1 && ishift>=0; ishift-=10 ){
203 AliHLTUInt32_t word10 = (fInput >> ishift) & 0x3FF;
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
210 if( fChannelNumWordsLeft <= 0 ){ // wait for the next channel
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();
221 fBunch->fTime = 0xFFFFFFFF;
222 fBunchNumWordsLeft = word10;
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 ){
231 fBunch->fMC.push_back( fkMCLabels[fCurrentMCLabel].fClusterID[0] );
232 fBunch->fMC.push_back( fkMCLabels[fCurrentMCLabel].fClusterID[1] );
233 fBunch->fMC.push_back( fkMCLabels[fCurrentMCLabel].fClusterID[2] );
236 //cout<<"Extractor: Bunch signal["<<fBunch->fNSignals<<"]: "<<word10<<endl;
239 fChannelNumWordsLeft--;
240 fBunchNumWordsLeft--;
244 if( fBunch==newBunch && oldBunch->fFlag==1 && oldBunch->fData.size()>0 ){