From 16c50ad810c9a83ffc72f21676a5b1d1893f3ee9 Mon Sep 17 00:00:00 2001 From: steve Date: Sat, 9 Dec 2000 03:42:52 +0000 Subject: [PATCH] Stuff registers into macrocells. --- tgt-pal/Makefile.in | 4 +- tgt-pal/dump_final.c | 59 ++++++++++++++++++++ tgt-pal/enables.c | 8 ++- tgt-pal/fit_reg.c | 127 +++++++++++++++++++++++++++++++++++++++++++ tgt-pal/imain.c | 42 ++++++-------- tgt-pal/priv.h | 10 +++- 6 files changed, 220 insertions(+), 30 deletions(-) create mode 100644 tgt-pal/dump_final.c create mode 100644 tgt-pal/fit_reg.c diff --git a/tgt-pal/Makefile.in b/tgt-pal/Makefile.in index 268b43d03..7e2d928ea 100644 --- a/tgt-pal/Makefile.in +++ b/tgt-pal/Makefile.in @@ -16,7 +16,7 @@ # 59 Temple Place - Suite 330 # Boston, MA 02111-1307, USA # -#ident "$Id: Makefile.in,v 1.2 2000/12/09 01:19:58 steve Exp $" +#ident "$Id: Makefile.in,v 1.3 2000/12/09 03:42:52 steve Exp $" # # SHELL = /bin/sh @@ -50,7 +50,7 @@ all: pal.tgt $(CC) -Wall $(CPPFLAGS) -I$(srcdir)/.. -MD -c $< -o $*.o mv $*.d dep -O = imain.o enables.o pads.o +O = imain.o dump_final.o enables.o fit_reg.o pads.o ifeq (@CYGWIN@,yes) TGTLDFLAGS=-Wl,--enable-auto-image-base -L.. -livl diff --git a/tgt-pal/dump_final.c b/tgt-pal/dump_final.c new file mode 100644 index 000000000..7f27e9e3b --- /dev/null +++ b/tgt-pal/dump_final.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2000 Stephen Williams (steve@icarus.com) + * + * This source code is free software; you can redistribute it + * and/or modify it in source code form under the terms of the GNU + * General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ +#if !defined(WINNT) +#ident "$Id: dump_final.c,v 1.1 2000/12/09 03:42:52 steve Exp $" +#endif + +# include "priv.h" +# include + + +void dump_final_design(FILE*out) +{ + unsigned idx; + for (idx = 0 ; idx < pins ; idx += 1) { + struct pal_bind_s*pin = bind_pin + idx; + + if (bind_pin[idx].sop) { + fprintf(out, "Output pin %u:\n", idx+1); + fprintf(out, " pin nexus=%s\n", + pin->nexus? ivl_nexus_name(pin->nexus) : ""); + fprintf(out, " pin enable=%s\n", + pin->enable ? ivl_logic_name(pin->enable) : "1"); + + fprintf(out, " pin ff=%s.q%u\n", + pin->reg ? ivl_lpm_name(pin->reg) : "*", + pin->reg_q); + } else { + fprintf(out, "Input pin %u:\n", idx+1); + fprintf(out, " pin nexus=%s\n", + pin->nexus? ivl_nexus_name(pin->nexus) : ""); + } + } +} + + + +/* + * $Log: dump_final.c,v $ + * Revision 1.1 2000/12/09 03:42:52 steve + * Stuff registers into macrocells. + * + */ + diff --git a/tgt-pal/enables.c b/tgt-pal/enables.c index 10dd81eba..b9918c86b 100644 --- a/tgt-pal/enables.c +++ b/tgt-pal/enables.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#ident "$Id: enables.c,v 1.1 2000/12/09 01:17:38 steve Exp $" +#ident "$Id: enables.c,v 1.2 2000/12/09 03:42:52 steve Exp $" # include # include @@ -25,7 +25,8 @@ /* * Given a pin index, look at the nexus for a bufif device that is - * driving it, if any. + * driving it, if any. Save that device in the enable slot for the + * cell. We'll try to fit it later. */ static void absorb_pad_enable(unsigned idx) { @@ -76,6 +77,9 @@ void absorb_pad_enables(void) /* * $Log: enables.c,v $ + * Revision 1.2 2000/12/09 03:42:52 steve + * Stuff registers into macrocells. + * * Revision 1.1 2000/12/09 01:17:38 steve * Add the pal loadable target. * diff --git a/tgt-pal/fit_reg.c b/tgt-pal/fit_reg.c new file mode 100644 index 000000000..041aac4c3 --- /dev/null +++ b/tgt-pal/fit_reg.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2000 Stephen Williams (steve@icarus.com) + * + * This source code is free software; you can redistribute it + * and/or modify it in source code form under the terms of the GNU + * General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ +#if !defined(WINNT) +#ident "$Id: fit_reg.c,v 1.1 2000/12/09 03:42:52 steve Exp $" +#endif + +# include +# include +# include +# include "priv.h" + +static int scan_ff_q(ivl_lpm_ff_t ff, unsigned q); + +int fit_registers(ivl_scope_t scope) +{ + int rc; + unsigned idx; + unsigned lpms; + + rc = ivl_scope_children(scope, fit_registers); + if (rc != 0) + return rc; + + lpms = ivl_scope_lpms(scope); + + for (idx = 0 ; idx < lpms ; idx += 1) { + ivl_lpm_t lpm = ivl_scope_lpm(scope, idx); + ivl_lpm_ff_t ff; + unsigned wid, q; + + if (ivl_lpm_type(lpm) != IVL_LPM_FF) + continue; + + wid = ivl_lpm_width(lpm); + ff = ivl_lpm_ff(lpm); + + for (q = 0 ; q < wid ; q += 1) { + rc = scan_ff_q(ff, q); + if (rc != 0) + return rc; + } + } + + return 0; +} + +int scan_ff_q(ivl_lpm_ff_t ff, unsigned q) +{ + unsigned idx; + ivl_nexus_t nex; + + nex = ivl_lpm_ff_q(ff, q); + + /* First, look to see if the Q is already connected to a pin + or an enable. If I find such a connection, then immediately + finish. */ + + for (idx = 0 ; idx < pins ; idx += 1) { + struct pal_bind_s*pin = bind_pin + idx; + + if (pin->sop == 0) + continue; + + if (pin->enable) { + + if (nex == ivl_logic_pin(pin->enable, 1)) { + pin->reg = ff; + pin->reg_q = q; + return 0; + } + + } else if (pin->nexus == nex) { + + pin->reg = ff; + pin->reg_q = q; + return 0; + } + } + + /* There is no poin connection, so try setting this to an + unbound sop cell. We know that a sop is unbound if there + are no enables, nexus or ff devices connected to it. */ + + for (idx = 0 ; idx < pins ; idx += 1) { + struct pal_bind_s*pin = bind_pin + idx; + + if (pin->sop == 0) + continue; + + if (pin->enable || pin->nexus || pin->reg) + continue; + + /* Found one. Put the reg here. Leave the nexus empty so + that the code generator knows to disable the pin. */ + pin->reg = ff; + pin->reg_q = q; + return 0; + } + + fprintf(stderr, "No room for this ff.\n"); + error_count += 1; + return 0; +} + +/* + * $Log: fit_reg.c,v $ + * Revision 1.1 2000/12/09 03:42:52 steve + * Stuff registers into macrocells. + * + */ + diff --git a/tgt-pal/imain.c b/tgt-pal/imain.c index 4eb215ea0..0f5afd267 100644 --- a/tgt-pal/imain.c +++ b/tgt-pal/imain.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: imain.c,v 1.1 2000/12/09 01:17:38 steve Exp $" +#ident "$Id: imain.c,v 1.2 2000/12/09 03:42:52 steve Exp $" #endif /* @@ -31,6 +31,8 @@ # include # include +extern void dump_final_design(FILE*out); + /* * As processing proceeds, this variable is incremented as errors are * encountered. This allows the code generator to give up if it @@ -50,29 +52,6 @@ pal_t pal = 0; unsigned pins = 0; struct pal_bind_s* bind_pin = 0; -static void dump_final_design(FILE*out) -{ - unsigned idx; - for (idx = 0 ; idx < pins ; idx += 1) { - if (bind_pin[idx].sop) { - fprintf(out, "Output pin %u:\n", idx+1); - fprintf(out, " pin nexus=%s\n", - bind_pin[idx].nexus? - ivl_nexus_name(bind_pin[idx].nexus) : ""); - fprintf(out, " pin enable=%s\n", - bind_pin[idx].enable ? - ivl_logic_name(bind_pin[idx].enable) : "1"); - - } else { - fprintf(out, "Input pin %u:\n", idx+1); - fprintf(out, " pin nexus=%s\n", - bind_pin[idx].nexus? - ivl_nexus_name(bind_pin[idx].nexus) : ""); - } - } -} - - /* * This is the main entry point that Icarus Verilog calls to generate @@ -120,7 +99,7 @@ int target_design(ivl_design_t des) get_pad_bindings(root); if (pal_errors) { - fprintf(stderr, "code generator failed.\n"); + fprintf(stderr, "PAD assignment failed.\n"); pal_free(pal); return -1; } @@ -129,6 +108,16 @@ int target_design(ivl_design_t des) enables that are connected to them. */ absorb_pad_enables(); + /* Scan all the registers, and assign them to + macro-cells. */ + root = ivl_design_root(des); + fit_registers(root); + if (pal_errors) { + fprintf(stderr, "Register fitting failed.\n"); + pal_free(pal); + return -1; + } + dump_final_design(stdout); @@ -143,6 +132,9 @@ DECLARE_CYGWIN_DLL(DllMain); /* * $Log: imain.c,v $ + * Revision 1.2 2000/12/09 03:42:52 steve + * Stuff registers into macrocells. + * * Revision 1.1 2000/12/09 01:17:38 steve * Add the pal loadable target. * diff --git a/tgt-pal/priv.h b/tgt-pal/priv.h index f42150cd1..43c2ad0ce 100644 --- a/tgt-pal/priv.h +++ b/tgt-pal/priv.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: priv.h,v 1.1 2000/12/09 01:17:38 steve Exp $" +#ident "$Id: priv.h,v 1.2 2000/12/09 03:42:52 steve Exp $" #endif # include @@ -41,6 +41,9 @@ struct pal_bind_s { pal_sop_t sop; /* If the output has an enable, this is it. */ ivl_net_logic_t enable; + /* If there is a register here, this is it. */ + ivl_lpm_ff_t reg; + unsigned reg_q; }; extern unsigned pins; @@ -50,8 +53,13 @@ extern int get_pad_bindings(ivl_scope_t net); extern void absorb_pad_enables(void); +extern int fit_registers(ivl_scope_t scope); + /* * $Log: priv.h,v $ + * Revision 1.2 2000/12/09 03:42:52 steve + * Stuff registers into macrocells. + * * Revision 1.1 2000/12/09 01:17:38 steve * Add the pal loadable target. *