Merge pull request #424 from steveicarus/steveicarus/br412

Handle dynamic queue objects in event context
This commit is contained in:
Stephen Williams 2020-12-13 20:18:32 -08:00 committed by GitHub
commit e589d6f59a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 45 additions and 13 deletions

View File

@ -1245,9 +1245,10 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
} else if (netdarray) { } else if (netdarray) {
if (debug_elaborate) { if (debug_elaborate) {
cerr << get_fileline() << ": debug: Create signal " << wtype cerr << get_fileline() << ": PWire::elaborate_sig: "
<< " dynamic array " << "Create signal " << wtype
<< name_ << " in scope " << scope_path(scope) << endl; << " dynamic array " << name_
<< " in scope " << scope_path(scope) << endl;
} }
ivl_assert(*this, packed_dimensions.empty()); ivl_assert(*this, packed_dimensions.empty());

View File

@ -224,7 +224,7 @@ void NetPins::set_default_dir(Link::DIR d)
default_dir_ = d; default_dir_ = d;
} }
bool NetPins::is_linked(void) bool NetPins::is_linked(void) const
{ {
bool linked_flag = false; bool linked_flag = false;
if (pins_ == NULL) return false; if (pins_ == NULL) return false;

View File

@ -215,7 +215,7 @@ class NetPins : public LineInfo {
void dump_node_pins(ostream&, unsigned, const char**pin_names =0) const; void dump_node_pins(ostream&, unsigned, const char**pin_names =0) const;
void set_default_dir(Link::DIR d); void set_default_dir(Link::DIR d);
bool is_linked(); bool is_linked() const;
bool pins_are_virtual(void) const; bool pins_are_virtual(void) const;
void devirtualize_pins(void); void devirtualize_pins(void);

View File

@ -915,12 +915,10 @@ bool dll_target::proc_wait(const NetEvWait*net)
break; break;
} }
for (unsigned bit = 0 for (unsigned bit = 0; bit < pr->pin_count(); bit += 1) {
; bit < pr->pin_count()
; bit += 1) {
ivl_nexus_t nex = (ivl_nexus_t) ivl_nexus_t nex = (ivl_nexus_t)
pr->pin(bit).nexus()->t_cookie(); pr->pin(bit).nexus()->t_cookie();
assert(nex); ivl_assert(*ev, nex);
ev_tmp->pins[base+bit] = nex; ev_tmp->pins[base+bit] = nex;
} }
} }

View File

@ -2599,7 +2599,6 @@ void dll_target::signal(const NetNet*net)
obj->discipline = net->get_discipline(); obj->discipline = net->get_discipline();
obj->array_dimensions_ = net->unpacked_dimensions(); obj->array_dimensions_ = net->unpacked_dimensions();
assert(obj->array_dimensions_ == net->unpacked_dimensions());
switch (net->port_type()) { switch (net->port_type()) {
@ -2679,6 +2678,18 @@ void dll_target::signal(const NetNet*net)
obj->nattr = net->attr_cnt(); obj->nattr = net->attr_cnt();
obj->attr = fill_in_attributes(net); 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 /* Get the nexus objects for all the pins of the signal. If
the signal has only one pin, then write the single the signal has only one pin, then write the single
ivl_nexus_t object into n.pin_. Otherwise, make an array of ivl_nexus_t object into n.pin_. Otherwise, make an array of

View File

@ -326,11 +326,19 @@ static void show_signal_expression(ivl_expr_t net, unsigned ind)
ivl_expr_t word = ivl_expr_oper1(net); ivl_expr_t word = ivl_expr_oper1(net);
ivl_signal_t sig = ivl_expr_signal(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 dimensions = ivl_signal_dimensions(sig);
unsigned word_count = ivl_signal_array_count(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", fprintf(out, "%*sERROR: Word count = %u for non-array object\n",
ind, "", word_count); ind, "", word_count);
stub_errors += 1; 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 /* If this is not an array, then the expression with must
match the signal width. We have IVL_EX_SELECT expressions match the signal width. We have IVL_EX_SELECT expressions
for casting signal widths. */ 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", fprintf(out, "%*sERROR: Expression width (%u) doesn't match ivl_signal_width(sig)=%u\n",
ind+2, "", width, ivl_signal_width(sig)); ind+2, "", width, ivl_signal_width(sig));
stub_errors += 1; stub_errors += 1;

View File

@ -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() vvp_fun_anyedge_aa::vvp_fun_anyedge_aa()
{ {
context_scope_ = vpip_peek_context_scope(); context_scope_ = vpip_peek_context_scope();

View File

@ -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, void recv_string(vvp_net_ptr_t port, const std::string&bit,
vvp_context_t context); vvp_context_t context);
void recv_object(vvp_net_ptr_t port, vvp_object_t bit,
vvp_context_t context);
private: private:
vthread_t threads_; vthread_t threads_;