From ca488dff4efb6b9830b62dc9e8b4c4b8910ca3c4 Mon Sep 17 00:00:00 2001 From: steve Date: Sat, 19 Mar 2005 06:23:49 +0000 Subject: [PATCH] Handle LPM shifts. --- elab_net.cc | 13 +++- tgt-stub/stub.c | 72 +++++++++++--------- tgt-vvp/vvp_scope.c | 36 +++------- vvp/README.txt | 13 ++-- vvp/arith.cc | 162 ++++++++++++++++++-------------------------- vvp/arith.h | 17 +++-- vvp/compile.cc | 83 ++--------------------- 7 files changed, 149 insertions(+), 247 deletions(-) diff --git a/elab_net.cc b/elab_net.cc index 67e589e5d..9c3eef401 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.156 2005/03/18 02:56:03 steve Exp $" +#ident "$Id: elab_net.cc,v 1.157 2005/03/19 06:23:49 steve Exp $" #endif # include "config.h" @@ -1130,8 +1130,12 @@ NetNet* PEBinary::elaborate_net_shift_(Design*des, NetScope*scope, connect(osig->pin(0), gate->pin_Result()); // Connect the lsig (the left expression) to the Data input, - // and pad it if necessary with constant zeros. - assert(lsig->vector_width() == lwidth); + // and pad it if necessary. The lwidth is the width of the + // NetCLShift gate, and the D input must match. + if (lsig->vector_width() < lwidth) + lsig = pad_to_width(des, lsig, lwidth); + + assert(lsig->vector_width() <= lwidth); connect(lsig->pin(0), gate->pin_Data()); // Connect the rsig (the shift amount expression) to the @@ -2490,6 +2494,9 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope, /* * $Log: elab_net.cc,v $ + * Revision 1.157 2005/03/19 06:23:49 steve + * Handle LPM shifts. + * * Revision 1.156 2005/03/18 02:56:03 steve * Add support for LPM_UFUNC user defined functions. * diff --git a/tgt-stub/stub.c b/tgt-stub/stub.c index d0892804e..d88339bd6 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.117 2005/03/18 02:56:04 steve Exp $" +#ident "$Id: stub.c,v 1.118 2005/03/19 06:23:49 steve Exp $" #endif # include "config.h" @@ -594,6 +594,37 @@ static void show_lpm_repeat(ivl_lpm_t net) } } +static void show_lpm_shift(ivl_lpm_t net, const char*shift_dir) +{ + ivl_nexus_t nex; + unsigned width = ivl_lpm_width(net); + + fprintf(out, " LPM_SHIFT%s %s: \n", shift_dir, + ivl_lpm_basename(net), width); + + nex = ivl_lpm_q(net, 0); + fprintf(out, " Q: %s\n", ivl_nexus_name(nex)); + + if (width != width_of_nexus(nex)) { + fprintf(out, " ERROR: Q output nexus width=%u " + "does not match part width\n", width_of_nexus(nex)); + stub_errors += 1; + } + + nex = ivl_lpm_data(net, 0); + fprintf(out, " D: %s\n", ivl_nexus_name(nex)); + + if (width != width_of_nexus(nex)) { + fprintf(out, " ERROR: Q output nexus width=%u " + "does not match part width\n", width_of_nexus(nex)); + stub_errors += 1; + } + + nex = ivl_lpm_data(net, 1); + fprintf(out, " S: %s \n", + ivl_nexus_name(nex), width_of_nexus(nex)); +} + static void show_lpm_sub(ivl_lpm_t net) { unsigned width = ivl_lpm_width(net); @@ -671,37 +702,13 @@ static void show_lpm(ivl_lpm_t net) show_lpm_re(net); break; - case IVL_LPM_SHIFTL: { - fprintf(out, " LPM_SHIFTL %s: \n", - ivl_lpm_basename(net), width, ivl_lpm_selects(net), - ivl_lpm_signed(net)? "signed" : "unsigned"); - for (idx = 0 ; idx < width ; idx += 1) - fprintf(out, " Q %u: %s\n", idx, - ivl_nexus_name(ivl_lpm_q(net, idx))); - for (idx = 0 ; idx < width ; idx += 1) - fprintf(out, " Data A %u: %s\n", idx, - ivl_nexus_name(ivl_lpm_data(net, idx))); - for (idx = 0 ; idx < ivl_lpm_selects(net) ; idx += 1) - fprintf(out, " Shift %u: %s\n", idx, - ivl_nexus_name(ivl_lpm_select(net, idx))); - break; - } + case IVL_LPM_SHIFTL: + show_lpm_shift(net, "L"); + break; - case IVL_LPM_SHIFTR: { - fprintf(out, " LPM_SHIFTR %s: \n", - ivl_lpm_basename(net), width, ivl_lpm_selects(net), - ivl_lpm_signed(net)? "signed" : "unsigned"); - for (idx = 0 ; idx < width ; idx += 1) - fprintf(out, " Q %u: %s\n", idx, - ivl_nexus_name(ivl_lpm_q(net, idx))); - for (idx = 0 ; idx < width ; idx += 1) - fprintf(out, " Data A %u: %s\n", idx, - ivl_nexus_name(ivl_lpm_data(net, idx))); - for (idx = 0 ; idx < ivl_lpm_selects(net) ; idx += 1) - fprintf(out, " Shift %u: %s\n", idx, - ivl_nexus_name(ivl_lpm_select(net, idx))); - break; - } + case IVL_LPM_SHIFTR: + show_lpm_shift(net, "R"); + break; case IVL_LPM_SUB: show_lpm_sub(net); @@ -1216,6 +1223,9 @@ int target_design(ivl_design_t des) /* * $Log: stub.c,v $ + * Revision 1.118 2005/03/19 06:23:49 steve + * Handle LPM shifts. + * * Revision 1.117 2005/03/18 02:56:04 steve * Add support for LPM_UFUNC user defined functions. * diff --git a/tgt-vvp/vvp_scope.c b/tgt-vvp/vvp_scope.c index a418546cd..9a17f47ea 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.122 2005/03/18 02:56:04 steve Exp $" +#ident "$Id: vvp_scope.c,v 1.123 2005/03/19 06:23:49 steve Exp $" #endif # include "vvp_priv.h" @@ -1674,40 +1674,19 @@ static void draw_lpm_ff(ivl_lpm_t net) static void draw_lpm_shiftl(ivl_lpm_t net) { - unsigned idx, width, selects; - unsigned selwid; + unsigned width = ivl_lpm_width(net); - width = ivl_lpm_width(net); - selects = ivl_lpm_selects(net); - - /* The .shift device can only take as many select inputs as - the width of the device. - - XXXX I should make some sort of overflow gate for this? If - any high bits are set, then the shift is certain to be - *way* beyond the width of the left shifted value. XXXX */ - selwid = selects; - if (selwid > width) - selwid = width; if (ivl_lpm_type(net) == IVL_LPM_SHIFTR) fprintf(vvp_out, "L_%p .shift/r %u", net, width); else fprintf(vvp_out, "L_%p .shift/l %u", net, width); - for (idx = 0 ; idx < width ; idx += 1) { - fprintf(vvp_out, ", "); - draw_input_from_net(ivl_lpm_data(net, idx)); - } + fprintf(vvp_out, ", "); + draw_input_from_net(ivl_lpm_data(net, 0)); - for (idx = 0 ; idx < selwid ; idx += 1) { - fprintf(vvp_out, ", "); - draw_input_from_net(ivl_lpm_select(net, idx)); - } - - for (idx = selwid ; idx < width ; idx += 1) { - fprintf(vvp_out, ", C<0>"); - } + fprintf(vvp_out, ", "); + draw_input_from_net(ivl_lpm_data(net, 1)); fprintf(vvp_out, ";\n"); } @@ -2007,6 +1986,9 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent) /* * $Log: vvp_scope.c,v $ + * Revision 1.123 2005/03/19 06:23:49 steve + * Handle LPM shifts. + * * Revision 1.122 2005/03/18 02:56:04 steve * Add support for LPM_UFUNC user defined functions. * diff --git a/vvp/README.txt b/vvp/README.txt index bba2e57b8..af21e138f 100644 --- a/vvp/README.txt +++ b/vvp/README.txt @@ -1,7 +1,7 @@ /* * Copyright (c) 2001 Stephen Williams (steve@icarus.com) * - * $Id: README.txt,v 1.61 2005/03/18 02:56:04 steve Exp $ + * $Id: README.txt,v 1.62 2005/03/19 06:23:49 steve Exp $ */ VVP SIMULATION ENGINE @@ -598,11 +598,14 @@ STRUCTURAL SHIFTER STATEMENTS: Variable shifts in structural context are implemented with .shift statements: -