From 5882c6a48172e607e997934cfc85cdc7ac12480b Mon Sep 17 00:00:00 2001 From: steve Date: Sun, 21 Apr 2002 22:31:02 +0000 Subject: [PATCH] Redo handling of assignment internal delays. Leave it possible for them to be calculated at run time. --- Statement.cc | 11 ++++-- Statement.h | 9 +++-- elaborate.cc | 79 ++++++++++++++++++++++++++++++++++++------- net_assign.cc | 51 +++++++++------------------- netlist.h | 22 ++++++------ t-dll-proc.cc | 26 +++++++++++--- tgt-vvp/vvp_process.c | 59 +++++++++++++++++++++++++------- 7 files changed, 178 insertions(+), 79 deletions(-) diff --git a/Statement.cc b/Statement.cc index 16a93b4de..008eea9ff 100644 --- a/Statement.cc +++ b/Statement.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: Statement.cc,v 1.26 2002/04/21 04:59:07 steve Exp $" +#ident "$Id: Statement.cc,v 1.27 2002/04/21 22:31:02 steve Exp $" #endif # include "config.h" @@ -32,17 +32,19 @@ Statement::~Statement() PAssign_::PAssign_(PExpr*lval, PExpr*ex) : event_(0), lval_(lval), rval_(ex) { + delay_ = 0; } PAssign_::PAssign_(PExpr*lval, PExpr*de, PExpr*ex) : event_(0), lval_(lval), rval_(ex) { - if (de) delay_.set_delay(de); + delay_ = de; } PAssign_::PAssign_(PExpr*lval, PEventStatement*ev, PExpr*ex) : event_(ev), lval_(lval), rval_(ex) { + delay_ = 0; } PAssign_::~PAssign_() @@ -293,6 +295,11 @@ PWhile::~PWhile() /* * $Log: Statement.cc,v $ + * Revision 1.27 2002/04/21 22:31:02 steve + * Redo handling of assignment internal delays. + * Leave it possible for them to be calculated + * at run time. + * * Revision 1.26 2002/04/21 04:59:07 steve * Add support for conbinational events by finding * the inputs to expressions and some statements. diff --git a/Statement.h b/Statement.h index 61494f277..a6cc65de4 100644 --- a/Statement.h +++ b/Statement.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: Statement.h,v 1.32 2002/04/21 04:59:07 steve Exp $" +#ident "$Id: Statement.h,v 1.33 2002/04/21 22:31:02 steve Exp $" #endif # include @@ -97,7 +97,7 @@ class PAssign_ : public Statement { protected: NetAssign_* elaborate_lval(Design*, NetScope*scope) const; - PDelays delay_; + PExpr* delay_; PEventStatement*event_; private: @@ -453,6 +453,11 @@ class PWhile : public Statement { /* * $Log: Statement.h,v $ + * Revision 1.33 2002/04/21 22:31:02 steve + * Redo handling of assignment internal delays. + * Leave it possible for them to be calculated + * at run time. + * * Revision 1.32 2002/04/21 04:59:07 steve * Add support for conbinational events by finding * the inputs to expressions and some statements. diff --git a/elaborate.cc b/elaborate.cc index 2c055b90e..9e00271e4 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: elaborate.cc,v 1.243 2002/04/21 04:59:07 steve Exp $" +#ident "$Id: elaborate.cc,v 1.244 2002/04/21 22:31:02 steve Exp $" #endif # include "config.h" @@ -875,6 +875,57 @@ NetAssign_* PAssign_::elaborate_lval(Design*des, NetScope*scope) const return lval_->elaborate_lval(des, scope); } +/* + * This function elaborates delay expressions. This is a little + * different from normal elaboration because the result may need to be + * scaled. + */ +static NetExpr*elaborate_delay_expr(PExpr*expr, Design*des, NetScope*scope) +{ + + if (verireal*dr = expr->eval_rconst(des, scope)) { + int shift = scope->time_unit() - des->get_precision(); + long val = dr->as_long(shift); + delete dr; + return new NetEConst(verinum(val)); + + } + + if (verinum*dv = expr->eval_const(des, scope)) { + unsigned long val = dv->as_ulong(); + val = des->scale_to_precision(val, scope); + return new NetEConst(verinum(val)); + + } + + NetExpr*delay = expr->elaborate_expr(des, scope); + + int shift = scope->time_unit() - des->get_precision(); + if (shift > 0) { + unsigned long scale = 1; + while (shift > 0) { + scale *= 10; + shift -= 1; + } + + NetExpr*scal_val = new NetEConst(verinum(scale)); + delay = new NetEBMult('*', delay, scal_val); + } + + if (shift < 0) { + unsigned long scale = 1; + while (shift < 0) { + scale *= 10; + shift += 1; + } + + NetExpr*scal_val = new NetEConst(verinum(scale)); + delay = new NetEBDiv('/', delay, scal_val); + } + + return delay; +} + NetProc* PAssign::elaborate(Design*des, NetScope*scope) const { assert(scope); @@ -900,9 +951,10 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const NetAssign_*lv = elaborate_lval(des, scope); if (lv == 0) return 0; - /* If there is a delay expression, elaborate it. */ - unsigned long rise_time, fall_time, decay_time; - delay_.eval_delays(des, scope, rise_time, fall_time, decay_time); + /* If there is an internal delay expression, elaborate it. */ + NetExpr*delay = 0; + if (delay_ != 0) + delay = elaborate_delay_expr(delay_, des, scope); /* Elaborate the r-value expression. */ @@ -947,7 +999,7 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const actually and literally represent the delayed assign in the netlist. The compound statement is exactly equivalent. */ - if (rise_time || event_) { + if (delay || event_) { string n = scope->local_hsymbol(); unsigned wid = lv->lwidth(); @@ -995,7 +1047,7 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const assert(st); } else { - NetPDelay*de = new NetPDelay(rise_time, a2); + NetPDelay*de = new NetPDelay(delay, a2); st = de; } @@ -1091,15 +1143,13 @@ NetProc* PAssignNB::elaborate(Design*des, NetScope*scope) const rv = pad_to_width(rv, wid); } - - unsigned long rise_time, fall_time, decay_time; - delay_.eval_delays(des, scope, rise_time, fall_time, decay_time); + NetExpr*delay = 0; + if (delay_ != 0) + delay = elaborate_delay_expr(delay_, des, scope); /* All done with this node. mark its line number and check it in. */ NetAssignNB*cur = new NetAssignNB(lv, rv); - cur->rise_time(rise_time); - cur->fall_time(fall_time); - cur->decay_time(decay_time); + cur->set_delay(delay); cur->set_line(*this); return cur; } @@ -2454,6 +2504,11 @@ Design* elaborate(listroots) /* * $Log: elaborate.cc,v $ + * Revision 1.244 2002/04/21 22:31:02 steve + * Redo handling of assignment internal delays. + * Leave it possible for them to be calculated + * at run time. + * * Revision 1.243 2002/04/21 04:59:07 steve * Add support for conbinational events by finding * the inputs to expressions and some statements. diff --git a/net_assign.cc b/net_assign.cc index dcebc85b0..cd3f32de3 100644 --- a/net_assign.cc +++ b/net_assign.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: net_assign.cc,v 1.8 2001/08/25 23:50:03 steve Exp $" +#ident "$Id: net_assign.cc,v 1.9 2002/04/21 22:31:02 steve Exp $" #endif # include "config.h" @@ -99,7 +99,7 @@ unsigned NetAssign_::get_loff() const } NetAssignBase::NetAssignBase(NetAssign_*lv, NetExpr*rv) -: lval_(lv), rval_(rv) +: lval_(lv), rval_(rv), delay_(0) { } @@ -180,6 +180,15 @@ unsigned NetAssignBase::lwidth() const return sum; } +void NetAssignBase::set_delay(NetExpr*expr) +{ + delay_ = expr; +} + +const NetExpr* NetAssignBase::get_delay() const +{ + return delay_; +} NetAssign::NetAssign(NetAssign_*lv, NetExpr*rv) : NetAssignBase(lv, rv) @@ -193,47 +202,19 @@ NetAssign::~NetAssign() NetAssignNB::NetAssignNB(NetAssign_*lv, NetExpr*rv) : NetAssignBase(lv, rv) { - rise_time_ = 0; - fall_time_ = 0; - decay_time_ = 0; } NetAssignNB::~NetAssignNB() { } -void NetAssignNB::rise_time(unsigned t) -{ - rise_time_ = t; -} - -void NetAssignNB::fall_time(unsigned t) -{ - fall_time_ = t; -} - -void NetAssignNB::decay_time(unsigned t) -{ - decay_time_ = t; -} - -unsigned NetAssignNB::rise_time() const -{ - return rise_time_; -} - -unsigned NetAssignNB::fall_time() const -{ - return fall_time_; -} - -unsigned NetAssignNB::decay_time() const -{ - return decay_time_; -} - /* * $Log: net_assign.cc,v $ + * Revision 1.9 2002/04/21 22:31:02 steve + * Redo handling of assignment internal delays. + * Leave it possible for them to be calculated + * at run time. + * * Revision 1.8 2001/08/25 23:50:03 steve * Change the NetAssign_ class to refer to the signal * instead of link into the netlist. This is faster diff --git a/netlist.h b/netlist.h index 4f53c7c8f..ce8824b7f 100644 --- a/netlist.h +++ b/netlist.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: netlist.h,v 1.234 2002/04/21 17:43:13 steve Exp $" +#ident "$Id: netlist.h,v 1.235 2002/04/21 22:31:02 steve Exp $" #endif /* @@ -1281,6 +1281,9 @@ class NetAssignBase : public NetProc { const NetAssign_* l_val(unsigned) const; unsigned l_val_count() const; + void set_delay(NetExpr*); + const NetExpr* get_delay() const; + virtual NexusSet* nex_input(); // This returns the total width of the accumulated l-value. It @@ -1293,6 +1296,7 @@ class NetAssignBase : public NetProc { private: NetAssign_*lval_; NetExpr *rval_; + NetExpr *delay_; }; class NetAssign : public NetAssignBase { @@ -1313,23 +1317,12 @@ class NetAssignNB : public NetAssignBase { explicit NetAssignNB(NetAssign_*lv, NetExpr*rv); ~NetAssignNB(); - void rise_time(unsigned); - void fall_time(unsigned); - void decay_time(unsigned); - - unsigned rise_time() const; - unsigned fall_time() const; - unsigned decay_time() const; virtual bool emit_proc(struct target_t*) const; virtual int match_proc(struct proc_match_t*); virtual void dump(ostream&, unsigned ind) const; private: - - unsigned rise_time_; - unsigned fall_time_; - unsigned decay_time_; }; /* @@ -2984,6 +2977,11 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.235 2002/04/21 22:31:02 steve + * Redo handling of assignment internal delays. + * Leave it possible for them to be calculated + * at run time. + * * Revision 1.234 2002/04/21 17:43:13 steve * implement nex_input for behavioral statements. * diff --git a/t-dll-proc.cc b/t-dll-proc.cc index 53d5bf37a..84f9552a4 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.41 2002/01/19 19:02:08 steve Exp $" +#ident "$Id: t-dll-proc.cc,v 1.42 2002/04/21 22:31:02 steve Exp $" #endif # include "config.h" @@ -157,6 +157,13 @@ void dll_target::proc_assign(const NetAssign*net) net->rval()->expr_scan(this); stmt_cur_->u_.assign_.rval_ = expr_; expr_ = 0; + + const NetExpr*del = net->get_delay(); + if (del) { + del->expr_scan(this); + stmt_cur_->u_.assign_.delay = expr_; + expr_ = 0; + } } @@ -164,7 +171,7 @@ void dll_target::proc_assign_nb(const NetAssignNB*net) { unsigned cnt = net->l_val_count(); - unsigned long delay_val = net->rise_time(); + const NetExpr* delay_exp = net->get_delay(); assert(stmt_cur_); assert(stmt_cur_->type_ == IVL_ST_NONE); @@ -198,13 +205,19 @@ void dll_target::proc_assign_nb(const NetAssignNB*net) stmt_cur_->u_.assign_.rval_ = expr_; expr_ = 0; - if (delay_val > 0) { + if (const NetEConst*delay_num = dynamic_cast(delay_exp)) { + verinum val = delay_num->value(); ivl_expr_t de = new struct ivl_expr_s; de->type_ = IVL_EX_ULONG; de->width_ = 8 * sizeof(unsigned long); de->signed_ = 0; - de->u_.ulong_.value = delay_val; + de->u_.ulong_.value = val.as_ulong(); stmt_cur_->u_.assign_.delay = de; + + } else if (delay_exp != 0) { + delay_exp->expr_scan(this); + stmt_cur_->u_.assign_.delay = expr_; + expr_ = 0; } } @@ -793,6 +806,11 @@ void dll_target::proc_while(const NetWhile*net) /* * $Log: t-dll-proc.cc,v $ + * Revision 1.42 2002/04/21 22:31:02 steve + * Redo handling of assignment internal delays. + * Leave it possible for them to be calculated + * at run time. + * * Revision 1.41 2002/01/19 19:02:08 steve * Pass back target errors processing conditionals. * diff --git a/tgt-vvp/vvp_process.c b/tgt-vvp/vvp_process.c index 9ab29f8b8..2d84c3501 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.55 2002/04/14 19:19:21 steve Exp $" +#ident "$Id: vvp_process.c,v 1.56 2002/04/21 22:31:02 steve Exp $" #endif # include "vvp_priv.h" @@ -97,16 +97,21 @@ static void set_to_memory(ivl_memory_t mem, unsigned idx, unsigned bit) * a calculated assign. */ static void assign_to_lvariable(ivl_lval_t lval, unsigned idx, - unsigned bit, unsigned delay) + unsigned bit, unsigned delay, + int delay_in_index_flag) { ivl_signal_t sig = ivl_lval_sig(lval); unsigned part_off = ivl_lval_part_off(lval); + char *delay_suffix = delay_in_index_flag? "/d" : ""; + if (ivl_lval_mux(lval)) - fprintf(vvp_out, " %%assign/x0 V_%s, %u, %u;\n", + fprintf(vvp_out, " %%assign/x0%s V_%s, %u, %u;\n", + delay_suffix, vvp_mangle_id(ivl_signal_name(sig)), delay, bit); else - fprintf(vvp_out, " %%assign V_%s[%u], %u, %u;\n", + fprintf(vvp_out, " %%assign%s V_%s[%u], %u, %u;\n", + delay_suffix, vvp_mangle_id(ivl_signal_name(sig)), idx+part_off, delay, bit); } @@ -127,6 +132,13 @@ static void calculate_into_x0(ivl_expr_t expr) clr_vector(vec); } +static void calculate_into_x1(ivl_expr_t expr) +{ + struct vector_info vec = draw_eval_expr(expr); + fprintf(vvp_out, " %%ix/get 1, %u, %u;\n", vec.base, vec.wid); + clr_vector(vec); +} + static int show_stmt_assign(ivl_statement_t net) { ivl_lval_t lval; @@ -239,10 +251,9 @@ static int show_stmt_assign_nb(ivl_statement_t net) ivl_memory_t mem; unsigned long delay = 0; - if (del != 0) { - /* XXXX Only support constant values. */ - assert(ivl_expr_type(del) == IVL_EX_ULONG); + if (del && (ivl_expr_type(del) == IVL_EX_ULONG)) { delay = ivl_expr_uvalue(del); + del = 0; } /* Handle the special case that the r-value is a constant. We @@ -255,6 +266,9 @@ static int show_stmt_assign_nb(ivl_statement_t net) unsigned wid = ivl_expr_width(rval); unsigned cur_rbit = 0; + if (del != 0) + calculate_into_x1(del); + for (lidx = 0 ; lidx < ivl_stmt_lvals(net) ; lidx += 1) { unsigned idx; unsigned bit_limit = wid - cur_rbit; @@ -277,19 +291,26 @@ static int show_stmt_assign_nb(ivl_statement_t net) assign_to_memory(mem, idx, bitchar_to_idx(bits[cur_rbit]), delay); + else if (del != 0) + assign_to_lvariable(lval, idx, + bitchar_to_idx(bits[cur_rbit]), + 1, 1); else assign_to_lvariable(lval, idx, bitchar_to_idx(bits[cur_rbit]), - delay); - + delay, 0); cur_rbit += 1; } for (idx = bit_limit; idx < ivl_lval_pins(lval); idx += 1) if (mem) assign_to_memory(mem, idx, 0, delay); + else if (del != 0) + assign_to_lvariable(lval, idx, 0, + 1, 1); else - assign_to_lvariable(lval, idx, 0, delay); + assign_to_lvariable(lval, idx, 0, + delay, 0); } return 0; @@ -301,6 +322,9 @@ static int show_stmt_assign_nb(ivl_statement_t net) unsigned lidx; unsigned cur_rbit = 0; + if (del != 0) + calculate_into_x1(del); + for (lidx = 0 ; lidx < ivl_stmt_lvals(net) ; lidx += 1) { unsigned idx; unsigned bit_limit = wid - cur_rbit; @@ -325,8 +349,12 @@ static int show_stmt_assign_nb(ivl_statement_t net) : (res.base+cur_rbit); if (mem) assign_to_memory(mem, idx, bidx, delay); + else if (del != 0) + assign_to_lvariable(lval, idx, bidx, + 1, 1); else - assign_to_lvariable(lval, idx, bidx, delay); + assign_to_lvariable(lval, idx, bidx, + delay, 0); cur_rbit += 1; } @@ -334,8 +362,10 @@ static int show_stmt_assign_nb(ivl_statement_t net) for (idx = bit_limit ; idx < ivl_lval_pins(lval) ; idx += 1) if (mem) assign_to_memory(mem, idx, 0, delay); + else if (del != 0) + assign_to_lvariable(lval, idx, 0, 1, 1); else - assign_to_lvariable(lval, idx, 0, delay); + assign_to_lvariable(lval, idx, 0, delay, 0); } @@ -1105,6 +1135,11 @@ int draw_func_definition(ivl_scope_t scope) /* * $Log: vvp_process.c,v $ + * Revision 1.56 2002/04/21 22:31:02 steve + * Redo handling of assignment internal delays. + * Leave it possible for them to be calculated + * at run time. + * * Revision 1.55 2002/04/14 19:19:21 steve * Handle empty true case of conditional statements. *