Add support for wait on list of named events.

This commit is contained in:
steve 2003-12-03 02:46:23 +00:00
parent 9967bfcbfd
commit e56b77a43f
8 changed files with 148 additions and 81 deletions

View File

@ -354,10 +354,6 @@ constructs.
- Event controls inside non-blocking assignments are not supported.
i.e.: a <= @(posedge clk) b;
- Lists of named events of the form @(event_1 or event_2) are not
supported. Named events are otherwise supported, and lists of
other kinds of events are also supported.
- Macro arguments are not supported. `define macros are supported,
but they cannot take arguments.

View File

@ -178,11 +178,12 @@ ivl_stmt_cond_false
ivl_stmt_cond_true
ivl_stmt_delay_expr
ivl_stmt_delay_val
ivl_stmt_event
ivl_stmt_events
ivl_stmt_lval
ivl_stmt_lvals
ivl_stmt_lwidth
ivl_stmt_name
ivl_stmt_nevent
ivl_stmt_nexus
ivl_stmt_nexus_count
ivl_stmt_parm

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: ivl_target.h,v 1.123 2003/11/08 20:06:21 steve Exp $"
#ident "$Id: ivl_target.h,v 1.124 2003/12/03 02:46:24 steve Exp $"
#endif
#ifdef __cplusplus
@ -1168,8 +1168,9 @@ extern ivl_statement_t ivl_stmt_cond_true(ivl_statement_t net);
extern ivl_expr_t ivl_stmt_delay_expr(ivl_statement_t net);
/* IVL_ST_DELAY */
extern unsigned long ivl_stmt_delay_val(ivl_statement_t net);
/* IVL_ST_WAIT */
extern ivl_event_t ivl_stmt_event(ivl_statement_t net);
/* IVL_ST_WAIT IVL_ST_TRIGGER */
extern unsigned ivl_stmt_nevent(ivl_statement_t net);
extern ivl_event_t ivl_stmt_events(ivl_statement_t net, unsigned idx);
/* IVL_ST_ASSIGN IVL_ST_ASSIGN_NB IVL_ST_CASSIGN IVL_ST_DEASSIGN
IVL_ST_FORCE IVL_ST_RELEASE */
extern ivl_lval_t ivl_stmt_lval(ivl_statement_t net, unsigned idx);
@ -1232,6 +1233,9 @@ _END_DECL
/*
* $Log: ivl_target.h,v $
* Revision 1.124 2003/12/03 02:46:24 steve
* Add support for wait on list of named events.
*
* Revision 1.123 2003/11/08 20:06:21 steve
* Spelling fixes in comments.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: t-dll-api.cc,v 1.105 2003/11/10 20:59:03 steve Exp $"
#ident "$Id: t-dll-api.cc,v 1.106 2003/12/03 02:46:24 steve Exp $"
#endif
# include "config.h"
@ -1720,13 +1720,34 @@ extern "C" unsigned long ivl_stmt_delay_val(ivl_statement_t net)
return net->u_.delay_.delay_;
}
extern "C" ivl_event_t ivl_stmt_event(ivl_statement_t net)
extern "C" unsigned ivl_stmt_nevent(ivl_statement_t net)
{
switch (net->type_) {
case IVL_ST_WAIT:
return net->u_.wait_.event_;
return net->u_.wait_.nevent;
case IVL_ST_TRIGGER:
return net->u_.trig_.event_;
return 1;
default:
assert(0);
}
return 0;
}
extern "C" ivl_event_t ivl_stmt_events(ivl_statement_t net, unsigned idx)
{
switch (net->type_) {
case IVL_ST_WAIT:
assert(idx < net->u_.wait_.nevent);
if (net->u_.wait_.nevent == 1)
return net->u_.wait_.event;
else
return net->u_.wait_.events[idx];
case IVL_ST_TRIGGER:
assert(idx == 0);
return net->u_.wait_.event;
default:
assert(0);
}
@ -1913,6 +1934,9 @@ extern "C" ivl_variable_type_t ivl_variable_type(ivl_variable_t net)
/*
* $Log: t-dll-api.cc,v $
* Revision 1.106 2003/12/03 02:46:24 steve
* Add support for wait on list of named events.
*
* Revision 1.105 2003/11/10 20:59:03 steve
* Design::get_flag returns const char* instead of string.
*

View File

@ -18,7 +18,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: t-dll-proc.cc,v 1.60 2003/06/24 01:38:03 steve Exp $"
#ident "$Id: t-dll-proc.cc,v 1.61 2003/12/03 02:46:24 steve Exp $"
#endif
# include "config.h"
@ -698,6 +698,7 @@ bool dll_target::proc_trigger(const NetEvTrig*net)
assert(stmt_cur_->type_ == IVL_ST_NONE);
stmt_cur_->type_ = IVL_ST_TRIGGER;
stmt_cur_->u_.wait_.nevent = 1;
/* Locate the event by name. Save the ivl_event_t in the
statement so that the generator can find it easily. */
@ -707,7 +708,7 @@ bool dll_target::proc_trigger(const NetEvTrig*net)
for (unsigned idx = 0 ; idx < ev_scope->nevent_ ; idx += 1) {
const char*ename = ivl_event_basename(ev_scope->event_[idx]);
if (strcmp(ev->name(), ename) == 0) {
stmt_cur_->u_.wait_.event_ = ev_scope->event_[idx];
stmt_cur_->u_.wait_.event = ev_scope->event_[idx];
break;
}
}
@ -734,63 +735,71 @@ bool dll_target::proc_wait(const NetEvWait*net)
stmt_cur_->u_.wait_.stmt_ = (struct ivl_statement_s*)
calloc(1, sizeof(struct ivl_statement_s));
if (net->nevents() != 1) {
cerr << net->get_line() << ": internal error: "
<< "multiple events not supported." << endl;
return false;
stmt_cur_->u_.wait_.nevent = net->nevents();
if (net->nevents() > 1) {
stmt_cur_->u_.wait_.events = (ivl_event_t*)
calloc(net->nevents(), sizeof(ivl_event_t*));
}
/* Locate the event by name. Save the ivl_event_t in the
statement so that the generator can find it easily. */
const NetEvent*ev = net->event(0);
ivl_scope_t ev_scope = lookup_scope_(ev->scope());
for (unsigned edx = 0 ; edx < net->nevents() ; edx += 1) {
for (unsigned idx = 0 ; idx < ev_scope->nevent_ ; idx += 1) {
const char*ename = ivl_event_basename(ev_scope->event_[idx]);
if (strcmp(ev->name(), ename) == 0) {
stmt_cur_->u_.wait_.event_ = ev_scope->event_[idx];
break;
}
}
/* Locate the event by name. Save the ivl_event_t in the
statement so that the generator can find it easily. */
const NetEvent*ev = net->event(edx);
ivl_scope_t ev_scope = lookup_scope_(ev->scope());
ivl_event_t ev_tmp;
/* If this is an event with a probe, then connect up the
pins. This wasn't done during the ::event method because
the signals weren't scanned yet. */
if (ev->nprobe() >= 1) {
ivl_event_t evnt = stmt_cur_->u_.wait_.event_;
unsigned iany = 0;
unsigned ineg = evnt->nany;
unsigned ipos = ineg + evnt->nneg;
for (unsigned idx = 0 ; idx < ev->nprobe() ; idx += 1) {
const NetEvProbe*pr = ev->probe(idx);
unsigned base = 0;
switch (pr->edge()) {
case NetEvProbe::ANYEDGE:
base = iany;
iany += pr->pin_count();
for (unsigned idx = 0 ; idx < ev_scope->nevent_ ; idx += 1) {
const char*ename = ivl_event_basename(ev_scope->event_[idx]);
if (strcmp(ev->name(), ename) == 0) {
ev_tmp = ev_scope->event_[idx];
break;
case NetEvProbe::NEGEDGE:
base = ineg;
ineg += pr->pin_count();
break;
case NetEvProbe::POSEDGE:
base = ipos;
ipos += pr->pin_count();
break;
}
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);
evnt->pins[base+bit] = nex;
}
}
if (net->nevents() == 1)
stmt_cur_->u_.wait_.event = ev_tmp;
else
stmt_cur_->u_.wait_.events[edx] = ev_tmp;
/* If this is an event with a probe, then connect up the
pins. This wasn't done during the ::event method because
the signals weren't scanned yet. */
if (ev->nprobe() >= 1) {
unsigned iany = 0;
unsigned ineg = ev_tmp->nany;
unsigned ipos = ineg + ev_tmp->nneg;
for (unsigned idx = 0 ; idx < ev->nprobe() ; idx += 1) {
const NetEvProbe*pr = ev->probe(idx);
unsigned base = 0;
switch (pr->edge()) {
case NetEvProbe::ANYEDGE:
base = iany;
iany += pr->pin_count();
break;
case NetEvProbe::NEGEDGE:
base = ineg;
ineg += pr->pin_count();
break;
case NetEvProbe::POSEDGE:
base = ipos;
ipos += pr->pin_count();
break;
}
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);
ev_tmp->pins[base+bit] = nex;
}
}
}
}
/* The ivl_statement_t for the wait statement is not complete
@ -833,6 +842,9 @@ void dll_target::proc_while(const NetWhile*net)
/*
* $Log: t-dll-proc.cc,v $
* Revision 1.61 2003/12/03 02:46:24 steve
* Add support for wait on list of named events.
*
* Revision 1.60 2003/06/24 01:38:03 steve
* Various warnings fixed.
*

17
t-dll.h
View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: t-dll.h,v 1.107 2003/11/10 20:59:04 steve Exp $"
#ident "$Id: t-dll.h,v 1.108 2003/12/03 02:46:24 steve Exp $"
#endif
# include "target.h"
@ -652,16 +652,16 @@ struct ivl_statement_s {
ivl_expr_t*parms_;
} stask_;
struct { /* IVL_ST_TRIGGER */
ivl_event_t event_;
} trig_;
struct { /* IVL_ST_UTASK */
ivl_scope_t def;
} utask_;
struct { /* IVL_ST_WAIT */
ivl_event_t event_;
struct { /* IVL_ST_TRIGGER IVL_ST_WAIT */
unsigned nevent;
union {
ivl_event_t event;
ivl_event_t*events;
};
ivl_statement_t stmt_;
} wait_;
@ -683,6 +683,9 @@ struct ivl_variable_s {
/*
* $Log: t-dll.h,v $
* Revision 1.108 2003/12/03 02:46:24 steve
* Add support for wait on list of named events.
*
* Revision 1.107 2003/11/10 20:59:04 steve
* Design::get_flag returns const char* instead of string.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: stub.c,v 1.82 2003/12/03 01:54:07 steve Exp $"
#ident "$Id: stub.c,v 1.83 2003/12/03 02:46:24 steve Exp $"
#endif
# include "config.h"
@ -484,14 +484,21 @@ static void show_statement(ivl_statement_t net, unsigned ind)
break;
case IVL_ST_WAIT: {
ivl_event_t evnt = ivl_stmt_event(net);
fprintf(out, "%*s@(", ind, "");
const char*comma = "";
if (evnt == 0)
fprintf(out, "%*s@(/*ERROR*/)\n", ind, "");
else
fprintf(out, "%*s@(%s)\n", ind, "",
ivl_event_name(evnt));
for (idx = 0 ; idx < ivl_stmt_nevent(net) ; idx += 1) {
ivl_event_t evnt = ivl_stmt_events(net, idx);
if (evnt == 0)
fprintf(out, "%s/*ERROR*/", comma);
else
fprintf(out, "%s%s", comma, ivl_event_name(evnt));
comma = ", ";
}
fprintf(out, ")\n");
show_statement(ivl_stmt_sub_stmt(net), ind+4);
break;
}
@ -885,6 +892,9 @@ int target_design(ivl_design_t des)
/*
* $Log: stub.c,v $
* Revision 1.83 2003/12/03 02:46:24 steve
* Add support for wait on list of named events.
*
* Revision 1.82 2003/12/03 01:54:07 steve
* Handle erroneous event lists.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: vvp_process.c,v 1.90 2003/10/25 02:07:57 steve Exp $"
#ident "$Id: vvp_process.c,v 1.91 2003/12/03 02:46:24 steve Exp $"
#endif
# include "vvp_priv.h"
@ -1223,7 +1223,7 @@ static int show_stmt_repeat(ivl_statement_t net, ivl_scope_t sscope)
static int show_stmt_trigger(ivl_statement_t net)
{
ivl_event_t ev = ivl_stmt_event(net);
ivl_event_t ev = ivl_stmt_events(net, 0);
assert(ev);
fprintf(vvp_out, " %%set E_%p, 0;\n", ev);
return 0;
@ -1243,9 +1243,23 @@ static int show_stmt_utask(ivl_statement_t net)
static int show_stmt_wait(ivl_statement_t net, ivl_scope_t sscope)
{
ivl_event_t ev = ivl_stmt_event(net);
fprintf(vvp_out, " %%wait E_%p;\n", ev);
if (ivl_stmt_nevent(net) == 1) {
ivl_event_t ev = ivl_stmt_events(net, 0);
fprintf(vvp_out, " %%wait E_%p;\n", ev);
} else {
unsigned idx;
static unsigned int cascade_counter = 0;
ivl_event_t ev = ivl_stmt_events(net, 0);
fprintf(vvp_out, "Ewait_%u .event/or E_%p", cascade_counter, ev);
for (idx = 1 ; idx < ivl_stmt_nevent(net) ; idx += 1) {
ev = ivl_stmt_events(net, idx);
fprintf(vvp_out, ", E_%p", ev);
}
fprintf(vvp_out, ";\n %%wait Ewait_%u;\n", cascade_counter);
cascade_counter += 1;
}
/* Always clear the expression lookaside after a
%wait. Anything can happen while the thread is waiting. */
clear_expression_lookaside();
@ -1560,6 +1574,9 @@ int draw_func_definition(ivl_scope_t scope)
/*
* $Log: vvp_process.c,v $
* Revision 1.91 2003/12/03 02:46:24 steve
* Add support for wait on list of named events.
*
* Revision 1.90 2003/10/25 02:07:57 steve
* vvp_signal_label does not return a unique string.
*