From 962c0af1b620652e791d56285a8e207c56c10043 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 10 Jan 2022 10:02:39 +0100 Subject: [PATCH 1/3] Don't set information not needed on enum signals When creating a PWire for a enum type the signedness as well as whether the base type is an integer is assigned to the wire. But this information is never queried again. When creating the netenum_t this information is directly taken from the enum_type_t. The signedness and integer information of the PWire is only used when elaborating a netvector_t. Removing this makes the pfrom_set_enum() function similar to those for other types and will allow us to consolidate them in follow up patches. Signed-off-by: Lars-Peter Clausen --- pform.cc | 8 -------- 1 file changed, 8 deletions(-) diff --git a/pform.cc b/pform.cc index 374040291..749c3249d 100644 --- a/pform.cc +++ b/pform.cc @@ -3535,14 +3535,6 @@ static void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, PWire*cur = pform_get_make_wire_in_scope(li, name, net_type, NetNet::NOT_A_PORT, enum_type->base_type); assert(cur); - cur->set_signed(enum_type->signed_flag); - - //XXXXcur->set_range(*enum_type->range, SR_NET); - // If this is an integer enumeration switch the wire to an integer. - if (enum_type->integer_flag) { - bool res = cur->set_wire_type(NetNet::INTEGER); - assert(res); - } pform_bind_attributes(cur->attributes, attr, true); } From aa7e25302631e94f0b37f56be04905f8b875003d Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 9 Jan 2022 19:09:08 +0100 Subject: [PATCH 2/3] Consolidate most pform_set__data_type() functions There are a couple of different functions for the different data types that are called when the type of a signal is set. But they all effectively do the same. Consolidate this code by moving the common code into the main pform_set_data_type() function. This allows to remove most of the type specific functions and eliminates some duplicated code. It ensures consistent and data type independent behavior at the parser level. Something that will be required to eventually support type parameters. Signed-off-by: Lars-Peter Clausen --- Makefile.in | 2 +- pform.cc | 127 +++++++++---------------------------------- pform.h | 2 - pform_class_type.cc | 40 -------------- pform_string_type.cc | 39 ------------- pform_struct_type.cc | 33 ----------- 6 files changed, 28 insertions(+), 215 deletions(-) delete mode 100644 pform_class_type.cc delete mode 100644 pform_string_type.cc diff --git a/Makefile.in b/Makefile.in index 68e54b744..b3af18d84 100644 --- a/Makefile.in +++ b/Makefile.in @@ -116,7 +116,7 @@ O = main.o async.o design_dump.o discipline.o dup_expr.o elaborate.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 \ pform_disciplines.o pform_dump.o pform_package.o pform_pclass.o \ - pform_class_type.o pform_string_type.o pform_struct_type.o pform_types.o \ + pform_struct_type.o pform_types.o \ symbol_search.o sync.o sys_funcs.o verinum.o verireal.o vpi_modules.o target.o \ Attrib.o HName.o Module.o PClass.o PDelays.o PEvent.o PExpr.o PFunction.o \ PGate.o PGenerate.o PModport.o PNamedItem.o PPackage.o PScope.o PSpec.o \ diff --git a/pform.cc b/pform.cc index 749c3249d..3d72b9fe0 100644 --- a/pform.cc +++ b/pform.cc @@ -863,33 +863,6 @@ void pform_put_enum_type_in_scope(enum_type_t*enum_set) lexical_scope->enum_sets.push_back(enum_set); } -PWire*pform_get_make_wire_in_scope(const struct vlltype&, perm_string name, - NetNet::Type net_type, NetNet::PortType port_type, - ivl_variable_type_t vt_type) -{ - PWire*cur = pform_get_wire_in_scope(name); - - // If the wire already exists and is fully defined, this - // must be a redeclaration. Start again with a new wire. - // The error will be reported when we add the new wire - // to the scope. Do not delete the old wire - it will - // remain in the local symbol map. - if (cur && cur->get_data_type() != IVL_VT_NO_TYPE) - cur = 0; - - if (cur == 0) { - cur = new PWire(name, net_type, port_type, vt_type); - pform_put_wire_in_scope(name, cur); - } else { - bool rc = cur->set_wire_type(net_type); - assert(rc); - rc = cur->set_data_type(vt_type); - assert(rc); - } - - return cur; -} - void pform_set_typedef(perm_string name, data_type_t*data_type, std::list*unp_ranges) { if(unp_ranges) @@ -3486,9 +3459,9 @@ void pform_set_port_type(const struct vlltype&li, delete attr; } -static void pform_set_integer_2atom(const struct vlltype&li, uint64_t width, bool signed_flag, perm_string name, NetNet::Type net_type, list*attr) +static void pform_set_integer_2atom(uint64_t width, bool signed_flag, perm_string name) { - PWire*cur = pform_get_make_wire_in_scope(li, name, net_type, NetNet::NOT_A_PORT, IVL_VT_BOOL); + PWire*cur = pform_get_wire_in_scope(name); assert(cur); cur->set_signed(signed_flag); @@ -3499,69 +3472,24 @@ static void pform_set_integer_2atom(const struct vlltype&li, uint64_t width, boo listrlist; rlist.push_back(rng); cur->set_range(rlist, SR_NET); - pform_bind_attributes(cur->attributes, attr, true); } -static void pform_set_integer_2atom(const struct vlltype&li, uint64_t width, bool signed_flag, list*names, NetNet::Type net_type, list*attr) +static void pform_set_integer_2atom(uint64_t width, bool signed_flag, list*names) { for (list::iterator cur = names->begin() ; cur != names->end() ; ++ cur ) { perm_string txt = *cur; - pform_set_integer_2atom(li, width, signed_flag, txt, net_type, attr); + pform_set_integer_2atom(width, signed_flag, txt); } } -template static void pform_set2_data_type(const struct vlltype&li, T*data_type, perm_string name, NetNet::Type net_type, list*attr) -{ - ivl_variable_type_t base_type = data_type->figure_packed_base_type(); - - PWire*net = pform_get_make_wire_in_scope(li, name, net_type, NetNet::NOT_A_PORT, base_type); - assert(net); - pform_bind_attributes(net->attributes, attr, true); -} - -template static void pform_set2_data_type(const struct vlltype&li, T*data_type, list*names, NetNet::Type net_type, list*attr) -{ - for (list::iterator cur = names->begin() - ; cur != names->end() ; ++ cur) { - pform_set2_data_type(li, data_type, *cur, net_type, attr); - } -} - -static void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, - perm_string name, NetNet::Type net_type, - std::list*attr) -{ - PWire*cur = pform_get_make_wire_in_scope(li, name, net_type, NetNet::NOT_A_PORT, enum_type->base_type); - assert(cur); - - pform_bind_attributes(cur->attributes, attr, true); -} - -static void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, - list*names, NetNet::Type net_type, - std::list*attr) -{ - // By definition, the base type can only be IVL_VT_LOGIC or - // IVL_VT_BOOL. - assert(enum_type->base_type==IVL_VT_LOGIC || enum_type->base_type==IVL_VT_BOOL); - - // Now apply the checked enumeration type to the variables - // that are being declared with this type. - for (list::iterator cur = names->begin() - ; cur != names->end() ; ++ cur) { - perm_string txt = *cur; - pform_set_enum(li, enum_type, txt, net_type, attr); - } - -} - /* * This function detects the derived class for the given type and * dispatches the type to the proper subtype function. */ void pform_set_data_type(const struct vlltype&li, data_type_t*data_type, list*names, NetNet::Type net_type, list*attr) { + ivl_variable_type_t vt; if (data_type == 0) { VLerror(li, "internal error: data_type==0."); assert(0); @@ -3572,15 +3500,8 @@ void pform_set_data_type(const struct vlltype&li, data_type_t*data_type, listbase_type; if (atom2_type_t*atom2_type = dynamic_cast (data_type)) { - pform_set_integer_2atom(li, atom2_type->type_code, atom2_type->signed_flag, names, net_type, attr); - } - - else if (struct_type_t*struct_type = dynamic_cast (data_type)) { - pform_set_struct_type(li, struct_type, names, net_type, attr); - } - - else if (enum_type_t*enum_type = dynamic_cast (data_type)) { - pform_set_enum(li, enum_type, names, net_type, attr); + pform_set_integer_2atom(atom2_type->type_code, atom2_type->signed_flag, names); + vt = IVL_VT_BOOL; } else if (vector_type_t*vec_type = dynamic_cast (data_type)) { @@ -3589,37 +3510,43 @@ void pform_set_data_type(const struct vlltype&li, data_type_t*data_type, listpdims.get(), vec_type->signed_flag, - vec_type->base_type, net_type, attr); + IVL_VT_NO_TYPE, NetNet::NONE, 0); + vt = vec_type->base_type; } else if (/*real_type_t*real_type =*/ dynamic_cast (data_type)) { - pform_set_net_range(names, 0, true, IVL_VT_REAL, net_type, attr); + pform_set_net_range(names, 0, true, IVL_VT_NO_TYPE, NetNet::NONE, 0); + vt = IVL_VT_REAL; } - else if (class_type_t*class_type = dynamic_cast (data_type)) { - pform_set_class_type(li, class_type, names, net_type, attr); + else if (dynamic_cast (data_type)) { + vt = IVL_VT_CLASS; } - - else if (parray_type_t*array_type = dynamic_cast (data_type)) { - pform_set2_data_type(li, array_type, names, net_type, attr); - } - - else if (string_type_t*string_type = dynamic_cast (data_type)) { - pform_set_string_type(li, string_type, names, net_type, attr); - + else if (dynamic_cast (data_type)) { + vt = IVL_VT_STRING; } else { - VLerror(li, "internal error: Unexpected data_type."); - assert(0); + vt = data_type->figure_packed_base_type(); } for (list::iterator cur = names->begin() ; cur != names->end() ; ++ cur ) { PWire*wire = pform_get_wire_in_scope(*cur); + + // If these fail there is a bug somewhere else. pform_set_data_type() + // is only ever called on a fresh wire that already exists. + ivl_assert(li, wire); + bool rc = wire->set_wire_type(net_type); + ivl_assert(li, rc); + rc = wire->set_data_type(vt); + ivl_assert(li, rc); + if (uarray_type) { wire->set_unpacked_idx(*uarray_type->dims.get()); wire->set_uarray_type(uarray_type); } wire->set_data_type(data_type); + + pform_bind_attributes(wire->attributes, attr, true); } delete names; diff --git a/pform.h b/pform.h index 30a8be7a6..3dda00d94 100644 --- a/pform.h +++ b/pform.h @@ -387,8 +387,6 @@ extern void pform_set_reg_idx(perm_string name, extern void pform_set_data_type(const struct vlltype&li, data_type_t*, std::list*names, NetNet::Type net_type, std::list*attr); -extern void pform_set_struct_type(const struct vlltype&li, struct_type_t*struct_type, std::list*names, NetNet::Type net_type, std::list*attr); - extern void pform_set_string_type(const struct vlltype&li, const string_type_t*string_type, std::list*names, NetNet::Type net_type, std::list*attr); extern void pform_set_class_type(const struct vlltype&li, class_type_t*class_type, std::list*names, NetNet::Type net_type, std::list*addr); diff --git a/pform_class_type.cc b/pform_class_type.cc deleted file mode 100644 index 2408eb39d..000000000 --- a/pform_class_type.cc +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2012-2021 Picture Elements, Inc. - * Stephen Williams (steve@icarus.com) - * - * This source code is free software; you can redistribute it - * and/or modify it in source code form under the terms of the GNU - * General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -# include "pform.h" -# include "parse_misc.h" -# include "ivl_assert.h" - -using namespace std; - -static void pform_set_class_type(const struct vlltype&li, class_type_t*, perm_string name, NetNet::Type net_type, list*attr) -{ - PWire*net = pform_get_make_wire_in_scope(li, name, net_type, NetNet::NOT_A_PORT, IVL_VT_CLASS); - assert(net); - pform_bind_attributes(net->attributes, attr, true); -} - -void pform_set_class_type(const struct vlltype&li, class_type_t*class_type, list*names, NetNet::Type net_type, list*attr) -{ - for (list::iterator cur = names->begin() - ; cur != names->end() ; ++ cur) { - pform_set_class_type(li, class_type, *cur, net_type, attr); - } -} diff --git a/pform_string_type.cc b/pform_string_type.cc deleted file mode 100644 index 9976225dc..000000000 --- a/pform_string_type.cc +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2012-2021 Stephen Williams (steve@icarus.com) - * - * This source code is free software; you can redistribute it - * and/or modify it in source code form under the terms of the GNU - * General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -# include "pform.h" -# include "parse_misc.h" -# include "ivl_assert.h" - -using namespace std; - -static void pform_set_string_type(const struct vlltype&li, const string_type_t*, perm_string name, NetNet::Type net_type, list*attr) -{ - PWire*net = pform_get_make_wire_in_scope(li, name, net_type, NetNet::NOT_A_PORT, IVL_VT_STRING); - assert(net); - pform_bind_attributes(net->attributes, attr, true); -} - -void pform_set_string_type(const struct vlltype&li, const string_type_t*string_type, list*names, NetNet::Type net_type, list*attr) -{ - for (list::iterator cur = names->begin() - ; cur != names->end() ; ++ cur) { - pform_set_string_type(li, string_type, *cur, net_type, attr); - } -} diff --git a/pform_struct_type.cc b/pform_struct_type.cc index 221722c43..fb88c541e 100644 --- a/pform_struct_type.cc +++ b/pform_struct_type.cc @@ -58,36 +58,3 @@ ivl_variable_type_t struct_type_t::figure_packed_base_type(void) const return base_type; } - -/* - * When we parse a packed struct, we can early on (right here) figure - * out the base type of the packed variable. Elaboration, later on, - * well figure out the rest. - */ -static void pform_set_packed_struct(const struct vlltype&li, struct_type_t*struct_type, perm_string name, NetNet::Type net_type, list*attr) -{ - ivl_variable_type_t base_type = struct_type->figure_packed_base_type(); - - PWire*net = pform_get_make_wire_in_scope(li, name, net_type, NetNet::NOT_A_PORT, base_type); - assert(net); - pform_bind_attributes(net->attributes, attr, true); -} - -static void pform_set_struct_type(const struct vlltype&li, struct_type_t*struct_type, perm_string name, NetNet::Type net_type, list*attr) -{ - if (struct_type->packed_flag) { - pform_set_packed_struct(li, struct_type, name, net_type, attr); - return; - } - - // For now, can only handle packed structs. The parser generates - // a "sorry" message, so no need to do anything here. -} - -void pform_set_struct_type(const struct vlltype&li, struct_type_t*struct_type, list*names, NetNet::Type net_type, list*attr) -{ - for (list::iterator cur = names->begin() - ; cur != names->end() ; ++ cur) { - pform_set_struct_type(li, struct_type, *cur, net_type, attr); - } -} From a4eb971655c599fd32157b9b91a0bfafac1f1e0d Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 14 Mar 2022 15:25:41 +0100 Subject: [PATCH 3/3] Remove unused parameter from pform_set_net_range() The `net_type` and `dt` parameter of `pform_set_net_range()` always get passed the same value, NetNet::NONE and IVL_VT_NO_TYPE respectively. Both these values are ignore by the function. So these parameters don't do anything useful, remove them. Signed-off-by: Lars-Peter Clausen --- pform.cc | 31 ++++--------------------------- 1 file changed, 4 insertions(+), 27 deletions(-) diff --git a/pform.cc b/pform.cc index 3d72b9fe0..0fb212892 100644 --- a/pform.cc +++ b/pform.cc @@ -2152,10 +2152,8 @@ void pform_make_udp(const struct vlltype&loc, perm_string name, * and the name that I receive only has the tail component. */ static void pform_set_net_range(perm_string name, - NetNet::Type net_type, const list*range, bool signed_flag, - ivl_variable_type_t dt, PWSRType rt, std::list*attr) { @@ -2165,20 +2163,6 @@ static void pform_set_net_range(perm_string name, return; } - // If this is not implicit ("implicit" meaning we don't - // know what the type is yet) then set the type now. - if (net_type != NetNet::IMPLICIT && net_type != NetNet::NONE) { - bool rc = cur->set_wire_type(net_type); - if (rc == false) { - ostringstream msg; - msg << name << " " << net_type - << " definition conflicts with " << cur->get_wire_type() - << " definition at " << cur->get_fileline() - << "."; - VLerror(msg.str().c_str()); - } - } - if (range == 0) { /* This is the special case that we really mean a scalar. Set a fake range. */ @@ -2189,23 +2173,18 @@ static void pform_set_net_range(perm_string name, } cur->set_signed(signed_flag); - if (dt != IVL_VT_NO_TYPE) - cur->set_data_type(dt); - pform_bind_attributes(cur->attributes, attr, true); } static void pform_set_net_range(list*names, list*range, bool signed_flag, - ivl_variable_type_t dt, - NetNet::Type net_type, std::list*attr) { for (list::iterator cur = names->begin() ; cur != names->end() ; ++ cur ) { perm_string txt = *cur; - pform_set_net_range(txt, net_type, range, signed_flag, dt, SR_NET, attr); + pform_set_net_range(txt, range, signed_flag, SR_NET, attr); } } @@ -3431,8 +3410,7 @@ void pform_set_port_type(const struct vlltype&li, ; cur != ports->end() ; ++ cur ) { pform_set_port_type(li, cur->name, pt); - pform_set_net_range(cur->name, NetNet::NONE, range, signed_flag, - IVL_VT_NO_TYPE, SR_PORT, attr); + pform_set_net_range(cur->name, range, signed_flag, SR_PORT, attr); if (cur->udims) { cerr << li << ": warning: " << "Array dimensions in incomplete port declarations " @@ -3509,13 +3487,12 @@ void pform_set_data_type(const struct vlltype&li, data_type_t*data_type, listpdims.get(), - vec_type->signed_flag, - IVL_VT_NO_TYPE, NetNet::NONE, 0); + vec_type->signed_flag, 0); vt = vec_type->base_type; } else if (/*real_type_t*real_type =*/ dynamic_cast (data_type)) { - pform_set_net_range(names, 0, true, IVL_VT_NO_TYPE, NetNet::NONE, 0); + pform_set_net_range(names, 0, true, 0); vt = IVL_VT_REAL; }