diff --git a/design_dump.cc b/design_dump.cc index 993323eb9..9dfaac2e1 100644 --- a/design_dump.cc +++ b/design_dump.cc @@ -149,7 +149,7 @@ ostream& ivl_type_s::debug_dump(ostream&o) const ostream& netdarray_t::debug_dump(ostream&o) const { - o << "dynamic array of " << *elem_type_; + o << "dynamic array of " << *element_type(); return o; } diff --git a/elab_expr.cc b/elab_expr.cc index 3e937cc25..631891647 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -2356,7 +2356,7 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode) if (netdarray_t*darray = net? net->darray_type() : 0) { if (use_sel == index_component_t::SEL_BIT) { expr_type_ = darray->element_base_type(); - expr_width_ = darray->vector_width(); + expr_width_ = darray->element_width(); min_width_ = expr_width_; signed_flag_ = net->get_signed(); } else { @@ -3749,7 +3749,7 @@ NetExpr* PEIdent::elaborate_expr_net_bit_(Design*des, NetScope*scope, cerr << get_fileline() << ": debug: " << "Bit select of a dynamic array becomes NetESelect." << endl; } - NetESelect*res = new NetESelect(net, mux, darray->vector_width()); + NetESelect*res = new NetESelect(net, mux, darray->element_width()); res->set_line(*net); return res; } diff --git a/ivl_target.h b/ivl_target.h index 37766be64..b8ff60c57 100644 --- a/ivl_target.h +++ b/ivl_target.h @@ -2193,12 +2193,16 @@ extern unsigned ivl_switch_lineno(ivl_switch_t net); * ivl_variable_type_t definition for the various base types. * * ivl_type_element - * Return the type of the element of an array. + * Return the type of the element of an array. This is only valid + * for array types. * * SEMANTIC NOTES */ extern ivl_variable_type_t ivl_type_base(ivl_type_t net); extern ivl_type_t ivl_type_element(ivl_type_t net); +extern unsigned ivl_type_packed_dimensions(ivl_type_t net); +extern int ivl_type_packed_lsb(ivl_type_t net, unsigned dim); +extern int ivl_type_packed_msb(ivl_type_t net, unsigned dim); #if defined(__MINGW32__) || defined (__CYGWIN32__) diff --git a/net_assign.cc b/net_assign.cc index d8af4357c..aface2b08 100644 --- a/net_assign.cc +++ b/net_assign.cc @@ -89,7 +89,7 @@ unsigned NetAssign_::lwidth() const if (word_ == 0) return 1; else - return darray->vector_width(); + return darray->element_width(); } return lwid_; diff --git a/netdarray.cc b/netdarray.cc index 1a6cca3d0..b1845831a 100644 --- a/netdarray.cc +++ b/netdarray.cc @@ -21,14 +21,13 @@ using namespace std; -netdarray_t::netdarray_t(netvector_t*vec) -: elem_type_(vec) +netdarray_t::netdarray_t(ivl_type_t vec) +: netarray_t(vec) { } netdarray_t::~netdarray_t() { - delete elem_type_; } ivl_variable_type_t netdarray_t::base_type(void) const diff --git a/netdarray.h b/netdarray.h index 92ee69ae8..8068896dd 100644 --- a/netdarray.h +++ b/netdarray.h @@ -20,16 +20,12 @@ */ # include "nettypes.h" -# include "netvector.h" # include "ivl_target.h" -# include -class netvector_t; - -class netdarray_t : public ivl_type_s { +class netdarray_t : public netarray_t { public: - explicit netdarray_t(netvector_t*vec); + explicit netdarray_t(ivl_type_t vec); ~netdarray_t(); // This is the "base_type()" virtual method of the @@ -37,18 +33,18 @@ class netdarray_t : public ivl_type_s { // IVL_VT_DARRAY for dynamic arrays? ivl_variable_type_t base_type() const; - // The ivl_target.h API uses this method to get the type of - // the element of the array. - inline const ivl_type_s* element_type() const { return elem_type_; } + // This is the base_type() of the element of the array. We + // need this in some cases in order to get the base type of + // the element, and not the IVL_VT_DARRAY of the array itself. + inline ivl_variable_type_t element_base_type() const { return element_type()->base_type(); } - // This is the base_type() of the element of the array. - inline ivl_variable_type_t element_base_type() const { return elem_type_->base_type(); } - inline unsigned long vector_width(void) const { return elem_type_->packed_width(); } + // This is a convenience function for getting the width of an + // element. Strictly speaking it's not necessary. + inline unsigned long element_width(void) const { return element_type()->packed_width(); } std::ostream& debug_dump(std::ostream&) const; private: - netvector_t*elem_type_; }; #endif diff --git a/netparray.cc b/netparray.cc index 31f1274b7..d8779a92d 100644 --- a/netparray.cc +++ b/netparray.cc @@ -22,13 +22,17 @@ using namespace std; +netparray_t::~netparray_t() +{ +} + /* * The packed width of a packed array is the packed width of the * element times the dimension width of the array itself. */ long netparray_t::packed_width(void) const { - long cur_width = element_type_->packed_width(); + long cur_width = element_type()->packed_width(); for (vector::const_iterator cur = packed_dims_.begin() ; cur != packed_dims_.end() ; ++cur) { @@ -40,7 +44,7 @@ long netparray_t::packed_width(void) const vector netparray_t::slice_dimensions() const { - vector elem_dims = element_type_->slice_dimensions(); + vector elem_dims = element_type()->slice_dimensions(); vector res (packed_dims_.size() + elem_dims.size()); @@ -51,8 +55,3 @@ vector netparray_t::slice_dimensions() const return res; } - -ivl_variable_type_t netparray_t::base_type() const -{ - return element_type_->base_type(); -} diff --git a/netparray.h b/netparray.h index 325437645..4850059b5 100644 --- a/netparray.h +++ b/netparray.h @@ -26,7 +26,7 @@ /* * Packed arrays. */ -class netparray_t : public ivl_type_s { +class netparray_t : public netarray_t { public: explicit netparray_t(const std::vector&packed, @@ -37,27 +37,19 @@ class netparray_t : public ivl_type_s { // Virtual methods from the ivl_type_s type... long packed_width(void) const; std::vector slice_dimensions() const; - ivl_variable_type_t base_type() const; public: - inline const ivl_type_s* element_type() const { return element_type_; } - inline const std::vector& packed_dimensions() const { return packed_dims_; } private: std::vector packed_dims_; - ivl_type_t element_type_; }; inline netparray_t::netparray_t(const std::vector&packed, ivl_type_t etype) -: packed_dims_(packed), element_type_(etype) -{ -} - -inline netparray_t::~netparray_t() +: netarray_t(etype), packed_dims_(packed) { } diff --git a/nettypes.cc b/nettypes.cc index 215e5e3f1..6b5797146 100644 --- a/nettypes.cc +++ b/nettypes.cc @@ -46,6 +46,15 @@ bool ivl_type_s::get_signed() const return false; } +netarray_t::~netarray_t() +{ +} + +ivl_variable_type_t netarray_t::base_type() const +{ + return element_type_->base_type(); +} + unsigned long netrange_width(const vector&packed) { unsigned wid = 1; diff --git a/nettypes.h b/nettypes.h index 983425e48..df7779edb 100644 --- a/nettypes.h +++ b/nettypes.h @@ -45,6 +45,27 @@ class ivl_type_s { virtual std::ostream& debug_dump(std::ostream&) const; }; +/* + * There are a couple types of array types. This class represents the + * common bits of array types. + */ +class netarray_t : public ivl_type_s { + + public: + inline explicit netarray_t(ivl_type_t etype) : element_type_(etype) { } + ~netarray_t(); + + public: + // Some virtual methods have a common implementation for arrays. + ivl_variable_type_t base_type() const; + + public: + inline ivl_type_t element_type() const { return element_type_; } + + private: + ivl_type_t element_type_; +}; + inline static std::ostream& operator << (std::ostream&out, const ivl_type_s&obj) { return obj.debug_dump(out); diff --git a/t-dll-api.cc b/t-dll-api.cc index 28dc4361a..b1f0c51fe 100644 --- a/t-dll-api.cc +++ b/t-dll-api.cc @@ -2792,9 +2792,29 @@ extern "C" ivl_variable_type_t ivl_type_base(ivl_type_t net) extern "C" ivl_type_t ivl_type_element(ivl_type_t net) { - if (const netdarray_t*da = dynamic_cast (net)) + if (const netarray_t*da = dynamic_cast (net)) return da->element_type(); assert(0); return 0; } + +extern "C" unsigned ivl_type_packed_dimensions(ivl_type_t net) +{ + vector slice = net->slice_dimensions(); + return slice.size(); +} + +extern "C" int ivl_type_packed_lsb(ivl_type_t net, unsigned dim) +{ + vector slice = net->slice_dimensions(); + assert(dim < slice.size()); + return slice[dim].get_lsb(); +} + +extern "C" int ivl_type_packed_msb(ivl_type_t net, unsigned dim) +{ + vector slice = net->slice_dimensions(); + assert(dim < slice.size()); + return slice[dim].get_msb(); +} diff --git a/tgt-stub/stub.c b/tgt-stub/stub.c index ba1b23eae..f87face83 100644 --- a/tgt-stub/stub.c +++ b/tgt-stub/stub.c @@ -1222,7 +1222,6 @@ static void show_signal(ivl_signal_t net) const char*type = "?"; const char*port = ""; - const char*data_type = "?"; const char*sign = ivl_signal_signed(net)? "signed" : "unsigned"; switch (ivl_signal_type(net)) { @@ -1263,32 +1262,6 @@ static void show_signal(ivl_signal_t net) break; } - data_type = "?data?"; - switch (ivl_signal_data_type(net)) { - - case IVL_VT_NO_TYPE: - data_type = ""; - break; - case IVL_VT_BOOL: - data_type = "bool"; - break; - case IVL_VT_LOGIC: - data_type = "logic"; - break; - case IVL_VT_REAL: - data_type = "real"; - break; - case IVL_VT_STRING: - data_type = "string"; - break; - case IVL_VT_DARRAY: - data_type = "darray"; - break; - case IVL_VT_VOID: - data_type = "void"; - break; - } - const char*discipline_txt = "NONE"; if (ivl_signal_discipline(net)) { ivl_discipline_t dis = ivl_signal_discipline(net); @@ -1367,7 +1340,7 @@ static void show_signal(ivl_signal_t net) switch (ivl_signal_data_type(net)) { case IVL_VT_NO_TYPE: case IVL_VT_VOID: - fprintf(out, " ERROR: Invalid type for signal: %s\n", data_type); + fprintf(out, " ERROR: Invalid type for signal.\n"); stub_errors += 1; break; default: diff --git a/tgt-stub/types.c b/tgt-stub/types.c index 751ee366c..0a7e143f5 100644 --- a/tgt-stub/types.c +++ b/tgt-stub/types.c @@ -60,6 +60,13 @@ static void show_net_type(ivl_type_t net_type) fprintf(out, "void"); break; } + + unsigned packed_dimensions = ivl_type_packed_dimensions(net_type); + unsigned idx; + for (idx = 0 ; idx < packed_dimensions ; idx += 1) { + fprintf(out, "[%d:%d]", ivl_type_packed_msb(net_type, idx), + ivl_type_packed_lsb(net_type, idx)); + } } void show_type_of_signal(ivl_signal_t net)