Explicitly size all parameters, even if not used for module cells

This commit is contained in:
Wilson Snyder 2009-07-16 14:49:34 -04:00
parent 556d90a1b4
commit 510fe8e634
6 changed files with 76 additions and 5 deletions

View File

@ -1713,7 +1713,14 @@ void V3Const::constifyParam(AstNode* nodep) {
V3Signed::signedParams(nodep);
}
ConstVisitor visitor (true,false,false,false);
visitor.main(nodep);
if (AstVar* varp=nodep->castVar()) {
// If a var wants to be constified, it's really a param, and
// we want the value to be constant. We aren't passed just the
// init value because we need widthing above to handle the var's type.
if (varp->initp()) visitor.main(varp->initp());
} else {
visitor.main(nodep);
}
// Because we do edits, nodep links may get trashed and core dump this.
//if (debug()>0) nodep->dumpTree(cout," forceConDONE: ");
}

View File

@ -127,6 +127,14 @@ private:
}
virtual void visit(AstCell* nodep, AstNUser*);
// Make sure all parameters are constantified
virtual void visit(AstVar* nodep, AstNUser*) {
if (nodep->isParam()) {
if (!nodep->hasSimpleInit()) { nodep->v3fatalSrc("Parameter without initial value"); }
V3Const::constifyParam(nodep); // The variable, not just the var->init()
}
}
// Generate Statements
virtual void visit(AstGenerate* nodep, AstNUser*) {
if (debug()>=9) nodep->dumpTree(cout,"-genin: ");

View File

@ -442,6 +442,8 @@ private:
virtual void visit(AstVar* nodep, AstNUser* vup) {
//if (debug()) nodep->dumpTree(cout," InitPre: ");
// Must have deterministic constant width
// We can't skip this step when width()!=0, as creating a AstVar
// with non-constant range gets size 1, not size 0.
int width=1; int mwidth=1;
nodep->arraysp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
if (nodep->rangep()) {
@ -457,8 +459,11 @@ private:
}
if (nodep->initp()) {
nodep->initp()->iterateAndNext(*this,WidthVP(width,0,BOTH).p());
if (nodep->isParam() && !nodep->rangep()) {
if (nodep->initp()->widthSized()) {
if (nodep->isParam()) {
if (nodep->rangep()) {
// Parameters need to preserve widthMin from the value, not get a constant size
mwidth = nodep->initp()->widthMin();
} else if (nodep->initp()->widthSized()) {
width = mwidth = nodep->initp()->width();
} else {
if (nodep->initp()->width()>32) nodep->initp()->v3warn(WIDTH,"Assigning >32 bit to unranged parameter (defaults to 32 bits)\n");
@ -847,7 +852,7 @@ public:
m_taskDepth = 0;
m_cellRangep = NULL;
m_casep = NULL;
nodep->accept(*this);
nodep->accept(*this, WidthVP(ANYSIZE,0,BOTH).p());
}
virtual ~WidthVisitor() {}
};

View File

@ -0,0 +1,21 @@
#!/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 (
v_flags2 => ["--lint-only"],
fails=>1,
expect=>
q{%Error: t/t_func_const_bad.v:\d+: Expecting expression to be constant, but can't convert a FUNCREF 'f_bad_output' to constant.
%Error: t/t_func_const_bad.v:\d+: Expecting expression to be constant, but can't convert a FUNCREF 'f_bad_dotted' to constant.
%Error: t/t_func_const_bad.v:\d+: Expecting expression to be constant, but can't convert a FUNCREF 'f_bad_nonparam' to constant.
%Error: Exiting due to.*},
);
ok(1);
1;

View File

@ -0,0 +1,28 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2009 by Wilson Snyder.
module t;
// Speced ignored: system calls. I think this is nasty, so we error instead.
// Speced Illegal: inout/output/ref not allowed
localparam B1 = f_bad_output(1,2);
function integer f_bad_output(input [31:0] a, output [31:0] o);
f_bad_output = 0;
endfunction
// Speced Illegal: void
// Speced Illegal: dotted
localparam EIGHT = 8;
localparam B2 = f_bad_dotted(2);
function integer f_bad_dotted(input [31:0] a);
f_bad_dotted = t.EIGHT;
endfunction
// Speced Illegal: ref to non-local var
integer modvar;
localparam B3 = f_bad_nonparam(3);
function integer f_bad_nonparam(input [31:0] a);
f_bad_nonparam = modvar;
endfunction
// Speced Illegal: needs constant function itself
endmodule

View File

@ -36,8 +36,10 @@ module t (/*AUTOARG*/
endmodule
module m1;
localparam PAR1MINUS1 = PAR1DUP-2-1;
localparam PAR1DUP = PAR1+2; // Check we propagate parameters properly
parameter PAR1 = 0;
m2 #(PAR1-1) m2 ();
m2 #(PAR1MINUS1) m2 ();
endmodule
module m2;