Revert: 21020ea2: Support printing enum names for %p and %s (#5523 revert) (#7338 revert) (#7521 test)
This commit is contained in:
parent
021f5f7d02
commit
dd75c4cd1b
|
|
@ -944,20 +944,6 @@ std::string _vl_vsformat_time(std::string& tmp, T ld, int timeunit, bool left,
|
|||
// Do a va_arg returning a quad, assuming input argument is anything less than wide
|
||||
#define VL_VA_ARG_Q_(ap, bits) (((bits) <= VL_IDATASIZE) ? va_arg(ap, IData) : va_arg(ap, QData))
|
||||
|
||||
static void _vl_vsformat_read_qint(va_list app, int lbits, QData& ld, std::vector<EData>& strwide,
|
||||
WDataInP& lwp, int& lsb) VL_MT_SAFE {
|
||||
if (lbits <= VL_QUADSIZE) {
|
||||
ld = VL_VA_ARG_Q_(app, lbits);
|
||||
strwide.resize(2);
|
||||
VL_SET_WQ(strwide, ld);
|
||||
lwp = strwide.data();
|
||||
} else {
|
||||
lwp = va_arg(app, WDataInP);
|
||||
ld = 0; // Consume the arg; enums > 64 bits wide are unsupported.
|
||||
}
|
||||
lsb = lbits - 1;
|
||||
}
|
||||
|
||||
void _vl_vsformat(std::string& output, const std::string& format, int argc,
|
||||
va_list ap) VL_MT_SAFE {
|
||||
// Format a Verilog $write style format into the output list
|
||||
|
|
@ -1092,7 +1078,6 @@ void _vl_vsformat(std::string& output, const std::string& format, int argc,
|
|||
// Similar code flow in V3Number::displayed
|
||||
int lbits = 0;
|
||||
void* thingp = nullptr;
|
||||
const std::string* enump = nullptr;
|
||||
QData ld = 0;
|
||||
std::vector<EData> strwide;
|
||||
WDataInP lwp = nullptr;
|
||||
|
|
@ -1112,31 +1097,17 @@ void _vl_vsformat(std::string& output, const std::string& format, int argc,
|
|||
} else if (formatAttr == VL_VFORMATATTR_STRING) {
|
||||
thingp = va_arg(ap, std::string*);
|
||||
if (fmt != 'p' && fmt != 'x') fmt = 's'; // Override
|
||||
} else if (formatAttr == VL_VFORMATATTR_ENUM) {
|
||||
lbits = va_arg(ap, int);
|
||||
_vl_vsformat_read_qint(ap, lbits, ld, strwide, lwp, lsb);
|
||||
++argn; // Internal ABI: runtime enum args are followed by generated name string
|
||||
static_cast<void>(va_arg(ap, int)); // VL_VFORMATATTR_STRING
|
||||
enump = va_arg(ap, std::string*);
|
||||
if (enump && !enump->empty()) {
|
||||
formatAttr = (fmt == 'p') ? VL_VFORMATATTR_COMPLEX : VL_VFORMATATTR_STRING;
|
||||
thingp = const_cast<std::string*>(enump);
|
||||
} else if (fmt == 'p' && widthSet && width == 0) {
|
||||
output += "'h";
|
||||
fmt = 'h';
|
||||
formatAttr = VL_VFORMATATTR_UNSIGNED;
|
||||
} else {
|
||||
if (fmt == 'p') width = 0;
|
||||
widthSet = true;
|
||||
fmt = 'd';
|
||||
formatAttr = VL_VFORMATATTR_UNSIGNED;
|
||||
}
|
||||
if (widthSet && width == 0) {
|
||||
while (lsb && !VL_BITISSET_W(lwp, lsb)) --lsb;
|
||||
}
|
||||
} else { // Numeric
|
||||
lbits = va_arg(ap, int);
|
||||
_vl_vsformat_read_qint(ap, lbits, ld, strwide, lwp, lsb);
|
||||
if (lbits <= VL_QUADSIZE) {
|
||||
ld = VL_VA_ARG_Q_(ap, lbits);
|
||||
strwide.resize(2);
|
||||
VL_SET_WQ(strwide, ld);
|
||||
lwp = strwide.data();
|
||||
} else {
|
||||
lwp = va_arg(ap, WDataInP);
|
||||
ld = lwp[0];
|
||||
}
|
||||
if (fmt == 'p') {
|
||||
if (widthSet && width == 0) { // For %0p, IEEE our choice, use 'h%0h
|
||||
output += "'h";
|
||||
|
|
@ -1147,6 +1118,7 @@ void _vl_vsformat(std::string& output, const std::string& format, int argc,
|
|||
fmt = 'd';
|
||||
}
|
||||
}
|
||||
lsb = lbits - 1;
|
||||
if (widthSet && width == 0) {
|
||||
while (lsb && !VL_BITISSET_W(lwp, lsb)) --lsb;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -442,7 +442,6 @@ using ssize_t = uint32_t; ///< signed size_t; returned from read()
|
|||
#define VL_VFORMATATTR_SIGNED '~' // (int widthMin, IData/WData/etc) Signed number; for %d showing sign
|
||||
#define VL_VFORMATATTR_COMPLEX '!' // (std::string*); for non-POD; e.g. struct, requires %p typically
|
||||
#define VL_VFORMATATTR_DOUBLE 'D' // (double); promote %p to %f
|
||||
#define VL_VFORMATATTR_ENUM 'E' // (width, data..., std::string* name); enum with runtime %p/%s
|
||||
#define VL_VFORMATATTR_SCOPE 'M' // (char* name, char* scope); for scopes
|
||||
#define VL_VFORMATATTR_STRING 'S' // (char* name, char* scope); for scopes // (std::string*); for %p/%s
|
||||
#define VL_VFORMATATTR_TIMEUNIT 'T' // (int timeunit); timeunits passed from V3Emit to runtime
|
||||
|
|
|
|||
|
|
@ -318,7 +318,7 @@ void EmitCFunc::displayNode(AstNode* nodep, AstSFormatF* fmtp, // fmtp is nullp
|
|||
AstNode* const subargp = fargp ? fargp->exprp() : argp;
|
||||
const VFormatAttr formatAttr = AstSFormatArg::formatAttrDefauled(fargp, subargp->dtypep());
|
||||
puts(", '"s + formatAttr.ascii() + '\'');
|
||||
if (formatAttr.isSigned() || formatAttr.isUnsigned() || formatAttr.isEnum())
|
||||
if (formatAttr.isSigned() || formatAttr.isUnsigned())
|
||||
puts("," + cvtToStr(subargp->widthMin()));
|
||||
const bool addrof = isScan || formatAttr.isString() || formatAttr.isComplex();
|
||||
puts(",");
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@ public:
|
|||
//
|
||||
COMPLEX = VL_VFORMATATTR_COMPLEX,
|
||||
DOUBLE = VL_VFORMATATTR_DOUBLE,
|
||||
ENUM = VL_VFORMATATTR_ENUM,
|
||||
SCOPE = VL_VFORMATATTR_SCOPE,
|
||||
STRING = VL_VFORMATATTR_STRING,
|
||||
TIMEUNIT = VL_VFORMATATTR_TIMEUNIT
|
||||
|
|
@ -63,7 +62,6 @@ public:
|
|||
char ascii() const { return m_e; }
|
||||
bool isComplex() const { return m_e == COMPLEX; }
|
||||
bool isDouble() const { return m_e == DOUBLE; }
|
||||
bool isEnum() const { return m_e == ENUM; }
|
||||
bool isSigned() const { return m_e == SIGNED; }
|
||||
bool isString() const { return m_e == STRING; }
|
||||
bool isUnsigned() const { return m_e == UNSIGNED; }
|
||||
|
|
|
|||
|
|
@ -6364,17 +6364,7 @@ class WidthVisitor final : public VNVisitor {
|
|||
AstNodeExpr* const newp = new AstToStringN{argp->fileline(), argp};
|
||||
formatAttr = VFormatAttr::COMPLEX;
|
||||
argp = newp;
|
||||
} else if (nodep->exprFormat()) {
|
||||
if (AstEnumDType* const enumDtp = formatEnumDType(argp)) {
|
||||
nodep->addExprsp(new AstSFormatArg{argp->fileline(), VFormatAttr::ENUM, argp});
|
||||
AstNodeExpr* const namep
|
||||
= enumSelect(argp->cloneTreePure(false), enumDtp, VAttrType::ENUM_NAME);
|
||||
nodep->addExprsp(
|
||||
new AstSFormatArg{namep->fileline(), VFormatAttr::STRING, namep});
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (formatAttr.isUnsigned() && dtypep->isSigned()) {
|
||||
} else if (dtypep->isSigned()) {
|
||||
formatAttr = VFormatAttr::SIGNED;
|
||||
}
|
||||
if (VN_IS(argp, SFormatArg) // Already done
|
||||
|
|
@ -8241,16 +8231,13 @@ class WidthVisitor final : public VNVisitor {
|
|||
// For sformatf's with constant format, iterate/check arguments
|
||||
UASSERT_OBJ(!nodep->exprFormat(), nodep, "Assumes constant format");
|
||||
bool inPct = false;
|
||||
string fmtMods;
|
||||
AstNodeExpr* argp = nodep->exprsp();
|
||||
string newFormat;
|
||||
for (char ch : nodep->text()) {
|
||||
if (!inPct && ch == '%') {
|
||||
inPct = true;
|
||||
fmtMods = "";
|
||||
newFormat += ch;
|
||||
} else if (inPct && (std::isdigit(ch) || ch == '.' || ch == '-')) {
|
||||
fmtMods += ch;
|
||||
newFormat += ch;
|
||||
} else if (!inPct) { // Normal text
|
||||
newFormat += ch;
|
||||
|
|
@ -8258,7 +8245,7 @@ class WidthVisitor final : public VNVisitor {
|
|||
inPct = false;
|
||||
AstNodeExpr* const nextp = argp ? VN_AS(argp->nextp(), NodeExpr) : nullptr;
|
||||
AstSFormatArg* const fargp = VN_CAST(argp, SFormatArg); // May not exist yet
|
||||
AstNodeExpr* subargp = fargp ? fargp->exprp() : argp;
|
||||
AstNodeExpr* const subargp = fargp ? fargp->exprp() : argp;
|
||||
const AstNodeDType* const dtypep
|
||||
= subargp ? subargp->dtypep()->skipRefp() : nullptr;
|
||||
ch = std::tolower(ch);
|
||||
|
|
@ -8315,35 +8302,7 @@ class WidthVisitor final : public VNVisitor {
|
|||
}
|
||||
break;
|
||||
case 'p': // FALLTHRU
|
||||
case 's':
|
||||
// Keep enum `%p`/`%s` behavior aligned with enum.name():
|
||||
// valid enum values print the mnemonic; invalid values print numeric fallback.
|
||||
if (subargp) {
|
||||
if (AstEnumDType* const enumDtp = formatEnumDType(subargp)) {
|
||||
string fallbackFormat = "%0d";
|
||||
if (ch == 'p') {
|
||||
bool widthSet = false;
|
||||
size_t width = 0;
|
||||
for (const char mod : fmtMods) {
|
||||
if (!std::isdigit(mod)) continue;
|
||||
widthSet = true;
|
||||
width = width * 10 + (mod - '0');
|
||||
}
|
||||
if (widthSet && width == 0) fallbackFormat = "'h%0h";
|
||||
}
|
||||
AstNodeExpr* const newp = new AstCond{
|
||||
subargp->fileline(), enumTestValid(subargp, enumDtp),
|
||||
enumSelect(subargp->cloneTreePure(false), enumDtp,
|
||||
VAttrType::ENUM_NAME),
|
||||
new AstSFormatF{subargp->fileline(), fallbackFormat, true,
|
||||
subargp->cloneTreePure(false)}};
|
||||
subargp->replaceWith(new AstSFormatArg{subargp->fileline(),
|
||||
VFormatAttr::COMPLEX, newp});
|
||||
VL_DO_DANGLING(pushDeletep(subargp), subargp);
|
||||
}
|
||||
}
|
||||
argp = nextp;
|
||||
break;
|
||||
case 's': // FALLTHRU
|
||||
default: // Most operators, just move to next argument
|
||||
argp = nextp;
|
||||
break;
|
||||
|
|
@ -8354,16 +8313,6 @@ class WidthVisitor final : public VNVisitor {
|
|||
nodep->text(newFormat);
|
||||
}
|
||||
|
||||
static AstEnumDType* formatEnumDType(AstNodeExpr* subargp) {
|
||||
AstEnumDType* enumDtp = VN_CAST(subargp->dtypep()->skipRefToEnump(), EnumDType);
|
||||
if (!enumDtp) {
|
||||
if (const AstVarRef* const varrefp = VN_CAST(subargp, VarRef)) {
|
||||
enumDtp = VN_CAST(varrefp->varp()->dtypep()->skipRefToEnump(), EnumDType);
|
||||
}
|
||||
}
|
||||
return enumDtp;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// LOWER LEVEL WIDTH METHODS (none iterate)
|
||||
|
||||
|
|
|
|||
|
|
@ -4,11 +4,6 @@
|
|||
// SPDX-FileCopyrightText: 2020 Wilson Snyder
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
// verilog_format: off
|
||||
`define stop $stop
|
||||
`define checks(gotv, expv) do if ((gotv) != (expv)) begin $write("%%Error: %s:%0d: got='%s' exp='%s'\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
|
||||
// verilog_format: on
|
||||
|
||||
module t;
|
||||
|
||||
class Cls;
|
||||
|
|
@ -17,32 +12,11 @@ module t;
|
|||
B = 20,
|
||||
C = 30
|
||||
} en_t;
|
||||
en_t en;
|
||||
endclass
|
||||
|
||||
class WideCls;
|
||||
typedef enum logic [95:0] {
|
||||
A = 96'h1,
|
||||
B = 96'h2
|
||||
} en_t;
|
||||
en_t en;
|
||||
endclass
|
||||
|
||||
initial begin
|
||||
Cls c;
|
||||
WideCls w;
|
||||
string s;
|
||||
if (c.A != 10) $stop;
|
||||
c = new;
|
||||
c.en = c.B;
|
||||
if (c.en != 20) $stop;
|
||||
s = $sformatf("%p", c);
|
||||
`checks(s, "'{en:'h14}");
|
||||
|
||||
w = new;
|
||||
w.en = w.B;
|
||||
s = $sformatf("%p", w);
|
||||
`checks(s, "'{en:'h2}");
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,18 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# 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-FileCopyrightText: 2026 Wilson Snyder
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
test.scenarios('simulator')
|
||||
|
||||
test.compile()
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
|
|
@ -1,167 +0,0 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// 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-FileCopyrightText: 2026 Wilson Snyder
|
||||
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
module t (
|
||||
input string empty_no_opt
|
||||
);
|
||||
typedef enum logic [1:0] {
|
||||
E0 = 0,
|
||||
E1 = 1,
|
||||
E2 = 2
|
||||
} my_e;
|
||||
|
||||
typedef enum logic [63:0] {
|
||||
W64A = 64'h1,
|
||||
W64B = 64'h0000_0001_0000_0001
|
||||
} wide64_e;
|
||||
|
||||
my_e e;
|
||||
wide64_e e64;
|
||||
logic [63:0] n64;
|
||||
`define check(got, exp) do if ((got) != (exp)) begin \
|
||||
$write("%%Error: %s:%0d: got='%s' exp='%s'\n", `__FILE__, `__LINE__, got, exp); \
|
||||
$stop; \
|
||||
end while(0)
|
||||
|
||||
initial begin
|
||||
string fmt;
|
||||
begin
|
||||
my_e it;
|
||||
string names_p;
|
||||
string names_s;
|
||||
string vals_d;
|
||||
names_p = "";
|
||||
names_s = "";
|
||||
vals_d = "";
|
||||
for (it = it.first; ; it = it.next) begin
|
||||
if (names_p != "") begin
|
||||
names_p = {names_p, ","};
|
||||
names_s = {names_s, ","};
|
||||
vals_d = {vals_d, ","};
|
||||
end
|
||||
names_p = {names_p, $sformatf("%p", it)};
|
||||
names_s = {names_s, $sformatf("%s", it)};
|
||||
vals_d = {vals_d, $sformatf("%0d", it)};
|
||||
if (it == it.last) break;
|
||||
end
|
||||
`check(names_p, "E0,E1,E2");
|
||||
`check(names_s, "E0,E1,E2");
|
||||
`check(vals_d, "0,1,2");
|
||||
end
|
||||
|
||||
// Valid enum values print mnemonic for %p/%s.
|
||||
e = E0;
|
||||
`check($sformatf("%p", e), "E0");
|
||||
`check($sformatf("%s", e), "E0");
|
||||
|
||||
e = E1;
|
||||
`check($sformatf("%p", e), "E1");
|
||||
`check($sformatf("%P", e), "E1");
|
||||
`check($sformatf("%0p", e), "E1");
|
||||
`check($sformatf("%s", e), "E1");
|
||||
`check($sformatf("%S", e), "E1");
|
||||
`check($sformatf("%d", e), "1");
|
||||
`check($sformatf("%0d", e), "1");
|
||||
`check($sformatf("%h", e), "1");
|
||||
`check($sformatf("%0h", e), "1");
|
||||
`check($sformatf("%b", e), "01");
|
||||
`check($sformatf("%0b", e), "1");
|
||||
`check($sformatf("%o", e), "1");
|
||||
`check($sformatf("%0o", e), "1");
|
||||
`check($sformatf("%x", e), "1");
|
||||
`check($sformatf("%0x", e), "1");
|
||||
|
||||
e = E2;
|
||||
`check($sformatf("%p", e), "E2");
|
||||
`check($sformatf("%s", e), "E2");
|
||||
`check($sformatf("%s|%p", e, e), "E2|E2");
|
||||
`check($sformatf("%4p", e), "E2");
|
||||
`check($sformatf("%-4p", e), "E2");
|
||||
`check($sformatf("%d", e), "2");
|
||||
`check($sformatf("%h", e), "2");
|
||||
`check($sformatf("%b", e), "10");
|
||||
`check($sformatf("%0b", e), "10");
|
||||
`check($sformatf("%o", e), "2");
|
||||
`check($sformatf("%x", e), "2");
|
||||
`check($sformatf("%4d", e), " 2");
|
||||
`check($sformatf("%04d", e), "0002");
|
||||
`check($sformatf("%4h", e), "0002");
|
||||
`check($sformatf("%-4s", e), "E2 ");
|
||||
`check($sformatf("%4s", e), " E2");
|
||||
// `%p`/`%s` in non-terminal positions with mixed formatters.
|
||||
`check($sformatf("%0d:%s:%0d", 9, e, 7), "9:E2:7");
|
||||
`check($sformatf("%s %h %p", e, 4'hA, e), "E2 a E2");
|
||||
`check($sformatf("pre %% %s post", e), "pre % E2 post");
|
||||
// Complex enum expressions (non-var-ref) in format args.
|
||||
`check($sformatf("%s", (1'b1 ? E2 : E0)), "E2");
|
||||
// 64-bit enums should preserve bits above 32 in both named and numeric cases.
|
||||
e64 = W64B;
|
||||
`check($sformatf("%p", e64), "W64B");
|
||||
`check($sformatf("%s", e64), "W64B");
|
||||
e64 = wide64_e'(64'h0000_0002_0000_0001);
|
||||
`check($sformatf("%p", e64), "8589934593");
|
||||
`check($sformatf("%s", e64), "8589934593");
|
||||
n64 = 64'h0000_0000_0000_0001;
|
||||
`check($sformatf("%0p", n64), "'h1");
|
||||
// Exercise display/write-family formatting path in addition to $sformatf checks.
|
||||
$display("display-valid:%s:%0d:%p", e, 7, e);
|
||||
$write("write-valid:%s:%0d:%p\n", e, 8, e);
|
||||
// Invalid enum values fall back to numeric formatting for %p/%s.
|
||||
e = my_e'(3);
|
||||
`check($sformatf("%p", e), "3");
|
||||
`check($sformatf("%P", e), "3");
|
||||
`check($sformatf("%0p", e), "'h3");
|
||||
`check($sformatf("%s", e), "3");
|
||||
`check($sformatf("%S", e), "3");
|
||||
`check($sformatf("%4p", e), "3");
|
||||
`check($sformatf("%4s", e), " 3");
|
||||
`check($sformatf("%d", e), "3");
|
||||
`check($sformatf("%0d", e), "3");
|
||||
`check($sformatf("%h", e), "3");
|
||||
`check($sformatf("%0h", e), "3");
|
||||
`check($sformatf("%b", e), "11");
|
||||
`check($sformatf("%0b", e), "11");
|
||||
`check($sformatf("%o", e), "3");
|
||||
`check($sformatf("%x", e), "3");
|
||||
// Non-terminal invalid-value fallback with mixed formatters.
|
||||
`check($sformatf("%0d:%p:%0d", 9, e, 7), "9:3:7");
|
||||
`check($sformatf("%s %h %p", e, 4'hA, e), "3 a 3");
|
||||
`check($sformatf("pre %% %s post", e), "pre % 3 post");
|
||||
`check($sformatf("%s|%p", e, e), "3|3");
|
||||
`check($sformatf("%s", (1'b1 ? my_e'(3) : E0)), "3");
|
||||
`check($sformatf("%p", (1'b0 ? E0 : my_e'(3))), "3");
|
||||
$display("display-invalid:%s:%0d:%p", e, 7, e);
|
||||
$write("write-invalid:%s:%0d:%p\n", e, 8, e);
|
||||
// Runtime-computed $sformatf formats should preserve enum mnemonic/fallback behavior.
|
||||
e = E2;
|
||||
fmt = {"%", "s", empty_no_opt};
|
||||
`check($sformatf(fmt, e), "E2");
|
||||
fmt = {"%", "p", empty_no_opt};
|
||||
`check($sformatf(fmt, e), "E2");
|
||||
fmt = {"%0d:%", "s", ":%0d", empty_no_opt};
|
||||
`check($sformatf(fmt, 9, e, 7), "9:E2:7");
|
||||
fmt = {"%", "s", " %h %", "p", empty_no_opt};
|
||||
`check($sformatf(fmt, e, 4'hA, e), "E2 a E2");
|
||||
e = my_e'(3);
|
||||
fmt = {"%", "s", empty_no_opt};
|
||||
`check($sformatf(fmt, e), "3");
|
||||
fmt = {"%", "p", empty_no_opt};
|
||||
`check($sformatf(fmt, e), "3");
|
||||
fmt = {"%0", "p", empty_no_opt};
|
||||
`check($sformatf(fmt, e), "'h3");
|
||||
fmt = {"%0d:%", "s", ":%0d", empty_no_opt};
|
||||
`check($sformatf(fmt, 9, e, 7), "9:3:7");
|
||||
fmt = {"%", "s", " %h %", "p", empty_no_opt};
|
||||
`check($sformatf(fmt, e, 4'hA, e), "3 a 3");
|
||||
fmt = {"%", "p", empty_no_opt};
|
||||
`check($sformatf(fmt, e64), "8589934593");
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -22,7 +22,7 @@ module t (
|
|||
integer cyc = 0;
|
||||
my_t e;
|
||||
|
||||
string s;
|
||||
string all;
|
||||
int i_cast;
|
||||
|
||||
// Check runtime
|
||||
|
|
@ -45,10 +45,6 @@ module t (
|
|||
`checkh(e.prev, E01);
|
||||
`checkh(e.next(0), ELARGE);
|
||||
`checkh(e.prev(0), ELARGE);
|
||||
s = $sformatf("%p", e);
|
||||
`checks(s, "ELARGE");
|
||||
s = $sformatf("%s", e); // Non-standard but majority
|
||||
`checks(s, "ELARGE");
|
||||
e <= E01;
|
||||
end
|
||||
//
|
||||
|
|
@ -72,8 +68,6 @@ module t (
|
|||
end
|
||||
else if (cyc == 21) begin
|
||||
`checks(e.name, ""); // Unknown
|
||||
s = $sformatf("%p", e);
|
||||
`checks(s, "17");
|
||||
end
|
||||
else if (cyc == 99) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ module t (
|
|||
integer cyc = 0;
|
||||
my_t e;
|
||||
|
||||
string s;
|
||||
string all;
|
||||
|
||||
// Check runtime
|
||||
always @(posedge clk) begin
|
||||
|
|
@ -40,8 +40,6 @@ module t (
|
|||
`checks(e.name, "ELARGE");
|
||||
`checkh(e.next, E01);
|
||||
`checkh(e.prev, E01);
|
||||
s = $sformatf("%p", e);
|
||||
`checks(s, "ELARGE");
|
||||
e <= E01;
|
||||
end
|
||||
else if (cyc == 20) begin
|
||||
|
|
@ -49,8 +47,6 @@ module t (
|
|||
end
|
||||
else if (cyc == 21) begin
|
||||
`checks(e.name, ""); // Unknown
|
||||
s = $sformatf("%p", e);
|
||||
`checks(s, "17");
|
||||
end
|
||||
else if (cyc == 99) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@
|
|||
// verilog_format: on
|
||||
|
||||
module t (
|
||||
input clk
|
||||
);
|
||||
input clk
|
||||
);
|
||||
|
||||
typedef enum [3:0] {
|
||||
E01 = 1,
|
||||
|
|
@ -20,18 +20,12 @@ module t (
|
|||
E04 = 4
|
||||
} my_t;
|
||||
|
||||
integer cyc = 0;
|
||||
integer cyc = 0;
|
||||
my_t e;
|
||||
|
||||
int arrayfits[e.num]; // Check can use as constant
|
||||
int arrayfits [e.num]; // Check can use as constant
|
||||
|
||||
typedef struct {
|
||||
my_t m_a;
|
||||
my_t m_b;
|
||||
} mystr_t;
|
||||
mystr_t mystr;
|
||||
|
||||
string s;
|
||||
string all;
|
||||
|
||||
// Check constification
|
||||
initial begin
|
||||
|
|
@ -54,38 +48,25 @@ module t (
|
|||
`checkh(e.num, 3);
|
||||
`checks(e.name, "E03");
|
||||
//
|
||||
s = "";
|
||||
all = "";
|
||||
for (my_t e = e.first; e != e.last; e = e.next) begin
|
||||
s = {s, e.name};
|
||||
all = {all, e.name};
|
||||
end
|
||||
e = e.last;
|
||||
s = {s, e.name};
|
||||
`checks(s, "E01E03E04");
|
||||
//
|
||||
e = E04;
|
||||
s = $sformatf("%p", e);
|
||||
`checks(s, "E04");
|
||||
s = $sformatf("%p", E03);
|
||||
`checks(s, "E03");
|
||||
s = $sformatf("%s", E03); // Non-standard but majority
|
||||
`checks(s, "E03");
|
||||
//
|
||||
mystr.m_a = E03;
|
||||
mystr.m_b = E04;
|
||||
s = $sformatf("%p", mystr);
|
||||
`checks(s, "'{m_a:'h3, m_b:'h4}");
|
||||
all = {all, e.name};
|
||||
`checks(all, "E01E03E04");
|
||||
end
|
||||
|
||||
localparam THREE = 3;
|
||||
|
||||
// Check runtime
|
||||
always @(posedge clk) begin
|
||||
always @ (posedge clk) begin
|
||||
cyc <= cyc + 1;
|
||||
if (cyc == 0) begin
|
||||
if (cyc==0) begin
|
||||
// Setup
|
||||
e <= E01;
|
||||
end
|
||||
else if (cyc == 1) begin
|
||||
else if (cyc==1) begin
|
||||
`checks(e.name, "E01");
|
||||
`checkh(e.next, E03);
|
||||
`checkh(e.next(1), E03);
|
||||
|
|
@ -95,7 +76,7 @@ module t (
|
|||
`checkh(e.prev(2), E03);
|
||||
e <= E03;
|
||||
end
|
||||
else if (cyc == 2) begin
|
||||
else if (cyc==2) begin
|
||||
`checks(e.name, "E03");
|
||||
`checkh(e.next, E04);
|
||||
`checkh(e.next(1), E04);
|
||||
|
|
@ -105,7 +86,7 @@ module t (
|
|||
`checkh(e.prev(2), E04);
|
||||
e <= E04;
|
||||
end
|
||||
else if (cyc == 3) begin
|
||||
else if (cyc==3) begin
|
||||
`checks(e.name, "E04");
|
||||
`checkh(e.next, E01);
|
||||
`checkh(e.next(1), E01);
|
||||
|
|
@ -114,11 +95,8 @@ module t (
|
|||
`checkh(e.prev(1), E03);
|
||||
`checkh(e.prev(2), E01);
|
||||
e <= E01;
|
||||
//
|
||||
s = $sformatf("%p", e);
|
||||
`checks(s, "E04");
|
||||
end
|
||||
else if (cyc == 99) begin
|
||||
else if (cyc==99) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in New Issue