diff --git a/tgt-fpga/Makefile.in b/tgt-fpga/Makefile.in index 8bdef2680..b40551adf 100644 --- a/tgt-fpga/Makefile.in +++ b/tgt-fpga/Makefile.in @@ -16,7 +16,7 @@ # 59 Temple Place - Suite 330 # Boston, MA 02111-1307, USA # -#ident "$Id: Makefile.in,v 1.1 2001/08/28 04:14:20 steve Exp $" +#ident "$Id: Makefile.in,v 1.2 2001/09/02 21:33:07 steve Exp $" # # SHELL = /bin/sh @@ -49,7 +49,8 @@ all: fpga.tgt $(CC) -Wall -I$(srcdir)/.. $(CPPFLAGS) -MD -c $< -o $*.o mv $*.d dep -O = fpga.o gates.o d-generic.o mangle.o +D = d-generic.o d-generic-edif.o +O = fpga.o gates.o mangle.o tables.o $D ifeq (@WIN32@,yes) TGTLDFLAGS=-L.. -livl diff --git a/tgt-fpga/d-generic-edif.c b/tgt-fpga/d-generic-edif.c new file mode 100644 index 000000000..9ac8de32b --- /dev/null +++ b/tgt-fpga/d-generic-edif.c @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2001 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 + */ +#ident "$Id: d-generic-edif.c,v 1.1 2001/09/02 21:33:07 steve Exp $" + +# include "device.h" +# include "fpga_priv.h" +# include + +static void show_root_ports_edif(ivl_scope_t root) +{ + unsigned cnt = ivl_scope_sigs(root); + unsigned idx; + + for (idx = 0 ; idx < cnt ; idx += 1) { + ivl_signal_t sig = ivl_scope_sig(root, idx); + const char*use_name; + + const char*dir = 0; + switch (ivl_signal_port(sig)) { + case IVL_SIP_NONE: + continue; + + case IVL_SIP_INPUT: + dir = "INPUT"; + break; + + case IVL_SIP_OUTPUT: + dir = "OUTPUT"; + break; + + case IVL_SIP_INOUT: + dir = "INOUT"; + break; + } + + use_name = ivl_signal_basename(sig); + if (ivl_signal_pins(sig) == 1) { + fprintf(xnf, " (port %s (direction %s))\n", + use_name, dir); + + } else { + unsigned pin; + + for (pin = 0 ; pin < ivl_signal_pins(sig); pin += 1) { + fprintf(xnf, " (port (rename %s_%u " + "\"%s[%u]\") (direction %s))\n", use_name, + pin, use_name, pin, dir); + } + } + } +} + +static void edif_show_header(ivl_design_t des) +{ + ivl_scope_t root = ivl_design_root(des); + + /* write the primitive header */ + fprintf(xnf, "(edif %s\n", ivl_scope_name(root)); + fprintf(xnf, " (edifVersion 2 0 0)\n"); + fprintf(xnf, " (edifLevel 0)\n"); + fprintf(xnf, " (keywordMap (keywordLevel 0))\n"); + fprintf(xnf, " (status\n"); + fprintf(xnf, " (written\n"); + fprintf(xnf, " (timeStamp 0 0 0 0 0 0)\n"); + fprintf(xnf, " (author \"unknown\")\n"); + fprintf(xnf, " (program \"Icarus Verilog/fpga.tgt\")))\n"); + + /* Write out the external references here? */ + + /* Write out the library header */ + fprintf(xnf, " (library DESIGN\n"); + fprintf(xnf, " (edifLevel 0)\n"); + fprintf(xnf, " (technology (numberDefinition))\n"); + + /* The root module is a cell in the library. */ + fprintf(xnf, " (cell %s\n", ivl_scope_name(root)); + fprintf(xnf, " (cellType GENERIC)\n"); + fprintf(xnf, " (view Netlist_representation\n"); + fprintf(xnf, " (viewType NETLIST)\n"); + fprintf(xnf, " (interface\n"); + + show_root_ports_edif(root); + + fprintf(xnf, " )\n"); /* end the (interface ) sexp */ + + fprintf(xnf, " (contents\n"); +} + +static void edif_show_footer(ivl_design_t des) +{ + ivl_scope_t root = ivl_design_root(des); + + fprintf(xnf, " )\n"); /* end the (contents ) sexp */ + fprintf(xnf, " )\n"); /* end the (view ) sexp */ + fprintf(xnf, " )\n"); /* end the (cell ) sexp */ + fprintf(xnf, " )\n"); /* end the (library ) sexp */ + + /* Make an instance of the defined object */ + fprintf(xnf, " (design %s\n", ivl_scope_name(root)); + fprintf(xnf, " (cellRef %s (libraryRef DESIGN))\n", + ivl_scope_name(root)); + + if (part) + fprintf(xnf, " (property PART (string \"%s\"))\n", part); + + fprintf(xnf, " )\n"); + + fprintf(xnf, ")\n"); /* end the (edif ) sexp */ +} + +static void edif_show_logic(ivl_net_logic_t net) +{ + switch (ivl_logic_type(net)) { + + case IVL_LO_BUF: + assert(ivl_logic_pins(net) == 2); + fprintf(xnf, " (instance"); + fprintf(xnf, " %s", ivl_logic_name(net)); + fprintf(xnf, " (viewRef Netlist_representation" + " (cellRef BUF (libraryRef VIRTEX))))\n"); + break; + + } +} + +static void edif_show_dff(ivl_lpm_t net) +{ +} + + +const struct device_s d_generic_edif = { + edif_show_header, + edif_show_footer, + edif_show_logic, + edif_show_dff, + 0, + 0, + 0, + 0 +}; + + +/* + * $Log: d-generic-edif.c,v $ + * Revision 1.1 2001/09/02 21:33:07 steve + * Rearrange the XNF code generator to be generic-xnf + * so that non-XNF code generation is also possible. + * + * Start into the virtex EDIF output driver. + * + */ + diff --git a/tgt-fpga/d-generic.c b/tgt-fpga/d-generic.c index ae0bc50a8..9f356683c 100644 --- a/tgt-fpga/d-generic.c +++ b/tgt-fpga/d-generic.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: d-generic.c,v 1.7 2001/09/01 04:30:44 steve Exp $" +#ident "$Id: d-generic.c,v 1.8 2001/09/02 21:33:07 steve Exp $" # include "device.h" # include "fpga_priv.h" @@ -28,25 +28,113 @@ * logic. */ +static void xnf_draw_pin(ivl_nexus_t nex, const char*nam, char dir) +{ + const char*use_name = nam; + const char*nex_name = xnf_mangle_nexus_name(nex); + int invert = 0; + + if (use_name[0] == '~') { + invert = 1; + use_name += 1; + } + + fprintf(xnf, " PIN, %s, %c, %s", use_name, dir, nex_name); + + if (invert) + fprintf(xnf, ",,INV"); + + fprintf(xnf, "\n"); +} + +static void show_root_ports_xnf(ivl_scope_t root) +{ + unsigned cnt = ivl_scope_sigs(root); + unsigned idx; + + for (idx = 0 ; idx < cnt ; idx += 1) { + ivl_signal_t sig = ivl_scope_sig(root, idx); + const char*use_name; + + if (ivl_signal_port(sig) == IVL_SIP_NONE) + continue; + + use_name = ivl_signal_basename(sig); + if (ivl_signal_pins(sig) == 1) { + ivl_nexus_t nex = ivl_signal_pin(sig, 0); + fprintf(xnf, "SIG, %s, PIN=%s\n", + xnf_mangle_nexus_name(nex), use_name); + + } else { + unsigned pin; + + for (pin = 0 ; pin < ivl_signal_pins(sig); pin += 1) { + ivl_nexus_t nex = ivl_signal_pin(sig, pin); + fprintf(xnf, "SIG, %s, PIN=%s%u\n", + xnf_mangle_nexus_name(nex), use_name, + pin); + } + } + } +} + +static void show_design_consts_xnf(ivl_design_t des) +{ + unsigned idx; + + for (idx = 0 ; idx < ivl_design_consts(des) ; idx += 1) { + unsigned pin; + ivl_net_const_t net = ivl_design_const(des, idx); + const char*val = ivl_const_bits(net); + + for (pin = 0 ; pin < ivl_const_pins(net) ; pin += 1) { + ivl_nexus_t nex = ivl_const_pin(net, pin); + fprintf(xnf, "PWR,%c,%s\n", val[pin], + xnf_mangle_nexus_name(nex)); + } + } +} + +static void generic_show_header(ivl_design_t des) +{ + ivl_scope_t root = ivl_design_root(des); + + fprintf(xnf, "LCANET,6\n"); + fprintf(xnf, "PROG,iverilog,$Name: $,\"Icarus Verilog/fpga.tgt\"\n"); + + if (part && (part[0]!=0)) { + fprintf(xnf, "PART,%s\n", part); + } + + show_root_ports_xnf(root); +} + +static void generic_show_footer(ivl_design_t des) +{ + show_design_consts_xnf(des); + fprintf(xnf, "EOF\n"); +} + + static void generic_show_logic(ivl_net_logic_t net) { char name[1024]; ivl_nexus_t nex; unsigned idx; - mangle_logic_name(net, name, sizeof name); + xnf_mangle_logic_name(net, name, sizeof name); switch (ivl_logic_type(net)) { case IVL_LO_AND: fprintf(xnf, "SYM, %s, AND, LIBVER=2.0.0\n", name); nex = ivl_logic_pin(net, 0); - draw_pin(nex, "O", 'O'); + xnf_draw_pin(nex, "O", 'O'); for (idx = 1 ; idx < ivl_logic_pins(net) ; idx += 1) { char ipin[32]; nex = ivl_logic_pin(net, idx); sprintf(ipin, "I%u", idx-1); - draw_pin(nex, ipin, 'I'); + xnf_draw_pin(nex, ipin, 'I'); } fprintf(xnf, "END\n"); break; @@ -55,21 +143,21 @@ static void generic_show_logic(ivl_net_logic_t net) assert(ivl_logic_pins(net) == 2); fprintf(xnf, "SYM, %s, BUF, LIBVER=2.0.0\n", name); nex = ivl_logic_pin(net, 0); - draw_pin(nex, "O", 'O'); + xnf_draw_pin(nex, "O", 'O'); nex = ivl_logic_pin(net, 1); - draw_pin(nex, "I", 'I'); + xnf_draw_pin(nex, "I", 'I'); fprintf(xnf, "END\n"); break; case IVL_LO_NAND: fprintf(xnf, "SYM, %s, NAND, LIBVER=2.0.0\n", name); nex = ivl_logic_pin(net, 0); - draw_pin(nex, "O", 'O'); + xnf_draw_pin(nex, "O", 'O'); for (idx = 1 ; idx < ivl_logic_pins(net) ; idx += 1) { char ipin[32]; nex = ivl_logic_pin(net, idx); sprintf(ipin, "I%u", idx-1); - draw_pin(nex, ipin, 'I'); + xnf_draw_pin(nex, ipin, 'I'); } fprintf(xnf, "END\n"); break; @@ -77,12 +165,12 @@ static void generic_show_logic(ivl_net_logic_t net) case IVL_LO_NOR: fprintf(xnf, "SYM, %s, NOR, LIBVER=2.0.0\n", name); nex = ivl_logic_pin(net, 0); - draw_pin(nex, "O", 'O'); + xnf_draw_pin(nex, "O", 'O'); for (idx = 1 ; idx < ivl_logic_pins(net) ; idx += 1) { char ipin[32]; nex = ivl_logic_pin(net, idx); sprintf(ipin, "I%u", idx-1); - draw_pin(nex, ipin, 'I'); + xnf_draw_pin(nex, ipin, 'I'); } fprintf(xnf, "END\n"); break; @@ -91,21 +179,21 @@ static void generic_show_logic(ivl_net_logic_t net) assert(ivl_logic_pins(net) == 2); fprintf(xnf, "SYM, %s, INV, LIBVER=2.0.0\n", name); nex = ivl_logic_pin(net, 0); - draw_pin(nex, "O", 'O'); + xnf_draw_pin(nex, "O", 'O'); nex = ivl_logic_pin(net, 1); - draw_pin(nex, "I", 'I'); + xnf_draw_pin(nex, "I", 'I'); fprintf(xnf, "END\n"); break; case IVL_LO_OR: fprintf(xnf, "SYM, %s, OR, LIBVER=2.0.0\n", name); nex = ivl_logic_pin(net, 0); - draw_pin(nex, "O", 'O'); + xnf_draw_pin(nex, "O", 'O'); for (idx = 1 ; idx < ivl_logic_pins(net) ; idx += 1) { char ipin[32]; nex = ivl_logic_pin(net, idx); sprintf(ipin, "I%u", idx-1); - draw_pin(nex, ipin, 'I'); + xnf_draw_pin(nex, ipin, 'I'); } fprintf(xnf, "END\n"); break; @@ -113,12 +201,12 @@ static void generic_show_logic(ivl_net_logic_t net) case IVL_LO_XOR: fprintf(xnf, "SYM, %s, XOR, LIBVER=2.0.0\n", name); nex = ivl_logic_pin(net, 0); - draw_pin(nex, "O", 'O'); + xnf_draw_pin(nex, "O", 'O'); for (idx = 1 ; idx < ivl_logic_pins(net) ; idx += 1) { char ipin[32]; nex = ivl_logic_pin(net, idx); sprintf(ipin, "I%u", idx-1); - draw_pin(nex, ipin, 'I'); + xnf_draw_pin(nex, ipin, 'I'); } fprintf(xnf, "END\n"); break; @@ -126,12 +214,12 @@ static void generic_show_logic(ivl_net_logic_t net) case IVL_LO_XNOR: fprintf(xnf, "SYM, %s, XNOR, LIBVER=2.0.0\n", name); nex = ivl_logic_pin(net, 0); - draw_pin(nex, "O", 'O'); + xnf_draw_pin(nex, "O", 'O'); for (idx = 1 ; idx < ivl_logic_pins(net) ; idx += 1) { char ipin[32]; nex = ivl_logic_pin(net, idx); sprintf(ipin, "I%u", idx-1); - draw_pin(nex, ipin, 'I'); + xnf_draw_pin(nex, ipin, 'I'); } fprintf(xnf, "END\n"); break; @@ -139,22 +227,22 @@ static void generic_show_logic(ivl_net_logic_t net) case IVL_LO_BUFIF0: fprintf(xnf, "SYM, %s, TBUF, LIBVER=2.0.0\n", name); nex = ivl_logic_pin(net, 0); - draw_pin(nex, "O", 'O'); + xnf_draw_pin(nex, "O", 'O'); nex = ivl_logic_pin(net, 1); - draw_pin(nex, "I", 'I'); + xnf_draw_pin(nex, "I", 'I'); nex = ivl_logic_pin(net, 2); - draw_pin(nex, "~T", 'I'); + xnf_draw_pin(nex, "~T", 'I'); fprintf(xnf, "END\n"); break; case IVL_LO_BUFIF1: fprintf(xnf, "SYM, %s, TBUF, LIBVER=2.0.0\n", name); nex = ivl_logic_pin(net, 0); - draw_pin(nex, "O", 'O'); + xnf_draw_pin(nex, "O", 'O'); nex = ivl_logic_pin(net, 1); - draw_pin(nex, "I", 'I'); + xnf_draw_pin(nex, "I", 'I'); nex = ivl_logic_pin(net, 2); - draw_pin(nex, "T", 'I'); + xnf_draw_pin(nex, "T", 'I'); fprintf(xnf, "END\n"); break; @@ -171,21 +259,21 @@ static void generic_show_dff(ivl_lpm_t net) char name[1024]; ivl_nexus_t nex; - mangle_lpm_name(net, name, sizeof name); + xnf_mangle_lpm_name(net, name, sizeof name); fprintf(xnf, "SYM, %s, DFF, LIBVER=2.0.0\n", name); nex = ivl_lpm_q(net, 0); - draw_pin(nex, "Q", 'O'); + xnf_draw_pin(nex, "Q", 'O'); nex = ivl_lpm_data(net, 0); - draw_pin(nex, "D", 'I'); + xnf_draw_pin(nex, "D", 'I'); nex = ivl_lpm_clk(net); - draw_pin(nex, "C", 'I'); + xnf_draw_pin(nex, "C", 'I'); if ((nex = ivl_lpm_enable(net))) - draw_pin(nex, "CE", 'I'); + xnf_draw_pin(nex, "CE", 'I'); fprintf(xnf, "END\n"); } @@ -204,7 +292,7 @@ static void generic_show_cmp_eq(ivl_lpm_t net) /* Make this many single pair comparators. */ unsigned seqn = ivl_lpm_width(net) % 2; - mangle_lpm_name(net, name, sizeof name); + xnf_mangle_lpm_name(net, name, sizeof name); for (idx = 0 ; idx < deqn ; idx += 1) { fprintf(xnf, "SYM, %s/CD%u, EQN, " @@ -214,14 +302,14 @@ static void generic_show_cmp_eq(ivl_lpm_t net) fprintf(xnf, " PIN, O, O, %s/CDO%u\n", name, idx); nex = ivl_lpm_data(net, 2*idx); - draw_pin(nex, "I0", 'I'); + xnf_draw_pin(nex, "I0", 'I'); nex = ivl_lpm_datab(net, 2*idx); - draw_pin(nex, "I1", 'I'); + xnf_draw_pin(nex, "I1", 'I'); nex = ivl_lpm_data(net, 2*idx+1); - draw_pin(nex, "I2", 'I'); + xnf_draw_pin(nex, "I2", 'I'); nex = ivl_lpm_datab(net, 2*idx+1); - draw_pin(nex, "I3", 'I'); + xnf_draw_pin(nex, "I3", 'I'); fprintf(xnf, "END\n"); } @@ -232,10 +320,10 @@ static void generic_show_cmp_eq(ivl_lpm_t net) fprintf(xnf, " PIN, O, O, %s/CTO\n", name); nex = ivl_lpm_data(net, 2*deqn); - draw_pin(nex, "I0", 'I'); + xnf_draw_pin(nex, "I0", 'I'); nex = ivl_lpm_datab(net, 2*deqn); - draw_pin(nex, "I1", 'I'); + xnf_draw_pin(nex, "I1", 'I'); fprintf(xnf, "END\n"); } @@ -246,7 +334,7 @@ static void generic_show_cmp_eq(ivl_lpm_t net) fprintf(xnf, "SYM, %s/OUT, NAND, LIBVER=2.0.0\n", name); nex = ivl_lpm_q(net, 0); - draw_pin(nex, "O", 'O'); + xnf_draw_pin(nex, "O", 'O'); for (idx = 0 ; idx < deqn ; idx += 1) fprintf(xnf, " PIN, I%u, I, %s/CDO%u\n", idx, name, idx); @@ -274,7 +362,7 @@ static void generic_show_mux(ivl_lpm_t net) ivl_nexus_t nex, sel; unsigned idx; - mangle_lpm_name(net, name, sizeof name); + xnf_mangle_lpm_name(net, name, sizeof name); /* Access the single select bit. This is common to the whole width of the mux. */ @@ -287,15 +375,15 @@ static void generic_show_mux(ivl_lpm_t net) name, idx); nex = ivl_lpm_q(net, idx); - draw_pin(nex, "O", 'O'); + xnf_draw_pin(nex, "O", 'O'); nex = ivl_lpm_data2(net, 0, idx); - draw_pin(nex, "I0", 'I'); + xnf_draw_pin(nex, "I0", 'I'); nex = ivl_lpm_data2(net, 1, idx); - draw_pin(nex, "I1", 'I'); + xnf_draw_pin(nex, "I1", 'I'); - draw_pin(sel, "I2", 'I'); + xnf_draw_pin(sel, "I2", 'I'); fprintf(xnf, "END\n"); } @@ -312,7 +400,7 @@ static void generic_show_add(ivl_lpm_t net) ivl_nexus_t nex; unsigned idx, nadd4, tail; - mangle_lpm_name(net, name, sizeof name); + xnf_mangle_lpm_name(net, name, sizeof name); /* Make this many ADD4 devices. */ nadd4 = ivl_lpm_width(net) / 4; @@ -325,40 +413,40 @@ static void generic_show_add(ivl_lpm_t net) fprintf(xnf, " PIN, CI, I, %s/CO%u\n", name, idx-1); nex = ivl_lpm_q(net, idx*4+0); - draw_pin(nex, "S0", 'O'); + xnf_draw_pin(nex, "S0", 'O'); nex = ivl_lpm_q(net, idx*4+1); - draw_pin(nex, "S1", 'O'); + xnf_draw_pin(nex, "S1", 'O'); nex = ivl_lpm_q(net, idx*4+2); - draw_pin(nex, "S2", 'O'); + xnf_draw_pin(nex, "S2", 'O'); nex = ivl_lpm_q(net, idx*4+3); - draw_pin(nex, "S3", 'O'); + xnf_draw_pin(nex, "S3", 'O'); nex = ivl_lpm_data(net, idx*4+0); - draw_pin(nex, "A0", 'I'); + xnf_draw_pin(nex, "A0", 'I'); nex = ivl_lpm_data(net, idx*4+1); - draw_pin(nex, "A1", 'I'); + xnf_draw_pin(nex, "A1", 'I'); nex = ivl_lpm_data(net, idx*4+2); - draw_pin(nex, "A2", 'I'); + xnf_draw_pin(nex, "A2", 'I'); nex = ivl_lpm_data(net, idx*4+3); - draw_pin(nex, "A3", 'I'); + xnf_draw_pin(nex, "A3", 'I'); nex = ivl_lpm_datab(net, idx*4+0); - draw_pin(nex, "B0", 'I'); + xnf_draw_pin(nex, "B0", 'I'); nex = ivl_lpm_datab(net, idx*4+1); - draw_pin(nex, "B1", 'I'); + xnf_draw_pin(nex, "B1", 'I'); nex = ivl_lpm_datab(net, idx*4+2); - draw_pin(nex, "B2", 'I'); + xnf_draw_pin(nex, "B2", 'I'); nex = ivl_lpm_datab(net, idx*4+3); - draw_pin(nex, "B3", 'I'); + xnf_draw_pin(nex, "B3", 'I'); if ((idx*4+4) < ivl_lpm_width(net)) fprintf(xnf, " PIN, CO, O, %s/CO%u\n", name, idx); @@ -374,31 +462,31 @@ static void generic_show_add(ivl_lpm_t net) switch (tail) { case 3: nex = ivl_lpm_data(net, nadd4*4+2); - draw_pin(nex, "A2", 'I'); + xnf_draw_pin(nex, "A2", 'I'); nex = ivl_lpm_datab(net, nadd4*4+2); - draw_pin(nex, "B2", 'I'); + xnf_draw_pin(nex, "B2", 'I'); nex = ivl_lpm_q(net, nadd4*4+2); - draw_pin(nex, "S2", 'O'); + xnf_draw_pin(nex, "S2", 'O'); case 2: nex = ivl_lpm_data(net, nadd4*4+1); - draw_pin(nex, "A1", 'I'); + xnf_draw_pin(nex, "A1", 'I'); nex = ivl_lpm_datab(net, nadd4*4+1); - draw_pin(nex, "B1", 'I'); + xnf_draw_pin(nex, "B1", 'I'); nex = ivl_lpm_q(net, nadd4*4+1); - draw_pin(nex, "S1", 'O'); + xnf_draw_pin(nex, "S1", 'O'); case 1: nex = ivl_lpm_data(net, nadd4*4+0); - draw_pin(nex, "A0", 'I'); + xnf_draw_pin(nex, "A0", 'I'); nex = ivl_lpm_datab(net, nadd4*4+0); - draw_pin(nex, "B0", 'I'); + xnf_draw_pin(nex, "B0", 'I'); nex = ivl_lpm_q(net, nadd4*4+0); - draw_pin(nex, "S0", 'O'); + xnf_draw_pin(nex, "S0", 'O'); } fprintf(xnf, "END\n"); @@ -406,6 +494,8 @@ static void generic_show_add(ivl_lpm_t net) } const struct device_s d_generic = { + generic_show_header, + generic_show_footer, generic_show_logic, generic_show_dff, generic_show_cmp_eq, @@ -417,6 +507,12 @@ const struct device_s d_generic = { /* * $Log: d-generic.c,v $ + * Revision 1.8 2001/09/02 21:33:07 steve + * Rearrange the XNF code generator to be generic-xnf + * so that non-XNF code generation is also possible. + * + * Start into the virtex EDIF output driver. + * * Revision 1.7 2001/09/01 04:30:44 steve * Generic ADD code. * diff --git a/tgt-fpga/device.h b/tgt-fpga/device.h index a2e2721b1..05dcda638 100644 --- a/tgt-fpga/device.h +++ b/tgt-fpga/device.h @@ -18,7 +18,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: device.h,v 1.5 2001/09/01 04:30:44 steve Exp $" +#ident "$Id: device.h,v 1.6 2001/09/02 21:33:07 steve Exp $" # include @@ -36,6 +36,9 @@ typedef const struct device_s* device_t; struct device_s { + /* These methods draw leading and trailing format text. */ + void (*show_header)(ivl_design_t des); + void (*show_footer)(ivl_design_t des); /* Draw basic logic devices. */ void (*show_logic)(ivl_net_logic_t net); /* This method emits a D type Flip-Flop */ @@ -49,9 +52,24 @@ struct device_s { void (*show_add)(ivl_lpm_t net); }; +/* + * Return the device_t cookie given the name of the architecture. If + * the device is not found, return 0. + * + * This function is used if the user specifies the archetecture + * explicitly, with the -parch=name flag. + */ +extern device_t device_from_arch(const char*arch); + /* * $Log: device.h,v $ + * Revision 1.6 2001/09/02 21:33:07 steve + * Rearrange the XNF code generator to be generic-xnf + * so that non-XNF code generation is also possible. + * + * Start into the virtex EDIF output driver. + * * Revision 1.5 2001/09/01 04:30:44 steve * Generic ADD code. * diff --git a/tgt-fpga/fpga.c b/tgt-fpga/fpga.c index a56fabed0..4e3e7befd 100644 --- a/tgt-fpga/fpga.c +++ b/tgt-fpga/fpga.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: fpga.c,v 1.3 2001/09/01 02:01:30 steve Exp $" +#ident "$Id: fpga.c,v 1.4 2001/09/02 21:33:07 steve Exp $" #endif # include "config.h" @@ -29,77 +29,31 @@ # include # include "fpga_priv.h" + /* This is the opened xnf file descriptor. It is the output that this code generator writes to. */ FILE*xnf = 0; const char*part = 0; +const char*arch = 0; device_t device = 0; -extern const struct device_s d_generic; - static int show_process(ivl_process_t net, void*x) { fprintf(stderr, "fpga target: unsynthesized behavioral code\n"); return 0; } -static void show_root_ports(ivl_scope_t root) -{ - unsigned cnt = ivl_scope_sigs(root); - unsigned idx; - - for (idx = 0 ; idx < cnt ; idx += 1) { - ivl_signal_t sig = ivl_scope_sig(root, idx); - const char*use_name; - - if (ivl_signal_port(sig) == IVL_SIP_NONE) - continue; - - use_name = ivl_signal_basename(sig); - if (ivl_signal_pins(sig) == 1) { - ivl_nexus_t nex = ivl_signal_pin(sig, 0); - fprintf(xnf, "SIG, %s, PIN=%s\n", - mangle_nexus_name(nex), use_name); - - } else { - unsigned pin; - - for (pin = 0 ; pin < ivl_signal_pins(sig); pin += 1) { - ivl_nexus_t nex = ivl_signal_pin(sig, pin); - fprintf(xnf, "SIG, %s, PIN=%s%u\n", - mangle_nexus_name(nex), use_name, - pin); - } - } - } -} - -static void show_design_consts(ivl_design_t des) -{ - unsigned idx; - - for (idx = 0 ; idx < ivl_design_consts(des) ; idx += 1) { - unsigned pin; - ivl_net_const_t net = ivl_design_const(des, idx); - const char*val = ivl_const_bits(net); - - for (pin = 0 ; pin < ivl_const_pins(net) ; pin += 1) { - ivl_nexus_t nex = ivl_const_pin(net, pin); - fprintf(xnf, "PWR,%c,%s\n", val[pin], - mangle_nexus_name(nex)); - } - } -} - /* * This is the main entry point that ivl uses to invoke me, the code * generator. */ + + int target_design(ivl_design_t des) { - const char*path = ivl_design_flag(des, "-o"); ivl_scope_t root = ivl_design_root(des); + const char*path = ivl_design_flag(des, "-o"); xnf = fopen(path, "w"); if (xnf == 0) { @@ -107,34 +61,50 @@ int target_design(ivl_design_t des) return -1; } - fprintf(xnf, "LCANET,6\n"); - fprintf(xnf, "PROG,iverilog,$Name: $,\"Icarus Verilog/fpga.tgt\"\n"); - part = ivl_design_flag(des, "part"); - if (part && (part[0]!=0)) { - fprintf(xnf, "PART,%s\n", part); + if (part && (part[0] == 0)) + part = 0; + + arch = ivl_design_flag(des, "arch"); + if (arch && (arch[0] == 0)) + arch = 0; + + if (arch == 0) + arch = "generic-xnf"; + + device = device_from_arch(arch); + if (device == 0) { + fprintf(stderr, "Unknown architecture arch=%s\n", arch); + return -1; } - device = &d_generic; + /* Call the device driver to generate the netlist header. */ + device->show_header(des); /* Catch any behavioral code that is left, and write warnings that it is not supported. */ ivl_design_process(des, show_process, 0); - show_root_ports(root); - /* Scan the scopes, looking for gates to draw into the output netlist. */ show_scope_gates(root, 0); - show_design_consts(des); + /* Call the device driver to close out the file. */ + device->show_footer(des); - fprintf(xnf, "EOF\n"); + fclose(xnf); + xnf = 0; return 0; } /* * $Log: fpga.c,v $ + * Revision 1.4 2001/09/02 21:33:07 steve + * Rearrange the XNF code generator to be generic-xnf + * so that non-XNF code generation is also possible. + * + * Start into the virtex EDIF output driver. + * * Revision 1.3 2001/09/01 02:01:30 steve * identity compare, and PWR records for constants. * diff --git a/tgt-fpga/fpga_priv.h b/tgt-fpga/fpga_priv.h index 614ec4ea3..b8cc92966 100644 --- a/tgt-fpga/fpga_priv.h +++ b/tgt-fpga/fpga_priv.h @@ -18,31 +18,39 @@ * 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: fpga_priv.h,v 1.2 2001/08/30 04:31:04 steve Exp $" +#ident "$Id: fpga_priv.h,v 1.3 2001/09/02 21:33:07 steve Exp $" # include # include "device.h" /* This is the opened xnf file descriptor. It is the output that this - code generator writes to. */ + code generator writes to, whether the format is XNF or EDIF. */ extern FILE*xnf; extern int show_scope_gates(ivl_scope_t net, void*x); -extern void draw_pin(ivl_nexus_t nex, const char*nam, char dir); extern device_t device; +extern const char*part; +extern const char*arch; + /* * These are mangle functions. */ -extern void mangle_logic_name(ivl_net_logic_t net, char*buf, size_t nbuf); -extern void mangle_lpm_name(ivl_lpm_t net, char*buf, size_t nbuf); +extern void xnf_mangle_logic_name(ivl_net_logic_t net, char*buf, size_t nbuf); +extern void xnf_mangle_lpm_name(ivl_lpm_t net, char*buf, size_t nbuf); -extern const char*mangle_nexus_name(ivl_nexus_t net); +extern const char*xnf_mangle_nexus_name(ivl_nexus_t net); /* * $Log: fpga_priv.h,v $ + * Revision 1.3 2001/09/02 21:33:07 steve + * Rearrange the XNF code generator to be generic-xnf + * so that non-XNF code generation is also possible. + * + * Start into the virtex EDIF output driver. + * * Revision 1.2 2001/08/30 04:31:04 steve * Mangle nexus names. * diff --git a/tgt-fpga/gates.c b/tgt-fpga/gates.c index 2d474cf0d..25fc27fa5 100644 --- a/tgt-fpga/gates.c +++ b/tgt-fpga/gates.c @@ -16,31 +16,12 @@ * 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: gates.c,v 1.5 2001/09/01 04:30:44 steve Exp $" +#ident "$Id: gates.c,v 1.6 2001/09/02 21:33:07 steve Exp $" # include # include "fpga_priv.h" # include -void draw_pin(ivl_nexus_t nex, const char*nam, char dir) -{ - const char*use_name = nam; - const char*nex_name = mangle_nexus_name(nex); - int invert = 0; - - if (use_name[0] == '~') { - invert = 1; - use_name += 1; - } - - fprintf(xnf, " PIN, %s, %c, %s", use_name, dir, nex_name); - - if (invert) - fprintf(xnf, ",,INV"); - - fprintf(xnf, "\n"); -} - static void show_gate_logic(ivl_net_logic_t net) { device->show_logic(net); @@ -92,6 +73,12 @@ int show_scope_gates(ivl_scope_t net, void*x) /* * $Log: gates.c,v $ + * Revision 1.6 2001/09/02 21:33:07 steve + * Rearrange the XNF code generator to be generic-xnf + * so that non-XNF code generation is also possible. + * + * Start into the virtex EDIF output driver. + * * Revision 1.5 2001/09/01 04:30:44 steve * Generic ADD code. * diff --git a/tgt-fpga/mangle.c b/tgt-fpga/mangle.c index ca281d9b9..c6058b458 100644 --- a/tgt-fpga/mangle.c +++ b/tgt-fpga/mangle.c @@ -16,20 +16,20 @@ * 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: mangle.c,v 1.2 2001/08/30 04:31:05 steve Exp $" +#ident "$Id: mangle.c,v 1.3 2001/09/02 21:33:07 steve Exp $" # include "fpga_priv.h" # include # include -static size_t mangle_scope_name(ivl_scope_t net, char*buf, size_t nbuf) +static size_t xnf_mangle_scope_name(ivl_scope_t net, char*buf, size_t nbuf) { unsigned cnt = 0; ivl_scope_t parent = ivl_scope_parent(net); if (parent) { - cnt = mangle_scope_name(parent, buf, nbuf); + cnt = xnf_mangle_scope_name(parent, buf, nbuf); buf += cnt; nbuf -= cnt; *buf++ = '/'; @@ -43,16 +43,16 @@ static size_t mangle_scope_name(ivl_scope_t net, char*buf, size_t nbuf) return cnt; } -void mangle_logic_name(ivl_net_logic_t net, char*buf, size_t nbuf) +void xnf_mangle_logic_name(ivl_net_logic_t net, char*buf, size_t nbuf) { - size_t cnt = mangle_scope_name(ivl_logic_scope(net), buf, nbuf); + size_t cnt = xnf_mangle_scope_name(ivl_logic_scope(net), buf, nbuf); buf[cnt++] = '/'; strcpy(buf+cnt, ivl_logic_basename(net)); } -void mangle_lpm_name(ivl_lpm_t net, char*buf, size_t nbuf) +void xnf_mangle_lpm_name(ivl_lpm_t net, char*buf, size_t nbuf) { - size_t cnt = mangle_scope_name(ivl_lpm_scope(net), buf, nbuf); + size_t cnt = xnf_mangle_scope_name(ivl_lpm_scope(net), buf, nbuf); buf[cnt++] = '/'; strcpy(buf+cnt, ivl_lpm_basename(net)); } @@ -67,7 +67,7 @@ void mangle_lpm_name(ivl_lpm_t net, char*buf, size_t nbuf) * nexus by using the private pointer. Every nexus is used at least * twice, so this cuts the mangling time in half at least. */ -const char* mangle_nexus_name(ivl_nexus_t net) +const char* xnf_mangle_nexus_name(ivl_nexus_t net) { char*name = ivl_nexus_get_private(net); char*cp; @@ -94,6 +94,12 @@ const char* mangle_nexus_name(ivl_nexus_t net) /* * $Log: mangle.c,v $ + * Revision 1.3 2001/09/02 21:33:07 steve + * Rearrange the XNF code generator to be generic-xnf + * so that non-XNF code generation is also possible. + * + * Start into the virtex EDIF output driver. + * * Revision 1.2 2001/08/30 04:31:05 steve * Mangle nexus names. * diff --git a/tgt-fpga/tables.c b/tgt-fpga/tables.c new file mode 100644 index 000000000..99b8c10f6 --- /dev/null +++ b/tgt-fpga/tables.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2001 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 + */ +#ident "$Id: tables.c,v 1.1 2001/09/02 21:33:07 steve Exp $" + +# include "fpga_priv.h" +# include +# include + +extern const struct device_s d_generic; +extern const struct device_s d_generic_edif; + + +const struct device_table_s { + const char*name; + device_t driver; +} device_table[] = { + { "generic-edif", &d_generic_edif }, + { "generic-xnf", &d_generic }, + { "virtex", &d_generic_edif }, + { 0, 0 } +}; + +device_t device_from_arch(const char*arch) +{ + unsigned idx; + + assert(arch); + + for (idx = 0 ; device_table[idx].name ; idx += 1) { + if (strcmp(arch, device_table[idx].name) == 0) + return device_table[idx].driver; + + } + + return 0; +} + +/* + * $Log: tables.c,v $ + * Revision 1.1 2001/09/02 21:33:07 steve + * Rearrange the XNF code generator to be generic-xnf + * so that non-XNF code generation is also possible. + * + * Start into the virtex EDIF output driver. + * + */ +