diff --git a/elab_sig.cc b/elab_sig.cc index e1b472db2..490d39401 100644 --- a/elab_sig.cc +++ b/elab_sig.cc @@ -1245,9 +1245,10 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const } else if (netdarray) { if (debug_elaborate) { - cerr << get_fileline() << ": debug: Create signal " << wtype - << " dynamic array " - << name_ << " in scope " << scope_path(scope) << endl; + cerr << get_fileline() << ": PWire::elaborate_sig: " + << "Create signal " << wtype + << " dynamic array " << name_ + << " in scope " << scope_path(scope) << endl; } ivl_assert(*this, packed_dimensions.empty()); diff --git a/netlist.cc b/netlist.cc index 31f5265cb..6dc0b5bd2 100644 --- a/netlist.cc +++ b/netlist.cc @@ -224,7 +224,7 @@ void NetPins::set_default_dir(Link::DIR d) default_dir_ = d; } -bool NetPins::is_linked(void) +bool NetPins::is_linked(void) const { bool linked_flag = false; if (pins_ == NULL) return false; diff --git a/netlist.h b/netlist.h index 202153830..8ab6ca2a3 100644 --- a/netlist.h +++ b/netlist.h @@ -215,7 +215,7 @@ class NetPins : public LineInfo { void dump_node_pins(ostream&, unsigned, const char**pin_names =0) const; void set_default_dir(Link::DIR d); - bool is_linked(); + bool is_linked() const; bool pins_are_virtual(void) const; void devirtualize_pins(void); diff --git a/t-dll-proc.cc b/t-dll-proc.cc index ca61064e3..a8ff2f05a 100644 --- a/t-dll-proc.cc +++ b/t-dll-proc.cc @@ -915,12 +915,10 @@ bool dll_target::proc_wait(const NetEvWait*net) break; } - for (unsigned bit = 0 - ; bit < pr->pin_count() - ; bit += 1) { + for (unsigned bit = 0; bit < pr->pin_count(); bit += 1) { ivl_nexus_t nex = (ivl_nexus_t) pr->pin(bit).nexus()->t_cookie(); - assert(nex); + ivl_assert(*ev, nex); ev_tmp->pins[base+bit] = nex; } } diff --git a/t-dll.cc b/t-dll.cc index 8e7b1e5da..779fcb9a5 100644 --- a/t-dll.cc +++ b/t-dll.cc @@ -2599,7 +2599,6 @@ void dll_target::signal(const NetNet*net) obj->discipline = net->get_discipline(); obj->array_dimensions_ = net->unpacked_dimensions(); - assert(obj->array_dimensions_ == net->unpacked_dimensions()); switch (net->port_type()) { @@ -2679,6 +2678,18 @@ void dll_target::signal(const NetNet*net) obj->nattr = net->attr_cnt(); obj->attr = fill_in_attributes(net); + // Special case: IVL_VT_QUEUE objects don't normally show up in the + // network, but can in certain special cases. In these cases, it is the + // object itself and not the array elements that is in the network. of + // course, only do this if there is at least one link to this signal. + if (obj->net_type->base_type()==IVL_VT_QUEUE && net->is_linked()) { + const Nexus*nex = net->pin(0).nexus(); + ivl_nexus_t tmp = nexus_sig_make(obj, 0); + tmp->nexus_ = nex; + tmp->name_ = 0; + nex->t_cookie(tmp); + } + /* 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/tgt-stub/expression.c b/tgt-stub/expression.c index cd133baf7..569c7e6e4 100644 --- a/tgt-stub/expression.c +++ b/tgt-stub/expression.c @@ -326,11 +326,19 @@ static void show_signal_expression(ivl_expr_t net, unsigned ind) ivl_expr_t word = ivl_expr_oper1(net); ivl_signal_t sig = ivl_expr_signal(net); - const char*vt_sig = data_type_string(ivl_signal_data_type(sig)); + ivl_variable_type_t data_type = ivl_signal_data_type(sig); + const char*vt_sig = data_type_string(data_type); unsigned dimensions = ivl_signal_dimensions(sig); unsigned word_count = ivl_signal_array_count(sig); - if (dimensions == 0 && word_count != 1) { + if (data_type==IVL_VT_QUEUE) { + if (dimensions != 0) { + fprintf(out, "%*sERROR: Queue objects expect dimensions==0, got %u.\n", + ind, "", dimensions); + stub_errors += 1; + } + + } else if (dimensions == 0 && word_count != 1) { fprintf(out, "%*sERROR: Word count = %u for non-array object\n", ind, "", word_count); stub_errors += 1; @@ -353,7 +361,7 @@ static void show_signal_expression(ivl_expr_t net, unsigned ind) /* 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) { + if (dimensions == 0 && data_type!=IVL_VT_QUEUE && 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; diff --git a/vvp/event.cc b/vvp/event.cc index f070d8db5..eb1361614 100644 --- a/vvp/event.cc +++ b/vvp/event.cc @@ -627,6 +627,18 @@ void vvp_fun_anyedge_sa::recv_string(vvp_net_ptr_t port, const std::string&bit, } } +/* + * An anyedge receiving an object should do nothing with it, but should + * trigger waiting threads. + */ +void vvp_fun_anyedge_sa::recv_object(vvp_net_ptr_t port, vvp_object_t bit, + vvp_context_t) +{ + run_waiting_threads_(threads_); + vvp_net_t*net = port.ptr(); + net->send_vec4(vvp_vector4_t(), 0); +} + vvp_fun_anyedge_aa::vvp_fun_anyedge_aa() { context_scope_ = vpip_peek_context_scope(); diff --git a/vvp/event.h b/vvp/event.h index 5fa249732..d439c43f8 100644 --- a/vvp/event.h +++ b/vvp/event.h @@ -264,6 +264,8 @@ class vvp_fun_anyedge_sa : public vvp_fun_anyedge { void recv_string(vvp_net_ptr_t port, const std::string&bit, vvp_context_t context); + void recv_object(vvp_net_ptr_t port, vvp_object_t bit, + vvp_context_t context); private: vthread_t threads_;