mirror of
https://github.com/verilator/verilator.git
synced 2025-01-22 14:24:18 +00:00
Explicitly size all parameters, even if not used for module cells
This commit is contained in:
parent
556d90a1b4
commit
510fe8e634
@ -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: ");
|
||||
}
|
||||
|
@ -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: ");
|
||||
|
@ -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() {}
|
||||
};
|
||||
|
21
test_regress/t/t_func_const_bad.pl
Executable file
21
test_regress/t/t_func_const_bad.pl
Executable 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;
|
28
test_regress/t/t_func_const_bad.v
Normal file
28
test_regress/t/t_func_const_bad.v
Normal 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
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user