diff --git a/Changes b/Changes index 0c5fadb3e..d5982a285 100644 --- a/Changes +++ b/Changes @@ -11,19 +11,21 @@ The contributors that suggested a given feature are shown in []. Thanks! *** Verilation speed improvements, #2133, #2138. [Geza Lore] -*** Support libgoogle-perftools-dev's libtcmalloc if available. #2137. [Geza Lore] +*** Support libgoogle-perftools-dev's libtcmalloc if available, #2137. [Geza Lore] -*** Support $readmem/$writemem with assoc arrarys. Closes #2100. [agrobman] +*** Support $readmem/$writemem with assoc arrarys, #2100. [agrobman] -**** Support left justified $display. Closes #2101. [Pieter Kapsenberg] +**** Support type(expression) operator, #1650. + +**** Support left justified $display, #2101. [Pieter Kapsenberg] **** Add parameter values in XML. #2110. [Pieter Kapsenberg] -**** Add loc column location in XML (replaces fl). #2122. [Pieter Kapsenberg] +**** Add loc column location in XML (replaces fl), #2122. [Pieter Kapsenberg] **** Add error on misused define. [Topa Tota] -**** Add parameter to set maximum signal width. #2082. [Øyvind Harboe] +**** Add parameter to set maximum signal width, #2082. [Øyvind Harboe] **** Fix VPI scope naming for public modules. [Nandu Raj] diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index 23cdc23a3..4724e4f29 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -859,6 +859,11 @@ public: dtypeFrom(defp->dtypep()); widthFromSub(subDTypep()); } + class FlagTypeOfExpr {}; // type(expr) for parser only + AstRefDType(FileLine* fl, FlagTypeOfExpr, AstNode* typeofp) + : ASTGEN_SUPER(fl), m_refDTypep(NULL), m_packagep(NULL) { + setOp2p(typeofp); + } ASTNODE_NODE_FUNCS(RefDType) // METHODS virtual const char* broken() const { BROKEN_RTN(m_refDTypep && !m_refDTypep->brokeExists()); return NULL; } @@ -901,6 +906,7 @@ public: virtual AstNodeDType* subDTypep() const { return m_refDTypep; } AstPackage* packagep() const { return m_packagep; } void packagep(AstPackage* nodep) { m_packagep = nodep; } + AstNode* typeofp() const { return op2p(); } }; class AstStructDType : public AstNodeUOrStructDType { diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index 5f2d0089e..8a73837ac 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -2487,7 +2487,8 @@ private: } else { checkNoDot(nodep); } - if (!nodep->defp()) { + if (nodep->typeofp()) { // Really is a typeof not a reference + } else if (!nodep->defp()) { VSymEnt* foundp; if (nodep->packagep()) { foundp = m_statep->getNodeSym(nodep->packagep())->findIdFlat(nodep->name()); diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 74678896f..83a3e306d 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -1261,6 +1261,15 @@ private: } if (nodep->didWidthAndSet()) return; // This node is a dtype & not both PRELIMed+FINALed nodep->doingWidth(true); + if (nodep->typeofp()) { // type(typeofp_expression) + // Type comes from expression's type + userIterateAndNext(nodep->typeofp(), WidthVP(SELF, BOTH).p()); + AstNode* typeofp = nodep->typeofp(); + nodep->refDTypep(typeofp->dtypep()); + VL_DO_DANGLING(typeofp->unlinkFrBack()->deleteTree(), typeofp); + // We had to use AstRefDType for this construct as pointers to this type + // in type table are still correct (which they wouldn't be if we replaced the node) + } userIterateChildren(nodep, NULL); if (nodep->subDTypep()) nodep->refDTypep(iterateEditDTypep(nodep, nodep->subDTypep())); // Effectively nodep->dtypeFrom(nodep->dtypeSkipRefp()); @@ -4175,7 +4184,7 @@ private: AstNode* spliceCvtD(AstNode* nodep) { // For integer used in REAL context, convert to real // We don't warn here, "2.0 * 2" is common and reasonable - if (nodep && !nodep->isDouble()) { + if (nodep && !nodep->dtypep()->skipRefp()->isDouble()) { UINFO(6," spliceCvtD: "<unlinkFrBack(&linker); @@ -4189,7 +4198,7 @@ private: AstNode* spliceCvtS(AstNode* nodep, bool warnOn) { // IEEE-2012 11.8.1: Signed: Type coercion creates signed // 11.8.2: Argument to convert is self-determined - if (nodep && nodep->isDouble()) { + if (nodep && nodep->dtypep()->skipRefp()->isDouble()) { UINFO(6," spliceCvtS: "<unlinkFrBack(&linker); diff --git a/src/verilog.y b/src/verilog.y index e502e49e4..ed976fda3 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -1566,7 +1566,7 @@ data_typeNoRef: // ==IEEE: data_type, excluding class_type etc referenc // // instead see data_typeVar | yVIRTUAL__INTERFACE yINTERFACE id/*interface*/ { $$ = NULL; BBUNSUP($1, "Unsupported: virtual interface"); } | yVIRTUAL__anyID id/*interface*/ { $$ = NULL; BBUNSUP($1, "Unsupported: virtual data type"); } - //UNSUP type_reference { UNSUP } + | type_reference { $$ = $1; } // // IEEE: class_scope: see data_type above // // IEEE: class_type: see data_type above // // IEEE: ps_covergroup: see data_type above @@ -1583,9 +1583,9 @@ var_data_type: // ==IEEE: var_data_type | yVAR implicit_typeE { $$ = $2; } ; -//UNSUP type_reference: // ==IEEE: type_reference -//UNSUP yTYPE '(' exprOrDataType ')' { UNSUP } -//UNSUP ; +type_reference: // ==IEEE: type_reference + yTYPE '(' exprOrDataType ')' { $$ = new AstRefDType($1, AstRefDType::FlagTypeOfExpr(), $3); } + ; struct_unionDecl: // IEEE: part of data_type // // packedSigningE is NOP for unpacked diff --git a/test_regress/t/t_type.pl b/test_regress/t/t_type.pl new file mode 100755 index 000000000..b1acebe26 --- /dev/null +++ b/test_regress/t/t_type.pl @@ -0,0 +1,20 @@ +#!/usr/bin/perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2004 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. + +scenarios(simulator => 1); + +compile( + ); + +execute( + check_finished => 1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_type.v b/test_regress/t/t_type.v new file mode 100644 index 000000000..f0f0e029f --- /dev/null +++ b/test_regress/t/t_type.v @@ -0,0 +1,21 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2020 by Wilson Snyder. + +module t(/*AUTOARG*/); + + real x; + real y; + var type(x+y) z; + + initial begin + x = 1.2; + y = 2.3; + z = x + y; + if (z != (1.2+2.3)) $stop; + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule