From de9e3b791bfa94cabe6b6ac7f1134ba8131decf5 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 12 Mar 2022 22:40:14 +0100 Subject: [PATCH] Correctly handle separate port type declaration for atom2 types When using non-ANSI style port declarations it is possible to declare the port direction and the data type for the port in separate statements. E.g. ``` input x; reg x; ``` When using packed array dimensions they must match for both declarations. E.g. ``` input [3:0] x; reg [3:0] x; ``` But this only applies to vector types, i.e. the packed dimension is explicitly declared. It does not apply to the atom2 types which have an implicit packed dimension. The current implementation requires that even for atom2 types the implicit dimension needs to be explicitly declared in the port direction. E.g. the following will result in a elaboration error complaining about a packed dimension mismatch. ``` module test; output x; byte x; endmodule ``` Currently atom2_type_t's are deconstructed into base type, range and signdness in the parser. That data is then passed to the signal elaboration, which will then construct a netvector_t from it. This makes it impossible to e.g. differentiate between `bit signed [31:0]` and `int` during elaboration. Instead of breaking the data type apart pass it as the data_type_t of the signal and use the elaborate_type() method in the signal elaboration to generate the netvector_t. Signed-off-by: Lars-Peter Clausen --- elab_sig.cc | 3 ++- pform.cc | 43 +++---------------------------------------- 2 files changed, 5 insertions(+), 41 deletions(-) diff --git a/elab_sig.cc b/elab_sig.cc index f472c7595..646da858d 100644 --- a/elab_sig.cc +++ b/elab_sig.cc @@ -941,7 +941,8 @@ ivl_type_t PWire::elaborate_type(Design*des, NetScope*scope, dynamic_cast(set_data_type_) || dynamic_cast(set_data_type_) || dynamic_cast(set_data_type_) || - dynamic_cast(set_data_type_)) { + dynamic_cast(set_data_type_) || + dynamic_cast(set_data_type_)) { ivl_type_t use_type = set_data_type_->elaborate_type(des, scope); ivl_assert(*this, packed_dimensions.empty()); return use_type; diff --git a/pform.cc b/pform.cc index 9fcaeabae..fcd639a93 100644 --- a/pform.cc +++ b/pform.cc @@ -2601,11 +2601,6 @@ void pform_module_define_port(const struct vlltype&li, data_type = vec_type->base_type; signed_flag = vec_type->signed_flag; prange = vec_type->pdims.get(); - } else if (atom2_type_t*atype = dynamic_cast(vtype)) { - data_type = IVL_VT_BOOL; - signed_flag = atype->signed_flag; - prange = make_range_from_width(atype->type_code); - } else if (real_type_t*rtype = dynamic_cast(vtype)) { data_type = IVL_VT_REAL; signed_flag = true; @@ -2959,11 +2954,8 @@ vector*pform_make_task_ports(const struct vlltype&loc, vtype = uarray->base_type; } - if (atom2_type_t*atype = dynamic_cast (vtype)) { - list*range_tmp = make_range_from_width(atype->type_code); - ret = pform_make_task_ports(loc, pt, IVL_VT_BOOL, - atype->signed_flag, - range_tmp, ports); + if (dynamic_cast (vtype)) { + ret = do_make_task_ports(loc, pt, IVL_VT_BOOL, vtype, ports); } if (vector_type_t*vec_type = dynamic_cast (vtype)) { @@ -3431,30 +3423,6 @@ void pform_set_port_type(const struct vlltype&li, delete attr; } -static void pform_set_integer_2atom(uint64_t width, bool signed_flag, perm_string name) -{ - PWire*cur = pform_get_wire_in_scope(name); - assert(cur); - - cur->set_signed(signed_flag); - - pform_range_t rng; - rng.first = new PENumber(new verinum(width-1, integer_width)); - rng.second = new PENumber(new verinum((uint64_t)0, integer_width)); - listrlist; - rlist.push_back(rng); - cur->set_range(rlist, SR_NET); -} - -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(width, signed_flag, txt); - } -} - /* * This function detects the derived class for the given type and * dispatches the type to the proper subtype function. @@ -3471,12 +3439,7 @@ 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(atom2_type->type_code, atom2_type->signed_flag, names); - vt = IVL_VT_BOOL; - } - - else if (vector_type_t*vec_type = dynamic_cast (data_type)) { + if (vector_type_t*vec_type = dynamic_cast (data_type)) { if (net_type==NetNet::REG && vec_type->integer_flag) net_type=NetNet::INTEGER;