diff --git a/PFunction.cc b/PFunction.cc index 35eca86c7..a80123425 100644 --- a/PFunction.cc +++ b/PFunction.cc @@ -25,7 +25,7 @@ PFunction::PFunction(perm_string name, LexicalScope*parent, bool is_auto__) : PTaskFunc(name, parent), statement_(0) { is_auto_ = is_auto__; - return_type_.type = PTF_NONE; + return_type_ = 0; } PFunction::~PFunction() @@ -39,7 +39,7 @@ void PFunction::set_statement(Statement*s) statement_ = s; } -void PFunction::set_return(PTaskFuncArg t) +void PFunction::set_return(const data_type_t*t) { return_type_ = t; } diff --git a/PTask.h b/PTask.h index 4fce2369e..cbd2d7e2a 100644 --- a/PTask.h +++ b/PTask.h @@ -32,24 +32,6 @@ class PWire; class Statement; class PExpr; -enum PTaskFuncEnum { - PTF_NONE, - PTF_REG, - PTF_REG_S, - PTF_INTEGER, - PTF_REAL, - PTF_REALTIME, - PTF_TIME, - PTF_ATOM2, - PTF_ATOM2_S, - PTF_STRING, - PTF_VOID -}; - -struct PTaskFuncArg { - PTaskFuncEnum type; - std::list*range; -}; class PTaskFunc : public PScope, public LineInfo { @@ -126,7 +108,7 @@ class PFunction : public PTaskFunc { ~PFunction(); void set_statement(Statement *s); - void set_return(PTaskFuncArg t); + void set_return(const data_type_t*t); void elaborate_scope(Design*des, NetScope*scope) const; @@ -141,7 +123,7 @@ class PFunction : public PTaskFunc { void dump(ostream&, unsigned) const; private: - PTaskFuncArg return_type_; + const data_type_t* return_type_; Statement *statement_; bool is_auto_; }; diff --git a/PWire.cc b/PWire.cc index 31e117b48..e50e29f80 100644 --- a/PWire.cc +++ b/PWire.cc @@ -120,6 +120,7 @@ bool PWire::set_data_type(ivl_variable_type_t dt) assert(data_type_ == IVL_VT_NO_TYPE); data_type_ = dt; + return true; } @@ -140,7 +141,14 @@ bool PWire::get_signed() const bool PWire::get_isint() const { - return isint_; + if (isint_) + return true; + + if (vector_type_t*tmp = dynamic_cast(set_data_type_)) { + return tmp->integer_flag; + } + + return false; } bool PWire::get_scalar() const @@ -257,6 +265,11 @@ void PWire::set_data_type(data_type_t*type) { assert(set_data_type_ == 0); set_data_type_ = type; + + if (vector_type_t*tmp = dynamic_cast(type)) { + if (tmp->integer_flag) + isint_ = true; + } } void PWire::set_discipline(ivl_discipline_t d) diff --git a/elab_expr.cc b/elab_expr.cc index 2be59cac1..cf6ff341e 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -1134,7 +1134,7 @@ unsigned PECallFunction::test_width_method_(Design*des, NetScope*scope, << endl; } - netclass_t* class_type = net->class_type(); + const netclass_t* class_type = net->class_type(); member_type = class_type->get_property(member_name); use_path = tmp_path; @@ -1164,7 +1164,7 @@ unsigned PECallFunction::test_width_method_(Design*des, NetScope*scope, return expr_width_; } - if (netclass_t*class_type = net->class_type()) { + if (const netclass_t*class_type = net->class_type()) { cerr << get_fileline() << ": PECallFunction::test_width_method_: " << "Try to find method " << method_name << " of class " << class_type->get_name() << endl; @@ -1425,7 +1425,7 @@ NetExpr* PECallFunction::elaborate_access_func_(Design*des, NetScope*scope, */ static NetExpr* check_for_enum_methods(const LineInfo*li, Design*des, NetScope*scope, - netenum_t*netenum, + const netenum_t*netenum, pform_name_t use_path, perm_string method_name, NetExpr*expr, @@ -1760,7 +1760,7 @@ static NetExpr* check_for_class_property(const LineInfo*li, NetNet*net, const name_component_t&comp) { - netclass_t*class_type = net->class_type(); + const netclass_t*class_type = net->class_type(); const ivl_type_s*ptype = class_type->get_property(comp.name); if (ptype == 0) { @@ -2055,7 +2055,7 @@ NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope, } } - if (netenum_t*netenum = net->enumeration()) { + if (const netenum_t*netenum = net->enumeration()) { // We may need the net expression for the // enumeration variable so get it. NetESignal*expr = new NetESignal(net); @@ -2082,7 +2082,7 @@ NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope, } } - if (netclass_t*class_type = net->class_type()) { + if (const netclass_t*class_type = net->class_type()) { NetScope*func = class_type->method_from_name(method_name); if (func == 0) { return 0; @@ -2595,7 +2595,7 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode) ivl_assert(*this, 0); } - if (netdarray_t*darray = net? net->darray_type() : 0) { + if (const 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->element_width(); @@ -2637,7 +2637,7 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode) // The width of an enumeration literal is the width of the // enumeration base. if (const NetEConstEnum*par_enum = dynamic_cast (par)) { - netenum_t*use_enum = par_enum->enumeration(); + const netenum_t*use_enum = par_enum->enumeration(); ivl_assert(*this, use_enum != 0); expr_type_ = use_enum->base_type(); @@ -2714,7 +2714,7 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode) } } - if (netclass_t*class_type = net->class_type()) { + if (const netclass_t*class_type = net->class_type()) { const ivl_type_s*ptype = class_type->get_property(method_name); if (ptype) { expr_type_ = ptype->base_type(); @@ -3037,7 +3037,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope, if (net != 0) { // If this net is actually an enum, the method may // be an enumeration method. - if (netenum_t*netenum = net->enumeration()) { + if (const netenum_t*netenum = net->enumeration()) { // We may need the net expression for the // enumeration variable so get it. NetESignal*expr = new NetESignal(net); @@ -4177,7 +4177,7 @@ NetExpr* PEIdent::elaborate_expr_net_bit_(Design*des, NetScope*scope, NetExpr*mux = elab_and_eval(des, scope, index_tail.msb, -1, need_const); - if (netdarray_t*darray = net->sig()->darray_type()) { + if (const netdarray_t*darray = net->sig()->darray_type()) { // Special case: This is a select of a dynamic // array. Generate a NetESelect and attach it to // the NetESignal. This should be interpreted as diff --git a/elab_lval.cc b/elab_lval.cc index c0d470d51..41093b14b 100644 --- a/elab_lval.cc +++ b/elab_lval.cc @@ -790,12 +790,12 @@ bool PEIdent::elaborate_lval_net_class_member_(Design*des, NetScope*, << " of " << lv->sig()->name() << "." << endl; } - netclass_t*class_type = lv->sig()->class_type(); + const netclass_t*class_type = lv->sig()->class_type(); ivl_assert(*this, class_type); /* Make sure the property is really present in the class. If not, then generate an error message and return an error. */ - const ivl_type_s*ptype = class_type->get_property(method_name); + ivl_type_t ptype = class_type->get_property(method_name); if (ptype == 0) { cerr << get_fileline() << ": error: Class " << class_type->get_name() << " does not have a property " << method_name << "." << endl; diff --git a/elab_scope.cc b/elab_scope.cc index a1d07df66..c86c9b4de 100644 --- a/elab_scope.cc +++ b/elab_scope.cc @@ -280,6 +280,8 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope, if (cur_value.is_defined()) cur_value = cur_value + one_value; } + + use_enum->insert_name_close(); } static void elaborate_scope_enumerations(Design*des, NetScope*scope, diff --git a/elab_sig.cc b/elab_sig.cc index 7db92eb6e..fea0f837f 100644 --- a/elab_sig.cc +++ b/elab_sig.cc @@ -537,147 +537,20 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const elaborate_sig_wires_(des, scope); - NetNet*ret_sig = 0; - netvector_t*ret_vec = 0; + ivl_type_t ret_type; - /* Create the signals/variables of the return value and write - them into the function scope. */ - switch (return_type_.type) { - - case PTF_REG: - case PTF_REG_S: - if (return_type_.range) { - ivl_assert(*this, return_type_.range->size() == 1); - pform_range_t&return_range = return_type_.range->front(); - - NetExpr*me = elab_and_eval(des, scope, - return_range.first, -1, - true); - assert(me); - NetExpr*le = elab_and_eval(des, scope, - return_range.second, -1, - true); - assert(le); - - long mnum = 0, lnum = 0; - if ( ! get_const_argument(me, mnum) ) { - cerr << me->get_fileline() << ": error: " - "Unable to evaluate constant expression " - << *me << "." << endl; - des->errors += 1; - } - - if ( ! get_const_argument(le, lnum) ) { - cerr << le->get_fileline() << ": error: " - "Unable to evaluate constant expression " - << *le << "." << endl; - des->errors += 1; - } - - vector packed; - packed.push_back(netrange_t(mnum, lnum)); - ret_vec = new netvector_t(packed, IVL_VT_LOGIC); - ret_vec->set_signed(return_type_.type == PTF_REG_S); - ret_vec->set_scalar(false); - ret_sig = new NetNet(scope, fname, NetNet::REG, ret_vec); - - } else { - ret_vec = new netvector_t(IVL_VT_LOGIC); - ret_vec->set_signed(return_type_.type == PTF_REG_S); - ret_vec->set_scalar(true); - ret_sig = new NetNet(scope, fname, NetNet::REG, ret_vec); - } - ret_sig->set_line(*this); - ret_sig->port_type(NetNet::POUTPUT); - break; - - case PTF_INTEGER: - ret_vec = new netvector_t(IVL_VT_LOGIC, integer_width-1,0); - ret_vec->set_signed(true); - ret_vec->set_isint(true); - ret_vec->set_scalar(false); - ret_sig = new NetNet(scope, fname, NetNet::REG, ret_vec); - ret_sig->set_line(*this); - ret_sig->port_type(NetNet::POUTPUT); - break; - - case PTF_TIME: - ret_vec = new netvector_t(IVL_VT_LOGIC, 64-1,0); - ret_vec->set_isint(false); - ret_vec->set_scalar(false); - ret_sig = new NetNet(scope, fname, NetNet::REG, ret_vec); - ret_sig->set_line(*this); - ret_sig->port_type(NetNet::POUTPUT); - break; - - case PTF_REAL: - case PTF_REALTIME: - ret_vec = new netvector_t(IVL_VT_REAL); - ret_vec->set_signed(true); - ret_vec->set_isint(false); - ret_vec->set_scalar(true); - ret_sig = new NetNet(scope, fname, NetNet::REG, ret_vec); - ret_sig->set_line(*this); - ret_sig->port_type(NetNet::POUTPUT); - break; - - case PTF_ATOM2: - case PTF_ATOM2_S: - long use_wid; - { - ivl_assert(*this, return_type_.range->size() == 1); - pform_range_t&return_range = return_type_.range->front(); - NetExpr*me = elab_and_eval(des, scope, - return_range.first, -1, - true); - ivl_assert(*this, me); - NetExpr*le = elab_and_eval(des, scope, - return_range.second, -1, - true); - ivl_assert(*this, le); - - long mnum = 0, lnum = 0; - if ( ! get_const_argument(me, mnum) ) { - cerr << me->get_fileline() << ": error: " - "Unable to evaluate constant expression " - << *me << "." << endl; - des->errors += 1; - } - - if ( ! get_const_argument(le, lnum) ) { - cerr << le->get_fileline() << ": error: " - "Unable to evaluate constant expression " - << *le << "." << endl; - des->errors += 1; - } - - use_wid = mnum - lnum + 1; - } - ret_vec = new netvector_t(IVL_VT_BOOL, use_wid-1, 0); - ret_vec->set_isint(true); - ret_vec->set_scalar(false); - ret_vec->set_signed(return_type_.type == PTF_ATOM2_S? true : false); - ret_sig = new NetNet(scope, fname, NetNet::REG, ret_vec); - ret_sig->set_line(*this); - ret_sig->port_type(NetNet::POUTPUT); - break; - - case PTF_STRING: - cerr << get_fileline() << ": sorry: String functions are not supported yet" << endl; - break; - - case PTF_VOID: - // Void functions have no return value, so there is no - // signal to create here. - break; - - default: - /* If we do not have any ports or a return type this - * is probably a bad function definition. */ - cerr << get_fileline() << ": error: Bad definition for " - << "function " << scope->basename() << "?" << endl; - return; + if (return_type_) { + ret_type = return_type_->elaborate_type(des, scope); + } else { + netvector_t*tmp = new netvector_t(IVL_VT_LOGIC); + tmp->set_scalar(true); + ret_type = tmp; } + list ret_unpacked; + NetNet*ret_sig = new NetNet(scope, fname, NetNet::REG, ret_unpacked, ret_type); + + ret_sig->set_line(*this); + ret_sig->port_type(NetNet::POUTPUT); vectorports; elaborate_sig_ports_(des, scope, ports); @@ -1290,7 +1163,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const } else if (enum_type_t*enum_type = dynamic_cast(set_data_type_)) { list::const_iterator sample_name = enum_type->names->begin(); - netenum_t*use_enum = scope->enumeration_for_name(sample_name->name); + const netenum_t*use_enum = scope->enumeration_for_name(sample_name->name); if (debug_elaborate) { cerr << get_fileline() << ": debug: Create signal " << wtype diff --git a/elab_type.cc b/elab_type.cc index 7ddb9453f..60e04e8ca 100644 --- a/elab_type.cc +++ b/elab_type.cc @@ -23,6 +23,7 @@ # include "netdarray.h" # include "netscalar.h" # include "netvector.h" +# include "netmisc.h" # include # include "ivl_assert.h" @@ -77,6 +78,42 @@ ivl_type_s* class_type_t::elaborate_type(Design*, NetScope*scope) const return scope->find_class(name); } +ivl_type_s* vector_type_t::elaborate_type(Design*des, NetScope*scope) const +{ + vector packed; + + if (pdims.get()) { + for (list::const_iterator cur = pdims->begin() + ; cur != pdims->end() ; ++ cur) { + + NetExpr*me = elab_and_eval(des, scope, cur->first, 0, true); + assert(me); + + NetExpr*le = elab_and_eval(des, scope, cur->second, 0, true); + assert(le); + + long mnum = 0, lnum = 0; + if ( ! eval_as_long(mnum, me) ) { + assert(0); + des->errors += 1; + } + + if ( ! eval_as_long(lnum, le) ) { + assert(0); + des->errors += 1; + } + + packed.push_back(netrange_t(mnum, lnum)); + } + } + + netvector_t*tmp = new netvector_t(packed, base_type); + tmp->set_signed(signed_flag); + tmp->set_isint(integer_flag); + + return tmp; +} + ivl_type_s* real_type_t::elaborate_type(Design*, NetScope*) const { switch (type_code) { diff --git a/elaborate.cc b/elaborate.cc index 51fb41c14..b0cb3a8fc 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -3314,7 +3314,7 @@ NetProc* PCallTask::elaborate_method_(Design*des, NetScope*scope) const return sys; } - if (netclass_t*class_type = net->class_type()) { + if (const netclass_t*class_type = net->class_type()) { NetScope*task = class_type->method_from_name(method_name); if (task == 0) { cerr << get_fileline() << ": internal error: " diff --git a/ivl_target.h b/ivl_target.h index 5e7560f59..18131b50c 100644 --- a/ivl_target.h +++ b/ivl_target.h @@ -165,7 +165,7 @@ typedef struct ivl_branch_s *ivl_branch_t; typedef struct ivl_delaypath_s*ivl_delaypath_t; typedef struct ivl_design_s *ivl_design_t; typedef _CLASS ivl_discipline_s*ivl_discipline_t; -typedef _CLASS netenum_t *ivl_enumtype_t; +typedef const _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; diff --git a/net_assign.cc b/net_assign.cc index d4fefa69c..d787478a8 100644 --- a/net_assign.cc +++ b/net_assign.cc @@ -102,7 +102,7 @@ unsigned NetAssign_::lwidth() const return ptype->packed_width(); } - if (netdarray_t*darray = sig_->darray_type()) { + if (const netdarray_t*darray = sig_->darray_type()) { if (word_ == 0) return 1; else @@ -122,7 +122,7 @@ ivl_variable_type_t NetAssign_::expr_type() const return tmp->base_type(); } - if (netdarray_t*darray = sig_->darray_type()) { + if (const netdarray_t*darray = sig_->darray_type()) { if (word_ == 0) return IVL_VT_DARRAY; else @@ -153,9 +153,9 @@ const ivl_type_s* NetAssign_::net_type() const return 0; } -netenum_t*NetAssign_::enumeration() const +const netenum_t*NetAssign_::enumeration() const { - netenum_t*tmp = 0; + const netenum_t*tmp = 0; // If the base signal is not an enumeration, return nil. if ( (tmp = sig_->enumeration()) == 0 ) diff --git a/net_expr.cc b/net_expr.cc index 0e3cb24f0..dc0f2068c 100644 --- a/net_expr.cc +++ b/net_expr.cc @@ -64,7 +64,7 @@ ivl_variable_type_t NetExpr::expr_type() const return IVL_VT_LOGIC; } -netenum_t*NetExpr::enumeration() const +const netenum_t*NetExpr::enumeration() const { return 0; } @@ -246,7 +246,7 @@ void NetEConcat::set(unsigned idx, NetExpr*e) expr_width( expr_width() + repeat_ * e->expr_width() ); } -NetEConstEnum::NetEConstEnum(NetScope*s, perm_string n, netenum_t*eset, const verinum&v) +NetEConstEnum::NetEConstEnum(NetScope*s, perm_string n, const netenum_t*eset, const verinum&v) : NetEConst(v), scope_(s), enum_set_(eset), name_(n) { assert(has_width()); @@ -256,7 +256,7 @@ NetEConstEnum::~NetEConstEnum() { } -netenum_t*NetEConstEnum::enumeration() const +const netenum_t*NetEConstEnum::enumeration() const { return enum_set_; } @@ -307,7 +307,7 @@ const NetScope* NetECRealParam::scope() const } -NetENetenum::NetENetenum(netenum_t*s) +NetENetenum::NetENetenum(const netenum_t*s) : netenum_(s) { } @@ -316,7 +316,7 @@ NetENetenum::~NetENetenum() { } -netenum_t* NetENetenum::netenum() const +const netenum_t* NetENetenum::netenum() const { return netenum_; } @@ -456,7 +456,7 @@ NetESFunc::NetESFunc(const char*n, ivl_type_t rtype, unsigned np) ivl_assert(*this, 0); } -NetESFunc::NetESFunc(const char*n, netenum_t*enum_type, unsigned np) +NetESFunc::NetESFunc(const char*n, const netenum_t*enum_type, unsigned np) : name_(0), type_(enum_type->base_type()), enum_type_(enum_type), parms_(np) { name_ = lex_strings.add(n); @@ -506,7 +506,7 @@ ivl_variable_type_t NetESFunc::expr_type() const return type_; } -netenum_t* NetESFunc::enumeration() const +const netenum_t* NetESFunc::enumeration() const { return enum_type_; } diff --git a/net_scope.cc b/net_scope.cc index aa02ba390..64667c50e 100644 --- a/net_scope.cc +++ b/net_scope.cc @@ -570,7 +570,7 @@ bool NetScope::add_enumeration_name(netenum_t*enum_set, perm_string name) return cur.second; } -netenum_t*NetScope::enumeration_for_name(perm_string name) +const netenum_t*NetScope::enumeration_for_name(perm_string name) { NetEConstEnum*tmp = enum_names_[name]; assert(tmp != 0); diff --git a/netclass.cc b/netclass.cc index f28b78c18..690443f13 100644 --- a/netclass.cc +++ b/netclass.cc @@ -92,7 +92,7 @@ ivl_type_t netclass_t::get_prop_type(size_t idx) const return property_table_[idx].type; } -NetScope*netclass_t::method_from_name(perm_string name) +NetScope*netclass_t::method_from_name(perm_string name) const { NetScope*task = class_scope_->child( hname_t(name) ); if (task == 0) return 0; diff --git a/netclass.h b/netclass.h index 65310bc19..30bd1d087 100644 --- a/netclass.h +++ b/netclass.h @@ -59,7 +59,7 @@ class netclass_t : public ivl_type_s { int property_idx_from_name(perm_string pname) const; // The task method scopes from the method name. - NetScope*method_from_name(perm_string mname); + NetScope*method_from_name(perm_string mname) const; void elaborate_sig(Design*des, PClass*pclass); void elaborate(Design*des, PClass*pclass); diff --git a/netenum.cc b/netenum.cc index 614a9618a..24dc1d3f0 100644 --- a/netenum.cc +++ b/netenum.cc @@ -73,6 +73,32 @@ bool netenum_t::insert_name(size_t name_idx, perm_string name, const verinum&val return res.second; } +void netenum_t::insert_name_close(void) +{ + for (size_t idx = 0 ; idx < names_.size() ; idx += 1) { + netenum_t::iterator cur = names_map_.find(names_[idx]); + + vectorstr (cur->second.len() + 1); + for (unsigned bit = 0 ; bit < cur->second.len() ; bit += 1) { + switch (cur->second.get(bit)) { + case verinum::V0: + str[bit] = '0'; + break; + case verinum::V1: + str[bit] = '1'; + break; + case verinum::Vx: + str[bit] = 'x'; + break; + case verinum::Vz: + str[bit] = 'z'; + break; + } + } + bits_[idx] = bits_strings.make(&str[0]); + } +} + netenum_t::iterator netenum_t::find_name(perm_string name) const { return names_map_.find(name); @@ -115,32 +141,7 @@ perm_string netenum_t::name_at(size_t idx) const return names_[idx]; } -perm_string netenum_t::bits_at(size_t idx) +perm_string netenum_t::bits_at(size_t idx) const { - assert(idx < names_.size()); - - if (bits_[idx] == 0) { - netenum_t::iterator cur = names_map_.find(names_[idx]); - - vectorstr (cur->second.len() + 1); - for (unsigned bit = 0 ; bit < cur->second.len() ; bit += 1) { - switch (cur->second.get(bit)) { - case verinum::V0: - str[bit] = '0'; - break; - case verinum::V1: - str[bit] = '1'; - break; - case verinum::Vx: - str[bit] = 'x'; - break; - case verinum::Vz: - str[bit] = 'z'; - break; - } - } - bits_[idx] = bits_strings.make(&str[0]); - } - return bits_[idx]; } diff --git a/netenum.h b/netenum.h index 80704bd0c..a768d02c4 100644 --- a/netenum.h +++ b/netenum.h @@ -49,6 +49,9 @@ class netenum_t : public LineInfo, public ivl_type_s { // enumeration value. bool insert_name(size_t idx, perm_string name, const verinum&val); + // Indicate that there will be no more names to insert. + void insert_name_close(void); + typedef std::map::const_iterator iterator; iterator find_name(perm_string name) const; iterator end_name() const; @@ -59,7 +62,7 @@ class netenum_t : public LineInfo, public ivl_type_s { iterator last_name() const; perm_string name_at(size_t idx) const; - perm_string bits_at(size_t idx); + perm_string bits_at(size_t idx) const; private: ivl_variable_type_t base_type_; diff --git a/netlist.cc b/netlist.cc index bcaddb7f1..43cbb0760 100644 --- a/netlist.cc +++ b/netlist.cc @@ -530,7 +530,7 @@ void NetNet::calculate_slice_widths_from_packed_dims_(void) } NetNet::NetNet(NetScope*s, perm_string n, Type t, - const list&unpacked, ivl_type_s*use_net_type) + const list&unpacked, ivl_type_t use_net_type) : NetObj(s, n, calculate_count(unpacked)), type_(t), port_type_(NOT_A_PORT), local_flag_(false), net_type_(use_net_type), @@ -762,7 +762,7 @@ bool NetNet::get_signed() const bool NetNet::get_isint() const { - if (netvector_t*vec = dynamic_cast (net_type_)) + if (const netvector_t*vec = dynamic_cast (net_type_)) return vec->get_isint(); else return false; @@ -770,20 +770,20 @@ bool NetNet::get_isint() const bool NetNet::get_scalar() const { - if (netvector_t*vec = dynamic_cast (net_type_)) + if (const netvector_t*vec = dynamic_cast (net_type_)) return vec->get_scalar(); else return false; } -netenum_t*NetNet::enumeration(void) const +const netenum_t*NetNet::enumeration(void) const { - return dynamic_cast (net_type_); + return dynamic_cast (net_type_); } const netstruct_t*NetNet::struct_type(void) const { - const ivl_type_s*cur_type = net_type_; + ivl_type_t cur_type = net_type_; while (cur_type) { if (const netdarray_t*da = dynamic_cast (cur_type)) { cur_type = da->element_type(); @@ -803,14 +803,14 @@ const netstruct_t*NetNet::struct_type(void) const return 0; } -netdarray_t* NetNet::darray_type(void) const +const netdarray_t* NetNet::darray_type(void) const { - return dynamic_cast (net_type_); + return dynamic_cast (net_type_); } -netclass_t* NetNet::class_type(void) const +const netclass_t* NetNet::class_type(void) const { - return dynamic_cast (net_type_); + return dynamic_cast (net_type_); } /* @@ -2375,7 +2375,7 @@ perm_string NetESignal::name() const return net_->name(); } -netenum_t* NetESignal::enumeration() const +const netenum_t* NetESignal::enumeration() const { return enum_type_; } diff --git a/netlist.h b/netlist.h index 3a5c78ca4..7803c2d6a 100644 --- a/netlist.h +++ b/netlist.h @@ -604,7 +604,7 @@ class NetNet : public NetObj, public PortType { // now, the unpacked type is not burried into an ivl_type_s object. explicit NetNet(NetScope*s, perm_string n, Type t, const std::list&unpacked, - ivl_type_s*type =0); + ivl_type_t type =0); // This form builds a NetNet from its record/enum/darray // definition. They should probably be replaced with a single @@ -639,10 +639,10 @@ 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; + const netenum_t*enumeration(void) const; const netstruct_t*struct_type(void) const; - netdarray_t*darray_type(void) const; - netclass_t*class_type(void) const; + const netdarray_t*darray_type(void) const; + const netclass_t*class_type(void) const; /* Attach a discipline to the net. */ ivl_discipline_t get_discipline() const; @@ -729,7 +729,7 @@ class NetNet : public NetObj, public PortType { Type type_ : 5; PortType port_type_ : 3; bool local_flag_: 1; - ivl_type_s*net_type_; + ivl_type_t net_type_; ivl_discipline_t discipline_; std::vector unpacked_dims_; @@ -848,7 +848,7 @@ class NetScope : public Attrib { void add_enumeration_set(netenum_t*enum_set); bool add_enumeration_name(netenum_t*enum_set, perm_string enum_name); - netenum_t* enumeration_for_name(perm_string name); + const netenum_t* enumeration_for_name(perm_string name); void add_class(netclass_t*class_type); netclass_t* find_class(perm_string name); @@ -1810,7 +1810,7 @@ class NetExpr : public LineInfo { // Return the enumeration set that defines this expressions // enumeration type, or return nil if the expression is not // part of the enumeration. - virtual netenum_t*enumeration() const; + virtual const netenum_t*enumeration() const; // This method evaluates the expression and returns an // equivalent expression that is reduced as far as compile @@ -1903,12 +1903,12 @@ class NetEConstEnum : public NetEConst { public: explicit NetEConstEnum(NetScope*scope, perm_string name, - netenum_t*enum_set, const verinum&val); + const netenum_t*enum_set, const verinum&val); ~NetEConstEnum(); perm_string name() const; const NetScope*scope() const; - netenum_t*enumeration() const; + const netenum_t*enumeration() const; virtual void expr_scan(struct expr_scan_t*) const; virtual void dump(ostream&) const; @@ -1917,7 +1917,7 @@ class NetEConstEnum : public NetEConst { private: NetScope*scope_; - netenum_t*enum_set_; + const netenum_t*enum_set_; perm_string name_; }; @@ -2496,7 +2496,7 @@ class NetAssign_ { // Return the enumeration type of this l-value, or nil if it's // not an enumeration. - netenum_t*enumeration() const; + const netenum_t*enumeration() const; // Get the name of the underlying object. perm_string name() const; @@ -3916,10 +3916,10 @@ class NetEEvent : public NetExpr { class NetENetenum : public NetExpr { public: - NetENetenum(netenum_t*); + NetENetenum(const netenum_t*); ~NetENetenum(); - netenum_t* netenum() const; + const netenum_t* netenum() const; virtual void expr_scan(struct expr_scan_t*) const; virtual NetENetenum* dup_expr() const; @@ -3928,7 +3928,7 @@ class NetENetenum : public NetExpr { virtual void dump(ostream&os) const; private: - netenum_t*netenum_; + const netenum_t*netenum_; }; class NetENew : public NetExpr { @@ -4032,7 +4032,7 @@ class NetESFunc : public NetExpr { NetESFunc(const char*name, ivl_variable_type_t t, unsigned width, unsigned nprms); NetESFunc(const char*name, ivl_type_t rtype, unsigned nprms); - NetESFunc(const char*name, netenum_t*enum_type, unsigned nprms); + NetESFunc(const char*name, const netenum_t*enum_type, unsigned nprms); ~NetESFunc(); const char* name() const; @@ -4048,7 +4048,7 @@ class NetESFunc : public NetExpr { virtual ivl_variable_type_t expr_type() const; virtual NexusSet* nex_input(bool rem_out = true); - virtual netenum_t* enumeration() const; + virtual const netenum_t* enumeration() const; virtual void dump(ostream&) const; virtual void expr_scan(struct expr_scan_t*) const; @@ -4073,7 +4073,7 @@ class NetESFunc : public NetExpr { const char* name_; ivl_variable_type_t type_; - netenum_t*enum_type_; + const netenum_t*enum_type_; std::vectorparms_; ID built_in_id_() const; @@ -4252,7 +4252,7 @@ class NetESignal : public NetExpr { virtual NetESignal* dup_expr() const; NetNet* synthesize(Design*des, NetScope*scope, NetExpr*root); NexusSet* nex_input(bool rem_out = true); - netenum_t*enumeration() const; + const netenum_t*enumeration() const; virtual NetExpr*evaluate_function(const LineInfo&loc, map&ctx) const; @@ -4277,7 +4277,7 @@ class NetESignal : public NetExpr { private: NetNet*net_; - netenum_t*enum_type_; + const netenum_t*enum_type_; // Expression to select a word from the net. NetExpr*word_; }; diff --git a/parse.y b/parse.y index 53cf517a0..ff2700f10 100644 --- a/parse.y +++ b/parse.y @@ -385,8 +385,6 @@ static void current_function_set_statement(const YYLTYPE&loc, vector Statement*statement; vector*statement_list; - PTaskFuncArg function_type; - net_decl_assign_t*net_decl_assign; enum_type_t*enum_type; @@ -596,7 +594,6 @@ static void current_function_set_statement(const YYLTYPE&loc, vector %type integer_vector_type %type parameter_value_opt -%type function_range_or_type_opt %type event_expression_list %type event_expression %type event_control @@ -761,27 +758,36 @@ class_items /* IEEE1800-2005: A.1.2 */ class_item /* IEEE1800-2005: A.1.8 */ /* IEEE1800 A.1.8: class_constructor_declaration */ - : method_qualifier_opt K_function K_new '(' tf_port_list_opt ')' ';' + : method_qualifier_opt K_function K_new + { assert(current_function==0); + current_function = pform_push_constructor_scope(@3); + } + '(' tf_port_list_opt ')' ';' function_item_list_opt statement_or_null_list_opt K_endfunction endnew_opt - { yyerror(@3, "sorry: Class constructors not supported yet."); - yyerrok; + { current_function->set_ports($6); + pform_set_constructor_return(current_function); + pform_set_this_class(@3, current_function); + current_function_set_statement($10? @10 : @3, $10); + pform_pop_scope(); + current_function = 0; } /* IEEE1800 A.1.8: class_constructor_declaration with a call to parent constructor. Note that the implicit_class_handle must be K_super ("this.new" makes little sense) but that would cause a conflict. */ +/* XXXX | method_qualifier_opt K_function K_new '(' tf_port_list_opt ')' ';' function_item_list_opt attribute_list_opt implicit_class_handle '.' K_new '(' expression_list_with_nuls ')' statement_or_null_list_opt K_endfunction endnew_opt - { yyerror(@3, "sorry: Class constructors not supported yet."); + { yyerror(@3, "sorry: Class constructors with parent not supported yet."); yyerrok; } - +*/ /* Class properties... */ | property_qualifier_opt data_type list_of_variable_decl_assignments ';' @@ -934,6 +940,19 @@ data_type /* IEEE1800-2005: A.2.2.1 */ FILE_NAME(tmp, @1); $$ = tmp; } + | K_integer signed_unsigned_opt + { list*pd = make_range_from_width(integer_width); + vector_type_t*tmp = new vector_type_t(IVL_VT_LOGIC, $2, pd); + tmp->reg_flag = true; + tmp->integer_flag = true; + $$ = tmp; + } + | K_time + { list*pd = make_range_from_width(64); + vector_type_t*tmp = new vector_type_t(IVL_VT_LOGIC, true, pd); + tmp->reg_flag = true; + $$ = tmp; + } | TYPE_IDENTIFIER range_opt { if ($2) $$ = new parray_type_t($1, $2); else $$ = $1; @@ -1045,7 +1064,7 @@ for_step /* IEEE1800-2005: A.6.8 */ definitions in the func_body to take on the scope of the function instead of the module. */ function_declaration /* IEEE1800-2005: A.2.6 */ - : K_function K_automatic_opt function_range_or_type_opt IDENTIFIER ';' + : K_function K_automatic_opt data_type_or_implicit IDENTIFIER ';' { assert(current_function == 0); current_function = pform_push_function_scope(@1, $4, $2); } @@ -1070,7 +1089,7 @@ function_declaration /* IEEE1800-2005: A.2.6 */ if ($11) delete[]$11; } - | K_function K_automatic_opt function_range_or_type_opt IDENTIFIER + | K_function K_automatic_opt data_type_or_implicit IDENTIFIER { assert(current_function == 0); current_function = pform_push_function_scope(@1, $4, $2); } @@ -1102,7 +1121,7 @@ function_declaration /* IEEE1800-2005: A.2.6 */ /* Detect and recover from some errors. */ - | K_function K_automatic_opt function_range_or_type_opt IDENTIFIER error K_endfunction + | K_function K_automatic_opt data_type_or_implicit IDENTIFIER error K_endfunction { /* */ if (current_function) { pform_pop_scope(); @@ -1705,58 +1724,7 @@ tf_port_declaration /* IEEE1800-2005: A.2.7 */ tf_port_item /* IEEE1800-2005: A.2.7 */ - /* Ports can be integer with a width of [31:0]. */ - - : port_direction_opt K_integer IDENTIFIER range_opt tf_port_item_expr_opt - { list*range_stub = make_range_from_width(integer_width); - NetNet::PortType use_port_type = $1==NetNet::PIMPLICIT? NetNet::PINPUT : $1; - - port_declaration_context.port_type = use_port_type; - port_declaration_context.var_type = IVL_VT_LOGIC; - port_declaration_context.sign_flag = true; - delete port_declaration_context.range; - port_declaration_context.range = copy_range(range_stub); - vector*tmp = pform_make_task_ports(@3, use_port_type, - IVL_VT_LOGIC, true, - range_stub, - list_from_identifier($3), true); - $$ = tmp; - if ($4) { - yyerror(@4, "sorry: Port variable dimensions not supported yet."); - delete $4; - } - if ($5) { - yyerror(@5, "sorry: Port default expressions not supported yet."); - delete $5; - } - } - - /* Ports can be time with a width of [63:0] (unsigned). */ - - | port_direction_opt K_time IDENTIFIER range_opt tf_port_item_expr_opt - { list*range_stub = make_range_from_width(64); - NetNet::PortType use_port_type = $1==NetNet::PIMPLICIT? NetNet::PINPUT : $1; - - port_declaration_context.port_type = use_port_type; - port_declaration_context.var_type = IVL_VT_LOGIC; - port_declaration_context.sign_flag = false; - delete port_declaration_context.range; - port_declaration_context.range = copy_range(range_stub); - vector*tmp = pform_make_task_ports(@3, use_port_type, IVL_VT_LOGIC, - false, range_stub, - list_from_identifier($3)); - $$ = tmp; - if ($4) { - yyerror(@4, "sorry: Port variable dimensions not supported yet."); - delete $4; - } - if ($5) { - yyerror(@5, "sorry: Port default expressions not supported yet."); - delete $5; - } - } - - | port_direction_opt data_type_or_implicit IDENTIFIER range_opt tf_port_item_expr_opt + : port_direction_opt data_type_or_implicit IDENTIFIER range_opt tf_port_item_expr_opt { vector*tmp; NetNet::PortType use_port_type = $1==NetNet::PIMPLICIT? NetNet::PINPUT : $1; list* ilist = list_from_identifier($3); @@ -1987,22 +1955,10 @@ attribute block_item_decl - /* Integer atom declarations are simpler in that they do not have - all the trappings of a general variable declaration. All of that - is implicit in the "integer" of the declaration. */ - - : K_integer signed_unsigned_opt register_variable_list ';' - { pform_set_reg_integer($3, attributes_in_context); - } - - | K_time register_variable_list ';' - { pform_set_reg_time($2, attributes_in_context); - } - /* variable declarations. Note that data_type can be 0 if we are recovering from an error. */ - | data_type register_variable_list ';' + : data_type register_variable_list ';' { if ($1) pform_set_data_type(@1, $1, $2, NetNet::REG, attributes_in_context); } @@ -5006,42 +4962,6 @@ dimensions } ; - /* This is used to express the return type of a function. This is - not quite right, and should be replaced with a variant that uses - the data_type rule. This will get us by for now. */ -function_range_or_type_opt - : unsigned_signed_opt range_opt - { /* the default type is reg unsigned and no range */ - $$.type = PTF_REG; - $$.range = $2; - if ($1) - $$.type = PTF_REG_S; - } - | K_reg unsigned_signed_opt range_opt - { /* the default type is reg unsigned and no range */ - $$.type = PTF_REG; - $$.range = $3; - if ($2) - $$.type = PTF_REG_S; - } - | bit_logic unsigned_signed_opt range_opt - { /* the default type is bit/logic unsigned and no range */ - $$.type = PTF_REG; - $$.range = $3; - if ($2) - $$.type = PTF_REG_S; - } - | K_integer { $$.range = 0; $$.type = PTF_INTEGER; } - | K_real { $$.range = 0; $$.type = PTF_REAL; } - | K_realtime { $$.range = 0; $$.type = PTF_REALTIME; } - | K_string { $$.range = 0; $$.type = PTF_STRING; } - | K_time { $$.range = 0; $$.type = PTF_TIME; } - | K_void { $$.range = 0; $$.type = PTF_VOID; } - | atom2_type { $$.range = make_range_from_width($1); $$.type = PTF_ATOM2_S; } - | atom2_type K_signed { $$.range = make_range_from_width($1); $$.type = PTF_ATOM2_S; } - | atom2_type K_unsigned { $$.range = make_range_from_width($1); $$.type = PTF_ATOM2; } - ; - /* The register_variable rule is matched only when I am parsing variables in a "reg" definition. I therefore know that I am creating registers and I do not need to let the containing rule diff --git a/pform.cc b/pform.cc index e817fb6cf..786a3d343 100644 --- a/pform.cc +++ b/pform.cc @@ -368,7 +368,7 @@ PTask* pform_push_task_scope(const struct vlltype&loc, char*name, bool is_auto) return task; } -PFunction* pform_push_function_scope(const struct vlltype&loc, char*name, +PFunction* pform_push_function_scope(const struct vlltype&loc, const char*name, bool is_auto) { perm_string func_name = lex_strings.make(name); @@ -2932,57 +2932,6 @@ void pform_set_port_type(const struct vlltype&li, delete range; } -static void pform_set_reg_integer(perm_string name, list*attr) -{ - PWire*cur = pform_get_make_wire_in_scope(name, NetNet::INTEGER, NetNet::NOT_A_PORT, IVL_VT_LOGIC); - assert(cur); - - pform_range_t rng; - rng.first = new PENumber(new verinum(integer_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); - cur->set_signed(true); - - pform_bind_attributes(cur->attributes, attr, true); -} - -void pform_set_reg_integer(list*names, list*attr) -{ - for (list::iterator cur = names->begin() - ; cur != names->end() ; ++ cur ) { - perm_string txt = *cur; - pform_set_reg_integer(txt, attr); - } - delete names; -} - -static void pform_set_reg_time(perm_string name, list*attr) -{ - PWire*cur = pform_get_make_wire_in_scope(name, NetNet::REG, NetNet::NOT_A_PORT, IVL_VT_LOGIC); - assert(cur); - - pform_range_t rng; - rng.first = new PENumber(new verinum(TIME_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); - - pform_bind_attributes(cur->attributes, attr, true); -} - -void pform_set_reg_time(list*names, list*attr) -{ - for (list::iterator cur = names->begin() - ; cur != names->end() ; ++ cur ) { - perm_string txt = *cur; - pform_set_reg_time(txt, attr); - } - delete names; -} - static void pform_set_integer_2atom(uint64_t width, bool signed_flag, perm_string name, NetNet::Type net_type, list*attr) { PWire*cur = pform_get_make_wire_in_scope(name, net_type, NetNet::NOT_A_PORT, IVL_VT_BOOL); @@ -3101,6 +3050,9 @@ void pform_set_data_type(const struct vlltype&li, data_type_t*data_type, list (data_type)) { + if (net_type==NetNet::REG && vec_type->integer_flag) + net_type=NetNet::INTEGER; + pform_set_net_range(names, vec_type->pdims.get(), vec_type->signed_flag, vec_type->base_type, net_type, attr); diff --git a/pform.h b/pform.h index 20d039bc7..c7457c5b9 100644 --- a/pform.h +++ b/pform.h @@ -187,6 +187,7 @@ extern void pform_class_property(const struct vlltype&loc, data_type_t*data_type, std::list*decls); extern void pform_set_this_class(const struct vlltype&loc, PTaskFunc*net); +extern void pform_set_constructor_return(PFunction*net); extern void pform_end_class_declaration(void); @@ -232,10 +233,11 @@ extern void pform_pop_scope(); extern LexicalScope* pform_peek_scope(); extern PClass* pform_push_class_scope(const struct vlltype&loc, perm_string name); +extern PFunction*pform_push_constructor_scope(const struct vlltype&loc); extern PPackage* pform_push_package_scope(const struct vlltype&loc, perm_string name); extern PTask*pform_push_task_scope(const struct vlltype&loc, char*name, bool is_auto); -extern PFunction*pform_push_function_scope(const struct vlltype&loc, char*name, +extern PFunction*pform_push_function_scope(const struct vlltype&loc, const char*name, bool is_auto); extern PBlock*pform_push_block_scope(char*name, PBlock::BL_TYPE tt); @@ -342,8 +344,6 @@ extern void pform_set_port_type(const struct vlltype&li, extern void pform_set_reg_idx(perm_string name, std::list*indices); -extern void pform_set_reg_integer(list*names, list*attr); -extern void pform_set_reg_time(list*names, list*attr); extern void pform_set_data_type(const struct vlltype&li, data_type_t*, list*names, NetNet::Type net_type, list*attr); diff --git a/pform_dump.cc b/pform_dump.cc index 7d6e9d67f..eaca892a5 100644 --- a/pform_dump.cc +++ b/pform_dump.cc @@ -423,6 +423,13 @@ void PWire::dump(ostream&out, unsigned ind) const out << " signed"; } + if (get_isint()) { + out << " integer"; + } + if (set_data_type_) { + out << " set_data_type_=" << typeid(*set_data_type_).name(); + } + if (discipline_) { out << " discipline<" << discipline_->name() << ">"; } @@ -867,47 +874,12 @@ void PForStatement::dump(ostream&out, unsigned ind) const void PFunction::dump(ostream&out, unsigned ind) const { out << setw(ind) << "" << "function "; - if (is_auto_) cout << "automatic "; - switch (return_type_.type) { - case PTF_NONE: - out << "?none? "; - break; - case PTF_REG: - out << "reg "; - break; - case PTF_REG_S: - out << "reg_s "; - break; - case PTF_INTEGER: - out << "integer "; - break; - case PTF_REAL: - out << "real "; - break; - case PTF_REALTIME: - out << "realtime "; - break; - case PTF_TIME: - out << "time "; - break; - case PTF_ATOM2: - out << "int unsigned "; - break; - case PTF_ATOM2_S: - out << "int signed "; - break; - case PTF_STRING: - out << "string "; - break; - case PTF_VOID: - out << "void "; - break; - } + if (is_auto_) out << "automatic..."; - if (return_type_.range) { - out << "["; - out << "] "; - } + if (return_type_) + return_type_->pform_dump(out, ind+8); + else + out << setw(ind+8) << "" << "" << endl; out << pscope_name() << ";" << endl; if (method_of()) @@ -944,7 +916,7 @@ void PRepeat::dump(ostream&out, unsigned ind) const void PTask::dump(ostream&out, unsigned ind) const { out << setw(ind) << "" << "task "; - if (is_auto_) cout << "automatic "; + if (is_auto_) out << "automatic "; out << pscope_name() << ";" << endl; if (method_of()) out << setw(ind) << "" << "method of " << method_of()->name << ";" << endl; diff --git a/pform_pclass.cc b/pform_pclass.cc index e340d5b8c..f21479659 100644 --- a/pform_pclass.cc +++ b/pform_pclass.cc @@ -91,6 +91,22 @@ void pform_set_this_class(const struct vlltype&loc, PTaskFunc*net) net->set_this(pform_cur_class->type, this_wire); } +void pform_set_constructor_return(PFunction*net) +{ + assert(pform_cur_class); + net->set_return(pform_cur_class->type); +} + +/* + * A constructor is basically a function with special implications. + */ +PFunction*pform_push_constructor_scope(const struct vlltype&loc) +{ + assert(pform_cur_class); + PFunction*func = pform_push_function_scope(loc, "new", true); + return func; +} + void pform_end_class_declaration(void) { assert(pform_cur_class); diff --git a/pform_types.h b/pform_types.h index 3de4bf83a..e99b966fc 100644 --- a/pform_types.h +++ b/pform_types.h @@ -144,12 +144,14 @@ struct atom2_type_t : public data_type_t { struct vector_type_t : public data_type_t { inline explicit vector_type_t(ivl_variable_type_t bt, bool sf, std::list*pd) - : base_type(bt), signed_flag(sf), reg_flag(false), implicit_flag(false), pdims(pd) { } + : base_type(bt), signed_flag(sf), reg_flag(false), integer_flag(false), implicit_flag(false), pdims(pd) { } virtual ivl_variable_type_t figure_packed_base_type(void)const; + ivl_type_s* elaborate_type(Design*des, NetScope*scope) const; ivl_variable_type_t base_type; bool signed_flag; bool reg_flag; // True if "reg" was used + bool integer_flag; // True if "integer" was used bool implicit_flag; // True if this type is implicitly logic/reg std::auto_ptr< list > pdims; }; diff --git a/scripts/devel-stub.sh b/scripts/devel-stub.sh index e39315b3b..3f26a56aa 100644 --- a/scripts/devel-stub.sh +++ b/scripts/devel-stub.sh @@ -11,4 +11,4 @@ ./ivl -v -Ctgt-stub/stub.conf -C./scripts/devel-stub.conf -Pa.pf -Na.net -fDLL=tgt-stub/stub.tgt foo.vl |& tee foo.log -echo "*** ivl command completed, rc=$?" +echo "*** ivl command completed" diff --git a/tgt-stub/stub.c b/tgt-stub/stub.c index b6173a00f..c68c885ff 100644 --- a/tgt-stub/stub.c +++ b/tgt-stub/stub.c @@ -1232,6 +1232,8 @@ static void show_signal(ivl_signal_t net) switch (ivl_signal_type(net)) { case IVL_SIT_REG: type = "reg"; + if (ivl_signal_integer(net)) + type = "integer"; break; case IVL_SIT_TRI: type = "tri"; @@ -1351,6 +1353,11 @@ static void show_signal(ivl_signal_t net) default: break; } + + if (ivl_signal_integer(net) && ivl_signal_type(net)!=IVL_SIT_REG) { + fprintf(out, " ERROR: integers must be IVL_SIT_REG\n"); + stub_errors += 1; + } } void test_expr_is_delay(ivl_expr_t expr)