From 19c84ff9a2fceaa07374c5a9e273404eded3a4d8 Mon Sep 17 00:00:00 2001 From: steve Date: Tue, 3 Apr 2001 04:50:37 +0000 Subject: [PATCH] Support non-blocking assignments. --- ivl_target.h | 14 +++++--- t-dll-api.cc | 12 +++++-- t-dll-proc.cc | 53 +++++++++++++++++++++++++++- t-dll.h | 8 +++-- tgt-stub/stub.c | 27 ++++++++++++++- tgt-vvp/vvp_process.c | 80 ++++++++++++++++++++++++++++++++++++++++++- 6 files changed, 182 insertions(+), 12 deletions(-) diff --git a/ivl_target.h b/ivl_target.h index cef02341d..43ab1111d 100644 --- a/ivl_target.h +++ b/ivl_target.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: ivl_target.h,v 1.45 2001/04/02 02:28:12 steve Exp $" +#ident "$Id: ivl_target.h,v 1.46 2001/04/03 04:50:37 steve Exp $" #endif #ifdef __cplusplus @@ -239,6 +239,7 @@ typedef enum ivl_statement_type_e { IVL_ST_NONE = 0, IVL_ST_NOOP = 1, IVL_ST_ASSIGN, + IVL_ST_ASSIGN_NB, IVL_ST_BLOCK, IVL_ST_CASE, IVL_ST_CASEX, @@ -700,11 +701,11 @@ extern ivl_statement_t ivl_stmt_cond_true(ivl_statement_t net); 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_ASSIGN */ + /* IVL_ST_ASSIGN IVL_ST_ASSIGN_NB */ extern ivl_lval_t ivl_stmt_lval(ivl_statement_t net, unsigned idx); - /* IVL_ST_ASSIGN */ + /* IVL_ST_ASSIGN IVL_ST_ASSIGN_NB */ extern unsigned ivl_stmt_lvals(ivl_statement_t net); - /* IVL_ST_ASSIGN */ + /* IVL_ST_ASSIGN IVL_ST_ASSIGN_NB */ extern unsigned ivl_stmt_lwidth(ivl_statement_t net); /* IVL_ST_STASK */ extern const char* ivl_stmt_name(ivl_statement_t net); @@ -712,7 +713,7 @@ extern const char* ivl_stmt_name(ivl_statement_t net); extern ivl_expr_t ivl_stmt_parm(ivl_statement_t net, unsigned idx); /* IVL_ST_STASK */ extern unsigned ivl_stmt_parm_count(ivl_statement_t net); - /* IVL_ST_ASSIGN */ + /* IVL_ST_ASSIGN IVL_ST_ASSIGN_NB */ extern ivl_expr_t ivl_stmt_rval(ivl_statement_t net); /* IVL_ST_DELAY, IVL_ST_WAIT, IVL_ST_WHILE */ extern ivl_statement_t ivl_stmt_sub_stmt(ivl_statement_t net); @@ -735,6 +736,9 @@ _END_DECL /* * $Log: ivl_target.h,v $ + * Revision 1.46 2001/04/03 04:50:37 steve + * Support non-blocking assignments. + * * Revision 1.45 2001/04/02 02:28:12 steve * Generate code for task calls. * diff --git a/t-dll-api.cc b/t-dll-api.cc index f4baf01a4..bb39af2e3 100644 --- a/t-dll-api.cc +++ b/t-dll-api.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: t-dll-api.cc,v 1.32 2001/04/02 02:28:12 steve Exp $" +#ident "$Id: t-dll-api.cc,v 1.33 2001/04/03 04:50:37 steve Exp $" #endif # include "t-dll.h" @@ -729,6 +729,7 @@ extern "C" ivl_lval_t ivl_stmt_lval(ivl_statement_t net, unsigned idx) { switch (net->type_) { case IVL_ST_ASSIGN: + case IVL_ST_ASSIGN_NB: assert(idx < net->u_.assign_.lvals_); return net->u_.assign_.lval_ + idx; default: @@ -741,6 +742,7 @@ extern "C" unsigned ivl_stmt_lvals(ivl_statement_t net) { switch (net->type_) { case IVL_ST_ASSIGN: + case IVL_ST_ASSIGN_NB: return net->u_.assign_.lvals_; default: assert(0); @@ -750,7 +752,9 @@ extern "C" unsigned ivl_stmt_lvals(ivl_statement_t net) extern "C" unsigned ivl_stmt_lwidth(ivl_statement_t net) { - assert(net->type_ == IVL_ST_ASSIGN); + assert((net->type_ == IVL_ST_ASSIGN) + || (net->type_ == IVL_ST_ASSIGN_NB)); + unsigned sum = 0; for (unsigned idx = 0 ; idx < net->u_.assign_.lvals_ ; idx += 1) { ivl_lval_t cur = net->u_.assign_.lval_ + idx; @@ -803,6 +807,7 @@ extern "C" ivl_expr_t ivl_stmt_rval(ivl_statement_t net) { switch (net->type_) { case IVL_ST_ASSIGN: + case IVL_ST_ASSIGN_NB: return net->u_.assign_.rval_; default: assert(0); @@ -829,6 +834,9 @@ extern "C" ivl_statement_t ivl_stmt_sub_stmt(ivl_statement_t net) /* * $Log: t-dll-api.cc,v $ + * Revision 1.33 2001/04/03 04:50:37 steve + * Support non-blocking assignments. + * * Revision 1.32 2001/04/02 02:28:12 steve * Generate code for task calls. * diff --git a/t-dll-proc.cc b/t-dll-proc.cc index 032db16b7..e470630c6 100644 --- a/t-dll-proc.cc +++ b/t-dll-proc.cc @@ -18,7 +18,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: t-dll-proc.cc,v 1.20 2001/04/02 02:28:12 steve Exp $" +#ident "$Id: t-dll-proc.cc,v 1.21 2001/04/03 04:50:37 steve Exp $" #endif # include "target.h" @@ -140,6 +140,54 @@ void dll_target::proc_assign(const NetAssign*net) } +void dll_target::proc_assign_nb(const NetAssignNB*net) +{ + unsigned cnt; + + assert(stmt_cur_); + assert(stmt_cur_->type_ == IVL_ST_NONE); + + stmt_cur_->type_ = IVL_ST_ASSIGN_NB; + + stmt_cur_->u_.assign_.lvals_ = cnt = net->l_val_count(); + stmt_cur_->u_.assign_.lval_ = new struct ivl_lval_s[cnt]; + + for (unsigned idx = 0 ; idx < cnt ; idx += 1) { + struct ivl_lval_s*cur = stmt_cur_->u_.assign_.lval_ + idx; + const NetAssign_*asn = net->l_val(idx); + + cur->width_ = asn->pin_count(); + + if (cur->width_ > 1) { + cur->n.pins_ = new ivl_nexus_t[cur->width_]; + for (unsigned pp = 0 ; pp < cur->width_ ; pp += 1) { + const Nexus*nex = asn->pin(pp).nexus(); + assert(nex->t_cookie()); + cur->n.pins_[pp] = (ivl_nexus_t)nex->t_cookie(); + } + + } else { + const Nexus*nex = asn->pin(0).nexus(); + assert(nex->t_cookie()); + cur->n.pin_ = (ivl_nexus_t)nex->t_cookie(); + } + + cur->mux = 0; + if (asn->bmux()) { + assert(expr_ == 0); + asn->bmux()->expr_scan(this); + cur->mux = expr_; + expr_ = 0; + } + } + + assert(expr_ == 0); + net->rval()->expr_scan(this); + stmt_cur_->u_.assign_.rval_ = expr_; + expr_ = 0; +} + + bool dll_target::proc_block(const NetBlock*net) { assert(stmt_cur_); @@ -463,6 +511,9 @@ void dll_target::proc_while(const NetWhile*net) /* * $Log: t-dll-proc.cc,v $ + * Revision 1.21 2001/04/03 04:50:37 steve + * Support non-blocking assignments. + * * Revision 1.20 2001/04/02 02:28:12 steve * Generate code for task calls. * diff --git a/t-dll.h b/t-dll.h index 041e8c36e..5860a592e 100644 --- a/t-dll.h +++ b/t-dll.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: t-dll.h,v 1.32 2001/04/02 02:28:12 steve Exp $" +#ident "$Id: t-dll.h,v 1.33 2001/04/03 04:50:37 steve Exp $" #endif # include "target.h" @@ -78,6 +78,7 @@ struct dll_target : public target_t, public expr_scan_t { statements of a thread. */ struct ivl_statement_s*stmt_cur_; void proc_assign(const NetAssign*); + void proc_assign_nb(const NetAssignNB*); bool proc_block(const NetBlock*); void proc_case(const NetCase*); void proc_condit(const NetCondit*); @@ -346,7 +347,7 @@ struct ivl_signal_s { struct ivl_statement_s { enum ivl_statement_type_e type_; union { - struct { /* IVL_ST_ASSIGN */ + struct { /* IVL_ST_ASSIGN IVL_ST_ASSIGN_NB */ unsigned lvals_; struct ivl_lval_s*lval_; ivl_expr_t rval_; @@ -409,6 +410,9 @@ struct ivl_statement_s { /* * $Log: t-dll.h,v $ + * Revision 1.33 2001/04/03 04:50:37 steve + * Support non-blocking assignments. + * * Revision 1.32 2001/04/02 02:28:12 steve * Generate code for task calls. * diff --git a/tgt-stub/stub.c b/tgt-stub/stub.c index 51b665144..5d4b91815 100644 --- a/tgt-stub/stub.c +++ b/tgt-stub/stub.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: stub.c,v 1.35 2001/04/02 02:28:13 steve Exp $" +#ident "$Id: stub.c,v 1.36 2001/04/03 04:50:37 steve Exp $" #endif /* @@ -153,6 +153,28 @@ static void show_statement(ivl_statement_t net, unsigned ind) show_expression(ivl_stmt_rval(net), ind+4); break; + case IVL_ST_ASSIGN_NB: + fprintf(out, "%*sASSIGN_NB \n", ind, "", + ivl_stmt_lwidth(net)); + for (idx = 0 ; idx < ivl_stmt_lvals(net) ; idx += 1) { + unsigned pp; + ivl_lval_t lval = ivl_stmt_lval(net, idx); + ivl_nexus_t nex = ivl_lval_pin(lval, 0); + + fprintf(out, "%*s{%s", ind+4, "", ivl_nexus_name(nex)); + fprintf(out, "", ivl_nexus_ptrs(nex)); + for (pp = 1 ; pp < ivl_lval_pins(lval) ; pp += 1) { + nex = ivl_lval_pin(lval, pp); + fprintf(out, ", %s", ivl_nexus_name(nex)); + fprintf(out, "", ivl_nexus_ptrs(nex)); + } + fprintf(out, "}\n"); + } + + if (ivl_stmt_rval(net)) + show_expression(ivl_stmt_rval(net), ind+4); + break; + case IVL_ST_BLOCK: { unsigned cnt = ivl_stmt_block_count(net); fprintf(out, "%*sbegin\n", ind, ""); @@ -484,6 +506,9 @@ DECLARE_CYGWIN_DLL(DllMain); /* * $Log: stub.c,v $ + * Revision 1.36 2001/04/03 04:50:37 steve + * Support non-blocking assignments. + * * Revision 1.35 2001/04/02 02:28:13 steve * Generate code for task calls. * diff --git a/tgt-vvp/vvp_process.c b/tgt-vvp/vvp_process.c index fcbbf230e..7d1fc2a26 100644 --- a/tgt-vvp/vvp_process.c +++ b/tgt-vvp/vvp_process.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: vvp_process.c,v 1.20 2001/04/02 04:09:20 steve Exp $" +#ident "$Id: vvp_process.c,v 1.21 2001/04/03 04:50:37 steve Exp $" #endif # include "vvp_priv.h" @@ -81,6 +81,23 @@ static void set_to_nexus(ivl_nexus_t nex, unsigned bit) } } +static void assign_to_nexus(ivl_nexus_t nex, unsigned bit, unsigned delay) +{ + unsigned idx; + + for (idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) { + ivl_nexus_ptr_t ptr = ivl_nexus_ptr(nex, idx); + unsigned pin = ivl_nexus_ptr_pin(ptr); + ivl_signal_t sig = ivl_nexus_ptr_sig(ptr); + + if (sig == 0) + continue; + + fprintf(vvp_out, " %%assign V_%s[%u], %u, %u;\n", + ivl_signal_name(sig), pin, delay, bit); + } +} + static int show_stmt_assign(ivl_statement_t net) { ivl_lval_t lval; @@ -135,6 +152,60 @@ static int show_stmt_assign(ivl_statement_t net) return 0; } +static int show_stmt_assign_nb(ivl_statement_t net) +{ + ivl_lval_t lval; + ivl_expr_t rval = ivl_stmt_rval(net); + + + /* Handle the special case that the r-value is a constant. We + can generate the %set statement directly, without any worry + about generating code to evaluate the r-value expressions. */ + + if (ivl_expr_type(rval) == IVL_EX_NUMBER) { + unsigned idx; + const char*bits = ivl_expr_bits(rval); + + /* XXXX Only single l-value supported for now */ + assert(ivl_stmt_lvals(net) == 1); + + lval = ivl_stmt_lval(net, 0); + /* XXXX No mux support yet. */ + assert(ivl_lval_mux(lval) == 0); + + for (idx = 0 ; idx < ivl_lval_pins(lval) ; idx += 1) + assign_to_nexus(ivl_lval_pin(lval, idx), + bitchar_to_idx(bits[idx]), 0); + + return 0; + } + + { struct vector_info res = draw_eval_expr(rval); + unsigned wid = res.wid; + unsigned idx; + + /* XXXX Only single l-value supported for now */ + assert(ivl_stmt_lvals(net) == 1); + + lval = ivl_stmt_lval(net, 0); + /* XXXX No mux support yet. */ + assert(ivl_lval_mux(lval) == 0); + + if (ivl_lval_pins(lval) < wid) + wid = ivl_lval_pins(lval); + + for (idx = 0 ; idx < wid ; idx += 1) + assign_to_nexus(ivl_lval_pin(lval, idx), res.base+idx, 0); + + for (idx = wid ; idx < ivl_lval_pins(lval) ; idx += 1) + assign_to_nexus(ivl_lval_pin(lval, idx), 0, 0); + + clr_vector(res); + } + + return 0; +} + static int show_stmt_case(ivl_statement_t net) { ivl_expr_t exp = ivl_stmt_cond_expr(net); @@ -467,6 +538,10 @@ static int show_statement(ivl_statement_t net) rc += show_stmt_assign(net); break; + case IVL_ST_ASSIGN_NB: + rc += show_stmt_assign_nb(net); + break; + /* Begin-end blocks simply draw their contents. */ case IVL_ST_BLOCK: { unsigned idx; @@ -594,6 +669,9 @@ int draw_task_definition(ivl_scope_t scope) /* * $Log: vvp_process.c,v $ + * Revision 1.21 2001/04/03 04:50:37 steve + * Support non-blocking assignments. + * * Revision 1.20 2001/04/02 04:09:20 steve * thread bit allocation leak in assign. *