forked from github/verilator
Fix implicit one bit parameter selection, bug603.
This commit is contained in:
parent
f0a4bd28b6
commit
6d1b42bedb
7
Changes
7
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
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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());
|
||||
|
@ -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();
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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 "
|
||||
<<errp->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 "
|
||||
<<errp->prettyName());
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
18
test_regress/t/t_param_bit_sel.pl
Executable file
18
test_regress/t/t_param_bit_sel.pl
Executable file
@ -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;
|
32
test_regress/t/t_param_bit_sel.v
Normal file
32
test_regress/t/t_param_bit_sel.v
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user