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 };
00212
00213
00214
00215 unsigned L1MuGMTLUT::vec2u (const std::vector <unsigned>& vec, const std::vector<port>& widths) const{
00216 if (vec.size() != widths.size()) {
00217 edm::LogWarning("LUTMismatch") << "Error in L1MuGMTLUT::vec2u: number of LUT inputs/outputs does not match definition";
00218 return (0);
00219 }
00220
00221 unsigned value = 0;
00222 unsigned start_ofs=0;
00223
00224 for (int i=vec.size()-1; i>=0; i--) {
00225 if ( vec[i] >= (unsigned) (1 << widths[i].second) ) {
00226 edm::LogWarning("LUTMismatch") << "Error in L1MuGMTLUT::vec2u: LUT input/output number " << i
00227 << " exceeds range (0 to " << ( (1 << widths[i].second) -1 ) << ")."
00228 ;
00229 }
00230 else
00231 value |= vec[i] << start_ofs;
00232 start_ofs += widths[i].second;
00233 }
00234
00235 return (value);
00236 }
00237
00238
00239
00240 std::vector <unsigned> L1MuGMTLUT::u2vec (unsigned value, const std::vector<port>& widths) const {
00241 std::vector<unsigned> output( widths.size(), 0);
00242
00243 unsigned start_ofs=0;
00244
00245 for (int i=widths.size()-1; i>=0; i--) {
00246 int mask = ( (1 << widths[i].second) - 1 ) << start_ofs;
00247 output[i] = ( value & mask ) >> start_ofs;
00248 start_ofs += widths[i].second;
00249 }
00250
00251 return output;
00252 }
00253
00254
00255
00256
00257
00258
00259
00260
00261 unsigned L1MuGMTLUT::LookupPacked (int idx, unsigned address) const {
00262 if (! m_initialized) {
00263 edm::LogWarning("LUTMismatch") << "Error in L1MuGMTLUT::LookupPacked: LUT not initialized. ";
00264 return 0;
00265 }
00266 if ( idx >= m_NLUTS ) {
00267 edm::LogWarning("LUTMismatch") << "Error in L1MuGMTLUT::LookupPacked: LUT index exceeds range (0 to " << ( m_NLUTS -1 ) << ")."
00268 ;
00269 return 0;
00270 }
00271 if ( address >= (unsigned) (1 << m_TotalInWidth) ) {
00272 edm::LogWarning("LUTMismatch") << "Error in L1MuGMTLUT::LookupPacked: LUT input exceeds range (0 to " << ( (1 << m_TotalInWidth) -1 ) << ")."
00273 ;
00274 return 0;
00275 }
00276
00277 unsigned value = 0;
00278 if (m_UseLookupFunction) {
00279 value = LookupFunctionPacked (idx, address);
00280 } else {
00281 value = m_Contents[idx][address];
00282 }
00283
00284
00285 if ( value >= (unsigned) (1 << m_TotalOutWidth) ) {
00286 edm::LogWarning("LUTMismatch") << "Error in L1MuGMTLUT::LookupPacked(): LUT output value " << value
00287 << " exceeds range (0 to " << ( (1 << m_TotalOutWidth) -1 ) << ")."
00288 ;
00289 edm::LogWarning("LUTMismatch") << " LUT name: " << m_name;
00290 if (m_UseLookupFunction)
00291 edm::LogWarning("LUTMismatch") << " Lookup Function has to be corrected!!!";
00292 else
00293 edm::LogWarning("LUTMismatch") << " LUT File has to be corrected!!!";
00294 return (1 << m_TotalOutWidth) - 1;
00295 }
00296 return value;
00297 }
00298
00299 #endif
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311