Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:22:21

0001 /**
0002  * \class L1GtVhdlBitManager
0003  *
0004  *
0005  * \Description This class builds the LUTS for the GT firmware. Furthermore it is providing some helpers
0006  *  for basic bit operations in binary and hex format.
0007  *
0008  * Implementation:
0009  *    <TODO: enter implementation details>
0010  *
0011  * \author: Philipp Wagner
0012  *
0013  *
0014  */
0015 
0016 // this class header
0017 #include "L1TriggerConfig/L1GtConfigProducers/interface/L1GtVhdlWriterBitManager.h"
0018 
0019 #include "L1TriggerConfig/L1GtConfigProducers/interface/L1GtVhdlTemplateFile.h"
0020 
0021 #include "CondFormats/L1TObjects/interface/L1GtCaloTemplate.h"
0022 #include "CondFormats/L1TObjects/interface/L1GtMuonTemplate.h"
0023 #include "CondFormats/L1TObjects/interface/L1GtEnergySumTemplate.h"
0024 
0025 // system include files
0026 #include <iostream>
0027 #include <fstream>
0028 #include <map>
0029 #include <string>
0030 #include <sstream>
0031 #include <vector>
0032 #include <iomanip>
0033 
0034 L1GtVhdlWriterBitManager::L1GtVhdlWriterBitManager() {
0035   hex2binMap_["0"] = "0000";
0036   hex2binMap_["1"] = "0001";
0037   hex2binMap_["2"] = "0010";
0038   hex2binMap_["3"] = "0011";
0039   hex2binMap_["4"] = "0100";
0040   hex2binMap_["5"] = "0101";
0041   hex2binMap_["6"] = "0110";
0042   hex2binMap_["7"] = "0111";
0043   hex2binMap_["8"] = "1000";
0044   hex2binMap_["9"] = "1001";
0045 
0046   hex2binMap_["A"] = "1010";
0047   hex2binMap_["B"] = "1011";
0048   hex2binMap_["C"] = "1100";
0049   hex2binMap_["D"] = "1101";
0050   hex2binMap_["E"] = "1110";
0051   hex2binMap_["F"] = "1111";
0052 
0053   hex2binMap_["a"] = "1010";
0054   hex2binMap_["b"] = "1011";
0055   hex2binMap_["c"] = "1100";
0056   hex2binMap_["d"] = "1101";
0057   hex2binMap_["e"] = "1110";
0058   hex2binMap_["f"] = "1111";
0059 }
0060 
0061 std::string L1GtVhdlWriterBitManager::readMapInverse(const std::map<std::string, std::string> &map, std::string value) {
0062   std::map<std::string, std::string>::const_iterator iter = map.begin();
0063   while (iter != map.end()) {
0064     if ((*iter).second == value)
0065       return (*iter).first;
0066     iter++;
0067   }
0068   return "";
0069 }
0070 
0071 std::string L1GtVhdlWriterBitManager::hex2bin(std::string hexString) {
0072   std::string temp;
0073   for (unsigned int i = 0; i < hexString.length(); i++) {
0074     std::string str;
0075     str = hexString[i];
0076 
0077     temp += hex2binMap_[str];
0078   }
0079 
0080   return temp;
0081 }
0082 
0083 std::string L1GtVhdlWriterBitManager::bin2hex(std::string binString) {
0084   std::string temp;
0085   for (unsigned int i = 1; i <= binString.length(); i++) {
0086     //std::cout<<i%4<<std::endl;
0087     if (i % 4 == 0) {
0088       //std::cout<<"I'm here!"<<std::endl;
0089       std::string str;
0090       str = binString.substr(i - 4, 4);
0091       //std::cout<<str<<std::cout<<std::endl;
0092       temp += readMapInverse(hex2binMap_, str);
0093     }
0094   }
0095 
0096   return temp;
0097 }
0098 
0099 std::string L1GtVhdlWriterBitManager::mirror(unsigned int offset, std::string hexString, bool hexOutput) {
0100   std::string temp, binString;
0101 
0102   char digit;
0103   bool hexInput = false;
0104 
0105   // check weather input hex or binary
0106   for (unsigned int i = 0; i < hexString.length(); i++) {
0107     if (hexString[i] != '0' || hexString[i] != '1') {
0108       hexInput = true;
0109       break;
0110     }
0111   }
0112 
0113   if (hexInput)
0114     binString = hex2bin(hexString);
0115   else
0116     binString = hexString;
0117 
0118   unsigned int i = 0, len = 0;
0119   len = binString.length();
0120 
0121   if (offset > len)
0122     return binString;
0123 
0124   for (i = 0; i < (len - offset) / 2; i++) {
0125     digit = binString[i + offset];
0126 
0127     binString[i + offset] = binString[len - 1 - i];
0128     binString[len - 1 - i] = digit;
0129   }
0130 
0131   if (hexOutput)
0132     return bin2hex(binString);
0133   else
0134     return binString;
0135 }
0136 
0137 std::string L1GtVhdlWriterBitManager::capitalLetters(std::string hexString) {
0138   unsigned int i = 0;
0139   while (i < hexString.length()) {
0140     if (hexString[i] == 'a')
0141       hexString[i] = 'A';
0142     else if (hexString[i] == 'b')
0143       hexString[i] = 'B';
0144     else if (hexString[i] == 'c')
0145       hexString[i] = 'C';
0146     else if (hexString[i] == 'd')
0147       hexString[i] = 'D';
0148     else if (hexString[i] == 'e')
0149       hexString[i] = 'E';
0150     else if (hexString[i] == 'f')
0151       hexString[i] = 'F';
0152     i++;
0153   }
0154 
0155   return hexString;
0156 }
0157 
0158 std::string L1GtVhdlWriterBitManager::shiftLeft(std::string hexString) {
0159   std::string binString = hex2bin(hexString);
0160 
0161   binString.erase(0, 1);
0162   binString += "0";
0163 
0164   return bin2hex(binString);
0165 }
0166 
0167 std::string L1GtVhdlWriterBitManager::buildEtaMuon(const std::vector<L1GtMuonTemplate::ObjectParameter> *op,
0168                                                    const unsigned int &num,
0169                                                    const unsigned int &counter) {
0170   std::ostringstream ossEta;
0171 
0172   ossEta << counter << " => X\"";
0173 
0174   for (unsigned int i = 0; i < num; i++) {
0175     std::ostringstream ossEtaRange;
0176     ossEtaRange << std::hex << std::setw(16) << std::setfill('0') << (*op).at(i).etaRange << std::dec;
0177 
0178     /*
0179         ossEta
0180             <<mirror(32,ossEtaRange.str());
0181         */
0182 
0183     ossEta << ossEtaRange.str();
0184 
0185     if (num > 0 && i != num - 1)
0186       ossEta << "_";
0187   }
0188 
0189   ossEta << "\",\n";
0190   return ossEta.str();
0191 }
0192 
0193 std::string L1GtVhdlWriterBitManager::buildEtaCalo(const std::vector<L1GtCaloTemplate::ObjectParameter> *op,
0194                                                    const unsigned int &num,
0195                                                    const unsigned int &counter) {
0196   std::ostringstream ossEta;
0197 
0198   ossEta << counter << " => X\"";
0199 
0200   // loop over all relevant components of object parameters
0201 
0202   for (unsigned int i = 0; i < num; i++) {
0203     std::ostringstream ossEtaRange;
0204 
0205     ossEtaRange << std::hex << std::setw(4) << std::setfill('0') << (*op).at(i).etaRange << std::dec;
0206 
0207     /*
0208         std::string tempstr=hex2bin(ossEtaRange.str());
0209         tempstr[0]='0';
0210         tempstr[15]='0';
0211         */
0212 
0213     //ossEta<<std::setw(4)<<std::setfill('0')<<mirror(8,bin2hex(tempstr));
0214 
0215     ossEta << ossEtaRange.str();
0216 
0217     if (num > 0 && i != num - 1)
0218       ossEta << "_";
0219   }
0220 
0221   ossEta << "\",\n";
0222   return ossEta.str();
0223 }
0224 
0225 std::string L1GtVhdlWriterBitManager::buildPhiCalo(const std::vector<L1GtCaloTemplate::ObjectParameter> *op,
0226                                                    const unsigned int &num,
0227                                                    const unsigned int &counter) {
0228   std::ostringstream ossPhi;
0229 
0230   ossPhi << counter << " => X\"";
0231 
0232   for (unsigned int i = 0; i < num; i++) {
0233     ossPhi << std::hex << std::setw(8) << std::setfill('0') << (*op).at(i).phiRange << std::dec;
0234 
0235     if (num > 0 && i != num - 1)
0236       ossPhi << "_";
0237   }
0238 
0239   ossPhi << "\",\n";
0240   return capitalLetters(ossPhi.str());
0241 }
0242 
0243 std::string L1GtVhdlWriterBitManager::buildPhiEnergySum(const std::vector<L1GtEnergySumTemplate::ObjectParameter> *op,
0244                                                         const unsigned int &num,
0245                                                         const unsigned int &counter) {
0246   std::ostringstream ossPhi, count;
0247 
0248   if ((*op).at(0).phiRange0Word != 0) {
0249     ossPhi << "000000000000000000" << std::hex << (*op).at(0).phiRange1Word << (*op).at(0).phiRange0Word << std::dec;
0250 
0251     count << counter;
0252 
0253     return (count.str() + " => X\"" + capitalLetters(ossPhi.str()) + "\",\n");
0254 
0255   } else
0256     return "";
0257 }
0258 
0259 std::string L1GtVhdlWriterBitManager::buildPhiMuon(const std::vector<L1GtMuonTemplate::ObjectParameter> *op,
0260                                                    const unsigned int &num,
0261                                                    const unsigned int &counter,
0262                                                    bool high) {
0263   std::ostringstream ossPhi;
0264 
0265   ossPhi << counter << " => X\"";
0266 
0267   for (unsigned int i = 0; i < num; i++) {
0268     if (high)
0269       ossPhi << std::hex << std::setw(2) << std::setfill('0') << (*op).at(i).phiHigh << std::dec;
0270     else
0271       ossPhi << std::hex << std::setw(2) << std::setfill('0') << (*op).at(i).phiLow << std::dec;
0272 
0273     if (num > 0 && i != num - 1)
0274       ossPhi << "_";
0275   }
0276 
0277   ossPhi << "\",\n";
0278   return capitalLetters(ossPhi.str());
0279 }
0280 
0281 std::string L1GtVhdlWriterBitManager::buildDeltaEtaCalo(const L1GtCaloTemplate::CorrelationParameter *&cp,
0282                                                         const unsigned int &counter) {
0283   std::ostringstream deltaEtaRange, dEta, res;
0284 
0285   //std::cout<<"b:"<<.hex2bin("00383800")<<std::endl;
0286 
0287   deltaEtaRange << std::hex << std::setw(4) << std::setfill('0') << (*cp).deltaEtaRange << std::dec;
0288 
0289   // mirror deltaEtaRang and shift the mirrored value to the left by one bit;
0290   // add the original value to the calculated value
0291   dEta << hex2bin(shiftLeft(mirror(0, deltaEtaRange.str()))) << hex2bin(deltaEtaRange.str());
0292 
0293   std::string result = capitalLetters(bin2hex(dEta.str()));
0294 
0295   res << counter << " => X\"" << result << "\",\n";
0296 
0297   return res.str();
0298 }
0299 
0300 std::string L1GtVhdlWriterBitManager::buildDeltaEtaMuon(const L1GtMuonTemplate::CorrelationParameter *&cp,
0301                                                         const unsigned int &counter) {
0302   std::ostringstream deltaEtaRange, dEta;
0303   deltaEtaRange << std::hex << std::setw(16) << std::setfill('0') << (*cp).deltaEtaRange << std::dec;
0304 
0305   // mirror deltaEtaRang and shift the mirrored value to the left by one bit;
0306   // add the original value to the calculated value
0307 
0308   std::string result = capitalLetters((shiftLeft(mirror(0, deltaEtaRange.str())) + deltaEtaRange.str()));
0309 
0310   dEta << counter << " => X\"" << result << "\",\n";
0311 
0312   return dEta.str();
0313 }
0314 
0315 std::string L1GtVhdlWriterBitManager::buildDeltaPhiCalo(const L1GtCaloTemplate::CorrelationParameter *&cp,
0316                                                         const unsigned int &counter) {
0317   std::ostringstream dPhi, deltaPhiRange, result;
0318   //std::cout<<.hex2bin("03E0000000000F81")<<std::endl;
0319   //std::cout<<.hex2bin("0080000000000200")<<std::endl;
0320 
0321   deltaPhiRange << std::hex << std::setw(3) << std::setfill('0') << (*cp).deltaPhiRange << std::dec;
0322 
0323   std::string binString = hex2bin(deltaPhiRange.str());
0324 
0325   //std::cout <<"========================" <<std::endl;
0326 
0327   std::string help2 = binString.substr(2, binString.length() - 2);
0328   std::string help1 = help2.substr(1);
0329   help1 = mirror(0, bin2hex(help1), false);
0330 
0331   // here delta phi is built
0332   result << help1;
0333 
0334   // might be wrong - has to be tested with more reference values!
0335   result << help2.substr(0, 8);
0336   result << "0";
0337 
0338   result << "00000000000000000000000000000";
0339 
0340   result << help1;
0341 
0342   result << binString.substr(2, binString.length() - 2);
0343 
0344   dPhi << counter << " => X\"" << bin2hex(result.str()) << "\",\n";
0345 
0346   //std::cout<<result<<std::endl;
0347 
0348   /*
0349      * Code from old GTS:
0350       bm_dphi = bm_dphi.Get(2);
0351       BitMngr help1, help2 = bm_dphi;
0352       help2.SetAt(9, '\0');
0353       help1 = help2.Get(1);
0354       help1.Mirror();
0355       BitMngr nuller;
0356       nuller.InitBin("00 00 00 00 00 00 00 00 00 00 00 00 00 00 0");
0357       BitMngr result;
0358       result = result + help1 + help2 + nuller + help1 + bm_dphi;
0359     dphi = result.GetHex();
0360     */
0361 
0362   return capitalLetters(dPhi.str());
0363 }
0364 
0365 std::string L1GtVhdlWriterBitManager::buildDeltaPhiMuon(const L1GtMuonTemplate::CorrelationParameter *&cp,
0366                                                         const unsigned int &counter) {
0367   std::ostringstream dPhi, deltaPhiRange0, deltaPhiRange1, temp, result;
0368   std::string tempstr;
0369 
0370   deltaPhiRange0 << std::hex << std::setw(16) << std::setfill('0') << (*cp).deltaPhiRange0Word << std::dec;
0371   //deltaPhiRange1  /*<< std::hex<< std::setw(3)<<std::setfill('0')*/<<(*cp).deltaPhiRange1Word<<std::dec;
0372 
0373   //mirror deltaPhiRange, shift the mirrored value left and convert it to binary format
0374   temp << hex2bin(shiftLeft(mirror(0, deltaPhiRange0.str())));
0375   tempstr = temp.str();
0376   // set last bit of tempstr to one;
0377   tempstr[tempstr.length() - 1] = '1';
0378 
0379   // build delta eta as stringstreamtau
0380   result << tempstr
0381          // insert 16 ones
0382          << hex2bin("FFFF") << hex2bin(deltaPhiRange0.str());
0383 
0384   dPhi << counter << " => X\"" << bin2hex(result.str()) << "\",\n";
0385 
0386   return dPhi.str();
0387 }