Enable simple function localparams (#2461)
This commit is contained in:
parent
a18d8cbe86
commit
1488f9130d
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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()) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
//
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue