CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/L1Trigger/CSCCommonTrigger/src/vlib.cc

Go to the documentation of this file.
00001 // Copyright (c) 2002 Alexander Madorsky, University of Florida/Physics. All rights reserved.
00002 
00003 
00004 #include <L1Trigger/CSCCommonTrigger/interface/vlib.h>
00005 
00006 globcontrol glc;
00007 
00008 char const* obnames[] = 
00009 {
00010         "none "   , 
00011         "reg "    ,
00012         "wire "   ,
00013         "input "  ,
00014         "output " ,
00015         "inout "  ,
00016         "num "    ,
00017         "temp "
00018 };
00019 
00020 
00021 #define dbgmsg(a) std::cerr << a << " Set breakpoint at " << __FILE__ << ":" << __LINE__ << "\n";
00022 
00023 // Signal class --------------------------------------------------------------------------
00024 
00025 void Signal::create()
00026 {
00027 #ifdef VGEN
00028         name = "";
00029         orname = "";
00030         obname = "";
00031         lb = "(";
00032         rb = ")";
00033 #endif
00034 
00035         outhost = host = outreg = ca1 = ca2 = NULL;
00036         inited = printable = r = rc = l = pedge = nedge = change = alwaysn = mode = 0;
00037         h = 8*Sizeofrval - 1;
00038         mask = (rval)(- 1);
00039         hostl = -1;
00040 
00041 }
00042 
00043 Signal::Signal()
00044 {
00045         create();
00046 }
00047 
00048 Signal::Signal (int bits, rval value)
00049 {
00050         create();
00051 #ifdef VGEN     
00052         ostringstream sval;
00053         sval << dec << bits << "'d" << value;
00054         Signal::init(bits - 1, 0, sval.str().c_str());
00055 #else
00056         Signal::init(bits - 1, 0, "");
00057 #endif
00058         r = rc = value & mask;
00059 }
00060 
00061 Signal::Signal(const char* sval)
00062 {
00063         create();
00064         mode = mnum;
00065         std::string val = sval;
00066         int bits;
00067         unsigned int i;
00068         char radix;
00069         rval value = 0;
00070         int dig;
00071 
00072         sscanf(val.c_str(), "%d'%c", &bits, &radix);
00073         switch (radix)
00074         {
00075         case 'h':
00076         case 'H': 
00077 //              sscanf (val.c_str(), "%d'%c%x", &bits, &radix, &value);
00078                 for (i = 0; val[i] != 'h' && val[i] != 'H'; ++i);
00079                 for (; i < val.length(); ++i)
00080                 {
00081                         switch (val[i])
00082                         {
00083                         case '0':
00084                         case '1':
00085                         case '2':
00086                         case '3':
00087                         case '4':
00088                         case '5':
00089                         case '6':
00090                         case '7':
00091                         case '8':
00092                         case '9':
00093                                 dig = val[i] - '0';
00094                                 break;
00095                         case 'a':
00096                         case 'b':
00097                         case 'c':
00098                         case 'd':
00099                         case 'e':
00100                         case 'f':
00101                                 dig = val[i] - 'a' + 10;
00102                                 break;
00103                         case 'A':
00104                         case 'B':
00105                         case 'C':
00106                         case 'D':
00107                         case 'E':
00108                         case 'F':
00109                                 dig = val[i] - 'A' + 10;
00110                                 break;
00111                         default: 
00112                                 dig = -1;
00113                                 break;
00114                         }
00115                         if (dig >= 0)
00116                         {
00117                                 value = value << 4;
00118                                 value = value | dig;
00119                         }
00120                 }
00121 
00122 
00123                 break;
00124         case 'd':
00125         case 'D': 
00126                 sscanf (val.c_str(), "%d'%c%d", &bits, &radix, reinterpret_cast<int *>(&value));
00127                 break;
00128         case 'o': 
00129         case 'O': 
00130 //              sscanf (val.c_str(), "%d'%c%o", &bits, &radix, &value);
00131                 for (i = 0; val[i] != 'o' && val[i] != 'O'; ++i);
00132                 for (; i < val.length(); ++i)
00133                 {
00134                         switch (val[i])
00135                         {
00136                         case '0':
00137                         case '1':
00138                         case '2':
00139                         case '3':
00140                         case '4':
00141                         case '5':
00142                         case '6':
00143                         case '7':
00144                                 dig = val[i] - '0';
00145                                 break;
00146                         default: 
00147                                 dig = -1;
00148                                 break;
00149                         }
00150                         if (dig >= 0)
00151                         {
00152                                 value = value << 3;
00153                                 value = value | dig;
00154                         }
00155                 }
00156 
00157                 break;
00158 
00159         case 'b': 
00160         case 'B': 
00161                 
00162                 for (i = 0; val[i] != 'b' && val[i] != 'B'; ++i);
00163                 for (; i < val.length(); ++i)
00164                 {
00165                         switch (val[i])
00166                         {
00167                         case '0':
00168                                 value = value << 1;
00169                                 break;
00170                         case '1':
00171                                 value = value << 1;
00172                                 value = value | 1;
00173                                 break;
00174                         }
00175                 }
00176                 break;
00177         }
00178         Signal::init(bits - 1, 0, val.c_str());
00179         rc = value & mask;
00180         r = rc;
00181 
00182 }
00183 
00184 Signal::Signal(rval n)
00185 {
00186         create();
00187         mode = mnum;
00188 #ifdef VGEN
00189         ostringstream ln;
00190         ln << dec << n;
00191         init (8*Sizeofrval - 1, 0, ln.str().c_str());
00192 #else
00193         init (8*Sizeofrval - 1, 0, "");
00194 #endif
00195         inited = 0;
00196         rc = n;
00197         r = n;
00198 }
00199 
00200 Signal::Signal(int n)
00201 {
00202         create();
00203         mode = mnum;
00204 #ifdef VGEN
00205         ostringstream ln;
00206         ln << dec << n;
00207         init (Sizeofrval * 8 - 1, 0, ln.str().c_str());
00208 #else
00209         init (Sizeofrval * 8 - 1, 0, "");
00210 #endif
00211         inited = 0;
00212         r = (rval)n;
00213         rc = r;
00214 }
00215 
00216 Signal::Signal(unsigned int n)
00217 {
00218         create();
00219         mode = mnum;
00220 #ifdef VGEN
00221         ostringstream ln;
00222         ln << dec << n;
00223         init (Sizeofrval * 8 - 1, 0, ln.str().c_str());
00224 #else
00225         init (Sizeofrval * 8 - 1, 0, "");
00226 #endif
00227         inited = 0;
00228         r = (rval)n;
00229         rc = r;
00230 }
00231 
00232 void Signal::makemask() 
00233 {
00234         mask = (1LL << (h - l + 1)) - 1LL;
00235         if (mask == 0LL) mask = ~mask;
00236 }
00237 
00238 
00239 void Signal::init (int high, int low, const char* rname)
00240 {
00241         
00242 #ifdef VGEN
00243         name = rname;
00244         orname = rname;
00245         lb = "";
00246         rb = "";
00247 #endif
00248         if (!inited)
00249         {
00250                 h = high;
00251                 l = low;
00252                 makemask();
00253                 inited = 1;
00254         }
00255         source = this;
00256 }
00257 
00258 void Signal::init(Signal* shost, int high, int low, const char* rname)
00259 {
00260         host = shost; 
00261 #ifdef VGEN
00262         name = rname;
00263         orname = rname;
00264         lb = "";
00265         rb = "";
00266 #endif
00267         h = high;
00268         l = low;
00269         makemask();
00270         source = this;
00271         if (host) 
00272         {
00273                 rc = (host->getr() >> (l - host->getl())) & mask;
00274                 r = rc;
00275         }
00276         change = pedge = nedge = 0;
00277 }
00278 
00279 #ifdef VGEN
00280 string& Signal::getcatname()
00281 {
00282         if (lb[0] == '{')
00283                 catname = lb + name + rb; 
00284         else
00285                 catname = name;
00286         return catname;
00287 }
00288 #endif
00289 
00290 // unary operators -------------------------------------
00291 
00292 #ifdef VGEN
00293 #define unop(op,cop) \
00294 Signal Signal::op () \
00295 { \
00296         Signal t; \
00297         t.name = #cop + lb + name + rb; \
00298         printable = 0; \
00299         t.r = mask & (cop getval()); \
00300         return t; \
00301 }
00302 #else
00303 #define unop(op,cop) \
00304 Signal Signal::op () \
00305 { \
00306         Signal t; \
00307         t.init(h, l, ""); \
00308         t.r = mask & (cop getval()); \
00309         return t; \
00310 }
00311 #endif
00312 
00313 unop (operator!,!)
00314 unop (operator~,~)
00315 
00316 Signal* Signal::operator&  ()
00317 {
00318 #ifdef VGEN
00319         printable = 0;
00320 #endif
00321         return this;
00322 }
00323 
00324 
00325 // binary operators ------------------------------------
00326 #ifdef VGEN
00327 #define binop(op,cop) \
00328 Signal Signal::op (Signal arg) \
00329 { \
00330         Signal t; \
00331         t.name = lb + name + rb + " " + #cop + " " + arg.lb + arg.name + arg.rb; \
00332         printable = arg.printable = 0; \
00333         t.r = (getval() cop arg.getval()); \
00334         return t; \
00335 }
00336 #else
00337 #define binop(op,cop) \
00338 Signal Signal::op (Signal arg) \
00339 { \
00340         Signal t; \
00341         int ln  = h - l; \
00342         int aln = arg.h - arg.l; \
00343         t.init((ln > aln) ? ln : aln, 0, ""); \
00344         t.r = t.mask & (getval() cop arg.getval()); \
00345         return t; \
00346 }
00347 #endif
00348 
00349 binop (operator+,+)
00350 binop (operator-,-)
00351 binop (operator*,*)
00352 binop (operator/,/)
00353 binop (operator%,%)
00354 binop (operator^,^)
00355 binop (operator<<,<<)
00356 binop (operator>>,>>)
00357 binop (operator&,&)
00358 binop (operator&&,&&)
00359 binop (operator|,|)
00360 
00361 
00362 Signal Signal::operator|| (Signal arg)
00363 {
00364         Signal t;
00365 #ifdef VGEN
00366         t.name = lb + name + rb + " || " + arg.lb + arg.name + arg.rb;
00367         t.orname = orname + " or " + arg.orname;
00368         printable = arg.printable = 0;
00369 #else
00370         int ln  = h - l; 
00371         int aln = arg.h - arg.l; 
00372         t.init((ln > aln) ? ln : aln, 0, ""); 
00373 #endif
00374         t.r = t.mask & (getval() || arg.getval());
00375         t.change = change || arg.change;
00376         return t;
00377 }
00378 
00379 Signal Signal::operator,(Signal arg)
00380 {
00381         Signal t;
00382 #ifdef VGEN
00383         t.name = name + ", " + arg.name;
00384         t.lb = "{";
00385         t.rb = "}";
00386         printable = arg.printable = 0;
00387 #else
00388         t.ca1 = this;
00389         t.ca2 = arg.source;
00390         t.init(h - l + arg.h - arg.l + 1, 0, "");
00391 #endif
00392         t.r = (((getval() << (arg.h - arg.l + 1)) & (~(arg.mask))) | arg.getval()) & t.mask;
00393         return t;
00394 }
00395 
00396 // comparison operators ---------------------------------------------------
00397 
00398 #ifdef VGEN
00399 #define compop(op,cop) \
00400 Signal Signal::op (Signal arg) \
00401 { \
00402         Signal t; \
00403         t.name = lb + name + rb + " " + #cop + " " + arg.lb + arg.name + arg.rb; \
00404         printable = arg.printable = 0; \
00405         t.r = (getval() cop arg.getval()); \
00406         return t; \
00407 }
00408 #else
00409 #define compop(op,cop) \
00410 Signal Signal::op (Signal arg) \
00411 { \
00412         Signal t; \
00413         t.init(""); \
00414         t.r = (getval() cop arg.getval()); \
00415         return t; \
00416 }
00417 #endif
00418 
00419 compop (operator>,>)
00420 compop (operator<,<)
00421 compop (operator<=,<=)
00422 compop (operator>=,>=)
00423 compop (operator==,==)
00424 compop (operator!=,!=)
00425 
00426 // reduction operators --------------------------------------------------------------
00427 Signal ror (Signal arg)
00428 {
00429         Signal t;
00430         rval tr;
00431 #ifdef VGEN
00432         t.name = "|" + arg.lb + arg.name + arg.rb;
00433         arg.printable = 0;
00434 #else
00435         t.init("");
00436 #endif
00437         tr = (arg.getval()) & arg.mask;
00438         t.r = (tr != 0) ? 1 : 0;
00439         return t;
00440 }
00441 
00442 Signal rand (Signal arg)
00443 {
00444         Signal t;
00445         rval tr;
00446 #ifdef VGEN
00447         t.name = "&" + arg.lb + arg.name + arg.rb;
00448         arg.printable = 0;
00449 #else
00450         t.init("");
00451 #endif
00452         tr = (arg.getval()) & arg.mask;
00453         t.r = (tr == arg.mask) ? 1 : 0;
00454         return t;
00455 }
00456 
00457 Signal rxor (Signal arg)
00458 {
00459         Signal t;
00460         rval tr;
00461         int i;
00462 #ifdef VGEN
00463         t.name = "^" + arg.lb + arg.name + arg.rb;
00464         arg.printable = 0;
00465 #else
00466         t.init("");
00467 #endif
00468         tr = (arg.getval()) & arg.mask;
00469         t.r = 0;
00470         for (i = 0; i < arg.h-arg.l+1; ++i) 
00471         {
00472                 t.r = ((tr & 1) != 0) ? !t.r : t.r;
00473                 tr = tr >> 1;
00474         }
00475         t.r = t.r & 1;
00476         return t;
00477 }
00478 
00479 // blocking assignment operator -----------------------------------------------------
00480 
00481 rval Signal::getval()
00482 {
00483         return (getalwaysn() == glc.getalwaysn()) ? rc : r;
00484 }
00485 
00486 Signal Signal::operator=(Signal other)
00487 {
00488 
00489 #ifndef VGEN
00490 #ifdef _VDEBUG
00491         switch (mode)
00492         {
00493                 case moutput:
00494                         if (glc.getalwaysn() == -1 && outreg != NULL) 
00495                                 dbgmsg("Assigning output-reg outside always block.");
00496                         if (glc.getalwaysn() != -1 && outreg == NULL) 
00497                                 dbgmsg("Assigning non-reg output inside always block.");
00498                         break;
00499 
00500                 case minout:
00501                         if (glc.getalwaysn() != -1) 
00502                                 dbgmsg("Assigning inout inside always block.");
00503                         break;
00504 
00505                 case minput:
00506                         dbgmsg("Assigning to input is not allowed.");
00507                         return other;
00508 
00509                 case mreg:
00510                         if (glc.getalwaysn() == -1) 
00511                                 dbgmsg("Assigning reg outside always block.");
00512                         break;
00513 
00514                 case mwire:
00515                         if (glc.getalwaysn() != -1) 
00516                                 dbgmsg("Assigning wire inside always block.");
00517                         break;
00518         }
00519 #endif
00520 #endif
00521         return asgn(other);
00522 
00523 }
00524 
00525 Signal Signal::set(Signal other)
00526 {
00527 #ifdef VGEN
00528         glc.setprintassign(0);
00529 #endif
00530         return asgn(other);
00531 }
00532 
00533 Signal Signal::asgn(Signal other)
00534 {
00535         Signal t;
00536 
00537 #ifdef VGEN
00538         t.name = lb + name + rb + " = " + other.getcatname();
00539         if (glc.printassign()) std::cout << glc.getmargin() << t.name << ";\n" << flush;        
00540 #endif
00541         rval hr, portionr, portionmask, otr;
00542         int shn;
00543 
00544         otr = other.getval() & mask;
00545 
00546         if (otr != r) 
00547         {
00548                 setalwaysn (glc.getalwaysn());
00549                 glc.setchange(1);
00550         }
00551 
00552         rc = otr;
00553         if (host) //  is this a portion of the other register?
00554         {
00555                 hr = host->rc;
00556                 if (hostl > 0) shn = (hostl - host->getl());
00557                 else shn = (l - host->getl());
00558                 portionr = rc << shn;
00559                 portionmask = mask << shn;
00560                 host->set((hr & (~portionmask)) | portionr);
00561         }
00562 
00563         if (ca1 != NULL && ca2 != NULL) // is this a concatenation of the two registers?
00564         {
00565                 ca2->set(other);
00566                 ca1->set(other >> (ca2->h - ca2->l + 1));
00567         }
00568         if (outhost != NULL && outhost != this && (mode == moutput || mode == minout)) 
00569         {
00570                 outhost->set(other);
00571         }
00572         if (outreg)  
00573         {
00574                 outreg->set(other);
00575         }
00576 
00577         t.h = h;
00578         t.l = l;
00579         t.mask = mask;
00580         t.pedge = pedge;
00581         t.nedge = nedge;
00582         t.change = change;
00583         t.r = rc;
00584 #ifdef VGEN
00585         glc.setprintassign(1);
00586 #endif
00587         return t;
00588 }
00589 
00590 
00591 // bit selection operator -----------------------------------------------
00592 
00593 Signal Signal::operator()(Signal hn, Signal ln)
00594 {
00595         Signal t;
00596 #ifdef VGEN
00597         string bname;
00598         if (hn.getname().compare(ln.getname()) != 0) bname = name + "[" + hn.getname() + ":" + ln.getname() + "]";
00599         else bname = name + "[" + hn.getname() + "]";
00600         hn.printable = ln.printable = 0;
00601         t.init(this, 0, 0, bname.c_str());
00602 #else
00603         t.init(this, (unsigned)hn.getval(), (unsigned)ln.getval(), "");
00604 #endif
00605         t.rc = (getval() >> (t.l - l)) & t.mask;
00606         t.r = t.rc;
00607         return t;
00608 }
00609 
00610 Signal Signal::operator()(Signal n)
00611 {
00612         return (*this)(n, n);
00613 }
00614 
00615 // insertion operator ---------------------------------------------------
00616 std::ostream &operator<< (std::ostream &stream, Signal s)
00617 {
00618         stream << s.getr();
00619         s.setprintable(0);
00620         return stream;
00621 }
00622 
00623 
00624 // input -----------------------------------------------------------------------------
00625 void Signal::input(int high, int low, const char* rname)
00626 {
00627 #ifdef VGEN
00628         if (lb == "{") glc.AddIO(lb + name + rb);
00629         else glc.AddIO(name);
00630 #else
00631 #ifdef _VDEBUG
00632         if (h-l != high-low && inited) // inited is analysed in case the passed parameter is a temp var. Actually, every operator should return temp with the proper mask,h,l inherited from operands
00633         {
00634                 dbgmsg("Different port length for input argument: declared [" << high << ":" << low << "], passed: [" << h << ":" << l <<"]. ");
00635         }
00636 #endif
00637 #endif
00638         Signal::init(high, low, rname);
00639         if (high >= low)
00640         {
00641                 h = high;
00642                 l = low;
00643         }
00644         else
00645         {
00646                 h = low;
00647                 l = high;
00648         }
00649         mode = minput;
00650 #ifdef VGEN
00651         obname = obnames[mode];
00652         ostringstream ln;
00653         glc.AddParameter(name);
00654         if (h == l) ln << obname << name << ";\n";
00655         else ln << obname << "[" << dec << h << ":" << l << "] " << name << ";\n";
00656         glc.AddDeclarator(ln.str());
00657         printable = 0;
00658 #else
00659         outreg = glc.getparent()->AddOutReg((Signal)(*this));
00660         r = r & outreg->getmask();
00661         if (outreg->getr() != r) 
00662         {
00663                 change = 1; 
00664                 glc.getparent()->setchange(1);
00665                 if (r == 1 && outreg->getr() == 0) pedge = 1; else pedge = 0;
00666                 if (r == 0 && outreg->getr() == 1) nedge = 1; else nedge = 0;
00667         }
00668         else change = pedge = nedge = 0;
00669         outreg->setr(r);
00670         outreg->setrc(r);
00671         outhost = host = NULL;
00672 #endif
00673 
00674 }
00675 
00676 // clock input --------------------------------------------------------------
00677 void Signal::clock(const char* rname)
00678 {
00679 #ifdef VGEN
00680         if (lb == "{") glc.AddIO(lb + name + rb);
00681         else glc.AddIO(name);
00682 #else
00683 #ifdef _VDEBUG
00684         if (h-l != 0 && inited) // inited is analysed in case the passed parameter is a temp var. Actually, every operator should return temp with the proper mask,h,l inherited from operands
00685         {
00686                 dbgmsg("Different port length for clock argument: declared [" << 0 << ":" << 0 << "], passed: [" << h << ":" << l <<"]. ");
00687         }
00688 #endif
00689 #endif
00690         Signal::init(0, 0, rname);
00691         h = l = 0;
00692         mode = minput;
00693 #ifdef VGEN
00694         obname = obnames[mode];
00695         ostringstream ln;
00696         glc.AddParameter(name);
00697         if (h == l) ln << obname << name << ";\n";
00698         else ln << obname << "[" << dec << h << ":" << l << "] " << name << ";\n";
00699         glc.AddDeclarator(ln.str());
00700         printable = 0;
00701 #else
00702         outreg = glc.getparent()->AddOutReg((Signal)(*this));
00703         if (rc != r) 
00704         {
00705                 change = 1; 
00706                 glc.getparent()->setchange(1);
00707                 if (rc == 1 && r == 0) pedge = 1; else pedge = 0;
00708                 if (rc == 0 && r == 1) nedge = 1; else nedge = 0;
00709         }
00710         else change = pedge = nedge = 0;
00711         outreg->setr(r);
00712         outreg->setrc(r);
00713         outhost = host = NULL;
00714 #endif
00715 
00716 }
00717 
00718 
00719 
00720 // output -----------------------------------------------------------------------------
00721 
00722 void Signal::output(int high, int low, const char* rname)
00723 {
00724 #ifdef VGEN
00725         if (lb == "{") glc.AddIO(lb + name + rb);
00726         else glc.AddIO(name);
00727 #else
00728 #ifdef _VDEBUG
00729         if (h-l != high-low)
00730         {
00731                 dbgmsg("Different port length for output argument: declared [" << high << ":" << low << "], passed: [" << h << ":" << l <<"]. ");
00732         }
00733         if (mode == mreg)
00734         {
00735                 dbgmsg("Using reg as output.");
00736         }
00737 #endif
00738 #endif
00739         hostl = l;
00740         Signal::init(high, low, rname);
00741         if (high >= low)
00742         {
00743                 h = high;
00744                 l = low;
00745         }
00746         else
00747         {
00748                 h = low;
00749                 l = high;
00750         }
00751         mode = moutput;
00752 #ifdef VGEN
00753         obname = obnames[mode];
00754         ostringstream ln;
00755         glc.AddParameter(name);
00756         if (h == l) ln << obname << name << ";\n";
00757         else ln << obname << "[" << dec << h << ":" << l << "] " << name << ";\n";
00758         glc.AddDeclarator(ln.str());
00759         printable = 0;
00760 #endif
00761 
00762 }
00763 
00764 void Signal::output(int high, int low, const char* rname, module* parent)
00765 {
00766         output(high, low, rname);
00767 #ifdef VGEN
00768         ostringstream ln;
00769         if (h == l) ln << "reg    " << name << ";\n";
00770         else ln << "reg    [" << dec << h << ":" << l << "] " << name << ";\n";
00771         glc.AddDeclarator(ln.str());
00772 #else
00773         outreg = parent->AddOutReg((Signal)(*this));
00774         setr(outreg->getr());
00775         setchange(outreg->getchange());
00776         setposedge(outreg->getposedge());
00777         setnegedge(outreg->getnegedge());
00778 #endif
00779 }
00780 
00781 void Signal::output(const char* rname, module* parent)
00782 {
00783         output(0, 0, rname, parent);
00784 }
00785 
00786 // inout -----------------------------------------------------------------------------
00787 
00788 void Signal::inout(int high, int low, const char* rname)
00789 {
00790 #ifdef VGEN
00791         if (lb == "{") glc.AddIO(lb + name + rb);
00792         else glc.AddIO(name);
00793 #else
00794 #ifdef _VDEBUG
00795         if (h-l != high-low)
00796         {
00797                 dbgmsg("Different port length for inout argument: declared [" << high << ":" << low << "], passed: [" << h << ":" << l <<"]. ");
00798         }
00799 #endif
00800 #endif
00801         hostl = l;
00802         Signal::init(high, low, rname);
00803         if (high >= low)
00804         {
00805                 h = high;
00806                 l = low;
00807         }
00808         else
00809         {
00810                 h = low;
00811                 l = high;
00812         }
00813         mode = minout;
00814 #ifdef VGEN
00815         obname = obnames[mode];
00816         ostringstream ln;
00817         glc.AddParameter(name);
00818         if (h == l) ln << obname << name << ";\n";
00819         else ln << obname << "[" << dec << h << ":" << l << "] " << name << ";\n";
00820         glc.AddDeclarator(ln.str());
00821         printable = 0;
00822 #endif
00823 
00824 }
00825 
00826 // reg -------------------------------------------------------------------------------
00827 
00828 void Signal::reg(int high, int low, const char* rname)
00829 {
00830         initreg(high, low, rname);
00831 #ifdef VGEN
00832         if (h == l)     cout << glc.getmargin() << obname << name << ";\n" << flush;
00833         else std::cout << glc.getmargin() << obname << "[" << dec << h << ":" << l << "] "<< name << ";\n" << flush;
00834 #endif
00835 }
00836 
00837 void Signal::initreg(int high, int low, const char* rname)
00838 {
00839         Signal::init(high, low, rname);
00840         mode = mreg;
00841 #ifdef VGEN
00842         obname = obnames[mode];
00843 #endif
00844         change = (r != rc);
00845         if (change)     glc.getparent()->setchange(1);
00846         pedge = (rc == 1 && r == 0);
00847         nedge = (rc == 0 && r == 1);
00848         r = rc;
00849 }
00850 
00851 // parameter class -------------------------------------------------------------------------------
00852 
00853 parameter::parameter (const char* rname, Signal arg) : Signal() 
00854 {
00855 #ifdef VGEN
00856         obname = "parameter "; 
00857 #endif
00858         init(Sizeofrval * 8 - 1, 0, rname); 
00859         operator=(arg);
00860 }
00861 
00862 
00863 void parameter::init (int h, int l, const char* rname)
00864 {
00865         Signal::init(h, l, rname);
00866         change = pedge = nedge = 0;
00867 
00868 #ifdef VGEN
00869         cout << glc.getmargin() << obname << name << flush;
00870 #endif
00871 }
00872 
00873 void parameter::operator= (Signal arg)
00874 {
00875         r = arg.getr();
00876 #ifdef VGEN
00877         cout << " = " << arg.getname() << ";\n" << flush;
00878 #endif
00879 }
00880 
00881 
00882 
00883 // wire  -------------------------------------------------------------------------------
00884 
00885 void Signal::wire(int high, int low, const char* rname)
00886 {
00887         Signal::init(high, low, rname);
00888         mode = mwire;
00889         outhost = this;
00890         change = (r != rc);
00891         if (change && glc.getparent()) glc.getparent()->setchange(1);
00892         pedge = (rc == 1 && r == 0);
00893         nedge = (rc == 0 && r == 1);
00894         r = rc;
00895 #ifdef VGEN
00896         obname = obnames[mode];
00897         if (h == l)     cout << glc.getmargin() << obname << name << ";\n" << flush;
00898         else std::cout << glc.getmargin() << obname << "[" << dec << h << ":" << l << "] "<< name << ";\n" << flush;
00899 #endif
00900 }
00901 
00902 void Signal::wire(int high, int low, const char* rname, int i)
00903 {
00904 #ifdef VGEN
00905         ostringstream instnamestream;
00906         instnamestream << rname << dec << i;
00907 //      init(high, low, instnamestream.str().c_str());
00908         wire(high, low, instnamestream.str().c_str());
00909 #else
00910         wire(high, low, rname);
00911 #endif
00912 }
00913 
00914 
00915 // memory class -----------------------------------------------------------------------------
00916 
00917 void memory::reg (int high, int low, int nup, int ndown, const char* rname)
00918 {
00919         int i;
00920         if (nup > ndown)
00921         {
00922                 up = nup;
00923                 down = ndown;
00924         }
00925         else
00926         {
00927                 up = ndown;
00928                 down = nup;
00929         }
00930         if (r == NULL)
00931         {
00932                 r = new Signal [up - down + 1];
00933                 for (i = 0; i <= up - down; ++i)
00934                 {
00935                         r[i].initreg(high, low, "");
00936                         r[i].setr(0);
00937                 }
00938         }
00939         else
00940         {
00941                 for (i = 0; i <= up - down; ++i)
00942                 {
00943                         r[i].initreg(high, low, "");
00944                 }
00945         }
00946 #ifdef VGEN
00947         name = rname;
00948         if (high == low) std::cout << glc.getmargin() << "reg " << name << " [" << dec << up << ":" << down << "]" << ";\n" << flush;
00949         else std::cout << glc.getmargin() << "reg " << "[" << dec << high << ":" << low << "] "<< name << " [" << dec << up << ":" << down << "]" << ";\n" << flush;
00950 #endif
00951 }
00952 
00953 memory::~memory()
00954 {
00955         if (r != NULL) delete [] r;
00956         r = NULL;
00957 }
00958 
00959 #ifdef VGEN
00960 Signal memory::operator[] (Signal i)
00961 #else
00962 Signal& memory::operator[] (Signal i)
00963 #endif
00964 {
00965 #ifdef VGEN
00966         string ln;
00967         ln = name + "[" + i.getname() + "]";
00968         r[0].setname(ln);
00969         r[0].setorname(ln);
00970         return r[0];
00971 #else
00972         rval ind = i.getval();
00973 #ifdef _VDEBUG
00974         if (ind < down || ind > up)
00975         {
00976             dbgmsg("Memory index out of range: index: " << ind << ", range: [" << up << ":" << down << "]. ");
00977                 return r[down];
00978         }
00979         else
00980 #endif
00981         return r[ind - down];
00982 #endif
00983 }
00984 
00985 // module class -------------------------------------------------------------------------
00986 
00987 void module::create()
00988 {
00989         for (unsigned int i = 0; i < sizeof(outreg)/sizeof(Signal*); ++i) outreg[i] = NULL;
00990         outregn = 0;
00991         runperiod = NULL;
00992 }
00993 
00994 module::module()
00995 {
00996         create();
00997 }
00998 
00999 module::~module()
01000 {
01001         for (unsigned int i = 0; i < sizeof(outreg)/sizeof(Signal*); ++i)
01002         {
01003                 if (outreg[i] != NULL)
01004                         delete outreg[i];
01005         }
01006 
01007 }
01008 
01009 void module::init (const char* mname, const char* iname)
01010 {
01011 #ifdef VGEN
01012         name = mname;
01013         instname = iname;
01014 #endif
01015 }
01016 
01017 void module::init (const char* mname, const char* iname, module* fixt)
01018 {
01019 #ifdef VGEN
01020         name = mname;
01021         instname = iname;
01022 #endif
01023         tfixt = fixt;
01024 }
01025 
01026 
01027 void module::init (const char* mname, const char* iname, int index)
01028 {
01029 #ifdef VGEN
01030         name = mname;
01031         ostringstream instnamestream;
01032         instnamestream << iname << dec << index;
01033         instname = instnamestream.str().c_str();
01034 #endif
01035 }
01036 
01037 #ifdef VGEN
01038 void module::PrintHeader()
01039 {
01040         char *username = NULL;
01041         struct tm *newtime;
01042         time_t aclock;
01043         time( &aclock );                
01044         newtime = localtime( &aclock ); 
01045         username = getenv("USER");
01046         if (username == NULL || strlen(username) < 2) username = getenv("USERNAME");
01047         if (username == NULL || strlen(username) < 2) username = getenv("LOGNAME");
01048         cout << "// This  Verilog HDL  source  file was  automatically generated" << std::endl;
01049         cout << "// by C++ model based on VPP library. Modification of this file" << std::endl;
01050         cout << "// is possible, but if you want to keep it in sync with the C++" << std::endl;
01051         cout << "// model,  please  modify  the model and re-generate this file." << std::endl;
01052         cout << "// VPP library web-page: http://www.phys.ufl.edu/~madorsky/vpp/" << std::endl; 
01053         cout << std::endl;
01054         if (username != NULL)
01055                 cout << "// Author    : " << username << std::endl;
01056         cout << "// File name : " << name << ".v" << std::endl;
01057         cout << "// Timestamp : " << asctime(newtime) << std::endl << flush;
01058 
01059 }
01060 #endif
01061 
01062 void module::vbeginmodule()
01063 {
01064         switchn = 0;
01065 #ifdef VGEN
01066         string filename = name + ".v";
01067         cout << glc.getmargin() << name << " " << instname << std::endl << flush;
01068         cout << glc.getmargin() << "(" << glc.PrintIO(true).c_str() << std::endl << flush;
01069         cout << glc.getmargin() << ");\n" << flush;
01070     vfile.open (filename.c_str());
01071     outbuf = std::cout.rdbuf(vfile.rdbuf());
01072         OuterIndPos = glc.getpos();
01073         oldenmarg = glc.getenablemargin();
01074         glc.enablemargin(1);
01075         glc.setpos(0);
01076         PrintHeader();
01077         cout << glc.getmargin() << "module " << name << std::endl << glc.getmargin() << "(" << flush;
01078         glc.setfunction(0);
01079         glc.Print();
01080         glc.setFileOpen(1);
01081 #endif
01082 }
01083 
01084 void module::vendmodule()
01085 {
01086 #ifdef VGEN
01087         glc.Outdent();
01088         cout << glc.getmargin() << "endmodule\n" << flush;
01089         glc.setpos(OuterIndPos);
01090         cout.rdbuf(outbuf);
01091         vfile.close();
01092         glc.enablemargin(oldenmarg);
01093 #endif
01094         outregn = 0;
01095 }
01096 
01097 Signal module::posedge (Signal arg)
01098 {
01099         Signal t;
01100 #ifdef VGEN
01101         string ln = "";
01102         ln = "posedge " + arg.getname();
01103         t.init(NULL, 0, 0, ln.c_str());
01104 #else
01105         t.init(NULL, 0, 0, "");
01106 #endif
01107         if (arg.getposedge()) glc.setce(0);
01108         t.setchange(arg.getposedge());
01109         return t;
01110 }
01111 
01112 Signal module::negedge (Signal arg)
01113 {
01114         Signal t;
01115 #ifdef VGEN
01116         string ln = "";
01117         ln = "negedge " + arg.getname();
01118         t.init(NULL, 0, 0, ln.c_str());
01119 #else
01120         t.init(NULL, 0, 0, "");
01121 #endif
01122         if (arg.getnegedge()) glc.setce(0);
01123         t.setchange(arg.getnegedge());
01124         return t;
01125 }
01126 
01127 
01128 Signal* module::AddOutReg(Signal arg)
01129 {
01130         if (outreg[outregn] == NULL) 
01131         {
01132                 outreg[outregn] = new Signal;
01133                 outreg[outregn]->setr(0);
01134         }
01135         outreg[outregn]->reg(arg.geth(), arg.getl(), "");
01136         outregn++;
01137         return outreg[outregn - 1];
01138 }
01139 
01140 Signal module::ifelse(Signal condition, Signal iftrue, Signal iffalse)
01141 {
01142 
01143 #ifdef VGEN
01144         Signal t;
01145         string ln;
01146         ln = "(" + condition.getname() + ") ? " + iftrue.getname() + " : " + iffalse.getname();
01147         t.setname(ln);
01148         return t;
01149 #else
01150         if (condition.getbool()) return iftrue;
01151         else                                     return iffalse;
01152 #endif
01153 
01154 }
01155 
01156 // function class -------------------------------------------------------------
01157 
01158 void function::makemask(int hpar, int lpar) 
01159 {
01160         //int i;
01161         unsigned int lng = hpar - lpar + 1;
01162         
01163         if (lng < Sizeofrval * 8) 
01164                 mask = (1LL << lng) - 1;
01165         else
01166                 mask = (rval)(-1);                                              
01167 }
01168 
01169 void function::init(int high, int low, const char* rname)
01170 {
01171 #ifdef VGEN
01172         name = rname;
01173         cout << "`include " << '"' <<name << ".v" << '"' << "\n" << flush;
01174 #endif
01175         if (high >= low)
01176         {
01177                 h = high;
01178                 l = low;
01179         }
01180         else
01181         {
01182                 h = low;
01183                 l = high;
01184         }
01185         makemask(h, l);
01186 }
01187 
01188 void function::vbeginfunction()
01189 {
01190 #ifdef VGEN
01191         string filename = name + ".v";
01192         retname = name + "(" + glc.PrintIO(false) + ")";
01193     vfile.open (filename.c_str());
01194     outbuf = std::cout.rdbuf(vfile.rdbuf());
01195         OuterIndPos = glc.getpos();
01196         oldenmarg = glc.getenablemargin();
01197         glc.enablemargin(1);
01198         glc.setpos(0);
01199         PrintHeader();
01200         cout << glc.getmargin() << "function [" << dec << h << ":" << l << "] " << name << ";\n" << flush;
01201         glc.setfunction(1);
01202         glc.Print();
01203         glc.setFileOpen(1);
01204         result.setname(name);
01205         result.setbrackets("", "");
01206 #endif
01207         switchn = 0;
01208         OldChange = glc.getchange();
01209 }
01210 
01211 void function::vendfunction()
01212 {
01213 
01214         result.sethlmask(h, l, mask);
01215         result.setr(result.getr() & mask);
01216         glc.setchange(OldChange);
01217 #ifdef VGEN
01218         glc.Outdent();
01219         cout << glc.getmargin() << "endfunction\n" << flush;
01220         glc.setpos(OuterIndPos);
01221         cout.rdbuf(outbuf);
01222         result.setname(retname);
01223         result.setbrackets("", "");
01224         vfile.close();
01225         glc.enablemargin(oldenmarg);
01226 #endif
01227         outregn = 0;
01228 }
01229 
01230 // globcontrol class --------------------------------------------------------------------
01231 
01232 globcontrol::globcontrol()
01233 {
01234 #ifdef VGEN
01235         nomargin = 0;
01236         ndio = 0;
01237         npar = 0;
01238         ndecl = 0;
01239         indpos = 0;
01240         pa = 1; 
01241         zeromargin = ""; 
01242         VFileOpen = 0;
01243 #endif
01244         alwayscnt = -1; 
01245         alwaysn = 1;
01246         change = 0;
01247 }
01248 
01249 #ifdef VGEN
01250 void globcontrol::Print()
01251 {
01252         int i;
01253 
01254 
01255         if (functiondecl == 0)
01256         {
01257                 Indent();
01258                 for (i = 0; i < npar; ++i)
01259                 {
01260                         cout << std::endl;
01261                         cout << getmargin();
01262                         cout << pars[i];
01263                         if (i != npar-1) std::cout << ",";
01264                 }
01265                 Outdent();
01266                 cout << std::endl << getmargin() << ");\n";
01267         }
01268         Indent();
01269         cout << "\n";
01270 
01271         for (i = 0; i < ndecl; ++i)
01272         {
01273                 cout << glc.getmargin() << decls[i];
01274         }
01275         npar = ndecl = 0;
01276         cout << "\n" << flush;
01277 
01278 }
01279 
01280 
01281 string& globcontrol::PrintIO(bool col)
01282 {
01283         int i;
01284 
01285         if (col) Indent();
01286         outln = "";
01287         if (ndio > 0)
01288         {
01289                 for (i = 0; i < ndio; ++i)
01290                 {
01291                         if (col) 
01292                         {
01293                                 outln += "\n";
01294                                 outln += getmargin();
01295                         }
01296                         outln += dios[i];
01297                         if (i < ndio - 1) outln += ",";
01298                 }
01299         }
01300         ndio = 0;
01301         if (col) Outdent();
01302         return outln;
01303 }
01304 
01305 void globcontrol::PrepMargin()
01306 {
01307 
01308         int i;
01309         margin = "";
01310         for (i = 0; i < indpos; ++i)
01311         {
01312                 margin += "    ";
01313         }
01314 }
01315 
01316 
01317 void globcontrol::AddIO(std::string ln)
01318 {
01319         dios[ndio] = ln;
01320         ndio++;
01321 }
01322 #endif
01323 
01324 void globcontrol::setchange(int i)
01325 {
01326         change = i;
01327 }
01328 
01329 char* globcontrol::constant(int bits, char* value)
01330 {
01331         sprintf(constring, "%d%s", bits, value);
01332         return constring;
01333 }
01334 
01335 char* globcontrol::constant(int bits, int value)
01336 {
01337         sprintf(constring, "%d'd%u", bits, (unsigned)value);
01338         return constring;
01339 }