From 4e769123317693e91257aebff3710018d0394177 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Sun, 23 Sep 2012 09:28:49 -0700 Subject: [PATCH] ivl_target access to type information. --- design_dump.cc | 2 +- elab_expr.cc | 4 +- elab_sig.cc | 6 +-- ivl_target.h | 52 ++++++++++--------- net_assign.cc | 2 +- netdarray.cc | 5 ++ netdarray.h | 14 ++++- netenum.h | 2 +- netlist.cc | 8 +-- netlist.h | 5 +- netparray.h | 2 +- netstruct.h | 2 +- nettypes.cc | 10 ++-- nettypes.h | 6 +-- netvector.cc | 2 +- netvector.h | 2 +- pform_dump.cc | 22 ++++++++ pform_types.h | 3 ++ t-dll-api.cc | 35 +++++++++++-- t-dll.cc | 11 +--- t-dll.h | 6 +-- tgt-stub/Makefile.in | 2 +- tgt-stub/expression.c | 13 ++++- tgt-stub/priv.h | 5 ++ tgt-stub/stub.c | 8 +-- tgt-stub/types.c | 116 ++++++++++++++++++++++++++++++++++++++++++ tgt-vvp/draw_vpi.c | 3 ++ 27 files changed, 269 insertions(+), 79 deletions(-) create mode 100644 tgt-stub/types.c diff --git a/design_dump.cc b/design_dump.cc index 8875db21a..1aed8c1ef 100644 --- a/design_dump.cc +++ b/design_dump.cc @@ -141,7 +141,7 @@ ostream& operator << (ostream&o, ivl_switch_type_t val) return o; } -ostream& nettype_base_t::debug_dump(ostream&o) const +ostream& ivl_type_s::debug_dump(ostream&o) const { o << typeid(*this).name(); return o; diff --git a/elab_expr.cc b/elab_expr.cc index b7c890268..c027cc9c3 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -2355,7 +2355,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->data_type(); + expr_type_ = darray->element_base_type(); expr_width_ = darray->vector_width(); min_width_ = expr_width_; signed_flag_ = net->get_signed(); @@ -3970,7 +3970,7 @@ NetExpr* PEIdent::elaborate_expr_net(Design*des, NetScope*scope, return node; } -unsigned PENew::test_width(Design*des, NetScope*, width_mode_t&) +unsigned PENew::test_width(Design*, NetScope*, width_mode_t&) { expr_type_ = IVL_VT_DARRAY; expr_width_ = 1; diff --git a/elab_sig.cc b/elab_sig.cc index 22ee95b9a..c01323f1c 100644 --- a/elab_sig.cc +++ b/elab_sig.cc @@ -914,8 +914,8 @@ static netparray_t* elaborate_parray_type(Design*des, NetScope*scope, return res; } -static nettype_base_t*elaborate_type(Design*des, NetScope*scope, - data_type_t*pform_type) +static ivl_type_s*elaborate_type(Design*des, NetScope*scope, + data_type_t*pform_type) { if (struct_type_t*struct_type = dynamic_cast(pform_type)) { netstruct_t*use_type = elaborate_struct_type(des, scope, struct_type); @@ -1256,7 +1256,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const << " in scope " << scope_path(scope) << endl; } - nettype_base_t*base_type = elaborate_type(des, scope, parray_type->base_type); + ivl_type_s*base_type = elaborate_type(des, scope, parray_type->base_type); #if 0 cerr << get_fileline() << ": sorry: Packed array of " << typeid(*parray_type->base_type).name() diff --git a/ivl_target.h b/ivl_target.h index ed63d5c62..37766be64 100644 --- a/ivl_target.h +++ b/ivl_target.h @@ -21,12 +21,19 @@ # include +/* Re the _CLASS define: clang++ wants this to be class to match the + * definition, but clang (the C) compiler needs it to be a struct + * since class is not defined in C. They are effecively both pointers + * to an object so everything works out. */ + #ifdef __cplusplus #define _BEGIN_DECL extern "C" { #define _END_DECL } +#define _CLASS class #else #define _BEGIN_DECL #define _END_DECL +#define _CLASS struct #endif #ifndef __GNUC__ @@ -157,21 +164,8 @@ typedef struct ivl_array_s *ivl_array_t; typedef struct ivl_branch_s *ivl_branch_t; typedef struct ivl_delaypath_s*ivl_delaypath_t; typedef struct ivl_design_s *ivl_design_t; -/* clang++ wants this to be class to match the definition, but clang - * (the C) compiler needs it to be a struct since class is not defined - * in C. They are effecively both pointers to an object so everything - * works out. */ -#ifdef __cplusplus -typedef class ivl_discipline_s*ivl_discipline_t; -#else -typedef struct ivl_discipline_s*ivl_discipline_t; -#endif -/* See the comments above. */ -#ifdef __cplusplus -typedef class netenum_t *ivl_enumtype_t; -#else -typedef struct netenum_t *ivl_enumtype_t; -#endif +typedef _CLASS ivl_discipline_s*ivl_discipline_t; +typedef _CLASS netenum_t *ivl_enumtype_t; typedef struct ivl_event_s *ivl_event_t; typedef struct ivl_expr_s *ivl_expr_t; typedef struct ivl_island_s *ivl_island_t; @@ -180,12 +174,7 @@ typedef struct ivl_lval_s *ivl_lval_t; typedef struct ivl_net_const_s*ivl_net_const_t; typedef struct ivl_net_logic_s*ivl_net_logic_t; typedef struct ivl_udp_s *ivl_udp_t; -/* See the comments above. */ -#ifdef __cplusplus -typedef class ivl_nature_s *ivl_nature_t; -#else -typedef struct ivl_nature_s *ivl_nature_t; -#endif +typedef _CLASS ivl_nature_s *ivl_nature_t; typedef struct ivl_net_probe_s*ivl_net_probe_t; typedef struct ivl_nexus_s *ivl_nexus_t; typedef struct ivl_nexus_ptr_s*ivl_nexus_ptr_t; @@ -193,10 +182,11 @@ typedef struct ivl_parameter_s*ivl_parameter_t; typedef struct ivl_process_s *ivl_process_t; typedef struct ivl_scope_s *ivl_scope_t; typedef struct ivl_signal_s *ivl_signal_t; -typedef struct ivl_port_info_s *ivl_port_info_t; +typedef struct ivl_port_info_s*ivl_port_info_t; typedef struct ivl_switch_s *ivl_switch_t; typedef struct ivl_memory_s *ivl_memory_t; //XXXX __attribute__((deprecated)); typedef struct ivl_statement_s*ivl_statement_t; +typedef const _CLASS ivl_type_s*ivl_type_t; /* * These are types that are defined as enumerations. These have @@ -1907,6 +1897,7 @@ extern unsigned ivl_signal_npath(ivl_signal_t net); extern ivl_delaypath_t ivl_signal_path(ivl_signal_t net, unsigned idx); extern ivl_signal_type_t ivl_signal_type(ivl_signal_t net); extern ivl_variable_type_t ivl_signal_data_type(ivl_signal_t net); +extern ivl_type_t ivl_signal_net_type(ivl_signal_t net); extern const char* ivl_signal_name(ivl_signal_t net); extern const char* ivl_signal_basename(ivl_signal_t net); extern const char* ivl_signal_attr(ivl_signal_t net, const char*key); @@ -1994,7 +1985,7 @@ extern unsigned ivl_stmt_lineno(ivl_statement_t net); * Statements that have event arguments (TRIGGER and WAIT) make * those event objects available through these methods. * - * ivl_stmt_lval +* ivl_stmt_lval * ivl_stmt_lvals * Return the number of l-values for an assignment statement, or * the specific l-value. If there is more than 1 l-value, then the @@ -2195,6 +2186,21 @@ extern ivl_attribute_t ivl_switch_attr_val(ivl_switch_t net, unsigned idx); extern const char* ivl_switch_file(ivl_switch_t net); extern unsigned ivl_switch_lineno(ivl_switch_t net); +/* TYPES + * + * ivl_type_base + * This returns the base type for the type. See the + * ivl_variable_type_t definition for the various base types. + * + * ivl_type_element + * Return the type of the element of an array. + * + * 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); + + #if defined(__MINGW32__) || defined (__CYGWIN32__) # define DLLEXPORT __declspec(dllexport) #else diff --git a/net_assign.cc b/net_assign.cc index 2f5602a2a..d8af4357c 100644 --- a/net_assign.cc +++ b/net_assign.cc @@ -101,7 +101,7 @@ ivl_variable_type_t NetAssign_::expr_type() const if (word_ == 0) return IVL_VT_DARRAY; else - return darray->data_type(); + return darray->element_base_type(); } return sig_->data_type(); diff --git a/netdarray.cc b/netdarray.cc index ed5c3a85b..1a6cca3d0 100644 --- a/netdarray.cc +++ b/netdarray.cc @@ -30,3 +30,8 @@ netdarray_t::~netdarray_t() { delete elem_type_; } + +ivl_variable_type_t netdarray_t::base_type(void) const +{ + return IVL_VT_DARRAY; +} diff --git a/netdarray.h b/netdarray.h index d8aaf9f2a..92ee69ae8 100644 --- a/netdarray.h +++ b/netdarray.h @@ -26,13 +26,23 @@ class netvector_t; -class netdarray_t : public nettype_base_t { +class netdarray_t : public ivl_type_s { public: explicit netdarray_t(netvector_t*vec); ~netdarray_t(); - inline ivl_variable_type_t data_type() const { return elem_type_->base_type(); } + // This is the "base_type()" virtual method of the + // nettype_base_t. The ivl_target api expects this to return + // 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. + 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(); } std::ostream& debug_dump(std::ostream&) const; diff --git a/netenum.h b/netenum.h index 44a1a94b2..a0f3b5373 100644 --- a/netenum.h +++ b/netenum.h @@ -29,7 +29,7 @@ class NetScope; -class netenum_t : public LineInfo, public nettype_base_t { +class netenum_t : public LineInfo, public ivl_type_s { public: explicit netenum_t(ivl_variable_type_t base_type, bool signed_flag, diff --git a/netlist.cc b/netlist.cc index e3a39ddf4..a51fb9c37 100644 --- a/netlist.cc +++ b/netlist.cc @@ -566,22 +566,22 @@ void NetNet::calculate_slice_widths_from_packed_dims_(void) NetNet::NetNet(NetScope*s, perm_string n, Type t, const list&packed, const list&unpacked, - nettype_base_t*net_type) + ivl_type_s*use_net_type) : NetObj(s, n, calculate_count(unpacked)), type_(t), port_type_(NOT_A_PORT), - local_flag_(false), net_type_(net_type), + local_flag_(false), net_type_(use_net_type), discipline_(0), unpacked_dims_(unpacked.size()), eref_count_(0), lref_count_(0) { packed_dims_ = packed; // Special case: This is an enum, so it is its own packed vector. - if (netenum_t*et = dynamic_cast(net_type)) { + if (netenum_t*et = dynamic_cast(use_net_type)) { ivl_assert(*this, packed_dims_.empty()); packed_dims_.push_back(netrange_t(calculate_count(et)-1, 0)); } // Special case: netstruct types are like another packed // dimension. - if (netstruct_t*st = dynamic_cast(net_type)) { + if (netstruct_t*st = dynamic_cast(use_net_type)) { packed_dims_.push_back(netrange_t(calculate_count(st)-1, 0)); } diff --git a/netlist.h b/netlist.h index bd2970ba8..a8897fe3e 100644 --- a/netlist.h +++ b/netlist.h @@ -609,7 +609,7 @@ class NetNet : public NetObj, public PortType { explicit NetNet(NetScope*s, perm_string n, Type t, const std::list&packed, const std::list&unpacked, - nettype_base_t*type =0); + ivl_type_s*type =0); // This form builds a NetNet from its record/enum definition. explicit NetNet(NetScope*s, perm_string n, Type t, netstruct_t*type); @@ -641,6 +641,7 @@ class NetNet : public NetObj, public PortType { bool get_scalar() const; + inline const ivl_type_s* net_type(void) const { return net_type_; } netenum_t*enumeration(void) const; netstruct_t*struct_type(void) const; netdarray_t*darray_type(void) const; @@ -729,7 +730,7 @@ class NetNet : public NetObj, public PortType { Type type_ : 5; PortType port_type_ : 3; bool local_flag_: 1; - nettype_base_t*net_type_; + ivl_type_s*net_type_; ivl_discipline_t discipline_; std::list packed_dims_; diff --git a/netparray.h b/netparray.h index 70be869ec..ca3f10cfa 100644 --- a/netparray.h +++ b/netparray.h @@ -27,7 +27,7 @@ /* * Packed arrays. */ -class netparray_t : public nettype_base_t, public LineInfo { +class netparray_t : public ivl_type_s, public LineInfo { public: explicit netparray_t(const std::list&packed); diff --git a/netstruct.h b/netstruct.h index 25aaf70e4..592fff8cf 100644 --- a/netstruct.h +++ b/netstruct.h @@ -24,7 +24,7 @@ # include "ivl_target.h" # include "nettypes.h" -class netstruct_t : public LineInfo, public nettype_base_t { +class netstruct_t : public LineInfo, public ivl_type_s { public: struct member_t { diff --git a/nettypes.cc b/nettypes.cc index 7f95668fc..46e49db5a 100644 --- a/nettypes.cc +++ b/nettypes.cc @@ -22,21 +22,21 @@ using namespace std; -nettype_base_t::~nettype_base_t() +ivl_type_s::~ivl_type_s() { } -long nettype_base_t::packed_width(void) const +long ivl_type_s::packed_width(void) const { - return 0; + return 1; } -ivl_variable_type_t nettype_base_t::base_type() const +ivl_variable_type_t ivl_type_s::base_type() const { return IVL_VT_NO_TYPE; } -bool nettype_base_t::get_signed() const +bool ivl_type_s::get_signed() const { return false; } diff --git a/nettypes.h b/nettypes.h index ae3cad444..cbf759e48 100644 --- a/nettypes.h +++ b/nettypes.h @@ -29,9 +29,9 @@ * This is a fully abstract type that is a type that can be attached * to a NetNet object. */ -class nettype_base_t { +class ivl_type_s { public: - virtual ~nettype_base_t() =0; + virtual ~ivl_type_s() =0; virtual long packed_width(void) const; // Some types have a base variable type. @@ -41,7 +41,7 @@ class nettype_base_t { virtual std::ostream& debug_dump(std::ostream&) const; }; -inline static std::ostream& operator << (std::ostream&out, const nettype_base_t&obj) +inline static std::ostream& operator << (std::ostream&out, const ivl_type_s&obj) { return obj.debug_dump(out); } diff --git a/netvector.cc b/netvector.cc index 4ff99f78e..259ba532f 100644 --- a/netvector.cc +++ b/netvector.cc @@ -41,5 +41,5 @@ ivl_variable_type_t netvector_t::base_type() const long netvector_t::packed_width() const { - netrange_width(packed_dims_); + return netrange_width(packed_dims_); } diff --git a/netvector.h b/netvector.h index dcfdd2577..ede35cee4 100644 --- a/netvector.h +++ b/netvector.h @@ -23,7 +23,7 @@ # include "ivl_target.h" # include -class netvector_t : public nettype_base_t { +class netvector_t : public ivl_type_s { public: explicit netvector_t(const std::list&packed, diff --git a/pform_dump.cc b/pform_dump.cc index 0ce59a91a..4a6c60ae5 100644 --- a/pform_dump.cc +++ b/pform_dump.cc @@ -153,6 +153,28 @@ void parray_type_t::pform_dump(ostream&out, unsigned indent) const base_type->pform_dump(out, indent+4); } +void struct_type_t::pform_dump(ostream&out, unsigned indent) const +{ + out << setw(indent) << "" << "Struct " << (packed_flag?"packed":"unpacked") + << " with " << members->size() << " members" << endl; + for (list::iterator cur = members->begin() + ; cur != members->end() ; ++ cur) { + struct_member_t*curp = *cur; + curp->pform_dump(out, indent+4); + } +} + +void struct_member_t::pform_dump(ostream&out, unsigned indent) const +{ + out << setw(indent) << "" << type; + for (list::iterator cur = names->begin() + ; cur != names->end() ; ++cur) { + decl_assignment_t*curp = *cur; + out << " " << curp->name; + } + out << ";" << endl; +} + static void dump_attributes_map(ostream&out, const map&attributes, int ind) diff --git a/pform_types.h b/pform_types.h index a47b671fa..df2c8f9b8 100644 --- a/pform_types.h +++ b/pform_types.h @@ -97,10 +97,13 @@ struct struct_member_t : public LineInfo { ivl_variable_type_t type; std::auto_ptr< list > range; std::auto_ptr< list > names; + void pform_dump(std::ostream&out, unsigned indent) const; }; struct struct_type_t : public data_type_t { virtual ivl_variable_type_t figure_packed_base_type(void)const; + virtual void pform_dump(std::ostream&out, unsigned indent) const; + bool packed_flag; std::auto_ptr< list > members; }; diff --git a/t-dll-api.cc b/t-dll-api.cc index fcb8057b6..28dc4361a 100644 --- a/t-dll-api.cc +++ b/t-dll-api.cc @@ -21,7 +21,9 @@ # include "StringHeap.h" # include "t-dll.h" # include "discipline.h" +# include "netdarray.h" # include "netenum.h" +# include "netvector.h" # include # include # include @@ -1422,7 +1424,7 @@ extern "C" int ivl_lpm_signed(ivl_lpm_t net) case IVL_LPM_REPEAT: return 0; case IVL_LPM_ARRAY: // Array ports take the signedness of the array. - return net->u_.array.sig->signed_; + return net->u_.array.sig->net_type->get_signed()? 1 : 0; default: assert(0); return 0; @@ -2231,7 +2233,7 @@ extern "C" ivl_scope_t ivl_signal_scope(ivl_signal_t net) extern "C" unsigned ivl_signal_width(ivl_signal_t net) { - return net->width_; + return net->net_type->packed_width(); } extern "C" ivl_signal_port_t ivl_signal_port(ivl_signal_t net) @@ -2251,7 +2253,7 @@ extern "C" int ivl_signal_local(ivl_signal_t net) extern "C" int ivl_signal_signed(ivl_signal_t net) { - return net->signed_; + return net->net_type->get_signed()? 1 : 0; } extern "C" unsigned ivl_signal_forced_net(ivl_signal_t net) @@ -2273,12 +2275,20 @@ extern "C" unsigned ivl_signal_lineno(ivl_signal_t net) extern "C" int ivl_signal_integer(ivl_signal_t net) { - return net->isint_; + if (const netvector_t*vec = dynamic_cast (net->net_type)) + return vec->get_isint()? 1 : 0; + else + return 0; } extern "C" ivl_variable_type_t ivl_signal_data_type(ivl_signal_t net) { - return net->data_type; + return net->net_type->base_type(); +} + +extern "C" ivl_type_t ivl_signal_net_type(ivl_signal_t net) +{ + return net->net_type; } extern "C" unsigned ivl_signal_npath(ivl_signal_t net) @@ -2773,3 +2783,18 @@ extern "C" unsigned ivl_switch_lineno(ivl_switch_t net) { return net->lineno; } + +extern "C" ivl_variable_type_t ivl_type_base(ivl_type_t net) +{ + if (net == 0) return IVL_VT_NO_TYPE; + else return net->base_type(); +} + +extern "C" ivl_type_t ivl_type_element(ivl_type_t net) +{ + if (const netdarray_t*da = dynamic_cast (net)) + return da->element_type(); + + assert(0); + return 0; +} diff --git a/t-dll.cc b/t-dll.cc index 6a0cb4260..4a4a7cc23 100644 --- a/t-dll.cc +++ b/t-dll.cc @@ -2382,9 +2382,7 @@ void dll_target::signal(const NetNet*net) } } - obj->width_ = net->vector_width(); - obj->signed_= net->get_signed()? 1 : 0; - obj->isint_ = false; + obj->net_type = net->net_type(); obj->local_ = net->local_flag()? 1 : 0; obj->forced_net_ = (net->type() != NetNet::REG) && (net->peek_lref() > 0) ? 1 : 0; @@ -2418,7 +2416,6 @@ void dll_target::signal(const NetNet*net) case NetNet::REG: obj->type_ = IVL_SIT_REG; - obj->isint_ = net->get_isint(); break; /* The SUPPLY0/1 net types are replaced with pulldown/up @@ -2469,15 +2466,9 @@ void dll_target::signal(const NetNet*net) obj->npath = 0; obj->path = 0; - obj->data_type = net->data_type(); obj->nattr = net->attr_cnt(); obj->attr = fill_in_attributes(net); - /* If this is a dynamic array, then set the type to DARRAY. */ - if (net->darray_type()) { - obj->data_type = IVL_VT_DARRAY; - } - /* Get the nexus objects for all the pins of the signal. If the signal has only one pin, then write the single ivl_nexus_t object into n.pin_. Otherwise, make an array of diff --git a/t-dll.h b/t-dll.h index c3486e5f7..79177ca26 100644 --- a/t-dll.h +++ b/t-dll.h @@ -677,14 +677,12 @@ struct ivl_signal_s { ivl_signal_type_t type_; ivl_signal_port_t port_; int module_port_index_; - ivl_variable_type_t data_type; ivl_discipline_t discipline; perm_string file; unsigned lineno; - unsigned width_; - unsigned signed_ : 1; - unsigned isint_ : 1; + // This is the type for the signal + ivl_type_t net_type; unsigned local_ : 1; unsigned forced_net_ : 1; diff --git a/tgt-stub/Makefile.in b/tgt-stub/Makefile.in index 22d051fb2..d44973801 100644 --- a/tgt-stub/Makefile.in +++ b/tgt-stub/Makefile.in @@ -44,7 +44,7 @@ CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@ @PICFLAG@ CFLAGS = @WARNING_FLAGS@ @CFLAGS@ LDFLAGS = @LDFLAGS@ -O = stub.o enumerate.o expression.o statement.o switches.o +O = stub.o enumerate.o expression.o statement.o switches.o types.o all: dep stub.tgt diff --git a/tgt-stub/expression.c b/tgt-stub/expression.c index ecf2a61b1..f21684ca0 100644 --- a/tgt-stub/expression.c +++ b/tgt-stub/expression.c @@ -169,6 +169,7 @@ static void show_select_expression(ivl_expr_t net, unsigned ind) { unsigned width = ivl_expr_width(net); const char*sign = ivl_expr_signed(net)? "signed" : "unsigned"; + const char*vt = vt_type_string(net); ivl_expr_t oper1 = ivl_expr_oper1(net); ivl_expr_t oper2 = ivl_expr_oper2(net); @@ -186,8 +187,8 @@ static void show_select_expression(ivl_expr_t net, unsigned ind) /* If oper2 is present, then it is the base of a part select. The width of the expression defines the range of the part select. */ - fprintf(out, "%*s\n", ind, "", - width, sign); + fprintf(out, "%*s\n", ind, "", + width, sign, vt); show_expression(oper1, ind+3); show_expression(oper2, ind+3); @@ -233,6 +234,14 @@ static void show_signal_expression(ivl_expr_t net, unsigned ind) fprintf(out, "%*sERROR: Missing word expression\n", ind+2, ""); stub_errors += 1; } + /* If this is not an array, then the expression with must + match the signal width. We have IVL_EX_SELECT expressions + for casting signal widths. */ + if (dimensions == 0 && ivl_signal_width(sig) != width) { + fprintf(out, "%*sERROR: Expression width (%u) doesn't match ivl_signal_width(sig)=%u\n", + ind+2, "", width, ivl_signal_width(sig)); + stub_errors += 1; + } if (word != 0) { fprintf(out, "%*sAddress-0 word address:\n", ind+2, ""); diff --git a/tgt-stub/priv.h b/tgt-stub/priv.h index 0a70d13be..d8c301bef 100644 --- a/tgt-stub/priv.h +++ b/tgt-stub/priv.h @@ -61,6 +61,11 @@ extern void show_expression(ivl_expr_t net, unsigned ind); */ extern void show_statement(ivl_statement_t net, unsigned ind); +/* + * Show the type of the signal, in one line. + */ +extern void show_type_of_signal(ivl_signal_t); + extern void show_switch(ivl_switch_t net); /* diff --git a/tgt-stub/stub.c b/tgt-stub/stub.c index f8a1630ff..ba1b23eae 100644 --- a/tgt-stub/stub.c +++ b/tgt-stub/stub.c @@ -1298,13 +1298,9 @@ static void show_signal(ivl_signal_t net) for (idx = 0 ; idx < ivl_signal_array_count(net) ; idx += 1) { ivl_nexus_t nex = ivl_signal_nex(net, idx); - unsigned dim; - fprintf(out, " %s %s %s%s", type, sign, port, data_type); - for (dim = 0 ; dim < ivl_signal_packed_dimensions(net) ; dim += 1) { - fprintf(out, "[%d:%d]", ivl_signal_packed_msb(net,dim), - ivl_signal_packed_lsb(net,dim)); - } + fprintf(out, " %s %s %s", type, sign, port); + show_type_of_signal(net); fprintf(out, " %s[word=%u, adr=%d] ", ivl_signal_basename(net), idx, ivl_signal_array_base(net)+idx, diff --git a/tgt-stub/types.c b/tgt-stub/types.c new file mode 100644 index 000000000..751ee366c --- /dev/null +++ b/tgt-stub/types.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2012 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 "config.h" +# include "priv.h" +# include + +static void show_net_type(ivl_type_t net_type); + +static void show_net_type_darray(ivl_type_t net_type) +{ + /* Dynamic arrays have a single element type. */ + ivl_type_t element_type = ivl_type_element(net_type); + + fprintf(out, "darray of "); + show_net_type(element_type); +} + +static void show_net_type(ivl_type_t net_type) +{ + ivl_variable_type_t data_type = ivl_type_base(net_type); + + switch (data_type) { + case IVL_VT_NO_TYPE: + fprintf(out, ""); + stub_errors += 1; + break; + case IVL_VT_BOOL: + fprintf(out, "bool"); + break; + case IVL_VT_LOGIC: + fprintf(out, "logic"); + break; + case IVL_VT_REAL: + fprintf(out, "real"); + break; + case IVL_VT_STRING: + fprintf(out, "string"); + break; + case IVL_VT_DARRAY: + show_net_type_darray(net_type); + break; + case IVL_VT_VOID: + fprintf(out, "void"); + break; + } +} + +void show_type_of_signal(ivl_signal_t net) +{ + unsigned dim; + + /* The data_type is the base type of the signal. This the the + starting point for the type. In the long run I think I want + to remove this in favor of the ivl_signal_net_type below. */ + ivl_variable_type_t data_type = ivl_signal_data_type(net); + + /* This gets the more general type description. This is a + newer form so doesn't yet handle all the cases. Newer + types, such DARRAY types, REQUIRE this method to get at the + type details. */ + ivl_type_t net_type = ivl_signal_net_type(net); + + if (net_type) { + show_net_type(net_type); + return; + } + + switch (data_type) { + case IVL_VT_NO_TYPE: + fprintf(out, ""); + break; + case IVL_VT_BOOL: + fprintf(out, "bool"); + break; + case IVL_VT_LOGIC: + fprintf(out, "logic"); + break; + case IVL_VT_REAL: + fprintf(out, "real"); + break; + case IVL_VT_STRING: + fprintf(out, "string"); + break; + case IVL_VT_DARRAY: + /* The DARRAY type MUST be described by an + ivl_signal_net_type object. */ + fprintf(out, "ERROR-DARRAY"); + stub_errors += 1; + break; + case IVL_VT_VOID: + fprintf(out, "void"); + break; + } + + for (dim = 0 ; dim < ivl_signal_packed_dimensions(net) ; dim += 1) { + fprintf(out, "[%d:%d]", ivl_signal_packed_msb(net,dim), + ivl_signal_packed_lsb(net,dim)); + } +} diff --git a/tgt-vvp/draw_vpi.c b/tgt-vvp/draw_vpi.c index 1133c8c42..cf787a030 100644 --- a/tgt-vvp/draw_vpi.c +++ b/tgt-vvp/draw_vpi.c @@ -411,6 +411,9 @@ static void draw_vpi_taskfunc_args(const char*call_string, buffer[0] = 0; break; default: + fprintf(vvp_out, "\nXXXX Unexpected argument: call_string=<%s>, arg=%d, type=%d\n", + call_string, idx, ivl_expr_value(expr)); + fflush(vvp_out); assert(0); } args[idx].text = strdup(buffer);