diff --git a/include/verilated.cpp b/include/verilated.cpp index ed2f44b7f..8c2896324 100644 --- a/include/verilated.cpp +++ b/include/verilated.cpp @@ -1088,6 +1088,7 @@ 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 strwide; WDataInP lwp{nullptr}; @@ -1108,6 +1109,34 @@ 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) { + // Always <= VL_QUADSIZE; emit uses non-ENUM format for wider enums + lbits = va_arg(ap, int); + ld = VL_VA_ARG_Q_(ap, lbits); + strwide.resize(2); + WDataOutP strwidep = WDataOutP::external(strwide.data()); + VL_SET_WQ(strwidep, ld); + lwp = strwidep; + lsb = lbits - 1; + ++argn; // Enum value is followed by the generated name string argument + static_cast(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(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); if (lbits <= VL_QUADSIZE) { @@ -1118,7 +1147,7 @@ void _vl_vsformat(std::string& output, const std::string& format, int argc, lwp = strwidep; } else { lwp = WDataInP::external(va_arg(ap, EData*)); - ld = lwp[0]; + ld = VL_SET_QW(lwp); // Low 64 bits, for %c/%t } if (fmt == 'p') { if (widthSet && width == 0) { // For %0p, IEEE our choice, use 'h%0h diff --git a/include/verilatedos.h b/include/verilatedos.h index 03cdd8bdb..f866a36ce 100644 --- a/include/verilatedos.h +++ b/include/verilatedos.h @@ -442,6 +442,7 @@ using ssize_t = uint32_t; ///< signed size_t; returned from read() #define VL_VFORMATATTR_SIGNED '~' // (int widthMin, IData/VlWide/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, IData/QData, std::string* name); <= 64 bit 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 diff --git a/src/V3EmitCFunc.cpp b/src/V3EmitCFunc.cpp index 5570825bd..8eb82b31f 100644 --- a/src/V3EmitCFunc.cpp +++ b/src/V3EmitCFunc.cpp @@ -344,7 +344,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()) + if (formatAttr.isSigned() || formatAttr.isUnsigned() || formatAttr.isEnum()) puts("," + cvtToStr(subargp->widthMin())); const bool addrof = isScan || formatAttr.isString() || formatAttr.isComplex(); puts(","); diff --git a/src/V3Number.h b/src/V3Number.h index 6aa51cd54..771f5edd4 100644 --- a/src/V3Number.h +++ b/src/V3Number.h @@ -46,6 +46,7 @@ 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 @@ -62,6 +63,7 @@ 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; } diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 00ed32999..18013533b 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -6505,7 +6505,17 @@ class WidthVisitor final : public VNVisitor { AstNodeExpr* const newp = new AstToStringN{argp->fileline(), argp}; formatAttr = VFormatAttr::COMPLEX; argp = newp; - } else if (dtypep->isSigned()) { + } 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()) { formatAttr = VFormatAttr::SIGNED; } if (VN_IS(argp, SFormatArg) // Already done @@ -8387,13 +8397,16 @@ 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; @@ -8401,7 +8414,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* const subargp = fargp ? fargp->exprp() : argp; + AstNodeExpr* subargp = fargp ? fargp->exprp() : argp; const AstNodeDType* const dtypep = subargp ? subargp->dtypep()->skipRefp() : nullptr; ch = std::tolower(ch); @@ -8458,7 +8471,34 @@ class WidthVisitor final : public VNVisitor { } break; case 'p': // FALLTHRU - case 's': // FALLTHRU + case 's': + // As with enum.name(): valid values print the mnemonic, else numeric + 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; default: // Most operators, just move to next argument argp = nextp; break; @@ -8469,6 +8509,18 @@ 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); + } + } + // Enums > 64 bits have no name table (see enumMaxValue); format as plain numbers + if (enumDtp && enumDtp->width() > VL_QUADSIZE) return nullptr; + return enumDtp; + } + //---------------------------------------------------------------------- // LOWER LEVEL WIDTH METHODS (none iterate) diff --git a/test_regress/t/t_class_enum.v b/test_regress/t/t_class_enum.v index bd30cd2f8..98c09b246 100644 --- a/test_regress/t/t_class_enum.v +++ b/test_regress/t/t_class_enum.v @@ -4,6 +4,11 @@ // 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; @@ -12,11 +17,32 @@ 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 diff --git a/test_regress/t/t_display_enum_format.py b/test_regress/t/t_display_enum_format.py new file mode 100755 index 000000000..8a938befd --- /dev/null +++ b/test_regress/t/t_display_enum_format.py @@ -0,0 +1,18 @@ +#!/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() diff --git a/test_regress/t/t_display_enum_format.v b/test_regress/t/t_display_enum_format.v new file mode 100644 index 000000000..78acce4d1 --- /dev/null +++ b/test_regress/t/t_display_enum_format.v @@ -0,0 +1,199 @@ +// 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; + // Enums > 64 bits are beyond enum.name() support, so %p/%s format numerically + typedef enum logic [95:0] { + W96A = 96'h1, + W96B = 96'hA_0000_0000_0000_0001 + } wide96_e; + typedef logic signed [4095:0] uvm_bitstream_t; + + my_e e; + wide64_e e64; + wide96_e e96; + logic [63:0] n64; + uvm_bitstream_t bitstream_value; +`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"); + // > 64-bit enums print numerically for %p (no name table support) + e96 = W96B; // 10 * 2**64 + 1 + if (empty_no_opt != "") e96 = W96A; // Defeat constant folding + `check($sformatf("%p", e96), "184467440737095516161"); + `check($sformatf("%0p", e96), "'ha0000000000000001"); + `check($sformatf("%0d", e96), "184467440737095516161"); + `check($sformatf("%0h", e96), "a0000000000000001"); + // 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"); + // > 64-bit enums use the non-ENUM format in runtime formats too + fmt = {"%", "p", empty_no_opt}; + `check($sformatf(fmt, e96), "184467440737095516161"); + fmt = {"%0d", empty_no_opt}; + `check($sformatf(fmt, e96), "184467440737095516161"); + bitstream_value = 30; + `check($sformatf("%0s%0t", "", bitstream_value), "30"); + bitstream_value = '0; + bitstream_value[32] = 1'b1; + `check($sformatf("%0s%0t", "", bitstream_value), "4294967296"); + bitstream_value = '0; + bitstream_value[63:0] = 64'h0000_0001_0000_0001; + `check($sformatf("%0s%0t", "", bitstream_value), "4294967297"); + bitstream_value[7:0] = "A"; + // verilator lint_off WIDTHTRUNC + `check($sformatf("%c", bitstream_value), "A"); + // verilator lint_on WIDTHTRUNC + + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule diff --git a/test_regress/t/t_enum_huge_methods.v b/test_regress/t/t_enum_huge_methods.v index 06e64eef4..0d9afe845 100644 --- a/test_regress/t/t_enum_huge_methods.v +++ b/test_regress/t/t_enum_huge_methods.v @@ -22,7 +22,7 @@ module t ( integer cyc = 0; my_t e; - string all; + string s; int i_cast; // Check runtime @@ -45,6 +45,10 @@ 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 // @@ -68,6 +72,8 @@ 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"); diff --git a/test_regress/t/t_enum_large_methods.v b/test_regress/t/t_enum_large_methods.v index c8fbb2a16..ca0882ff7 100644 --- a/test_regress/t/t_enum_large_methods.v +++ b/test_regress/t/t_enum_large_methods.v @@ -22,7 +22,7 @@ module t ( integer cyc = 0; my_t e; - string all; + string s; // Check runtime always @(posedge clk) begin @@ -40,6 +40,8 @@ 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 @@ -47,6 +49,8 @@ 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"); diff --git a/test_regress/t/t_enum_type_methods.v b/test_regress/t/t_enum_type_methods.v index 210c668a5..fd295b1ce 100644 --- a/test_regress/t/t_enum_type_methods.v +++ b/test_regress/t/t_enum_type_methods.v @@ -11,8 +11,8 @@ // verilog_format: on module t ( - input clk - ); + input clk +); typedef enum [3:0] { E01 = 1, @@ -20,12 +20,18 @@ 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 - string all; + typedef struct { + my_t m_a; + my_t m_b; + } mystr_t; + mystr_t mystr; + + string s; // Check constification initial begin @@ -48,25 +54,38 @@ module t ( `checkh(e.num, 3); `checks(e.name, "E03"); // - all = ""; + s = ""; for (my_t e = e.first; e != e.last; e = e.next) begin - all = {all, e.name}; + s = {s, e.name}; end e = e.last; - all = {all, e.name}; - `checks(all, "E01E03E04"); + 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}"); 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); @@ -76,7 +95,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); @@ -86,7 +105,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); @@ -95,8 +114,11 @@ 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