diff --git a/tgt-pal/Makefile.in b/tgt-pal/Makefile.in index 7e2d928ea..4cf82bd64 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.3 2000/12/09 03:42:52 steve Exp $" +#ident "$Id: Makefile.in,v 1.4 2000/12/14 23:37:47 steve Exp $" # # SHELL = /bin/sh @@ -50,10 +50,10 @@ all: pal.tgt $(CC) -Wall $(CPPFLAGS) -I$(srcdir)/.. -MD -c $< -o $*.o mv $*.d dep -O = imain.o dump_final.o enables.o fit_reg.o pads.o +O = imain.o dump_final.o enables.o fit_log.o fit_reg.o pads.o ifeq (@CYGWIN@,yes) - TGTLDFLAGS=-Wl,--enable-auto-image-base -L.. -livl + TGTLDFLAGS=-L.. -livl TGTDEPLIBS=../libivl.a else TGTLDFLAGS= @@ -62,7 +62,7 @@ endif pal.tgt: $O $(TGTDEPLIBS) - $(CC) -shared -o $@ $O $(TGTLDFLAGS) -lipal + $(CC) @shared@ -o $@ $O $(TGTLDFLAGS) -lipal clean: rm -f *.o dep/*.d diff --git a/tgt-pal/fit_log.c b/tgt-pal/fit_log.c new file mode 100644 index 000000000..1a0f811ca --- /dev/null +++ b/tgt-pal/fit_log.c @@ -0,0 +1,133 @@ +/* + * 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_log.c,v 1.1 2000/12/14 23:37:47 steve Exp $" +#endif + +# include +# include +# include +# include +# include "priv.h" + +/* + * By the time we get here, all the flip-flops iave been placed in + * macrocells, and enables attached to them. So all that's left is to + * work backwards from each macrocell, making terms and sum-of-terms + * from the asynchronous logic until we get to the table inputs. + * + * A product term is a null terminated array of ivl_nexus_t + * objects. An expression is a null terminated array of terms. + */ + + +static void dump_expr(term_t**expr, const char*title) +{ + unsigned idx; + + fprintf(stderr, "expression for %s:\n", title); + for (idx = 0 ; expr[idx] ; idx += 1) { + term_t*tp; + fprintf(stderr, " term %u:\n", idx); + for (tp = expr[idx] ; tp->nex ; tp += 1) + fprintf(stderr, " %c%s\n", tp->inv? '~' : ' ', + ivl_nexus_name(tp->nex)); + } +} + +static term_t** build_expr(ivl_nexus_t nex) +{ + term_t* term = calloc(2, sizeof(term_t)); + term_t**expr = calloc(2, sizeof(term_t*)); + unsigned idx; + + assert(nex); + expr[0] = term; + term[0].inv = 0; + term[0].nex = nex; + + /* First look to see if I'm connected to an input pin. If so, + then this expression is done. */ + for (idx = 0 ; idx < pins ; idx += 1) { + struct pal_bind_s*pin = bind_pin + idx; + if ((nex == pin->nexus) && (pin->sop == 0)) { + return expr; + } + } + + fprintf(stderr, "sorry, I give up on nexus %s\n", ivl_nexus_name(nex)); + return 0; +} + +int fit_logic(void) +{ + unsigned idx; + + for (idx = 0 ; idx < pins ; idx += 1) { + ivl_nexus_t cell; + + struct pal_bind_s*pin = bind_pin + idx; + if (pin->sop == 0) + continue; + + cell = pin->nexus; + if (cell == 0) + continue; + + + /* If there is an enable, then this is a bufifX or a + notifX. Build the expression for the enable, and + guess that the input to the cell is actually the + input to the enable. */ + if (pin->enable) { + ivl_nexus_t en_nex = ivl_logic_pin(pin->enable, 2); + assert(cell == ivl_logic_pin(pin->enable, 0)); + + cell = ivl_logic_pin(pin->enable, 1); + assert(cell); + + pin->enable_ex = build_expr(en_nex); + dump_expr(pin->enable_ex, ivl_nexus_name(en_nex)); + } + + /* If there is a reg, then the input to the cell is + really the D input to the ff. */ + if (pin->reg) { + assert(cell == ivl_lpm_ff_q(pin->reg, pin->reg_q)); + cell = ivl_lpm_ff_data(pin->reg, pin->reg_q); + } + + assert(cell); + + /* Here we are. Generate the sum-of-products for the + input. */ + pin->sop_ex = build_expr(cell); + dump_expr(pin->sop_ex, ivl_nexus_name(cell)); + } + + return 0; +} + +/* + * $Log: fit_log.c,v $ + * Revision 1.1 2000/12/14 23:37:47 steve + * Start support for fitting the logic. + * + */ + diff --git a/tgt-pal/imain.c b/tgt-pal/imain.c index 1d35581e5..7785e686e 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.3 2000/12/09 05:40:42 steve Exp $" +#ident "$Id: imain.c,v 1.4 2000/12/14 23:37:47 steve Exp $" #endif /* @@ -128,6 +128,12 @@ int target_design(ivl_design_t des) return -1; } + fit_logic(); + if (pal_errors) { + fprintf(stderr, "Logic fitting failed.\n"); + pal_free(pal); + return -1; + } dump_final_design(stdout); @@ -142,6 +148,9 @@ DECLARE_CYGWIN_DLL(DllMain); /* * $Log: imain.c,v $ + * Revision 1.4 2000/12/14 23:37:47 steve + * Start support for fitting the logic. + * * Revision 1.3 2000/12/09 05:40:42 steve * documentation... * diff --git a/tgt-pal/priv.h b/tgt-pal/priv.h index 43c2ad0ce..8b32a5013 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.2 2000/12/09 03:42:52 steve Exp $" +#ident "$Id: priv.h,v 1.3 2000/12/14 23:37:47 steve Exp $" #endif # include @@ -33,7 +33,19 @@ extern unsigned error_count; * A device has an array of pins, that are bound to the netlist either * by attribute or by random lookup. The bind_pin table keeps track of * pin allocations. + * + * Each cell also has attached to it an expression that calculates + * results from an input. That expression is represented by a sum of + * product terms. A product term is an array of term_t objects, + * terminated by a term will a null nex pointers. A sum, then, is an + * array of pointers to term_t arrays, terminated by a null pointer. */ + +typedef struct term_s { + int inv; + ivl_nexus_t nex; +} term_t; + struct pal_bind_s { /* This is the netlist connection for the pin. */ ivl_nexus_t nexus; @@ -41,9 +53,12 @@ struct pal_bind_s { pal_sop_t sop; /* If the output has an enable, this is it. */ ivl_net_logic_t enable; + term_t **enable_ex; /* If there is a register here, this is it. */ ivl_lpm_ff_t reg; unsigned reg_q; + /* The input to the cell is this expression. */ + term_t **sop_ex; }; extern unsigned pins; @@ -55,8 +70,13 @@ extern void absorb_pad_enables(void); extern int fit_registers(ivl_scope_t scope); +extern int fit_logic(void); + /* * $Log: priv.h,v $ + * Revision 1.3 2000/12/14 23:37:47 steve + * Start support for fitting the logic. + * * Revision 1.2 2000/12/09 03:42:52 steve * Stuff registers into macrocells. *