diff --git a/PDelays.cc b/PDelays.cc index 0f72a3a51..5e5862567 100644 --- a/PDelays.cc +++ b/PDelays.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: PDelays.cc,v 1.11 2003/06/21 01:21:42 steve Exp $" +#ident "$Id: PDelays.cc,v 1.12 2006/01/02 05:33:19 steve Exp $" #endif # include "config.h" @@ -62,8 +62,7 @@ void PDelays::set_delays(const svector*del, bool df) delete_flag_ = df; } -static unsigned long calculate_val(Design*des, NetScope*scope, - const PExpr*expr) +static NetExpr*calculate_val(Design*des, NetScope*scope, const PExpr*expr) { NetExpr*dex = expr->elaborate_expr(des, scope); @@ -85,7 +84,9 @@ static unsigned long calculate_val(Design*des, NetScope*scope, delay = 0; delete tmp; - return delay; + NetEConst*tmp2 = new NetEConst(verinum(delay)); + tmp2->set_line(*expr); + return tmp2; } @@ -96,23 +97,19 @@ static unsigned long calculate_val(Design*des, NetScope*scope, des->scale_to_precision(fn.as_ulong(), scope); delete tmp; - return delay; + NetEConst*tmp2 = new NetEConst(verinum(delay)); + tmp2->set_line(*expr); + return tmp2; } - /* Oops, cannot evaluate down to a constant. Error message. */ - delete dex; - - cerr << expr->get_line() << ": sorry: non-constant " - << "delays not supported here: " << *expr << endl; - des->errors += 1; - return 0; - + /* Oops, cannot evaluate down to a constant. */ + return dex; } void PDelays::eval_delays(Design*des, NetScope*scope, - unsigned long&rise_time, - unsigned long&fall_time, - unsigned long&decay_time) const + NetExpr*&rise_time, + NetExpr*&fall_time, + NetExpr*&decay_time) const { assert(scope); @@ -146,6 +143,9 @@ void PDelays::eval_delays(Design*des, NetScope*scope, /* * $Log: PDelays.cc,v $ + * Revision 1.12 2006/01/02 05:33:19 steve + * Node delays can be more general expressions in structural contexts. + * * Revision 1.11 2003/06/21 01:21:42 steve * Harmless fixup of warnings. * diff --git a/PDelays.h b/PDelays.h index d62efa189..3c9349869 100644 --- a/PDelays.h +++ b/PDelays.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: PDelays.h,v 1.7 2002/08/12 01:34:58 steve Exp $" +#ident "$Id: PDelays.h,v 1.8 2006/01/02 05:33:19 steve Exp $" #endif # include "svector.h" @@ -34,6 +34,7 @@ using namespace std; class Design; class NetScope; +class NetExpr; class PExpr; /* @@ -53,9 +54,9 @@ class PDelays { void set_delays(const svector*del, bool delete_flag=true); void eval_delays(Design*des, NetScope*scope, - unsigned long&rise_time, - unsigned long&fall_time, - unsigned long&decay_time) const; + NetExpr*&rise_time, + NetExpr*&fall_time, + NetExpr*&decay_time) const; void dump_delays(ostream&out) const; @@ -72,6 +73,9 @@ ostream& operator << (ostream&o, const PDelays&); /* * $Log: PDelays.h,v $ + * Revision 1.8 2006/01/02 05:33:19 steve + * Node delays can be more general expressions in structural contexts. + * * Revision 1.7 2002/08/12 01:34:58 steve * conditional ident string using autoconfig. * diff --git a/PExpr.h b/PExpr.h index a9387ca17..17491d304 100644 --- a/PExpr.h +++ b/PExpr.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: PExpr.h,v 1.75 2005/12/07 04:04:23 steve Exp $" +#ident "$Id: PExpr.h,v 1.76 2006/01/02 05:33:19 steve Exp $" #endif # include @@ -66,9 +66,9 @@ class PExpr : public LineInfo { // continuous assign or other wholly structural context. virtual NetNet* elaborate_net(Design*des, NetScope*scope, unsigned lwidth, - unsigned long rise, - unsigned long fall, - unsigned long decay, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, Link::strength_t drive0 =Link::STRONG, Link::strength_t drive1 =Link::STRONG) const; @@ -129,9 +129,9 @@ class PEConcat : public PExpr { bool implicit_net_ok =false) const; virtual NetNet* elaborate_net(Design*des, NetScope*scope, unsigned width, - unsigned long rise, - unsigned long fall, - unsigned long decay, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, Link::strength_t drive0, Link::strength_t drive1) const; virtual NetExpr*elaborate_expr(Design*des, NetScope*, @@ -199,9 +199,9 @@ class PEFNumber : public PExpr { virtual NetNet* elaborate_net(Design*des, NetScope*scope, unsigned lwidth, - unsigned long rise, - unsigned long fall, - unsigned long decay, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, Link::strength_t drive0, Link::strength_t drive1) const; @@ -233,9 +233,9 @@ class PEIdent : public PExpr { // Structural r-values are OK. virtual NetNet* elaborate_net(Design*des, NetScope*scope, unsigned lwidth, - unsigned long rise, - unsigned long fall, - unsigned long decay, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, Link::strength_t drive0, Link::strength_t drive1) const; @@ -294,15 +294,15 @@ class PEIdent : public PExpr { NetNet* elaborate_net_ram_(Design*des, NetScope*scope, NetMemory*mem, unsigned lwidth, - unsigned long rise, - unsigned long fall, - unsigned long decay) const; + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay) const; NetNet* elaborate_net_bitmux_(Design*des, NetScope*scope, NetNet*sig, - unsigned long rise, - unsigned long fall, - unsigned long decay, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, Link::strength_t drive0, Link::strength_t drive1) const; @@ -332,9 +332,9 @@ class PENumber : public PExpr { virtual void dump(ostream&) const; virtual NetNet* elaborate_net(Design*des, NetScope*scope, unsigned lwidth, - unsigned long rise, - unsigned long fall, - unsigned long decay, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, Link::strength_t drive0, Link::strength_t drive1) const; virtual NetEConst*elaborate_expr(Design*des, NetScope*, @@ -370,9 +370,9 @@ class PEString : public PExpr { virtual void dump(ostream&) const; virtual NetNet* elaborate_net(Design*des, NetScope*scope, unsigned width, - unsigned long rise, - unsigned long fall, - unsigned long decay, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, Link::strength_t drive0, Link::strength_t drive1) const; virtual NetEConst*elaborate_expr(Design*des, NetScope*, @@ -395,9 +395,9 @@ class PEUnary : public PExpr { virtual void dump(ostream&out) const; virtual NetNet* elaborate_net(Design*des, NetScope*scope, unsigned width, - unsigned long rise, - unsigned long fall, - unsigned long decay, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, Link::strength_t drive0, Link::strength_t drive1) const; virtual NetExpr*elaborate_expr(Design*des, NetScope*, @@ -423,9 +423,9 @@ class PEBinary : public PExpr { virtual void dump(ostream&out) const; virtual NetNet* elaborate_net(Design*des, NetScope*scope, unsigned width, - unsigned long rise, - unsigned long fall, - unsigned long decay, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, Link::strength_t drive0, Link::strength_t drive1) const; virtual NetEBinary*elaborate_expr(Design*des, NetScope*, @@ -442,44 +442,44 @@ class PEBinary : public PExpr { NetNet* elaborate_net_add_(Design*des, NetScope*scope, unsigned lwidth, - unsigned long rise, - unsigned long fall, - unsigned long decay) const; + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay) const; NetNet* elaborate_net_bit_(Design*des, NetScope*scope, unsigned lwidth, - unsigned long rise, - unsigned long fall, - unsigned long decay) const; + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay) const; NetNet* elaborate_net_cmp_(Design*des, NetScope*scope, unsigned lwidth, - unsigned long rise, - unsigned long fall, - unsigned long decay) const; + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay) const; NetNet* elaborate_net_div_(Design*des, NetScope*scope, unsigned lwidth, - unsigned long rise, - unsigned long fall, - unsigned long decay) const; + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay) const; NetNet* elaborate_net_mod_(Design*des, NetScope*scope, unsigned lwidth, - unsigned long rise, - unsigned long fall, - unsigned long decay) const; + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay) const; NetNet* elaborate_net_log_(Design*des, NetScope*scope, unsigned lwidth, - unsigned long rise, - unsigned long fall, - unsigned long decay) const; + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay) const; NetNet* elaborate_net_mul_(Design*des, NetScope*scope, unsigned lwidth, - unsigned long rise, - unsigned long fall, - unsigned long decay) const; + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay) const; NetNet* elaborate_net_shift_(Design*des, NetScope*scope, unsigned lwidth, - unsigned long rise, - unsigned long fall, - unsigned long decay) const; + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay) const; }; /* @@ -497,9 +497,9 @@ class PETernary : public PExpr { virtual void dump(ostream&out) const; virtual NetNet* elaborate_net(Design*des, NetScope*scope, unsigned width, - unsigned long rise, - unsigned long fall, - unsigned long decay, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, Link::strength_t drive0, Link::strength_t drive1) const; virtual NetETernary*elaborate_expr(Design*des, NetScope*, @@ -527,9 +527,9 @@ class PECallFunction : public PExpr { virtual void dump(ostream &) const; virtual NetNet* elaborate_net(Design*des, NetScope*scope, unsigned width, - unsigned long rise, - unsigned long fall, - unsigned long decay, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, Link::strength_t drive0, Link::strength_t drive1) const; virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, @@ -546,6 +546,9 @@ class PECallFunction : public PExpr { /* * $Log: PExpr.h,v $ + * Revision 1.76 2006/01/02 05:33:19 steve + * Node delays can be more general expressions in structural contexts. + * * Revision 1.75 2005/12/07 04:04:23 steve * Allow constant concat expressions. * diff --git a/PGate.cc b/PGate.cc index 070f5d4f7..f96242d30 100644 --- a/PGate.cc +++ b/PGate.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: PGate.cc,v 1.16 2004/02/18 17:11:54 steve Exp $" +#ident "$Id: PGate.cc,v 1.17 2006/01/02 05:33:19 steve Exp $" #endif # include "config.h" @@ -90,12 +90,66 @@ void PGate::elaborate_scope(Design*, NetScope*) const * parameters. This method understands how to handle the different * numbers of expressions. */ + +void PGate::eval_delays(Design*des, NetScope*scope, + NetExpr*&rise_expr, + NetExpr*&fall_expr, + NetExpr*&decay_expr) const +{ + delay_.eval_delays(des, scope, rise_expr, fall_expr, decay_expr); +} + void PGate::eval_delays(Design*des, NetScope*scope, unsigned long&rise_time, unsigned long&fall_time, unsigned long&decay_time) const { - delay_.eval_delays(des, scope, rise_time, fall_time, decay_time); + NetExpr*rise_expr, *fall_expr, *decay_expr; + delay_.eval_delays(des, scope, rise_expr, fall_expr, decay_expr); + + if (rise_expr == 0) { + rise_time = 0; + fall_time = 0; + decay_time = 0; + } + + if (NetEConst*tmp = dynamic_cast (rise_expr)) { + rise_time = tmp->value().as_ulong(); + + } else { + cerr << get_line() << ": error: Delay expressions must be " + << "constant here." << endl; + cerr << get_line() << ": : Cannot calculate " + << *rise_expr << endl; + des->errors += 1; + rise_time = 0; + } + + if (NetEConst*tmp = dynamic_cast (fall_expr)) { + fall_time = tmp->value().as_ulong(); + + } else { + if (fall_expr != rise_expr) { + cerr << get_line() << ": error: Delay expressions must be " + << "constant here." << endl; + cerr << get_line() << ": : Cannot calculate " + << *rise_expr << endl; + } + des->errors += 1; + fall_time = 0; + } + + if (NetEConst*tmp = dynamic_cast (decay_expr)) { + decay_time = tmp->value().as_ulong(); + + } else { + cerr << get_line() << ": error: Delay expressions must be " + << "constant here." << endl; + cerr << get_line() << ": : Cannot calculate " + << *rise_expr << endl; + des->errors += 1; + decay_time = 0; + } } PGAssign::PGAssign(svector*pins) @@ -191,6 +245,9 @@ perm_string PGModule::get_type() /* * $Log: PGate.cc,v $ + * Revision 1.17 2006/01/02 05:33:19 steve + * Node delays can be more general expressions in structural contexts. + * * Revision 1.16 2004/02/18 17:11:54 steve * Use perm_strings for named langiage items. * diff --git a/PGate.h b/PGate.h index 3d8aca025..2e84604dc 100644 --- a/PGate.h +++ b/PGate.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: PGate.h,v 1.29 2004/10/04 01:10:52 steve Exp $" +#ident "$Id: PGate.h,v 1.30 2006/01/02 05:33:19 steve Exp $" #endif # include "svector.h" @@ -66,11 +66,22 @@ class PGate : public LineInfo { perm_string get_name() const { return name_; } + // This method evaluates the delays all the way to an + // integer. If the delay is non-constant, then set the times + // to 0, print an error message and mark an error to the + // design. void eval_delays(Design*des, NetScope*scope, unsigned long&rise_time, unsigned long&fall_time, unsigned long&decay_time) const; + // This evaluates the delays as far as possible, but returns + // an expression, and do not signal errors. + void eval_delays(Design*des, NetScope*scope, + NetExpr*&rise_time, + NetExpr*&fall_time, + NetExpr*&decay_time) const; + unsigned pin_count() const { return pins_? pins_->count() : 0; } const PExpr*pin(unsigned idx) const { return (*pins_)[idx]; } @@ -227,6 +238,9 @@ class PGModule : public PGate { /* * $Log: PGate.h,v $ + * Revision 1.30 2006/01/02 05:33:19 steve + * Node delays can be more general expressions in structural contexts. + * * Revision 1.29 2004/10/04 01:10:52 steve * Clean up spurious trailing white space. * diff --git a/elab_net.cc b/elab_net.cc index f39be3176..cc539b891 100644 --- a/elab_net.cc +++ b/elab_net.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: elab_net.cc,v 1.176 2005/10/11 16:15:52 steve Exp $" +#ident "$Id: elab_net.cc,v 1.177 2006/01/02 05:33:19 steve Exp $" #endif # include "config.h" @@ -39,9 +39,9 @@ static bool must_be_self_determined_flag = false; NetNet* PExpr::elaborate_net(Design*des, NetScope*scope, unsigned, - unsigned long, - unsigned long, - unsigned long, + const NetExpr*, + const NetExpr*, + const NetExpr*, Link::strength_t, Link::strength_t) const { @@ -57,9 +57,9 @@ NetNet* PExpr::elaborate_net(Design*des, NetScope*scope, unsigned, */ NetNet* PEBinary::elaborate_net(Design*des, NetScope*scope, unsigned width, - unsigned long rise, - unsigned long fall, - unsigned long decay, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, Link::strength_t drive0, Link::strength_t drive1) const { @@ -161,9 +161,9 @@ NetNet* PEBinary::elaborate_net(Design*des, NetScope*scope, */ NetNet* PEBinary::elaborate_net_add_(Design*des, NetScope*scope, unsigned lwidth, - unsigned long rise, - unsigned long fall, - unsigned long decay) const + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay) const { NetNet*lsig = left_->elaborate_net(des, scope, lwidth, 0, 0, 0), *rsig = right_->elaborate_net(des, scope, lwidth, 0, 0, 0); @@ -268,9 +268,9 @@ NetNet* PEBinary::elaborate_net_add_(Design*des, NetScope*scope, */ NetNet* PEBinary::elaborate_net_bit_(Design*des, NetScope*scope, unsigned width, - unsigned long rise, - unsigned long fall, - unsigned long decay) const + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay) const { NetNet*lsig = left_->elaborate_net(des, scope, width, 0, 0, 0), *rsig = right_->elaborate_net(des, scope, width, 0, 0, 0); @@ -350,9 +350,9 @@ NetNet* PEBinary::elaborate_net_bit_(Design*des, NetScope*scope, static NetNet* compare_eq_constant(Design*des, NetScope*scope, NetNet*lsig, NetEConst*rexp, char op_code, - unsigned long rise, - unsigned long fall, - unsigned long decay) + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay) { if (op_code != 'e' && op_code != 'n') return 0; @@ -464,9 +464,9 @@ static NetNet* compare_eq_constant(Design*des, NetScope*scope, */ NetNet* PEBinary::elaborate_net_cmp_(Design*des, NetScope*scope, unsigned lwidth, - unsigned long rise, - unsigned long fall, - unsigned long decay) const + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay) const { /* Elaborate the operands of the compare first as expressions @@ -691,9 +691,9 @@ NetNet* PEBinary::elaborate_net_cmp_(Design*des, NetScope*scope, */ NetNet* PEBinary::elaborate_net_div_(Design*des, NetScope*scope, unsigned lwidth, - unsigned long rise, - unsigned long fall, - unsigned long decay) const + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay) const { NetNet*lsig = left_->elaborate_net(des, scope, lwidth, 0, 0, 0); if (lsig == 0) return 0; @@ -771,9 +771,9 @@ NetNet* PEBinary::elaborate_net_div_(Design*des, NetScope*scope, */ NetNet* PEBinary::elaborate_net_mod_(Design*des, NetScope*scope, unsigned lwidth, - unsigned long rise, - unsigned long fall, - unsigned long decay) const + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay) const { NetNet*lsig = left_->elaborate_net(des, scope, 0, 0, 0, 0); if (lsig == 0) return 0; @@ -824,9 +824,9 @@ NetNet* PEBinary::elaborate_net_mod_(Design*des, NetScope*scope, NetNet* PEBinary::elaborate_net_log_(Design*des, NetScope*scope, unsigned lwidth, - unsigned long rise, - unsigned long fall, - unsigned long decay) const + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay) const { NetNet*lsig = left_->elaborate_net(des, scope, 0, 0, 0, 0); NetNet*rsig = right_->elaborate_net(des, scope, 0, 0, 0, 0); @@ -913,9 +913,9 @@ NetNet* PEBinary::elaborate_net_log_(Design*des, NetScope*scope, NetNet* PEBinary::elaborate_net_mul_(Design*des, NetScope*scope, unsigned lwidth, - unsigned long rise, - unsigned long fall, - unsigned long decay) const + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay) const { verinum*lnum = left_->eval_const(des, scope); verinum*rnum = right_->eval_const(des, scope); @@ -1000,9 +1000,9 @@ NetNet* PEBinary::elaborate_net_mul_(Design*des, NetScope*scope, NetNet* PEBinary::elaborate_net_shift_(Design*des, NetScope*scope, unsigned lwidth, - unsigned long rise, - unsigned long fall, - unsigned long decay) const + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay) const { NetNet*lsig = left_->elaborate_net(des, scope, lwidth, 0, 0, 0); if (lsig == 0) return 0; @@ -1196,9 +1196,9 @@ NetNet* PEBinary::elaborate_net_shift_(Design*des, NetScope*scope, */ NetNet* PECallFunction::elaborate_net(Design*des, NetScope*scope, unsigned width, - unsigned long rise, - unsigned long fall, - unsigned long decay, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, Link::strength_t drive0, Link::strength_t drive1) const { @@ -1321,9 +1321,9 @@ NetNet* PECallFunction::elaborate_net(Design*des, NetScope*scope, */ NetNet* PEConcat::elaborate_net(Design*des, NetScope*scope, unsigned, - unsigned long rise, - unsigned long fall, - unsigned long decay, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, Link::strength_t drive0, Link::strength_t drive1) const { @@ -1460,9 +1460,9 @@ NetNet* PEConcat::elaborate_net(Design*des, NetScope*scope, */ NetNet* PEIdent::elaborate_net_bitmux_(Design*des, NetScope*scope, NetNet*sig, - unsigned long rise, - unsigned long fall, - unsigned long decay, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, Link::strength_t drive0, Link::strength_t drive1) const { @@ -1515,9 +1515,9 @@ NetNet* PEIdent::elaborate_net_bitmux_(Design*des, NetScope*scope, NetNet* PEIdent::elaborate_net(Design*des, NetScope*scope, unsigned lwidth, - unsigned long rise, - unsigned long fall, - unsigned long decay, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, Link::strength_t drive0, Link::strength_t drive1) const { @@ -1660,9 +1660,9 @@ NetNet* PEIdent::elaborate_net(Design*des, NetScope*scope, */ NetNet* PEIdent::elaborate_net_ram_(Design*des, NetScope*scope, NetMemory*mem, unsigned lwidth, - unsigned long rise, - unsigned long fall, - unsigned long decay) const + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay) const { assert(scope); @@ -1809,9 +1809,9 @@ NetNet* PEConcat::elaborate_lnet(Design*des, NetScope*scope, */ NetNet* PEFNumber::elaborate_net(Design*des, NetScope*scope, unsigned lwidth, - unsigned long rise, - unsigned long fall, - unsigned long decay, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, Link::strength_t drive0, Link::strength_t drive1) const { @@ -2143,9 +2143,9 @@ NetNet* PEIdent::elaborate_port(Design*des, NetScope*scope) const */ NetNet* PENumber::elaborate_net(Design*des, NetScope*scope, unsigned lwidth, - unsigned long rise, - unsigned long fall, - unsigned long decay, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, Link::strength_t drive0, Link::strength_t drive1) const { @@ -2259,9 +2259,9 @@ NetNet* PENumber::elaborate_net(Design*des, NetScope*scope, */ NetNet* PEString::elaborate_net(Design*des, NetScope*scope, unsigned lwidth, - unsigned long rise, - unsigned long fall, - unsigned long decay, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, Link::strength_t drive0, Link::strength_t drive1) const { @@ -2316,9 +2316,9 @@ NetNet* PEString::elaborate_net(Design*des, NetScope*scope, */ NetNet* PETernary::elaborate_net(Design*des, NetScope*scope, unsigned width, - unsigned long rise, - unsigned long fall, - unsigned long decay, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, Link::strength_t drive0, Link::strength_t drive1) const { @@ -2458,9 +2458,9 @@ NetNet* PETernary::elaborate_net(Design*des, NetScope*scope, NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope, unsigned width, - unsigned long rise, - unsigned long fall, - unsigned long decay, + const NetExpr* rise, + const NetExpr* fall, + const NetExpr* decay, Link::strength_t drive0, Link::strength_t drive1) const { @@ -2645,6 +2645,9 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope, /* * $Log: elab_net.cc,v $ + * Revision 1.177 2006/01/02 05:33:19 steve + * Node delays can be more general expressions in structural contexts. + * * Revision 1.176 2005/10/11 16:15:52 steve * Logical or/and return VT_LOGIC type. * diff --git a/elaborate.cc b/elaborate.cc index 7a2e2f10c..b979a2f46 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: elaborate.cc,v 1.332 2005/11/26 00:35:42 steve Exp $" +#ident "$Id: elaborate.cc,v 1.333 2006/01/02 05:33:19 steve Exp $" #endif # include "config.h" @@ -75,7 +75,7 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const { assert(scope); - unsigned long rise_time, fall_time, decay_time; + NetExpr* rise_time, *fall_time, *decay_time; eval_delays(des, scope, rise_time, fall_time, decay_time); Link::strength_t drive0 = drive_type(strength0()); @@ -204,10 +204,20 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const if (debug_elaborate) { cerr << get_line() << ": debug: PGAssign: " << "Connect lval to " << id->path() - << " through bufz. delay=(" - << rise_time << ":" - << fall_time << ":" - << decay_time << ")" << endl; + << " through bufz. delay=("; + if (rise_time) + cerr << *rise_time << ":"; + else + cerr << ":"; + if (fall_time) + cerr << *fall_time << ":"; + else + cerr << ":"; + if (decay_time) + cerr << *decay_time; + else + cerr << ""; + cerr << ")" << endl; } NetBUFZ*dev = new NetBUFZ(scope, scope->local_symbol(), @@ -332,7 +342,7 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const /* Detect the special case that the l-value width exactly matches the gate count. In this case, we will make a single gate that has the desired vector width. */ - if (lval_sig->vector_width() == (long)count) { + if (lval_sig->vector_width() == count) { instance_width = count; count = 1; @@ -359,7 +369,7 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const of the rise and fall times. Finally, if all three values are given, they are taken as specified. */ - unsigned long rise_time, fall_time, decay_time; + NetExpr* rise_time, *fall_time, *decay_time; eval_delays(des, scope, rise_time, fall_time, decay_time); struct attrib_list_t*attrib_list = 0; @@ -522,7 +532,7 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const for (unsigned gdx = 0 ; gdx < count ; gdx += 1) connect(cur[gdx]->pin(idx), sig->pin(0)); - } else if (sig->vector_width() == (long)count) { + } else if (sig->vector_width() == count) { /* Handle the general case that each bit of the value is connected to a different instance. In @@ -1027,6 +1037,7 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const void PGModule::elaborate_udp_(Design*des, PUdp*udp, NetScope*scope) const { + NetExpr*rise_expr =0, *fall_expr =0, *decay_expr =0; perm_string my_name = get_name(); if (my_name == 0) @@ -1035,19 +1046,49 @@ void PGModule::elaborate_udp_(Design*des, PUdp*udp, NetScope*scope) const /* When the parser notices delay expressions in front of a module or primitive, it interprets them as parameter overrides. Correct that misconception here. */ - unsigned long rise_time = 0, fall_time = 0, decay_time = 0; if (overrides_) { PDelays tmp_del; tmp_del.set_delays(overrides_, false); - tmp_del.eval_delays(des, scope, rise_time, fall_time, decay_time); + tmp_del.eval_delays(des, scope, rise_expr, fall_expr, decay_expr); + + if (dynamic_cast (rise_expr)) { + + } else { + cerr << get_line() << ": error: Delay expressions must be " + << "constant for primitives." << endl; + cerr << get_line() << ": : Cannot calculate " + << *rise_expr << endl; + des->errors += 1; + } + + if (dynamic_cast (fall_expr)) { + + } else { + cerr << get_line() << ": error: Delay expressions must be " + << "constant for primitives." << endl; + cerr << get_line() << ": : Cannot calculate " + << *rise_expr << endl; + des->errors += 1; + } + + if (dynamic_cast (decay_expr)) { + + } else { + cerr << get_line() << ": error: Delay expressions must be " + << "constant for primitives." << endl; + cerr << get_line() << ": : Cannot calculate " + << *rise_expr << endl; + des->errors += 1; + } + } assert(udp); NetUDP*net = new NetUDP(scope, my_name, udp->ports.count(), udp); - net->rise_time(rise_time); - net->fall_time(fall_time); - net->decay_time(decay_time); + net->rise_time(rise_expr); + net->fall_time(fall_expr); + net->decay_time(decay_expr); struct attrib_list_t*attrib_list = 0; unsigned attrib_list_n = 0; @@ -3028,6 +3069,9 @@ Design* elaborate(listroots) /* * $Log: elaborate.cc,v $ + * Revision 1.333 2006/01/02 05:33:19 steve + * Node delays can be more general expressions in structural contexts. + * * Revision 1.332 2005/11/26 00:35:42 steve * More precise about r-value width of constants. * diff --git a/ivl_target.h b/ivl_target.h index 37e4edaa3..a865abafd 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 */ #ifdef HAVE_CVS_IDENT -#ident "$Id: ivl_target.h,v 1.163 2005/12/22 15:44:29 steve Exp $" +#ident "$Id: ivl_target.h,v 1.164 2006/01/02 05:33:19 steve Exp $" #endif #ifdef __cplusplus @@ -702,6 +702,22 @@ extern ivl_memory_t ivl_expr_memory(ivl_expr_t net); * drive strengths for the output pin-0, and match the drive values * stored in the ivl_nexus_ptr_t object for the pin. * + * Logic devices have a logic propagation delay. The delay can be any + * expression, although the most common expression is an IVL_EX_NUMBER + * for a number value. The expression already includes scaling for the + * containing module, so the delay value is always taken to be in + * simulation clock ticks. + * + * If the delay is present, then ivl_logic_delay returns a non-nil + * object. If any of the three delays is present, then all three are + * present, even if they are all the same. The compiler will translate + * shorthands into a complete set of delay expressions. + * + * The ivl_logic_delay expression will always be an IVL_EX_NUMBER, an + * IVL_EX_ULONG, or an IVL_EX_SIGNAL. These expressions can easily be + * used in structural contexts. The compiler will take care of + * elaborating more complex expressions to nets. + * * - IVL_LO_PULLUP/IVL_LO_PULLDOWN * These devices are grouped as logic devices with zero inputs because * the outputs have the same characteristics as other logic @@ -725,7 +741,7 @@ extern ivl_logic_t ivl_logic_type(ivl_net_logic_t net); extern ivl_nexus_t ivl_logic_pin(ivl_net_logic_t net, unsigned pin); extern unsigned ivl_logic_pins(ivl_net_logic_t net); extern ivl_udp_t ivl_logic_udp(ivl_net_logic_t net); -extern unsigned ivl_logic_delay(ivl_net_logic_t net, unsigned transition); +extern ivl_expr_t ivl_logic_delay(ivl_net_logic_t net, unsigned transition); extern ivl_drive_t ivl_logic_drive0(ivl_net_logic_t net); extern ivl_drive_t ivl_logic_drive1(ivl_net_logic_t net); extern unsigned ivl_logic_width(ivl_net_logic_t net); @@ -1687,6 +1703,9 @@ _END_DECL /* * $Log: ivl_target.h,v $ + * Revision 1.164 2006/01/02 05:33:19 steve + * Node delays can be more general expressions in structural contexts. + * * Revision 1.163 2005/12/22 15:44:29 steve * Document binary expression use. * diff --git a/netlist.h b/netlist.h index f0cd5119b..1bbb3b83a 100644 --- a/netlist.h +++ b/netlist.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: netlist.h,v 1.353 2005/11/27 05:56:20 steve Exp $" +#ident "$Id: netlist.h,v 1.354 2006/01/02 05:33:19 steve Exp $" #endif /* @@ -105,13 +105,13 @@ class NetObj : public Attrib, public virtual LineInfo { unsigned pin_count() const { return npins_; } - unsigned rise_time() const { return delay1_; } - unsigned fall_time() const { return delay2_; } - unsigned decay_time() const { return delay3_; } + const NetExpr* rise_time() const { return delay1_; } + const NetExpr* fall_time() const { return delay2_; } + const NetExpr* decay_time() const { return delay3_; } - void rise_time(unsigned d) { delay1_ = d; } - void fall_time(unsigned d) { delay2_ = d; } - void decay_time(unsigned d) { delay3_ = d; } + void rise_time(const NetExpr* d) { delay1_ = d; } + void fall_time(const NetExpr* d) { delay2_ = d; } + void decay_time(const NetExpr* d) { delay3_ = d; } Link&pin(unsigned idx); const Link&pin(unsigned idx) const; @@ -124,9 +124,9 @@ class NetObj : public Attrib, public virtual LineInfo { perm_string name_; Link*pins_; const unsigned npins_; - unsigned delay1_; - unsigned delay2_; - unsigned delay3_; + const NetExpr* delay1_; + const NetExpr* delay2_; + const NetExpr* delay3_; }; class Link { @@ -3451,6 +3451,9 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.354 2006/01/02 05:33:19 steve + * Node delays can be more general expressions in structural contexts. + * * Revision 1.353 2005/11/27 05:56:20 steve * Handle bit select of parameter with ranges. * diff --git a/t-dll-api.cc b/t-dll-api.cc index 581939c71..f3db3bb1c 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 */ #ifdef HAVE_CVS_IDENT -#ident "$Id: t-dll-api.cc,v 1.131 2005/08/06 17:58:16 steve Exp $" +#ident "$Id: t-dll-api.cc,v 1.132 2006/01/02 05:33:19 steve Exp $" #endif # include "config.h" @@ -608,7 +608,7 @@ extern "C" ivl_udp_t ivl_logic_udp(ivl_net_logic_t net) return net->udp; } -extern "C" unsigned ivl_logic_delay(ivl_net_logic_t net, unsigned transition) +extern "C" ivl_expr_t ivl_logic_delay(ivl_net_logic_t net, unsigned transition) { assert(transition < 3); return net->delay[transition]; @@ -2033,6 +2033,9 @@ extern "C" ivl_statement_t ivl_stmt_sub_stmt(ivl_statement_t net) /* * $Log: t-dll-api.cc,v $ + * Revision 1.132 2006/01/02 05:33:19 steve + * Node delays can be more general expressions in structural contexts. + * * Revision 1.131 2005/08/06 17:58:16 steve * Implement bi-directional part selects. * diff --git a/t-dll.cc b/t-dll.cc index a3580724f..34fa463d8 100644 --- a/t-dll.cc +++ b/t-dll.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: t-dll.cc,v 1.154 2005/08/06 17:58:16 steve Exp $" +#ident "$Id: t-dll.cc,v 1.155 2006/01/02 05:33:19 steve Exp $" #endif # include "config.h" @@ -602,6 +602,44 @@ void dll_target::logic_attributes(struct ivl_net_logic_s *obj, obj->attr = fill_in_attributes(net); } +void dll_target::make_logic_delays_(struct ivl_net_logic_s*obj, + const NetObj*net) +{ + obj->delay[0] = 0; + obj->delay[1] = 0; + obj->delay[2] = 0; + + /* Translate delay expressions to ivl_target form. Try to + preserve pointer equality, not as a rule but to save on + expression trees. */ + if (net->rise_time()) { + expr_ = 0; + net->rise_time()->expr_scan(this); + obj->delay[0] = expr_; + expr_ = 0; + } + if (net->fall_time()) { + if (net->fall_time() == net->rise_time()) { + obj->delay[1] = obj->delay[0]; + } else { + expr_ = 0; + net->fall_time()->expr_scan(this); + obj->delay[1] = expr_; + expr_ = 0; + } + } + if (net->decay_time()) { + if (net->decay_time() == net->rise_time()) { + obj->delay[2] = obj->delay[0]; + } else { + expr_ = 0; + net->decay_time()->expr_scan(this); + obj->delay[2] = expr_; + expr_ = 0; + } + } +} + /* * Add a bufz object to the scope that contains it. * @@ -682,10 +720,8 @@ bool dll_target::bufz(const NetBUFZ*net) obj->name_ = net->name(); logic_attributes(obj, net); - obj->delay[0] = net->rise_time(); - obj->delay[1] = net->fall_time(); - obj->delay[2] = net->decay_time(); - + make_logic_delays_(obj, net); + scope_add_logic(scope, obj); return true; @@ -859,9 +895,7 @@ void dll_target::logic(const NetLogic*net) logic_attributes(obj, net); - obj->delay[0] = net->rise_time(); - obj->delay[1] = net->fall_time(); - obj->delay[2] = net->decay_time(); + make_logic_delays_(obj, net); scope_add_logic(scope, obj); } @@ -1104,9 +1138,7 @@ void dll_target::udp(const NetUDP*net) obj->scope_= scope; obj->name_ = net->name(); - obj->delay[0] = net->rise_time(); - obj->delay[1] = net->fall_time(); - obj->delay[2] = net->decay_time(); + make_logic_delays_(obj, net); obj->nattr = 0; obj->attr = 0; @@ -2131,6 +2163,9 @@ extern const struct target tgt_dll = { "dll", &dll_target_obj }; /* * $Log: t-dll.cc,v $ + * Revision 1.155 2006/01/02 05:33:19 steve + * Node delays can be more general expressions in structural contexts. + * * Revision 1.154 2005/08/06 17:58:16 steve * Implement bi-directional part selects. * diff --git a/t-dll.h b/t-dll.h index c2bd3617d..e985c90fe 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 */ #ifdef HAVE_CVS_IDENT -#ident "$Id: t-dll.h,v 1.128 2005/07/11 16:56:51 steve Exp $" +#ident "$Id: t-dll.h,v 1.129 2006/01/02 05:33:19 steve Exp $" #endif # include "target.h" @@ -166,6 +166,7 @@ struct dll_target : public target_t, public expr_scan_t { void sub_off_from_expr_(long); void mul_expr_by_const_(long); + void make_logic_delays_(struct ivl_net_logic_s*obj, const NetObj*net); void make_scope_parameters(ivl_scope_t scope, const NetScope*net); static ivl_expr_t expr_from_value_(const verinum&that); @@ -424,7 +425,7 @@ struct ivl_net_logic_s { struct ivl_attribute_s*attr; unsigned nattr; - unsigned delay[3]; + ivl_expr_t delay[3]; }; @@ -670,6 +671,9 @@ struct ivl_statement_s { /* * $Log: t-dll.h,v $ + * Revision 1.129 2006/01/02 05:33:19 steve + * Node delays can be more general expressions in structural contexts. + * * Revision 1.128 2005/07/11 16:56:51 steve * Remove NetVariable and ivl_variable_t structures. * diff --git a/tgt-stub/stub.c b/tgt-stub/stub.c index 2a0636c3a..4c9e520cf 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 */ #ifdef HAVE_CVS_IDENT -#ident "$Id: stub.c,v 1.135 2005/12/22 15:38:33 steve Exp $" +#ident "$Id: stub.c,v 1.136 2006/01/02 05:33:20 steve Exp $" #endif # include "config.h" @@ -1282,6 +1282,23 @@ static void show_signal(ivl_signal_t net) } +static void test_expr_is_delay(ivl_expr_t exp) +{ + switch (ivl_expr_type(exp)) { + case IVL_EX_ULONG: + return; + case IVL_EX_NUMBER: + return; + case IVL_EX_SIGNAL: + return; + default: + break; + } + + fprintf(out, " ERROR: Expression is not a suitable delay\n"); + stub_errors += 1; +} + /* * All logic gates have inputs and outputs that match exactly in * width. For example, and AND gate with 4 bit inputs generates a 4 @@ -1308,10 +1325,10 @@ static void show_logic(ivl_net_logic_t net) fprintf(out, " bufif1 %s", name); break; case IVL_LO_BUFZ: - fprintf(out, " bufz #(%u) %s", ivl_logic_delay(net, 0), name); + fprintf(out, " bufz %s", name); break; case IVL_LO_NOT: - fprintf(out, " not #(%u) %s", ivl_logic_delay(net, 0), name); + fprintf(out, " not %s", name); break; case IVL_LO_OR: fprintf(out, " or %s", name); @@ -1336,9 +1353,21 @@ static void show_logic(ivl_net_logic_t net) break; } - fprintf(out, " \n", - ivl_logic_width(net), ivl_logic_delay(net,0), - ivl_logic_delay(net,1), ivl_logic_delay(net,2)); + fprintf(out, " \n", ivl_logic_width(net)); + + fprintf(out, " \n"); + if (ivl_logic_delay(net,0)) { + test_expr_is_delay(ivl_logic_delay(net,0)); + show_expression(ivl_logic_delay(net,0), 6); + } + if (ivl_logic_delay(net,1)) { + test_expr_is_delay(ivl_logic_delay(net,1)); + show_expression(ivl_logic_delay(net,1), 6); + } + if (ivl_logic_delay(net,2)) { + test_expr_is_delay(ivl_logic_delay(net,2)); + show_expression(ivl_logic_delay(net,2), 6); + } npins = ivl_logic_pins(net); @@ -1551,6 +1580,9 @@ int target_design(ivl_design_t des) /* * $Log: stub.c,v $ + * Revision 1.136 2006/01/02 05:33:20 steve + * Node delays can be more general expressions in structural contexts. + * * Revision 1.135 2005/12/22 15:38:33 steve * More detailed check of binary expressions. * diff --git a/tgt-vvp/eval_expr.c b/tgt-vvp/eval_expr.c index 555339d74..e02628bc2 100644 --- a/tgt-vvp/eval_expr.c +++ b/tgt-vvp/eval_expr.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: eval_expr.c,v 1.128 2005/12/22 15:42:22 steve Exp $" +#ident "$Id: eval_expr.c,v 1.129 2006/01/02 05:33:20 steve Exp $" #endif # include "vvp_priv.h" @@ -57,7 +57,9 @@ int number_is_immediate(ivl_expr_t ex, unsigned lim_wid) const char*bits; unsigned idx; - assert(ivl_expr_type(ex) == IVL_EX_NUMBER); + if (ivl_expr_type(ex) != IVL_EX_NUMBER + && ivl_expr_type(ex) != IVL_EX_ULONG) + return 0; bits = ivl_expr_bits(ex); for (idx = lim_wid ; idx < ivl_expr_width(ex) ; idx += 1) @@ -2175,6 +2177,9 @@ struct vector_info draw_eval_expr(ivl_expr_t exp, int stuff_ok_flag) /* * $Log: eval_expr.c,v $ + * Revision 1.129 2006/01/02 05:33:20 steve + * Node delays can be more general expressions in structural contexts. + * * Revision 1.128 2005/12/22 15:42:22 steve * Pad part selects * diff --git a/tgt-vvp/vvp_scope.c b/tgt-vvp/vvp_scope.c index 04eaf5a2d..a0a8bd9ab 100644 --- a/tgt-vvp/vvp_scope.c +++ b/tgt-vvp/vvp_scope.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: vvp_scope.c,v 1.138 2005/11/25 17:55:26 steve Exp $" +#ident "$Id: vvp_scope.c,v 1.139 2006/01/02 05:33:20 steve Exp $" #endif # include "vvp_priv.h" @@ -945,17 +945,25 @@ static void draw_net_in_scope(ivl_signal_t sig) static void draw_delay(ivl_net_logic_t lptr) { - unsigned d0 = ivl_logic_delay(lptr, 0); - unsigned d1 = ivl_logic_delay(lptr, 1); - unsigned d2 = ivl_logic_delay(lptr, 2); + ivl_expr_t d0 = ivl_logic_delay(lptr, 0); + ivl_expr_t d1 = ivl_logic_delay(lptr, 1); + ivl_expr_t d2 = ivl_logic_delay(lptr, 2); if (d0 == 0 && d1 == 0 && d2 == 0) return; + /* FIXME: Assume that the expression is a constant */ + assert(number_is_immediate(d0, 64)); + assert(number_is_immediate(d1, 64)); + assert(number_is_immediate(d2, 64)); + if (d0 == d1 && d1 == d2) - fprintf(vvp_out, " (%d)", d0); + fprintf(vvp_out, " (%lu)", get_number_immediate(d0)); else - fprintf(vvp_out, " (%d,%d,%d)", d0, d1, d2); + fprintf(vvp_out, " (%lu,%lu,%lu)", + get_number_immediate(d0), + get_number_immediate(d1), + get_number_immediate(d2)); } static void draw_udp_def(ivl_udp_t udp) @@ -1045,9 +1053,11 @@ static void draw_logic_in_scope(ivl_net_logic_t lptr) { unsigned pdx; const char*ltype = "?"; - const char*lcasc = 0x0; + const char*lcasc = 0; char identity_val = '0'; + int need_delay_flag = ivl_logic_delay(lptr,0)? 1 : 0; + unsigned vector_width = width_of_nexus(ivl_logic_pin(lptr, 0)); ivl_drive_t str0, str1; @@ -1207,10 +1217,9 @@ static void draw_logic_in_scope(ivl_net_logic_t lptr) fprintf(vvp_out, "L_%p/%d/%d .functor %s %u", lptr, level, inst, lcasc, vector_width); else { - fprintf(vvp_out, "L_%p .functor %s %u", - lptr, ltype, vector_width); - - draw_delay(lptr); + fprintf(vvp_out, "L_%p%s .functor %s %u", + lptr, need_delay_flag? "/d" : "", + ltype, vector_width); if (str0 != IVL_DR_STRONG || str1 != IVL_DR_STRONG) fprintf(vvp_out, " [%u %u]", str0, str1); @@ -1244,6 +1253,40 @@ static void draw_logic_in_scope(ivl_net_logic_t lptr) /* Free the array of char*. The strings themselves are persistent, held by the ivl_nexus_t objects. */ free(input_strings); + + /* If there are delays, then draw the delay functor to carry + that delay. This is the final output. */ + if (need_delay_flag) { + ivl_expr_t rise_exp = ivl_logic_delay(lptr,0); + ivl_expr_t fall_exp = ivl_logic_delay(lptr,1); + ivl_expr_t decay_exp = ivl_logic_delay(lptr,2); + + if (number_is_immediate(rise_exp,64) + && number_is_immediate(fall_exp,64) + && number_is_immediate(decay_exp,64)) { + + fprintf(vvp_out, "L_%p .delay (%lu,%lu,%lu) L_%p/d;\n", + lptr, get_number_immediate(rise_exp), + get_number_immediate(rise_exp), + get_number_immediate(rise_exp), lptr); + } else { + ivl_signal_t sig; + assert(ivl_expr_type(rise_exp) == IVL_EX_SIGNAL); + assert(ivl_expr_type(fall_exp) == IVL_EX_SIGNAL); + assert(ivl_expr_type(decay_exp) == IVL_EX_SIGNAL); + + fprintf(vvp_out, "L_%p .delay L_%p/d", lptr, lptr); + + sig = ivl_expr_signal(rise_exp); + fprintf(vvp_out, ", V_%p", sig); + + sig = ivl_expr_signal(fall_exp); + fprintf(vvp_out, ", V_%p", sig); + + sig = ivl_expr_signal(decay_exp); + fprintf(vvp_out, ", V_%p;\n", sig); + } + } } static void draw_event_in_scope(ivl_event_t obj) @@ -2110,6 +2153,9 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent) /* * $Log: vvp_scope.c,v $ + * Revision 1.139 2006/01/02 05:33:20 steve + * Node delays can be more general expressions in structural contexts. + * * Revision 1.138 2005/11/25 17:55:26 steve * Put vec8 and vec4 nets into seperate net classes. *