Line data Source code
1 : // $Id$
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"
29 : #include <iostream>
30 :
31 15 : AliHLTTPCHWCFExtractorUnit::AliHLTTPCHWCFExtractorUnit()
32 : :
33 6 : fStatus(kReadingData),
34 3 : fInput(0),
35 3 : fInputStatus(kEmpty),
36 3 : fkMapping(0),
37 3 : fBunch(fMemory),
38 3 : fPendingOutput(0),
39 3 : fChannelNumWordsLeft(0),
40 3 : fBunchNumWordsLeft(0),
41 3 : fBunchCurrentTime(-2),
42 3 : fRCU2Flag(0),
43 3 : fkMCLabels(0),
44 3 : fNMCLabels(0),
45 3 : fCurrentMCLabel(0)
46 6 : {
47 : //constructor
48 3 : fBunch->fFlag = 0; // wait for the next channel
49 6 : }
50 :
51 :
52 : AliHLTTPCHWCFExtractorUnit::~AliHLTTPCHWCFExtractorUnit()
53 6 : {
54 : //destructor
55 18 : }
56 :
57 0 : AliHLTTPCHWCFExtractorUnit::AliHLTTPCHWCFExtractorUnit(const AliHLTTPCHWCFExtractorUnit&)
58 : :
59 0 : fStatus(kReadingData),
60 0 : fInput(0),
61 0 : fInputStatus(kEmpty),
62 0 : fkMapping(0),
63 0 : fBunch(fMemory),
64 0 : fPendingOutput(0),
65 0 : fChannelNumWordsLeft(0),
66 0 : fBunchNumWordsLeft(0),
67 0 : fBunchCurrentTime(-2),
68 0 : fRCU2Flag(0),
69 0 : fkMCLabels(0),
70 0 : fNMCLabels(0),
71 0 : fCurrentMCLabel(0)
72 0 : {
73 : // dummy
74 0 : }
75 :
76 : AliHLTTPCHWCFExtractorUnit& AliHLTTPCHWCFExtractorUnit::operator=(const AliHLTTPCHWCFExtractorUnit&)
77 : {
78 : // dummy
79 0 : return *this;
80 : }
81 :
82 : int AliHLTTPCHWCFExtractorUnit::Init( const AliHLTUInt32_t *mapping, const AliHLTTPCClusterMCLabel *mcLabels, AliHLTUInt32_t nMCLables )
83 : {
84 : // initialisation
85 :
86 0 : fStatus = kReadingData;
87 0 : fInput = 0;
88 0 : fInputStatus = kEmpty;
89 0 : fkMapping = mapping;
90 0 : fBunch->fFlag = 0; // wait for the next channel
91 0 : fBunch->fData.clear();
92 0 : fPendingOutput = 0;
93 0 : fkMCLabels = mcLabels;
94 0 : fNMCLabels = nMCLables;
95 0 : fCurrentMCLabel = 0;
96 0 : fBunchCurrentTime = -2;
97 0 : if( !fkMapping ) return -1;
98 0 : return 0;
99 0 : }
100 :
101 : int AliHLTTPCHWCFExtractorUnit::InputEndOfData()
102 : {
103 : // input "end of data" signal
104 :
105 : int ret = 0;
106 0 : if( fInputStatus != kEmpty ) ret = -1;
107 0 : fInputStatus = kEndOfData;
108 0 : return ret;
109 : }
110 :
111 : int AliHLTTPCHWCFExtractorUnit::InputStream( AliHLTUInt32_t word )
112 : {
113 : // input stream of data
114 :
115 : int ret = 0;
116 0 : if( fInputStatus != kEmpty ) ret = -1;
117 0 : fInputStatus = kData;
118 0 : fInput = word;
119 0 : return ret;
120 : }
121 :
122 : const AliHLTTPCHWCFBunch *AliHLTTPCHWCFExtractorUnit::OutputStream()
123 : {
124 : // output stream of data
125 :
126 0 : AliHLTTPCHWCFExtractorInputStatus inpStatus = fInputStatus;
127 0 : fInputStatus = kEmpty;
128 :
129 0 : if( fPendingOutput ){
130 0 : fPendingOutput = 0;
131 0 : return fBunch;
132 : }
133 :
134 0 : if( fStatus == kStop ) return 0;
135 :
136 0 : if( !fkMapping ) inpStatus = kEndOfData;
137 :
138 0 : AliHLTTPCHWCFBunch *oldBunch = fBunch;
139 0 : AliHLTTPCHWCFBunch *newBunch = ( fBunch == fMemory ) ?fMemory+1 :fMemory;
140 :
141 0 : if( fStatus == kFinishing || inpStatus == kEndOfData){
142 0 : if( fBunch->fFlag == 1 ){
143 0 : fBunch = newBunch;
144 0 : fPendingOutput = 1;
145 0 : }
146 0 : fBunch->fData.clear();
147 0 : fBunch->fFlag = 3; // end of data
148 0 : fStatus = kStop;
149 0 : return oldBunch;
150 : }
151 :
152 0 : if( inpStatus == kEmpty ) return 0;
153 :
154 0 : AliHLTUInt32_t flag = (fInput >> 30);
155 :
156 0 : if( flag >= 0x2 ){ // RCU trailer
157 0 : if( fBunch->fFlag == 1 ){
158 0 : fBunch = newBunch;
159 0 : fPendingOutput = 1;
160 0 : }
161 0 : fBunch->fData.clear();
162 0 : fBunch->fFlag = 2; // rcu
163 0 : AliHLTTPCHWCFDigit d;
164 0 : d.fQ = fInput;
165 0 : fBunch->fData.push_back(d);
166 0 : fStatus = ( flag == 0x2 ) ?kReadingRCU :kFinishing;
167 : return oldBunch;
168 0 : }
169 :
170 0 : if( fStatus!=kReadingData ) return 0;
171 :
172 0 : if( flag==0x1 ){ // header of a new channel
173 :
174 0 : if( fBunch->fFlag==1 ){
175 : //cout<<"Extractor: Bunch finished: "<<fBunch->fFlag
176 : //<<" R "<<fBunch->fRow<<" P "<<fBunch->fPad<<" T "<<fBunch->fTime<<" NS "<<fBunch->fNSignals<<endl;
177 0 : fBunch = newBunch;
178 0 : }
179 0 : AliHLTUInt32_t hwAddress = fInput & 0xFFF;
180 :
181 0 : fBunch->fFlag = 1;
182 :
183 0 : fBunch->fBranch = (hwAddress >> 11) & 0x1;
184 0 : if( fRCU2Flag ) fBunch->fBranch = 0;
185 :
186 0 : if( hwAddress>=fkMapping[0] ) fBunch->fFlag = 0; //readout errors
187 : else{
188 0 : AliHLTUInt32_t configWord = fkMapping[hwAddress+1];
189 0 : fBunch->fRow = (configWord>>8) & 0x3F;
190 0 : fBunch->fPad = configWord & 0xFF;
191 0 : fBunch->fBorder = (configWord>>14) & 0x1;
192 0 : if( !( (configWord>>15) & 0x1 ) ) fBunch->fFlag = 0;// channel not active
193 0 : fBunch->fGain = (configWord>>16 ) & 0x1FFF;
194 : }
195 0 : fBunch->fData.clear();
196 0 : fChannelNumWordsLeft= (fInput >> 16) & 0x3FF; // payload size in 10-bit words
197 0 : fBunchNumWordsLeft = 0;
198 0 : fBunchCurrentTime = -2;
199 :
200 0 : if( (fInput >> 29) & 0x1 ) fBunch->fFlag = 0; // there were readout errors
201 :
202 : //cout<<"Extractor: Header of new channel F "<<fBunch->fFlag
203 : //<<" R "<<fBunch->fRow<<" P "<<fBunch->fPad<<" NWords10 "<<fChannelNumWordsLeft<<endl;
204 :
205 0 : } else if( flag==0x0 ){
206 :
207 : // bunch data, read three 10-bit words
208 :
209 0 : for( int ishift=20; fBunch->fFlag==1 && ishift>=0; ishift-=10 ){
210 :
211 0 : AliHLTUInt32_t word10 = (fInput >> ishift) & 0x3FF;
212 :
213 0 : if( fChannelNumWordsLeft <= 0 || fBunchNumWordsLeft <= 0 ){ // bunch finished
214 : //cout<<"Extractor: Bunch finished: "<<fBunch->fFlag
215 : //<<" R "<<fBunch->fRow<<" P "<<fBunch->fPad<<" T "<<fBunch->fTime<<" NS "<<fBunch->fNSignals<<endl;
216 0 : fBunch = newBunch; // push to the output
217 :
218 0 : if( fChannelNumWordsLeft <= 0 ){ // wait for the next channel
219 0 : fBunch->fFlag = 0;
220 0 : } else {
221 0 : fBunch->fFlag = 1;
222 0 : fBunch->fRow = oldBunch->fRow;
223 0 : fBunch->fPad = oldBunch->fPad;
224 0 : fBunch->fBranch = oldBunch->fBranch;
225 0 : fBunch->fBorder = oldBunch->fBorder;
226 0 : fBunch->fGain = oldBunch->fGain;
227 0 : fBunch->fData.clear();
228 0 : fBunchNumWordsLeft = word10;
229 0 : fBunchCurrentTime = -2;
230 : }
231 : } else { // continue the bunch
232 0 : if( fBunchCurrentTime <-1 ){ // time has not been read so far
233 0 : fBunchCurrentTime = word10;
234 : //cout<<"Extractor: Bunch time: "<<fBunch->fTime<<endl;
235 0 : } else { // read the signal
236 0 : AliHLTTPCHWCFDigit d;
237 0 : d.fQ = word10;
238 0 : d.fPeak = 0;
239 0 : if( fkMCLabels && fCurrentMCLabel<fNMCLabels ){
240 0 : d.fMC = fkMCLabels[fCurrentMCLabel];
241 0 : fCurrentMCLabel++;
242 0 : }
243 0 : if( fBunchCurrentTime >= 0 ){
244 0 : d.fTime = (AliHLTUInt32_t) fBunchCurrentTime;
245 0 : fBunch->fData.push_back(d);
246 0 : fBunchCurrentTime--;
247 0 : }
248 : //cout<<"Extractor: Bunch signal["<<fBunch->fNSignals<<"]: "<<word10<<endl;
249 0 : }
250 : }
251 0 : fChannelNumWordsLeft--;
252 0 : fBunchNumWordsLeft--;
253 : }
254 0 : }
255 :
256 0 : if( fBunch==newBunch && oldBunch->fFlag==1 && oldBunch->fData.size()>0 ){
257 0 : return oldBunch;
258 : }
259 0 : return 0;
260 0 : }
|