CMS 3D CMS Logo

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

Generated on Tue Jun 9 17:39:41 2009 for CMSSW by  doxygen 1.5.4