Commit 2e079021 authored by dauncey's avatar dauncey

Including ECON architectures

parent eea2c1cc
#ifndef BeSlinkAna_HH
#define BeSlinkAna_HH
#include <iostream>
#include <iomanip>
#include <cassert>
#include "TH1D.h"
#include "TH2D.h"
#include "TH1I.h"
#include "Buffering/BeSlinkSim.hh"
class BeSlinkAna {
public:
BeSlinkAna() {
}
void boj(const BeSlinkSim &b, unsigned nHistory=100000) {
fBeSlinkSim=&b;
std::ostringstream sout;
sout << "BeSlinkAna" << std::setw(2) << std::setfill('0')
<< fBeSlinkSim->fSlink;
std::string sHgcroc[18]={"00","01","02","03","04","05","06","07","08",
"09","10","11","12","13","14","15","16","17"};
hBitmapWordsVsChannels=new TH1I((sout.str()+"BitmapWordsVsChannels").c_str(),
";Number of channels per HGCROC packet;Number of words per HGCROC packet",73,-0.5,72.5);
hLabelsWordsVsChannels=new TH1I((sout.str()+"LabelsWordsVsChannels").c_str(),
";Number of channels per HGCROC packet;Number of words per HGCROC packet",73,-0.5,72.5);
hTotalChannels=new TH1D((sout.str()+"TotalChannels").c_str(),
";ECON total number of channels",1300,0,1300);
hTotalWords=new TH1D((sout.str()+"TotalWords").c_str(),
";ECON total number of words",1000,0,1000);
for(unsigned block(0);block<1;block++) {
hBlockTotalChannels[block]=new TH1D((sout.str()+"Block"+sHgcroc[block]+"TotalChannels").c_str(),
";Block total number of channels",1300,0,1300);
hBlockTotalWords[block]=new TH1D((sout.str()+"Block"+sHgcroc[block]+"TotalWords").c_str(),
";Block total number of words",1000,0,1000);
hEventBufferUsed[block]=new TH1D((sout.str()+"Block"+sHgcroc[block]+"EventBufferUsed").c_str(),
";Number of event buffer words used",50000,0,50000);
hEventBufferUsedHistory[block]=new TH1I((sout.str()+"Block"+sHgcroc[block]+"EventBufferUsedHistory").c_str(),
";BX;Number of event buffer words used",nHistory,0,nHistory);
}
for(unsigned h(0);h<18;h++) {
hChannels[h]=new TH1D((sout.str()+"Hgcroc"+sHgcroc[h]+"Channels").c_str(),
";Number of channels per HGCROC packet",73,0,73);
hWords[h]=new TH1D((sout.str()+"Hgcroc"+sHgcroc[h]+"Words").c_str(),
";Number of words per HGCROC packet",60,0,60);
hWordsVsChannels[h]=new TH2D((sout.str()+"Hgcroc"+sHgcroc[h]+"WordsVsChannels").c_str(),
";Number of channels per HGCROC packet;Number of words per HGCROC packet",73,-0.5,72.5,60,-0.5,59.5);
}
}
void analyseL1Accept(uint64_t bx) {
/*
unsigned nChannels(0),nWords(0);
for(unsigned h(0);h<18;h++) {
hChannels[h]->Fill(fEconSim->numberOfChannels(h));
hWords[h]->Fill(fEconSim->numberOfWords(h));
hWordsVsChannels[h]->Fill(fEconSim->numberOfChannels(h),fEconSim->numberOfWords(h));
nChannels+=fEconSim->numberOfChannels(h);
nWords+=fEconSim->numberOfWords(h);
}
hTotalChannels->Fill(nChannels);
hTotalWords->Fill(nWords);
for(unsigned block(0);block<fEconSim->fEconArch.fNumberOfBlocks;block++) {
unsigned nBlockChannels(0),nBlockWords(0);
for(unsigned i(0);i<fEconSim->fEconArch.fHgcrocNumber[block].size();i++) {
unsigned h(fEconSim->fEconArch.fHgcrocNumber[block][i]);
nBlockChannels+=fEconSim->numberOfChannels(h);
nBlockWords+=fEconSim->numberOfWords(h);
}
hBlockTotalChannels[block]->Fill(nBlockChannels);
hBlockTotalWords[block]->Fill(nBlockWords);
}
*/
}
void analyseBx(uint64_t bx) {
/*
for(unsigned block(0);block<fEconSim->fEconArch.fNumberOfBlocks;block++) {
hEventBufferUsed[block]->Fill(fEconSim->fEventBuffer[block].used());
hEventBufferUsedHistory[block]->Fill(bx,fEconSim->fEventBuffer[block].used());
}
*/
}
void eoj() {
}
private:
const BeSlinkSim *fBeSlinkSim;
TH1I *hBitmapWordsVsChannels;
TH1I *hLabelsWordsVsChannels;
TH1D *hMeans;
TH1D *hChannels[18];
TH1D *hWords[18];
TH2D *hWordsVsChannels[18];
TH1D *hTotalChannels;
TH1D *hTotalWords;
TH1D *hBlockTotalChannels[7];
TH1D *hBlockTotalWords[7];
TH1D *hEventBufferUsed[7];
TH1I *hEventBufferUsedHistory[7];
};
#endif
#ifndef BeSlinkSim_HH
#define BeSlinkSim_HH
#include <iostream>
#include <iomanip>
#include <cassert>
#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(unsigned s, 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;
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));
}
}
/*
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 << "BeSlinkSim::ctor() "
<< "Number of blocks = " << fNumberOfBlocks << std::endl;
for(unsigned block(0);block<fNumberOfBlocks;block++) {
std::cout << " Block " << block << ", HGCROCs =";
for(unsigned h(0);h<fHgcrocNumber[block].size();h++) {
std::cout << " " << fHgcrocNumber[block][h];
}
std::cout << ", Elinks =";
for(unsigned e(0);e<fElinkNumber[block].size();e++) {
std::cout << " " << fElinkNumber[block][e];
}
std::cout << std::endl;
}
}
*/
//fHgcrocToElink[h]=(h%7);
}
//void slinkNumber(unsigned s) {
// fSlink=s;
//}
void processL1Accept(uint64_t bx, uint64_t l1a) {
uint64_t d[2];
SlinkBoe sboe(0xce00,bx&0xffffffff,l1a&0xffffffff,0xab);
sboe.words(d);
assert(cbBoe.writeAndIncrementPtr(d[0]));
assert(cbBoe.writeAndIncrementPtr(d[1]));
if(fPrintLevel>4) {
std::cout << "BeSlinkSim[" << fSlinkArch->slinkNumber() << "]::processL1Accept(" << bx << "," << l1a << ") "
<< "Writing Slink BOE" << std::endl;
sboe.print();
}
}
void processBx(const SlinkElinkData &d) {
for(unsigned e(0);e<fSlinkArch->numberOfEcons();e++) processEconBx(e,d.fData[e]);
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) {
if(!cbBoe.empty()) {
assert(cbBoe.readAndIncrementPtr(w.first));
assert(cbBoe.readAndIncrementPtr(w.second));
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;
} 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;
} else {
for(unsigned i(0);i<4 && fEconRead<fSlinkArch->numberOfEcons() && fArrayWrite<4;i++) {
if(!fEventBuffer[fEconRead][fBlockRead].empty()) {
uint64_t d;
assert(fEventBuffer[fEconRead][fBlockRead].readAndIncrementPtr(d));
fArrayWord[fArrayWrite]=(d&0xffffffff);
fArrayWrite++;
if(fPrintLevel>5) {
std::cout << "BeSlinkSim[" << fSlinkArch->slinkNumber() << "]::processBx() "
<< "Read buffer word = 0x" << std::hex << fArrayWord[fArrayWrite-1]
<< std::dec << std::endl;
}
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 {
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<uint128_t,bool>(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) {
// Switch for different dataflow methods
for(unsigned w(0);w<Dimensions::MaxNumberOfElinksPerEcon;w++) {
if(d[w]!=0) assert(fEventBuffer[ec][fSlinkArch->econArch(ec).numberOfBlocks()==1?0:w].writeAndIncrementPtr(d[w]));
}
return;
uint32_t a[7];
// 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 << "BeSlinkSim[" << fSlinkArch->slinkNumber() << "][" << fEcon << "]::processBx() "
<< "Data flow method = fixed HGCROC map, reading "
<< nWords << " words per BX" << std::endl;
}
for(unsigned b(0);b<NumberOfParallelBuffers;b++) {
if(b!=(fActiveInputBuffer%NumberOfParallelBuffers)) {
for(unsigned e(0);e<7;e++) {
if(fReadHgcroc[b]<fEconFile.fNumberOfHgcrocs) {
for(unsigned w(0);w<nWords;w++) {
assert(fReadHgcroc[b]<fEconFile.fNumberOfHgcrocs);
assert(fReadWord[b]<fFirstBuffer[b][fReadHgcroc[b]].size());
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]]));
}
}
}
}
}
// 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;
}
}
#endif
} 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);block<fEconArch.fNumberOfBlocks;block++) {
for(unsigned b(0);b<NumberOfParallelBuffers;b++) {
if(b!=(fActiveInputBuffer%NumberOfParallelBuffers)) {
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;
}
//if(fReadHgcrocNumber[b]<fEconFile.fNumberOfHgcrocs) {
if(fReadHgcrocNumber[b][block]<fEconArch.fHgcrocNumber[block].size()) {
for(unsigned w(0);w<nWords;w++) {
//assert(fReadHgcroc[b]<fEconFile.fNumberOfHgcrocs);
unsigned readHgcroc(fEconArch.fHgcrocNumber[block][fReadHgcrocNumber[b][block]]);
std::vector<uint32_t> &readBuffer(fFirstBuffer[b][readHgcroc]); // Convenient
assert(fReadWord[b][block]<readBuffer.size());
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
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);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;
}
}
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;
}
}
} else {
assert(false);
}
}
unsigned numberOfSlinkWords() const {
return fNumberOfSlinkWords;
}
const std::pair<uint128_t,bool>& slinkWord(unsigned n) const {
assert(n<fNumberOfSlinkWords);
return fSlinkWord[n];
}
unsigned econSlink() const {
return fSlink;
}
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;
unsigned fEcon;
EconFile fEconFile;
EconArch fEconArch;
//unsigned fNumberOfHgcrocs;
//double fHgcrocMean[18];
unsigned fHgcrocToElink[18];
CircularBuffer<1> fElink[7];
CircularBuffer<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;
BlockCheck fBlockCheck[Dimensions::MaxNumberOfEconsPerSlink][Dimensions::MaxNumberOfBlocksPerEcon];
//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 fActiveInputBuffer;
std::vector<uint32_t> fFirstBuffer[NumberOfParallelBuffers][18];
CircularBuffer<1> cbBoe;
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);
#endif