File indexing completed on 2024-09-07 04:36:48
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043 #ifndef L1TriggerGlobalMuonTrigger_L1MuGMTLUT_h
0044 #define L1TriggerGlobalMuonTrigger_L1MuGMTLUT_h
0045
0046
0047
0048
0049
0050 #include <vector>
0051 #include <iostream>
0052
0053 #include <string>
0054 #include <cstdlib>
0055 #include <cstdio>
0056
0057
0058
0059
0060 class L1MuGMTLUTConverter;
0061
0062
0063
0064
0065 #include <L1Trigger/GlobalMuonTrigger/src/L1MuGMTLUTHelpers.h>
0066
0067 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0068
0069
0070
0071
0072
0073 class L1MuGMTLUT {
0074 public:
0075 typedef std::pair<std::string, unsigned> port;
0076
0077
0078
0079
0080 L1MuGMTLUT() : m_initialized(false), m_NLUTS(0), m_UseLookupFunction(true), m_saveFlag(false) {}
0081
0082
0083 L1MuGMTLUT(const char* name,
0084 const std::vector<std::string>& instances,
0085 const std::vector<port>& in_widths,
0086 const std::vector<port>& out_widths,
0087 unsigned vme_addr_width = 0,
0088 bool distrRAM = false)
0089 : m_initialized(false), m_NLUTS(0), m_UseLookupFunction(true), m_saveFlag(false) {
0090 Init(name, instances, in_widths, out_widths, vme_addr_width, distrRAM);
0091 };
0092
0093 L1MuGMTLUT(const char* name,
0094 const std::string& instances,
0095 const std::string& inputs,
0096 const std::string& outputs,
0097 unsigned vme_addr_width = 0,
0098 bool distrRAM = false)
0099 : m_initialized(false), m_NLUTS(0), m_UseLookupFunction(true), m_saveFlag(false) {
0100 Init(name,
0101 L1MuGMTLUTHelpers::Tokenizer(" ", instances),
0102 PortDecoder(inputs),
0103 PortDecoder(outputs),
0104 vme_addr_width,
0105 distrRAM);
0106 };
0107
0108
0109 virtual ~L1MuGMTLUT();
0110
0111
0112
0113 inline unsigned LookupPacked(int idx, unsigned) const;
0114
0115
0116 inline unsigned LookupPacked(int idx, const std::vector<unsigned>& address) const {
0117 return LookupPacked(idx, vec2u(address, m_Inputs));
0118 };
0119
0120
0121 inline std::vector<unsigned> Lookup(int idx, const std::vector<unsigned>& address) const {
0122 return Lookup(idx, vec2u(address, m_Inputs));
0123 };
0124
0125
0126 inline std::vector<unsigned> Lookup(int idx, unsigned address) const {
0127 return u2vec(LookupPacked(idx, address), m_Outputs);
0128 };
0129
0130
0131
0132
0133 void Load(const char* path);
0134
0135
0136 void Save(const char* path);
0137
0138
0139
0140 virtual unsigned LookupFunctionPacked(int idx, unsigned address) const { return 0; };
0141
0142
0143 void MakeSubClass(const char* fname = "",
0144 const char* template_file_h = "../interface/L1MuGMTLUT_SubClass.h_template",
0145 const char* template_file_cc = "../interface/L1MuGMTLUT_SubClass.cc_template");
0146
0147 std::string Name() { return m_name; };
0148
0149 friend class L1MuGMTLUTConverter;
0150
0151
0152 int numberOfInstances() { return m_NLUTS; };
0153
0154 protected:
0155
0156 void Init(const char* name,
0157 const std::vector<std::string>& instances,
0158 const std::vector<port>& in_widths,
0159 const std::vector<port>& out_widths,
0160 unsigned vme_addr_width = 0,
0161 bool distrRAM = false);
0162
0163
0164 inline unsigned vec2u(const std::vector<unsigned>& vec, const std::vector<port>& widths) const;
0165
0166
0167 inline std::vector<unsigned> u2vec(unsigned value, const std::vector<port>& widths) const;
0168
0169
0170 void Set(int idx, unsigned address, unsigned value);
0171
0172 class PortDecoder : public std::vector<port> {
0173 typedef std::vector<port> base;
0174
0175 public:
0176 PortDecoder(const std::vector<port>& pt) : base(pt) {}
0177
0178 PortDecoder(const std::string& input) {
0179
0180 L1MuGMTLUTHelpers::Tokenizer tok(" ", input);
0181 for (unsigned int i = 0; i < tok.size(); i++) {
0182 size_type obrace = tok[i].find('('), cbrace = tok[i].find(')');
0183 if (obrace != std::string::npos && cbrace != std::string::npos)
0184 push_back(
0185 port(tok[i].substr(0, obrace), (unsigned)atoi(tok[i].substr(obrace + 1, cbrace - obrace - 1).c_str())));
0186 else
0187 edm::LogWarning("LUTMismatch") << "L1MuGMTLUT::PortDecoder: error decoding port " << tok[i];
0188 }
0189 };
0190 std::string str() {
0191 std::string temp;
0192 for (unsigned int i = 0; i < size(); i++) {
0193
0194
0195
0196 char buf[100];
0197 sprintf(buf, "(%d)", (*this)[i].second);
0198 temp += (*this)[i].first + std::string(buf);
0199
0200 if (i != size() - 1)
0201 temp += " ";
0202 }
0203 return temp;
0204 };
0205
0206 private:
0207 };
0208
0209 bool m_initialized;
0210 int m_NLUTS;
0211 bool m_UseLookupFunction;
0212 std::vector<std::string> m_InstNames;
0213 std::vector<std::vector<unsigned> > m_Contents;
0214 std::vector<port> m_Inputs;
0215 std::vector<port> m_Outputs;
0216 unsigned m_TotalInWidth;
0217 unsigned m_TotalOutWidth;
0218 unsigned m_vme_addr_width;
0219 bool m_distrRAM;
0220 std::string m_name;
0221 bool m_saveFlag;
0222 unsigned m_GeneralLUTVersion;
0223 };
0224
0225
0226
0227 unsigned L1MuGMTLUT::vec2u(const std::vector<unsigned>& vec, const std::vector<port>& widths) const {
0228 if (vec.size() != widths.size()) {
0229 edm::LogWarning("LUTMismatch")
0230 << "Error in L1MuGMTLUT::vec2u: number of LUT inputs/outputs does not match definition";
0231 return (0);
0232 }
0233
0234 unsigned value = 0;
0235 unsigned start_ofs = 0;
0236
0237 for (int i = vec.size() - 1; i >= 0; i--) {
0238 if (vec[i] >= (unsigned)(1 << widths[i].second)) {
0239 edm::LogWarning("LUTMismatch") << "Error in L1MuGMTLUT::vec2u: LUT input/output number " << i
0240 << " exceeds range (0 to " << ((1 << widths[i].second) - 1) << ").";
0241 } else
0242 value |= vec[i] << start_ofs;
0243 start_ofs += widths[i].second;
0244 }
0245
0246 return (value);
0247 }
0248
0249
0250
0251 std::vector<unsigned> L1MuGMTLUT::u2vec(unsigned value, const std::vector<port>& widths) const {
0252 std::vector<unsigned> output(widths.size(), 0);
0253
0254 unsigned start_ofs = 0;
0255
0256 for (int i = widths.size() - 1; i >= 0; i--) {
0257 int mask = ((1 << widths[i].second) - 1) << start_ofs;
0258 output[i] = (value & mask) >> start_ofs;
0259 start_ofs += widths[i].second;
0260 }
0261
0262 return output;
0263 }
0264
0265
0266
0267
0268
0269
0270
0271
0272 unsigned L1MuGMTLUT::LookupPacked(int idx, unsigned address) const {
0273 if (!m_initialized) {
0274 edm::LogWarning("LUTMismatch") << "Error in L1MuGMTLUT::LookupPacked: LUT not initialized. ";
0275 return 0;
0276 }
0277 if (idx >= m_NLUTS) {
0278 edm::LogWarning("LUTMismatch") << "Error in L1MuGMTLUT::LookupPacked: LUT index exceeds range (0 to "
0279 << (m_NLUTS - 1) << ").";
0280 return 0;
0281 }
0282 if (address >= (unsigned)(1 << m_TotalInWidth)) {
0283 edm::LogWarning("LUTMismatch") << "Error in L1MuGMTLUT::LookupPacked: LUT input exceeds range (0 to "
0284 << ((1 << m_TotalInWidth) - 1) << ").";
0285 return 0;
0286 }
0287
0288 unsigned value = 0;
0289 if (m_UseLookupFunction) {
0290 value = LookupFunctionPacked(idx, address);
0291 } else {
0292 value = m_Contents[idx][address];
0293 }
0294
0295
0296 if (value >= (unsigned)(1 << m_TotalOutWidth)) {
0297 edm::LogWarning("LUTMismatch") << "Error in L1MuGMTLUT::LookupPacked(): LUT output value " << value
0298 << " exceeds range (0 to " << ((1 << m_TotalOutWidth) - 1) << ").";
0299 edm::LogWarning("LUTMismatch") << " LUT name: " << m_name;
0300 if (m_UseLookupFunction)
0301 edm::LogWarning("LUTMismatch") << " Lookup Function has to be corrected!!!";
0302 else
0303 edm::LogWarning("LUTMismatch") << " LUT File has to be corrected!!!";
0304 return (1 << m_TotalOutWidth) - 1;
0305 }
0306 return value;
0307 }
0308
0309 #endif