Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-07-07 22:33:41

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