From 520b00095c5c4576bff82d5166fe39fee8af3f01 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 3 Jan 2023 07:50:55 -0800 Subject: [PATCH 1/8] Remove unused `named_number_t` type The last user of the named_number_t type was removed in commit 2f474358d999 ("2f474358d99929ec625a46690d1be6939ed67064"). Remove the type as well. Signed-off-by: Lars-Peter Clausen --- parse.y | 3 --- pform_types.h | 1 - 2 files changed, 4 deletions(-) diff --git a/parse.y b/parse.y index 24c3a27a0..581a87db9 100644 --- a/parse.y +++ b/parse.y @@ -455,9 +455,6 @@ Module::port_t *module_declare_port(const YYLTYPE&loc, char *id, std::list*let_port_lst; PLet::let_port_t*let_port_itm; - named_number_t* named_number; - std::list* named_numbers; - named_pexpr_t*named_pexpr; std::list*named_pexprs; struct parmvalue_t*parmvalue; diff --git a/pform_types.h b/pform_types.h index 234930445..ebdff6f0b 100644 --- a/pform_types.h +++ b/pform_types.h @@ -47,7 +47,6 @@ class PWire; class Statement; class netclass_t; class netenum_t; -typedef named named_number_t; typedef named named_pexpr_t; /* From 2cef85f8a114d6a3d946e170ce70315727922464 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 1 Jan 2023 12:54:49 -0800 Subject: [PATCH 2/8] Add helper function for printing expression list There are a few places where some sort of expression list is printed. Add helper functions to consolidate this in a single place and reduce the amount of code. Signed-off-by: Lars-Peter Clausen --- design_dump.cc | 57 ++++++++--------------------- pform_dump.cc | 99 ++++++++++++++++++-------------------------------- 2 files changed, 52 insertions(+), 104 deletions(-) diff --git a/design_dump.cc b/design_dump.cc index 31f9915c3..7e8f50f7a 100644 --- a/design_dump.cc +++ b/design_dump.cc @@ -206,6 +206,18 @@ ostream& operator << (ostream&fd, NetCaseCmp::kind_t that) return fd; } +static std::ostream& operator << (std::ostream &out, const std::vector &exprs) +{ + for (size_t idx = 0; idx < exprs.size(); idx++) { + if (idx != 0) + out << ", "; + if (exprs[idx]) + out << *exprs[idx]; + } + + return out; +} + ostream& ivl_type_s::debug_dump(ostream&o) const { o << typeid(*this).name(); @@ -1650,17 +1662,7 @@ void NetSTask::dump(ostream&o, unsigned ind) const o << setw(ind) << "" << name_; if (! parms_.empty()) { - o << "("; - if (parms_[0]) - parms_[0]->dump(o); - - for (unsigned idx = 1 ; idx < parms_.size() ; idx += 1) { - o << ", "; - if (parms_[idx]) - parms_[idx]->dump(o); - } - - o << ")"; + o << "(" << parms_ << ")"; } o << ";" << endl; } @@ -1702,15 +1704,7 @@ void NetEAccess::dump(ostream&o) const void NetEArrayPattern::dump(ostream&fd) const { - fd << "'{"; - if (items_.size() >= 1) { - if (items_[0]) fd << *items_[0]; - } - for (size_t idx = 1 ; idx < items_.size() ; idx += 1) { - fd << ", "; - if (items_[idx]) fd << *items_[idx]; - } - fd << "}"; + fd << "'{" << items_ << "}"; } void NetEBinary::dump(ostream&o) const @@ -1814,18 +1808,7 @@ void NetEConcat::dump(ostream&o) const if (repeat_ != 1) o << repeat_; - if (parms_[0]) - o << "{" << *parms_[0]; - else - o << "{"; - - for (unsigned idx = 1 ; idx < parms_.size() ; idx += 1) { - if (parms_[idx]) - o << ", " << *parms_[idx]; - else - o << ", "; - } - o << "}"; + o << "{" << parms_ << "}"; } void NetEConst::dump(ostream&o) const @@ -1965,15 +1948,7 @@ void NetETernary::dump(ostream&o) const void NetEUFunc::dump(ostream&o) const { - o << scope_path(func_) << "("; - if (! parms_.empty()) { - parms_[0]->dump(o); - for (unsigned idx = 1 ; idx < parms_.size() ; idx += 1) { - o << ", "; - parms_[idx]->dump(o); - } - } - o << ")"; + o << scope_path(func_) << "(" << parms_ << ")"; } void NetEUnary::dump(ostream&o) const diff --git a/pform_dump.cc b/pform_dump.cc index 4f5ba286e..735d0f923 100644 --- a/pform_dump.cc +++ b/pform_dump.cc @@ -177,6 +177,35 @@ std::ostream& operator << (std::ostream&out, ivl_dis_domain_t dom) return out; } +static std::ostream& operator << (std::ostream &out, const std::vector &exprs) +{ + for (size_t idx = 0; idx < exprs.size(); idx++) { + if (idx != 0) + out << ", "; + if (exprs[idx]) + exprs[idx]->dump(out); + } + + return out; +} + +static std::ostream& operator << (std::ostream &out, + const std::vector &exprs) +{ + for (size_t idx = 0; idx < exprs.size(); idx++) { + if (idx != 0) + out << ", "; + if (!exprs[idx].name.nil()) + out << "." << exprs[idx].name << "("; + if (exprs[idx].parm) + exprs[idx].parm->dump(out); + if (!exprs[idx].name.nil()) + out << ")"; + } + + return out; +} + void data_type_t::pform_dump(ostream&out, unsigned indent) const { out << setw(indent) << "" << typeid(*this).name() << endl; @@ -380,15 +409,7 @@ void PExpr::dump(ostream&out) const void PEAssignPattern::dump(ostream&out) const { - out << "'{"; - if (parms_.size() > 0) { - parms_[0]->dump(out); - for (size_t idx = 1 ; idx < parms_.size() ; idx += 1) { - out << ", "; - parms_[idx]->dump(out); - } - } - out << "}"; + out << "'{" << parms_ << "}"; } void PEConcat::dump(ostream&out) const @@ -401,30 +422,14 @@ void PEConcat::dump(ostream&out) const return; } - out << "{"; - if (parms_[0]) out << *parms_[0]; - for (unsigned idx = 1 ; idx < parms_.size() ; idx += 1) { - out << ", "; - if (parms_[idx]) out << *parms_[idx]; - } - - out << "}"; + out << "{" << parms_ << "}"; if (repeat_) out << "}"; } void PECallFunction::dump(ostream &out) const { - out << path_ << "("; - - if (! parms_.empty()) { - if (parms_[0]) parms_[0]->dump(out); - for (unsigned idx = 1; idx < parms_.size(); ++idx) { - out << ", "; - if (parms_[idx]) parms_[idx]->dump(out); - } - } - out << ")"; + out << path_ << "(" << parms_ << ")"; } void PECastSize::dump(ostream &out) const @@ -487,15 +492,7 @@ void PENewArray::dump(ostream&out) const void PENewClass::dump(ostream&out) const { - out << "class_new("; - if (parms_.size() > 0) { - parms_[0]->dump(out); - for (size_t idx = 1 ; idx < parms_.size() ; idx += 1) { - out << ", "; - if (parms_[idx]) parms_[idx]->dump(out); - } - } - out << ")"; + out << "class_new(" << parms_ << ")"; } void PENewCopy::dump(ostream&out) const @@ -830,14 +827,7 @@ void PGModule::dump(ostream&out, unsigned ind) const // If parameters are overridden by name, dump them. if (parms_) { assert(overrides_ == 0); - out << "#("; - for (unsigned idx = 0 ; idx < nparms_ ; idx += 1) { - if (idx > 0) out << ", "; - out << "." << parms_[idx].name << "("; - if (parms_[idx].parm) out << *parms_[idx].parm; - out << ")"; - } - out << ") "; + out << "#(" << parms_ << ") "; } out << get_name(); @@ -940,16 +930,7 @@ void PCallTask::dump(ostream&out, unsigned ind) const out << setw(ind) << "" << path_; if (! parms_.empty()) { - out << "("; - if (parms_[0]) - out << *parms_[0]; - - for (unsigned idx = 1 ; idx < parms_.size() ; idx += 1) { - out << ", "; - if (parms_[idx]) - out << *parms_[idx]; - } - out << ")"; + out << "(" << parms_ << ")"; } out << "; /* " << get_fileline() << " */" << endl; @@ -1017,15 +998,7 @@ void PCase::dump(ostream&out, unsigned ind) const void PChainConstructor::dump(ostream&out, unsigned ind) const { - out << setw(ind) << "" << "super.new("; - if (parms_.size() > 0) { - if (parms_[0]) out << *parms_[0]; - } - for (size_t idx = 1 ; idx < parms_.size() ; idx += 1) { - out << ", "; - if (parms_[idx]) out << *parms_[idx]; - } - out << ");" << endl; + out << setw(ind) << "" << "super.new(" << parms_ << ")" < Date: Mon, 2 Jan 2023 18:43:03 -0800 Subject: [PATCH 3/8] Use `named_pexpr_t` type instead of open-coding it `named_pexpr_t` is a typedef for `named`. There are a few places where `named` is used directly. Replace those with `named_pexpr_t` for consistency. Signed-off-by: Lars-Peter Clausen --- PGate.cc | 4 ++-- PGate.h | 8 ++++---- pform.cc | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/PGate.cc b/PGate.cc index f7cc7f958..59ad57048 100644 --- a/PGate.cc +++ b/PGate.cc @@ -270,7 +270,7 @@ PGModule::PGModule(perm_string type, perm_string name, list*pins) } PGModule::PGModule(perm_string type, perm_string name, - named*pins, unsigned npins) + named_pexpr_t *pins, unsigned npins) : PGate(name, 0), bound_type_(0), type_(type), overrides_(0), pins_(pins), npins_(npins), parms_(0), nparms_(0) { @@ -292,7 +292,7 @@ void PGModule::set_parameters(list*o) overrides_ = o; } -void PGModule::set_parameters(named*pa, unsigned npa) +void PGModule::set_parameters(named_pexpr_t *pa, unsigned npa) { ivl_assert(*this, parms_ == 0); ivl_assert(*this, overrides_ == 0); diff --git a/PGate.h b/PGate.h index ab514f16b..2bb1c68dc 100644 --- a/PGate.h +++ b/PGate.h @@ -204,7 +204,7 @@ class PGModule : public PGate { // If the binding of ports is by name, this constructor takes // the bindings and stores them for later elaboration. explicit PGModule(perm_string type, perm_string name, - named*pins, unsigned npins); + named_pexpr_t *pins, unsigned npins); // If the module type is known by design, then use this // constructor. @@ -215,7 +215,7 @@ class PGModule : public PGate { // Parameter overrides can come as an ordered list, or a set // of named expressions. void set_parameters(std::list*o); - void set_parameters(named*pa, unsigned npa); + void set_parameters(named_pexpr_t *pa, unsigned npa); std::map attributes; @@ -232,11 +232,11 @@ class PGModule : public PGate { Module*bound_type_; perm_string type_; std::list*overrides_; - named*pins_; + named_pexpr_t *pins_; unsigned npins_; // These members support parameter override by name - named*parms_; + named_pexpr_t *parms_; unsigned nparms_; friend class delayed_elaborate_scope_mod_instances; diff --git a/pform.cc b/pform.cc index 61da7ad75..72a6435f0 100644 --- a/pform.cc +++ b/pform.cc @@ -2278,7 +2278,7 @@ static void pform_make_modgate(perm_string type, if (overrides && overrides->by_name) { unsigned cnt = overrides->by_name->size(); - named*byname = new named[cnt]; + named_pexpr_t *byname = new named_pexpr_t[cnt]; list::iterator by_name_cur = overrides->by_name->begin(); for (unsigned idx = 0 ; idx < cnt ; idx += 1, ++ by_name_cur) { @@ -2311,7 +2311,7 @@ static void pform_make_modgate(perm_string type, std::list*attr) { unsigned npins = bind->size(); - named*pins = new named[npins]; + named_pexpr_t *pins = new named_pexpr_t[npins]; list::iterator bind_cur = bind->begin(); for (unsigned idx = 0 ; idx < npins ; idx += 1, ++bind_cur) { pins[idx].name = bind_cur->name; @@ -2325,7 +2325,7 @@ static void pform_make_modgate(perm_string type, if (overrides && overrides->by_name) { unsigned cnt = overrides->by_name->size(); - named*byname = new named[cnt]; + named_pexpr_t *byname = new named_pexpr_t[cnt]; list::iterator by_name_cur = overrides->by_name->begin(); for (unsigned idx = 0 ; idx < cnt ; idx += 1, ++by_name_cur) { From e7f66fe7acac084d0cb89e7a63da3d2755c34bb0 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 6 Jan 2023 18:56:24 -0800 Subject: [PATCH 4/8] Use standard constructor to copy std::list to std::vector There are a few places in the code where a std::list is copied to a std::vector by iterating through the list and copying each element over to the vector. The std::vector type has a iterator based constructor that can do the same. Update the code to use it instead. This removes a bit of boilerplate code and also makes it easier to update the code. Signed-off-by: Lars-Peter Clausen --- PExpr.cc | 46 +++++++--------------------------------------- PSpec.cc | 7 ++++--- PSpec.h | 6 ++++-- Statement.cc | 38 +++++--------------------------------- netlist.cc | 8 +------- pform.cc | 15 +-------------- 6 files changed, 22 insertions(+), 98 deletions(-) diff --git a/PExpr.cc b/PExpr.cc index 7837268b6..9ca575264 100644 --- a/PExpr.cc +++ b/PExpr.cc @@ -99,14 +99,8 @@ PEAssignPattern::PEAssignPattern() } PEAssignPattern::PEAssignPattern(const list&p) -: parms_(p.size()) +: parms_(p.begin(), p.end()) { - size_t idx = 0; - for (list::const_iterator cur = p.begin() - ; cur != p.end() ; ++cur) { - parms_[idx] = *cur; - idx += 1; - } } PEAssignPattern::~PEAssignPattern() @@ -239,14 +233,9 @@ static pform_name_t pn_from_ps(perm_string n) return tmp; } -PECallFunction::PECallFunction(PPackage*pkg, const pform_name_t &n, const list &parms) -: path_(pkg, n), parms_(parms.size()), is_overridden_(false) +PECallFunction::PECallFunction(PPackage*pkg, const pform_name_t&n, const list &parms) +: path_(pkg, n), parms_(parms.begin(), parms.end()), is_overridden_(false) { - int tmp_idx = 0; - ivl_assert(*this, parms_.size() == parms.size()); - for (list::const_iterator idx = parms.begin() - ; idx != parms.end() ; ++idx) - parms_[tmp_idx++] = *idx; } PECallFunction::PECallFunction(perm_string n, const vector&parms) @@ -261,23 +250,13 @@ PECallFunction::PECallFunction(perm_string n) // NOTE: Anachronism. Try to work all use of svector out. PECallFunction::PECallFunction(const pform_name_t&n, const list &parms) -: path_(n), parms_(parms.size()), is_overridden_(false) +: path_(n), parms_(parms.begin(), parms.end()), is_overridden_(false) { - int tmp_idx = 0; - ivl_assert(*this, parms_.size() == parms.size()); - for (list::const_iterator idx = parms.begin() - ; idx != parms.end() ; ++idx) - parms_[tmp_idx++] = *idx; } PECallFunction::PECallFunction(perm_string n, const list&parms) -: path_(pn_from_ps(n)), parms_(parms.size()), is_overridden_(false) +: package_(0), path_(pn_from_ps(n)), parms_(parms.begin(), parms.end()), is_overridden_(false) { - int tmp_idx = 0; - ivl_assert(*this, parms_.size() == parms.size()); - for (list::const_iterator idx = parms.begin() - ; idx != parms.end() ; ++idx) - parms_[tmp_idx++] = *idx; } PECallFunction::~PECallFunction() @@ -303,14 +282,8 @@ bool PECallFunction::has_aa_term(Design*des, NetScope*scope) const } PEConcat::PEConcat(const list&p, PExpr*r) -: parms_(p.size()), width_modes_(SIZED, p.size()), repeat_(r) +: parms_(p.begin(), p.end()), width_modes_(SIZED, p.size()), repeat_(r) { - int tmp_idx = 0; - ivl_assert(*this, parms_.size() == p.size()); - for (list::const_iterator idx = p.begin() - ; idx != p.end() ; ++idx) - parms_[tmp_idx++] = *idx; - tested_scope_ = 0; repeat_count_ = 1; } @@ -494,13 +467,8 @@ PENewClass::PENewClass(void) } PENewClass::PENewClass(const list&p, data_type_t *class_type) -: parms_(p.size()), class_type_(class_type) +: parms_(p.begin(), p.end()), class_type_(class_type) { - size_t tmp_idx = 0; - for (list::const_iterator cur = p.begin() - ; cur != p.end() ; ++ cur) { - parms_[tmp_idx++] = *cur; - } } PENewClass::~PENewClass() diff --git a/PSpec.cc b/PSpec.cc index 54825344e..639e3e197 100644 --- a/PSpec.cc +++ b/PSpec.cc @@ -19,10 +19,11 @@ # include "PSpec.h" -PSpecPath::PSpecPath(unsigned src_cnt, unsigned dst_cnt, char polarity, - bool full_flag) +PSpecPath::PSpecPath(const std::list &src_list, + const std::list &dst_list, + char polarity, bool full_flag) : conditional(false), condition(0), edge(0), - src(src_cnt), dst(dst_cnt), + src(src_list.begin(), src_list.end()), dst(dst_list.begin(), dst_list.end()), data_source_expression(0) { full_flag_ = full_flag; diff --git a/PSpec.h b/PSpec.h index 7c34f5bf6..450fbd393 100644 --- a/PSpec.h +++ b/PSpec.h @@ -22,6 +22,7 @@ # include "LineInfo.h" # include "StringHeap.h" # include +# include class PExpr; @@ -56,8 +57,9 @@ class PExpr; class PSpecPath : public LineInfo { public: - PSpecPath(unsigned src_cnt, unsigned dst_cnt, char polarity, - bool full_flag); + PSpecPath(const std::list &src_list, + const std::list &dst_list, + char polarity, bool full_flag); ~PSpecPath(); void elaborate(class Design*des, class NetScope*scope) const; diff --git a/Statement.cc b/Statement.cc index 7799eca73..41d0bbb22 100644 --- a/Statement.cc +++ b/Statement.cc @@ -167,36 +167,18 @@ PNamedItem::SymbolType PBlock::symbol_type() const } PCallTask::PCallTask(const pform_name_t&n, const list&p) -: package_(0), path_(n), parms_(p.size()) +: package_(0), path_(n), parms_(p.begin(), p.end()) { - list::const_iterator cur = p.begin(); - for (size_t idx = 0 ; idx < parms_.size() ; idx += 1) { - parms_[idx] = *cur; - ++cur; - } - ivl_assert(*this, cur == p.end()); } PCallTask::PCallTask(PPackage*pkg, const pform_name_t&n, const list&p) -: package_(pkg), path_(n), parms_(p.size()) +: package_(pkg), path_(n), parms_(p.begin(), p.end()) { - list::const_iterator cur = p.begin(); - for (size_t idx = 0 ; idx < parms_.size() ; idx += 1) { - parms_[idx] = *cur; - ++cur; - } - ivl_assert(*this, cur == p.end()); } PCallTask::PCallTask(perm_string n, const list&p) -: package_(0), parms_(p.size()) +: package_(0), parms_(p.begin(), p.end()) { - list::const_iterator cur = p.begin(); - for (size_t idx = 0 ; idx < parms_.size() ; idx += 1) { - parms_[idx] = *cur; - ++cur; - } - ivl_assert(*this, cur == p.end()); path_.push_back(name_component_t(n)); } @@ -235,14 +217,8 @@ PCAssign::~PCAssign() } PChainConstructor::PChainConstructor(const list&parms) -: parms_(parms.size()) +: parms_(parms.begin(), parms.end()) { - list::const_iterator cur = parms.begin(); - for (size_t idx = 0 ; idx < parms_.size() ; idx += 1) { - parms_[idx] = *cur; - ++cur; - } - ivl_assert(*this, cur == parms.end()); } PChainConstructor::~PChainConstructor() @@ -350,12 +326,8 @@ PForce::~PForce() } PForeach::PForeach(perm_string av, const list&ix, Statement*s) -: array_var_(av), index_vars_(ix.size()), statement_(s) +: array_var_(av), index_vars_(ix.begin(), ix.end()), statement_(s) { - size_t idx = 0; - for (list::const_iterator cur = ix.begin() - ; cur != ix.end() ; ++cur) - index_vars_[idx++] = *cur; } PForeach::~PForeach() diff --git a/netlist.cc b/netlist.cc index f1f825d16..561701b32 100644 --- a/netlist.cc +++ b/netlist.cc @@ -579,16 +579,10 @@ NetNet::NetNet(NetScope*s, perm_string n, Type t, : NetObj(s, n, calculate_count(unpacked)), type_(t), port_type_(NOT_A_PORT), local_flag_(false), net_type_(use_net_type), - discipline_(0), unpacked_dims_(unpacked.size()), + discipline_(0), unpacked_dims_(unpacked.begin(), unpacked.end()), eref_count_(0), lref_count_(0) { calculate_slice_widths_from_packed_dims_(); - size_t idx = 0; - for (list::const_iterator cur = unpacked.begin() - ; cur != unpacked.end() ; ++cur, idx += 1) { - unpacked_dims_[idx] = *cur; - } - ivl_assert(*this, idx == unpacked_dims_.size()); ivl_assert(*this, s); if (pin_count() == 0) { diff --git a/pform.cc b/pform.cc index 72a6435f0..03c5df422 100644 --- a/pform.cc +++ b/pform.cc @@ -3053,23 +3053,10 @@ extern PSpecPath* pform_make_specify_path(const struct vlltype&li, list*src, char pol, bool full_flag, list*dst) { - PSpecPath*path = new PSpecPath(src->size(), dst->size(), pol, full_flag); + PSpecPath*path = new PSpecPath(*src, *dst, pol, full_flag); FILE_NAME(path, li); - unsigned idx; - list::const_iterator cur; - - idx = 0; - for (idx = 0, cur = src->begin() ; cur != src->end() ; ++ idx, ++ cur) { - path->src[idx] = *cur; - } - ivl_assert(li, idx == path->src.size()); delete src; - - for (idx = 0, cur = dst->begin() ; cur != dst->end() ; ++ idx, ++ cur) { - path->dst[idx] = *cur; - } - ivl_assert(li, idx == path->dst.size()); delete dst; return path; From 4036c7741626564314864fbfcec287b0e34e493a Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 16 Feb 2022 14:34:02 +0100 Subject: [PATCH 5/8] parser: Consolidate named expression parsing There are a few different places in the parser that all parse named expressions in the same way. Consolidate them into a single rule. Signed-off-by: Lars-Peter Clausen --- parse.y | 43 ++++++++++++------------------------------- 1 file changed, 12 insertions(+), 31 deletions(-) diff --git a/parse.y b/parse.y index 581a87db9..f5bf5a89b 100644 --- a/parse.y +++ b/parse.y @@ -675,7 +675,7 @@ Module::port_t *module_declare_port(const YYLTYPE&loc, char *id, %type tf_port_declaration tf_port_item tf_port_item_list %type tf_port_list tf_port_list_opt tf_port_list_parens_opt -%type modport_simple_port port_name parameter_value_byname +%type named_expression named_expression_opt port_name %type port_name_list parameter_value_byname_list %type port_conn_expression_list_with_nuls @@ -1975,7 +1975,7 @@ modport_item modport_ports_list : modport_ports_declaration | modport_ports_list ',' modport_ports_declaration - | modport_ports_list ',' modport_simple_port + | modport_ports_list ',' named_expression { if (last_modport_port.type == MP_SIMPLE) { pform_add_modport_port(@3, last_modport_port.direction, $3->name, $3->parm); @@ -2009,7 +2009,7 @@ modport_ports_declaration delete[] $3; delete $1; } - | attribute_list_opt port_direction modport_simple_port + | attribute_list_opt port_direction named_expression { last_modport_port.type = MP_SIMPLE; last_modport_port.direction = $2; pform_add_modport_port(@3, $2, $3->name, $3->parm); @@ -2038,16 +2038,6 @@ modport_ports_declaration } ; -modport_simple_port - : '.' IDENTIFIER '(' expression ')' - { named_pexpr_t*tmp = new named_pexpr_t; - tmp->name = lex_strings.make($2); - tmp->parm = $4; - delete[]$2; - $$ = tmp; - } - ; - modport_tf_port : K_task IDENTIFIER tf_port_list_parens_opt | K_function data_type_or_implicit_or_void IDENTIFIER tf_port_list_parens_opt @@ -5550,7 +5540,7 @@ parameter_value_opt { $$ = 0; } ; -parameter_value_byname +named_expression : '.' IDENTIFIER '(' expression ')' { named_pexpr_t*tmp = new named_pexpr_t; tmp->name = lex_strings.make($2); @@ -5558,6 +5548,9 @@ parameter_value_byname delete[]$2; $$ = tmp; } + +named_expression_opt + : named_expression | '.' IDENTIFIER '(' ')' { named_pexpr_t*tmp = new named_pexpr_t; tmp->name = lex_strings.make($2); @@ -5568,13 +5561,13 @@ parameter_value_byname ; parameter_value_byname_list - : parameter_value_byname + : named_expression_opt { std::list*tmp = new std::list; tmp->push_back(*$1); delete $1; $$ = tmp; } - | parameter_value_byname_list ',' parameter_value_byname + | parameter_value_byname_list ',' named_expression_opt { std::list*tmp = $1; tmp->push_back(*$3); delete $3; @@ -5643,13 +5636,9 @@ port_opt looking for the ports of a module declaration. */ port_name - : attribute_list_opt '.' IDENTIFIER '(' expression ')' - { named_pexpr_t*tmp = new named_pexpr_t; - tmp->name = lex_strings.make($3); - tmp->parm = $5; - delete[]$3; - delete $1; - $$ = tmp; + : attribute_list_opt named_expression_opt + { delete $1; + $$ = $2; } | attribute_list_opt '.' IDENTIFIER '(' error ')' { yyerror(@3, "error: Invalid port connection expression."); @@ -5660,14 +5649,6 @@ port_name delete $1; $$ = tmp; } - | attribute_list_opt '.' IDENTIFIER '(' ')' - { named_pexpr_t*tmp = new named_pexpr_t; - tmp->name = lex_strings.make($3); - tmp->parm = 0; - delete[]$3; - delete $1; - $$ = tmp; - } | attribute_list_opt '.' IDENTIFIER { pform_requires_sv(@3, "Implicit named port connections"); named_pexpr_t*tmp = new named_pexpr_t; From 102d85c4e5cd7c5c3a41fff81f6615b548f79483 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 31 Dec 2022 19:22:56 -0800 Subject: [PATCH 6/8] Attach line information to named items Attach line information to named items. This allows to provide better location information for messages involving named items. The location of item itself can't always be used, since the item itself might be empty. Signed-off-by: Lars-Peter Clausen --- named.h | 3 ++- parse.y | 26 ++++++++++++++++++++------ pform.cc | 24 ++++++++---------------- 3 files changed, 30 insertions(+), 23 deletions(-) diff --git a/named.h b/named.h index 1086637c5..fd85d9433 100644 --- a/named.h +++ b/named.h @@ -20,13 +20,14 @@ */ # include "StringHeap.h" +# include "libmisc/LineInfo.h" /* * There are lots of places where names are attached to objects. This * simple template expresses the lot. */ -template struct named { +template struct named : public LineInfo { perm_string name; T parm; }; diff --git a/parse.y b/parse.y index f5bf5a89b..11e28dcc0 100644 --- a/parse.y +++ b/parse.y @@ -199,7 +199,10 @@ static PECallFunction*make_call_function(perm_string tn, PExpr*arg1, PExpr*arg2) return tmp; } -static std::list* make_named_numbers(perm_string name, long first, long last, PExpr*val =0) +static std::list* make_named_numbers(const struct vlltype &loc, + perm_string name, + long first, long last, + PExpr *val = nullptr) { std::list*lst = new std::list; named_pexpr_t tmp; @@ -210,6 +213,7 @@ static std::list* make_named_numbers(perm_string name, long first buf << name.str() << idx << ends; tmp.name = lex_strings.make(buf.str()); tmp.parm = val; + FILE_NAME(&tmp, loc); val = 0; lst->push_back(tmp); } @@ -220,6 +224,7 @@ static std::list* make_named_numbers(perm_string name, long first buf << name.str() << idx << ends; tmp.name = lex_strings.make(buf.str()); tmp.parm = val; + FILE_NAME(&tmp, loc); val = 0; lst->push_back(tmp); } @@ -227,12 +232,15 @@ static std::list* make_named_numbers(perm_string name, long first return lst; } -static std::list* make_named_number(perm_string name, PExpr*val =0) +static std::list* make_named_number(const struct vlltype &loc, + perm_string name, + PExpr *val = nullptr) { std::list*lst = new std::list; named_pexpr_t tmp; tmp.name = name; tmp.parm = val; + FILE_NAME(&tmp, loc); lst->push_back(tmp); return lst; } @@ -2700,6 +2708,7 @@ attribute_list attribute : IDENTIFIER initializer_opt { named_pexpr_t*tmp = new named_pexpr_t; + FILE_NAME(tmp, @$); tmp->name = lex_strings.make($1); tmp->parm = $2; delete[]$1; @@ -2894,19 +2903,19 @@ enum_name : IDENTIFIER initializer_opt { perm_string name = lex_strings.make($1); delete[]$1; - $$ = make_named_number(name, $2); + $$ = make_named_number(@$, name, $2); } | IDENTIFIER '[' pos_neg_number ']' initializer_opt { perm_string name = lex_strings.make($1); long count = check_enum_seq_value(@1, $3, false); - $$ = make_named_numbers(name, 0, count-1, $5); + $$ = make_named_numbers(@$, name, 0, count-1, $5); delete[]$1; delete $3; } | IDENTIFIER '[' pos_neg_number ':' pos_neg_number ']' initializer_opt { perm_string name = lex_strings.make($1); - $$ = make_named_numbers(name, check_enum_seq_value(@1, $3, true), - check_enum_seq_value(@1, $5, true), $7); + $$ = make_named_numbers(@$, name, check_enum_seq_value(@1, $3, true), + check_enum_seq_value(@1, $5, true), $7); delete[]$1; delete $3; delete $5; @@ -5543,6 +5552,7 @@ parameter_value_opt named_expression : '.' IDENTIFIER '(' expression ')' { named_pexpr_t*tmp = new named_pexpr_t; + FILE_NAME(tmp, @$); tmp->name = lex_strings.make($2); tmp->parm = $4; delete[]$2; @@ -5553,6 +5563,7 @@ named_expression_opt : named_expression | '.' IDENTIFIER '(' ')' { named_pexpr_t*tmp = new named_pexpr_t; + FILE_NAME(tmp, @$); tmp->name = lex_strings.make($2); tmp->parm = 0; delete[]$2; @@ -5643,6 +5654,7 @@ port_name | attribute_list_opt '.' IDENTIFIER '(' error ')' { yyerror(@3, "error: Invalid port connection expression."); named_pexpr_t*tmp = new named_pexpr_t; + FILE_NAME(tmp, @$); tmp->name = lex_strings.make($3); tmp->parm = 0; delete[]$3; @@ -5652,6 +5664,7 @@ port_name | attribute_list_opt '.' IDENTIFIER { pform_requires_sv(@3, "Implicit named port connections"); named_pexpr_t*tmp = new named_pexpr_t; + FILE_NAME(tmp, @$); tmp->name = lex_strings.make($3); tmp->parm = new PEIdent(lex_strings.make($3), true); FILE_NAME(tmp->parm, @3); @@ -5661,6 +5674,7 @@ port_name } | K_DOTSTAR { named_pexpr_t*tmp = new named_pexpr_t; + FILE_NAME(tmp, @$); tmp->name = lex_strings.make("*"); tmp->parm = 0; $$ = tmp; diff --git a/pform.cc b/pform.cc index 03c5df422..c2431ac5a 100644 --- a/pform.cc +++ b/pform.cc @@ -2280,11 +2280,8 @@ static void pform_make_modgate(perm_string type, unsigned cnt = overrides->by_name->size(); named_pexpr_t *byname = new named_pexpr_t[cnt]; - list::iterator by_name_cur = overrides->by_name->begin(); - for (unsigned idx = 0 ; idx < cnt ; idx += 1, ++ by_name_cur) { - byname[idx].name = by_name_cur->name; - byname[idx].parm = by_name_cur->parm; - } + std::copy(overrides->by_name->begin(), overrides->by_name->end(), + byname); cur->set_parameters(byname, cnt); @@ -2312,12 +2309,10 @@ static void pform_make_modgate(perm_string type, { unsigned npins = bind->size(); named_pexpr_t *pins = new named_pexpr_t[npins]; - list::iterator bind_cur = bind->begin(); - for (unsigned idx = 0 ; idx < npins ; idx += 1, ++bind_cur) { - pins[idx].name = bind_cur->name; - pins[idx].parm = bind_cur->parm; - pform_declare_implicit_nets(bind_cur->parm); - } + for (const auto &bind_cur : *bind) + pform_declare_implicit_nets(bind_cur.parm); + + std::copy(bind->begin(), bind->end(), pins); PGModule*cur = new PGModule(type, name, pins, npins); cur->set_line(li); @@ -2327,11 +2322,8 @@ static void pform_make_modgate(perm_string type, unsigned cnt = overrides->by_name->size(); named_pexpr_t *byname = new named_pexpr_t[cnt]; - list::iterator by_name_cur = overrides->by_name->begin(); - for (unsigned idx = 0 ; idx < cnt ; idx += 1, ++by_name_cur) { - byname[idx].name = by_name_cur->name; - byname[idx].parm = by_name_cur->parm; - } + std::copy(overrides->by_name->begin(), overrides->by_name->end(), + byname); cur->set_parameters(byname, cnt); From f6a51bc9db575362b7e29031a46f575c25f2d157 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 6 Jan 2023 19:13:29 -0800 Subject: [PATCH 7/8] Add support for binding function/task arguments by name In addition to providing positional arguments for task and functions SystemVerilog allows to bind arguments by name. This is similar to how module ports can be bound by name. ``` task t(int a, int b); ... endtask ... t(.b(1), .a(2)); ``` Extend the parser and elaboration stage to be able to handle this. During elaboration the named argument list is transformed into a purely positional list so that later stages like synthesis do not have to care about the names. For system functions and tasks all arguments must be unnamed, otherwise an error will be reported. In addition to functions and tasks arguments can also be bound by name for the various different ways of invoking a class constructor. Signed-off-by: Lars-Peter Clausen --- Makefile.in | 3 +- PExpr.cc | 28 +++--- PExpr.h | 18 ++-- PTask.h | 3 +- Statement.cc | 13 ++- Statement.h | 21 ++-- elab_expr.cc | 188 ++++++++++++++++++++---------------- elab_sig.cc | 13 ++- elaborate.cc | 241 ++++++++++++++++++++++++++++++---------------- map_named_args.cc | 75 +++++++++++++++ map_named_args.h | 22 +++++ netmisc.cc | 3 + parse.y | 95 ++++++++++++------ pform.cc | 6 +- pform.h | 8 +- pform_analog.cc | 16 +-- pform_dump.cc | 10 +- pform_pclass.cc | 13 ++- pform_types.h | 2 +- 19 files changed, 504 insertions(+), 274 deletions(-) create mode 100644 map_named_args.cc create mode 100644 map_named_args.h diff --git a/Makefile.in b/Makefile.in index 65223fb60..ace61b063 100644 --- a/Makefile.in +++ b/Makefile.in @@ -114,7 +114,8 @@ O = main.o async.o design_dump.o discipline.o dup_expr.o elaborate.o \ net_event.o net_expr.o net_func.o \ net_func_eval.o net_link.o net_modulo.o \ net_nex_input.o net_nex_output.o net_proc.o net_scope.o net_tran.o \ - net_udp.o pad_to_width.o parse.o parse_misc.o pform.o pform_analog.o \ + net_udp.o map_named_args.o \ + pad_to_width.o parse.o parse_misc.o pform.o pform_analog.o \ pform_disciplines.o pform_dump.o pform_package.o pform_pclass.o \ pform_types.o \ symbol_search.o sync.o sys_funcs.o verinum.o verireal.o vpi_modules.o target.o \ diff --git a/PExpr.cc b/PExpr.cc index 9ca575264..73679a4b1 100644 --- a/PExpr.cc +++ b/PExpr.cc @@ -215,12 +215,12 @@ PEBShift::~PEBShift() { } -PECallFunction::PECallFunction(const pform_name_t&n, const vector &parms) +PECallFunction::PECallFunction(const pform_name_t &n, const vector &parms) : path_(n), parms_(parms), is_overridden_(false) { } -PECallFunction::PECallFunction(PPackage*pkg, const pform_name_t&n, const vector &parms) +PECallFunction::PECallFunction(PPackage *pkg, const pform_name_t &n, const vector &parms) : path_(pkg, n), parms_(parms), is_overridden_(false) { } @@ -233,12 +233,12 @@ static pform_name_t pn_from_ps(perm_string n) return tmp; } -PECallFunction::PECallFunction(PPackage*pkg, const pform_name_t&n, const list &parms) +PECallFunction::PECallFunction(PPackage *pkg, const pform_name_t &n, const list &parms) : path_(pkg, n), parms_(parms.begin(), parms.end()), is_overridden_(false) { } -PECallFunction::PECallFunction(perm_string n, const vector&parms) +PECallFunction::PECallFunction(perm_string n, const vector &parms) : path_(pn_from_ps(n)), parms_(parms), is_overridden_(false) { } @@ -249,13 +249,13 @@ PECallFunction::PECallFunction(perm_string n) } // NOTE: Anachronism. Try to work all use of svector out. -PECallFunction::PECallFunction(const pform_name_t&n, const list &parms) +PECallFunction::PECallFunction(const pform_name_t &n, const list &parms) : path_(n), parms_(parms.begin(), parms.end()), is_overridden_(false) { } -PECallFunction::PECallFunction(perm_string n, const list&parms) -: package_(0), path_(pn_from_ps(n)), parms_(parms.begin(), parms.end()), is_overridden_(false) +PECallFunction::PECallFunction(perm_string n, const list &parms) +: path_(pn_from_ps(n)), parms_(parms.begin(), parms.end()), is_overridden_(false) { } @@ -265,18 +265,18 @@ PECallFunction::~PECallFunction() void PECallFunction::declare_implicit_nets(LexicalScope*scope, NetNet::Type type) { - for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) { - if (parms_[idx]) - parms_[idx]->declare_implicit_nets(scope, type); + for (const auto &parm : parms_) { + if (parm.parm) + parm.parm->declare_implicit_nets(scope, type); } } bool PECallFunction::has_aa_term(Design*des, NetScope*scope) const { bool flag = false; - for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) { - if (parms_[idx]) - flag |= parms_[idx]->has_aa_term(des, scope); + for (const auto &parm : parms_) { + if (parm.parm) + flag |= parm.parm->has_aa_term(des, scope); } return flag; } @@ -466,7 +466,7 @@ PENewClass::PENewClass(void) { } -PENewClass::PENewClass(const list&p, data_type_t *class_type) +PENewClass::PENewClass(const list &p, data_type_t *class_type) : parms_(p.begin(), p.end()), class_type_(class_type) { } diff --git a/PExpr.h b/PExpr.h index 8958ed62a..a70a6f1e7 100644 --- a/PExpr.h +++ b/PExpr.h @@ -570,7 +570,7 @@ class PENewClass : public PExpr { // New without (or with default) constructor explicit PENewClass (); // New with constructor arguments - explicit PENewClass (const std::list&p, + explicit PENewClass (const std::list &p, data_type_t *class_type = nullptr); ~PENewClass(); @@ -592,7 +592,7 @@ class PENewClass : public PExpr { NetExpr*obj, unsigned flags) const; private: - std::vectorparms_; + std::vector parms_; data_type_t *class_type_; }; @@ -895,20 +895,20 @@ class PETernary : public PExpr { */ class PECallFunction : public PExpr { public: - explicit PECallFunction(const pform_name_t&n, const std::vector &parms); + explicit PECallFunction(const pform_name_t &n, const std::vector &parms); // Call function defined in package. - explicit PECallFunction(PPackage*pkg, const pform_name_t&n, const std::list &parms); + explicit PECallFunction(PPackage *pkg, const pform_name_t &n, const std::list &parms); // Used to convert a user function called as a task - explicit PECallFunction(PPackage*pkg, const pform_name_t&n, const std::vector &parms); + explicit PECallFunction(PPackage *pkg, const pform_name_t &n, const std::vector &parms); // Call of system function (name is not hierarchical) - explicit PECallFunction(perm_string n, const std::vector &parms); + explicit PECallFunction(perm_string n, const std::vector &parms); explicit PECallFunction(perm_string n); // std::list versions. Should be removed! - explicit PECallFunction(const pform_name_t&n, const std::list &parms); - explicit PECallFunction(perm_string n, const std::list &parms); + explicit PECallFunction(const pform_name_t &n, const std::list &parms); + explicit PECallFunction(perm_string n, const std::list &parms); ~PECallFunction(); @@ -929,7 +929,7 @@ class PECallFunction : public PExpr { private: pform_scoped_name_t path_; - std::vector parms_; + std::vector parms_; // For system functions. bool is_overridden_; diff --git a/PTask.h b/PTask.h index 4702d0a12..7ea3e924a 100644 --- a/PTask.h +++ b/PTask.h @@ -63,7 +63,8 @@ class PTaskFunc : public PScope, public PNamedItem { // default value expressions, if any. void elaborate_sig_ports_(Design*des, NetScope*scope, std::vector&ports, - std::vector&pdefs) const; + std::vector &pdefs, + std::vector &port_names) const; void dump_ports_(std::ostream&out, unsigned ind) const; diff --git a/Statement.cc b/Statement.cc index 41d0bbb22..1dda37940 100644 --- a/Statement.cc +++ b/Statement.cc @@ -166,17 +166,17 @@ PNamedItem::SymbolType PBlock::symbol_type() const return BLOCK; } -PCallTask::PCallTask(const pform_name_t&n, const list&p) +PCallTask::PCallTask(const pform_name_t &n, const list &p) : package_(0), path_(n), parms_(p.begin(), p.end()) { } -PCallTask::PCallTask(PPackage*pkg, const pform_name_t&n, const list&p) +PCallTask::PCallTask(PPackage *pkg, const pform_name_t &n, const list &p) : package_(pkg), path_(n), parms_(p.begin(), p.end()) { } -PCallTask::PCallTask(perm_string n, const list&p) +PCallTask::PCallTask(perm_string n, const list &p) : package_(0), parms_(p.begin(), p.end()) { path_.push_back(name_component_t(n)); @@ -216,11 +216,16 @@ PCAssign::~PCAssign() delete expr_; } -PChainConstructor::PChainConstructor(const list&parms) +PChainConstructor::PChainConstructor(const list &parms) : parms_(parms.begin(), parms.end()) { } +PChainConstructor::PChainConstructor(const vector &parms) +: parms_(parms) +{ +} + PChainConstructor::~PChainConstructor() { } diff --git a/Statement.h b/Statement.h index d9b7f0faf..6aa2e9bca 100644 --- a/Statement.h +++ b/Statement.h @@ -223,9 +223,9 @@ class PBreak : public Statement { class PCallTask : public Statement { public: - explicit PCallTask(PPackage*pkg, const pform_name_t&n, const std::list&parms); - explicit PCallTask(const pform_name_t&n, const std::list&parms); - explicit PCallTask(perm_string n, const std::list&parms); + explicit PCallTask(PPackage *pkg, const pform_name_t &n, const std::list &parms); + explicit PCallTask(const pform_name_t &n, const std::list &parms); + explicit PCallTask(perm_string n, const std::list &parms); ~PCallTask(); const pform_name_t& path() const; @@ -253,11 +253,13 @@ class PCallTask : public Statement { NetProc*elaborate_sys_task_method_(Design*des, NetScope*scope, NetNet*net, perm_string method_name, - const char*sys_task_name) const; + const char *sys_task_name, + const std::vector &parm_names = {}) const; NetProc*elaborate_queue_method_(Design*des, NetScope*scope, NetNet*net, perm_string method_name, - const char*sys_task_name) const; + const char *sys_task_name, + const std::vector &parm_names) const; NetProc*elaborate_method_func_(NetScope*scope, NetNet*net, ivl_type_t type, @@ -267,7 +269,7 @@ class PCallTask : public Statement { PPackage*package_; pform_name_t path_; - std::vector parms_; + std::vector parms_; bool void_cast_ = false; }; @@ -320,17 +322,18 @@ class PCAssign : public Statement { */ class PChainConstructor : public Statement { public: - explicit PChainConstructor(const std::list&parms); + explicit PChainConstructor(const std::list &parms); + explicit PChainConstructor(const std::vector &parms); ~PChainConstructor(); virtual NetProc* elaborate(Design*des, NetScope*scope) const; virtual void dump(std::ostream&out, unsigned ind) const; - inline const std::vector& chain_args(void) const + inline const std::vector& chain_args(void) const { return parms_; } private: - std::vector parms_; + std::vector parms_; }; class PCondit : public Statement { diff --git a/elab_expr.cc b/elab_expr.cc index 45773cede..1918908cf 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -40,6 +40,7 @@ # include "netscalar.h" # include "util.h" # include "ivl_assert.h" +# include "map_named_args.h" using namespace std; @@ -1374,7 +1375,7 @@ unsigned PECallFunction::test_width_sfunc_(Design*des, NetScope*scope, // The Icarus Verilog specific $ivlh_to_unsigned() system // task takes a second argument which is the output // size. This can be an arbitrary constant function. - PExpr*pexpr = parms_[1]; + PExpr *pexpr = parms_[1].parm; if (pexpr == 0) { cerr << get_fileline() << ": error: " << "Missing $ivlh_to_unsigned width." << endl; @@ -1396,7 +1397,7 @@ unsigned PECallFunction::test_width_sfunc_(Design*des, NetScope*scope, // The argument width is self-determined and doesn't // affect the result width. width_mode_t arg_mode = SIZED; - parms_[0]->test_width(des, scope, arg_mode); + parms_[0].parm->test_width(des, scope, arg_mode); expr_type_ = pexpr->expr_type(); expr_width_ = value; @@ -1406,7 +1407,7 @@ unsigned PECallFunction::test_width_sfunc_(Design*des, NetScope*scope, } if (name=="$signed" || name=="$unsigned") { - PExpr*expr = parms_[0]; + PExpr *expr = parms_[0].parm; if (expr == 0) return 0; @@ -1423,7 +1424,7 @@ unsigned PECallFunction::test_width_sfunc_(Design*des, NetScope*scope, } if (name=="$sizeof" || name=="$bits") { - PExpr*expr = parms_[0]; + PExpr *expr = parms_[0].parm; if (expr == 0) return 0; @@ -1450,7 +1451,7 @@ unsigned PECallFunction::test_width_sfunc_(Design*des, NetScope*scope, } if (name=="$is_signed") { - PExpr*expr = parms_[0]; + PExpr *expr = parms_[0].parm; if (expr == 0) return 0; @@ -1887,6 +1888,17 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope, { perm_string name = peek_tail_name(path_); + // System functions don't have named parameters + for (const auto &parm : parms_) { + if (!parm.name.nil()) { + des->errors++; + cerr << parm.get_fileline() << ": error: " + << "The system function `" << name + << "` has no argument called `" << parm.name << "`." + << endl; + } + } + /* Catch the special case that the system function is the $ivl_unsigned function. In this case the second argument is the size of the expression, but should already be accounted @@ -1894,7 +1906,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope, if (name=="$ivlh_to_unsigned") { ivl_assert(*this, parms_.size()==2); - PExpr*expr = parms_[0]; + PExpr *expr = parms_[0].parm; ivl_assert(*this, expr); NetExpr*sub = expr->elaborate_expr(des, scope, expr->expr_width(), flags); return cast_to_width_(sub, expr_wid); @@ -1904,7 +1916,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope, function. Its argument will be evaluated as a self-determined expression. */ if (name=="$signed" || name=="$unsigned") { - if ((parms_.size() != 1) || (parms_[0] == 0)) { + if ((parms_.size() != 1) || !parms_[0].parm) { cerr << get_fileline() << ": error: The " << name << " function takes exactly one(1) argument." << endl; des->errors += 1; @@ -1922,7 +1934,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope, cerr << get_fileline() << ": PECallFunction::elaborate_sfunc_: " << name << " expression is the argument cast to expr_wid=" << expr_wid << endl; } - PExpr*expr = parms_[0]; + PExpr *expr = parms_[0].parm; NetExpr*sub = expr->elaborate_expr(des, scope, expr_width_, flags); return cast_to_width_(sub, expr_wid); @@ -1933,7 +1945,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope, sub-expression is not used, so the expression itself can be deleted. */ if (name=="$sizeof" || name=="$bits") { - if ((parms_.size() != 1) || (parms_[0] == 0)) { + if ((parms_.size() != 1) || !parms_[0].parm) { cerr << get_fileline() << ": error: The " << name << " function takes exactly one(1) argument." << endl; des->errors += 1; @@ -1944,7 +1956,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope, cerr << get_fileline() << ": warning: $sizeof is deprecated." << " Use $bits() instead." << endl; - PExpr*expr = parms_[0]; + PExpr *expr = parms_[0].parm; uint64_t use_width = 0; if (PETypename*type_expr = dynamic_cast(expr)) { @@ -1991,14 +2003,14 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope, a single bit flag -- 1 if the expression is signed, 0 otherwise. */ if (name=="$is_signed") { - if ((parms_.size() != 1) || (parms_[0] == 0)) { + if ((parms_.size() != 1) || !parms_[0].parm) { cerr << get_fileline() << ": error: The " << name << " function takes exactly one(1) argument." << endl; des->errors += 1; return 0; } - PExpr*expr = parms_[0]; + PExpr *expr = parms_[0].parm; verinum val (expr->has_sign() ? verinum::V1 : verinum::V0, 1); NetEConst*sub = new NetEConst(val); @@ -2039,7 +2051,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope, expression if one is created. */ /* These functions can work in a constant context with a signal expression. */ - if ((nparms == 1) && (dynamic_cast(parms_[0]))) { + if ((nparms == 1) && (dynamic_cast(parms_[0].parm))) { if (strcmp(name, "$dimensions") == 0) need_const = false; else if (strcmp(name, "$high") == 0) need_const = false; else if (strcmp(name, "$increment") == 0) need_const = false; @@ -2053,7 +2065,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope, unsigned parm_errors = 0; unsigned missing_parms = 0; for (unsigned idx = 0 ; idx < nparms ; idx += 1) { - PExpr*expr = parms_[idx]; + PExpr *expr = parms_[idx].parm; if (expr) { NetExpr*tmp = elab_sys_task_arg(des, scope, name, idx, expr, need_const); @@ -2092,7 +2104,7 @@ NetExpr* PECallFunction::elaborate_access_func_(Design*des, NetScope*scope, NetBranch*branch = 0; if (parms_.size() == 1) { - PExpr*arg1 = parms_[0]; + PExpr *arg1 = parms_[0].parm; PEIdent*arg_ident = dynamic_cast (arg1); ivl_assert(*this, arg_ident); @@ -2147,7 +2159,7 @@ static NetExpr* check_for_enum_methods(const LineInfo*li, const pform_scoped_name_t&use_path, perm_string method_name, NetExpr*expr, - PExpr*parg, unsigned args) + const std::vector &parms) { if (debug_elaborate) { cerr << li->get_fileline() << ": " << __func__ << ": " @@ -2168,9 +2180,9 @@ static NetExpr* check_for_enum_methods(const LineInfo*li, // The "num()" method returns the number of elements. This is // actually a static constant, and can be replaced at compile time // with a constant value. - if (args != 0) { + if (parms.size() != 0) { cerr << li->get_fileline() << ": error: enumeration " - "method " << use_path << ".num() does not " + "method " << use_path << " does not " "take an argument." << endl; des->errors += 1; } @@ -2184,9 +2196,9 @@ static NetExpr* check_for_enum_methods(const LineInfo*li, // The "first()" method returns the first enumeration value. This // doesn't actually care about the constant value, and instead // returns as a constant literal the first value of the enumeration. - if (args != 0) { + if (parms.size() != 0) { cerr << li->get_fileline() << ": error: enumeration " - "method " << use_path << ".first() does not " + "method " << use_path << " does not " "take an argument." << endl; des->errors += 1; } @@ -2201,9 +2213,9 @@ static NetExpr* check_for_enum_methods(const LineInfo*li, // The "last()" method returns the first enumeration value. This // doesn't actually care about the constant value, and instead // returns as a constant literal the last value of the enumeration. - if (args != 0) { + if (parms.size() != 0) { cerr << li->get_fileline() << ": error: enumeration " - "method " << use_path << ".last() does not " + "method " << use_path << " does not " "take an argument." << endl; des->errors += 1; } @@ -2216,34 +2228,14 @@ static NetExpr* check_for_enum_methods(const LineInfo*li, NetESFunc*sys_expr; - // Process the method argument if it is available. - NetExpr* count = 0; - if (args != 0 && parg) { - count = elaborate_rval_expr(des, scope, &netvector_t::atom2u32, - parg); - if (count == 0) { - cerr << li->get_fileline() << ": error: unable to elaborate " - "enumeration method argument " << use_path << "." - << method_name << "(" << parg << ")." << endl; - args = 0; - des->errors += 1; - } else if (NetEEvent*evt = dynamic_cast (count)) { - cerr << evt->get_fileline() << ": error: An event '" - << evt->event()->name() << "' cannot be an enumeration " - "method argument." << endl; - args = 0; - des->errors += 1; - } - } - if (method_name == "name") { // The "name()" method returns the name of the current enumeration // value. The generated system task takes the enumeration // definition and the enumeration value. The return value is the // string name of the enumeration. - if (args != 0) { + if (parms.size() != 0) { cerr << li->get_fileline() << ": error: enumeration " - "method " << use_path << ".name() does not " + "method " << use_path << " does not " "take an argument." << endl; des->errors += 1; } @@ -2257,37 +2249,51 @@ static NetExpr* check_for_enum_methods(const LineInfo*li, sys_expr->parm(0, def); sys_expr->parm(1, expr); - } else if (method_name == "next") { - // The "next()" method returns the next enumeration value. - if (args > 1) { - cerr << li->get_fileline() << ": error: enumeration " - "method " << use_path << ".next() take at " - "most one argument." << endl; - des->errors += 1; - } - sys_expr = new NetESFunc("$ivl_enum_method$next", netenum, - 2 + (args != 0)); - NetENetenum* def = new NetENetenum(netenum); - def->set_line(*li); - sys_expr->parm(0, def); - sys_expr->parm(1, expr); - if (args != 0) sys_expr->parm(2, count); + } else if (method_name == "next" || method_name == "prev") { + static const std::vector parm_names = { + perm_string::literal("N"), + }; + auto args = map_named_args(des, parm_names, parms); - } else if (method_name == "prev") { - // The "prev()" method returns the previous enumeration value. - if (args > 1) { + // Process the method argument if it is available. + NetExpr *count = nullptr; + if (args.size() != 0 && args[0]) { + count = elaborate_rval_expr(des, scope, &netvector_t::atom2u32, + args[0]); + if (!count) { + cerr << li->get_fileline() << ": error: unable to elaborate " + "enumeration method argument " << use_path << "." + << method_name << "(" << args[0] << ")." << endl; + des->errors++; + } else if (NetEEvent *evt = dynamic_cast (count)) { + cerr << evt->get_fileline() << ": error: An event '" + << evt->event()->name() << "' cannot be an enumeration " + "method argument." << endl; + des->errors++; + } + } + + // The "next()" and "prev()" methods returns the next or previous enumeration value. + if (args.size() > 1) { cerr << li->get_fileline() << ": error: enumeration " - "method " << use_path << ".prev() take at " + "method " << use_path << " takes at " "most one argument." << endl; des->errors += 1; } - sys_expr = new NetESFunc("$ivl_enum_method$prev", netenum, - 2 + (args != 0)); + + const char *func_name; + if (method_name == "next") + func_name = "$ivl_enum_method$next"; + else + func_name = "$ivl_enum_method$prev"; + + sys_expr = new NetESFunc(func_name, netenum, + 2 + (count != nullptr)); NetENetenum* def = new NetENetenum(netenum); def->set_line(*li); sys_expr->parm(0, def); sys_expr->parm(1, expr); - if (args != 0) sys_expr->parm(2, count); + if (count) sys_expr->parm(2, count); } else { // This is an unknown enumeration method. @@ -3119,9 +3125,12 @@ unsigned PECallFunction::elaborate_arguments_(Design*des, NetScope*scope, des->errors += 1; } + auto args = map_named_args(des, def, parms_, parm_off); + for (unsigned idx = 0 ; idx < parm_count ; idx += 1) { unsigned pidx = idx + parm_off; - PExpr*tmp = (idx < actual_count) ? parms_[idx] : NULL; + PExpr *tmp = args[idx]; + if (tmp) { parms[pidx] = elaborate_rval_expr(des, scope, def->port(pidx)->net_type(), @@ -3354,12 +3363,10 @@ NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope, // Get the method name that we are looking for. perm_string method_name = search_results.path_tail.back().name; - - PExpr*tmp = parms_.size() ? parms_[0] : NULL; return check_for_enum_methods(this, des, scope, netenum, path_, method_name, sub_expr, - tmp, parms_.size()); + parms_); } // Class methods. Generate function call to the class method. @@ -3437,6 +3444,17 @@ NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope, } if (method_name == "substr") { + if (parms_.size() != 2) + cerr << get_fileline() << ": error: Method `substr()`" + << " requires 2 arguments, got " << parms_.size() + << "." << endl; + + static const std::vector parm_names = { + perm_string::literal("i"), + perm_string::literal("j") + }; + auto args = map_named_args(des, parm_names, parms_); + NetESFunc*sys_expr = new NetESFunc("$ivl_string_method$substr", &netstring_t::type_string, 3); sys_expr->set_line(*this); @@ -3444,16 +3462,15 @@ NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope, // First argument is the source string. sys_expr->parm(0, sub_expr); - ivl_assert(*this, parms_.size() == 2); - NetExpr*tmp; + for (int i = 0; i < 2; i++) { + if (!args[i]) + continue; - tmp = elaborate_rval_expr(des, scope, &netvector_t::atom2u32, - parms_[0], false); - sys_expr->parm(1, tmp); - - tmp = elaborate_rval_expr(des, scope, &netvector_t::atom2u32, - parms_[1], false); - sys_expr->parm(2, tmp); + auto expr = elaborate_rval_expr(des, scope, + &netvector_t::atom2u32, + args[i], false); + sys_expr->parm(i + 1, expr); + } return sys_expr; } @@ -4943,7 +4960,7 @@ NetExpr* PEIdent::elaborate_expr_(Design*des, NetScope*scope, return check_for_enum_methods(this, des, scope, netenum, sr.path_head, member_comp.name, - expr, NULL, 0); + expr, {}); } ivl_assert(*this, sr.path_tail.empty()); @@ -6661,8 +6678,8 @@ NetExpr* PENewClass::elaborate_expr_constructor_(Design*des, NetScope*scope, // generate an error message. The case of too few arguments // will be handled below, when we run out of arguments. if ((parms_.size()+1) > def->port_count()) { - cerr << get_fileline() << ": error: Parm count mismatch" - << " passing " << parms_.size() << " arguments " + cerr << get_fileline() << ": error: Argument count mismatch." + << " Passing " << parms_.size() << " arguments" << " to constructor expecting " << (def->port_count()-1) << " arguments." << endl; des->errors += 1; @@ -6671,14 +6688,15 @@ NetExpr* PENewClass::elaborate_expr_constructor_(Design*des, NetScope*scope, vector parms (def->port_count()); parms[0] = obj; + auto args = map_named_args(des, def, parms_, 1); + int missing_parms = 0; for (size_t idx = 1 ; idx < parms.size() ; idx += 1) { // While there are default arguments, check them. - if (idx <= parms_.size() && parms_[idx-1]) { - PExpr*tmp = parms_[idx-1]; + if (args[idx - 1]) { parms[idx] = elaborate_rval_expr(des, scope, def->port(idx)->net_type(), - tmp, false); + args[idx - 1], false); // NOTE: if elaborate_rval_expr fails, it will return a // nullptr, but it will also increment des->errors so there // is nothing we need to do here. diff --git a/elab_sig.cc b/elab_sig.cc index a855d9948..c3a0fc64f 100644 --- a/elab_sig.cc +++ b/elab_sig.cc @@ -688,7 +688,8 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const vectorports; vectorpdef; - elaborate_sig_ports_(des, scope, ports, pdef); + vector port_names; + elaborate_sig_ports_(des, scope, ports, pdef, port_names); NetFuncDef*def = new NetFuncDef(scope, ret_sig, ports, pdef); @@ -722,7 +723,8 @@ void PTask::elaborate_sig(Design*des, NetScope*scope) const vectorports; vectorpdefs; - elaborate_sig_ports_(des, scope, ports, pdefs); + vector port_names; + elaborate_sig_ports_(des, scope, ports, pdefs, port_names); NetTaskDef*def = new NetTaskDef(scope, ports, pdefs); scope->set_task_def(def); @@ -732,11 +734,14 @@ void PTask::elaborate_sig(Design*des, NetScope*scope) const } void PTaskFunc::elaborate_sig_ports_(Design*des, NetScope*scope, - vector&ports, vector&pdefs) const + vector &ports, + vector &pdefs, + vector &port_names) const { if (ports_ == 0) { ports.clear(); pdefs.clear(); + port_names.clear(); /* Make sure the function has at least one input port. If it fails this test, print an error @@ -755,6 +760,7 @@ void PTaskFunc::elaborate_sig_ports_(Design*des, NetScope*scope, ports.resize(ports_->size()); pdefs.resize(ports_->size()); + port_names.resize(ports_->size()); for (size_t idx = 0 ; idx < ports_->size() ; idx += 1) { @@ -817,6 +823,7 @@ void PTaskFunc::elaborate_sig_ports_(Design*des, NetScope*scope, } ports[idx] = tmp; + port_names[idx] = port_name; pdefs[idx] = tmp_def; if (scope->type()==NetScope::FUNC && tmp->port_type()!=NetNet::PINPUT) { cerr << tmp->get_fileline() << ": error: " diff --git a/elaborate.cc b/elaborate.cc index e858d6e1c..16c482f12 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -54,6 +54,7 @@ # include "parse_api.h" # include "compiler.h" # include "ivl_assert.h" +# include "map_named_args.h" using namespace std; @@ -3301,12 +3302,12 @@ NetProc* PChainConstructor::elaborate(Design*des, NetScope*scope) const vector parms (def->port_count()); parms[0] = eres; + auto args = map_named_args(des, def, parms_, 1); for (size_t idx = 1 ; idx < parms.size() ; idx += 1) { - if (idx <= parms_.size() && parms_[idx-1]) { - PExpr*tmp = parms_[idx-1]; + if (args[idx - 1]) { parms[idx] = elaborate_rval_expr(des, scope, def->port(idx)->net_type(), - tmp, false); + args[idx - 1], false); continue; } @@ -3480,12 +3481,19 @@ NetProc* PCallTask::elaborate_sys(Design*des, NetScope*scope) const perm_string name = peek_tail_name(path_); for (unsigned idx = 0 ; idx < parm_count ; idx += 1) { - PExpr*ex = parms_[idx]; - if (ex != 0) { - eparms[idx] = elab_sys_task_arg(des, scope, name, idx, ex); - } else { - eparms[idx] = 0; + auto &parm = parms_[idx]; + + // System functions don't have named parameters + if (!parm.name.nil()) { + cerr << parm.get_fileline() << ": error: " + << "The system task `" << name + << "` has no argument called `" << parm.name + << "`." << endl; + des->errors++; } + + eparms[idx] = elab_sys_task_arg(des, scope, name, idx, + parm.parm); } // Special case: Specify blocks are turned off, and this is an @@ -3615,7 +3623,8 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const NetProc* PCallTask::elaborate_sys_task_method_(Design*des, NetScope*scope, NetNet*net, perm_string method_name, - const char*sys_task_name) const + const char *sys_task_name, + const std::vector &parm_names) const { NetESignal*sig = new NetESignal(net); sig->set_line(*this); @@ -3638,17 +3647,17 @@ NetProc* PCallTask::elaborate_sys_task_method_(Design*des, NetScope*scope, << "method takes no arguments." << endl; des->errors += 1; } + } else if (parm_names.size() != parms_.size()) { + cerr << get_fileline() << ": error: " << method_name + << "() method takes " << parm_names.size() << " arguments, got " + << parms_.size() << "." << endl; + des->errors++; } + auto args = map_named_args(des, parm_names, parms_); for (unsigned idx = 0 ; idx < nparms ; idx += 1) { - PExpr*ex = parms_[idx]; - if (ex != 0) { - argv[idx+1] = elab_sys_task_arg(des, scope, - method_name, - idx, ex); - } else { - argv[idx+1] = 0; - } + argv[idx + 1] = elab_sys_task_arg(des, scope, method_name, + idx, args[idx]); } NetSTask*sys = new NetSTask(sys_task_name, IVL_SFUNC_AS_TASK_IGNORE, argv); @@ -3663,7 +3672,8 @@ NetProc* PCallTask::elaborate_sys_task_method_(Design*des, NetScope*scope, NetProc* PCallTask::elaborate_queue_method_(Design*des, NetScope*scope, NetNet*net, perm_string method_name, - const char*sys_task_name) const + const char *sys_task_name, + const std::vector &parm_names) const { NetESignal*sig = new NetESignal(net); sig->set_line(*this); @@ -3696,33 +3706,38 @@ NetProc* PCallTask::elaborate_queue_method_(Design*des, NetScope*scope, vectorargv (nparms+1); argv[0] = sig; - if (method_name != "insert") { - if ((nparms == 0) || (parms_[0] == 0)) { - argv[1] = 0; - cerr << get_fileline() << ": error: " << method_name - << "() methods first argument is missing." << endl; - des->errors += 1; - } else - argv[1] = elab_and_eval(des, scope, parms_[0], context_width, - false, false, base_type); - } else { - if ((nparms == 0) || (parms_[0] == 0)) { - argv[1] = 0; - cerr << get_fileline() << ": error: " << method_name - << "() methods first argument is missing." << endl; - des->errors += 1; - } else - argv[1] = elab_and_eval(des, scope, parms_[0], 32, - false, false, IVL_VT_LOGIC); - if ((nparms < 2) || (parms_[1] == 0)) { - argv[2] = 0; + auto args = map_named_args(des, parm_names, parms_); + if (method_name != "insert") { + if (nparms == 0 || !args[0]) { + argv[1] = nullptr; + cerr << get_fileline() << ": error: " << method_name + << "() methods first argument is missing." << endl; + des->errors += 1; + } else { + argv[1] = elab_and_eval(des, scope, args[0], context_width, + false, false, base_type); + } + } else { + if (nparms == 0 || !args[0]) { + argv[1] = nullptr; + cerr << get_fileline() << ": error: " << method_name + << "() methods first argument is missing." << endl; + des->errors += 1; + } else { + argv[1] = elab_and_eval(des, scope, args[0], context_width, + false, false, IVL_VT_LOGIC); + } + + if (nparms < 2 || !args[1]) { + argv[2] = nullptr; cerr << get_fileline() << ": error: " << method_name << "() methods second argument is missing." << endl; des->errors += 1; - } else - argv[2] = elab_and_eval(des, scope, parms_[1], context_width, + } else { + argv[2] = elab_and_eval(des, scope, args[1], context_width, false, false, base_type); + } } NetSTask*sys = new NetSTask(sys_task_name, IVL_SFUNC_AS_TASK_IGNORE, argv); @@ -3814,34 +3829,65 @@ NetProc* PCallTask::elaborate_method_(Design*des, NetScope*scope, // Is this a method of a "string" type? if (dynamic_cast(net->net_type())) { - if (method_name=="itoa") + if (method_name == "itoa") { + static const std::vector parm_names = { + perm_string::literal("i") + }; + return elaborate_sys_task_method_(des, scope, net, method_name, - "$ivl_string_method$itoa"); - else if (method_name=="hextoa") + "$ivl_string_method$itoa", + parm_names); + } else if (method_name == "hextoa") { + static const std::vector parm_names = { + perm_string::literal("i") + }; + return elaborate_sys_task_method_(des, scope, net, method_name, - "$ivl_string_method$hextoa"); - else if (method_name=="octtoa") + "$ivl_string_method$hextoa", + parm_names); + } else if (method_name == "octtoa") { + static const std::vector parm_names = { + perm_string::literal("i") + }; + return elaborate_sys_task_method_(des, scope, net, method_name, - "$ivl_string_method$octtoa"); - else if (method_name=="bintoa") + "$ivl_string_method$octtoa", + parm_names); + } else if (method_name == "bintoa") { + static const std::vector parm_names = { + perm_string::literal("i") + }; + return elaborate_sys_task_method_(des, scope, net, method_name, - "$ivl_string_method$bintoa"); - else if (method_name=="realtoa") + "$ivl_string_method$bintoa", + parm_names); + } else if (method_name == "realtoa") { + static const std::vector parm_names = { + perm_string::literal("r") + }; + return elaborate_sys_task_method_(des, scope, net, method_name, - "$ivl_string_method$realtoa"); + "$ivl_string_method$realtoa", + parm_names); + } } // Is this a delete method for dynamic arrays or queues? if (net->darray_type()) { - if (method_name=="delete") + if (method_name == "delete") { + static const std::vector parm_names = { + perm_string::literal("index") + }; + return elaborate_sys_task_method_(des, scope, net, method_name, - "$ivl_darray_method$delete"); - else if (method_name=="size") + "$ivl_darray_method$delete", + parm_names); + } else if (method_name == "size") { // This returns an int. It could be removed, but keep for now. return elaborate_method_func_(scope, net, &netvector_t::atom2s32, method_name, "$size"); - else if (method_name=="reverse") { + } else if (method_name == "reverse") { cerr << get_fileline() << ": sorry: 'reverse()' " "array sorting method is not currently supported." << endl; @@ -3870,25 +3916,42 @@ NetProc* PCallTask::elaborate_method_(Design*des, NetScope*scope, if (net->queue_type()) { const netdarray_t*use_darray = net->darray_type(); - if (method_name == "push_back") + if (method_name == "push_back") { + static const std::vector parm_names = { + perm_string::literal("item") + }; + return elaborate_queue_method_(des, scope, net, method_name, - "$ivl_queue_method$push_back"); - else if (method_name == "push_front") + "$ivl_queue_method$push_back", + parm_names); + } else if (method_name == "push_front") { + static const std::vector parm_names = { + perm_string::literal("item") + }; + return elaborate_queue_method_(des, scope, net, method_name, - "$ivl_queue_method$push_front"); - else if (method_name == "insert") + "$ivl_queue_method$push_front", + parm_names); + } else if (method_name == "insert") { + static const std::vector parm_names = { + perm_string::literal("index"), + perm_string::literal("item") + }; + return elaborate_queue_method_(des, scope, net, method_name, - "$ivl_queue_method$insert"); - else if (method_name == "pop_front") + "$ivl_queue_method$insert", + parm_names); + } else if (method_name == "pop_front") { return elaborate_method_func_(scope, net, use_darray->element_type(), method_name, "$ivl_queue_method$pop_front"); - else if (method_name == "pop_back") + } else if (method_name == "pop_back") { return elaborate_method_func_(scope, net, use_darray->element_type(), method_name, "$ivl_queue_method$pop_back"); + } } if (const netclass_t*class_type = dynamic_cast(par_type)) { @@ -4096,9 +4159,11 @@ NetProc* PCallTask::elaborate_build_call_(Design*des, NetScope*scope, expression the r-value. We know by definition that the port is a reg type, so this elaboration is pretty obvious. */ - for (unsigned idx = use_this?1:0 ; idx < parm_count ; idx += 1) { + unsigned int off = use_this ? 1 : 0; - size_t parms_idx = use_this? idx-1 : idx; + auto args = map_named_args(des, def, parms_, off); + for (unsigned int idx = off; idx < parm_count; idx++) { + size_t parms_idx = idx - off; NetNet*port = def->port(idx); ivl_assert(*this, port->port_type() != NetNet::NOT_A_PORT); @@ -4111,9 +4176,9 @@ NetProc* PCallTask::elaborate_build_call_(Design*des, NetScope*scope, NetExpr*rv = 0; - if (parms_idx < parms_.size() && parms_[parms_idx]) { + if (args[parms_idx]) { rv = elaborate_rval_expr(des, scope, port->net_type(), - parms_ [parms_idx]); + args[parms_idx]); if (NetEEvent*evt = dynamic_cast (rv)) { cerr << evt->get_fileline() << ": error: An event '" << evt->event()->name() << "' can not be a user " @@ -4161,9 +4226,9 @@ NetProc* PCallTask::elaborate_build_call_(Design*des, NetScope*scope, expression that can be a target to a procedural assignment, including a memory word. */ - for (unsigned idx = use_this?1:0 ; idx < parm_count ; idx += 1) { + for (unsigned int idx = off; idx < parm_count; idx++) { - size_t parms_idx = use_this? idx-1 : idx; + size_t parms_idx = idx - off; NetNet*port = def->port(idx); @@ -4179,12 +4244,12 @@ NetProc* PCallTask::elaborate_build_call_(Design*des, NetScope*scope, message. Note that the elaborate_lval method already printed a detailed message for the latter case. */ NetAssign_*lv = 0; - if (parms_idx < parms_.size() && parms_[parms_idx]) { - lv = parms_[parms_idx]->elaborate_lval(des, scope, false, false); + if (args[parms_idx]) { + lv = args[parms_idx]->elaborate_lval(des, scope, false, false); if (lv == 0) { - cerr << parms_[parms_idx]->get_fileline() << ": error: " + cerr << args[parms_idx]->get_fileline() << ": error: " << "I give up on task port " << (idx+1) - << " expression: " << *parms_[parms_idx] << endl; + << " expression: " << *args[parms_idx] << endl; } } else if (port->port_type() == NetNet::POUTPUT) { // Output ports were skipped earlier, so @@ -4335,19 +4400,25 @@ bool PCallTask::elaborate_elab(Design*des, NetScope*scope) const bool const_parms = true; for (unsigned idx = 0 ; idx < parm_count ; idx += 1) { - PExpr*ex = parms_[idx]; - if (ex != 0) { - eparms[idx] = elab_sys_task_arg(des, scope, name, idx, ex); - if (!check_parm_is_const(eparms[idx])) { - cerr << get_fileline() << ": error: Elaboration task " - << name << "() parameter [" << idx+1 << "] '" - << *eparms[idx] << "' is not constant." << endl; - des->errors += 1; - const_parms = false; - } - } else { - eparms[idx] = 0; - } + auto &parm = parms_[idx]; + + // Elaboration tasks don't have named parameters + if (!parm.name.nil()) { + cerr << parm.get_fileline() << ": error: " + << "The elaboration system task `" << name + << "` has no argument called `" << parm.name + << "`." << endl; + des->errors++; + } + + eparms[idx] = elab_sys_task_arg(des, scope, name, idx, parm.parm); + if (!check_parm_is_const(eparms[idx])) { + cerr << get_fileline() << ": error: Elaboration task " + << name << "() parameter [" << idx+1 << "] '" + << *eparms[idx] << "' is not constant." << endl; + des->errors += 1; + const_parms = false; + } } if (!const_parms) return true; diff --git a/map_named_args.cc b/map_named_args.cc new file mode 100644 index 000000000..fc108feef --- /dev/null +++ b/map_named_args.cc @@ -0,0 +1,75 @@ +// SPDX-FileCopyrightText: 2023 Lars-Peter Clausen +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "PExpr.h" +#include "ivl_assert.h" +#include "map_named_args.h" +#include "netlist.h" + +#include + +std::vector map_named_args(Design *des, + const std::vector &names, + const std::vector &parms) +{ + std::vector args(names.size()); + + bool has_named = false; + for (size_t i = 0; i < parms.size(); i++) { + if (parms[i].name.nil()) { + if (!parms[i].parm) + continue; + + if (has_named) { + std::cerr << parms[i].get_fileline() << ": error: " + << "Positional argument must preceded " + << "named arguments." + << std::endl; + } else if (i < args.size()) { + args[i] = parms[i].parm; + } + + continue; + } + has_named = true; + + bool found = false; + for (size_t j = 0; j < names.size(); j++) { + if (names[j] == parms[i].name) { + if (args[j]) { + std::cerr << parms[i].get_fileline() << ": error: " + << "Argument `" + << parms[i].name + << "` has already been specified." + << std::endl; + des->errors++; + } else { + args[j] = parms[i].parm; + } + found = true; + break; + } + } + if (!found) { + std::cerr << parms[i].get_fileline() << ": error: " + << "No argument called `" + << parms[i].name << "`." + << std::endl; + des->errors++; + } + } + + return args; +} + +std::vector map_named_args(Design *des, NetBaseDef *def, + const std::vector &parms, + unsigned int off) +{ + std::vector names; + + for (size_t j = off; j < def->port_count(); j++) + names.push_back(def->port(j)->name()); + + return map_named_args(des, names, parms); +} diff --git a/map_named_args.h b/map_named_args.h new file mode 100644 index 000000000..f0017198f --- /dev/null +++ b/map_named_args.h @@ -0,0 +1,22 @@ +// SPDX-FileCopyrightText: 2023 Lars-Peter Clausen +// SPDX-License-Identifier: GPL-2.0-or-later + +#ifndef MAP_NAMED_ARGS_H +#define MAP_NAMED_ARGS_H + +#include +#include "pform_types.h" + +class PExpr; +class Design; +class NetBaseDef; + +std::vector map_named_args(Design *des, + const std::vector &names, + const std::vector &parms); + +std::vector map_named_args(Design *des, NetBaseDef *def, + const std::vector &parms, + unsigned int off); + +#endif diff --git a/netmisc.cc b/netmisc.cc index 5954db89f..8f3f89b84 100644 --- a/netmisc.cc +++ b/netmisc.cc @@ -1046,6 +1046,9 @@ NetExpr* elab_and_eval(Design*des, NetScope*scope, PExpr*pe, NetExpr* elab_sys_task_arg(Design*des, NetScope*scope, perm_string name, unsigned arg_idx, PExpr*pe, bool need_const) { + if (!pe) + return nullptr; + PExpr::width_mode_t mode = PExpr::SIZED; pe->test_width(des, scope, mode); diff --git a/parse.y b/parse.y index 11e28dcc0..1aa5f0105 100644 --- a/parse.y +++ b/parse.y @@ -172,9 +172,9 @@ template void append(vector&out, const std::vector&in) * The parser parses an empty argument list as an argument list with an single * empty argument. Fix this up here and replace it with an empty list. */ -static void argument_list_fixup(list*lst) +static void argument_list_fixup(list *lst) { - if (lst->size() == 1 && !lst->front()) + if (lst->size() == 1 && lst->front().name.nil() && !lst->front().parm) lst->clear(); } @@ -184,17 +184,20 @@ static void argument_list_fixup(list*lst) */ static PECallFunction*make_call_function(perm_string tn, PExpr*arg) { - std::vector parms(1); - parms[0] = arg; + std::vector parms(1); + parms[0].parm = arg; + parms[0].set_line(*arg); PECallFunction*tmp = new PECallFunction(tn, parms); return tmp; } static PECallFunction*make_call_function(perm_string tn, PExpr*arg1, PExpr*arg2) { - std::vector parms(2); - parms[0] = arg1; - parms[1] = arg2; + std::vector parms(2); + parms[0].parm = arg1; + parms[0].set_line(*arg1); + parms[1].parm = arg2; + parms[1].set_line(*arg2); PECallFunction*tmp = new PECallFunction(tn, parms); return tmp; } @@ -510,7 +513,7 @@ Module::port_t *module_declare_port(const YYLTYPE&loc, char *id, struct { data_type_t*type; - std::list*exprs; + std::list *args; } class_declaration_extends; struct { @@ -690,6 +693,10 @@ Module::port_t *module_declare_port(const YYLTYPE&loc, char *id, %type attribute %type attribute_list attribute_instance_list attribute_list_opt +%type argument +%type argument_list +%type argument_list_parens argument_list_parens_opt + %type case_item %type case_items @@ -717,7 +724,6 @@ Module::port_t *module_declare_port(const YYLTYPE&loc, char *id, %type delay_value delay_value_simple %type delay1 delay3 delay3_opt delay_value_list %type expression_list_with_nuls expression_list_proper -%type argument_list_parens argument_list_parens_opt %type cont_assign cont_assign_list %type variable_decl_assignment @@ -889,7 +895,7 @@ class_declaration /* IEEE1800-2005: A.1.2 */ class_type_t *class_type= new class_type_t(name); FILE_NAME(class_type, @4); pform_set_typedef(@4, name, class_type, nullptr); - pform_start_class_declaration(@2, class_type, $5.type, $5.exprs, $1); + pform_start_class_declaration(@2, class_type, $5.type, $5.args, $1); } class_items_opt K_endclass { // Process a class. @@ -932,11 +938,12 @@ class_declaration_endlabel_opt class_declaration_extends_opt /* IEEE1800-2005: A.1.2 */ : K_extends ps_type_identifier argument_list_parens_opt - { $$.type = $2; - $$.exprs = $3; + { $$.type = $2; + $$.args = $3; } | - { $$.type = 0; $$.exprs = 0; } + { $$ = {nullptr, nullptr}; + } ; /* The class_items_opt and class_items rules together implement the @@ -2251,7 +2258,7 @@ simple_immediate_assertion_statement /* IEEE1800-2012 A.6.10 */ : assert_or_assume '(' expression ')' statement_or_null %prec less_than_K_else { if (gn_supported_assertions_flag) { - std::listarg_list; + std::list arg_list; PCallTask*tmp1 = new PCallTask(lex_strings.make("$error"), arg_list); FILE_NAME(tmp1, @1); PCondit*tmp2 = new PCondit($3, $5, tmp1); @@ -3714,12 +3721,45 @@ expression_list_with_nuls } ; +argument + : expression + { named_pexpr_t *tmp = new named_pexpr_t; + FILE_NAME(tmp, @$); + tmp->name = perm_string(); + tmp->parm = $1; + $$ = tmp; + } + | named_expression_opt + { $$ = $1; + } + | + { named_pexpr_t *tmp = new named_pexpr_t; + tmp->name = perm_string(); + tmp->parm = nullptr; + $$ = tmp; + } + ; + +argument_list + : argument + { std::list *expr = new std::list; + expr->push_back(*$1); + delete $1; + $$ = expr; + } + | argument_list ',' argument + { $1->push_back(*$3); + delete $3; + $$ = $1; + } + ; + /* An argument list enclosed in parenthesis. The parser will parse '()' as a * argument list with an single empty item. We fix this up once the list * parsing is done by replacing it with the empty list. */ argument_list_parens - : '(' expression_list_with_nuls ')' + : '(' argument_list ')' { argument_list_fixup($2); $$ = $2; } ; @@ -3731,7 +3771,8 @@ argument_list_parens_opt : argument_list_parens { $$ = $1; } | - { $$ = new std::list; } + { $$ = new std::list; } + ; expression_list_proper : expression_list_proper ',' expression @@ -3874,12 +3915,14 @@ expr_primary delete $2; $$ = tmp; } - | SYSTEM_IDENTIFIER '(' expression_list_proper ')' + | SYSTEM_IDENTIFIER argument_list_parens { perm_string tn = lex_strings.make($1); - PECallFunction*tmp = new PECallFunction(tn, *$3); + PECallFunction *tmp = new PECallFunction(tn, *$2); + if ($2->empty()) + pform_requires_sv(@1, "Empty function argument list"); FILE_NAME(tmp, @1); delete[]$1; - delete $3; + delete $2; $$ = tmp; } | package_scope hierarchy_identifier { lex_in_package_scope(0); } argument_list_parens @@ -3889,16 +3932,6 @@ expr_primary delete $4; $$ = tmp; } - | SYSTEM_IDENTIFIER '(' ')' - { perm_string tn = lex_strings.make($1); - const std::vectorempty; - PECallFunction*tmp = new PECallFunction(tn, empty); - FILE_NAME(tmp, @1); - delete[]$1; - $$ = tmp; - pform_requires_sv(@1, "Empty function argument list"); - } - | K_this { PEIdent*tmp = new PEIdent(perm_string::literal(THIS_TOKEN)); FILE_NAME(tmp,@1); @@ -6551,7 +6584,7 @@ subroutine_call } | hierarchy_identifier '(' error ')' { yyerror(@3, "error: Syntax error in task arguments."); - listpt; + std::list pt; PCallTask*tmp = pform_make_call_task(@1, *$1, pt); delete $1; $$ = tmp; @@ -6928,7 +6961,7 @@ statement_item /* This is roughly statement_item in the LRM */ } else { yyerror(@2, "error: Constraint block can only be applied to randomize method."); } - listpt; + list pt; PCallTask*tmp = new PCallTask(*$1, pt); FILE_NAME(tmp, @1); delete $1; diff --git a/pform.cc b/pform.cc index c2431ac5a..142df2c66 100644 --- a/pform.cc +++ b/pform.cc @@ -927,7 +927,7 @@ typedef_t* pform_test_type_identifier(const struct vlltype&loc, const char*txt) PECallFunction* pform_make_call_function(const struct vlltype&loc, const pform_name_t&name, - const list&parms) + const list &parms) { if (gn_system_verilog()) check_potential_imports(loc, name.front().name, true); @@ -939,7 +939,7 @@ PECallFunction* pform_make_call_function(const struct vlltype&loc, PCallTask* pform_make_call_task(const struct vlltype&loc, const pform_name_t&name, - const list&parms) + const list &parms) { if (gn_system_verilog()) check_potential_imports(loc, name.front().name, true); @@ -1732,7 +1732,7 @@ void pform_endgenerate(bool end_conditional) void pform_make_elab_task(const struct vlltype&li, perm_string name, - const list¶ms) + const list ¶ms) { PCallTask*elab_task = new PCallTask(name, params); FILE_NAME(elab_task, li); diff --git a/pform.h b/pform.h index 92d3edfb2..bb3dabfef 100644 --- a/pform.h +++ b/pform.h @@ -173,7 +173,7 @@ extern void pform_endmodule(const char*, bool inside_celldefine, extern void pform_start_class_declaration(const struct vlltype&loc, class_type_t*type, data_type_t*base_type, - std::list*base_exprs, + std::list *base_args, bool virtual_class); extern void pform_class_property(const struct vlltype&loc, property_qualifier_t pq, @@ -307,7 +307,7 @@ bool pform_error_in_generate(const vlltype&loc, const char *type); extern void pform_make_elab_task(const struct vlltype&li, perm_string name, - const std::list¶ms); + const std::list ¶ms); extern void pform_set_typedef(const struct vlltype&loc, perm_string name, data_type_t*data_type, @@ -322,10 +322,10 @@ extern void pform_set_type_referenced(const struct vlltype&loc, const char*name) */ extern PECallFunction* pform_make_call_function(const struct vlltype&loc, const pform_name_t&name, - const std::list&parms); + const std::list &parms); extern PCallTask* pform_make_call_task(const struct vlltype&loc, const pform_name_t&name, - const std::list&parms); + const std::list &parms); extern void pform_make_foreach_declarations(const struct vlltype&loc, std::list*loop_vars); diff --git a/pform_analog.cc b/pform_analog.cc index b849f6b82..eb96cce61 100644 --- a/pform_analog.cc +++ b/pform_analog.cc @@ -46,12 +46,12 @@ void pform_make_analog_behavior(const struct vlltype&loc, ivl_process_type_t pt, PExpr* pform_make_branch_probe_expression(const struct vlltype&loc, char*name, char*n1, char*n2) { - vector parms (2); - parms[0] = new PEIdent(lex_strings.make(n1)); - FILE_NAME(parms[0], loc); + vector parms (2); + parms[0].parm = new PEIdent(lex_strings.make(n1)); + FILE_NAME(parms[0].parm, loc); - parms[1] = new PEIdent(lex_strings.make(n2)); - FILE_NAME(parms[1], loc); + parms[1].parm = new PEIdent(lex_strings.make(n2)); + FILE_NAME(parms[1].parm, loc); PECallFunction*res = new PECallFunction(lex_strings.make(name), parms); FILE_NAME(res, loc); @@ -61,9 +61,9 @@ PExpr* pform_make_branch_probe_expression(const struct vlltype&loc, PExpr* pform_make_branch_probe_expression(const struct vlltype&loc, char*name, char*branch_name) { - vector parms (1); - parms[0] = new PEIdent(lex_strings.make(branch_name)); - FILE_NAME(parms[0], loc); + vector parms (1); + parms[0].parm = new PEIdent(lex_strings.make(branch_name)); + FILE_NAME(parms[0].parm, loc); PECallFunction*res = new PECallFunction(lex_strings.make(name), parms); FILE_NAME(res, loc); diff --git a/pform_dump.cc b/pform_dump.cc index 735d0f923..1a43caaa5 100644 --- a/pform_dump.cc +++ b/pform_dump.cc @@ -345,15 +345,7 @@ void class_type_t::pform_dump(ostream&out, unsigned indent) const if (base_type) out << " extends "; if (! base_args.empty()) { - out << " ("; - for (list::const_iterator cur = base_args.begin() - ; cur != base_args.end() ; ++cur) { - const PExpr*curp = *cur; - if (cur != base_args.begin()) - out << ", "; - curp->dump(out); - } - out << ")"; + out << " (" << base_args << ")"; } out << " {"; diff --git a/pform_pclass.cc b/pform_pclass.cc index f70fc8621..b438f4cde 100644 --- a/pform_pclass.cc +++ b/pform_pclass.cc @@ -43,7 +43,7 @@ static PClass*pform_cur_class = 0; void pform_start_class_declaration(const struct vlltype&loc, class_type_t*type, data_type_t*base_type, - list*base_exprs, + list *base_args, bool virtual_class) { PClass*class_scope = pform_push_class_scope(loc, type->name); @@ -55,13 +55,12 @@ void pform_start_class_declaration(const struct vlltype&loc, type->base_type.reset(base_type); type->virtual_class = virtual_class; + ivl_assert(loc, type->base_args.empty()); - if (base_exprs) { - for (list::iterator cur = base_exprs->begin() - ; cur != base_exprs->end() ; ++ cur) { - type->base_args.push_back(*cur); - } - delete base_exprs; + if (base_args) { + type->base_args.insert(type->base_args.begin(), base_args->begin(), + base_args->end()); + delete base_args; } } diff --git a/pform_types.h b/pform_types.h index ebdff6f0b..fb7a03f8a 100644 --- a/pform_types.h +++ b/pform_types.h @@ -377,7 +377,7 @@ struct class_type_t : public data_type_t { // hierarchy. If there are arguments to the base class, then // put them in the base_args vector. std::unique_ptr base_type; - std::listbase_args; + std::vector base_args; bool virtual_class; From 250c456f94134ddb9dbcbd5f5ee586b56f97bad8 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 31 Dec 2022 19:02:01 -0800 Subject: [PATCH 8/8] Add regression tests for binding task/function arguments by name Check that binding task and function arguments by name works as expected. Also check that is works for the various variations of invoking a class constructor. Signed-off-by: Lars-Peter Clausen --- ivtest/ivltests/sv_named_arg_base1.v | 25 ++++++++++++++++ ivtest/ivltests/sv_named_arg_base2.v | 26 ++++++++++++++++ ivtest/ivltests/sv_named_arg_base3.v | 27 +++++++++++++++++ ivtest/ivltests/sv_named_arg_base_fail1.v | 21 +++++++++++++ ivtest/ivltests/sv_named_arg_base_fail2.v | 21 +++++++++++++ ivtest/ivltests/sv_named_arg_base_fail3.v | 21 +++++++++++++ ivtest/ivltests/sv_named_arg_base_fail4.v | 21 +++++++++++++ ivtest/ivltests/sv_named_arg_base_fail5.v | 20 +++++++++++++ ivtest/ivltests/sv_named_arg_chained1.v | 28 +++++++++++++++++ ivtest/ivltests/sv_named_arg_chained2.v | 29 ++++++++++++++++++ ivtest/ivltests/sv_named_arg_chained3.v | 30 +++++++++++++++++++ ivtest/ivltests/sv_named_arg_chained_fail1.v | 24 +++++++++++++++ ivtest/ivltests/sv_named_arg_chained_fail2.v | 24 +++++++++++++++ ivtest/ivltests/sv_named_arg_chained_fail3.v | 24 +++++++++++++++ ivtest/ivltests/sv_named_arg_chained_fail4.v | 24 +++++++++++++++ ivtest/ivltests/sv_named_arg_chained_fail5.v | 23 ++++++++++++++ ivtest/ivltests/sv_named_arg_func1.v | 19 ++++++++++++ ivtest/ivltests/sv_named_arg_func2.v | 20 +++++++++++++ ivtest/ivltests/sv_named_arg_func3.v | 21 +++++++++++++ ivtest/ivltests/sv_named_arg_func_fail1.v | 15 ++++++++++ ivtest/ivltests/sv_named_arg_func_fail2.v | 16 ++++++++++ ivtest/ivltests/sv_named_arg_func_fail3.v | 16 ++++++++++ ivtest/ivltests/sv_named_arg_func_fail4.v | 16 ++++++++++ ivtest/ivltests/sv_named_arg_func_fail5.v | 15 ++++++++++ ivtest/ivltests/sv_named_arg_new1.v | 22 ++++++++++++++ ivtest/ivltests/sv_named_arg_new2.v | 23 ++++++++++++++ ivtest/ivltests/sv_named_arg_new3.v | 24 +++++++++++++++ ivtest/ivltests/sv_named_arg_new_fail1.v | 18 +++++++++++ ivtest/ivltests/sv_named_arg_new_fail2.v | 18 +++++++++++ ivtest/ivltests/sv_named_arg_new_fail3.v | 18 +++++++++++ ivtest/ivltests/sv_named_arg_new_fail4.v | 18 +++++++++++ ivtest/ivltests/sv_named_arg_new_fail5.v | 17 +++++++++++ ivtest/ivltests/sv_named_arg_task1.v | 17 +++++++++++ ivtest/ivltests/sv_named_arg_task2.v | 18 +++++++++++ ivtest/ivltests/sv_named_arg_task3.v | 19 ++++++++++++ ivtest/ivltests/sv_named_arg_task_fail1.v | 14 +++++++++ ivtest/ivltests/sv_named_arg_task_fail2.v | 14 +++++++++ ivtest/ivltests/sv_named_arg_task_fail3.v | 14 +++++++++ ivtest/ivltests/sv_named_arg_task_fail4.v | 15 ++++++++++ ivtest/ivltests/sv_named_arg_task_fail5.v | 14 +++++++++ ivtest/vvp_tests/sv_named_arg_base1.json | 5 ++++ ivtest/vvp_tests/sv_named_arg_base2.json | 5 ++++ ivtest/vvp_tests/sv_named_arg_base3.json | 5 ++++ ivtest/vvp_tests/sv_named_arg_base_fail1.json | 5 ++++ ivtest/vvp_tests/sv_named_arg_base_fail2.json | 5 ++++ ivtest/vvp_tests/sv_named_arg_base_fail3.json | 5 ++++ ivtest/vvp_tests/sv_named_arg_base_fail4.json | 5 ++++ ivtest/vvp_tests/sv_named_arg_base_fail5.json | 5 ++++ ivtest/vvp_tests/sv_named_arg_chained1.json | 5 ++++ ivtest/vvp_tests/sv_named_arg_chained2.json | 5 ++++ ivtest/vvp_tests/sv_named_arg_chained3.json | 5 ++++ .../vvp_tests/sv_named_arg_chained_fail1.json | 5 ++++ .../vvp_tests/sv_named_arg_chained_fail2.json | 5 ++++ .../vvp_tests/sv_named_arg_chained_fail3.json | 5 ++++ .../vvp_tests/sv_named_arg_chained_fail4.json | 5 ++++ .../vvp_tests/sv_named_arg_chained_fail5.json | 5 ++++ ivtest/vvp_tests/sv_named_arg_func1.json | 5 ++++ ivtest/vvp_tests/sv_named_arg_func2.json | 5 ++++ ivtest/vvp_tests/sv_named_arg_func3.json | 5 ++++ ivtest/vvp_tests/sv_named_arg_func_fail1.json | 5 ++++ ivtest/vvp_tests/sv_named_arg_func_fail2.json | 5 ++++ ivtest/vvp_tests/sv_named_arg_func_fail3.json | 5 ++++ ivtest/vvp_tests/sv_named_arg_func_fail4.json | 5 ++++ ivtest/vvp_tests/sv_named_arg_func_fail5.json | 5 ++++ ivtest/vvp_tests/sv_named_arg_new1.json | 5 ++++ ivtest/vvp_tests/sv_named_arg_new2.json | 5 ++++ ivtest/vvp_tests/sv_named_arg_new3.json | 5 ++++ ivtest/vvp_tests/sv_named_arg_new_fail1.json | 5 ++++ ivtest/vvp_tests/sv_named_arg_new_fail2.json | 5 ++++ ivtest/vvp_tests/sv_named_arg_new_fail3.json | 5 ++++ ivtest/vvp_tests/sv_named_arg_new_fail4.json | 5 ++++ ivtest/vvp_tests/sv_named_arg_new_fail5.json | 5 ++++ ivtest/vvp_tests/sv_named_arg_task1.json | 5 ++++ ivtest/vvp_tests/sv_named_arg_task2.json | 5 ++++ ivtest/vvp_tests/sv_named_arg_task3.json | 5 ++++ ivtest/vvp_tests/sv_named_arg_task_fail1.json | 5 ++++ ivtest/vvp_tests/sv_named_arg_task_fail2.json | 5 ++++ ivtest/vvp_tests/sv_named_arg_task_fail3.json | 5 ++++ ivtest/vvp_tests/sv_named_arg_task_fail4.json | 5 ++++ ivtest/vvp_tests/sv_named_arg_task_fail5.json | 5 ++++ 80 files changed, 1009 insertions(+) create mode 100644 ivtest/ivltests/sv_named_arg_base1.v create mode 100644 ivtest/ivltests/sv_named_arg_base2.v create mode 100644 ivtest/ivltests/sv_named_arg_base3.v create mode 100644 ivtest/ivltests/sv_named_arg_base_fail1.v create mode 100644 ivtest/ivltests/sv_named_arg_base_fail2.v create mode 100644 ivtest/ivltests/sv_named_arg_base_fail3.v create mode 100644 ivtest/ivltests/sv_named_arg_base_fail4.v create mode 100644 ivtest/ivltests/sv_named_arg_base_fail5.v create mode 100644 ivtest/ivltests/sv_named_arg_chained1.v create mode 100644 ivtest/ivltests/sv_named_arg_chained2.v create mode 100644 ivtest/ivltests/sv_named_arg_chained3.v create mode 100644 ivtest/ivltests/sv_named_arg_chained_fail1.v create mode 100644 ivtest/ivltests/sv_named_arg_chained_fail2.v create mode 100644 ivtest/ivltests/sv_named_arg_chained_fail3.v create mode 100644 ivtest/ivltests/sv_named_arg_chained_fail4.v create mode 100644 ivtest/ivltests/sv_named_arg_chained_fail5.v create mode 100644 ivtest/ivltests/sv_named_arg_func1.v create mode 100644 ivtest/ivltests/sv_named_arg_func2.v create mode 100644 ivtest/ivltests/sv_named_arg_func3.v create mode 100644 ivtest/ivltests/sv_named_arg_func_fail1.v create mode 100644 ivtest/ivltests/sv_named_arg_func_fail2.v create mode 100644 ivtest/ivltests/sv_named_arg_func_fail3.v create mode 100644 ivtest/ivltests/sv_named_arg_func_fail4.v create mode 100644 ivtest/ivltests/sv_named_arg_func_fail5.v create mode 100644 ivtest/ivltests/sv_named_arg_new1.v create mode 100644 ivtest/ivltests/sv_named_arg_new2.v create mode 100644 ivtest/ivltests/sv_named_arg_new3.v create mode 100644 ivtest/ivltests/sv_named_arg_new_fail1.v create mode 100644 ivtest/ivltests/sv_named_arg_new_fail2.v create mode 100644 ivtest/ivltests/sv_named_arg_new_fail3.v create mode 100644 ivtest/ivltests/sv_named_arg_new_fail4.v create mode 100644 ivtest/ivltests/sv_named_arg_new_fail5.v create mode 100644 ivtest/ivltests/sv_named_arg_task1.v create mode 100644 ivtest/ivltests/sv_named_arg_task2.v create mode 100644 ivtest/ivltests/sv_named_arg_task3.v create mode 100644 ivtest/ivltests/sv_named_arg_task_fail1.v create mode 100644 ivtest/ivltests/sv_named_arg_task_fail2.v create mode 100644 ivtest/ivltests/sv_named_arg_task_fail3.v create mode 100644 ivtest/ivltests/sv_named_arg_task_fail4.v create mode 100644 ivtest/ivltests/sv_named_arg_task_fail5.v create mode 100644 ivtest/vvp_tests/sv_named_arg_base1.json create mode 100644 ivtest/vvp_tests/sv_named_arg_base2.json create mode 100644 ivtest/vvp_tests/sv_named_arg_base3.json create mode 100644 ivtest/vvp_tests/sv_named_arg_base_fail1.json create mode 100644 ivtest/vvp_tests/sv_named_arg_base_fail2.json create mode 100644 ivtest/vvp_tests/sv_named_arg_base_fail3.json create mode 100644 ivtest/vvp_tests/sv_named_arg_base_fail4.json create mode 100644 ivtest/vvp_tests/sv_named_arg_base_fail5.json create mode 100644 ivtest/vvp_tests/sv_named_arg_chained1.json create mode 100644 ivtest/vvp_tests/sv_named_arg_chained2.json create mode 100644 ivtest/vvp_tests/sv_named_arg_chained3.json create mode 100644 ivtest/vvp_tests/sv_named_arg_chained_fail1.json create mode 100644 ivtest/vvp_tests/sv_named_arg_chained_fail2.json create mode 100644 ivtest/vvp_tests/sv_named_arg_chained_fail3.json create mode 100644 ivtest/vvp_tests/sv_named_arg_chained_fail4.json create mode 100644 ivtest/vvp_tests/sv_named_arg_chained_fail5.json create mode 100644 ivtest/vvp_tests/sv_named_arg_func1.json create mode 100644 ivtest/vvp_tests/sv_named_arg_func2.json create mode 100644 ivtest/vvp_tests/sv_named_arg_func3.json create mode 100644 ivtest/vvp_tests/sv_named_arg_func_fail1.json create mode 100644 ivtest/vvp_tests/sv_named_arg_func_fail2.json create mode 100644 ivtest/vvp_tests/sv_named_arg_func_fail3.json create mode 100644 ivtest/vvp_tests/sv_named_arg_func_fail4.json create mode 100644 ivtest/vvp_tests/sv_named_arg_func_fail5.json create mode 100644 ivtest/vvp_tests/sv_named_arg_new1.json create mode 100644 ivtest/vvp_tests/sv_named_arg_new2.json create mode 100644 ivtest/vvp_tests/sv_named_arg_new3.json create mode 100644 ivtest/vvp_tests/sv_named_arg_new_fail1.json create mode 100644 ivtest/vvp_tests/sv_named_arg_new_fail2.json create mode 100644 ivtest/vvp_tests/sv_named_arg_new_fail3.json create mode 100644 ivtest/vvp_tests/sv_named_arg_new_fail4.json create mode 100644 ivtest/vvp_tests/sv_named_arg_new_fail5.json create mode 100644 ivtest/vvp_tests/sv_named_arg_task1.json create mode 100644 ivtest/vvp_tests/sv_named_arg_task2.json create mode 100644 ivtest/vvp_tests/sv_named_arg_task3.json create mode 100644 ivtest/vvp_tests/sv_named_arg_task_fail1.json create mode 100644 ivtest/vvp_tests/sv_named_arg_task_fail2.json create mode 100644 ivtest/vvp_tests/sv_named_arg_task_fail3.json create mode 100644 ivtest/vvp_tests/sv_named_arg_task_fail4.json create mode 100644 ivtest/vvp_tests/sv_named_arg_task_fail5.json diff --git a/ivtest/ivltests/sv_named_arg_base1.v b/ivtest/ivltests/sv_named_arg_base1.v new file mode 100644 index 000000000..b6448fd08 --- /dev/null +++ b/ivtest/ivltests/sv_named_arg_base1.v @@ -0,0 +1,25 @@ +// Check that binding task arguments by name is supported. + +module test; + + class B; + integer val; + + function new(integer a, integer b); + val = a + b * 10; + endfunction + endclass + + class C extends B(.b(2), .a(1)); + endclass + + initial begin + C c; + c = new; + if (c.val == 21) begin + $display("PASSED"); + end else begin + $display("FAILED"); + end + end +endmodule diff --git a/ivtest/ivltests/sv_named_arg_base2.v b/ivtest/ivltests/sv_named_arg_base2.v new file mode 100644 index 000000000..42a379d8d --- /dev/null +++ b/ivtest/ivltests/sv_named_arg_base2.v @@ -0,0 +1,26 @@ +// Check that binding task arguments by name is supported and that a mix of +// positional and named arguments is supported. + +module test; + + class B; + integer val; + + function new(integer a, integer b, integer c); + val = a + b * 10 + c * 100; + endfunction + endclass + + class C extends B(1, .c(3), .b(2)); + endclass + + initial begin + C c; + c = new; + if (c.val == 321) begin + $display("PASSED"); + end else begin + $display("FAILED"); + end + end +endmodule diff --git a/ivtest/ivltests/sv_named_arg_base3.v b/ivtest/ivltests/sv_named_arg_base3.v new file mode 100644 index 000000000..e1954044c --- /dev/null +++ b/ivtest/ivltests/sv_named_arg_base3.v @@ -0,0 +1,27 @@ +// Check that binding task arguments by name is supported and that an empty +// value can be bound to the name, in which case the default argument value +// should be used. + +module test; + + class B; + integer val; + + function new(integer a, integer b = 2); + val = a + b * 10; + endfunction + endclass + + class C extends B(.a(1), .b()); + endclass + + initial begin + C c; + c = new; + if (c.val == 21) begin + $display("PASSED"); + end else begin + $display("FAILED"); + end + end +endmodule diff --git a/ivtest/ivltests/sv_named_arg_base_fail1.v b/ivtest/ivltests/sv_named_arg_base_fail1.v new file mode 100644 index 000000000..378e0c067 --- /dev/null +++ b/ivtest/ivltests/sv_named_arg_base_fail1.v @@ -0,0 +1,21 @@ +// Check that an error is reported when trying to bind an argument by nae that +// does not exist + +module test; + + class B; + function new(integer a, integer b); + $display("FAILED"); + endfunction + endclass + + class C extends B(.b(2), .c(1)); // This should fail. `c` is not an arugment + // of the base constructor. + endclass + + initial begin + C c; + c = new; + end + +endmodule diff --git a/ivtest/ivltests/sv_named_arg_base_fail2.v b/ivtest/ivltests/sv_named_arg_base_fail2.v new file mode 100644 index 000000000..90180ab19 --- /dev/null +++ b/ivtest/ivltests/sv_named_arg_base_fail2.v @@ -0,0 +1,21 @@ +// Check that an error is reported when trying to bind the same argument by name +// multiple times. + +module test; + + class B; + function new(integer a, integer b); + $display("FAILED"); + endfunction + endclass + + class C extends B(.a(1), .a(2)); // This should fail. `a` is provided twice + // as a named argument. + endclass + + initial begin + C c; + c = new; + end + +endmodule diff --git a/ivtest/ivltests/sv_named_arg_base_fail3.v b/ivtest/ivltests/sv_named_arg_base_fail3.v new file mode 100644 index 000000000..10728a5fd --- /dev/null +++ b/ivtest/ivltests/sv_named_arg_base_fail3.v @@ -0,0 +1,21 @@ +// Check that an error is reported when trying to bind an argument by name that +// is also provided as a positional argument. + +module test; + + class B; + function new(integer a, integer b); + $display("FAILED"); + endfunction + endclass + + class C extends B(1, .a(2)); // This should fail. `a` is provided both as a + // positional and named argument. + endclass + + initial begin + C c; + c = new; + end + +endmodule diff --git a/ivtest/ivltests/sv_named_arg_base_fail4.v b/ivtest/ivltests/sv_named_arg_base_fail4.v new file mode 100644 index 000000000..921fbd198 --- /dev/null +++ b/ivtest/ivltests/sv_named_arg_base_fail4.v @@ -0,0 +1,21 @@ +// Check that an error is reported trying to provide a positional argument to a +// function after a named argument. + +module test; + + class B; + function new(integer a, integer b); + $display("FAILED"); + endfunction + endclass + + class C extends B(.a(2), 1); // This should fail. Positional arguments must + // precede named arguments. + endclass + + initial begin + C c; + c = new; + end + +endmodule diff --git a/ivtest/ivltests/sv_named_arg_base_fail5.v b/ivtest/ivltests/sv_named_arg_base_fail5.v new file mode 100644 index 000000000..406143563 --- /dev/null +++ b/ivtest/ivltests/sv_named_arg_base_fail5.v @@ -0,0 +1,20 @@ +// Check that an error is reported when binding an empty value to an argument by +// name and the argument does not have a default value. + +module test; + + class B; + function new(integer a); + $display("FAILED"); + endfunction + endclass + + class C extends B(.a()); // This should fail. `a` has no default value. + endclass + + initial begin + C c; + c = new; + end + +endmodule diff --git a/ivtest/ivltests/sv_named_arg_chained1.v b/ivtest/ivltests/sv_named_arg_chained1.v new file mode 100644 index 000000000..d28a70969 --- /dev/null +++ b/ivtest/ivltests/sv_named_arg_chained1.v @@ -0,0 +1,28 @@ +// Check that binding task arguments by name is supported. + +module test; + + class B; + integer val; + + function new(integer a, integer b); + val = a + b * 10; + endfunction + endclass + + class C extends B; + function new; + super.new(.b(2), .a(1)); + endfunction + endclass + + initial begin + C c; + c = new; + if (c.val == 21) begin + $display("PASSED"); + end else begin + $display("FAILED"); + end + end +endmodule diff --git a/ivtest/ivltests/sv_named_arg_chained2.v b/ivtest/ivltests/sv_named_arg_chained2.v new file mode 100644 index 000000000..2816a817d --- /dev/null +++ b/ivtest/ivltests/sv_named_arg_chained2.v @@ -0,0 +1,29 @@ +// Check that binding task arguments by name is supported and that a mix of +// positional and named arguments is supported. + +module test; + + class B; + integer val; + + function new(integer a, integer b, integer c); + val = a + b * 10 + c * 100; + endfunction + endclass + + class C extends B; + function new; + super.new(1, .c(3), .b(2)); + endfunction + endclass + + initial begin + C c; + c = new; + if (c.val == 321) begin + $display("PASSED"); + end else begin + $display("FAILED"); + end + end +endmodule diff --git a/ivtest/ivltests/sv_named_arg_chained3.v b/ivtest/ivltests/sv_named_arg_chained3.v new file mode 100644 index 000000000..8af5a15c9 --- /dev/null +++ b/ivtest/ivltests/sv_named_arg_chained3.v @@ -0,0 +1,30 @@ +// Check that binding task arguments by name is supported and that an empty +// value can be bound to the name, in which case the default argument value +// should be used. + +module test; + + class B; + integer val; + + function new(integer a, integer b = 2); + val = a + b * 10; + endfunction + endclass + + class C extends B; + function new; + super.new(.a(1), .b()); + endfunction + endclass + + initial begin + C c; + c = new; + if (c.val == 21) begin + $display("PASSED"); + end else begin + $display("FAILED"); + end + end +endmodule diff --git a/ivtest/ivltests/sv_named_arg_chained_fail1.v b/ivtest/ivltests/sv_named_arg_chained_fail1.v new file mode 100644 index 000000000..915664f60 --- /dev/null +++ b/ivtest/ivltests/sv_named_arg_chained_fail1.v @@ -0,0 +1,24 @@ +// Check that an error is reported when trying to bind an argument by nae that +// does not exist + +module test; + + class B; + function new(integer a, integer b); + $display("FAILED"); + endfunction + endclass + + class C extends B; + function new; + super.new(.b(2), .c(1)); // This should fail. `c` is not an arugment of + // the base constructor. + endfunction + endclass + + initial begin + C c; + c = new; + end + +endmodule diff --git a/ivtest/ivltests/sv_named_arg_chained_fail2.v b/ivtest/ivltests/sv_named_arg_chained_fail2.v new file mode 100644 index 000000000..7002e7595 --- /dev/null +++ b/ivtest/ivltests/sv_named_arg_chained_fail2.v @@ -0,0 +1,24 @@ +// Check that an error is reported when trying to bind the same argument by name +// multiple times. + +module test; + + class B; + function new(integer a, integer b); + $display("FAILED"); + endfunction + endclass + + class C extends B; + function new; + super.new(.a(1), .a(2)); // This should fail. `a` is provided twice as a + // named argument. + endfunction + endclass + + initial begin + C c; + c = new; + end + +endmodule diff --git a/ivtest/ivltests/sv_named_arg_chained_fail3.v b/ivtest/ivltests/sv_named_arg_chained_fail3.v new file mode 100644 index 000000000..7affb0f9f --- /dev/null +++ b/ivtest/ivltests/sv_named_arg_chained_fail3.v @@ -0,0 +1,24 @@ +// Check that an error is reported when trying to bind an argument by name that +// is also provided as a positional argument. + +module test; + + class B; + function new(integer a, integer b); + $display("FAILED"); + endfunction + endclass + + class C extends B; + function new; + super.new(1, .a(2)); // This should fail. `a` is provided both as a + // positional and named argument. + endfunction + endclass + + initial begin + C c; + c = new; + end + +endmodule diff --git a/ivtest/ivltests/sv_named_arg_chained_fail4.v b/ivtest/ivltests/sv_named_arg_chained_fail4.v new file mode 100644 index 000000000..4647ed6f8 --- /dev/null +++ b/ivtest/ivltests/sv_named_arg_chained_fail4.v @@ -0,0 +1,24 @@ +// Check that an error is reported trying to provide a positional argument to a +// function after a named argument. + +module test; + + class B; + function new(integer a, integer b); + $display("FAILED"); + endfunction + endclass + + class C extends B; + function new; + super.new(.a(2), 1); // This should fail. Positional arguments must + // precede named arguments. + endfunction + endclass + + initial begin + C c; + c = new; + end + +endmodule diff --git a/ivtest/ivltests/sv_named_arg_chained_fail5.v b/ivtest/ivltests/sv_named_arg_chained_fail5.v new file mode 100644 index 000000000..abf44565e --- /dev/null +++ b/ivtest/ivltests/sv_named_arg_chained_fail5.v @@ -0,0 +1,23 @@ +// Check that an error is reported when binding an empty value to an argument by +// name and the argument does not have a default value. + +module test; + + class B; + function new(integer a); + $display("FAILED"); + endfunction + endclass + + class C extends B; + function new; + super.new(.a()); // This should fail. `a` has no default value. + endfunction + endclass + + initial begin + C c; + c = new; + end + +endmodule diff --git a/ivtest/ivltests/sv_named_arg_func1.v b/ivtest/ivltests/sv_named_arg_func1.v new file mode 100644 index 000000000..c38b26adb --- /dev/null +++ b/ivtest/ivltests/sv_named_arg_func1.v @@ -0,0 +1,19 @@ +// Check that binding task arguments by name is supported. + +module test; + + function integer f(integer a, integer b); + return a + b * 10; + endfunction + + initial begin + integer x; + x = f(.b(2), .a(1)); + if (x == 21) begin + $display("PASSED"); + end else begin + $display("FAILED"); + end + end + +endmodule diff --git a/ivtest/ivltests/sv_named_arg_func2.v b/ivtest/ivltests/sv_named_arg_func2.v new file mode 100644 index 000000000..49e211d79 --- /dev/null +++ b/ivtest/ivltests/sv_named_arg_func2.v @@ -0,0 +1,20 @@ +// Check that binding task arguments by name is supported and that a mix of +// positional and named arguments is supported. + +module test; + + function integer f(integer a, integer b, integer c); + return a + b * 10 + c * 100; + endfunction + + initial begin + integer x; + x = f(1, .c(3), .b(2)); + if (x == 321) begin + $display("PASSED"); + end else begin + $display("FAILED"); + end + end + +endmodule diff --git a/ivtest/ivltests/sv_named_arg_func3.v b/ivtest/ivltests/sv_named_arg_func3.v new file mode 100644 index 000000000..9592f694e --- /dev/null +++ b/ivtest/ivltests/sv_named_arg_func3.v @@ -0,0 +1,21 @@ +// Check that binding task arguments by name is supported and that an empty +// value can be bound to the name, in which case the default argument value +// should be used. + +module test; + + function integer f(integer a, integer b = 2); + return a + b * 10; + endfunction + + initial begin + integer x; + x = f(.a(1), .b()); + if (x == 21) begin + $display("PASSED"); + end else begin + $display("FAILED"); + end + end + +endmodule diff --git a/ivtest/ivltests/sv_named_arg_func_fail1.v b/ivtest/ivltests/sv_named_arg_func_fail1.v new file mode 100644 index 000000000..21d3b0494 --- /dev/null +++ b/ivtest/ivltests/sv_named_arg_func_fail1.v @@ -0,0 +1,15 @@ +// Check that an error is reported when trying to bind an argument by nae that +// does not exist + +module test; + + function f(integer a, integer b); + $display("FAILED"); + endfunction + + initial begin + integer x; + x = f(.b(2), .c(1)); // This should fail. `c` is not an arugment of `f`. + end + +endmodule diff --git a/ivtest/ivltests/sv_named_arg_func_fail2.v b/ivtest/ivltests/sv_named_arg_func_fail2.v new file mode 100644 index 000000000..662f37a14 --- /dev/null +++ b/ivtest/ivltests/sv_named_arg_func_fail2.v @@ -0,0 +1,16 @@ +// Check that an error is reported when trying to bind the same argument by name +// multiple times. + +module test; + + function f(integer a, integer b); + $display("FAILED"); + endfunction + + initial begin + integer x; + x = f(.a(1), .a(2)); // This should fail. `a` is provided twice as a named + // argument. + end + +endmodule diff --git a/ivtest/ivltests/sv_named_arg_func_fail3.v b/ivtest/ivltests/sv_named_arg_func_fail3.v new file mode 100644 index 000000000..6c8cbb1e7 --- /dev/null +++ b/ivtest/ivltests/sv_named_arg_func_fail3.v @@ -0,0 +1,16 @@ +// Check that an error is reported when trying to bind an argument by name that +// is also provided as a positional argument. + +module test; + + function f(integer a, integer b); + $display("FAILED"); + endfunction + + initial begin + integer x; + x = f(1, .a(2)); // This should fail. `a` is provided both as a positional + // and named argument. + end + +endmodule diff --git a/ivtest/ivltests/sv_named_arg_func_fail4.v b/ivtest/ivltests/sv_named_arg_func_fail4.v new file mode 100644 index 000000000..e8f8ca070 --- /dev/null +++ b/ivtest/ivltests/sv_named_arg_func_fail4.v @@ -0,0 +1,16 @@ +// Check that an error is reported trying to provide a positional argument to a +// function after a named argument. + +module test; + + function f(integer a, integer b); + $display("FAILED"); + endfunction + + initial begin + integer x; + x = f(.a(2), 1); // This should fail. Positional arguments must precede + // named arguments. + end + +endmodule diff --git a/ivtest/ivltests/sv_named_arg_func_fail5.v b/ivtest/ivltests/sv_named_arg_func_fail5.v new file mode 100644 index 000000000..ad503d56e --- /dev/null +++ b/ivtest/ivltests/sv_named_arg_func_fail5.v @@ -0,0 +1,15 @@ +// Check that an error is reported when binding an empty value to an argument by +// name and the argument does not have a default value. + +module test; + + function f(integer a); + $display("FAILED"); + endfunction + + initial begin + integer x; + x = f(.a()); // This should fail. `a` has no default value. + end + +endmodule diff --git a/ivtest/ivltests/sv_named_arg_new1.v b/ivtest/ivltests/sv_named_arg_new1.v new file mode 100644 index 000000000..c316add56 --- /dev/null +++ b/ivtest/ivltests/sv_named_arg_new1.v @@ -0,0 +1,22 @@ +// Check that binding task arguments by name is supported. + +module test; + + class C; + integer val; + + function new(integer a, integer b); + val = a + b * 10; + endfunction + endclass + + initial begin + C c; + c = new(.b(2), .a(1)); + if (c.val == 21) begin + $display("PASSED"); + end else begin + $display("FAILED"); + end + end +endmodule diff --git a/ivtest/ivltests/sv_named_arg_new2.v b/ivtest/ivltests/sv_named_arg_new2.v new file mode 100644 index 000000000..64c1fd8f8 --- /dev/null +++ b/ivtest/ivltests/sv_named_arg_new2.v @@ -0,0 +1,23 @@ +// Check that binding task arguments by name is supported and that a mix of +// positional and named arguments is supported. + +module test; + + class C; + integer val; + + function new(integer a, integer b, integer c); + val = a + b * 10 + c * 100; + endfunction + endclass + + initial begin + C c; + c = new(1, .c(3), .b(2)); + if (c.val == 321) begin + $display("PASSED"); + end else begin + $display("FAILED"); + end + end +endmodule diff --git a/ivtest/ivltests/sv_named_arg_new3.v b/ivtest/ivltests/sv_named_arg_new3.v new file mode 100644 index 000000000..80d09bdb0 --- /dev/null +++ b/ivtest/ivltests/sv_named_arg_new3.v @@ -0,0 +1,24 @@ +// Check that binding task arguments by name is supported and that an empty +// value can be bound to the name, in which case the default argument value +// should be used. + +module test; + + class C; + integer val; + + function new(integer a, integer b = 2); + val = a + b * 10; + endfunction + endclass + + initial begin + C c; + c = new(.a(1), .b()); + if (c.val == 21) begin + $display("PASSED"); + end else begin + $display("FAILED"); + end + end +endmodule diff --git a/ivtest/ivltests/sv_named_arg_new_fail1.v b/ivtest/ivltests/sv_named_arg_new_fail1.v new file mode 100644 index 000000000..e9d9403ce --- /dev/null +++ b/ivtest/ivltests/sv_named_arg_new_fail1.v @@ -0,0 +1,18 @@ +// Check that an error is reported when trying to bind an argument by nae that +// does not exist + +module test; + + class C; + function new(integer a, integer b); + $display("FAILED"); + endfunction + endclass + + initial begin + C c; + c = new(.b(2), .c(1)); // This should fail. `c` is not an arugment of the + // constructor. + end + +endmodule diff --git a/ivtest/ivltests/sv_named_arg_new_fail2.v b/ivtest/ivltests/sv_named_arg_new_fail2.v new file mode 100644 index 000000000..8b4e3468b --- /dev/null +++ b/ivtest/ivltests/sv_named_arg_new_fail2.v @@ -0,0 +1,18 @@ +// Check that an error is reported when trying to bind the same argument by name +// multiple times. + +module test; + + class C; + function new(integer a, integer b); + $display("FAILED"); + endfunction + endclass + + initial begin + C c; + c = new(.a(1), .a(2)); // This should fail. `a` is provided twice as a named + // argument. + end + +endmodule diff --git a/ivtest/ivltests/sv_named_arg_new_fail3.v b/ivtest/ivltests/sv_named_arg_new_fail3.v new file mode 100644 index 000000000..de94c4ff0 --- /dev/null +++ b/ivtest/ivltests/sv_named_arg_new_fail3.v @@ -0,0 +1,18 @@ +// Check that an error is reported when trying to bind an argument by name that +// is also provided as a positional argument. + +module test; + + class C; + function new(integer a, integer b); + $display("FAILED"); + endfunction + endclass + + initial begin + C c; + c = new(1, .a(2)); // This should fail. `a` is provided both as a positional + // and named argument. + end + +endmodule diff --git a/ivtest/ivltests/sv_named_arg_new_fail4.v b/ivtest/ivltests/sv_named_arg_new_fail4.v new file mode 100644 index 000000000..4803cb5c4 --- /dev/null +++ b/ivtest/ivltests/sv_named_arg_new_fail4.v @@ -0,0 +1,18 @@ +// Check that an error is reported trying to provide a positional argument to a +// function after a named argument. + +module test; + + class C; + function new(integer a, integer b); + $display("FAILED"); + endfunction + endclass + + initial begin + C c; + c = new(.a(2), 1); // This should fail. Positional arguments must precede + // named arguments. + end + +endmodule diff --git a/ivtest/ivltests/sv_named_arg_new_fail5.v b/ivtest/ivltests/sv_named_arg_new_fail5.v new file mode 100644 index 000000000..fc5bfcdfd --- /dev/null +++ b/ivtest/ivltests/sv_named_arg_new_fail5.v @@ -0,0 +1,17 @@ +// Check that an error is reported when binding an empty value to an argument by +// name and the argument does not have a default value. + +module test; + + class C; + function new(integer a); + $display("FAILED"); + endfunction + endclass + + initial begin + C c; + c = new(.a()); // This should fail. `a` has no default value. + end + +endmodule diff --git a/ivtest/ivltests/sv_named_arg_task1.v b/ivtest/ivltests/sv_named_arg_task1.v new file mode 100644 index 000000000..525c334b3 --- /dev/null +++ b/ivtest/ivltests/sv_named_arg_task1.v @@ -0,0 +1,17 @@ +// Check that binding task arguments by name is supported. + +module test; + + task t(integer a, integer b); + if (a == 1 && b == 2) begin + $display("PASSED"); + end else begin + $display("FAILED"); + end + endtask + + initial begin + t(.b(2), .a(1)); + end + +endmodule diff --git a/ivtest/ivltests/sv_named_arg_task2.v b/ivtest/ivltests/sv_named_arg_task2.v new file mode 100644 index 000000000..b0c47d95e --- /dev/null +++ b/ivtest/ivltests/sv_named_arg_task2.v @@ -0,0 +1,18 @@ +// Check that binding task arguments by name is supported and that a mix of +// positional and named arguments is supported. + +module test; + + task t(integer a, integer b, integer c); + if (a == 1 && b == 2 && c == 3) begin + $display("PASSED"); + end else begin + $display("FAILED"); + end + endtask + + initial begin + t(1, .c(3), .b(2)); + end + +endmodule diff --git a/ivtest/ivltests/sv_named_arg_task3.v b/ivtest/ivltests/sv_named_arg_task3.v new file mode 100644 index 000000000..1018b7e2e --- /dev/null +++ b/ivtest/ivltests/sv_named_arg_task3.v @@ -0,0 +1,19 @@ +// Check that binding task arguments by name is supported and that an empty +// value can be bound to the name, in which case the default argument value +// should be used. + +module test; + + task t(integer a, integer b = 2); + if (a == 1 && b == 2) begin + $display("PASSED"); + end else begin + $display("FAILED"); + end + endtask + + initial begin + t(.a(1), .b()); + end + +endmodule diff --git a/ivtest/ivltests/sv_named_arg_task_fail1.v b/ivtest/ivltests/sv_named_arg_task_fail1.v new file mode 100644 index 000000000..2ede7b366 --- /dev/null +++ b/ivtest/ivltests/sv_named_arg_task_fail1.v @@ -0,0 +1,14 @@ +// Check that an error is reported when trying to bind an argument by nae that +// does not exist + +module test; + + task t(integer a, integer b); + $display("FAILED"); + endtask + + initial begin + t(.b(2), .c(1)); + end + +endmodule diff --git a/ivtest/ivltests/sv_named_arg_task_fail2.v b/ivtest/ivltests/sv_named_arg_task_fail2.v new file mode 100644 index 000000000..1c3cbcca7 --- /dev/null +++ b/ivtest/ivltests/sv_named_arg_task_fail2.v @@ -0,0 +1,14 @@ +// Check that an error is reported when trying to bind the same argument by name +// multiple times. + +module test; + + task t(integer a, integer b); + $display("FAILED"); + endtask + + initial begin + t(.a(1), .a(2)); + end + +endmodule diff --git a/ivtest/ivltests/sv_named_arg_task_fail3.v b/ivtest/ivltests/sv_named_arg_task_fail3.v new file mode 100644 index 000000000..dccb9c2ed --- /dev/null +++ b/ivtest/ivltests/sv_named_arg_task_fail3.v @@ -0,0 +1,14 @@ +// Check that an error is reported when trying to bind an argument by name that +// is also provided as a positional argument. + +module test; + + task t(integer a, integer b); + $display("FAILED"); + endtask + + initial begin + t(1, .a(2)); + end + +endmodule diff --git a/ivtest/ivltests/sv_named_arg_task_fail4.v b/ivtest/ivltests/sv_named_arg_task_fail4.v new file mode 100644 index 000000000..0e4aa101e --- /dev/null +++ b/ivtest/ivltests/sv_named_arg_task_fail4.v @@ -0,0 +1,15 @@ +// Check that an error is reported trying to provide a positional argument to a +// task after a named argument. + +module test; + + task t(integer a, integer b); + $display("FAILED"); + endtask + + initial begin + t(.a(2), 1); // This should fail. Positional arguments must precede + // named arguments. + end + +endmodule diff --git a/ivtest/ivltests/sv_named_arg_task_fail5.v b/ivtest/ivltests/sv_named_arg_task_fail5.v new file mode 100644 index 000000000..f549e1ed3 --- /dev/null +++ b/ivtest/ivltests/sv_named_arg_task_fail5.v @@ -0,0 +1,14 @@ +// Check that an error is reported when binding an empty value to an argument by +// name and the argument does not have a default value. + +module test; + + task t(integer a); + $display("FAILED"); + endtask + + initial begin + t(.a()); // This should fail. `a` has no default value. + end + +endmodule diff --git a/ivtest/vvp_tests/sv_named_arg_base1.json b/ivtest/vvp_tests/sv_named_arg_base1.json new file mode 100644 index 000000000..ef23d9462 --- /dev/null +++ b/ivtest/vvp_tests/sv_named_arg_base1.json @@ -0,0 +1,5 @@ +{ + "type" : "normal", + "source" : "sv_named_arg_base1.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_named_arg_base2.json b/ivtest/vvp_tests/sv_named_arg_base2.json new file mode 100644 index 000000000..3707d8096 --- /dev/null +++ b/ivtest/vvp_tests/sv_named_arg_base2.json @@ -0,0 +1,5 @@ +{ + "type" : "normal", + "source" : "sv_named_arg_base2.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_named_arg_base3.json b/ivtest/vvp_tests/sv_named_arg_base3.json new file mode 100644 index 000000000..34edbb3c8 --- /dev/null +++ b/ivtest/vvp_tests/sv_named_arg_base3.json @@ -0,0 +1,5 @@ +{ + "type" : "normal", + "source" : "sv_named_arg_base3.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_named_arg_base_fail1.json b/ivtest/vvp_tests/sv_named_arg_base_fail1.json new file mode 100644 index 000000000..c117c291e --- /dev/null +++ b/ivtest/vvp_tests/sv_named_arg_base_fail1.json @@ -0,0 +1,5 @@ +{ + "type" : "CE", + "source" : "sv_named_arg_base_fail1.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_named_arg_base_fail2.json b/ivtest/vvp_tests/sv_named_arg_base_fail2.json new file mode 100644 index 000000000..e0e2ab1c7 --- /dev/null +++ b/ivtest/vvp_tests/sv_named_arg_base_fail2.json @@ -0,0 +1,5 @@ +{ + "type" : "CE", + "source" : "sv_named_arg_base_fail2.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_named_arg_base_fail3.json b/ivtest/vvp_tests/sv_named_arg_base_fail3.json new file mode 100644 index 000000000..ed2dc83cc --- /dev/null +++ b/ivtest/vvp_tests/sv_named_arg_base_fail3.json @@ -0,0 +1,5 @@ +{ + "type" : "CE", + "source" : "sv_named_arg_base_fail3.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_named_arg_base_fail4.json b/ivtest/vvp_tests/sv_named_arg_base_fail4.json new file mode 100644 index 000000000..203a02860 --- /dev/null +++ b/ivtest/vvp_tests/sv_named_arg_base_fail4.json @@ -0,0 +1,5 @@ +{ + "type" : "CE", + "source" : "sv_named_arg_base_fail4.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_named_arg_base_fail5.json b/ivtest/vvp_tests/sv_named_arg_base_fail5.json new file mode 100644 index 000000000..04f7ce8a2 --- /dev/null +++ b/ivtest/vvp_tests/sv_named_arg_base_fail5.json @@ -0,0 +1,5 @@ +{ + "type" : "CE", + "source" : "sv_named_arg_base_fail5.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_named_arg_chained1.json b/ivtest/vvp_tests/sv_named_arg_chained1.json new file mode 100644 index 000000000..1187d39c6 --- /dev/null +++ b/ivtest/vvp_tests/sv_named_arg_chained1.json @@ -0,0 +1,5 @@ +{ + "type" : "normal", + "source" : "sv_named_arg_chained1.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_named_arg_chained2.json b/ivtest/vvp_tests/sv_named_arg_chained2.json new file mode 100644 index 000000000..909ad3763 --- /dev/null +++ b/ivtest/vvp_tests/sv_named_arg_chained2.json @@ -0,0 +1,5 @@ +{ + "type" : "normal", + "source" : "sv_named_arg_chained2.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_named_arg_chained3.json b/ivtest/vvp_tests/sv_named_arg_chained3.json new file mode 100644 index 000000000..b0270b485 --- /dev/null +++ b/ivtest/vvp_tests/sv_named_arg_chained3.json @@ -0,0 +1,5 @@ +{ + "type" : "normal", + "source" : "sv_named_arg_chained3.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_named_arg_chained_fail1.json b/ivtest/vvp_tests/sv_named_arg_chained_fail1.json new file mode 100644 index 000000000..09ffa9ea7 --- /dev/null +++ b/ivtest/vvp_tests/sv_named_arg_chained_fail1.json @@ -0,0 +1,5 @@ +{ + "type" : "CE", + "source" : "sv_named_arg_chained_fail1.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_named_arg_chained_fail2.json b/ivtest/vvp_tests/sv_named_arg_chained_fail2.json new file mode 100644 index 000000000..7fd51bd3b --- /dev/null +++ b/ivtest/vvp_tests/sv_named_arg_chained_fail2.json @@ -0,0 +1,5 @@ +{ + "type" : "CE", + "source" : "sv_named_arg_chained_fail2.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_named_arg_chained_fail3.json b/ivtest/vvp_tests/sv_named_arg_chained_fail3.json new file mode 100644 index 000000000..0a0d5ebbd --- /dev/null +++ b/ivtest/vvp_tests/sv_named_arg_chained_fail3.json @@ -0,0 +1,5 @@ +{ + "type" : "CE", + "source" : "sv_named_arg_chained_fail3.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_named_arg_chained_fail4.json b/ivtest/vvp_tests/sv_named_arg_chained_fail4.json new file mode 100644 index 000000000..7ae7f84c6 --- /dev/null +++ b/ivtest/vvp_tests/sv_named_arg_chained_fail4.json @@ -0,0 +1,5 @@ +{ + "type" : "CE", + "source" : "sv_named_arg_chained_fail4.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_named_arg_chained_fail5.json b/ivtest/vvp_tests/sv_named_arg_chained_fail5.json new file mode 100644 index 000000000..1dd296eec --- /dev/null +++ b/ivtest/vvp_tests/sv_named_arg_chained_fail5.json @@ -0,0 +1,5 @@ +{ + "type" : "CE", + "source" : "sv_named_arg_chained_fail5.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_named_arg_func1.json b/ivtest/vvp_tests/sv_named_arg_func1.json new file mode 100644 index 000000000..0fe90f86a --- /dev/null +++ b/ivtest/vvp_tests/sv_named_arg_func1.json @@ -0,0 +1,5 @@ +{ + "type" : "normal", + "source" : "sv_named_arg_func1.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_named_arg_func2.json b/ivtest/vvp_tests/sv_named_arg_func2.json new file mode 100644 index 000000000..4d7363514 --- /dev/null +++ b/ivtest/vvp_tests/sv_named_arg_func2.json @@ -0,0 +1,5 @@ +{ + "type" : "normal", + "source" : "sv_named_arg_func2.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_named_arg_func3.json b/ivtest/vvp_tests/sv_named_arg_func3.json new file mode 100644 index 000000000..f8037c5ce --- /dev/null +++ b/ivtest/vvp_tests/sv_named_arg_func3.json @@ -0,0 +1,5 @@ +{ + "type" : "normal", + "source" : "sv_named_arg_func3.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_named_arg_func_fail1.json b/ivtest/vvp_tests/sv_named_arg_func_fail1.json new file mode 100644 index 000000000..70da8a2bc --- /dev/null +++ b/ivtest/vvp_tests/sv_named_arg_func_fail1.json @@ -0,0 +1,5 @@ +{ + "type" : "CE", + "source" : "sv_named_arg_func_fail1.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_named_arg_func_fail2.json b/ivtest/vvp_tests/sv_named_arg_func_fail2.json new file mode 100644 index 000000000..611797c72 --- /dev/null +++ b/ivtest/vvp_tests/sv_named_arg_func_fail2.json @@ -0,0 +1,5 @@ +{ + "type" : "CE", + "source" : "sv_named_arg_func_fail2.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_named_arg_func_fail3.json b/ivtest/vvp_tests/sv_named_arg_func_fail3.json new file mode 100644 index 000000000..9f4e80a3b --- /dev/null +++ b/ivtest/vvp_tests/sv_named_arg_func_fail3.json @@ -0,0 +1,5 @@ +{ + "type" : "CE", + "source" : "sv_named_arg_func_fail3.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_named_arg_func_fail4.json b/ivtest/vvp_tests/sv_named_arg_func_fail4.json new file mode 100644 index 000000000..c052b6262 --- /dev/null +++ b/ivtest/vvp_tests/sv_named_arg_func_fail4.json @@ -0,0 +1,5 @@ +{ + "type" : "CE", + "source" : "sv_named_arg_func_fail4.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_named_arg_func_fail5.json b/ivtest/vvp_tests/sv_named_arg_func_fail5.json new file mode 100644 index 000000000..2df8abb47 --- /dev/null +++ b/ivtest/vvp_tests/sv_named_arg_func_fail5.json @@ -0,0 +1,5 @@ +{ + "type" : "CE", + "source" : "sv_named_arg_func_fail5.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_named_arg_new1.json b/ivtest/vvp_tests/sv_named_arg_new1.json new file mode 100644 index 000000000..6695b02a4 --- /dev/null +++ b/ivtest/vvp_tests/sv_named_arg_new1.json @@ -0,0 +1,5 @@ +{ + "type" : "normal", + "source" : "sv_named_arg_new1.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_named_arg_new2.json b/ivtest/vvp_tests/sv_named_arg_new2.json new file mode 100644 index 000000000..6f4ec4d0b --- /dev/null +++ b/ivtest/vvp_tests/sv_named_arg_new2.json @@ -0,0 +1,5 @@ +{ + "type" : "normal", + "source" : "sv_named_arg_new2.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_named_arg_new3.json b/ivtest/vvp_tests/sv_named_arg_new3.json new file mode 100644 index 000000000..4c2009f8c --- /dev/null +++ b/ivtest/vvp_tests/sv_named_arg_new3.json @@ -0,0 +1,5 @@ +{ + "type" : "normal", + "source" : "sv_named_arg_new3.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_named_arg_new_fail1.json b/ivtest/vvp_tests/sv_named_arg_new_fail1.json new file mode 100644 index 000000000..efe60694e --- /dev/null +++ b/ivtest/vvp_tests/sv_named_arg_new_fail1.json @@ -0,0 +1,5 @@ +{ + "type" : "CE", + "source" : "sv_named_arg_new_fail1.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_named_arg_new_fail2.json b/ivtest/vvp_tests/sv_named_arg_new_fail2.json new file mode 100644 index 000000000..e5e1d890a --- /dev/null +++ b/ivtest/vvp_tests/sv_named_arg_new_fail2.json @@ -0,0 +1,5 @@ +{ + "type" : "CE", + "source" : "sv_named_arg_new_fail2.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_named_arg_new_fail3.json b/ivtest/vvp_tests/sv_named_arg_new_fail3.json new file mode 100644 index 000000000..a8cc1f8f0 --- /dev/null +++ b/ivtest/vvp_tests/sv_named_arg_new_fail3.json @@ -0,0 +1,5 @@ +{ + "type" : "CE", + "source" : "sv_named_arg_new_fail3.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_named_arg_new_fail4.json b/ivtest/vvp_tests/sv_named_arg_new_fail4.json new file mode 100644 index 000000000..58128d0ae --- /dev/null +++ b/ivtest/vvp_tests/sv_named_arg_new_fail4.json @@ -0,0 +1,5 @@ +{ + "type" : "CE", + "source" : "sv_named_arg_new_fail4.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_named_arg_new_fail5.json b/ivtest/vvp_tests/sv_named_arg_new_fail5.json new file mode 100644 index 000000000..5339eee9a --- /dev/null +++ b/ivtest/vvp_tests/sv_named_arg_new_fail5.json @@ -0,0 +1,5 @@ +{ + "type" : "CE", + "source" : "sv_named_arg_new_fail5.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_named_arg_task1.json b/ivtest/vvp_tests/sv_named_arg_task1.json new file mode 100644 index 000000000..10c7cc90c --- /dev/null +++ b/ivtest/vvp_tests/sv_named_arg_task1.json @@ -0,0 +1,5 @@ +{ + "type" : "normal", + "source" : "sv_named_arg_task1.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_named_arg_task2.json b/ivtest/vvp_tests/sv_named_arg_task2.json new file mode 100644 index 000000000..5ba8429ff --- /dev/null +++ b/ivtest/vvp_tests/sv_named_arg_task2.json @@ -0,0 +1,5 @@ +{ + "type" : "normal", + "source" : "sv_named_arg_task2.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_named_arg_task3.json b/ivtest/vvp_tests/sv_named_arg_task3.json new file mode 100644 index 000000000..1ffe13fab --- /dev/null +++ b/ivtest/vvp_tests/sv_named_arg_task3.json @@ -0,0 +1,5 @@ +{ + "type" : "normal", + "source" : "sv_named_arg_task3.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_named_arg_task_fail1.json b/ivtest/vvp_tests/sv_named_arg_task_fail1.json new file mode 100644 index 000000000..cbddc6ade --- /dev/null +++ b/ivtest/vvp_tests/sv_named_arg_task_fail1.json @@ -0,0 +1,5 @@ +{ + "type" : "CE", + "source" : "sv_named_arg_task_fail1.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_named_arg_task_fail2.json b/ivtest/vvp_tests/sv_named_arg_task_fail2.json new file mode 100644 index 000000000..1b438073f --- /dev/null +++ b/ivtest/vvp_tests/sv_named_arg_task_fail2.json @@ -0,0 +1,5 @@ +{ + "type" : "CE", + "source" : "sv_named_arg_task_fail2.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_named_arg_task_fail3.json b/ivtest/vvp_tests/sv_named_arg_task_fail3.json new file mode 100644 index 000000000..cdf212dd4 --- /dev/null +++ b/ivtest/vvp_tests/sv_named_arg_task_fail3.json @@ -0,0 +1,5 @@ +{ + "type" : "CE", + "source" : "sv_named_arg_task_fail3.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_named_arg_task_fail4.json b/ivtest/vvp_tests/sv_named_arg_task_fail4.json new file mode 100644 index 000000000..cff8adbbe --- /dev/null +++ b/ivtest/vvp_tests/sv_named_arg_task_fail4.json @@ -0,0 +1,5 @@ +{ + "type" : "CE", + "source" : "sv_named_arg_task_fail4.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_named_arg_task_fail5.json b/ivtest/vvp_tests/sv_named_arg_task_fail5.json new file mode 100644 index 000000000..663c7d86c --- /dev/null +++ b/ivtest/vvp_tests/sv_named_arg_task_fail5.json @@ -0,0 +1,5 @@ +{ + "type" : "CE", + "source" : "sv_named_arg_task_fail5.v", + "iverilog-args" : [ "-g2005-sv" ] +}