Enable simple function localparams (#2461)

This commit is contained in:
Wilson Snyder 2020-07-15 19:31:19 -04:00
parent a18d8cbe86
commit 1488f9130d
6 changed files with 95 additions and 12 deletions

View File

@ -55,7 +55,7 @@ public:
}
virtual ~VerilatedSerialize() {
close();
if (m_bufp) VL_DO_CLEAR(delete [] m_bufp, m_bufp = NULL);
if (m_bufp) VL_DO_CLEAR(delete[] m_bufp, m_bufp = NULL);
}
// METHODS
bool isOpen() const { return m_isOpen; }
@ -118,7 +118,7 @@ public:
}
virtual ~VerilatedDeserialize() {
close();
if (m_bufp) VL_DO_CLEAR(delete [] m_bufp, m_bufp = NULL);
if (m_bufp) VL_DO_CLEAR(delete[] m_bufp, m_bufp = NULL);
}
// METHODS
bool isOpen() const { return m_isOpen; }

View File

@ -1008,12 +1008,6 @@ class LinkDotFindVisitor : public AstNVisitor {
// Var: Remember its name for later resolution
UASSERT_OBJ(m_curSymp && m_modSymp, nodep, "Var not under module?");
iterateChildren(nodep);
if (m_ftaskp && nodep->isParam()) {
nodep->v3warn(E_UNSUPPORTED,
"Unsupported: Parameters in functions"); // Big3 unsupported too
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
return;
}
if (nodep->isFuncLocal() && nodep->lifetime().isStatic()) {
nodep->v3warn(E_UNSUPPORTED, "Unsupported: 'static' function/task variables");
} else if (nodep->isClassMember() && nodep->lifetime().isStatic()) {

View File

@ -106,6 +106,8 @@ private:
typedef std::deque<AstCell*> CellList;
CellList m_cellps; // Cells left to process (in this module)
AstNodeFTask* m_ftaskp; // Function/task reference
AstNodeModule* m_modp; // Current module being processed
string m_unlinkedTxt; // Text for AstUnlinkedRef
@ -302,6 +304,11 @@ private:
nodep->user5p(genHierNamep);
m_cellps.push_back(nodep);
}
virtual void visit(AstNodeFTask* nodep) VL_OVERRIDE {
m_ftaskp = nodep;
iterateChildren(nodep);
m_ftaskp = NULL;
}
// Make sure all parameters are constantified
virtual void visit(AstVar* nodep) VL_OVERRIDE {
@ -323,6 +330,16 @@ private:
new AstAssign(nodep->fileline(),
new AstVarRef(nodep->fileline(), nodep, true),
nodep->valuep()->cloneTree(true))));
if (m_ftaskp) {
// We put the initial in wrong place under a function. We
// should move the parameter out of the function and to the
// module, with appropriate dotting, but this confuses LinkDot
// (as then name isn't found later), so punt - probably can
// treat as static function variable when that is supported.
nodep->v3warn(
E_UNSUPPORTED,
"Unsupported: Parameters in functions with complex assign");
}
}
}
}
@ -556,6 +573,7 @@ public:
// CONSTRUCTORS
explicit ParamVisitor(AstNetlist* nodep) {
m_longId = 0;
m_ftaskp = NULL;
m_modp = NULL;
m_nextValue = 1;
//

21
test_regress/t/t_param_func2.pl Executable file
View File

@ -0,0 +1,21 @@
#!/usr/bin/env 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.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
scenarios(simulator => 1);
compile(
);
execute(
check_finished => 1,
);
ok(1);
1;

View File

@ -0,0 +1,52 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2020 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
module t;
sub #(.WIDTH(4)) sub4();
sub #(.WIDTH(8)) sub8();
logic [3:0] out4;
logic [7:0] out8;
initial begin
out4 = sub4.orer(4'b1000);
out8 = sub8.orer(8'b10000000);
if (out4 != 4'b1011) $stop;
if (out8 != 8'b10111111) $stop;
out4 = sub4.orer2(4'b1000);
out8 = sub8.orer2(8'b10000000);
if (out4 != 4'b1001) $stop;
if (out8 != 8'b10011111) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
endmodule
module sub;
parameter WIDTH = 1;
function [WIDTH-1:0] orer;
input [WIDTH-1:0] in;
// IEEE provices no way to override this parameter, basically it's a localparam
parameter MASK_W = WIDTH - 2;
localparam [MASK_W-1:0] MASK = '1;
// verilator lint_off WIDTH
return in | MASK;
// verilator lint_on WIDTH
endfunction
function [WIDTH-1:0] orer2;
input [WIDTH-1:0] in;
// Same param names as other function to check we disambiguate
// IEEE provices no way to override this parameter, basically it's a localparam
parameter MASK_W = WIDTH - 3;
localparam [MASK_W-1:0] MASK = '1;
// verilator lint_off WIDTH
return in | MASK;
// verilator lint_on WIDTH
endfunction
endmodule

View File

@ -1,7 +1,5 @@
%Error-UNSUPPORTED: t/t_param_in_func_bad.v:24:26: Unsupported: Parameters in functions
%Error-UNSUPPORTED: t/t_param_in_func_bad.v:24:26: Unsupported: Parameters in functions with complex assign
: ... In instance t
24 | localparam logic[7:0] digits[10]
| ^~~~~~
%Error: t/t_param_in_func_bad.v:28:11: Can't find definition of variable: 'digits'
28 | return digits[d];
| ^~~~~~
%Error: Exiting due to