diff --git a/elab_expr.cc b/elab_expr.cc index 8e88efb01..d88524cac 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: elab_expr.cc,v 1.13 1999/12/12 06:03:14 steve Exp $" +#ident "$Id: elab_expr.cc,v 1.14 2000/01/01 06:18:00 steve Exp $" #endif @@ -159,6 +159,42 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, const string&path) const } +NetExpr* PEConcat::elaborate_expr(Design*des, const string&path) const +{ + unsigned repeat = 1; + + /* If there is a repeat expression, then evaluate the constant + value and set the repeat count. */ + if (repeat_) { + verinum*vrep = repeat_->eval_const(des, path); + if (vrep == 0) { + cerr << get_line() << ": error: " + "concatenation repeat expression cannot be evaluated." + << endl; + des->errors += 1; + return 0; + } + + repeat = vrep->as_ulong(); + delete vrep; + } + + /* Make the empty concat expression. */ + NetEConcat*tmp = new NetEConcat(parms_.count(), repeat); + tmp->set_line(*this); + + /* Elaborate all the parameters and attach them to the concat node. */ + for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) { + assert(parms_[idx]); + NetExpr*ex = parms_[idx]->elaborate_expr(des, path); + if (ex == 0) continue; + ex->set_line(*parms_[idx]); + tmp->set(idx, ex); + } + + return tmp; +} + NetExpr* PEIdent::elaborate_expr(Design*des, const string&path) const { // System identifiers show up in the netlist as identifiers. @@ -337,6 +373,9 @@ NetExpr*PETernary::elaborate_expr(Design*des, const string&path) const /* * $Log: elab_expr.cc,v $ + * Revision 1.14 2000/01/01 06:18:00 steve + * Handle synthesis of concatenation. + * * Revision 1.13 1999/12/12 06:03:14 steve * Allow memories without indices in expressions. * diff --git a/elaborate.cc b/elaborate.cc index 613243f8c..727bf2569 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) -#ident "$Id: elaborate.cc,v 1.135 1999/12/14 23:42:16 steve Exp $" +#ident "$Id: elaborate.cc,v 1.136 2000/01/01 06:18:00 steve Exp $" #endif /* @@ -772,41 +772,6 @@ NetNet* PEUnary::elaborate_net(Design*des, const string&path, return sig; } -NetExpr* PEConcat::elaborate_expr(Design*des, const string&path) const -{ - unsigned repeat = 1; - - /* If there is a repeat expression, then evaluate the constant - value and set the repeat count. */ - if (repeat_) { - verinum*vrep = repeat_->eval_const(des, path); - if (vrep == 0) { - cerr << get_line() << ": error: " - "concatenation repeat expression cannot be evaluated." - << endl; - des->errors += 1; - return 0; - } - - repeat = vrep->as_ulong(); - delete vrep; - } - - /* Make the empty concat expression. */ - NetEConcat*tmp = new NetEConcat(parms_.count(), repeat); - tmp->set_line(*this); - - /* Elaborate all the parameters and attach them to the concat node. */ - for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) { - assert(parms_[idx]); - NetExpr*ex = parms_[idx]->elaborate_expr(des, path); - if (ex == 0) continue; - tmp->set(idx, parms_[idx]->elaborate_expr(des, path)); - } - - return tmp; -} - NetExpr* PENumber::elaborate_expr(Design*des, const string&path) const { assert(value_); @@ -2113,6 +2078,9 @@ Design* elaborate(const map&modules, /* * $Log: elaborate.cc,v $ + * Revision 1.136 2000/01/01 06:18:00 steve + * Handle synthesis of concatenation. + * * Revision 1.135 1999/12/14 23:42:16 steve * Detect duplicate scopes. * diff --git a/expr_synth.cc b/expr_synth.cc index e4f91f35f..55cc8c009 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 */ #if !defined(WINNT) -#ident "$Id: expr_synth.cc,v 1.8 1999/12/17 06:18:15 steve Exp $" +#ident "$Id: expr_synth.cc,v 1.9 2000/01/01 06:18:00 steve Exp $" #endif # include "netlist.h" @@ -120,6 +120,31 @@ NetNet* NetEBBits::synthesize(Design*des) return osig; } +NetNet* NetEConcat::synthesize(Design*des) +{ + assert(repeat_ == 1); + + string path = des->local_symbol("SYNTH"); + NetNet*osig = new NetNet(0, path, NetNet::IMPLICIT, expr_width()); + osig->local_flag(true); + + unsigned obit = 0; + for (unsigned idx = parms_.count() ; idx > 0 ; idx -= 1) { + NetNet*tmp = parms_[idx-1]->synthesize(des); + + for (unsigned bit = 0 ; bit < tmp->pin_count() ; bit += 1) { + connect(osig->pin(obit), tmp->pin(bit)); + obit += 1; + } + + if (tmp->local_flag()) + delete tmp; + } + + des->add_signal(osig); + return osig; +} + NetNet* NetEConst::synthesize(Design*des) { string path = des->local_symbol("SYNTH"); @@ -203,6 +228,9 @@ NetNet* NetESignal::synthesize(Design*des) /* * $Log: expr_synth.cc,v $ + * Revision 1.9 2000/01/01 06:18:00 steve + * Handle synthesis of concatenation. + * * Revision 1.8 1999/12/17 06:18:15 steve * Rewrite the cprop functor to use the functor_t interface. * diff --git a/netlist.h b/netlist.h index 0528d09fa..df7cf67c7 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) -#ident "$Id: netlist.h,v 1.105 1999/12/30 04:19:12 steve Exp $" +#ident "$Id: netlist.h,v 1.106 2000/01/01 06:18:00 steve Exp $" #endif /* @@ -1629,6 +1629,7 @@ class NetEConcat : public NetExpr { virtual bool set_width(unsigned w); virtual NetEConcat* dup_expr() const; virtual NetExpr* eval_tree(); + virtual NetNet*synthesize(Design*); virtual void expr_scan(struct expr_scan_t*) const; virtual void dump(ostream&) const; @@ -2081,6 +2082,9 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.106 2000/01/01 06:18:00 steve + * Handle synthesis of concatenation. + * * Revision 1.105 1999/12/30 04:19:12 steve * Propogate constant 0 in low bits of adders. *