BeSlinkSim.hh 16.2 KB
Newer Older
dauncey's avatar
dauncey committed
1 2 3 4 5 6 7
#ifndef BeSlinkSim_HH
#define BeSlinkSim_HH

#include <iostream>
#include <iomanip>
#include <cassert>

8
#include "Buffering/CircularBufferUR32.hh"
dauncey's avatar
dauncey committed
9 10 11 12 13 14 15 16
#include "Buffering/SlinkBoe.hh"
#include "Buffering/SlinkEoe.hh"
#include "Buffering/SlinkArch.hh"

class BeSlinkSim {
  friend class BeSlinkAna;

public:
dauncey's avatar
dauncey committed
17
  /*
dauncey's avatar
dauncey committed
18
    enum {
dauncey's avatar
dauncey committed
19
    NumberOfParallelBuffers=2
dauncey's avatar
dauncey committed
20
    };
dauncey's avatar
dauncey committed
21
  
dauncey's avatar
dauncey committed
22
    enum DataRandomMethod {
dauncey's avatar
dauncey committed
23 24 25 26
    NotRandom,
    Binomial,
    Flat,
    Mixed
dauncey's avatar
dauncey committed
27
    };
dauncey's avatar
dauncey committed
28

dauncey's avatar
dauncey committed
29
    enum DataFormatMethod {
dauncey's avatar
dauncey committed
30 31 32 33
    FixedChannelBitmap,
    FixedChannelLabels,
    FixedMixture,
    VariableMixture
dauncey's avatar
dauncey committed
34
    };
dauncey's avatar
dauncey committed
35

dauncey's avatar
dauncey committed
36
    enum DataFlowMethod {
dauncey's avatar
dauncey committed
37 38 39
    FixedHgcrocMap,
    VariableHgcrocMap,
    EventBuild
dauncey's avatar
dauncey committed
40
    };
dauncey's avatar
dauncey committed
41 42
  */
  
dauncey's avatar
dauncey committed
43 44 45 46
  //BeSlinkSim(unsigned e, unsigned h=18, unsigned m=0) : fEcon(e) {
  BeSlinkSim() {
  }

dauncey's avatar
dauncey committed
47
  void boj(const SlinkArch &a, unsigned bl) {
dauncey's avatar
dauncey committed
48
    fSlinkArch=&a;
dauncey's avatar
dauncey committed
49
    fBufferLimit=bl;
dauncey's avatar
dauncey committed
50 51 52
      
    if(fPrintLevel>0) {	
      std::cout << "BeSlinkSim[" << fSlinkArch->slinkNumber() << "]::ctor() "
dauncey's avatar
dauncey committed
53
		<< "Entered with buffer limit = " << fBufferLimit << std::endl;
dauncey's avatar
dauncey committed
54 55
    }

dauncey's avatar
dauncey committed
56
    fThrottleActive=false;
dauncey's avatar
dauncey committed
57 58 59
    fEventActive=false;
    fActiveInputBuffer=0;    
    fWriteElink=0;
dauncey's avatar
dauncey committed
60
    
dauncey's avatar
dauncey committed
61 62 63 64 65 66 67
    fArrayWrite=0;
    for(unsigned i(0);i<4;i++) fArrayWord[i]=0;

    for(unsigned e(0);e<fSlinkArch->numberOfEcons();e++) {
      const EconArch &econArch(fSlinkArch->econArch(e));
      for(unsigned b(0);b<econArch.numberOfBlocks();b++) {
	fBlockCheck[e][b].initialise(fSlinkArch->slinkNumber(),e,b,econArch.hgcrocNumber(b));
dauncey's avatar
dauncey committed
68
	fBlockPair[e][b].first=true;
dauncey's avatar
dauncey committed
69 70
      }
    }
dauncey's avatar
dauncey committed
71 72 73 74 75 76
  }

  void processL1Accept(uint64_t bx, uint64_t l1a) {
    uint64_t d[2];
    SlinkBoe sBoe(0xce00,bx&0xffffffff,l1a&0xffffffff,0xab);
    sBoe.words(d);
dauncey's avatar
dauncey committed
77
    
dauncey's avatar
dauncey committed
78 79 80 81 82
    if(fPrintLevel>4) {
      std::cout << "BeSlinkSim[" << fSlinkArch->slinkNumber() << "]::processL1Accept(" << bx << "," << l1a << ") "
		<< "Saving Slink BOE" << std::endl;
      sBoe.print();
    }
83 84 85

    assert(fSlinkBoeCb.writeAndIncrementPtr(d[0]));
    assert(fSlinkBoeCb.writeAndIncrementPtr(d[1]));
dauncey's avatar
dauncey committed
86
  }
dauncey's avatar
dauncey committed
87

dauncey's avatar
dauncey committed
88
  void processBx(uint64_t bx, const SlinkElinkData &d) {
dauncey's avatar
dauncey committed
89

dauncey's avatar
dauncey committed
90 91 92 93
    fExceededBuffer=false;
    
    for(unsigned e(0);e<fSlinkArch->numberOfEcons();e++) {
      const EconArch &econArch(fSlinkArch->econArch(e));
dauncey's avatar
dauncey committed
94
      
dauncey's avatar
dauncey committed
95 96 97
      for(unsigned b(0);b<econArch.numberOfBlocks();b++) {
	const std::vector<unsigned> &elinkNumber(econArch.elinkNumber(b));
	
98 99 100 101 102
	uint32_t word;
	for(unsigned w(0);w<elinkNumber.size();w++) {
	  word=d.fData[e][elinkNumber[w]];
	  if(word!=0 || fEventBuffer[e][b].isCachedWriteWord()) assert(fEventBuffer[e][b].halfWriteAndIncrementPtr(word));
	}
dauncey's avatar
dauncey committed
103 104
	
	if(fEventBuffer[e][b].used()>=4095) fExceededBuffer=true;
dauncey's avatar
dauncey committed
105 106
      }
    }
dauncey's avatar
dauncey committed
107
    
dauncey's avatar
dauncey committed
108
    // Output to Slink
dauncey's avatar
dauncey committed
109
    
110 111
    fL1AcceptBoe=false;
    fL1AcceptEoe=false;
dauncey's avatar
dauncey committed
112
    
dauncey's avatar
dauncey committed
113 114 115 116 117 118 119 120 121 122 123 124 125 126
    bool done(false);
    uint128_t w;
    fNumberOfSlinkWords=0;

    for(fNumberOfSlinkWords=0;fNumberOfSlinkWords<3 && !done;) {
      if(fPrintLevel>5) {
	std::cout << "BeSlinkSim[" << fSlinkArch->slinkNumber() << "]::processBx() "
		  << "Number of Slink words written = " << fNumberOfSlinkWords
		  << ", event active = " << (fEventActive?"true":"false")
		  << ", done = " << (done?"true":"false")
		  << std::endl;
      }
    
      if(!fEventActive) {
dauncey's avatar
dauncey committed
127 128 129
	if(!fSlinkBoeCb.empty()) {
	  assert(fSlinkBoeCb.readAndIncrementPtr(w.first));
	  assert(fSlinkBoeCb.readAndIncrementPtr(w.second));
dauncey's avatar
dauncey committed
130 131 132 133 134 135 136 137 138 139 140 141 142
	  fSlinkWord[fNumberOfSlinkWords]=std::pair<uint128_t,bool>(w,true);
	  fNumberOfSlinkWords++;

	  if(fPrintLevel>3) {
	    std::cout << "BeSlinkSim[" << fSlinkArch->slinkNumber() << "]::processBx() "
		      << "Writing Slink BOE = 0x" << std::hex << w.second << " " << w.first
		      << std::dec << std::endl;
	  }
	  
	  fEconRead=0;
	  fBlockRead=0;
	  fNumberOfEventWords=0;
	  fEventActive=true;
143 144
	  fL1AcceptBoe=true;
	  
dauncey's avatar
dauncey committed
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
	} else {
	  done=true;
	}
	
      } else {
	if(fEconRead==fSlinkArch->numberOfEcons()) {
	  SlinkEoe seoe(0xce00,0x77,0xff,fNumberOfEventWords);
	  seoe.word(w);
	  fSlinkWord[fNumberOfSlinkWords]=std::pair<uint128_t,bool>(w,true);
	  fNumberOfSlinkWords++;
	  
	  if(fPrintLevel>3) {
	    std::cout << "BeSlinkSim[" << fSlinkArch->slinkNumber() << "]::processBx() "
		      << "Writing Slink EOE = 0x" << std::hex << w.second << " " << w.first
		      << std::dec << std::endl;
	  }
	  
	  fEventActive=false;
163 164
	  fL1AcceptEoe=true;	
	  fTotalNumberOfEventWords=fNumberOfEventWords;
dauncey's avatar
dauncey committed
165 166
	  
	} else {
167 168 169 170 171 172 173

	  if(fPrintLevel>4) {
	    std::cout << "BeSlinkSim[" << fSlinkArch->slinkNumber() << "]::processBx() "
		      << "Reading from ECON " << fEconRead
		      << ", block " << fBlockRead
		      << std::endl;
	  }
dauncey's avatar
dauncey committed
174
	  
dauncey's avatar
dauncey committed
175
	  for(unsigned i(0);/*i<4 &&*/ !done && fEconRead<fSlinkArch->numberOfEcons() && fArrayWrite<4;i++) {
176
#ifdef OLD_METHOD
dauncey's avatar
dauncey committed
177 178 179 180 181 182 183 184 185 186 187 188
	    if(!(fEventBuffer[fEconRead][fBlockRead].empty() && fBlockPair[fEconRead][fBlockRead].first)) {

	      uint32_t nextWord(0);
	      if(fBlockPair[fEconRead][fBlockRead].first) {
		uint64_t d;
		assert(fEventBuffer[fEconRead][fBlockRead].readAndIncrementPtr(d));
		nextWord=(d&0xffffffff);
		fBlockPair[fEconRead][fBlockRead].second=(d>>32);
		fBlockPair[fEconRead][fBlockRead].first=false;
	      } else {
		nextWord=fBlockPair[fEconRead][fBlockRead].second;
		fBlockPair[fEconRead][fBlockRead].first=true;
dauncey's avatar
dauncey committed
189
	      }
dauncey's avatar
dauncey committed
190 191 192 193
	      
	      //fArrayWord[fArrayWrite  ]=(d&0xffffffff);
	      //fArrayWord[fArrayWrite+1]=(d>>32);
	      //fArrayWrite+=2;
194 195 196 197 198
#else
	      if(!fEventBuffer[fEconRead][fBlockRead].unreadable()) {
		uint32_t nextWord(0);
		assert(fEventBuffer[fEconRead][fBlockRead].halfReadAndIncrementPtr(nextWord));
#endif
dauncey's avatar
dauncey committed
199 200 201 202 203 204
		if(nextWord!=0) {
		  if(fPrintLevel>5) {
		    std::cout << "BeSlinkSim[" << fSlinkArch->slinkNumber() << "]::processBx() "
			      << "Read buffer words = 0x" << std::hex
			      << nextWord << std::dec << std::endl;
		  }
dauncey's avatar
dauncey committed
205
		
dauncey's avatar
dauncey committed
206 207
		  fArrayWord[fArrayWrite]=nextWord;
		  fArrayWrite++;
208
		
dauncey's avatar
dauncey committed
209
		  if(fBlockCheck[fEconRead][fBlockRead].processBx(fArrayWord[fArrayWrite-1])) fBlockRead++;
dauncey's avatar
dauncey committed
210
		
dauncey's avatar
dauncey committed
211 212 213 214
		  if(fBlockRead==fSlinkArch->econArch(fEconRead).numberOfBlocks()) {
		    fBlockRead=0;
		    fEconRead++;
		  }
dauncey's avatar
dauncey committed
215
		
dauncey's avatar
dauncey committed
216 217
		  if(fEconRead==fSlinkArch->numberOfEcons()) fArrayWrite=4;
		}
dauncey's avatar
dauncey committed
218
	      
dauncey's avatar
dauncey committed
219 220 221 222 223
	      } else {
		if(fPrintLevel>5) {
		  std::cout << "BeSlinkSim[" << fSlinkArch->slinkNumber() << "]::processBx() "
			    << "Nothing in buffer" << std::endl;
		}
224
	      
dauncey's avatar
dauncey committed
225 226
		done=true;
	      }
dauncey's avatar
dauncey committed
227 228
	    }
	  
dauncey's avatar
dauncey committed
229 230 231 232 233 234 235 236
	    if(fArrayWrite==4) {
	      w.first=fArrayWord[1];
	      w.first=(w.first<<32)+fArrayWord[0];
	      w.second=fArrayWord[3];
	      w.second=(w.second<<32)+fArrayWord[2];
	      fSlinkWord[fNumberOfSlinkWords]=std::pair<uint128_t,bool>(w,false);
	      fNumberOfSlinkWords++;
	      fNumberOfEventWords++;
dauncey's avatar
dauncey committed
237
	    
dauncey's avatar
dauncey committed
238 239 240 241 242
	      if(fPrintLevel>3) {
		std::cout << "BeSlinkSim[" << fSlinkArch->slinkNumber() << "]::processBx() "
			  << "Writing Slink data word = 0x" << std::hex << w.second << " " << w.first
			  << std::dec << std::endl;
	      }
dauncey's avatar
dauncey committed
243
	  
dauncey's avatar
dauncey committed
244 245 246
	      fArrayWrite=0;
	      for(unsigned i(0);i<4;i++) fArrayWord[i]=0;
	    }
dauncey's avatar
dauncey committed
247 248 249 250 251
	  }
	}
      }
    }

dauncey's avatar
dauncey committed
252 253 254 255 256
    bool exceededBuffer() const {
      return fExceededBuffer;
    }
    
    void processEconBx(unsigned ec, const uint32_t *d) {
dauncey's avatar
dauncey committed
257

dauncey's avatar
dauncey committed
258
      return;
dauncey's avatar
dauncey committed
259
#ifdef NOT_YET
dauncey's avatar
dauncey committed
260
    
dauncey's avatar
dauncey committed
261
      uint32_t a[7];
dauncey's avatar
dauncey committed
262
    
dauncey's avatar
dauncey committed
263
      // Switch for different dataflow methods
dauncey's avatar
dauncey committed
264

dauncey's avatar
dauncey committed
265
      if(fDataFlowMethod==FixedHgcrocMap) {
dauncey's avatar
dauncey committed
266 267

      
dauncey's avatar
dauncey committed
268 269
	//  4 words per BX for 7 eLinks
	unsigned nWords(4);
dauncey's avatar
dauncey committed
270
      
dauncey's avatar
dauncey committed
271 272 273 274 275
	if(fPrintLevel>3) {
	  std::cout << "BeSlinkSim[" << fSlinkArch->slinkNumber() << "][" << fEcon << "]::processBx() "
		    << "Data flow method = fixed HGCROC map, reading "
		    << nWords << " words per BX"	<< std::endl;
	}
dauncey's avatar
dauncey committed
276
	    
dauncey's avatar
dauncey committed
277 278
	for(unsigned b(0);b<NumberOfParallelBuffers;b++) {
	  if(b!=(fActiveInputBuffer%NumberOfParallelBuffers)) {
dauncey's avatar
dauncey committed
279
	  
dauncey's avatar
dauncey committed
280 281
	    for(unsigned e(0);e<7;e++) {
	      if(fReadHgcroc[b]<fEconFile.fNumberOfHgcrocs) {
dauncey's avatar
dauncey committed
282
	      
dauncey's avatar
dauncey committed
283 284 285
		for(unsigned w(0);w<nWords;w++) {
		  assert(fReadHgcroc[b]<fEconFile.fNumberOfHgcrocs);
		  assert(fReadWord[b]<fFirstBuffer[b][fReadHgcroc[b]].size());
dauncey's avatar
dauncey committed
286
		
dauncey's avatar
dauncey committed
287 288 289 290 291 292 293 294 295
		  if(fPrintLevel>4) {
		    std::cout << "BeSlinkSim[" << fSlinkArch->slinkNumber() << "][" << fEcon << "]::processBx() "
			      << "Copying BX word " << w << " from first buffer " << b
			      << ", HGCROC " << fReadHgcroc[b] << ", word " << fReadWord[b]
			      << " of " << fFirstBuffer[b][fReadHgcroc[b]].size() << " = "
			      << std::hex << fFirstBuffer[b][fReadHgcroc[b]][fReadWord[b]]
			      << std::dec << std::endl;
		  }
		  assert(fElink[fHgcrocToElink[h]].writeAndIncrementPtr(fFirstBuffer[b][fReadHgcrocNumber[b]][fReadWord[b]]));
dauncey's avatar
dauncey committed
296 297 298 299 300 301
		}
	      }
	    }
	  }
	}

dauncey's avatar
dauncey committed
302 303
	// Add zero padding word if odd
	//if((nWords%2)==1) assert(fElink[fHgcrocToElink[h]].writeAndIncrementPtr(0));
dauncey's avatar
dauncey committed
304
      
dauncey's avatar
dauncey committed
305 306 307 308
	uint64_t d;
	for(unsigned e(0);e<7;e++) {
	  if(fElink[e].readAndIncrementPtr(d)) a[e]=(d&0xffffffff);
	  else a[e]=0;
dauncey's avatar
dauncey committed
309

dauncey's avatar
dauncey committed
310 311 312 313 314 315
	  if(fPrintLevel>4) {
	    std::cout << "BeSlinkSim[" << fSlinkArch->slinkNumber() << "][" << fEcon << "]::processBx() "
		      << "Sending eLink " << e << " = "
		      << std::hex << a[e]
		      << std::dec << std::endl;
	  }
dauncey's avatar
dauncey committed
316 317 318
	}

      
dauncey's avatar
dauncey committed
319
      } else if(fDataFlowMethod==VariableHgcrocMap) {
dauncey's avatar
dauncey committed
320

dauncey's avatar
dauncey committed
321
	unsigned nWords(0);
dauncey's avatar
dauncey committed
322
      
dauncey's avatar
dauncey committed
323 324 325 326 327
	if(fPrintLevel>3) {
	  std::cout << "BeSlinkSim[" << fSlinkArch->slinkNumber() << "][" << fEcon << "]::processBx() "
		    << "Data flow method = variable HGCROC map, reading "
		    << nWords << " words per BX"	<< std::endl;
	}
dauncey's avatar
dauncey committed
328
	    
dauncey's avatar
dauncey committed
329
	assert(false);
dauncey's avatar
dauncey committed
330 331

      
dauncey's avatar
dauncey committed
332
      } else if(fDataFlowMethod==EventBuild) {
dauncey's avatar
dauncey committed
333
      
dauncey's avatar
dauncey committed
334 335 336 337
	// 24 words per BX for 2 parallel buffers = 960 MHz
	// 12 words per BX for 3 parallel buffers = 480 MHz
	//  8 words per BX for 4 parallel buffers = 320 MHz
	//unsigned nWords(24/(NumberOfParallelBuffers-1));
dauncey's avatar
dauncey committed
338 339


dauncey's avatar
dauncey committed
340 341 342 343 344 345
	// For one block, must be > 55 words x 18 HGCROCs/44 BX = 22.5; also more than output = 7 words/BX
	//  OR
	// For one block, must be > 39 words x 18 HGCROCs/44 BX = 15.95; also more than output = 7 words/BX
	// For seven blocks, must be > 55 words x 3 HGCROCs/44 BX = 3.75; also more than output = 1 word/BX
	//  OR
	// For seven blocks, must be > 39 words x 3 HGCROCs/44 BX = 2.66; also more than output = 1 word/BX
dauncey's avatar
dauncey committed
346

dauncey's avatar
dauncey committed
347 348
	unsigned nWords(fEconArch.fNumberOfBlocks==1?24:4);
	//unsigned nWords(fEconArch.fNumberOfBlocks==1?16:3);
dauncey's avatar
dauncey committed
349
      
dauncey's avatar
dauncey committed
350 351 352 353 354
	if(fPrintLevel>3) {
	  std::cout << "BeSlinkSim[" << fSlinkArch->slinkNumber() << "][" << fEcon << "]::processBx() "
		    << "Data flow method = event build, reading "
		    << nWords << " words per BX"	<< std::endl;
	}
dauncey's avatar
dauncey committed
355
	    
dauncey's avatar
dauncey committed
356
	for(unsigned block(0);block<fEconArch.fNumberOfBlocks;block++) {
dauncey's avatar
dauncey committed
357

dauncey's avatar
dauncey committed
358 359
	  for(unsigned b(0);b<NumberOfParallelBuffers;b++) {
	    if(b!=(fActiveInputBuffer%NumberOfParallelBuffers)) {
dauncey's avatar
dauncey committed
360

dauncey's avatar
dauncey committed
361 362 363 364 365 366
	      if(fPrintLevel>4) {
		std::cout << "BeSlinkSim[" << fSlinkArch->slinkNumber() << "][" << fEcon << "]::processBx() "
			  << "Reading HGCROC number " << fReadHgcrocNumber[b][block]
			  << " < " << fEconArch.fHgcrocNumber[block].size()
			  << ", word number " << fReadWord[b][block] << std::endl;
	      }
dauncey's avatar
dauncey committed
367
	    
dauncey's avatar
dauncey committed
368 369
	      //if(fReadHgcrocNumber[b]<fEconFile.fNumberOfHgcrocs) {
	      if(fReadHgcrocNumber[b][block]<fEconArch.fHgcrocNumber[block].size()) {
dauncey's avatar
dauncey committed
370

dauncey's avatar
dauncey committed
371 372
		for(unsigned w(0);w<nWords;w++) {
		  //assert(fReadHgcroc[b]<fEconFile.fNumberOfHgcrocs);
dauncey's avatar
dauncey committed
373
		
dauncey's avatar
dauncey committed
374 375 376
		  unsigned readHgcroc(fEconArch.fHgcrocNumber[block][fReadHgcrocNumber[b][block]]);
		  std::vector<uint32_t> &readBuffer(fFirstBuffer[b][readHgcroc]); // Convenient
		  assert(fReadWord[b][block]<readBuffer.size());
dauncey's avatar
dauncey committed
377
	      
dauncey's avatar
dauncey committed
378 379 380 381 382 383 384 385 386 387
		  if(fPrintLevel>4) {
		    std::cout << "BeSlinkSim[" << fSlinkArch->slinkNumber() << "][" << fEcon << "]::processBx() "
			      << "Copying BX word " << w << " from block " << block << ", first buffer " << b
			      << ", HGCROC " << readHgcroc << ", word " << fReadWord[b][block]
			      << " of " << readBuffer.size() << " = "
			      << std::hex << readBuffer[fReadWord[b][block]]
			      << std::dec << std::endl;
		  }

		  // Write word to FIFO
dauncey's avatar
dauncey committed
388
		
dauncey's avatar
dauncey committed
389
		  assert(fEventBuffer[0][block].writeAndIncrementPtr(readBuffer[fReadWord[b][block]]));
dauncey's avatar
dauncey committed
390
		
dauncey's avatar
dauncey committed
391
		  // Check if completed all words of this HGCROC
dauncey's avatar
dauncey committed
392
		
dauncey's avatar
dauncey committed
393 394 395 396
		  fReadWord[b][block]++;
		  if(fReadWord[b][block]==readBuffer.size()) {
		    fReadWord[b][block]=0;
		    fReadHgcrocNumber[b][block]++;
dauncey's avatar
dauncey committed
397
		  
dauncey's avatar
dauncey committed
398
		    // Check if completed all HGCROCs
dauncey's avatar
dauncey committed
399
		  
dauncey's avatar
dauncey committed
400 401
		    if(fReadHgcrocNumber[b][block]==fEconArch.fHgcrocNumber[block].size()) w=nWords;
		  }
dauncey's avatar
dauncey committed
402 403 404 405
		}
	      }
	    }
	  }
dauncey's avatar
dauncey committed
406 407 408 409 410 411

	  uint64_t d;
	  for(unsigned e(0);e<fEconArch.fElinkNumber[block].size();e++) {
	    if(fEventBuffer[0][block].readAndIncrementPtr(d)) a[fEconArch.fElinkNumber[block][e]]=(d&0xffffffff);
	    else a[fEconArch.fElinkNumber[block][e]]=0;
	  }
dauncey's avatar
dauncey committed
412 413
	}

dauncey's avatar
dauncey committed
414 415 416 417 418 419 420
	if(fPrintLevel>4) {
	  for(unsigned e(0);e<7;e++) {
	    std::cout << "BeSlinkSim[" << fSlinkArch->slinkNumber() << "][" << fEcon << "]::processBx() "
		      << "Sending eLink " << e << " = "
		      << std::hex << a[e]
		      << std::dec << std::endl;
	  }
dauncey's avatar
dauncey committed
421
	}
dauncey's avatar
dauncey committed
422 423 424
        
      } else {
	assert(false);
dauncey's avatar
dauncey committed
425
      }
dauncey's avatar
dauncey committed
426 427
#endif
    }
dauncey's avatar
dauncey committed
428

dauncey's avatar
dauncey committed
429 430 431 432 433 434 435 436 437 438 439 440 441 442 443
    bool throttle() {
      if(fThrottleActive) return false;
    
      for(unsigned e(0);e<fSlinkArch->numberOfEcons();e++) {
	const EconArch &econArch(fSlinkArch->econArch(e));
	for(unsigned b(0);b<econArch.numberOfBlocks();b++) {
	  if(fEventBuffer[e][b].used()>=fBufferLimit) {
	    if(fPrintLevel>5) {
	      std::cout << "BeSlinkSim[" << fSlinkArch->slinkNumber() << "]::throttle() "
			<< "Applying throttle" 
			<< std::endl;
	    }
	    fThrottleActive=true;
	    return true;
	  }
dauncey's avatar
dauncey committed
444 445
	}
      }
dauncey's avatar
dauncey committed
446 447

      return false;
dauncey's avatar
dauncey committed
448 449
    }

dauncey's avatar
dauncey committed
450 451 452 453 454 455 456 457
    bool unThrottle() {
      if(!fThrottleActive) return false;
    
      for(unsigned e(0);e<fSlinkArch->numberOfEcons();e++) {
	const EconArch &econArch(fSlinkArch->econArch(e));
	for(unsigned b(0);b<econArch.numberOfBlocks();b++) {
	  if(fEventBuffer[e][b].used()>=fBufferLimit) {
	    return false;
dauncey's avatar
dauncey committed
458 459 460
	  }
	}
      }
dauncey's avatar
dauncey committed
461 462 463 464 465 466 467 468 469
    
      if(fPrintLevel>5) {
	std::cout << "BeSlinkSim[" << fSlinkArch->slinkNumber() << "]::throttle() "
		  << "Removing throttle" 
		  << std::endl;
      }
    
      fThrottleActive=false;
      return true;
dauncey's avatar
dauncey committed
470 471
    }

dauncey's avatar
dauncey committed
472 473 474
    unsigned numberOfSlinkWords() const {
      return fNumberOfSlinkWords;
    }
dauncey's avatar
dauncey committed
475
  
dauncey's avatar
dauncey committed
476 477 478 479
    const std::pair<uint128_t,bool>& slinkWord(unsigned n) const {
      assert(n<fNumberOfSlinkWords);
      return fSlinkWord[n];
    }
dauncey's avatar
dauncey committed
480

dauncey's avatar
dauncey committed
481 482 483
    unsigned slinkNumber() const {
      return fSlinkArch->slinkNumber();
    }
dauncey's avatar
dauncey committed
484

dauncey's avatar
dauncey committed
485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500
  public:
    static unsigned fPrintLevel;
    /*
      static DataRandomMethod fDataRandomMethod;
      static DataFormatMethod fDataFormatMethod;
      static DataFlowMethod fDataFlowMethod;
      static unsigned fFormatBreakEven;

      double fTotalNum;
      double fTotalMean;
      double fTotalWords;
    */
  protected:
  private:
    //unsigned fSlink;
    const SlinkArch *fSlinkArch;
dauncey's avatar
dauncey committed
501
  
dauncey's avatar
dauncey committed
502
    SlinkElinkData fSlinkElinkData;
dauncey's avatar
dauncey committed
503
  
dauncey's avatar
dauncey committed
504 505
    //unsigned fEcon;
    EconFile fEconFile;
dauncey's avatar
dauncey committed
506

dauncey's avatar
dauncey committed
507
    EconArch fEconArch;
dauncey's avatar
dauncey committed
508

dauncey's avatar
dauncey committed
509 510
    bool fL1AcceptBoe;
    bool fL1AcceptEoe;
511

dauncey's avatar
dauncey committed
512 513
    //unsigned fNumberOfHgcrocs;
    //double fHgcrocMean[18];
dauncey's avatar
dauncey committed
514
  
dauncey's avatar
dauncey committed
515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534
    //unsigned fHgcrocToElink[18];
    //CircularBufferUR32<1> fElink[7];
    CircularBufferUR32<16> fEventBuffer[Dimensions::MaxNumberOfEconsPerSlink][Dimensions::MaxNumberOfBlocksPerEcon];
    //PartitionedBuffer<7,16> fPartitionedBuffer[5];

    //unsigned fNumberOfChannels[18];
    //unsigned fNumberOfWords[18];

    bool fThrottleActive;
    bool fEventActive;
    bool fExceededBuffer;
    unsigned fEconRead;
    unsigned fBlockRead;
    unsigned fArrayWrite;
    uint32_t fArrayWord[4];
    unsigned fNumberOfEventWords;
    unsigned fTotalNumberOfEventWords;

    BlockCheck fBlockCheck[Dimensions::MaxNumberOfEconsPerSlink][Dimensions::MaxNumberOfBlocksPerEcon];
    std::pair<bool,uint32_t> fBlockPair[Dimensions::MaxNumberOfEconsPerSlink][Dimensions::MaxNumberOfBlocksPerEcon];
dauncey's avatar
dauncey committed
535 536

  
dauncey's avatar
dauncey committed
537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562
    //unsigned fReadHgcroc[NumberOfParallelBuffers];
    //unsigned fReadWord[NumberOfParallelBuffers];
    //unsigned fReadHgcrocNumber[NumberOfParallelBuffers][20];
    //unsigned fReadWord[NumberOfParallelBuffers][20];
    unsigned fWriteElink;

    //unsigned fNumberOfBlocks;
    std::vector<unsigned> fHgcrocNumber[7];
    std::vector<unsigned> fElinkNumber[7];

    unsigned fBufferLimit;
    unsigned fActiveInputBuffer;
    //std::vector<uint32_t> fFirstBuffer[NumberOfParallelBuffers][18];

    CircularBufferUR<1> fSlinkBoeCb;
    unsigned fNumberOfSlinkWords;
    std::pair<uint128_t,bool> fSlinkWord[3];
  };

  unsigned BeSlinkSim::fPrintLevel(1);
  /*
    BeSlinkSim::DataRandomMethod BeSlinkSim::fDataRandomMethod(BeSlinkSim::Binomial);
    BeSlinkSim::DataFormatMethod BeSlinkSim::fDataFormatMethod(BeSlinkSim::FixedChannelBitmap);
    BeSlinkSim::DataFlowMethod BeSlinkSim::fDataFlowMethod(BeSlinkSim::FixedHgcrocMap);
    unsigned BeSlinkSim::fFormatBreakEven(0);
  */
dauncey's avatar
dauncey committed
563
#endif