parent
9c054a5774
commit
ba3930777a
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2182,6 +2182,8 @@ void EmitCStmts::displayNode(AstNode* nodep, AstScopeName* scopenamep, const str
|
|||
case 'g': displayArg(nodep, &elistp, isScan, vfmt, ignore, 'g'); break;
|
||||
case '^': displayArg(nodep, &elistp, isScan, vfmt, ignore, '^'); break; // Realtime
|
||||
case 'v': displayArg(nodep, &elistp, isScan, vfmt, ignore, 'v'); break;
|
||||
case 'u': displayArg(nodep, &elistp, isScan, vfmt, ignore, 'u'); break;
|
||||
case 'z': displayArg(nodep, &elistp, isScan, vfmt, ignore, 'z'); break;
|
||||
case 'm': {
|
||||
UASSERT_OBJ(scopenamep, nodep, "Display with %m but no AstScopeName");
|
||||
string suffix = scopenamep->scopePrettySymName();
|
||||
|
|
|
|||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,27 @@
|
|||
#!/usr/bin/env perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you
|
||||
# can redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
scenarios(simulator => 1);
|
||||
|
||||
unlink("$Self->{obj_dir}/t_sys_file_basic_uz_test.log");
|
||||
|
||||
compile();
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
files_identical("$Self->{obj_dir}/t_sys_file_basic_uz_test.log", $Self->{golden_filename});
|
||||
|
||||
files_identical("$Self->{obj_dir}/t_sys_file_basic_uz_test.bin",
|
||||
"$Self->{t_dir}/t_sys_file_basic_uz.dat");
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
|
|
@ -0,0 +1,137 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2030 by Stephen Henry.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module t;
|
||||
|
||||
int fdin_bin, fdout_txt, fdout_bin;
|
||||
`define STRINGIFY(x) `"x`"
|
||||
|
||||
`define checkh(gotv,expv) \
|
||||
do if ((gotv) !== (expv)) begin\
|
||||
$write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv));\
|
||||
end while(0)
|
||||
|
||||
//
|
||||
//
|
||||
task automatic test1; begin
|
||||
for (int i = 0; i < 256; i++) begin
|
||||
byte actual, expected;
|
||||
expected = i[7:0];
|
||||
$fscanf(fdin_bin, "%u", actual);
|
||||
`checkh(actual, expected);
|
||||
$fdisplay(fdout_txt, "%h", actual);
|
||||
$fwrite(fdout_bin, "%u", actual);
|
||||
end
|
||||
|
||||
for (int i = 0; i < 256; i++) begin
|
||||
shortint actual, expected;
|
||||
for (int j = 0; j < 2; j++)
|
||||
expected[(8 * j)+:8] = i[7:0] + j[7:0];
|
||||
$fscanf(fdin_bin, "%u", actual);
|
||||
`checkh(actual, expected);
|
||||
$fdisplay(fdout_txt, "%h", actual);
|
||||
$fwrite(fdout_bin, "%u", actual);
|
||||
end
|
||||
|
||||
for (int i = 0; i < 256; i++) begin
|
||||
int actual, expected;
|
||||
for (int j = 0; j < 4; j++)
|
||||
expected[(8 * j)+:8] = i[7:0] + j[7:0];
|
||||
$fscanf(fdin_bin, "%u", actual);
|
||||
`checkh(actual, expected);
|
||||
$fdisplay(fdout_txt, "%h", actual);
|
||||
$fwrite(fdout_bin, "%u", actual);
|
||||
end
|
||||
|
||||
for (int i = 0; i < 256; i++) begin
|
||||
longint actual, expected;
|
||||
for (int j = 0; j < 8; j++)
|
||||
expected[(8 * j)+:8] = i[7:0] + j[7:0];
|
||||
$fscanf(fdin_bin, "%u", actual);
|
||||
`checkh(actual, expected);
|
||||
$fdisplay(fdout_txt, "%h", actual);
|
||||
$fwrite(fdout_bin, "%u", actual);
|
||||
end
|
||||
end endtask
|
||||
|
||||
//
|
||||
//
|
||||
task automatic test2; begin
|
||||
for (int i = 0; i < 256; i++) begin
|
||||
byte actual, expected;
|
||||
expected = i[7:0];
|
||||
$fscanf(fdin_bin, "%z", actual);
|
||||
`checkh(actual, expected);
|
||||
$fdisplay(fdout_txt, "%h", actual);
|
||||
$fwrite(fdout_bin, "%z", actual);
|
||||
end
|
||||
|
||||
for (int i = 0; i < 256; i++) begin
|
||||
shortint actual, expected;
|
||||
for (int j = 0; j < 2; j++)
|
||||
expected[(8 * j)+:8] = i[7:0] + j[7:0];
|
||||
$fscanf(fdin_bin, "%z", actual);
|
||||
`checkh(actual, expected);
|
||||
$fdisplay(fdout_txt, "%h", actual);
|
||||
$fwrite(fdout_bin, "%z", actual);
|
||||
end
|
||||
|
||||
for (int i = 0; i < 256; i++) begin
|
||||
int actual, expected;
|
||||
for (int j = 0; j < 4; j++)
|
||||
expected[(8 * j)+:8] = i[7:0] + j[7:0];
|
||||
$fscanf(fdin_bin, "%z", actual);
|
||||
`checkh(actual, expected);
|
||||
$fdisplay(fdout_txt, "%h", actual);
|
||||
$fwrite(fdout_bin, "%z", actual);
|
||||
end
|
||||
|
||||
for (int i = 0; i < 256; i++) begin
|
||||
longint actual, expected;
|
||||
for (int j = 0; j < 8; j++)
|
||||
expected[(8 * j)+:8] = i[7:0] + j[7:0];
|
||||
$fscanf(fdin_bin, "%z", actual);
|
||||
`checkh(actual, expected);
|
||||
$fdisplay(fdout_txt, "%h", actual);
|
||||
$fwrite(fdout_bin, "%z", actual);
|
||||
end
|
||||
end endtask
|
||||
|
||||
initial begin : main_PROC
|
||||
|
||||
string filename;
|
||||
|
||||
filename = "t/t_sys_file_basic_uz.dat";
|
||||
fdin_bin = $fopen(filename, "rb");
|
||||
|
||||
`ifdef IVERILOG
|
||||
filename = $sformatf("%s/t_sys_file_basic_uz_test.log","obj_iv/t_sys_file_basic_uz");
|
||||
`else
|
||||
filename = $sformatf("%s/t_sys_file_basic_uz_test.log",`STRINGIFY(`TEST_OBJ_DIR));
|
||||
`endif
|
||||
fdout_txt = $fopen(filename, "w");
|
||||
|
||||
`ifdef IVERILOG
|
||||
filename = $sformatf("%s/t_sys_file_basic_uz_test.bin","obj_iv/t_sys_file_basic_uz");
|
||||
`else
|
||||
filename = $sformatf("%s/t_sys_file_basic_uz_test.bin",`STRINGIFY(`TEST_OBJ_DIR));
|
||||
`endif
|
||||
$display(filename);
|
||||
fdout_bin = $fopen(filename, "wb");
|
||||
|
||||
test1;
|
||||
test2;
|
||||
|
||||
$fclose(fdin_bin);
|
||||
$fclose(fdout_txt);
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish(0); // Test arguments to finish
|
||||
|
||||
end // block: main_PROC
|
||||
|
||||
`undef STRINGIFY
|
||||
endmodule // t
|
||||
Loading…
Reference in New Issue