Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #include "L1Trigger/TrackFindingTracklet/interface/VMRouter.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/VMStubsMEMemory.h"
0008 #include "L1Trigger/TrackFindingTracklet/interface/VMStubsTEMemory.h"
0009 
0010 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0011 #include "FWCore/Utilities/interface/Exception.h"
0012 
0013 using namespace std;
0014 using namespace trklet;
0015 
0016 VMRouter::VMRouter(string name, Settings const& settings, Globals* global)
0017     : ProcessBase(name, settings, global),
0018       meTable_(settings),
0019       diskTable_(settings),
0020       innerTable_(settings),
0021       innerOverlapTable_(settings),
0022       innerThirdTable_(settings) {
0023   layerdisk_ = initLayerDisk(4);
0024 
0025   vmstubsMEPHI_.resize(settings_.nvmme(layerdisk_), nullptr);
0026 
0027   unsigned int region = name[9] - 'A';
0028   assert(region < settings_.nallstubs(layerdisk_));
0029 
0030   overlapbits_ = 7;
0031   nextrabits_ = overlapbits_ - (settings_.nbitsallstubs(layerdisk_) + settings_.nbitsvmme(layerdisk_));
0032 
0033   meTable_.initVMRTable(layerdisk_, TrackletLUT::VMRTableType::me, region);  //used for ME and outer TE barrel
0034 
0035   if (layerdisk_ == LayerDisk::D1 || layerdisk_ == LayerDisk::D2 || layerdisk_ == D4) {
0036     diskTable_.initVMRTable(layerdisk_, TrackletLUT::VMRTableType::disk, region);  //outer disk used by D1, D2, and D4
0037   }
0038 
0039   if (layerdisk_ == LayerDisk::L1 || layerdisk_ == LayerDisk::L2 || layerdisk_ == LayerDisk::L3 ||
0040       layerdisk_ == LayerDisk::L5 || layerdisk_ == LayerDisk::D1 || layerdisk_ == LayerDisk::D3) {
0041     innerTable_.initVMRTable(layerdisk_, TrackletLUT::VMRTableType::inner, region);  //projection to next layer/disk
0042   }
0043 
0044   if (layerdisk_ == LayerDisk::L1 || layerdisk_ == LayerDisk::L2) {
0045     innerOverlapTable_.initVMRTable(
0046         layerdisk_, TrackletLUT::VMRTableType::inneroverlap, region);  //projection to disk from layer
0047   }
0048 
0049   if (layerdisk_ == LayerDisk::L2 || layerdisk_ == LayerDisk::L3 || layerdisk_ == LayerDisk::L5 ||
0050       layerdisk_ == LayerDisk::D1) {
0051     innerThirdTable_.initVMRTable(
0052         layerdisk_, TrackletLUT::VMRTableType::innerthird, region);  //projection to third layer/disk
0053   }
0054 
0055   nbitszfinebintable_ = settings_.vmrlutzbits(layerdisk_);
0056   nbitsrfinebintable_ = settings_.vmrlutrbits(layerdisk_);
0057 }
0058 
0059 void VMRouter::addOutput(MemoryBase* memory, string output) {
0060   if (settings_.writetrace()) {
0061     edm::LogVerbatim("Tracklet") << "In " << name_ << " adding output to " << memory->getName() << " to output "
0062                                  << output;
0063   }
0064 
0065   if (output.substr(0, 10) == "allstubout") {
0066     AllStubsMemory* tmp = dynamic_cast<AllStubsMemory*>(memory);
0067     assert(tmp != nullptr);
0068     allstubs_.push_back(tmp);
0069     return;
0070   }
0071 
0072   if (output.substr(0, 12) == "vmstuboutPHI" || output.substr(0, 14) == "vmstuboutMEPHI" ||
0073       output.substr(0, 15) == "vmstuboutTEIPHI" || output.substr(0, 15) == "vmstuboutTEOPHI") {
0074     char seedtype = memory->getName().substr(11, 1)[0];
0075     unsigned int pos = 12;
0076     int vmbin = memory->getName().substr(pos, 1)[0] - '0';
0077     pos++;
0078     if (pos < memory->getName().size()) {
0079       if (memory->getName().substr(pos, 1)[0] != 'n') {
0080         vmbin = vmbin * 10 + memory->getName().substr(pos, 1)[0] - '0';
0081         pos++;
0082       }
0083     }
0084 
0085     int iseed = -1;
0086     unsigned int inner = 1;
0087     if (memory->getName().substr(3, 2) == "TE") {
0088       VMStubsTEMemory* tmp = dynamic_cast<VMStubsTEMemory*>(memory);
0089       assert(tmp != nullptr);
0090       if (seedtype < 'I') {
0091         if (layerdisk_ == LayerDisk::L1 || layerdisk_ == LayerDisk::L2)
0092           iseed = Seed::L1L2;
0093         if (layerdisk_ == LayerDisk::L3 || layerdisk_ == LayerDisk::L4)
0094           iseed = Seed::L3L4;
0095         if (layerdisk_ == LayerDisk::L5 || layerdisk_ == LayerDisk::L6)
0096           iseed = Seed::L5L6;
0097         if (layerdisk_ == LayerDisk::D1 || layerdisk_ == LayerDisk::D2)
0098           iseed = Seed::D1D2;
0099         if (layerdisk_ == LayerDisk::D3 || layerdisk_ == LayerDisk::D4)
0100           iseed = Seed::D3D4;
0101         if (layerdisk_ == LayerDisk::L1 || layerdisk_ == LayerDisk::L3 || layerdisk_ == LayerDisk::L5 ||
0102             layerdisk_ == LayerDisk::D1 || layerdisk_ == LayerDisk::D3)
0103           inner = 0;
0104       } else if (seedtype < 'M') {
0105         if (layerdisk_ == LayerDisk::L2 || layerdisk_ == LayerDisk::L3)
0106           iseed = Seed::L2L3;
0107         if (layerdisk_ == LayerDisk::L2)
0108           inner = 0;
0109       } else if (seedtype <= 'Z') {
0110         if (layerdisk_ == LayerDisk::L1 || layerdisk_ == LayerDisk::D1)
0111           iseed = Seed::L1D1;
0112         if (layerdisk_ == LayerDisk::L2 || layerdisk_ == LayerDisk::D1)
0113           iseed = Seed::L2D1;
0114         if (layerdisk_ == LayerDisk::L1 || layerdisk_ == LayerDisk::L2)
0115           inner = 0;
0116       } else if (seedtype < 'o' && seedtype >= 'a') {
0117         if (layerdisk_ == LayerDisk::L2 || layerdisk_ == LayerDisk::L3)
0118           iseed = Seed::L2L3D1;
0119         if (layerdisk_ == LayerDisk::L2)
0120           inner = 0;
0121       } else if (seedtype > 'o' && seedtype <= 'z') {
0122         if (layerdisk_ == LayerDisk::L2)
0123           iseed = Seed::D1D2L2;
0124         if (layerdisk_ == LayerDisk::D1)
0125           iseed = Seed::L2L3D1;
0126         inner = 2;
0127       } else {
0128         throw cms::Exception("LogicError") << __FILE__ << " " << __LINE__ << " Invalid seeding!";
0129       }
0130       assert(iseed != -1);
0131       int seedindex = -1;
0132       for (unsigned int k = 0; k < vmstubsTEPHI_.size(); k++) {
0133         if (vmstubsTEPHI_[k].seednumber == (unsigned int)iseed) {
0134           seedindex = k;
0135         }
0136       }
0137       if (seedindex == -1) {
0138         seedindex = vmstubsTEPHI_.size();
0139         vector<VMStubsTEMemory*> avectmp;
0140         vector<vector<VMStubsTEMemory*> > vectmp(settings_.nvmte(inner, iseed), avectmp);
0141         VMStubsTEPHI atmp(iseed, inner, vectmp);
0142         vmstubsTEPHI_.push_back(atmp);
0143       }
0144       vmstubsTEPHI_[seedindex].vmstubmem[(vmbin - 1) & (settings_.nvmte(inner, iseed) - 1)].push_back(tmp);
0145 
0146     } else if (memory->getName().substr(3, 2) == "ME") {
0147       VMStubsMEMemory* tmp = dynamic_cast<VMStubsMEMemory*>(memory);
0148       assert(tmp != nullptr);
0149       vmstubsMEPHI_[(vmbin - 1) & (settings_.nvmme(layerdisk_) - 1)] = tmp;
0150     } else {
0151       throw cms::Exception("LogicError") << __FILE__ << " " << __LINE__ << " should never get here!";
0152     }
0153 
0154     return;
0155   }
0156 
0157   throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " Could not find output : " << output;
0158 }
0159 
0160 void VMRouter::addInput(MemoryBase* memory, string input) {
0161   if (settings_.writetrace()) {
0162     edm::LogVerbatim("Tracklet") << "In " << name_ << " adding input from " << memory->getName() << " to input "
0163                                  << input;
0164   }
0165   if (input == "stubin") {
0166     InputLinkMemory* tmp1 = dynamic_cast<InputLinkMemory*>(memory);
0167     assert(tmp1 != nullptr);
0168     if (tmp1 != nullptr) {
0169       if (layerdisk_ >= N_LAYER && tmp1->getName().find("2S_") != string::npos) {
0170         stubinputdisk2stmp_.push_back(tmp1);
0171       } else {
0172         stubinputtmp_.push_back(tmp1);
0173       }
0174     }
0175     //This gymnastic is done to ensure that in the disks the PS stubs are processed before
0176     //the 2S stubs. This is needed by the current HLS implemenation of the VM router.
0177     stubinputs_ = stubinputtmp_;
0178     for (auto& mem : stubinputdisk2stmp_) {
0179       stubinputs_.push_back(mem);
0180     }
0181     return;
0182   }
0183   throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " Could not find input : " << input;
0184 }
0185 
0186 void VMRouter::execute() {
0187   unsigned int allStubCounter = 0;
0188 
0189   //Loop over the input stubs
0190   for (auto& stubinput : stubinputs_) {
0191     for (unsigned int i = 0; i < stubinput->nStubs(); i++) {
0192       if (allStubCounter >= settings_.maxStep("VMR"))
0193         continue;
0194       if (allStubCounter >= (1 << N_BITSMEMADDRESS))
0195         continue;
0196       Stub* stub = stubinput->getStub(i);
0197 
0198       //Note - below information is not part of the stub, but rather from which input memory we are reading
0199       bool negdisk = (stub->disk().value() < 0);
0200 
0201       //use &127 to make sure we fit into the number of bits -
0202       //though we should have protected against overflows above
0203       FPGAWord allStubIndex(allStubCounter & ((1 << N_BITSMEMADDRESS) - 1), N_BITSMEMADDRESS, true, __LINE__, __FILE__);
0204 
0205       //TODO - should not be needed - but need to migrate some other pieces of code before removing
0206       stub->setAllStubIndex(allStubCounter);
0207       //TODO - should not be needed - but need to migrate some other pieces of code before removing
0208       stub->l1tstub()->setAllStubIndex(allStubCounter);
0209 
0210       allStubCounter++;
0211 
0212       //Fill allstubs memories - in HLS this is the same write to multiple memories
0213       for (auto& allstub : allstubs_) {
0214         allstub->addStub(stub);
0215       }
0216 
0217       //Fill all the ME VM memories
0218 
0219       FPGAWord iphi = stub->phicorr();
0220       unsigned int ivm =
0221           iphi.bits(iphi.nbits() - (settings_.nbitsallstubs(layerdisk_) + settings_.nbitsvmme(layerdisk_)),
0222                     settings_.nbitsvmme(layerdisk_));
0223       unsigned int extrabits = iphi.bits(iphi.nbits() - overlapbits_, nextrabits_);
0224 
0225       unsigned int ivmPlus = ivm;
0226 
0227       if (extrabits == ((1U << nextrabits_) - 1) && ivm != ((1U << settings_.nbitsvmme(layerdisk_)) - 1))
0228         ivmPlus++;
0229       unsigned int ivmMinus = ivm;
0230       if (extrabits == 0 && ivm != 0)
0231         ivmMinus--;
0232 
0233       //Calculate the z and r position for the vmstub
0234 
0235       //Take the top nbitszfinebintable_ bits of the z coordinate
0236       int indexz = (((1 << (stub->z().nbits() - 1)) + stub->z().value()) >> (stub->z().nbits() - nbitszfinebintable_));
0237       int indexr = -1;
0238       if (layerdisk_ > (N_LAYER - 1)) {
0239         if (negdisk) {
0240           indexz = (1 << nbitszfinebintable_) - indexz;
0241         }
0242         indexr = stub->r().value();
0243         if (stub->isPSmodule()) {
0244           indexr = stub->r().value() >> (stub->r().nbits() - nbitsrfinebintable_);
0245         }
0246       } else {
0247         //Take the top nbitsfinebintable_ bits of the z coordinate. The & is to handle the negative z values.
0248         indexr = (((1 << (stub->r().nbits() - 1)) + stub->r().value()) >> (stub->r().nbits() - nbitsrfinebintable_));
0249       }
0250 
0251       assert(indexz >= 0);
0252       assert(indexr >= 0);
0253       assert(indexz < (1 << nbitszfinebintable_));
0254       assert(indexr < (1 << nbitsrfinebintable_));
0255 
0256       int melut = meTable_.lookup((indexz << nbitsrfinebintable_) + indexr);
0257       assert(melut >= 0);
0258 
0259       int vmbin = melut >> 3;
0260       if (negdisk)
0261         vmbin += 8;
0262       int rzfine = melut & 7;
0263 
0264       // pad disk PS bend word with a '0' in MSB so that all disk bends have 4 bits (for HLS compatibility)
0265       int nbendbits = stub->bend().nbits();
0266       if (layerdisk_ >= N_LAYER)
0267         nbendbits = settings_.nbendbitsmedisk();
0268 
0269       VMStubME vmstub(stub,
0270                       stub->iphivmFineBins(settings_.nbitsallstubs(layerdisk_) + settings_.nbitsvmme(layerdisk_), 3),
0271                       FPGAWord(rzfine, 3, true, __LINE__, __FILE__),
0272                       FPGAWord(stub->bend().value(), nbendbits, true, __LINE__, __FILE__),
0273                       allStubIndex);
0274 
0275       assert(vmstubsMEPHI_[ivmPlus] != nullptr);
0276       vmstubsMEPHI_[ivmPlus]->addStub(vmstub, vmbin);
0277       if (settings_.debugTracklet()) {
0278         edm::LogVerbatim("Tracklet") << getName() << " adding stub to " << vmstubsMEPHI_[ivmPlus]->getName()
0279                                      << " ivmPlus" << ivmPlus << " bin=" << vmbin;
0280       }
0281 
0282       if (ivmMinus != ivmPlus) {
0283         assert(vmstubsMEPHI_[ivmMinus] != nullptr);
0284         vmstubsMEPHI_[ivmMinus]->addStub(vmstub, vmbin);
0285         if (settings_.debugTracklet()) {
0286           edm::LogVerbatim("Tracklet") << getName() << " adding stub to " << vmstubsMEPHI_[ivmMinus]->getName()
0287                                        << " ivmMinus" << ivmMinus << " bin=" << vmbin;
0288         }
0289       }
0290 
0291       //Fill the TE VM memories
0292 
0293       for (auto& ivmstubTEPHI : vmstubsTEPHI_) {
0294         unsigned int iseed = ivmstubTEPHI.seednumber;
0295         unsigned int inner = ivmstubTEPHI.stubposition;
0296         if ((iseed == Seed::D1D2 || iseed == Seed::D3D4 || iseed == Seed::L1D1 || iseed == Seed::L2D1) &&
0297             (!stub->isPSmodule()))
0298           continue;
0299 
0300         unsigned int lutwidth = settings_.lutwidthtab(inner, iseed);
0301         if (settings_.extended()) {
0302           lutwidth = settings_.lutwidthtabextended(inner, iseed);
0303         }
0304 
0305         int lutval = -999;
0306 
0307         if (inner > 0) {
0308           if (layerdisk_ < N_LAYER) {
0309             lutval = melut;
0310           } else {
0311             if (inner == 2 && iseed == Seed::L2L3D1) {
0312               lutval = 0;
0313               if (stub->r().value() < 10) {
0314                 lutval = 8 * (1 + (stub->r().value() >> 2));
0315               } else {
0316                 if (stub->r().value() < settings_.rmindiskl3overlapvm() / settings_.kr()) {
0317                   lutval = -1;
0318                 }
0319               }
0320             } else {
0321               lutval = diskTable_.lookup((indexz << nbitsrfinebintable_) + indexr);
0322             }
0323           }
0324           if (lutval == -1)
0325             continue;
0326         } else {
0327           if (iseed < Seed::L1D1 || iseed > Seed::L2D1) {
0328             lutval = innerTable_.lookup((indexz << nbitsrfinebintable_) + indexr);
0329           } else {
0330             lutval = innerOverlapTable_.lookup((indexz << nbitsrfinebintable_) + indexr);
0331           }
0332           if (lutval == -1)
0333             continue;
0334           if (settings_.extended() &&
0335               (iseed == Seed::L3L4 || iseed == Seed::L5L6 || iseed == Seed::D1D2 || iseed == Seed::L2L3D1)) {
0336             int lutval2 = innerThirdTable_.lookup((indexz << nbitsrfinebintable_) + indexr);
0337             if (lutval2 != -1)
0338               lutval += (lutval2 << 10);
0339           }
0340         }
0341 
0342         assert(lutval >= 0);
0343 
0344         FPGAWord binlookup(lutval, lutwidth, true, __LINE__, __FILE__);
0345 
0346         if (binlookup.value() < 0)
0347           continue;
0348 
0349         unsigned int ivmte =
0350             iphi.bits(iphi.nbits() - (settings_.nbitsallstubs(layerdisk_) + settings_.nbitsvmte(inner, iseed)),
0351                       settings_.nbitsvmte(inner, iseed));
0352 
0353         int bin = -1;
0354         if (inner != 0) {
0355           bin = binlookup.value() / 8;
0356           unsigned int tmp = binlookup.value() & 7;  //three bits in outer layers - this could be coded cleaner...
0357           binlookup.set(tmp, 3, true, __LINE__, __FILE__);
0358         }
0359 
0360         FPGAWord finephi = stub->iphivmFineBins(settings_.nphireg(inner, iseed), settings_.nfinephi(inner, iseed));
0361 
0362         VMStubTE tmpstub(stub, finephi, stub->bend(), binlookup, allStubIndex);
0363 
0364         unsigned int nmem = ivmstubTEPHI.vmstubmem[ivmte].size();
0365 
0366         assert(nmem > 0);
0367 
0368         for (unsigned int l = 0; l < nmem; l++) {
0369           if (settings_.debugTracklet()) {
0370             edm::LogVerbatim("Tracklet") << getName() << " try adding stub to "
0371                                          << ivmstubTEPHI.vmstubmem[ivmte][l]->getName() << " inner=" << inner
0372                                          << " bin=" << bin;
0373           }
0374           if (inner == 0) {
0375             ivmstubTEPHI.vmstubmem[ivmte][l]->addVMStub(tmpstub);
0376           } else {
0377             ivmstubTEPHI.vmstubmem[ivmte][l]->addVMStub(tmpstub, bin);
0378           }
0379         }
0380       }
0381     }
0382   }
0383 }