diff --git a/design_dump.cc b/design_dump.cc index 19f307282..1e99b8005 100644 --- a/design_dump.cc +++ b/design_dump.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: design_dump.cc,v 1.143 2003/07/05 20:42:08 steve Exp $" +#ident "$Id: design_dump.cc,v 1.144 2003/07/26 03:34:42 steve Exp $" #endif # include "config.h" @@ -941,6 +941,25 @@ void NetEScope::dump(ostream&o) const o << "name() << ">"; } +void NetESelect::dump(ostream&o) const +{ + o << "dump(o); + o << "["; + + if (base_) + base_->dump(o); + else + o << "(0)"; + + o << "+:" << expr_width() << "]>"; +} + void NetESFunc::dump(ostream&o) const { o << name_ << "("; @@ -1049,6 +1068,9 @@ void Design::dump(ostream&o) const /* * $Log: design_dump.cc,v $ + * Revision 1.144 2003/07/26 03:34:42 steve + * Start handling pad of expressions in code generators. + * * Revision 1.143 2003/07/05 20:42:08 steve * Fix some enumeration warnings. * diff --git a/expr_synth.cc b/expr_synth.cc index b4514d555..33267bd41 100644 --- a/expr_synth.cc +++ b/expr_synth.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: expr_synth.cc,v 1.45 2003/06/24 01:38:02 steve Exp $" +#ident "$Id: expr_synth.cc,v 1.46 2003/07/26 03:34:42 steve Exp $" #endif # include "config.h" @@ -643,6 +643,44 @@ NetNet* NetEUReduce::synthesize(Design*des) return osig; } +NetNet* NetESelect::synthesize(Design *des) +{ + // XXXX For now, only support pad form + assert(base_ == 0); + + NetNet*sub = expr_->synthesize(des); + if (sub == 0) + return 0; + + NetScope*scope = sub->scope(); + NetNet*net = new NetNet(scope, scope->local_symbol(), + NetNet::IMPLICIT, expr_width()); + if (has_sign()) { + unsigned idx; + + for (idx = 0 ; idx < sub->pin_count() ; idx += 1) + connect(sub->pin(idx), net->pin(idx)); + + for ( ; idx < net->pin_count(); idx += 1) + connect(sub->pin(sub->pin_count()-1), net->pin(idx)); + + } else { + unsigned idx; + for (idx = 0 ; idx < sub->pin_count() ; idx += 1) + connect(sub->pin(idx), net->pin(idx)); + + NetConst*tmp = new NetConst(scope, scope->local_symbol(), + verinum::V0); + + for ( ; idx < net->pin_count() ; idx += 1) + connect(net->pin(idx), tmp->pin(0)); + + des->add_node(tmp); + } + + return net; +} + /* * Synthesize a ?: operator an a NetMux device. Connect the condition * expression to the select input, then connect the true and false @@ -732,6 +770,9 @@ NetNet* NetESignal::synthesize(Design*des) /* * $Log: expr_synth.cc,v $ + * Revision 1.46 2003/07/26 03:34:42 steve + * Start handling pad of expressions in code generators. + * * Revision 1.45 2003/06/24 01:38:02 steve * Various warnings fixed. * diff --git a/net_nex_input.cc b/net_nex_input.cc index 21eb5c061..1efcada33 100644 --- a/net_nex_input.cc +++ b/net_nex_input.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: net_nex_input.cc,v 1.9 2003/04/22 04:48:29 steve Exp $" +#ident "$Id: net_nex_input.cc,v 1.10 2003/07/26 03:34:42 steve Exp $" #endif # include "config.h" @@ -114,7 +114,7 @@ NexusSet* NetEScope::nex_input() NexusSet* NetESelect::nex_input() { - NexusSet*result = base_->nex_input(); + NexusSet*result = base_? base_->nex_input() : new NexusSet(); NexusSet*tmp = expr_->nex_input(); result->add(*tmp); delete tmp; @@ -377,6 +377,9 @@ NexusSet* NetWhile::nex_input() /* * $Log: net_nex_input.cc,v $ + * Revision 1.10 2003/07/26 03:34:42 steve + * Start handling pad of expressions in code generators. + * * Revision 1.9 2003/04/22 04:48:29 steve * Support event names as expressions elements. * diff --git a/netlist.h b/netlist.h index 5d1d183c5..3dbcf30cb 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.294 2003/07/15 03:49:22 steve Exp $" +#ident "$Id: netlist.h,v 1.295 2003/07/26 03:34:42 steve Exp $" #endif /* @@ -2661,6 +2661,10 @@ class NetEParam : public NetExpr { * selected from it. The base is the expression that identifies the * lsb of the expression, and the wid is the width of the part select, * or 1 for a bit select. + * + * If the base expression is null, then this expression node can be + * used to express width expansion, signed or unsigned depending on + * the has_sign() flag. */ class NetESelect : public NetExpr { @@ -2677,6 +2681,8 @@ class NetESelect : public NetExpr { virtual void expr_scan(struct expr_scan_t*) const; virtual NetEConst* eval_tree(); virtual NetESelect* dup_expr() const; + virtual NetNet*synthesize(Design*des); + virtual void dump(ostream&) const; private: NetExpr*expr_; @@ -3309,6 +3315,9 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.295 2003/07/26 03:34:42 steve + * Start handling pad of expressions in code generators. + * * Revision 1.294 2003/07/15 03:49:22 steve * Spelling fixes. * diff --git a/set_width.cc b/set_width.cc index 4f06a320f..42101dff3 100644 --- a/set_width.cc +++ b/set_width.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: set_width.cc,v 1.32 2003/06/21 01:21:43 steve Exp $" +#ident "$Id: set_width.cc,v 1.33 2003/07/26 03:34:42 steve Exp $" #endif # include "config.h" @@ -93,14 +93,14 @@ bool NetEBAdd::set_width(unsigned w) right_->set_width(wid); if (left_->expr_width() < wid) { - NetExpr*tmp = pad_to_width(left_, wid); - assert(tmp); + NetExpr*tmp = new NetESelect(left_, 0, wid); + tmp->cast_signed(left_->has_sign()); left_ = tmp; } if (right_->expr_width() < wid) { - NetExpr*tmp = pad_to_width(right_, wid); - assert(tmp); + NetExpr*tmp = new NetESelect(right_, 0, wid); + tmp->cast_signed(right_->has_sign()); right_ = tmp; } @@ -411,6 +411,9 @@ bool NetEUReduce::set_width(unsigned w) /* * $Log: set_width.cc,v $ + * Revision 1.33 2003/07/26 03:34:42 steve + * Start handling pad of expressions in code generators. + * * Revision 1.32 2003/06/21 01:21:43 steve * Harmless fixup of warnings. * diff --git a/t-dll-expr.cc b/t-dll-expr.cc index c155a382a..d5d62ddac 100644 --- a/t-dll-expr.cc +++ b/t-dll-expr.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-expr.cc,v 1.37 2003/06/24 01:38:03 steve Exp $" +#ident "$Id: t-dll-expr.cc,v 1.38 2003/07/26 03:34:43 steve Exp $" #endif # include "config.h" @@ -344,7 +344,9 @@ void dll_target::expr_select(const NetESelect*net) ivl_expr_t left = expr_; expr_ = 0; - net->select()->expr_scan(this); + if (net->select()) + net->select()->expr_scan(this); + ivl_expr_t rght = expr_; expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s)); @@ -601,6 +603,9 @@ void dll_target::expr_variable(const NetEVariable*net) /* * $Log: t-dll-expr.cc,v $ + * Revision 1.38 2003/07/26 03:34:43 steve + * Start handling pad of expressions in code generators. + * * Revision 1.37 2003/06/24 01:38:03 steve * Various warnings fixed. * diff --git a/tgt-stub/stub.c b/tgt-stub/stub.c index 0ae399044..07cfa5483 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.80 2003/06/23 01:25:44 steve Exp $" +#ident "$Id: stub.c,v 1.81 2003/07/26 03:34:43 steve Exp $" #endif # include "config.h" @@ -95,10 +95,18 @@ static void show_expression(ivl_expr_t net, unsigned ind) } case IVL_EX_SELECT: - fprintf(out, "%*s\n", ind, "", - width, sign); - show_expression(ivl_expr_oper1(net), ind+3); - show_expression(ivl_expr_oper2(net), ind+3); + /* The SELECT expression can be used to express part + select, or if the base is null vector extension. */ + if (ivl_expr_oper2(net)) { + fprintf(out, "%*s\n", ind, "", + width, sign); + show_expression(ivl_expr_oper1(net), ind+3); + show_expression(ivl_expr_oper2(net), ind+3); + } else { + fprintf(out, "%*s\n", ind, "", + width, sign); + show_expression(ivl_expr_oper1(net), ind+3); + } break; case IVL_EX_STRING: @@ -870,6 +878,9 @@ int target_design(ivl_design_t des) /* * $Log: stub.c,v $ + * Revision 1.81 2003/07/26 03:34:43 steve + * Start handling pad of expressions in code generators. + * * Revision 1.80 2003/06/23 01:25:44 steve * Module attributes make it al the way to ivl_target. * diff --git a/tgt-vvp/eval_expr.c b/tgt-vvp/eval_expr.c index 4dae0ef5a..da7311dae 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.102 2003/06/18 03:55:19 steve Exp $" +#ident "$Id: eval_expr.c,v 1.103 2003/07/26 03:34:43 steve Exp $" #endif # include "vvp_priv.h" @@ -1325,6 +1325,45 @@ static struct vector_info draw_number_expr(ivl_expr_t exp, unsigned wid) return res; } +/* + * The PAD expression takes a smaller node and pads it out to a larger + * value. It will zero extend or sign extend depending on the + * signedness of the expression. + */ +static struct vector_info draw_pad_expr(ivl_expr_t exp, unsigned wid) +{ + struct vector_info subv; + struct vector_info res; + + subv = draw_eval_expr(ivl_expr_oper1(exp), 0); + if (wid == subv.wid) { + if (subv.base >= 8) + save_expression_lookaside(subv.base, exp, wid); + return subv; + } + + res.base = allocate_vector(wid); + res.wid = wid; + + fprintf(vvp_out, " %%mov %u, %u, %u;\n", + res.base, subv.base, subv.wid); + + assert(wid > subv.wid); + + if (ivl_expr_signed(exp)) { + unsigned idx; + for (idx = subv.wid ; idx < res.wid ; idx += 1) + fprintf(vvp_out, " %%mov %u, %u, 1;\n", + res.base+idx, subv.base+subv.wid-1); + } else { + fprintf(vvp_out, " %%mov %u, 0, %u;\n", + res.base+subv.wid, res.wid - subv.wid); + } + + save_expression_lookaside(res.base, exp, wid); + return res; +} + static struct vector_info draw_realnum_expr(ivl_expr_t exp, unsigned wid) { struct vector_info res; @@ -2031,7 +2070,10 @@ struct vector_info draw_eval_expr_wid(ivl_expr_t exp, unsigned wid, break; case IVL_EX_SELECT: - res = draw_select_expr(exp, wid); + if (ivl_expr_oper2(exp) == 0) + res = draw_pad_expr(exp, wid); + else + res = draw_select_expr(exp, wid); break; case IVL_EX_SIGNAL: @@ -2073,6 +2115,9 @@ struct vector_info draw_eval_expr(ivl_expr_t exp, int stuff_ok_flag) /* * $Log: eval_expr.c,v $ + * Revision 1.103 2003/07/26 03:34:43 steve + * Start handling pad of expressions in code generators. + * * Revision 1.102 2003/06/18 03:55:19 steve * Add arithmetic shift operators. *