Support complex function arguments.

This commit is contained in:
Wilson Snyder 2020-11-28 13:46:14 -05:00
parent 30686d8550
commit 9a9931fb9d
10 changed files with 163 additions and 24 deletions

View File

@ -5,16 +5,18 @@ The contributors that suggested a given feature are shown in []. Thanks!
* Verilator 4.105 devel
*** Change -sv option to select 1800-2017 instead of 1800-2005.
** Change -sv option to select 1800-2017 instead of 1800-2005.
*** Check for proper 'local' and 'protected' (#2228).
*** Support $random and $urandom seeds.
*** Support complex function arguments.
*** Support 'super'.
*** Support 'with item.index'.
*** Check for proper 'local' and 'protected' (#2228).
**** Fix trace signal names getting hashed (#2643). [Barbara Gigerl]
**** Fix unpacked array parameters near functions (#2639). [Anderson Ignacio da Silva]

View File

@ -154,6 +154,7 @@ public:
// METHODS
T_Value& atDefault() { return m_defaultValue; }
const T_Value& atDefault() const { return m_defaultValue; }
const Deque& privateDeque() const { return m_deque; }
// Size. Verilog: function int size(), or int num()
@ -512,6 +513,7 @@ public:
// METHODS
T_Value& atDefault() { return m_defaultValue; }
const T_Value& atDefault() const { return m_defaultValue; }
// Size of array. Verilog: function int size(), or int num()
int size() const { return m_map.size(); }

View File

@ -395,7 +395,8 @@ public:
virtual AstNodeDType* skipRefToEnump() const override { return subDTypep()->skipRefToEnump(); }
virtual bool similarDType(AstNodeDType* samep) const override {
const AstParamTypeDType* sp = static_cast<const AstParamTypeDType*>(samep);
return (sp && this->subDTypep()->skipRefp()->similarDType(sp->subDTypep()->skipRefp()));
return type() == samep->type() && sp
&& this->subDTypep()->skipRefp()->similarDType(sp->subDTypep()->skipRefp());
}
virtual int widthAlignBytes() const override { return dtypep()->widthAlignBytes(); }
virtual int widthTotalBytes() const override { return dtypep()->widthTotalBytes(); }
@ -545,8 +546,8 @@ public:
}
virtual bool similarDType(AstNodeDType* samep) const override {
const AstAssocArrayDType* asamep = static_cast<const AstAssocArrayDType*>(samep);
if (!asamep->subDTypep()) return false;
return (subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp()));
return type() == samep->type() && asamep->subDTypep()
&& subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp());
}
virtual string prettyDTypeName() const override;
virtual void dumpSmall(std::ostream& str) const override;
@ -643,8 +644,8 @@ public:
}
virtual bool similarDType(AstNodeDType* samep) const override {
const AstAssocArrayDType* asamep = static_cast<const AstAssocArrayDType*>(samep);
if (!asamep->subDTypep()) return false;
return (subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp()));
return type() == samep->type() && asamep->subDTypep()
&& subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp());
}
virtual string prettyDTypeName() const override;
virtual void dumpSmall(std::ostream& str) const override;
@ -753,8 +754,8 @@ public:
}
virtual bool similarDType(AstNodeDType* samep) const override {
const AstNodeArrayDType* asamep = static_cast<const AstNodeArrayDType*>(samep);
if (!asamep->subDTypep()) return false;
return (subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp()));
return type() == samep->type() && asamep->subDTypep()
&& subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp());
}
virtual void dumpSmall(std::ostream& str) const override;
virtual V3Hash sameHash() const override { return V3Hash(m_refDTypep); }
@ -1013,7 +1014,7 @@ public:
return (m_classp == asamep->m_classp && m_classOrPackagep == asamep->m_classOrPackagep);
}
virtual bool similarDType(AstNodeDType* samep) const override {
return this == samep || same(samep);
return this == samep || (type() == samep->type() && same(samep));
}
virtual V3Hash sameHash() const override {
return V3Hash(V3Hash(m_classp), V3Hash(m_classOrPackagep));
@ -1127,8 +1128,8 @@ public:
}
virtual bool similarDType(AstNodeDType* samep) const override {
const AstQueueDType* asamep = static_cast<const AstQueueDType*>(samep);
if (!asamep->subDTypep()) return false;
return (subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp()));
return type() == samep->type() && asamep->subDTypep()
&& subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp());
}
virtual void dumpSmall(std::ostream& str) const override;
virtual V3Hash sameHash() const override { return V3Hash(m_refDTypep); }

View File

@ -1787,13 +1787,6 @@ private:
nodep->dtypep(newp);
v3Global.rootp()->typeTablep()->addTypesp(newp);
}
} else if (nodep->isIO()
&& !(VN_IS(nodep->dtypeSkipRefp(), BasicDType)
|| VN_IS(nodep->dtypeSkipRefp(), ClassRefDType)
|| VN_IS(nodep->dtypeSkipRefp(), NodeArrayDType)
|| VN_IS(nodep->dtypeSkipRefp(), NodeUOrStructDType))) {
nodep->v3warn(E_UNSUPPORTED,
"Unsupported: Inputs and outputs must be simple data types");
}
if (VN_IS(nodep->dtypep()->skipRefToConstp(), ConstDType)) nodep->isConst(true);
// Parameters if implicit untyped inherit from what they are assigned to
@ -1999,7 +1992,7 @@ private:
}
virtual void visit(AstConsAssoc* nodep) override {
// Type computed when constructed here
auto* vdtypep = VN_CAST(m_vup->dtypep(), AssocArrayDType);
auto* vdtypep = VN_CAST(m_vup->dtypep()->skipRefp(), AssocArrayDType);
UASSERT_OBJ(vdtypep, nodep, "ConsAssoc requires assoc upper parent data type");
if (m_vup->prelim()) {
nodep->dtypeFrom(vdtypep);
@ -2011,7 +2004,7 @@ private:
}
virtual void visit(AstSetAssoc* nodep) override {
// Type computed when constructed here
auto* vdtypep = VN_CAST(m_vup->dtypep(), AssocArrayDType);
auto* vdtypep = VN_CAST(m_vup->dtypep()->skipRefp(), AssocArrayDType);
UASSERT_OBJ(vdtypep, nodep, "SetsAssoc requires assoc upper parent data type");
if (m_vup->prelim()) {
nodep->dtypeFrom(vdtypep);
@ -2024,7 +2017,7 @@ private:
}
virtual void visit(AstConsDynArray* nodep) override {
// Type computed when constructed here
AstDynArrayDType* vdtypep = VN_CAST(m_vup->dtypep(), DynArrayDType);
AstDynArrayDType* vdtypep = VN_CAST(m_vup->dtypep()->skipRefp(), DynArrayDType);
UASSERT_OBJ(vdtypep, nodep, "ConsDynArray requires queue upper parent data type");
if (m_vup->prelim()) {
userIterateAndNext(nodep->lhsp(), WidthVP(vdtypep, PRELIM).p());
@ -2056,7 +2049,7 @@ private:
}
virtual void visit(AstConsQueue* nodep) override {
// Type computed when constructed here
AstQueueDType* vdtypep = VN_CAST(m_vup->dtypep(), QueueDType);
AstQueueDType* vdtypep = VN_CAST(m_vup->dtypep()->skipRefp(), QueueDType);
UASSERT_OBJ(vdtypep, nodep, "ConsQueue requires queue upper parent data type");
if (m_vup->prelim()) {
userIterateAndNext(nodep->lhsp(), WidthVP(vdtypep, PRELIM).p());

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,54 @@
// 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();
typedef integer q_t[$];
function void queue_set(ref q_t q);
`ifdef TEST_NOINLINE
// verilator no_inline_task
`endif
q.push_back(42);
endfunction
function void queue_check_nref(q_t q);
`ifdef TEST_NOINLINE
// verilator no_inline_task
`endif
q[0] = 11;
if (q[0] != 11) $stop;
endfunction
function void queue_check_ref(const ref q_t q);
`ifdef TEST_NOINLINE
// verilator no_inline_task
`endif
if (q[0] != 42) $stop;
endfunction
function q_t queue_ret();
`ifdef TEST_NOINLINE
// verilator no_inline_task
`endif
queue_ret = '{101};
endfunction
initial begin
q_t iq;
queue_set(iq);
queue_check_ref(iq);
iq[0] = 44;
queue_check_nref(iq);
if (iq[0] != 44) $stop;
iq = queue_ret();
if (iq[0] != 101) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
endmodule

View File

@ -0,0 +1,24 @@
#!/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
top_filename("t/t_func_complex.v");
scenarios(simulator => 1);
compile(
v_flags2 => ["+define+TEST_NOINLINE"],
);
execute(
check_finished => 1,
);
ok(1);
1;

View File

@ -0,0 +1,5 @@
%Error: t/t_func_refio_bad.v:16:17: Ref argument requires matching types; port 'q' requires VAR 'q' but connection is CONST '?32?sh2a'.
: ... In instance t
16 | queue_set(42);
| ^~
%Error: Exiting due to

View File

@ -0,0 +1,19 @@
#!/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(linter => 1);
lint(
fails => $Self->{vlt_all},
expect_filename => $Self->{golden_filename},
);
ok(1);
1;

View File

@ -0,0 +1,18 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2020 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
module t();
typedef integer q_t[$];
function void queue_set(ref q_t q);
q.push_back(42);
endfunction
initial begin
q_t iq;
queue_set(42); // 42 is bad, meant iq
end
endmodule