#ifndef BeSlinkSim_HH #define BeSlinkSim_HH #include #include #include #include "Buffering/CircularBufferUR32.hh" #include "Buffering/SlinkBoe.hh" #include "Buffering/SlinkEoe.hh" #include "Buffering/SlinkArch.hh" class BeSlinkSim { friend class BeSlinkAna; public: /* enum { NumberOfParallelBuffers=2 }; enum DataRandomMethod { NotRandom, Binomial, Flat, Mixed }; enum DataFormatMethod { FixedChannelBitmap, FixedChannelLabels, FixedMixture, VariableMixture }; enum DataFlowMethod { FixedHgcrocMap, VariableHgcrocMap, EventBuild }; */ //BeSlinkSim(unsigned e, unsigned h=18, unsigned m=0) : fEcon(e) { BeSlinkSim() { } void boj(const SlinkArch &a) { //fSlink=a.slinkNumber(); fSlinkArch=&a; if(fPrintLevel>0) { std::cout << "BeSlinkSim[" << fSlinkArch->slinkNumber() << "]::ctor() " << "Entered" << std::endl; } fEventActive=false; fActiveInputBuffer=0; fWriteElink=0; //fBufferLimit=1048; fBufferLimit=1000000000; fArrayWrite=0; for(unsigned i(0);i<4;i++) fArrayWord[i]=0; for(unsigned e(0);enumberOfEcons();e++) { const EconArch &econArch(fSlinkArch->econArch(e)); for(unsigned b(0);bslinkNumber(),e,b,econArch.hgcrocNumber(b)); fBlockPair[e][b].first=true; } } } void processL1Accept(uint64_t bx, uint64_t l1a) { uint64_t d[2]; SlinkBoe sBoe(0xce00,bx&0xffffffff,l1a&0xffffffff,0xab); sBoe.words(d); if(fPrintLevel>4) { std::cout << "BeSlinkSim[" << fSlinkArch->slinkNumber() << "]::processL1Accept(" << bx << "," << l1a << ") " << "Saving Slink BOE" << std::endl; sBoe.print(); } assert(fSlinkBoeCb.writeAndIncrementPtr(d[0])); assert(fSlinkBoeCb.writeAndIncrementPtr(d[1])); } void processBx(uint64_t bx, const SlinkElinkData &d) { //#define OLD_METHOD #ifdef OLD_METHOD if((bx%2)==0) { fSlinkElinkData=d; } else { uint64_t word,word2; #endif for(unsigned e(0);enumberOfEcons();e++) { const EconArch &econArch(fSlinkArch->econArch(e)); for(unsigned b(0);b &elinkNumber(econArch.elinkNumber(b)); #ifdef OLD_METHOD unsigned eo(0); for(unsigned w(0);weconArch(e).numberOfBlocks()==1?0:w].writeAndIncrementPtr(word)); if(word!=0) assert(fEventBuffer[e][b].writeAndIncrementPtr(word)); } eo++; } for(unsigned w(0);weconArch(e).numberOfBlocks()==1?0:w].writeAndIncrementPtr(word)); if(word!=0) assert(fEventBuffer[e][b].writeAndIncrementPtr(word)); } eo++; } /* // DO BY ARCH PROPERLY!!! for(unsigned w(0);weconArch(e).numberOfBlocks()==1?0:w].writeAndIncrementPtr(word)); } for(unsigned w(0);weconArch(e).numberOfBlocks()==1?0:w].writeAndIncrementPtr(word)); } */ } #else uint32_t word; for(unsigned w(0);w5) { 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) { if(!fSlinkBoeCb.empty()) { assert(fSlinkBoeCb.readAndIncrementPtr(w.first)); assert(fSlinkBoeCb.readAndIncrementPtr(w.second)); fSlinkWord[fNumberOfSlinkWords]=std::pair(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; fL1AcceptBoe=true; } else { done=true; } } else { if(fEconRead==fSlinkArch->numberOfEcons()) { SlinkEoe seoe(0xce00,0x77,0xff,fNumberOfEventWords); seoe.word(w); fSlinkWord[fNumberOfSlinkWords]=std::pair(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; fL1AcceptEoe=true; fTotalNumberOfEventWords=fNumberOfEventWords; } else { if(fPrintLevel>4) { std::cout << "BeSlinkSim[" << fSlinkArch->slinkNumber() << "]::processBx() " << "Reading from ECON " << fEconRead << ", block " << fBlockRead << std::endl; } for(unsigned i(0);/*i<4 &&*/ !done && fEconReadnumberOfEcons() && fArrayWrite<4;i++) { #ifdef OLD_METHOD 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; } //fArrayWord[fArrayWrite ]=(d&0xffffffff); //fArrayWord[fArrayWrite+1]=(d>>32); //fArrayWrite+=2; #else if(!fEventBuffer[fEconRead][fBlockRead].unreadable()) { uint32_t nextWord(0); assert(fEventBuffer[fEconRead][fBlockRead].halfReadAndIncrementPtr(nextWord)); #endif if(nextWord!=0) { if(fPrintLevel>5) { std::cout << "BeSlinkSim[" << fSlinkArch->slinkNumber() << "]::processBx() " << "Read buffer words = 0x" << std::hex << nextWord << std::dec << std::endl; } fArrayWord[fArrayWrite]=nextWord; fArrayWrite++; if(fBlockCheck[fEconRead][fBlockRead].processBx(fArrayWord[fArrayWrite-1])) fBlockRead++; if(fBlockRead==fSlinkArch->econArch(fEconRead).numberOfBlocks()) { fBlockRead=0; fEconRead++; } if(fEconRead==fSlinkArch->numberOfEcons()) fArrayWrite=4; } } else { if(fPrintLevel>5) { std::cout << "BeSlinkSim[" << fSlinkArch->slinkNumber() << "]::processBx() " << "Nothing in buffer" << std::endl; } done=true; } } 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(w,false); fNumberOfSlinkWords++; fNumberOfEventWords++; if(fPrintLevel>3) { std::cout << "BeSlinkSim[" << fSlinkArch->slinkNumber() << "]::processBx() " << "Writing Slink data word = 0x" << std::hex << w.second << " " << w.first << std::dec << std::endl; } fArrayWrite=0; for(unsigned i(0);i<4;i++) fArrayWord[i]=0; } } } } } void processEconBx(unsigned ec, const uint32_t *d) { return; #ifdef NOT_YET uint32_t a[7]; // Switch for different dataflow methods if(fDataFlowMethod==FixedHgcrocMap) { // 4 words per BX for 7 eLinks unsigned nWords(4); if(fPrintLevel>3) { std::cout << "BeSlinkSim[" << fSlinkArch->slinkNumber() << "][" << fEcon << "]::processBx() " << "Data flow method = fixed HGCROC map, reading " << nWords << " words per BX" << std::endl; } for(unsigned b(0);b4) { 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]])); } } } } } // Add zero padding word if odd //if((nWords%2)==1) assert(fElink[fHgcrocToElink[h]].writeAndIncrementPtr(0)); uint64_t d; for(unsigned e(0);e<7;e++) { if(fElink[e].readAndIncrementPtr(d)) a[e]=(d&0xffffffff); else a[e]=0; if(fPrintLevel>4) { std::cout << "BeSlinkSim[" << fSlinkArch->slinkNumber() << "][" << fEcon << "]::processBx() " << "Sending eLink " << e << " = " << std::hex << a[e] << std::dec << std::endl; } } } else if(fDataFlowMethod==VariableHgcrocMap) { unsigned nWords(0); if(fPrintLevel>3) { std::cout << "BeSlinkSim[" << fSlinkArch->slinkNumber() << "][" << fEcon << "]::processBx() " << "Data flow method = variable HGCROC map, reading " << nWords << " words per BX" << std::endl; } assert(false); } else if(fDataFlowMethod==EventBuild) { // 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)); // 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 unsigned nWords(fEconArch.fNumberOfBlocks==1?24:4); //unsigned nWords(fEconArch.fNumberOfBlocks==1?16:3); if(fPrintLevel>3) { std::cout << "BeSlinkSim[" << fSlinkArch->slinkNumber() << "][" << fEcon << "]::processBx() " << "Data flow method = event build, reading " << nWords << " words per BX" << std::endl; } for(unsigned block(0);block4) { std::cout << "BeSlinkSim[" << fSlinkArch->slinkNumber() << "][" << fEcon << "]::processBx() " << "Reading HGCROC number " << fReadHgcrocNumber[b][block] << " < " << fEconArch.fHgcrocNumber[block].size() << ", word number " << fReadWord[b][block] << std::endl; } //if(fReadHgcrocNumber[b] &readBuffer(fFirstBuffer[b][readHgcroc]); // Convenient assert(fReadWord[b][block]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 assert(fEventBuffer[0][block].writeAndIncrementPtr(readBuffer[fReadWord[b][block]])); // Check if completed all words of this HGCROC fReadWord[b][block]++; if(fReadWord[b][block]==readBuffer.size()) { fReadWord[b][block]=0; fReadHgcrocNumber[b][block]++; // Check if completed all HGCROCs if(fReadHgcrocNumber[b][block]==fEconArch.fHgcrocNumber[block].size()) w=nWords; } } } } } uint64_t d; for(unsigned e(0);e4) { 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; } } } else { assert(false); } #endif } bool throttle() const { for(unsigned e(0);enumberOfEcons();e++) { const EconArch &econArch(fSlinkArch->econArch(e)); for(unsigned b(0);b=fBufferLimit) { if(fPrintLevel>5) { std::cout << "BeSlinkSim[" << fSlinkArch->slinkNumber() << "]::throttle() " << "Applying throttle" << std::endl; } return true; } } } return false; } unsigned numberOfSlinkWords() const { return fNumberOfSlinkWords; } const std::pair& slinkWord(unsigned n) const { assert(nslinkNumber(); } 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; SlinkElinkData fSlinkElinkData; //unsigned fEcon; EconFile fEconFile; EconArch fEconArch; bool fL1AcceptBoe; bool fL1AcceptEoe; //unsigned fNumberOfHgcrocs; //double fHgcrocMean[18]; //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 fEventActive; unsigned fEconRead; unsigned fBlockRead; unsigned fArrayWrite; uint32_t fArrayWord[4]; unsigned fNumberOfEventWords; unsigned fTotalNumberOfEventWords; BlockCheck fBlockCheck[Dimensions::MaxNumberOfEconsPerSlink][Dimensions::MaxNumberOfBlocksPerEcon]; std::pair fBlockPair[Dimensions::MaxNumberOfEconsPerSlink][Dimensions::MaxNumberOfBlocksPerEcon]; //unsigned fReadHgcroc[NumberOfParallelBuffers]; //unsigned fReadWord[NumberOfParallelBuffers]; //unsigned fReadHgcrocNumber[NumberOfParallelBuffers][20]; //unsigned fReadWord[NumberOfParallelBuffers][20]; unsigned fWriteElink; //unsigned fNumberOfBlocks; std::vector fHgcrocNumber[7]; std::vector fElinkNumber[7]; unsigned fBufferLimit; unsigned fActiveInputBuffer; //std::vector fFirstBuffer[NumberOfParallelBuffers][18]; CircularBufferUR<1> fSlinkBoeCb; unsigned fNumberOfSlinkWords; std::pair 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); */ #endif