00001
00002
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #ifndef L1TriggerGlobalMuonTrigger_L1MuGMTLUT_h
00046 #define L1TriggerGlobalMuonTrigger_L1MuGMTLUT_h
00047
00048
00049
00050
00051
00052 #include <vector>
00053 #include <iostream>
00054
00055 #include <string>
00056 #include <stdlib.h>
00057 #include "stdio.h"
00058
00059
00060
00061
00062 class L1MuGMTLUTConverter;
00063
00064
00065
00066
00067 #include <L1Trigger/GlobalMuonTrigger/src/L1MuGMTLUTHelpers.h>
00068
00069
00070 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00071
00072
00073
00074
00075
00076
00077 class L1MuGMTLUT {
00078
00079 public:
00080 typedef std::pair<std::string, unsigned> port;
00081
00083
00085 L1MuGMTLUT() : m_initialized(0), m_NLUTS(0), m_UseLookupFunction(true), m_saveFlag(false) {};
00086
00088 L1MuGMTLUT(const char* name,
00089 const std::vector<std::string>& instances,
00090 const std::vector<port>& in_widths,
00091 const std::vector<port>& out_widths,
00092 unsigned vme_addr_width=0, bool distrRAM=false) : m_initialized(0), m_NLUTS(0), m_UseLookupFunction(true), m_saveFlag(false) {
00093 Init (name, instances, in_widths, out_widths, vme_addr_width, distrRAM);
00094 };
00095
00096 L1MuGMTLUT(const char* name,
00097 const std::string& instances,
00098 const std::string& inputs,
00099 const std::string& outputs,
00100 unsigned vme_addr_width=0, bool distrRAM=false) : m_initialized(0), m_NLUTS(0), m_UseLookupFunction(true), m_saveFlag(false) {
00101 Init (name, L1MuGMTLUTHelpers::Tokenizer(" ",instances), PortDecoder(inputs), PortDecoder(outputs),
00102 vme_addr_width, distrRAM);
00103 };
00104
00106 virtual ~L1MuGMTLUT();
00107
00110 inline unsigned LookupPacked (int idx, unsigned ) const;
00111
00113 inline unsigned LookupPacked (int idx, const std::vector<unsigned>& address) const {
00114 return LookupPacked (idx, vec2u ( address, m_Inputs ) ); };
00115
00117 inline std::vector<unsigned> Lookup (int idx, const std::vector<unsigned>& address) const {
00118 return Lookup (idx, vec2u ( address, m_Inputs ) ); };
00119
00121 inline std::vector<unsigned> Lookup (int idx, unsigned address) const {
00122 return u2vec ( LookupPacked(idx, address), m_Outputs );
00123 };
00124
00125
00127
00129 void Load (const char* path);
00130
00132 void Save (const char* path);
00133
00136 virtual unsigned LookupFunctionPacked (int idx, unsigned address) const { return 0; };
00137
00139 void MakeSubClass (const char* fname = "", const char* template_file_h = "../interface/L1MuGMTLUT_SubClass.h_template",
00140 const char* template_file_cc = "../interface/L1MuGMTLUT_SubClass.cc_template");
00141
00142 std::string Name() {return m_name;};
00143
00144 friend class L1MuGMTLUTConverter;
00145
00147 int numberOfInstances() { return m_NLUTS; };
00148
00149 protected:
00150
00152 void Init(const char* name, const std::vector<std::string>& instances,
00153 const std::vector<port>& in_widths, const std::vector<port>& out_widths,
00154 unsigned vme_addr_width=0, bool distrRAM=false);
00155
00157 inline unsigned vec2u (const std::vector <unsigned>& vec, const std::vector<port>& widths) const;
00158
00160 inline std::vector<unsigned> u2vec (unsigned value, const std::vector<port>& widths) const;
00161
00163 void Set (int idx, unsigned address, unsigned value);
00164
00165 class PortDecoder : public std::vector<port> {
00166 typedef std::vector<port> base;
00167 public:
00168 PortDecoder(const std::vector<port> &pt) : base(pt) {};
00169
00170 PortDecoder(const std::string& input){
00171
00172 L1MuGMTLUTHelpers::Tokenizer tok(" ", input);
00173 for (unsigned int i=0;i<tok.size(); i++) {
00174 size_type obrace=tok[i].find("("), cbrace=tok[i].find(")");
00175 if (obrace != std::string::npos && cbrace != std::string::npos)
00176 push_back( port ( tok[i].substr(0,obrace), (unsigned) atoi (tok[i].substr(obrace+1,cbrace-obrace-1).c_str() ) ) );
00177 else
00178 edm::LogWarning("LUTMismatch") << "L1MuGMTLUT::PortDecoder: error decoding port " << tok[i];
00179 }
00180 };
00181 std::string str() {
00182 std::string temp;
00183 for (unsigned int i=0; i<size();i++) {
00184
00185
00186
00187 char buf[100]; sprintf(buf,"(%d)",(*this)[i].second);
00188 temp += (*this)[i].first + std::string(buf);
00189
00190 if (i!=size()-1) temp += " ";
00191 }
00192 return temp;
00193 };
00194
00195 private:
00196 };
00197
00198 bool m_initialized;
00199 int m_NLUTS;
00200 bool m_UseLookupFunction;
00201 std::vector <std::string> m_InstNames;
00202 std::vector <std::vector <unsigned> > m_Contents;
00203 std::vector <port> m_Inputs;
00204 std::vector <port> m_Outputs;
00205 unsigned m_TotalInWidth;
00206 unsigned m_TotalOutWidth;
00207 unsigned m_vme_addr_width;
00208 bool m_distrRAM;
00209 std::string m_name;
00210 bool m_saveFlag;
00211 unsigned m_GeneralLUTVersion;
00212 };
00213
00214
00215
00216 unsigned L1MuGMTLUT::vec2u (const std::vector <unsigned>& vec, const std::vector<port>& widths) const{
00217 if (vec.size() != widths.size()) {
00218 edm::LogWarning("LUTMismatch") << "Error in L1MuGMTLUT::vec2u: number of LUT inputs/outputs does not match definition";
00219 return (0);
00220 }
00221
00222 unsigned value = 0;
00223 unsigned start_ofs=0;
00224
00225 for (int i=vec.size()-1; i>=0; i--) {
00226 if ( vec[i] >= (unsigned) (1 << widths[i].second) ) {
00227 edm::LogWarning("LUTMismatch") << "Error in L1MuGMTLUT::vec2u: LUT input/output number " << i
00228 << " exceeds range (0 to " << ( (1 << widths[i].second) -1 ) << ")."
00229 ;
00230 }
00231 else
00232 value |= vec[i] << start_ofs;
00233 start_ofs += widths[i].second;
00234 }
00235
00236 return (value);
00237 }
00238
00239
00240
00241 std::vector <unsigned> L1MuGMTLUT::u2vec (unsigned value, const std::vector<port>& widths) const {
00242 std::vector<unsigned> output( widths.size(), 0);
00243
00244 unsigned start_ofs=0;
00245
00246 for (int i=widths.size()-1; i>=0; i--) {
00247 int mask = ( (1 << widths[i].second) - 1 ) << start_ofs;
00248 output[i] = ( value & mask ) >> start_ofs;
00249 start_ofs += widths[i].second;
00250 }
00251
00252 return output;
00253 }
00254
00255
00256
00257
00258
00259
00260
00261
00262 unsigned L1MuGMTLUT::LookupPacked (int idx, unsigned address) const {
00263 if (! m_initialized) {
00264 edm::LogWarning("LUTMismatch") << "Error in L1MuGMTLUT::LookupPacked: LUT not initialized. ";
00265 return 0;
00266 }
00267 if ( idx >= m_NLUTS ) {
00268 edm::LogWarning("LUTMismatch") << "Error in L1MuGMTLUT::LookupPacked: LUT index exceeds range (0 to " << ( m_NLUTS -1 ) << ")."
00269 ;
00270 return 0;
00271 }
00272 if ( address >= (unsigned) (1 << m_TotalInWidth) ) {
00273 edm::LogWarning("LUTMismatch") << "Error in L1MuGMTLUT::LookupPacked: LUT input exceeds range (0 to " << ( (1 << m_TotalInWidth) -1 ) << ")."
00274 ;
00275 return 0;
00276 }
00277
00278 unsigned value = 0;
00279 if (m_UseLookupFunction) {
00280 value = LookupFunctionPacked (idx, address);
00281 } else {
00282 value = m_Contents[idx][address];
00283 }
00284
00285
00286 if ( value >= (unsigned) (1 << m_TotalOutWidth) ) {
00287 edm::LogWarning("LUTMismatch") << "Error in L1MuGMTLUT::LookupPacked(): LUT output value " << value
00288 << " exceeds range (0 to " << ( (1 << m_TotalOutWidth) -1 ) << ")."
00289 ;
00290 edm::LogWarning("LUTMismatch") << " LUT name: " << m_name;
00291 if (m_UseLookupFunction)
00292 edm::LogWarning("LUTMismatch") << " Lookup Function has to be corrected!!!";
00293 else
00294 edm::LogWarning("LUTMismatch") << " LUT File has to be corrected!!!";
00295 return (1 << m_TotalOutWidth) - 1;
00296 }
00297 return value;
00298 }
00299
00300 #endif
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312