Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-10-14 01:44:13

0001 #include "L1Trigger/TrackFindingTracklet/interface/VMRouterCM.h"
0002 #include "L1Trigger/TrackFindingTracklet/interface/Settings.h"
0003 #include "L1Trigger/TrackFindingTracklet/interface/Globals.h"
0004 #include "L1Trigger/TrackFindingTracklet/interface/VMStubTE.h"
0005 #include "L1Trigger/TrackFindingTracklet/interface/InputLinkMemory.h"
0006 #include "L1Trigger/TrackFindingTracklet/interface/AllStubsMemory.h"
0007 #include "L1Trigger/TrackFindingTracklet/interface/AllInnerStubsMemory.h"
0008 #include "L1Trigger/TrackFindingTracklet/interface/VMStubsMEMemory.h"
0009 #include "L1Trigger/TrackFindingTracklet/interface/VMStubsTEMemory.h"
0010 
0011 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0012 #include "FWCore/Utilities/interface/Exception.h"
0013 
0014 using namespace std;
0015 using namespace trklet;
0016 
0017 VMRouterCM::VMRouterCM(string name, Settings const& settings, Globals* global)
0018     : ProcessBase(name, settings, global), meTable_(settings), diskTable_(settings) {
0019   layerdisk_ = initLayerDisk(4);
0020 
0021   unsigned int region = name[9] - 'A';
0022   assert(region < settings_.nallstubs(layerdisk_));
0023 
0024   vmstubsMEPHI_.resize(1, nullptr);
0025 
0026   overlapbits_ = 7;
0027   nextrabits_ = overlapbits_ - (settings_.nbitsallstubs(layerdisk_) + settings_.nbitsvmme(layerdisk_));
0028 
0029   meTable_.initVMRTable(layerdisk_, TrackletLUT::VMRTableType::me, region);  //used for ME and outer TE barrel
0030 
0031   if (layerdisk_ == LayerDisk::D1 || layerdisk_ == LayerDisk::D2 || layerdisk_ == LayerDisk::D4) {
0032     diskTable_.initVMRTable(layerdisk_, TrackletLUT::VMRTableType::disk, region);  //outer disk used by D1, D2, and D4
0033   }
0034 
0035   nbitszfinebintable_ = settings_.vmrlutzbits(layerdisk_);
0036   nbitsrfinebintable_ = settings_.vmrlutrbits(layerdisk_);
0037 
0038   nvmmebins_ = settings_.NLONGVMBINS() * ((layerdisk_ >= N_LAYER) ? 2 : 1);  //number of long z/r bins in VM
0039 }
0040 
0041 void VMRouterCM::addOutput(MemoryBase* memory, string output) {
0042   if (settings_.writetrace()) {
0043     edm::LogVerbatim("Tracklet") << "In " << name_ << " adding output to " << memory->getName() << " to output "
0044                                  << output;
0045   }
0046 
0047   if (output == "allinnerstubout") {
0048     AllInnerStubsMemory* tmp = dynamic_cast<AllInnerStubsMemory*>(memory);
0049     assert(tmp != nullptr);
0050     char memtype = memory->getName().back();
0051     allinnerstubs_.emplace_back(memtype, tmp);
0052     return;
0053   }
0054 
0055   if (output.substr(0, 10) == "allstubout") {
0056     AllStubsMemory* tmp = dynamic_cast<AllStubsMemory*>(memory);
0057     allstubs_.push_back(tmp);
0058     return;
0059   }
0060 
0061   if (output.substr(0, 9) == "vmstubout") {
0062     if (memory->getName().substr(3, 2) == "TE") {
0063       VMStubsTEMemory* tmp = dynamic_cast<VMStubsTEMemory*>(memory);
0064       unsigned int iseed = output[output.size() - 1] - '0';
0065       assert(iseed < N_SEED_PROMPT);
0066 
0067       int seedindex = -1;
0068       for (unsigned int k = 0; k < vmstubsTEPHI_.size(); k++) {
0069         if (vmstubsTEPHI_[k].seednumber == iseed) {
0070           seedindex = k;
0071         }
0072       }
0073       if (seedindex == -1) {
0074         seedindex = vmstubsTEPHI_.size();
0075         vector<VMStubsTEMemory*> vectmp;
0076         VMStubsTEPHICM atmp(iseed, vectmp);
0077         vmstubsTEPHI_.push_back(atmp);
0078       }
0079       tmp->resize(settings_.NLONGVMBINS() * settings_.nvmte(1, iseed));
0080       vmstubsTEPHI_[seedindex].vmstubmem.push_back(tmp);
0081 
0082     } else if (memory->getName().substr(3, 2) == "ME") {
0083       VMStubsMEMemory* tmp = dynamic_cast<VMStubsMEMemory*>(memory);
0084       assert(tmp != nullptr);
0085       tmp->resize(nvmmebins_ * settings_.nvmme(layerdisk_));
0086       assert(vmstubsMEPHI_[0] == nullptr);
0087       vmstubsMEPHI_[0] = tmp;
0088     } else {
0089       throw cms::Exception("LogicError") << __FILE__ << " " << __LINE__ << " memory: " << memory->getName()
0090                                          << " => should never get here!";
0091     }
0092 
0093     return;
0094   }
0095 
0096   throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " Could not find output : " << output;
0097 }
0098 
0099 void VMRouterCM::addInput(MemoryBase* memory, string input) {
0100   if (settings_.writetrace()) {
0101     edm::LogVerbatim("Tracklet") << "In " << name_ << " adding input from " << memory->getName() << " to input "
0102                                  << input;
0103   }
0104   if (input == "stubin") {
0105     InputLinkMemory* tmp1 = dynamic_cast<InputLinkMemory*>(memory);
0106     assert(tmp1 != nullptr);
0107     if (tmp1 != nullptr) {
0108       stubinputs_.push_back(tmp1);
0109     }
0110     return;
0111   }
0112   throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " Could not find input : " << input;
0113 }
0114 
0115 void VMRouterCM::execute(unsigned int) {
0116   unsigned int allStubCounter = 0;
0117 
0118   //bool print = getName() == "VMR_D1PHIB" && iSector == 3;
0119   //print = false;
0120 
0121   //Loop over the input stubs
0122   for (auto& stubinput : stubinputs_) {
0123     for (unsigned int i = 0; i < stubinput->nStubs(); i++) {
0124       if (allStubCounter > settings_.maxStep("VMR"))
0125         continue;
0126       if (allStubCounter >= (1 << N_BITSMEMADDRESS))
0127         continue;
0128 
0129       Stub* stub = stubinput->getStub(i);
0130 
0131       //Note - below information is not part of the stub, but rather from which input memory
0132       //we are reading
0133       bool negdisk = (stub->disk().value() < 0);
0134 
0135       //use &127 to make sure we fit into the number of bits -
0136       //though we should have protected against overflows above
0137       FPGAWord allStubIndex(allStubCounter & ((1 << N_BITSMEMADDRESS) - 1), N_BITSMEMADDRESS, true, __LINE__, __FILE__);
0138 
0139       //TODO - should not be needed - but need to migrate some other pieces of code before removing
0140       stub->setAllStubIndex(allStubCounter);
0141       //TODO - should not be needed - but need to migrate some other pieces of code before removing
0142       stub->l1tstub()->setAllStubIndex(allStubCounter);
0143 
0144       allStubCounter++;
0145 
0146       for (auto& allstub : allstubs_) {
0147         allstub->addStub(stub);
0148         if (settings_.debugTracklet()) {
0149           edm::LogVerbatim("Tracklet") << getName() << " adding stub to " << allstub->getName();
0150         }
0151       }
0152 
0153       FPGAWord iphi = stub->phicorr();
0154       unsigned int iphipos = iphi.bits(iphi.nbits() - (settings_.nbitsallstubs(layerdisk_) + N_PHIBITS), N_PHIBITS);
0155 
0156       unsigned int phicutmax = 4;
0157       unsigned int phicutmin = 4;
0158 
0159       if (layerdisk_ != 0) {
0160         phicutmax = 6;
0161         phicutmin = 2;
0162       }
0163 
0164       //Fill inner allstubs memories - in HLS this is the same write to multiple memories
0165       for (auto& allstub : allinnerstubs_) {
0166         char memtype = allstub.first;
0167         if (memtype == 'R' && iphipos < phicutmax)
0168           continue;
0169         if (memtype == 'L' && iphipos >= phicutmin)
0170           continue;
0171         if (memtype == 'A' && iphipos < 4)
0172           continue;
0173         if (memtype == 'B' && iphipos >= 4)
0174           continue;
0175         if (memtype == 'E' && iphipos >= 4)
0176           continue;
0177         if (memtype == 'F' && iphipos < 4)
0178           continue;
0179         if (memtype == 'C' && iphipos >= 4)
0180           continue;
0181         if (memtype == 'D' && iphipos < 4)
0182           continue;
0183 
0184         int absz = std::abs(stub->z().value());
0185         if (layerdisk_ == LayerDisk::L2 && absz < VMROUTERCUTZL2 / settings_.kz(layerdisk_))
0186           continue;
0187         if ((layerdisk_ == LayerDisk::L3 || layerdisk_ == LayerDisk::L5) &&
0188             absz > VMROUTERCUTZL1L3L5 / settings_.kz(layerdisk_))
0189           continue;
0190         if ((layerdisk_ == LayerDisk::D1 || layerdisk_ == LayerDisk::D3) &&
0191             stub->r().value() > VMROUTERCUTRD1D3 / settings_.kr())
0192           continue;
0193         if ((layerdisk_ == LayerDisk::D1 || layerdisk_ == LayerDisk::D3) && stub->r().value() < 2 * int(N_DSS_MOD))
0194           continue;
0195         if (layerdisk_ == LayerDisk::L1) {
0196           if (memtype == 'M' || memtype == 'R' || memtype == 'L') {
0197             if (absz < VMROUTERCUTZL1 / settings_.kz(layerdisk_))
0198               continue;
0199           } else {
0200             if (absz > VMROUTERCUTZL1L3L5 / settings_.kz(layerdisk_))
0201               continue;
0202           }
0203         }
0204 
0205         if (settings_.debugTracklet()) {
0206           edm::LogVerbatim("Tracklet") << getName() << " adding stub to " << allstub.second->getName();
0207         }
0208 
0209         allstub.second->addStub(stub);
0210       }
0211 
0212       //Fill all the ME VM memories
0213       unsigned int ivm =
0214           iphi.bits(iphi.nbits() - (settings_.nbitsallstubs(layerdisk_) + settings_.nbitsvmme(layerdisk_)),
0215                     settings_.nbitsvmme(layerdisk_));
0216 
0217       //Calculate the z and r position for the vmstub
0218 
0219       //Take the top nbitszfinebintable_ bits of the z coordinate
0220       int indexz = (stub->z().value() >> (stub->z().nbits() - nbitszfinebintable_)) & ((1 << nbitszfinebintable_) - 1);
0221       int indexr = -1;
0222       if (layerdisk_ > (N_LAYER - 1)) {
0223         if (negdisk) {
0224           indexz = ((1 << nbitszfinebintable_) - 1) - indexz;
0225         }
0226         indexr = stub->r().value();
0227         if (stub->isPSmodule()) {
0228           indexr = stub->r().value() >> (stub->r().nbits() - nbitsrfinebintable_);
0229         }
0230       } else {
0231         //Take the top nbitsfinebintable_ bits of the z coordinate. The & is to handle the negative z values.
0232         indexr = (stub->r().value() >> (stub->r().nbits() - nbitsrfinebintable_)) & ((1 << nbitsrfinebintable_) - 1);
0233       }
0234 
0235       assert(indexz >= 0);
0236       assert(indexr >= 0);
0237       assert(indexz < (1 << nbitszfinebintable_));
0238       assert(indexr < (1 << nbitsrfinebintable_));
0239 
0240       int melut = meTable_.lookup((indexz << nbitsrfinebintable_) + indexr);
0241 
0242       assert(melut >= 0);
0243 
0244       int vmbin = melut >> NFINERZBITS;
0245       if (negdisk)
0246         vmbin += (1 << NFINERZBITS);
0247       int rzfine = melut & ((1 << NFINERZBITS) - 1);
0248 
0249       // pad disk PS bend word with a '0' in MSB so that all disk bends have 4 bits (for HLS compatibility)
0250       int nbendbits = stub->bend().nbits();
0251       if (layerdisk_ >= N_LAYER)
0252         nbendbits = settings_.nbendbitsmedisk();
0253 
0254       VMStubME vmstub(
0255           stub,
0256           stub->iphivmFineBins(settings_.nbitsallstubs(layerdisk_) + settings_.nbitsvmme(layerdisk_), NFINERZBITS),
0257           FPGAWord(rzfine, NFINERZBITS, true, __LINE__, __FILE__),
0258           FPGAWord(stub->bend().value(), nbendbits, true, __LINE__, __FILE__),
0259           allStubIndex);
0260 
0261       assert(vmstubsMEPHI_[0] != nullptr);
0262 
0263       vmstubsMEPHI_[0]->addStub(vmstub, ivm * nvmmebins_ + vmbin);
0264 
0265       //Fill the TE VM memories
0266       if (layerdisk_ >= N_LAYER && (!stub->isPSmodule()))
0267         continue;
0268 
0269       for (auto& ivmstubTEPHI : vmstubsTEPHI_) {
0270         unsigned int iseed = ivmstubTEPHI.seednumber;
0271         unsigned int lutwidth = settings_.lutwidthtab(1, iseed);
0272 
0273         int lutval = -999;
0274 
0275         if (layerdisk_ < N_LAYER) {
0276           lutval = melut;
0277         } else {
0278           lutval = diskTable_.lookup((indexz << nbitsrfinebintable_) + indexr);
0279           if (lutval == 0) {
0280             continue;
0281           }
0282         }
0283 
0284         assert(lutval >= 0);
0285 
0286         FPGAWord binlookup(lutval, lutwidth, true, __LINE__, __FILE__);
0287 
0288         if (binlookup.value() < 0)
0289           continue;
0290 
0291         unsigned int ivmte =
0292             iphi.bits(iphi.nbits() - (settings_.nbitsallstubs(layerdisk_) + settings_.nbitsvmte(1, iseed)),
0293                       settings_.nbitsvmte(1, iseed));
0294 
0295         int bin = binlookup.value() / 8;
0296         unsigned int tmp = binlookup.value() & 7;  //three bits in outer layers - this could be coded cleaner...
0297         binlookup.set(tmp, 3, true, __LINE__, __FILE__);
0298 
0299         FPGAWord finephi = stub->iphivmFineBins(settings_.nphireg(1, iseed), settings_.nfinephi(1, iseed));
0300 
0301         VMStubTE tmpstub(stub, finephi, stub->bend(), binlookup, allStubIndex);
0302 
0303         unsigned int nmem = ivmstubTEPHI.vmstubmem.size();
0304         assert(nmem > 0);
0305 
0306         for (unsigned int l = 0; l < nmem; l++) {
0307           if (settings_.debugTracklet()) {
0308             edm::LogVerbatim("Tracklet") << getName() << " try adding stub to " << ivmstubTEPHI.vmstubmem[l]->getName()
0309                                          << " bin=" << bin << " ivmte " << ivmte << " finephi " << finephi.value()
0310                                          << " regions bits " << settings_.nphireg(1, iseed) << " finephibits "
0311                                          << settings_.nfinephi(1, iseed);
0312           }
0313           ivmstubTEPHI.vmstubmem[l]->addVMStub(tmpstub, ivmte * settings_.NLONGVMBINS() + bin);
0314         }
0315       }
0316     }
0317   }
0318 }