diff --git a/Changes b/Changes index 1bcdbcd81..4f92d4afe 100644 --- a/Changes +++ b/Changes @@ -12,9 +12,12 @@ indicates the contributor was also the author of the fix; Thanks! *** Support bind, to module names only, bug602. [Ed Lander] -*** Fix pin width mismatch error, bug595. [Alex Solomatnikov] +*** Define SYSTEMVERILOG, SV_COV_START and other IEEE mandated predefines. + +**** Fix pin width mismatch error, bug595. [Alex Solomatnikov] + +**** Fix implicit one bit parameter selection, bug603. [Jeremy Bennett] -**** Define SYSTEMVERILOG, SV_COV_START and other IEEE mandated predefines. * Verilator 3.844 2013/01/09 diff --git a/src/V3Ast.cpp b/src/V3Ast.cpp index 9367590b8..f84254154 100644 --- a/src/V3Ast.cpp +++ b/src/V3Ast.cpp @@ -1099,6 +1099,10 @@ AstNodeDType* AstNode::findLogicDType(int width, int widthMin, AstNumeric numeri return v3Global.rootp()->typeTablep() ->findLogicBitDType(fileline(), AstBasicDTypeKwd::LOGIC, width, widthMin, numeric); } +AstNodeDType* AstNode::findLogicRangeDType(VNumRange range, int widthMin, AstNumeric numeric) const { + return v3Global.rootp()->typeTablep() + ->findLogicBitDType(fileline(), AstBasicDTypeKwd::LOGIC, range, widthMin, numeric); +} AstBasicDType* AstNode::findInsertSameDType(AstBasicDType* nodep) { return v3Global.rootp()->typeTablep() ->findInsertSameDType(nodep); diff --git a/src/V3Ast.h b/src/V3Ast.h index 18dc50a1b..b56b48619 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -551,6 +551,9 @@ struct VNumRange { } // VNumRange() : m_msb(0), m_lsb(0), mu_flags(0) {} + VNumRange(int msb, int lsb, bool littleEndian) + : m_msb(0), m_lsb(0), mu_flags(0) + { init(msb,lsb,littleEndian); } ~VNumRange() {} // MEMBERS void init(int msb, int lsb, bool littleEndian) { @@ -1076,6 +1079,7 @@ public: AstNodeDType* findUInt64DType() { return findBasicDType(AstBasicDTypeKwd::UINT64); } // Twostate AstNodeDType* findBitDType(int width, int widthMin, AstNumeric numeric) const; AstNodeDType* findLogicDType(int width, int widthMin, AstNumeric numeric) const; + AstNodeDType* findLogicRangeDType(VNumRange range, int widthMin, AstNumeric numeric) const; AstNodeDType* findBasicDType(AstBasicDTypeKwd kwd) const; AstBasicDType* findInsertSameDType(AstBasicDType* nodep); diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 734000288..0e465a305 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -557,6 +557,15 @@ AstBasicDType* AstTypeTable::findLogicBitDType(FileLine* fl, AstBasicDTypeKwd kw return newp; } +AstBasicDType* AstTypeTable::findLogicBitDType(FileLine* fl, AstBasicDTypeKwd kwd, + VNumRange range, int widthMin, AstNumeric numeric) { + AstBasicDType* new1p = new AstBasicDType(fl, kwd, numeric, range, widthMin); + AstBasicDType* newp = findInsertSameDType(new1p); + if (newp != new1p) new1p->deleteTree(); + else addTypesp(newp); + return newp; +} + AstBasicDType* AstTypeTable::findInsertSameDType(AstBasicDType* nodep) { VBasicTypeKey key (nodep->width(), nodep->widthMin(), nodep->numeric(), nodep->keyword(), nodep->nrange()); diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index 98d09db36..8e46ff6b6 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -302,6 +302,11 @@ public: : AstNodeDType(fl) { init(kwd, numer, wantwidth, widthmin, NULL); } + AstBasicDType(FileLine* fl, AstBasicDTypeKwd kwd, AstNumeric numer, VNumRange range, int widthmin) + : AstNodeDType(fl) { + init(kwd, numer, range.elements(), widthmin, NULL); + m.m_nrange = range; // as init() presumes lsb==0, but range.lsb() might not be + } // See also addRange in verilog.y private: void init(AstBasicDTypeKwd kwd, AstNumeric numer, @@ -4482,6 +4487,8 @@ public: AstBasicDType* findBasicDType(FileLine* fl, AstBasicDTypeKwd kwd); AstBasicDType* findLogicBitDType(FileLine* fl, AstBasicDTypeKwd kwd, int width, int widthMin, AstNumeric numeric); + AstBasicDType* findLogicBitDType(FileLine* fl, AstBasicDTypeKwd kwd, + VNumRange range, int widthMin, AstNumeric numeric); AstBasicDType* findInsertSameDType(AstBasicDType* nodep); void clearCache(); void repairCache(); diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 0a14a5065..9f151b784 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -840,7 +840,17 @@ private: width = 32; } // Can't just inherit valuep()->dtypep() as mwidth might not equal width - nodep->dtypeChgWidthSigned(width, nodep->valuep()->widthMin(),issigned); + if (width==1) { + // one bit parameter is same as "parameter [0] foo", not "parameter logic foo" + // as you can extract "foo[0]" from a parameter but not a wire + nodep->dtypeChgWidthSigned(width, nodep->valuep()->widthMin(),issigned); + nodep->dtypep(nodep->findLogicRangeDType + (VNumRange(0,0,false), + nodep->valuep()->widthMin(), + issigned?AstNumeric::SIGNED : AstNumeric::UNSIGNED)); + } else { + nodep->dtypeChgWidthSigned(width, nodep->valuep()->widthMin(),issigned); + } didchk = true; nodep->valuep()->iterateAndNext(*this,WidthVP(width,nodep->widthMin(),FINAL).p()); } diff --git a/src/V3WidthSel.cpp b/src/V3WidthSel.cpp index 7e296e56a..d323be581 100644 --- a/src/V3WidthSel.cpp +++ b/src/V3WidthSel.cpp @@ -104,10 +104,7 @@ private: false); // big endian } else if (AstBasicDType* adtypep = ddtypep->castBasicDType()) { - if (!adtypep->isRanged()) { - nodep->v3error("Illegal bit or array select; type does not have a bit range, or bad dimension: type is " - <prettyName()); - } else { + if (adtypep->isRanged()) { if (adtypep->rangep() && (!adtypep->rangep()->msbp()->castConst() || !adtypep->rangep()->lsbp()->castConst())) @@ -115,6 +112,9 @@ private: fromRange.init(adtypep->msb(), adtypep->lsb(), adtypep->littleEndian()); + } else { + nodep->v3error("Illegal bit or array select; type does not have a bit range, or bad dimension: type is " + <prettyName()); } } else { diff --git a/test_regress/t/t_param_bit_sel.pl b/test_regress/t/t_param_bit_sel.pl new file mode 100755 index 000000000..f91289753 --- /dev/null +++ b/test_regress/t/t_param_bit_sel.pl @@ -0,0 +1,18 @@ +#!/usr/bin/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. + +compile ( + ); + +execute ( + check_finished=>1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_param_bit_sel.v b/test_regress/t/t_param_bit_sel.v new file mode 100644 index 000000000..f28d56c88 --- /dev/null +++ b/test_regress/t/t_param_bit_sel.v @@ -0,0 +1,32 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// We see Verilator assumes a 1-bit parameter is a scalar rather than a 1-bit +// long vector. This causes the following code to fail. +// +// Other event drive simulators accept this. +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2013 by Jeremy Bennett. + +module t (/*AUTOARG*/ + // Inputs + clk + ); + input clk; + + // At this point it is ambiguous whether a is scalar or vector + parameter a = 1'b0; + wire b = a[0]; + // Note however b[0] is illegal. + + always @(posedge clk) begin + if (b == 1'b0) begin + $write("*-* All Finished *-*\n"); + $finish; + end + else begin + $stop; + end + end + +endmodule