From a95463ff81f14b184bcd5f9b1948dc742ba71ecd Mon Sep 17 00:00:00 2001 From: steve Date: Sat, 9 Aug 2003 03:23:03 +0000 Subject: [PATCH] Add support for IVL_LPM_MULT device. --- expr_synth.cc | 44 +++++++++++++++++++++++++- netlist.h | 6 +++- tgt-fpga/d-lpm.c | 79 +++++++++++++++++++++++++++++++++++++++++++++-- tgt-fpga/device.h | 7 ++++- tgt-fpga/gates.c | 14 ++++++++- 5 files changed, 144 insertions(+), 6 deletions(-) diff --git a/expr_synth.cc b/expr_synth.cc index 33267bd41..a462b9305 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.46 2003/07/26 03:34:42 steve Exp $" +#ident "$Id: expr_synth.cc,v 1.47 2003/08/09 03:23:40 steve Exp $" #endif # include "config.h" @@ -316,6 +316,45 @@ NetNet* NetEBComp::synthesize(Design*des) return osig; } +NetNet* NetEBMult::synthesize(Design*des) +{ + NetNet*lsig = left_->synthesize(des); + NetNet*rsig = right_->synthesize(des); + + if (lsig == 0) + return 0; + + if (rsig == 0) + return 0; + + NetScope*scope = lsig->scope(); + assert(scope); + + NetMult*mult = new NetMult(scope, scope->local_symbol(), + expr_width(), + lsig->pin_count(), + rsig->pin_count()); + des->add_node(mult); + + mult->set_signed( has_sign() ); + mult->set_line(*this); + + for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1) + connect(mult->pin_DataA(idx), lsig->pin(idx)); + + for (unsigned idx = 0 ; idx < rsig->pin_count() ; idx += 1) + connect(mult->pin_DataB(idx), lsig->pin(idx)); + + NetNet*osig = new NetNet(scope, scope->local_symbol(), + NetNet::IMPLICIT, expr_width()); + osig->local_flag(true); + + for (unsigned idx = 0 ; idx < osig->pin_count() ; idx += 1) + connect(mult->pin_Result(idx), osig->pin(idx)); + + return osig; +} + NetNet* NetEBDiv::synthesize(Design*des) { cerr << get_line() << ": internal error: cannot synthesize division: " @@ -770,6 +809,9 @@ NetNet* NetESignal::synthesize(Design*des) /* * $Log: expr_synth.cc,v $ + * Revision 1.47 2003/08/09 03:23:40 steve + * Add support for IVL_LPM_MULT device. + * * Revision 1.46 2003/07/26 03:34:42 steve * Start handling pad of expressions in code generators. * diff --git a/netlist.h b/netlist.h index 3dbcf30cb..721e232b9 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.295 2003/07/26 03:34:42 steve Exp $" +#ident "$Id: netlist.h,v 1.296 2003/08/09 03:23:40 steve Exp $" #endif /* @@ -2525,6 +2525,7 @@ class NetEBMult : public NetEBinary { virtual bool set_width(unsigned w); virtual NetEBMult* dup_expr() const; virtual NetExpr* eval_tree(); + virtual NetNet* synthesize(Design*); private: @@ -3315,6 +3316,9 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.296 2003/08/09 03:23:40 steve + * Add support for IVL_LPM_MULT device. + * * Revision 1.295 2003/07/26 03:34:42 steve * Start handling pad of expressions in code generators. * diff --git a/tgt-fpga/d-lpm.c b/tgt-fpga/d-lpm.c index 643906428..ffebc31be 100644 --- a/tgt-fpga/d-lpm.c +++ b/tgt-fpga/d-lpm.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: d-lpm.c,v 1.3 2003/08/09 02:40:50 steve Exp $" +#ident "$Id: d-lpm.c,v 1.4 2003/08/09 03:23:03 steve Exp $" #endif /* @@ -581,6 +581,77 @@ static void lpm_show_add(ivl_lpm_t net) } } +static void lpm_show_mult(ivl_lpm_t net) +{ + char name[64]; + unsigned idx; + + edif_cell_t cell; + edif_cellref_t ref; + edif_joint_t jnt; + + sprintf(name, "mult%u", ivl_lpm_width(net)); + cell = edif_xlibrary_findcell(xlib, name); + + if (cell == 0) { + cell = edif_xcell_create(xlib, strdup(name), + 3 * ivl_lpm_width(net)); + + for (idx = 0 ; idx < ivl_lpm_width(net) ; idx += 1) { + + sprintf(name, "Result%u", idx); + edif_cell_portconfig(cell, idx*3+0, + strdup(name), + IVL_SIP_OUTPUT); + + sprintf(name, "DataA%u", idx); + edif_cell_portconfig(cell, idx*3+1, + strdup(name), + IVL_SIP_INPUT); + + sprintf(name, "DataB%u", idx); + edif_cell_portconfig(cell, idx*3+2, + strdup(name), + IVL_SIP_INPUT); + } + + edif_cell_pstring(cell, "LPM_Type", "LPM_MULT"); + edif_cell_pinteger(cell, "LPM_WidthP", ivl_lpm_width(net)); + edif_cell_pinteger(cell, "LPM_WidthA", ivl_lpm_width(net)); + edif_cell_pinteger(cell, "LPM_WidthB", ivl_lpm_width(net)); + } + + ref = edif_cellref_create(edf, cell); + + for (idx = 0 ; idx < ivl_lpm_width(net) ; idx += 1) { + unsigned pin; + ivl_nexus_t nex; + + sprintf(name, "Result%u", idx); + pin = edif_cell_port_byname(cell, name); + + jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, idx)); + edif_add_to_joint(jnt, ref, pin); + + if ( (nex = ivl_lpm_data(net, idx)) ) { + sprintf(name, "DataA%u", idx); + pin = edif_cell_port_byname(cell, name); + + jnt = edif_joint_of_nexus(edf, nex); + edif_add_to_joint(jnt, ref, pin); + } + + if ( (nex = ivl_lpm_datab(net, idx)) ) { + sprintf(name, "DataB%u", idx); + pin = edif_cell_port_byname(cell, name); + + jnt = edif_joint_of_nexus(edf, nex); + edif_add_to_joint(jnt, ref, pin); + } + } + +} + const struct device_s d_lpm_edif = { lpm_show_header, lpm_show_footer, @@ -595,11 +666,15 @@ const struct device_s d_lpm_edif = { lpm_show_add, /* show_add */ lpm_show_add, /* show_sub */ 0, /* show_shiftl */ - 0 /* show_shiftr */ + 0, /* show_shiftr */ + lpm_show_mult /* show_mult */ }; /* * $Log: d-lpm.c,v $ + * Revision 1.4 2003/08/09 03:23:03 steve + * Add support for IVL_LPM_MULT device. + * * Revision 1.3 2003/08/09 02:40:50 steve * Generate LPM_FF devices. * diff --git a/tgt-fpga/device.h b/tgt-fpga/device.h index d2afccc65..a84662320 100644 --- a/tgt-fpga/device.h +++ b/tgt-fpga/device.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: device.h,v 1.11 2003/06/24 03:55:00 steve Exp $" +#ident "$Id: device.h,v 1.12 2003/08/09 03:23:03 steve Exp $" #endif # include @@ -61,6 +61,8 @@ struct device_s { /* These methods draw SHIFT devices */ void (*show_shiftl)(ivl_lpm_t net); void (*show_shiftr)(ivl_lpm_t net); + /* Multipliers */ + void (*show_mult)(ivl_lpm_t net); }; /* @@ -75,6 +77,9 @@ extern device_t device_from_arch(const char*arch); /* * $Log: device.h,v $ + * Revision 1.12 2003/08/09 03:23:03 steve + * Add support for IVL_LPM_MULT device. + * * Revision 1.11 2003/06/24 03:55:00 steve * Add ivl_synthesis_cell support for virtex2. * diff --git a/tgt-fpga/gates.c b/tgt-fpga/gates.c index 8884c7585..fca23a8b5 100644 --- a/tgt-fpga/gates.c +++ b/tgt-fpga/gates.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: gates.c,v 1.12 2003/08/07 04:04:01 steve Exp $" +#ident "$Id: gates.c,v 1.13 2003/08/09 03:23:03 steve Exp $" #endif # include @@ -114,6 +114,15 @@ static void show_gate_lpm(ivl_lpm_t net) device->show_mux(net); break; + case IVL_LPM_MULT: + if (device->show_mult == 0) { + fprintf(stderr, "fpga.tgt: IVL_LPM_MULT not supported" + " by this target.\n"); + return; + } + device->show_mult(net); + break; + case IVL_LPM_SHIFTL: if (device->show_shiftl == 0) { fprintf(stderr, "fpga.tgt: IVL_LPM_SHIFTL not supported" @@ -159,6 +168,9 @@ int show_scope_gates(ivl_scope_t net, void*x) /* * $Log: gates.c,v $ + * Revision 1.13 2003/08/09 03:23:03 steve + * Add support for IVL_LPM_MULT device. + * * Revision 1.12 2003/08/07 04:04:01 steve * Add an LPM device type. *