Fix internal error elaborating types used in different scopes

Some types, i.e. vector types with parameterized dimensions,
may have different elaboration results in different scopes.
Handle those cases in the elaboration caches.
This commit is contained in:
Stephen Williams 2014-04-24 18:36:49 -07:00
parent 5893d13ea3
commit ec0c66ff25
7 changed files with 75 additions and 23 deletions

View File

@ -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<netrange_t> 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);

View File

@ -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<NetScope*,ivl_type_s*>::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<NetScope*,ivl_type_s*>(scope, tmp));
return tmp;
}
ivl_type_s* data_type_t::elaborate_type_raw(Design*des, NetScope*) const
{
cerr << get_fileline() << ": internal error: "

View File

@ -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) {

View File

@ -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<pform_range_t>::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;

View File

@ -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()
{
}

View File

@ -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<NetScope*,ivl_type_s*> 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<pform_range_t>*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;

View File

@ -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;
}