00001
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
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
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
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
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
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
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
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
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)
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)
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
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
00615 ostream &operator<< (ostream &stream, Signal s)
00616 {
00617 stream << s.getr();
00618 s.setprintable(0);
00619 return stream;
00620 }
00621
00622
00623
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)
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
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)
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
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
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
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
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
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
00907 wire(high, low, instnamestream.str().c_str());
00908 #else
00909 wire(high, low, rname);
00910 #endif
00911 }
00912
00913
00914
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
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
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
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 }