Support complex function arguments.
This commit is contained in:
parent
30686d8550
commit
9a9931fb9d
8
Changes
8
Changes
|
|
@ -5,16 +5,18 @@ The contributors that suggested a given feature are shown in []. Thanks!
|
||||||
|
|
||||||
* Verilator 4.105 devel
|
* 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 $random and $urandom seeds.
|
||||||
|
|
||||||
|
*** Support complex function arguments.
|
||||||
|
|
||||||
*** Support 'super'.
|
*** Support 'super'.
|
||||||
|
|
||||||
*** Support 'with item.index'.
|
*** Support 'with item.index'.
|
||||||
|
|
||||||
*** Check for proper 'local' and 'protected' (#2228).
|
|
||||||
|
|
||||||
**** Fix trace signal names getting hashed (#2643). [Barbara Gigerl]
|
**** Fix trace signal names getting hashed (#2643). [Barbara Gigerl]
|
||||||
|
|
||||||
**** Fix unpacked array parameters near functions (#2639). [Anderson Ignacio da Silva]
|
**** Fix unpacked array parameters near functions (#2639). [Anderson Ignacio da Silva]
|
||||||
|
|
|
||||||
|
|
@ -154,6 +154,7 @@ public:
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
T_Value& atDefault() { return m_defaultValue; }
|
T_Value& atDefault() { return m_defaultValue; }
|
||||||
|
const T_Value& atDefault() const { return m_defaultValue; }
|
||||||
const Deque& privateDeque() const { return m_deque; }
|
const Deque& privateDeque() const { return m_deque; }
|
||||||
|
|
||||||
// Size. Verilog: function int size(), or int num()
|
// Size. Verilog: function int size(), or int num()
|
||||||
|
|
@ -512,6 +513,7 @@ public:
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
T_Value& atDefault() { return m_defaultValue; }
|
T_Value& atDefault() { return m_defaultValue; }
|
||||||
|
const T_Value& atDefault() const { return m_defaultValue; }
|
||||||
|
|
||||||
// Size of array. Verilog: function int size(), or int num()
|
// Size of array. Verilog: function int size(), or int num()
|
||||||
int size() const { return m_map.size(); }
|
int size() const { return m_map.size(); }
|
||||||
|
|
|
||||||
|
|
@ -395,7 +395,8 @@ public:
|
||||||
virtual AstNodeDType* skipRefToEnump() const override { return subDTypep()->skipRefToEnump(); }
|
virtual AstNodeDType* skipRefToEnump() const override { return subDTypep()->skipRefToEnump(); }
|
||||||
virtual bool similarDType(AstNodeDType* samep) const override {
|
virtual bool similarDType(AstNodeDType* samep) const override {
|
||||||
const AstParamTypeDType* sp = static_cast<const AstParamTypeDType*>(samep);
|
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 widthAlignBytes() const override { return dtypep()->widthAlignBytes(); }
|
||||||
virtual int widthTotalBytes() const override { return dtypep()->widthTotalBytes(); }
|
virtual int widthTotalBytes() const override { return dtypep()->widthTotalBytes(); }
|
||||||
|
|
@ -545,8 +546,8 @@ public:
|
||||||
}
|
}
|
||||||
virtual bool similarDType(AstNodeDType* samep) const override {
|
virtual bool similarDType(AstNodeDType* samep) const override {
|
||||||
const AstAssocArrayDType* asamep = static_cast<const AstAssocArrayDType*>(samep);
|
const AstAssocArrayDType* asamep = static_cast<const AstAssocArrayDType*>(samep);
|
||||||
if (!asamep->subDTypep()) return false;
|
return type() == samep->type() && asamep->subDTypep()
|
||||||
return (subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp()));
|
&& subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp());
|
||||||
}
|
}
|
||||||
virtual string prettyDTypeName() const override;
|
virtual string prettyDTypeName() const override;
|
||||||
virtual void dumpSmall(std::ostream& str) const override;
|
virtual void dumpSmall(std::ostream& str) const override;
|
||||||
|
|
@ -643,8 +644,8 @@ public:
|
||||||
}
|
}
|
||||||
virtual bool similarDType(AstNodeDType* samep) const override {
|
virtual bool similarDType(AstNodeDType* samep) const override {
|
||||||
const AstAssocArrayDType* asamep = static_cast<const AstAssocArrayDType*>(samep);
|
const AstAssocArrayDType* asamep = static_cast<const AstAssocArrayDType*>(samep);
|
||||||
if (!asamep->subDTypep()) return false;
|
return type() == samep->type() && asamep->subDTypep()
|
||||||
return (subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp()));
|
&& subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp());
|
||||||
}
|
}
|
||||||
virtual string prettyDTypeName() const override;
|
virtual string prettyDTypeName() const override;
|
||||||
virtual void dumpSmall(std::ostream& str) const override;
|
virtual void dumpSmall(std::ostream& str) const override;
|
||||||
|
|
@ -753,8 +754,8 @@ public:
|
||||||
}
|
}
|
||||||
virtual bool similarDType(AstNodeDType* samep) const override {
|
virtual bool similarDType(AstNodeDType* samep) const override {
|
||||||
const AstNodeArrayDType* asamep = static_cast<const AstNodeArrayDType*>(samep);
|
const AstNodeArrayDType* asamep = static_cast<const AstNodeArrayDType*>(samep);
|
||||||
if (!asamep->subDTypep()) return false;
|
return type() == samep->type() && asamep->subDTypep()
|
||||||
return (subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp()));
|
&& subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp());
|
||||||
}
|
}
|
||||||
virtual void dumpSmall(std::ostream& str) const override;
|
virtual void dumpSmall(std::ostream& str) const override;
|
||||||
virtual V3Hash sameHash() const override { return V3Hash(m_refDTypep); }
|
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);
|
return (m_classp == asamep->m_classp && m_classOrPackagep == asamep->m_classOrPackagep);
|
||||||
}
|
}
|
||||||
virtual bool similarDType(AstNodeDType* samep) const override {
|
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 {
|
virtual V3Hash sameHash() const override {
|
||||||
return V3Hash(V3Hash(m_classp), V3Hash(m_classOrPackagep));
|
return V3Hash(V3Hash(m_classp), V3Hash(m_classOrPackagep));
|
||||||
|
|
@ -1127,8 +1128,8 @@ public:
|
||||||
}
|
}
|
||||||
virtual bool similarDType(AstNodeDType* samep) const override {
|
virtual bool similarDType(AstNodeDType* samep) const override {
|
||||||
const AstQueueDType* asamep = static_cast<const AstQueueDType*>(samep);
|
const AstQueueDType* asamep = static_cast<const AstQueueDType*>(samep);
|
||||||
if (!asamep->subDTypep()) return false;
|
return type() == samep->type() && asamep->subDTypep()
|
||||||
return (subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp()));
|
&& subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp());
|
||||||
}
|
}
|
||||||
virtual void dumpSmall(std::ostream& str) const override;
|
virtual void dumpSmall(std::ostream& str) const override;
|
||||||
virtual V3Hash sameHash() const override { return V3Hash(m_refDTypep); }
|
virtual V3Hash sameHash() const override { return V3Hash(m_refDTypep); }
|
||||||
|
|
|
||||||
|
|
@ -1787,13 +1787,6 @@ private:
|
||||||
nodep->dtypep(newp);
|
nodep->dtypep(newp);
|
||||||
v3Global.rootp()->typeTablep()->addTypesp(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);
|
if (VN_IS(nodep->dtypep()->skipRefToConstp(), ConstDType)) nodep->isConst(true);
|
||||||
// Parameters if implicit untyped inherit from what they are assigned to
|
// Parameters if implicit untyped inherit from what they are assigned to
|
||||||
|
|
@ -1999,7 +1992,7 @@ private:
|
||||||
}
|
}
|
||||||
virtual void visit(AstConsAssoc* nodep) override {
|
virtual void visit(AstConsAssoc* nodep) override {
|
||||||
// Type computed when constructed here
|
// 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");
|
UASSERT_OBJ(vdtypep, nodep, "ConsAssoc requires assoc upper parent data type");
|
||||||
if (m_vup->prelim()) {
|
if (m_vup->prelim()) {
|
||||||
nodep->dtypeFrom(vdtypep);
|
nodep->dtypeFrom(vdtypep);
|
||||||
|
|
@ -2011,7 +2004,7 @@ private:
|
||||||
}
|
}
|
||||||
virtual void visit(AstSetAssoc* nodep) override {
|
virtual void visit(AstSetAssoc* nodep) override {
|
||||||
// Type computed when constructed here
|
// 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");
|
UASSERT_OBJ(vdtypep, nodep, "SetsAssoc requires assoc upper parent data type");
|
||||||
if (m_vup->prelim()) {
|
if (m_vup->prelim()) {
|
||||||
nodep->dtypeFrom(vdtypep);
|
nodep->dtypeFrom(vdtypep);
|
||||||
|
|
@ -2024,7 +2017,7 @@ private:
|
||||||
}
|
}
|
||||||
virtual void visit(AstConsDynArray* nodep) override {
|
virtual void visit(AstConsDynArray* nodep) override {
|
||||||
// Type computed when constructed here
|
// 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");
|
UASSERT_OBJ(vdtypep, nodep, "ConsDynArray requires queue upper parent data type");
|
||||||
if (m_vup->prelim()) {
|
if (m_vup->prelim()) {
|
||||||
userIterateAndNext(nodep->lhsp(), WidthVP(vdtypep, PRELIM).p());
|
userIterateAndNext(nodep->lhsp(), WidthVP(vdtypep, PRELIM).p());
|
||||||
|
|
@ -2056,7 +2049,7 @@ private:
|
||||||
}
|
}
|
||||||
virtual void visit(AstConsQueue* nodep) override {
|
virtual void visit(AstConsQueue* nodep) override {
|
||||||
// Type computed when constructed here
|
// 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");
|
UASSERT_OBJ(vdtypep, nodep, "ConsQueue requires queue upper parent data type");
|
||||||
if (m_vup->prelim()) {
|
if (m_vup->prelim()) {
|
||||||
userIterateAndNext(nodep->lhsp(), WidthVP(vdtypep, PRELIM).p());
|
userIterateAndNext(nodep->lhsp(), WidthVP(vdtypep, PRELIM).p());
|
||||||
|
|
|
||||||
|
|
@ -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,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
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -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
|
||||||
Loading…
Reference in New Issue