00001
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
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
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
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
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
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
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
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
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)
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)
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
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
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
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)
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
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)
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
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
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
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
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
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
00908 wire(high, low, instnamestream.str().c_str());
00909 #else
00910 wire(high, low, rname);
00911 #endif
00912 }
00913
00914
00915
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
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: https://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
01157
01158 void function::makemask(int hpar, int lpar)
01159 {
01160
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
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 }