#ifndef EconSim_HH #define EconSim_HH #include #include #include #include "Buffering/HgcrocBoe.hh" #include "Buffering/EconArch.hh" #include "Buffering/EconFile.hh" class EconSim { friend class EconAna; public: enum { NumberOfParallelBuffers=2 }; enum DataRandomMethod { NotRandom, Binomial, Flat, Mixed }; enum DataFormatMethod { FixedChannelBitmap, FixedChannelLabels, FixedMixture, VariableMixture }; enum DataFlowMethod { FixedHgcrocMap, VariableHgcrocMap, EventBuild }; //EconSim(unsigned e, unsigned h=18, unsigned m=0) : fEcon(e) { EconSim() { fSlink=0; if(fPrintLevel>0) { std::cout << "EconSim::ctor() " << "Entered" << std::endl; } setFormatBreakEven(); fActiveInputBuffer=0; fWriteElink=0; /* if(false) { fNumberOfBlocks=1; for(unsigned h(0);h<18;h++) { fHgcrocNumber[0].push_back(h); } for(unsigned e(0);e<7;e++) { fElinkNumber[0].push_back(e); } } else { fNumberOfBlocks=7; for(unsigned h(0);h<18;h++) { fHgcrocNumber[h%7].push_back(h); } for(unsigned e(0);e<7;e++) { fElinkNumber[e].push_back(e); } } if(fPrintLevel>1) { std::cout << "EconSim::ctor() " << "Number of blocks = " << fNumberOfBlocks << std::endl; for(unsigned block(0);block2) { std::cout << "EconSim::ctor() " << "First buffer " << b << ", block " << block << ", zeroing HGCROC number " << fReadHgcrocNumber[b][block] << ", word number " << fReadWord[b][block] << std::endl; } } for(unsigned h(0);hfNumberOfHgcrocs<=18); setFormatBreakEven(); fActiveInputBuffer=0; fWriteElink=0; // Random values for now /* for(unsigned h(0);hfHgcrocMean[h]=0.5*h+1; fHgcrocToElink[h]=(h%7); } */ for(unsigned h(0);h<18;h++) { fFirstBuffer[0][h].resize(channelsToWords(72,false)); fFirstBuffer[1][h].resize(channelsToWords(72,false)); fEconFile->fHgcrocMean[h]=0.0; } for(unsigned h(0);hfNumberOfHgcrocs;h++) { if(m==0) { fEconFile->fHgcrocMean[h]=10; if(h<14) fEconFile->fHgcrocMean[h]=20; if(h< 7) fEconFile->fHgcrocMean[h]=35; if(h==6) fEconFile->fHgcrocMean[h]=40; } if(m==1) { fEconFile->fHgcrocMean[h]=5; if(h<14) fEconFile->fHgcrocMean[h]=10; if(h< 7) fEconFile->fHgcrocMean[h]=15; } if(m==2) { fEconFile->fHgcrocMean[h]=3; if(h<14) fEconFile->fHgcrocMean[h]=7; if(h< 7) fEconFile->fHgcrocMean[h]=10; } if(m==3) { fEconFile->fHgcrocMean[h]=2; if(h<14) fEconFile->fHgcrocMean[h]=4; if(h< 7) fEconFile->fHgcrocMean[h]=5; } if(m>=4) { fEconFile->fHgcrocMean[h]=1; if(h<14) fEconFile->fHgcrocMean[h]=2; if(h< 7) fEconFile->fHgcrocMean[h]=3; } fHgcrocToElink[h]=(h%7); } std::cout << std::endl << "Econ::ctor() number of HGCROCs = " << fEconFile->fNumberOfHgcrocs << std::endl; double elinkNum[7]={0,0,0,0,0,0,0}; double elinkMean[7]={0,0,0,0,0,0,0}; for(unsigned h(0);hfNumberOfHgcrocs;h++) { std::cout << " HGCROC " << std::setw(2) << h << ", average number of channels = " << fEconFile->fHgcrocMean[h] << ", assigned to Elink = " << fHgcrocToElink[h] << std::endl; elinkNum[fHgcrocToElink[h]]++; elinkMean[fHgcrocToElink[h]]+=fEconFile->fHgcrocMean[h]; } /* fTotalNum=0; fTotalMean=0; for(unsigned e(0);e<7;e++) { fTotalNum+=elinkNum[e]; fTotalMean+=elinkMean[e]; std::cout << " Elink " << e << ", number of HGCROCs = " << elinkNum[e] << ", total average number of channels = " << elinkMean[e] << ", average number of 32-bit words = " << 3*elinkNum[e]+0.5*elinkMean[e] << std::endl; } fTotalWords=3*fTotalNum+0.5*fTotalMean; std::cout << " ECON, total average number of channels = " << fTotalMean << ", average number of 32-bit words = " << fTotalWords << std::endl; */ } #endif void slinkNumber(unsigned s) { fSlink=s; } void econNumber(unsigned e) { fEcon=e; } void econFile(const EconFile *e) { fEconFile=e; } const EconFile& econFile() const { return *fEconFile; } double mean(unsigned h) { assert(h<18); return fEconFile->fHgcrocMean[h]; } void processZs(uint8_t bx, uint8_t l1a) { if(fPrintLevel>3) { std::cout << "EconSim[" << fSlink << "][" << fEcon << "]::processZs(" << unsigned(bx) << "," << unsigned(l1a) << ") " << "Entered" << std::endl; } TRandom &random(Random::random()); bool binomialOrFlat; for(unsigned h(0);hfNumberOfHgcrocs;h++) { // Switch for different random methods if(fDataRandomMethod==NotRandom) { fNumberOfChannels[h]=unsigned(fEconFile->fHgcrocMean[h]+0.5); } else if(fDataRandomMethod==Binomial) { fNumberOfChannels[h]=random.Binomial(72,fEconFile->fHgcrocMean[h]/72.0); } else if(fDataRandomMethod==Flat) { int im(fEconFile->fHgcrocMean[h]+0.5); if(im>36) { fNumberOfChannels[h]=2*im-72+random.Integer(145-2*im); } else { fNumberOfChannels[h]=random.Integer(2*im+1); } } else if(fDataRandomMethod==Mixed) { binomialOrFlat=(random.Integer(2)==0); if(binomialOrFlat) { fNumberOfChannels[h]=random.Binomial(72,fEconFile->fHgcrocMean[h]/72.0); } else { int im(fEconFile->fHgcrocMean[h]+0.5); if(im>36) { fNumberOfChannels[h]=2*im-72+random.Integer(145-2*im); } else { fNumberOfChannels[h]=random.Integer(2*im+1); } } } else { assert(false); } // Switch for different format methods if(fDataFormatMethod==FixedChannelBitmap) { fNumberOfWords[h]=channelsToWords(fNumberOfChannels[h],true); } else if(fDataFormatMethod==FixedChannelLabels) { fNumberOfWords[h]=channelsToWords(fNumberOfChannels[h],false); } else if(fDataFormatMethod==FixedMixture) { fNumberOfWords[h]=channelsToWords(fNumberOfChannels[h],fEconFile->fHgcrocMean[h]>fFormatBreakEven); } else if(fDataFormatMethod==VariableMixture) { fNumberOfWords[h]=channelsToWords(fNumberOfChannels[h],fNumberOfChannels[h]>fFormatBreakEven); } else { assert(false); } if(fPrintLevel>4) { std::cout << "EconSim[" << fSlink << "][" << fEcon << "]::processZs(" << unsigned(bx) << "," << unsigned(l1a) << ") " << "Hgcroc " << h << ", number of channels = " << fNumberOfChannels[h] << ", words = " << fNumberOfWords[h] << std::endl; } // Create HGCROC header HgcrocBoe hboe(fEcon,h,bx,l1a,fNumberOfWords[h]); if(fPrintLevel>4) { std::cout << "EconSim[" << fSlink << "][" << fEcon << "]::processZs(" << unsigned(bx) << "," << unsigned(l1a) << ") " << "Hgcroc " << h << " BOE" << std::endl; hboe.print(); } // Write data into selected buffer assert((fActiveInputBuffer&0xff)==l1a); fFirstBuffer[fActiveInputBuffer%NumberOfParallelBuffers][h].resize(fNumberOfWords[h]); fFirstBuffer[fActiveInputBuffer%NumberOfParallelBuffers][h][0]=hboe.word(); for(unsigned i(1);ifNumberOfBlocks;block++) { fReadHgcrocNumber[fActiveInputBuffer%NumberOfParallelBuffers][block]=0; fReadWord[fActiveInputBuffer%NumberOfParallelBuffers][block]=0; } fActiveInputBuffer++; } void processBx(uint32_t *a) { // Switch for different dataflow methods if(fDataFlowMethod==FixedHgcrocMap) { #ifdef NOT_YET // 4 words per BX for 7 eLinks unsigned nWords(4); if(fPrintLevel>3) { std::cout << "EconSim[" << fSlink << "][" << fEcon << "]::processBx() " << "Data flow method = fixed HGCROC map, reading " << nWords << " words per BX" << std::endl; } for(unsigned b(0);bfNumberOfHgcrocs) { for(unsigned w(0);wfNumberOfHgcrocs); assert(fReadWord[b]4) { std::cout << "EconSim[" << fSlink << "][" << 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 << "EconSim[" << fSlink << "][" << fEcon << "]::processBx() " << "Sending eLink " << e << " = " << std::hex << a[e] << std::dec << std::endl; } } #endif } else if(fDataFlowMethod==VariableHgcrocMap) { unsigned nWords(0); if(fPrintLevel>3) { std::cout << "EconSim[" << fSlink << "][" << 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 << "EconSim[" << fSlink << "][" << fEcon << "]::processBx() " << "Data flow method = event build, reading " << nWords << " words per BX" << std::endl; } for(unsigned block(0);blockfNumberOfBlocks;block++) { for(unsigned b(0);b4) { std::cout << "EconSim[" << fSlink << "][" << fEcon << "]::processBx() " << "Reading HGCROC number " << fReadHgcrocNumber[b][block] << " < " << fEconArch->fHgcrocNumber[block].size() << ", word number " << fReadWord[b][block] << std::endl; } //if(fReadHgcrocNumber[b]fNumberOfHgcrocs) { if(fReadHgcrocNumber[b][block]fHgcrocNumber[block].size()) { for(unsigned w(0);wfNumberOfHgcrocs); unsigned readHgcroc(fEconArch->fHgcrocNumber[block][fReadHgcrocNumber[b][block]]); std::vector &readBuffer(fFirstBuffer[b][readHgcroc]); // Convenient assert(fReadWord[b][block]4) { std::cout << "EconSim[" << fSlink << "][" << 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[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);efElinkNumber[block].size();e++) { if(fEventBuffer[block].readAndIncrementPtr(d)) a[fEconArch->fElinkNumber[block][e]]=(d&0xffffffff); else a[fEconArch->fElinkNumber[block][e]]=0; } } if(fPrintLevel>4) { for(unsigned e(0);e<7;e++) { std::cout << "EconSim[" << fSlink << "][" << fEcon << "]::processBx() " << "Sending eLink " << e << " = " << std::hex << a[e] << std::dec << std::endl; } } } else { assert(false); } } unsigned numberOfHgcrocs() const { return fEconFile->fNumberOfHgcrocs; } unsigned space(unsigned elink) { assert(elink<7); return fElink[elink].space(); } unsigned used(unsigned elink) { assert(elink<7); return fElink[elink].used(); } unsigned numberOfChannels(unsigned h) const { assert(h<18); return fNumberOfChannels[h]; } unsigned numberOfWords(unsigned h) const { assert(h<18); return fNumberOfWords[h]; } void reset() { for(unsigned e(0);e<7;e++) { fElink[e].reset(); } } static unsigned channelsToWords(unsigned c, bool map) { if(map) return 3+(c+1)/2; else return 1+3*(c+1)/4; } /* unsigned channelsToWords(unsigned c, double m) const { if(fDataFormatMethod==FixedChannelBitmap) { return channelsToWords(c,true); } else if(fDataFormatMethod==FixedChannelLabels) { return channelsToWords(c,false); } else if(fDataFormatMethod==FixedMixture) { return channelsToWords(c,m>fFormatBreakEven); } else if(fDataFormatMethod==VariableMixture) { return channelsToWords(c,c>fFormatBreakEven); } else { assert(false); } return -1; } */ static void setFormatBreakEven() { if(fFormatBreakEven==0) { if(fPrintLevel>1) { std::cout << "EconSim::setFormatBreakEven() " << "Entered" << std::endl; } unsigned wMap,wLabel; for(unsigned c(0);c<72;c++) { wMap=channelsToWords(c,true); wLabel=channelsToWords(c,false); if(fPrintLevel>1) { std::cout << "EconSim::setFormatBreakEven() " << "Channels = " << c << ", map words = " << wMap << ", label words = " << wLabel << std::endl; } if(wLabel<=wMap) fFormatBreakEven=c; else break; } if(fPrintLevel>0) { std::cout << "EconSim::setFormatBreakEven() " << "Break-even channel number = " << fFormatBreakEven << std::endl; } } } unsigned econNumber() const { return fEcon; } unsigned econSlink() const { return fSlink; } const EconArch& econArch() const { return *fEconArch; } 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; unsigned fEcon; const EconFile *fEconFile; const EconArch *fEconArch; //unsigned fNumberOfHgcrocs; //double fHgcrocMean[18]; //unsigned fHgcrocToElink[18]; CircularBuffer<1> fElink[7]; CircularBuffer<16> fEventBuffer[7]; unsigned fNumberOfChannels[18]; unsigned fNumberOfWords[18]; //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 fActiveInputBuffer; std::vector fFirstBuffer[NumberOfParallelBuffers][18]; }; unsigned EconSim::fPrintLevel(1); EconSim::DataRandomMethod EconSim::fDataRandomMethod(EconSim::Binomial); EconSim::DataFormatMethod EconSim::fDataFormatMethod(EconSim::FixedChannelBitmap); EconSim::DataFlowMethod EconSim::fDataFlowMethod(EconSim::FixedHgcrocMap);unsigned EconSim::fFormatBreakEven(0); #endif