Support IEEE time units and time precisions, #234. (#2253)

Includes `timescale, $printtimescale, $timeformat.
VL_TIME_MULTIPLIER, VL_TIME_PRECISION, VL_TIME_UNIT have been removed
and the time precision must now match the SystemC time precision.
To get closer behavior to older versions, use e.g. --timescale-override
"1ps/1ps".
This commit is contained in:
Wilson Snyder
2020-04-15 19:39:03 -04:00
committed by GitHub
parent 9b8aebb00c
commit d4f7f5297a
131 changed files with 2611 additions and 1290 deletions
+110
View File
@@ -31,6 +31,7 @@
#ifndef _WIN32
# include <sys/utsname.h>
#endif
#include <algorithm>
#include <cctype>
#include <dirent.h>
#include <fcntl.h>
@@ -117,6 +118,75 @@ V3LangCode::V3LangCode(const char* textp) {
m_e = V3LangCode::L_ERROR;
}
//######################################################################
// VTimescale class functions
VTimescale::VTimescale(const string& value, bool& badr)
: m_e(VTimescale::NONE) {
badr = true;
string spaceless = VString::removeWhitespace(value);
for (int i = TS_1S; i < _ENUM_END; ++i) {
VTimescale ts(i);
if (spaceless == ts.ascii()) {
badr = false;
m_e = ts.m_e;
break;
}
}
}
void VTimescale::parseSlashed(FileLine* fl, const char* textp, VTimescale& unitr,
VTimescale& precr, bool allowEmpty) {
// Parse `timescale of <number><units> / <number><units>
unitr = VTimescale::NONE;
precr = VTimescale::NONE;
const char* cp = textp;
for (; isspace(*cp); ++cp) {}
const char* unitp = cp;
for (; *cp && *cp != '/'; ++cp) {}
string unitStr(unitp, cp - unitp);
for (; isspace(*cp); ++cp) {}
string precStr;
if (*cp == '/') {
++cp;
for (; isspace(*cp); ++cp) {}
const char* precp = cp;
for (; *cp && *cp != '/'; ++cp) {}
precStr = string(precp, cp - precp);
}
for (; isspace(*cp); ++cp) {}
if (*cp) {
fl->v3error("`timescale syntax error: '" << textp << "'");
return;
}
bool unitbad;
VTimescale unit(unitStr, unitbad /*ref*/);
if (unitbad && !(unitStr.empty() && allowEmpty)) {
fl->v3error("`timescale timeunit syntax error: '" << unitStr << "'");
return;
}
unitr = unit;
if (!precStr.empty()) {
VTimescale prec(VTimescale::NONE);
bool precbad;
prec = VTimescale(precStr, precbad /*ref*/);
if (precbad) {
fl->v3error("`timescale timeprecision syntax error: '" << precStr << "'");
return;
}
if (!unit.isNone() && !prec.isNone() && unit < prec) {
fl->v3error("`timescale timeunit '"
<< unitStr << "' must be greater than or equal to timeprecision '"
<< precStr << "'");
return;
}
precr = prec;
}
}
//######################################################################
// V3Options class functions
@@ -590,6 +660,26 @@ void V3Options::throwSigsegv() {
#endif
}
VTimescale V3Options::timeComputePrec(const VTimescale& flag) const {
if (!timeOverridePrec().isNone()) {
return timeOverridePrec();
} else if (flag.isNone()) {
return timeDefaultPrec();
} else {
return flag;
}
}
VTimescale V3Options::timeComputeUnit(const VTimescale& flag) const {
if (!timeOverrideUnit().isNone()) {
return timeOverrideUnit();
} else if (flag.isNone()) {
return timeDefaultUnit();
} else {
return flag;
}
}
//######################################################################
// V3 Options utilities
@@ -1127,6 +1217,26 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
m_threadsMaxMTasks = atoi(argv[i]);
if (m_threadsMaxMTasks < 1)
fl->v3fatal("--threads-max-mtasks must be >= 1: " << argv[i]);
} else if (!strcmp(sw, "-timescale") && (i + 1) < argc) {
shift;
VTimescale unit;
VTimescale prec;
VTimescale::parseSlashed(fl, argv[i], unit /*ref*/, prec /*ref*/);
if (!unit.isNone() && timeOverrideUnit().isNone()) m_timeDefaultUnit = unit;
if (!prec.isNone() && timeOverridePrec().isNone()) m_timeDefaultPrec = prec;
} else if (!strcmp(sw, "-timescale-override") && (i + 1) < argc) {
shift;
VTimescale unit;
VTimescale prec;
VTimescale::parseSlashed(fl, argv[i], unit /*ref*/, prec /*ref*/, true);
if (!unit.isNone()) {
m_timeDefaultUnit = unit;
m_timeOverrideUnit = unit;
}
if (!prec.isNone()) {
m_timeDefaultPrec = prec;
m_timeOverridePrec = prec;
}
} else if (!strcmp(sw, "-top-module") && (i + 1) < argc) {
shift;
m_topModule = argv[i];