diff --git a/elab_sig.cc b/elab_sig.cc index 2d6fdcf9b..980e198b1 100644 --- a/elab_sig.cc +++ b/elab_sig.cc @@ -563,7 +563,7 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const // Special case: this is a constructor, so the return // signal is also the first argument. For example, the // source code for the definition may be: - // function new(...); + // function new(...); // endfunction // In this case, the "@" port is the synthetic "this" // argument and we also use it as a return value at the @@ -594,6 +594,11 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const } if (ret_type) { + if (debug_elaborate) { + cerr << get_fileline() << ": PFunction::elaborate_sig: " + << "return type: " << *ret_type << endl; + return_type_->pform_dump(cerr, 8); + } list ret_unpacked; ret_sig = new NetNet(scope, fname, NetNet::REG, ret_unpacked, ret_type); @@ -615,9 +620,10 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const NetFuncDef*def = new NetFuncDef(scope, ret_sig, ports, pdef); if (debug_elaborate) - cerr << get_fileline() << ": debug: " - << "Attach function definition to scope " - << scope_path(scope) << "." << endl; + cerr << get_fileline() << ": PFunction::elaborate_sig: " + << "Attach function definition " << scope_path(scope) + << " with ret_sig width=" << (ret_sig? ret_sig->vector_width() : 0) + << "." << endl; scope->set_func_def(def); diff --git a/elab_type.cc b/elab_type.cc index c4c97eaa7..1167c1902 100644 --- a/elab_type.cc +++ b/elab_type.cc @@ -31,6 +31,21 @@ using namespace std; +/* + * Elaborations of types may vary depending on the scope that it is + * done in, so keep a per-scope cache of the results. + */ +ivl_type_s* data_type_t::elaborate_type(Design*des, NetScope*scope) +{ + map::iterator pos = cache_type_elaborate_.lower_bound(scope); + if (pos->first == scope) + return pos->second; + + ivl_type_s*tmp = elaborate_type_raw(des, scope); + cache_type_elaborate_.insert(pos, pair(scope, tmp)); + return tmp; +} + ivl_type_s* data_type_t::elaborate_type_raw(Design*des, NetScope*) const { cerr << get_fileline() << ": internal error: " diff --git a/expr_synth.cc b/expr_synth.cc index 89242ec9b..8812f23f0 100644 --- a/expr_synth.cc +++ b/expr_synth.cc @@ -1440,6 +1440,12 @@ NetNet* NetEUFunc::synthesize(Design*des, NetScope*scope, NetExpr*root) osig->local_flag(true); connect(net->pin(0), osig->pin(0)); + if (debug_synth2) { + cerr << get_fileline() << ": NetEUFunc::synthesize: " + << "result_sig_->vector_width()=" << result_sig_->vector_width() + << ", osig->vector_width()=" << osig->vector_width() << endl; + } + /* Connect the pins to the arguments. */ NetFuncDef*def = func_->func_def(); for (unsigned idx = 0; idx < eparms.size(); idx += 1) { diff --git a/pform_dump.cc b/pform_dump.cc index a8b08c04b..65fcdbfe4 100644 --- a/pform_dump.cc +++ b/pform_dump.cc @@ -160,13 +160,6 @@ void parray_type_t::pform_dump(ostream&out, unsigned indent) const base_type->pform_dump(out, indent+4); } -void uarray_type_t::pform_dump(ostream&out, unsigned indent) const -{ - out << setw(indent) << "" << "Unpacked array " << "[...]" - << " of:" << endl; - 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") @@ -181,6 +174,23 @@ void struct_type_t::pform_dump(ostream&out, unsigned indent) const } } +void uarray_type_t::pform_dump(ostream&out, unsigned indent) const +{ + out << setw(indent) << "" << "Unpacked array " << "[...]" + << " of:" << endl; + base_type->pform_dump(out, indent+4); +} + +void vector_type_t::pform_dump(ostream&fd, unsigned indent) const +{ + fd << setw(indent) << "" << "vector of " << base_type; + for (list::iterator cur = pdims->begin() + ; cur != pdims->end() ; ++cur) { + fd << "[" << *(cur->first) << ":" << *(cur->second) << "]"; + } + fd << endl; +} + void class_type_t::pform_dump(ostream&out, unsigned indent) const { out << setw(indent) << "" << "class " << name; diff --git a/pform_types.cc b/pform_types.cc index c809ffbf6..5a7868bef 100644 --- a/pform_types.cc +++ b/pform_types.cc @@ -24,15 +24,6 @@ data_type_t::~data_type_t() { } -ivl_type_s* data_type_t::elaborate_type(Design*des, NetScope*scope) -{ - if (cache_type_elaborate_) - return cache_type_elaborate_; - - cache_type_elaborate_ = elaborate_type_raw(des, scope); - return cache_type_elaborate_; -} - string_type_t::~string_type_t() { } diff --git a/pform_types.h b/pform_types.h index 32758f5e4..97149dcb4 100644 --- a/pform_types.h +++ b/pform_types.h @@ -88,7 +88,7 @@ struct pform_tf_port_t { */ class data_type_t : public LineInfo { public: - inline explicit data_type_t() : cache_type_elaborate_(0) { } + inline explicit data_type_t() { } virtual ~data_type_t() = 0; // This method is used to figure out the base type of a packed // compound object. Return IVL_VT_NO_TYPE if the type is not packed. @@ -102,7 +102,8 @@ class data_type_t : public LineInfo { // Elaborate the type to an ivl_type_s type. virtual ivl_type_s* elaborate_type_raw(Design*des, NetScope*scope) const; - ivl_type_s*cache_type_elaborate_; + // Keep per-scope elaboration results cached. + std::map cache_type_elaborate_; }; struct void_type_t : public data_type_t { @@ -175,6 +176,7 @@ struct vector_type_t : public data_type_t { std::list*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; + virtual void pform_dump(std::ostream&out, unsigned indent) const; ivl_type_s* elaborate_type_raw(Design*des, NetScope*scope) const; ivl_variable_type_t base_type; diff --git a/synth2.cc b/synth2.cc index ad3c7ddc3..560d553f6 100644 --- a/synth2.cc +++ b/synth2.cc @@ -89,6 +89,8 @@ bool NetAssignBase::synth_async(Design*des, NetScope*scope, << "r-value signal is " << rsig->vector_width() << " bits." << endl; cerr << get_fileline() << ": NetAssignBase::synth_async: " << "lval_->lwidth()=" << lval_->lwidth() << endl; + cerr << get_fileline() << ": NetAssignBase::synth_async: " + << "lsig = " << scope_path(scope) << "." << lsig->name() << endl; if (const NetExpr*base = lval_->get_base()) { cerr << get_fileline() << ": NetAssignBase::synth_async: " << "base_=" << *base << endl; @@ -450,6 +452,12 @@ bool NetCondit::synth_async(Design*des, NetScope*scope, connect(bsig.pin(idx), accumulated_nex_out.pin(idx)); accumulated_nex_out.pin(idx).unlink(); } + + if (debug_synth2) { + cerr << get_fileline() << ": NetCondit::synth_async: " + << "synthesize else clause at " << else_->get_fileline() + << " is done." << endl; + } } ivl_assert(*this, nex_out.pin_count()==asig.pin_count()); @@ -470,9 +478,23 @@ bool NetCondit::synth_async(Design*des, NetScope*scope, cerr << get_fileline() << ": internal error: " << "NetCondit::synth_async: " << "Mux input sizes do not match." - << "A size=" << mux_width + << " A size=" << mux_width << ", B size=" << bsig.pin(idx).nexus()->vector_width() << endl; + cerr << get_fileline() << ": : " + << "asig node pins:" << endl; + asig.dump_node_pins(cerr, 8); + cerr << get_fileline() << ": : " + << "if_ statement:" << endl; + if_->dump(cerr, 8); + cerr << get_fileline() << ": : " + << "bsig node pins:" << endl; + bsig.dump_node_pins(cerr, 4); + if (else_) { + cerr << get_fileline() << ": : " + << "else_ statement:" << endl; + else_->dump(cerr, 8); + } rc_flag = false; }