/* * An event in an expression context must be a named event. */ static void emit_expr_event(ivl_scope_t scope, ivl_expr_t expr, unsigned wid) { ivl_event_t event = ivl_expr_event(expr); ivl_scope_t ev_scope = ivl_event_scope(event); assert(! ivl_event_nany(event)); assert(! ivl_event_npos(event)); assert(! ivl_event_nneg(event)); emit_scope_call_path(scope, ev_scope); emit_id(ivl_event_basename(event)); }
static void show_event(ivl_event_t net) { unsigned idx; fprintf(out, " event %s (%u pos, %u neg, %u any);\n", ivl_event_basename(net), ivl_event_npos(net), ivl_event_nneg(net), ivl_event_nany(net)); for (idx = 0 ; idx < ivl_event_nany(net) ; idx += 1) { ivl_nexus_t nex = ivl_event_any(net, idx); fprintf(out, " ANYEDGE: %p\n", nex); } for (idx = 0 ; idx < ivl_event_nneg(net) ; idx += 1) { ivl_nexus_t nex = ivl_event_neg(net, idx); fprintf(out, " NEGEDGE: %p\n", nex); } for (idx = 0 ; idx < ivl_event_npos(net) ; idx += 1) { ivl_nexus_t nex = ivl_event_pos(net, idx); fprintf(out, " POSEDGE: %p\n", nex); } }
void emit_event(ivl_scope_t scope, ivl_statement_t stmt) { unsigned eidx, nevents, first = 1; nevents = ivl_stmt_nevent(stmt); for (eidx = 0; eidx < nevents; eidx += 1) { unsigned idx, count, had_edge = 0; ivl_event_t event = ivl_stmt_events(stmt, eidx); /* Check for any edge events. */ count = ivl_event_nany(event); if (count) had_edge = 1; for (idx = 0; idx < count; idx += 1) { if (first) first = 0; else fprintf(vlog_out, " or "); emit_nexus_as_ca(scope, ivl_event_any(event, idx), 0); } /* Check for positive edge events. */ count = ivl_event_npos(event); if (count) had_edge = 1; for (idx = 0; idx < count; idx += 1) { if (first) first = 0; else fprintf(vlog_out, " or "); fprintf(vlog_out, "posedge "); emit_nexus_as_ca(scope, ivl_event_pos(event, idx), 0); } /* Check for negative edge events. */ count = ivl_event_nneg(event); if (count) had_edge = 1; for (idx = 0; idx < count; idx += 1) { if (first) first = 0; else fprintf(vlog_out, " or "); fprintf(vlog_out, "negedge "); emit_nexus_as_ca(scope, ivl_event_neg(event, idx), 0); } /* We have a named event if there were no edge events. */ if (!had_edge) { ivl_scope_t ev_scope = ivl_event_scope(event); if (first) first = 0; else fprintf(vlog_out, " or "); emit_scope_module_path(scope, ev_scope); emit_id(ivl_event_basename(event)); } } }
static void draw_event_in_scope(ivl_event_t obj) { char tmp[4][32]; const unsigned ntmp = sizeof(tmp) / sizeof(tmp[0]); unsigned nany = ivl_event_nany(obj); unsigned nneg = ivl_event_nneg(obj); unsigned npos = ivl_event_npos(obj); unsigned cnt = 0; /* Figure out how many probe functors are needed. */ if (nany > 0) cnt += (nany+ntmp-1) / ntmp; if (nneg > 0) cnt += (nneg+ntmp-1) / ntmp; if (npos > 0) cnt += (npos+ntmp-1) / ntmp; if (cnt == 0) { /* If none are needed, then this is a named event. The code needed is easy. */ fprintf(vvp_out, "E_%p .event \"%s\";\n", obj, vvp_mangle_name(ivl_event_basename(obj))); } else if (cnt > 1) { /* There are a bunch of events that need to be event/or combined. */ unsigned idx; unsigned ecnt = 0; for (idx = 0 ; idx < nany ; idx += ntmp, ecnt += 1) { unsigned sub, top; top = idx + ntmp; if (nany < top) top = nany; for (sub = idx ; sub < top ; sub += 1) { ivl_nexus_t nex = ivl_event_any(obj, sub); strncpy(tmp[sub-idx], draw_input_from_net(nex), sizeof(tmp[0])); } fprintf(vvp_out, "E_%p/%u .event edge", obj, ecnt); for (sub = idx ; sub < top ; sub += 1) fprintf(vvp_out, ", %s", tmp[sub-idx]); fprintf(vvp_out, ";\n"); } for (idx = 0 ; idx < nneg ; idx += ntmp, ecnt += 1) { unsigned sub, top; top = idx + ntmp; if (nneg < top) top = nneg; for (sub = idx ; sub < top ; sub += 1) { ivl_nexus_t nex = ivl_event_neg(obj, sub); strncpy(tmp[sub-idx], draw_input_from_net(nex), sizeof(tmp[0])); } fprintf(vvp_out, "E_%p/%u .event negedge", obj, ecnt); for (sub = idx ; sub < top ; sub += 1) fprintf(vvp_out, ", %s", tmp[sub-idx]); fprintf(vvp_out, ";\n"); } for (idx = 0 ; idx < npos ; idx += ntmp, ecnt += 1) { unsigned sub, top; top = idx + ntmp; if (npos < top) top = npos; for (sub = idx ; sub < top ; sub += 1) { ivl_nexus_t nex = ivl_event_pos(obj, sub); strncpy(tmp[sub-idx], draw_input_from_net(nex), sizeof(tmp[0])); } fprintf(vvp_out, "E_%p/%u .event posedge", obj, ecnt); for (sub = idx ; sub < top ; sub += 1) fprintf(vvp_out, ", %s", tmp[sub-idx]); fprintf(vvp_out, ";\n"); } assert(ecnt == cnt); fprintf(vvp_out, "E_%p .event/or", obj); fprintf(vvp_out, " E_%p/0", obj); for (idx = 1 ; idx < cnt ; idx += 1) fprintf(vvp_out, ", E_%p/%u", obj, idx); fprintf(vvp_out, ";\n"); } else { unsigned num_input_strings = nany + nneg + npos; unsigned idx; const char*edge = 0; assert(num_input_strings <= ntmp); if (nany > 0) { assert((nneg + npos) == 0); edge = "edge"; for (idx = 0 ; idx < nany ; idx += 1) { ivl_nexus_t nex = ivl_event_any(obj, idx); strncpy(tmp[idx], draw_input_from_net(nex), sizeof(tmp[0])); } } else if (nneg > 0) { assert((nany + npos) == 0); edge = "negedge"; for (idx = 0 ; idx < nneg ; idx += 1) { ivl_nexus_t nex = ivl_event_neg(obj, idx); strncpy(tmp[idx], draw_input_from_net(nex), sizeof(tmp[0])); } } else { assert((nany + nneg) == 0); edge = "posedge"; for (idx = 0 ; idx < npos ; idx += 1) { ivl_nexus_t nex = ivl_event_pos(obj, idx); strncpy(tmp[idx], draw_input_from_net(nex), sizeof(tmp[0])); } } fprintf(vvp_out, "E_%p .event %s", obj, edge); for (idx = 0 ; idx < num_input_strings ; idx += 1) { fprintf(vvp_out, ", %s", tmp[idx]); } fprintf(vvp_out, ";\n"); } }