mirror of
https://github.com/verilator/verilator.git
synced 2026-09-03 16:28:53 +02:00
+64
-27
@@ -846,25 +846,22 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
|
||||
+ ((VL_BITISSETLIMIT_W(lwp, lbits, lsb + 2)) ? 4 : 0));
|
||||
}
|
||||
break;
|
||||
case 'u': // Packed 2-state
|
||||
output.reserve(output.size() + 4 * VL_WORDS_I(lbits));
|
||||
for (int i = 0; i < VL_WORDS_I(lbits); ++i) {
|
||||
output += static_cast<char>((lwp[i]) & 0xff);
|
||||
output += static_cast<char>((lwp[i] >> 8) & 0xff);
|
||||
output += static_cast<char>((lwp[i] >> 16) & 0xff);
|
||||
output += static_cast<char>((lwp[i] >> 24) & 0xff);
|
||||
}
|
||||
break;
|
||||
case 'z': // Packed 4-state
|
||||
output.reserve(output.size() + 8 * VL_WORDS_I(lbits));
|
||||
for (int i = 0; i < VL_WORDS_I(lbits); ++i) {
|
||||
output += static_cast<char>((lwp[i]) & 0xff);
|
||||
output += static_cast<char>((lwp[i] >> 8) & 0xff);
|
||||
output += static_cast<char>((lwp[i] >> 16) & 0xff);
|
||||
output += static_cast<char>((lwp[i] >> 24) & 0xff);
|
||||
output += "\0\0\0\0"; // No tristate
|
||||
case 'u':
|
||||
case 'z': { // Packed 4-state
|
||||
const bool is_4_state = (fmt == 'z');
|
||||
output.reserve(output.size() + ((is_4_state ? 2 : 1) * VL_WORDS_I(lbits)));
|
||||
int bytes_to_go = VL_BYTES_I(lbits);
|
||||
int bit = 0;
|
||||
while (bytes_to_go > 0) {
|
||||
const int wr_bytes = std::min(4, bytes_to_go);
|
||||
for (int byte = 0; byte < wr_bytes; byte++, bit += 8)
|
||||
output += static_cast<char>(VL_BITRSHIFT_W(lwp, bit) & 0xff);
|
||||
output.append(4 - wr_bytes, (char)0);
|
||||
if (is_4_state) output.append(4, (char)0);
|
||||
bytes_to_go -= wr_bytes;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'v': // Strength; assume always strong
|
||||
for (lsb = lbits - 1; lsb >= 0; --lsb) {
|
||||
if (VL_BITRSHIFT_W(lwp, lsb) & 1) {
|
||||
@@ -932,8 +929,8 @@ static inline void _vl_vsss_skipspace(FILE* fp, int& floc, WDataInP fromp,
|
||||
_vl_vsss_advance(fp, floc);
|
||||
}
|
||||
}
|
||||
static inline void _vl_vsss_read(FILE* fp, int& floc, WDataInP fromp, const std::string& fstr,
|
||||
char* tmpp, const char* acceptp) VL_MT_SAFE {
|
||||
static inline void _vl_vsss_read_str(FILE* fp, int& floc, WDataInP fromp, const std::string& fstr,
|
||||
char* tmpp, const char* acceptp) VL_MT_SAFE {
|
||||
// Read into tmp, consisting of characters from acceptp list
|
||||
char* cp = tmpp;
|
||||
while (true) {
|
||||
@@ -947,6 +944,19 @@ static inline void _vl_vsss_read(FILE* fp, int& floc, WDataInP fromp, const std:
|
||||
*cp++ = '\0';
|
||||
// VL_DBG_MSGF(" _read got='"<<tmpp<<"'\n");
|
||||
}
|
||||
static inline char* _vl_vsss_read_bin(FILE* fp, int& floc, WDataInP fromp, const std::string& fstr,
|
||||
char* beginp, std::size_t n, bool inhibit = false) {
|
||||
// Variant of _vl_vsss_read_str using the same underlying I/O functions but optimized
|
||||
// specifically for block reads of N bytes (read operations are not demarcated by
|
||||
// whitespace). In the fp case, except descriptor to have been opened in binary mode.
|
||||
while (n-- > 0) {
|
||||
const int c = _vl_vsss_peek(fp, floc, fromp, fstr);
|
||||
if (c == EOF) return NULL;
|
||||
if (!inhibit) *beginp++ = c;
|
||||
_vl_vsss_advance(fp, floc);
|
||||
}
|
||||
return beginp;
|
||||
}
|
||||
static inline void _vl_vsss_setbit(WDataOutP owp, int obits, int lsb, int nbits,
|
||||
IData ld) VL_MT_SAFE {
|
||||
for (; nbits && lsb < obits; nbits--, lsb++, ld >>= 1) {
|
||||
@@ -1045,7 +1055,7 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
|
||||
}
|
||||
case 's': {
|
||||
_vl_vsss_skipspace(fp, floc, fromp, fstr);
|
||||
_vl_vsss_read(fp, floc, fromp, fstr, tmp, NULL);
|
||||
_vl_vsss_read_str(fp, floc, fromp, fstr, tmp, NULL);
|
||||
if (!tmp[0]) goto done;
|
||||
int lpos = (static_cast<int>(strlen(tmp))) - 1;
|
||||
int lsb = 0;
|
||||
@@ -1057,7 +1067,7 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
|
||||
}
|
||||
case 'd': { // Signed decimal
|
||||
_vl_vsss_skipspace(fp, floc, fromp, fstr);
|
||||
_vl_vsss_read(fp, floc, fromp, fstr, tmp, "0123456789+-xXzZ?_");
|
||||
_vl_vsss_read_str(fp, floc, fromp, fstr, tmp, "0123456789+-xXzZ?_");
|
||||
if (!tmp[0]) goto done;
|
||||
vlsint64_t ld;
|
||||
sscanf(tmp, "%30" VL_PRI64 "d", &ld);
|
||||
@@ -1068,7 +1078,7 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
|
||||
case 'e':
|
||||
case 'g': { // Real number
|
||||
_vl_vsss_skipspace(fp, floc, fromp, fstr);
|
||||
_vl_vsss_read(fp, floc, fromp, fstr, tmp, "+-.0123456789eE");
|
||||
_vl_vsss_read_str(fp, floc, fromp, fstr, tmp, "+-.0123456789eE");
|
||||
if (!tmp[0]) goto done;
|
||||
// cppcheck-suppress unusedStructMember // It's used
|
||||
union {
|
||||
@@ -1082,7 +1092,7 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
|
||||
case 't': // FALLTHRU // Time
|
||||
case '#': { // Unsigned decimal
|
||||
_vl_vsss_skipspace(fp, floc, fromp, fstr);
|
||||
_vl_vsss_read(fp, floc, fromp, fstr, tmp, "0123456789+-xXzZ?_");
|
||||
_vl_vsss_read_str(fp, floc, fromp, fstr, tmp, "0123456789+-xXzZ?_");
|
||||
if (!tmp[0]) goto done;
|
||||
QData ld;
|
||||
sscanf(tmp, "%30" VL_PRI64 "u", &ld);
|
||||
@@ -1091,25 +1101,52 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
|
||||
}
|
||||
case 'b': {
|
||||
_vl_vsss_skipspace(fp, floc, fromp, fstr);
|
||||
_vl_vsss_read(fp, floc, fromp, fstr, tmp, "01xXzZ?_");
|
||||
_vl_vsss_read_str(fp, floc, fromp, fstr, tmp, "01xXzZ?_");
|
||||
if (!tmp[0]) goto done;
|
||||
_vl_vsss_based(owp, obits, 1, tmp, 0, strlen(tmp));
|
||||
break;
|
||||
}
|
||||
case 'o': {
|
||||
_vl_vsss_skipspace(fp, floc, fromp, fstr);
|
||||
_vl_vsss_read(fp, floc, fromp, fstr, tmp, "01234567xXzZ?_");
|
||||
_vl_vsss_read_str(fp, floc, fromp, fstr, tmp, "01234567xXzZ?_");
|
||||
if (!tmp[0]) goto done;
|
||||
_vl_vsss_based(owp, obits, 3, tmp, 0, strlen(tmp));
|
||||
break;
|
||||
}
|
||||
case 'x': {
|
||||
_vl_vsss_skipspace(fp, floc, fromp, fstr);
|
||||
_vl_vsss_read(fp, floc, fromp, fstr, tmp, "0123456789abcdefABCDEFxXzZ?_");
|
||||
_vl_vsss_read_str(fp, floc, fromp, fstr, tmp, "0123456789abcdefABCDEFxXzZ?_");
|
||||
if (!tmp[0]) goto done;
|
||||
_vl_vsss_based(owp, obits, 4, tmp, 0, strlen(tmp));
|
||||
break;
|
||||
}
|
||||
case 'u': {
|
||||
// Read packed 2-value binary data
|
||||
const int bytes = VL_BYTES_I(obits);
|
||||
char* out = reinterpret_cast<char*>(owp);
|
||||
if (!_vl_vsss_read_bin(fp, floc, fromp, fstr, out, bytes)) goto done;
|
||||
const int last = bytes % 4;
|
||||
if (last != 0
|
||||
&& !_vl_vsss_read_bin(fp, floc, fromp, fstr, out, 4 - last, true))
|
||||
goto done;
|
||||
break;
|
||||
}
|
||||
case 'z': {
|
||||
// Read packed 4-value binary data
|
||||
char* out = reinterpret_cast<char*>(owp);
|
||||
int bytes = VL_BYTES_I(obits);
|
||||
while (bytes > 0) {
|
||||
const int abytes = std::min(4, bytes);
|
||||
// aval (4B) read {0, 1} state
|
||||
out = _vl_vsss_read_bin(fp, floc, fromp, fstr, out, abytes);
|
||||
if (!out) goto done;
|
||||
// bval (4B) disregard {X, Z} state and align to new 8B boundary.
|
||||
out = _vl_vsss_read_bin(fp, floc, fromp, fstr, out, 8 - abytes, true);
|
||||
if (!out) goto done;
|
||||
bytes -= abytes;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
std::string msg = std::string("Unknown _vl_vsscanf code: ") + pos[0];
|
||||
VL_FATAL_MT(__FILE__, __LINE__, "", msg.c_str());
|
||||
@@ -1336,7 +1373,7 @@ void VL_FWRITEF(IData fpi, const char* formatp, ...) VL_MT_SAFE {
|
||||
const int n = VerilatedImp::fdToFp(fpi, fp, 30);
|
||||
for (std::size_t i = 0; i < n; i++) {
|
||||
if (VL_UNLIKELY(!fp[i])) continue;
|
||||
fputs(output.c_str(), fp[i]);
|
||||
fwrite(output.c_str(), 1, output.size(), fp[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user