]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/TPCLib/HWCFemulator/AliHLTTPCHWCFExtractorUnit.cxx
Emulation of FPGA clusterfinder
[u/mrichter/AliRoot.git] / HLT / TPCLib / HWCFemulator / AliHLTTPCHWCFExtractorUnit.cxx
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 ){
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] );
234             fCurrentMCLabel++;
235           }
236           //cout<<"Extractor: Bunch signal["<<fBunch->fNSignals<<"]: "<<word10<<endl;
237         }
238       }
239       fChannelNumWordsLeft--;
240       fBunchNumWordsLeft--;   
241     }
242   }
243
244   if( fBunch==newBunch && oldBunch->fFlag==1 && oldBunch->fData.size()>0 ){
245     return oldBunch;
246   }
247   return 0;
248 }