diff --git a/tgt-fpga/d-generic-edif.c b/tgt-fpga/d-generic-edif.c index e48bb5524..6fbaa5aaf 100644 --- a/tgt-fpga/d-generic-edif.c +++ b/tgt-fpga/d-generic-edif.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-edif.c,v 1.6 2001/09/15 18:27:04 steve Exp $" +#ident "$Id: d-generic-edif.c,v 1.7 2001/09/16 01:48:16 steve Exp $" # include "device.h" # include "fpga_priv.h" @@ -68,8 +68,11 @@ static void show_root_ports_edif(ivl_scope_t root) for (idx = 0 ; idx < cnt ; idx += 1) { ivl_signal_t sig = ivl_scope_sig(root, idx); const char*use_name; - const char*dir = 0; + + if (ivl_signal_attr(sig, "PAD") != 0) + continue; + switch (ivl_signal_port(sig)) { case IVL_SIP_NONE: continue; @@ -383,6 +386,7 @@ void edif_show_generic_dff(ivl_lpm_t net) const struct device_s d_generic_edif = { edif_show_header, edif_show_footer, + 0, /* draw_pad not implemented */ edif_show_logic, edif_show_generic_dff, 0, @@ -394,6 +398,9 @@ const struct device_s d_generic_edif = { /* * $Log: d-generic-edif.c,v $ + * Revision 1.7 2001/09/16 01:48:16 steve + * Suppor the PAD attribute on signals. + * * Revision 1.6 2001/09/15 18:27:04 steve * Make configure detect malloc.h * diff --git a/tgt-fpga/d-generic.c b/tgt-fpga/d-generic.c index 9f356683c..3bfb7c9d2 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.8 2001/09/02 21:33:07 steve Exp $" +#ident "$Id: d-generic.c,v 1.9 2001/09/16 01:48:16 steve Exp $" # include "device.h" # include "fpga_priv.h" @@ -496,6 +496,7 @@ static void generic_show_add(ivl_lpm_t net) const struct device_s d_generic = { generic_show_header, generic_show_footer, + 0, /* show_pad not implemented */ generic_show_logic, generic_show_dff, generic_show_cmp_eq, @@ -507,6 +508,9 @@ const struct device_s d_generic = { /* * $Log: d-generic.c,v $ + * Revision 1.9 2001/09/16 01:48:16 steve + * Suppor the PAD attribute on signals. + * * 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. diff --git a/tgt-fpga/d-virtex.c b/tgt-fpga/d-virtex.c index b44a794a7..abf377b1b 100644 --- a/tgt-fpga/d-virtex.c +++ b/tgt-fpga/d-virtex.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-virtex.c,v 1.8 2001/09/15 18:27:04 steve Exp $" +#ident "$Id: d-virtex.c,v 1.9 2001/09/16 01:48:16 steve Exp $" # include "device.h" # include "fpga_priv.h" @@ -81,6 +81,17 @@ static const char*virtex_library_text = " (interface\n" " (port O (direction OUTPUT))\n" " (port I (direction INPUT)))))\n" +" (cell IBUF (cellType GENERIC)\n" +" (view net\n" +" (viewType NETLIST)\n" +" (interface\n" +" (port O (direction OUTPUT))\n" +" (port I (direction INPUT)))))\n" +" (cell IPAD (cellType GENERIC)\n" +" (view net\n" +" (viewType NETLIST)\n" +" (interface\n" +" (port IPAD (direction OUTPUT)))))\n" " (cell LUT2 (cellType GENERIC)\n" " (view net\n" " (viewType NETLIST)\n" @@ -121,6 +132,17 @@ static const char*virtex_library_text = " (port S (direction INPUT))\n" " (port DI (direction INPUT))\n" " (port CI (direction INPUT)))))\n" +" (cell OBUF (cellType GENERIC)\n" +" (view net\n" +" (viewType NETLIST)\n" +" (interface\n" +" (port O (direction OUTPUT))\n" +" (port I (direction INPUT)))))\n" +" (cell OPAD (cellType GENERIC)\n" +" (view net\n" +" (viewType NETLIST)\n" +" (interface\n" +" (port OPAD (direction INPUT)))))\n" " (cell VCC (cellType GENERIC)\n" " (view net\n" " (viewType NETLIST)\n" @@ -141,6 +163,87 @@ static void edif_show_header(ivl_design_t des) edif_show_header_generic(des, virtex_library_text); } +static void edif_show_virtex_pad(ivl_signal_t sig, const char*str) +{ + unsigned idx; + unsigned*pins; + char jbuf[1024]; + + pins = calloc(ivl_signal_pins(sig), sizeof(unsigned)); + + for (idx = 0 ; idx < ivl_signal_pins(sig) ; idx += 1) { + char*tmp; + pins[idx] = strtoul(str, &tmp, 10); + switch (*tmp) { + case ',': + tmp += 1; + break; + case 0: + break; + default: + assert(0); + } + + str = tmp; + } + + for (idx = 0 ; idx < ivl_signal_pins(sig) ; idx += 1) { + + edif_uref += 1; + + switch (ivl_signal_port(sig)) { + case IVL_SIP_INPUT: + fprintf(xnf, "(instance U%uPAD" + " (viewRef net (cellRef IPAD (libraryRef VIRTEX)))", + edif_uref); + if (pins[idx] != 0) + fprintf(xnf, " (property LOC (string \"P%u\"))", + pins[idx]); + fprintf(xnf, ")\n"); + + fprintf(xnf, "(instance U%u" + " (viewRef net " + " (cellRef IBUF (libraryRef VIRTEX))))\n", + edif_uref); + fprintf(xnf, "(net U%uN (joined" + " (portRef IPAD (instanceRef U%uPAD))" + " (portRef I (instanceRef U%u))))\n", + edif_uref, edif_uref, edif_uref); + + sprintf(jbuf, "(portRef O (instanceRef U%u))", edif_uref); + edif_set_nexus_joint(ivl_signal_pin(sig, idx), jbuf); + break; + + case IVL_SIP_OUTPUT: + fprintf(xnf, "(instance U%uPAD" + " (viewRef net (cellRef OPAD (libraryRef VIRTEX)))", + edif_uref); + if (pins[idx] != 0) + fprintf(xnf, " (property LOC (string \"P%u\"))", + pins[idx]); + fprintf(xnf, ")\n"); + + fprintf(xnf, "(instance U%u" + " (viewRef net " + " (cellRef OBUF (libraryRef VIRTEX))))\n", + edif_uref); + fprintf(xnf, "(net U%uN (joined" + " (portRef OPAD (instanceRef U%uPAD))" + " (portRef O (instanceRef U%u))))\n", + edif_uref, edif_uref, edif_uref); + + sprintf(jbuf, "(portRef I (instanceRef U%u))", edif_uref); + edif_set_nexus_joint(ivl_signal_pin(sig, idx), jbuf); + break; + + default: + assert(0); + } + } + + free(pins); +} + static void edif_show_lut2(const char*name, unsigned uref, ivl_nexus_t O, ivl_nexus_t I0, ivl_nexus_t I1, const char*truth_table) @@ -889,6 +992,7 @@ static void edif_show_virtex_add(ivl_lpm_t net) const struct device_s d_virtex_edif = { edif_show_header, edif_show_footer, + edif_show_virtex_pad, edif_show_virtex_logic, edif_show_generic_dff, edif_show_virtex_eq, @@ -900,6 +1004,9 @@ const struct device_s d_virtex_edif = { /* * $Log: d-virtex.c,v $ + * Revision 1.9 2001/09/16 01:48:16 steve + * Suppor the PAD attribute on signals. + * * Revision 1.8 2001/09/15 18:27:04 steve * Make configure detect malloc.h * diff --git a/tgt-fpga/device.h b/tgt-fpga/device.h index 05dcda638..574c1a0e9 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.6 2001/09/02 21:33:07 steve Exp $" +#ident "$Id: device.h,v 1.7 2001/09/16 01:48:16 steve Exp $" # include @@ -39,6 +39,8 @@ 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 pads connected to the specified signal. */ + void (*show_pad)(ivl_signal_t sig, const char*str); /* Draw basic logic devices. */ void (*show_logic)(ivl_net_logic_t net); /* This method emits a D type Flip-Flop */ @@ -64,6 +66,9 @@ extern device_t device_from_arch(const char*arch); /* * $Log: device.h,v $ + * Revision 1.7 2001/09/16 01:48:16 steve + * Suppor the PAD attribute on signals. + * * 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. diff --git a/tgt-fpga/fpga.c b/tgt-fpga/fpga.c index 4e3e7befd..165844ca2 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.4 2001/09/02 21:33:07 steve Exp $" +#ident "$Id: fpga.c,v 1.5 2001/09/16 01:48:16 steve Exp $" #endif # include "config.h" @@ -44,12 +44,32 @@ static int show_process(ivl_process_t net, void*x) return 0; } +static void show_pads(ivl_scope_t scope) +{ + unsigned idx; + + if (device->show_pad == 0) + return; + + for (idx = 0 ; idx < ivl_scope_sigs(scope) ; idx += 1) { + ivl_signal_t sig = ivl_scope_sig(scope, idx); + const char*pad; + + if (ivl_signal_port(sig) == IVL_SIP_NONE) + continue; + + pad = ivl_signal_attr(sig, "PAD"); + if (pad == 0) + continue; + + device->show_pad(sig, pad); + } +} + /* * This is the main entry point that ivl uses to invoke me, the code * generator. */ - - int target_design(ivl_design_t des) { ivl_scope_t root = ivl_design_root(des); @@ -85,6 +105,10 @@ int target_design(ivl_design_t des) that it is not supported. */ ivl_design_process(des, show_process, 0); + /* Get the pads from the design, and draw them to connect to + the associated signals. */ + show_pads(root); + /* Scan the scopes, looking for gates to draw into the output netlist. */ show_scope_gates(root, 0); @@ -99,6 +123,9 @@ int target_design(ivl_design_t des) /* * $Log: fpga.c,v $ + * Revision 1.5 2001/09/16 01:48:16 steve + * Suppor the PAD attribute on signals. + * * 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. diff --git a/tgt-fpga/fpga.txt b/tgt-fpga/fpga.txt index e70d1fd3a..14d39c67f 100644 --- a/tgt-fpga/fpga.txt +++ b/tgt-fpga/fpga.txt @@ -2,7 +2,7 @@ FPGA LOADABLE CODE GENERATOR FOR Icarus Verilog Copyright 2001 Stephen Williams - $Id: fpga.txt,v 1.2 2001/09/06 04:28:40 steve Exp $ + $Id: fpga.txt,v 1.3 2001/09/16 01:48:16 steve Exp $ The FPGA code generator supports a variety of FPGA devices, writing XNF or EDIF depending on the target. You can select the architecture @@ -82,10 +82,76 @@ interface definition into the design. (This is *not* the same as the PADS of a part.) The generated EDIF interface section contains port definitions, including the proper direction marks. +With the (rename ...) s-exp in EDIF, it is possible to assign +arbitrary text to port names. The EDIF code generator therefore does +not resort to the mangling that is needed for the XNF target. The base +name of the signal that is an input or output is used as the name of +the port, complete with the proper case. +However, since the ports are single bit ports, the name of vectors +includes the string "[0]" where the number is the bit number. For +example, the module: + + + module main(out, in); + output out; + input [2:0] in; + [...] + endmodule + +creates these ports: + + out OUTPUT + in[0] INPUT + in[1] INPUT + in[2] INPUT + +Target tools, include Xilinx Foundation tools, understand the [] +characters in the name and recollect the signals into a proper bus, +when presenting the vector to the user. + + +PADS AND PIN ASSIGNMENT + +The ports of a root module may be assigned to specific pins, or to a +generic pad. If a signal (that is a port) has a PAD attribute, then +the value of that attribute is a list of numbers, one for each bit of +the signal, that specifies the pin for each bit of the signal. For +example: + + module main(out, in); + output out; + input [2:0] in; + [...] + $attribute(out, "PAD", "10"); + $attribute(in, "PAD", "20,21,22"); + endmodule + +In this example, port ``out'' is assigned to pin 10, and port ``in'' +is assigned to pins 20-22. If the architecture supports it, then a pin +number of 0 means let the back end tools choose a pin. + +NOTE: If a module port is assigned to a pin (and therefore attached to +a PAD) then it is *not* connected to a port of the EDIF file. This is +because the PAD (and possibly IBUF or OBUF) would become an extra +driver to the port. An error. + + +COMPILING WITH XILINX FOUNDATION + +Compile a single-file design with command line tools like so: + + % iverilog -parch=virtex -o foo.edf foo.vl + % edif2ngd foo.edf foo.ngo + % ngdbuild -p v50-pq240 foo.ngo foo.ngd + % map -o map.ncd foo.ngd + % par -w map.ncd foo.ncd --- $Log: fpga.txt,v $ +Revision 1.3 2001/09/16 01:48:16 steve + Suppor the PAD attribute on signals. + Revision 1.2 2001/09/06 04:28:40 steve Separate the virtex and generic-edif code generators.