Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Remove last vestiges of XNF.

XNF hasn't been supported in a while. Xilinx doesn't put any effort
into it either, for that matter.
  • Loading branch information...
commit 456fffa7ed3c966a5e8bcb127e06c36c7cca0a11 1 parent 1944f37
@steveicarus authored
View
10 Makefile.in
@@ -230,8 +230,6 @@ else
WIN32_INSTALL = $(bindir)/iverilog-vpi
endif
-XNF_INSTALL = $(libdir)/ivl/xnf.conf $(libdir)/ivl/xnf-s.conf
-
install: all installdirs $(libdir)/ivl/ivl@EXEEXT@ $(libdir)/ivl/include/constants.vams $(libdir)/ivl/include/disciplines.vams $(includedir)/ivl_target.h $(includedir)/_pli_types.h $(includedir)/vpi_user.h $(includedir)/acc_user.h $(includedir)/veriuser.h $(WIN32_INSTALL) $(INSTALL_DOC)
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
for dir in vpi ivlpp driver; \
@@ -249,12 +247,6 @@ $(libdir)/ivl/include/constants.vams: $(srcdir)/constants.vams
$(libdir)/ivl/include/disciplines.vams: $(srcdir)/disciplines.vams
$(INSTALL_DATA) $(srcdir)/disciplines.vams $(DESTDIR)$(libdir)/ivl/include/disciplines.vams
-$(libdir)/ivl/xnf-s.conf: $(srcdir)/xnf-s.conf
- $(INSTALL_DATA) $(srcdir)/xnf-s.conf $(DESTDIR)$(libdir)/ivl/xnf-s.conf
-
-$(libdir)/ivl/xnf.conf: $(srcdir)/xnf.conf
- $(INSTALL_DATA) $(srcdir)/xnf.conf $(DESTDIR)$(libdir)/ivl/xnf.conf
-
$(includedir)/ivl_target.h: $(srcdir)/ivl_target.h
$(INSTALL_DATA) $(srcdir)/ivl_target.h $(DESTDIR)$(includedir)/ivl_target.h
@@ -304,7 +296,7 @@ uninstall:
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
for dir in vpi ivlpp driver; \
do (cd $$dir ; $(MAKE) $@); done
- for f in xnf.conf xnf-s.conf ivl@EXEEXT@ include/constants.vams include/disciplines.vams; \
+ for f in ivl@EXEEXT@ include/constants.vams include/disciplines.vams; \
do rm -f $(DESTDIR)$(libdir)/ivl/$$f; done
-rmdir $(DESTDIR)$(libdir)/ivl/include
-rmdir $(DESTDIR)$(libdir)/ivl
View
5 README.txt
@@ -12,10 +12,7 @@ home page at <http://www.icarus.com/eda/verilog>.
Icarus Verilog is not aimed at being a simulator in the traditional
sense, but a compiler that generates code employed by back-end
-tools. These back-end tools currently include a simulator engine
-called VVP, an XNF (Xilinx Netlist Format) generator and an EDIF FPGA
-netlist generator. In the future, backends are expected for EDIF/LPM,
-structural Verilog, VHDL, etc.
+tools.
For instructions on how to run Icarus Verilog,
see the ``iverilog'' man page.
View
12 driver/iverilog.man
@@ -14,7 +14,7 @@ iverilog - Icarus Verilog compiler
\fIiverilog\fP is a compiler that translates Verilog source code into
executable programs for simulation, or other netlist formats for
further processing. The currently supported targets are \fIvvp\fP for
-simulation, and \fIxnf\fP and \fIfpga\fP for synthesis. Other target
+simulation, and \fIfpga\fP for synthesis. Other target
types are added as code generators are implemented.
.SH OPTIONS
@@ -212,11 +212,6 @@ This is the default. The vvp target generates code for the vvp
runtime. The output is a complete program that simulates the design
but must be run by the \fBvvp\fP command.
.TP 8
-.B xnf
-This is the Xilinx Netlist Format used by many tools for placing
-devices in FPGAs or other programmable devices. This target is
-obsolete, use the \fBfpga\fP target instead.
-.TP 8
.B fpga
This is a synthesis target that supports a variety of fpga devices,
mostly by EDIF format output. The Icarus Verilog fpga code generator
@@ -418,11 +413,6 @@ To compile and run explicitly using the vvp runtime:
iverilog -ohello.vvp -tvvp hello.v
-To compile hello.v to a file in XNF-format called hello.xnf
-
- iverilog -txnf -ohello.xnf hello.v
-
-
.SH "AUTHOR"
.nf
Steve Williams (steve@icarus.com)
View
6 main.cc
@@ -161,9 +161,6 @@ extern void synth(Design*des);
extern void synth2(Design*des);
extern void syn_rules(Design*des);
extern void nodangle(Design*des);
-#ifdef WITH_T_XNF
-extern void xnfio(Design*des);
-#endif
typedef void (*net_func)(Design*);
static struct net_func_map {
@@ -175,9 +172,6 @@ static struct net_func_map {
{ "synth", &synth },
{ "synth2", &synth2 },
{ "syn-rules", &syn_rules },
-#ifdef WITH_T_XNF
- { "xnfio", &xnfio },
-#endif
{ 0, 0 }
};
View
1,151 t-xnf.cc
@@ -1,1151 +0,0 @@
-/*
- * Copyright (c) 1998-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
- */
-#ifdef HAVE_CVS_IDENT
-#ident "$Id: t-xnf.cc,v 1.52 2004/02/20 18:53:36 steve Exp $"
-#endif
-
-# include "config.h"
-
-# include <iostream>
-
-/* XNF BACKEND
- * This target supports generating Xilinx Netlist Format netlists for
- * use by Xilinx tools, and other tools that accepts Xilinx designs.
- *
- * The code generator automatically detects ports to top level modules
- * and generates SIG records that make the XNF usable as a schematic.
- *
- * FLAGS
- * The XNF backend uses the following flags from the command line to
- * affect the generated file:
- *
- * part=<foo>
- * Specify the part type. The part string is written into the
- * PART record. Valid types are defined by Xilinx or the
- * receiving tools.
- *
- * ncf=<path>
- * Specify the path to a NCF file. This is an OUTPUT file into
- * which the code generator will write netlist constraints that
- * relate to pin assignments, CLB placement, etc. If this flag is
- * not given, no NCF file will be written.
- *
- * WIRE ATTRIBUTES
- *
- * PAD = <io><n>
- * Tell the XNF generator that this wire goes to a PAD. The <io>
- * is a single character that tells the direction, and <n> is the
- * pin number. For example, "o31" is output on pin 31. The PAD
- * attribute is not practically connected to a vector, as all the
- * bits would go to the same pad.
- *
- * NODE ATTRIBUTES
- *
- * XNF-LCA = <lname>:<pin>,<pin>...
- * Specify the LCA library part type for the gate. The lname
- * is the name of the symbol to use (i.e. DFF) and the comma
- * separated list is the names of the pins, in the order they
- * appear in the Verilog source. If the name is prefixed with a
- * tilde (~) then the pin is inverted, and the proper "INV" token
- * will be added to the PIN record.
- *
- * This attribute can override even the typical generation of
- * gates that one might naturally expect of the code generator,
- * but may be used by the optimizers for placing parts.
- *
- * An example is "XNF-LCA=OBUF:O,~I". This attribute means that
- * the object is an OBUF. Pin 0 is called "O", and pin 1 is
- * called "I". In addition, pin 1 is inverted.
- */
-
-# include "netlist.h"
-# include "target.h"
-# include <fstream>
-# include <sstream>
-
-verinum::V link_get_ival(const Link&lnk)
-{
- const Nexus*nex = lnk.nexus();
- for (const Link*cur = nex->first_nlink()
- ; cur ; cur = cur->next_nlink()) {
- if (cur == &lnk)
- continue;
-
- if (dynamic_cast<const NetNet*>(cur->get_obj()))
- return cur->nexus()->get_init();
-
- }
-
- return verinum::Vx;
-}
-
-class target_xnf : public target_t {
-
- public:
- bool start_design(const Design*);
- int end_design(const Design*);
- void memory(const NetMemory*);
- void signal(const NetNet*);
-
- void lpm_add_sub(const NetAddSub*);
- void lpm_compare(const NetCompare*);
- void lpm_compare_eq_(ostream&os, const NetCompare*);
- void lpm_compare_ge_(ostream&os, const NetCompare*);
- void lpm_compare_le_(ostream&os, const NetCompare*);
- void lpm_ff(const NetFF*);
- void lpm_mux(const NetMux*);
- void lpm_ram_dq(const NetRamDq*);
-
- bool net_const(const NetConst*);
- void logic(const NetLogic*);
- bool bufz(const NetBUFZ*);
- void udp(const NetUDP*);
-
- private:
- static string mangle(const string&);
- static string mangle(perm_string);
- static string choose_sig_name(const Link*lnk);
- static void draw_pin(ostream&os, const string&name,
- const Link&lnk);
- static void draw_sym_with_lcaname(ostream&os, string lca,
- const NetNode*net);
- static void draw_xor(ostream&os, const NetAddSub*, unsigned idx);
- enum adder_type {FORCE0, LOWER, DOUBLE, LOWER_W_CO, EXAMINE_CI };
- static void draw_carry(ostream&os, const NetAddSub*, unsigned idx,
- enum adder_type);
-
- ofstream out_;
- ofstream ncf_;
-};
-
-/*
- * This function takes a signal name and mangles it into an equivalent
- * name that is suitable to the XNF format.
- */
-string target_xnf::mangle(const string&name)
-{
- string result;
- for (unsigned idx = 0 ; idx < name.length() ; idx += 1)
- switch (name[idx]) {
- case '.':
- result = result + "/";
- break;
- default:
- result = result + name[idx];
- break;
- }
-
- return result;
-}
-
-string target_xnf::mangle(perm_string name)
-{
- return mangle(string(name));
-}
-
-/*
- * This method takes a signal and pin number as a nexus. Scan the
- * nexus to decide which name to use if there are lots of attached
- * signals.
- */
-string target_xnf::choose_sig_name(const Link*lnk)
-{
- return mangle( string(lnk->nexus()->name()) );
-}
-
-void target_xnf::draw_pin(ostream&os, const string&name,
- const Link&lnk)
-{
- bool inv = false;
- string use_name = name;
- if (use_name[0] == '~') {
- inv = true;
- use_name = use_name.substr(1);
- }
-
- char type=0;
- switch (lnk.get_dir()) {
- case Link::INPUT:
- case Link::PASSIVE:
- type = 'I';
- break;
- case Link::OUTPUT:
- type = 'O';
- break;
- }
- assert(type);
-
- os << " PIN, " << use_name << ", " << type << ", " <<
- choose_sig_name(&lnk);
- if (inv) os << ",,INV";
- os << endl;
-}
-
-static string scrape_pin_name(string&list)
-{
- unsigned idx = list.find(',');
- string name = list.substr(0, idx);
- list = list.substr(idx+1);
- return name;
-}
-
-/*
- * This method draws an LCA item based on the XNF-LCA attribute
- * given. The LCA attribute gives enough information to completely
- * draw the node in XNF, which is pretty handy at this point.
- */
-void target_xnf::draw_sym_with_lcaname(ostream&os, string lca,
- const NetNode*net)
-{
- unsigned idx = lca.find(':');
- string lcaname = lca.substr(0, idx);
- lca = lca.substr(idx+1);
-
- os << "SYM, " << mangle(net->name()) << ", " << lcaname
- << ", LIBVER=2.0.0" << endl;
-
- for (idx = 0 ; idx < net->pin_count() ; idx += 1) {
- string usename = scrape_pin_name(lca);
- if (usename == "") continue;
- draw_pin(os, usename, net->pin(idx));
- }
-
- os << "END" << endl;
-}
-
-bool target_xnf::start_design(const Design*des)
-{
- out_.open(des->get_flag("-o"), ios::out | ios::trunc);
-
- string ncfpath = des->get_flag("ncf");
- if (ncfpath != "")
- ncf_.open(ncfpath.c_str());
-
- out_ << "LCANET,6" << endl;
- out_ << "PROG,verilog,$Name: $,\"Icarus Verilog\"" << endl;
- ncf_ << "# Generated by Icarus Verilog $Name: $" << endl;
-
- if (des->get_flag("part") != 0) {
- out_ << "PART," << des->get_flag("part") << endl;
- ncf_ << "CONFIG PART=" << des->get_flag("part") << ";" << endl;
- }
-
- return true;
-}
-
-int target_xnf::end_design(const Design*)
-{
- out_ << "EOF" << endl;
- ncf_.close();
- return 0;
-}
-
-void scrape_pad_info(string str, char&dir, unsigned&num)
-{
- // Get rid of leading white space
- while (str[0] == ' ')
- str = str.substr(1);
-
- // Get the direction letter
- switch (str[0]) {
- case 'b':
- case 'B':
- dir = 'B';
- break;
- case 'o':
- case 'O':
- dir = 'O';
- break;
- case 'i':
- case 'I':
- dir = 'I';
- break;
- case 't':
- case 'T':
- dir = 'T';
- break;
- default:
- dir = '?';
- break;
- }
-
- // Get the number part.
- str = str.substr(1);
- unsigned val = 0;
- while (str.size() && isdigit(str[0])) {
- val = val * 10 + (str[0]-'0');
- str = str.substr(1);
- }
- num = val;
-}
-
-/*
- * Memories are handled by the lpm_ram_dq method, so there is nothing
- * to do here.
- */
-void target_xnf::memory(const NetMemory*)
-{
-}
-
-/*
- * Look for signals that have attributes that are pertinent to XNF
- * files. The most obvious are those that have the PAD attribute.
- *
- * Individual signals are easy, the pad description is a letter
- * followed by a decimal number that is the pin.
- *
- * The PAD attribute for a vector is a comma separated pin
- * descriptions, that enumerate the pins from most significant to
- * least significant.
- */
-void target_xnf::signal(const NetNet*net)
-{
-
- /* Look for signals that are ports to the root module. If they
- are, the write a SIG record and generate a pin name so that
- this module can be used as a macro. */
-
- if (const NetScope*scope = net->scope()) do {
-
- if (scope->parent())
- break;
-
- if (net->port_type() == NetNet::NOT_A_PORT)
- break;
-
- string mname = mangle(net->name());
- string pname = mname.substr(mname.find('/')+1, mname.length());
-
- if (net->pin_count() == 1) {
- out_ << "SIG, " << mangle(net->name()) << ", PIN="
- << pname << endl;
-
- } else for (unsigned idx = 0; idx < net->pin_count(); idx += 1) {
- out_ << "SIG, " << mangle(net->name()) << "<" << idx
- << ">, PIN=" << pname << idx << endl;
- }
-
- } while (0);
-
-
- /* Now look to see if a PAD attribute is attached, and if so
- write out PAD information to the XNF and the ncf files. */
-
- string pad = net->attribute(perm_string::literal("PAD")).as_string();
- if (pad == "")
- return;
-
- if (net->pin_count() > 1) {
- cerr << "Signal ``" << net->name() << "'' with PAD=" <<
- pad << " is a vector." << endl;
- return;
- }
-
- char dir;
- unsigned num;
- scrape_pad_info(pad, dir, num);
- out_ << "EXT, " << mangle(net->name()) << ", " << dir
- << ", " << num << endl;
-
- ncf_ << "# Assignment to pin " << num << " (DIR=" << dir <<
- ") by $attribute(" << net->name() << ", \"PAD\", \"" <<
- pad << "\")" << endl;
- ncf_ << "NET " << mangle(net->name()) << " LOC=P" << num << ";"
- << endl;
-}
-
-void target_xnf::draw_xor(ostream &os, const NetAddSub*gate, unsigned idx)
-{
- string name = mangle(gate->name());
- string name_add = name;
- string name_cout = name + "/COUT";
-
- // We only need to pick up the
- // carry if we are not the 0 bit. (We know it is 0).
- os << "SYM, " << name_add << "<" << (idx+0) << ">, XOR, "
- "LIBVER=2.0.0" << endl;
- draw_pin(os, "O", gate->pin_Result(idx));
- draw_pin(os, "I0", gate->pin_DataA(idx));
- draw_pin(os, "I1", gate->pin_DataB(idx));
- if (idx > 0) {
- os << " PIN, I2, I, " << name_cout << "<" <<
- idx << ">" << endl;
- }
- os << "END" << endl;
-}
-
-void target_xnf::draw_carry(ostream &os, const NetAddSub*gate, unsigned idx,
- enum adder_type type)
-{
- string name = mangle(gate->name());
-
- string name_cy4 = name + "/CY";
- string name_cym = name + "/CM";
- string name_cout = name + "/COUT";
-
- os << "SYM, " << name_cy4 << "<" << idx << ">, CY4, "
- "LIBVER=2.0.0" << endl;
-
- // Less significant bit addends, if any
- if ( type == LOWER || type == DOUBLE || type == LOWER_W_CO ) {
- draw_pin(os, "A0", gate->pin_DataA(idx));
- draw_pin(os, "B0", gate->pin_DataB(idx));
- }
-
- // More significant bit addends, if any
- if ( type == DOUBLE ) {
- draw_pin(os, "A1", gate->pin_DataA(idx+1));
- draw_pin(os, "B1", gate->pin_DataB(idx+1));
- }
-
- // All but FORCE0 cells have carry input
- if ( type != FORCE0 ) {
- os << " PIN, CIN, I, " << name_cout << "<" << idx << ">" << endl;
- }
-
- // Connect the Cout0 to a signal so that I can connect
- // it to the adder.
- switch (type) {
- case LOWER:
- case DOUBLE:
- os << " PIN, COUT0, O, " << name_cout << "<" << (idx+1) <<
- ">" << endl;
- break;
- case EXAMINE_CI:
- case LOWER_W_CO:
- draw_pin(os, "COUT0", gate->pin_Cout());
- break;
-
- default:
- assert(0);
- }
-
- // Connect the Cout, this will connect to the next Cin
- if ( type == FORCE0 || type == DOUBLE ) {
- unsigned int to = (type==FORCE0)?(0):(idx+2);
- os << " PIN, COUT, O, " << name_cout << "<" << to <<
- ">" << endl;
- }
-
- // These are the mode inputs from the CY_xx pseudo-device
- for (unsigned cn = 0 ; cn < 8 ; cn += 1) {
- os << " PIN, C" << cn << ", I, " << name << "/C"
- << cn << "<" << (idx) << ">" << endl;
- }
- os << "END" << endl;
-
- // On to the CY_xx pseudo-device itself
- os << "SYM, " << name_cym << "<" << (idx) << ">, ";
- switch (type) {
- case FORCE0:
- os << "CY4_37, CYMODE=FORCE-0" << endl;
- break;
- case LOWER:
- os << "CY4_01, CYMODE=ADD-F-CI" << endl;
- break;
- case LOWER_W_CO:
- os << "CY4_01, CYMODE=ADD-F-CI" << endl;
- break;
- case DOUBLE:
- os << "CY4_02, CYMODE=ADD-FG-CI" << endl;
- break;
- case EXAMINE_CI:
- os << "CY4_42, CYMODE=EXAMINE-CI" << endl;
- break;
- }
- for (unsigned cn = 0 ; cn < 8 ; cn += 1) {
- os << " PIN, C" << cn << ", O, " << name << "/C"
- << cn << "<" << (idx) << ">" << endl;
- }
- os << "END" << endl;
-}
-
-/*
- * This function makes an adder out of carry logic symbols. It makes
- * as many 2 bit adders as are possible, then the top bit is made into
- * a 1-bit adder (with carry in) in the F unit. The low carry is
- * initialized with the FORCE-0 configuration of a carry unit below
- * the 0 bit. This takes up the carry logic of the CLB below, but not
- * the G function.
- *
- * References:
- * XNF 6.1 Specification
- * Application note XAPP013
- * Xilinx Libraries Guide, Chapter 12
- */
-void target_xnf::lpm_add_sub(const NetAddSub*gate)
-{
- unsigned width = gate->width();
-
- /* Make the force-0 carry mode object to initialize the bottom
- bits of the carry chain. Label this with the width instead
- of the bit position so that symbols don't clash. */
-
- draw_carry(out_, gate, width+1, FORCE0);
-
-
- /* Now make the 2 bit adders that chain from the cin
- initializer and up. Save the tail bits for later. */
- for (unsigned idx = 0 ; idx < width-2 ; idx += 2)
- draw_carry(out_, gate, idx, DOUBLE);
-
- /* Always have one or two tail bits. The situation gets a
- little tricky if we want the carry output, so handle that
- here.
-
- If the carry-out is connected, and there are an even number
- of data bits, we need to see the cout from the CLB. This is
- done by configuring the top CLB CY device as ADD-FG-CI (to
- activate cout) and create an extra CLB CY device on top of
- the carry chain configured EXAMINE-CI to put the carry into
- the G function block.
-
- IF the carry-out is connected and there are an odd number
- of data bits, then the top CLB can be configured to carry
- the top bit in the F unit and deliver the carry out through
- the G unit.
-
- If the carry-out is not connected, then configure this top
- CLB as ADD-F-CI. The draw_xor for the top bit will include
- the F carry if needed. */
-
- if (gate->pin_Cout().is_linked()) {
- if (width%2 == 0) {
- draw_carry(out_, gate, width-2, DOUBLE);
- draw_carry(out_, gate, width, EXAMINE_CI);
- } else {
- draw_carry(out_, gate, width-1, LOWER_W_CO);
- }
-
- } else {
- if (width%2 == 0)
- draw_carry(out_, gate, width-2, LOWER);
- else
- draw_carry(out_, gate, width-1, LOWER);
- }
-
- /* Now draw all the single bit (plus carry in) adders from XOR
- gates. This puts the F and G units to use. */
- for (unsigned idx = 0 ; idx < width ; idx += 1)
- draw_xor(out_, gate, idx);
-
-}
-
-/*
- * In XNF, comparators are done differently depending on the type of
- * comparator being implemented. So, here we dispatch to the correct
- * code generator.
- */
-void target_xnf::lpm_compare(const NetCompare*dev)
-{
- if (dev->pin_AEB().is_linked() || dev->pin_ANEB().is_linked()) {
- lpm_compare_eq_(out_, dev);
- return;
- }
-
- if (dev->pin_AGEB().is_linked()) {
- lpm_compare_ge_(out_, dev);
- return;
- }
-
- if (dev->pin_ALEB().is_linked()) {
- lpm_compare_le_(out_, dev);
- return;
- }
-
- assert(0);
-}
-
-/*
- * To compare that vectors are equal (identity comparator) generate
- * XNOR gates to compare each pair of bits, then generate an AND gate
- * to combine the bitwise results. This is pretty much the best way to
- * do an identity compare in Xilinx CLBs.
- */
-void target_xnf::lpm_compare_eq_(ostream&os, const NetCompare*dev)
-{
- string mname = mangle(dev->name());
-
- /* Draw XNOR gates for each bit pair. These gates to the
- bitwise comparison. */
- for (unsigned idx = 0 ; idx < dev->width() ; idx += 1) {
- os << "SYM, " << mname << "/cmp<" << idx << ">, "
- << "XNOR, LIBVER=2.0.0" << endl;
- os << " PIN, O, O, " << mname << "/bit<" << idx << ">"
- << endl;
- draw_pin(os, "I0", dev->pin_DataA(idx));
- draw_pin(os, "I1", dev->pin_DataB(idx));
- os << "END" << endl;
- }
-
- /* Now draw an AND gate to combine all the bitwise
- comparisons. If there are more the 5 bits of data, then we
- are going to have generate a nested AND to combine the
- results. */
-
- if (dev->width() > 5) {
- for (unsigned idx = 0 ; idx < dev->width() ; idx += 5) {
-
- if ((idx+1) >= dev->width()) break;
- os << "SYM, " << mname << "/nest<" << idx
- << ">, AND, LIBVER=2.0.0" << endl;
-
- os << " PIN, O, O, " << mname << "/nbit<" << idx
- << ">" << endl;
-
- os << " PIN, I0, I, " << mname << "/bit<" << idx+0
- << ">" << endl;
- os << " PIN, I1, I, " << mname << "/bit<" << idx+1
- << ">" << endl;
- if ((idx+2) >= dev->width()) goto gate_out;
- os << " PIN, I2, I, " << mname << "/bit<" << idx+2
- << ">" << endl;
- if ((idx+3) >= dev->width()) goto gate_out;
- os << " PIN, I3, I, " << mname << "/bit<" << idx+3
- << ">" << endl;
- if ((idx+4) >= dev->width()) goto gate_out;
- os << " PIN, I4, I, " << mname << "/bit<" << idx+4
- << ">" << endl;
- gate_out:
- os << "END" << endl;
- }
-
- /* Draw an AND gate if this is an EQ result, or a NAND
- gate of this is a NEQ result. */
-
- if (dev->pin_AEB().is_linked()) {
- assert( ! dev->pin_ANEB().is_linked());
- os << "SYM, " << mname << ", AND, LIBVER=2.0.0" << endl;
- draw_pin(os, "O", dev->pin_AEB());
-
- } else {
- assert( dev->pin_ANEB().is_linked());
- os << "SYM, " << mname << ", NAND, LIBVER=2.0.0" << endl;
- draw_pin(os, "O", dev->pin_ANEB());
- }
-
- for (unsigned idx = 0 ; idx < dev->width() ; idx += 5) {
- if ((idx+1) == dev->width())
- os << " PIN, I" << idx/5 << ", I, " << mname
- << "/bit<" << idx << ">" << endl;
- else
- os << " PIN, I" << idx/5 << ", I, " << mname
- << "/nbit<" << idx << ">" << endl;
- }
- os << "END" << endl;
-
- } else {
- if (dev->pin_AEB().is_linked()) {
- assert( ! dev->pin_ANEB().is_linked());
- os << "SYM, " << mname << ", AND, LIBVER=2.0.0" << endl;
- draw_pin(os, "O", dev->pin_AEB());
-
- } else {
- assert( dev->pin_ANEB().is_linked());
- os << "SYM, " << mname << ", NAND, LIBVER=2.0.0" << endl;
- draw_pin(os, "O", dev->pin_ANEB());
- }
-
- for (unsigned idx = 0 ; idx < dev->width() ; idx += 1) {
- os << " PIN, I" << idx << ", I, " << mname << "/bit<"
- << idx << ">" << endl;
- }
- os << "END" << endl;
- }
-}
-
-void target_xnf::lpm_compare_ge_(ostream&os, const NetCompare*dev)
-{
- cerr << "XXXX GE not supported yet" << endl;
-}
-
-void target_xnf::lpm_compare_le_(ostream&os, const NetCompare*dev)
-{
- cerr << "XXXX LE not supported yet" << endl;
-}
-
-void target_xnf::lpm_ff(const NetFF*net)
-{
- string type = net->attribute(perm_string::literal("LPM_FFType")).as_string();
- if (type == "") type = "DFF";
-
- // XXXX For now, only support DFF
- assert(type == "DFF");
-
- string lcaname = net->attribute(perm_string::literal("XNF-LCA")).as_string();
- if (lcaname != "") {
- draw_sym_with_lcaname(out_, lcaname, net);
- return;
- }
-
- assert(net->attribute(perm_string::literal("XNF-LCA")) == verinum(""));
-
- /* Create a DFF object for each bit of width. The symbol name
- has the index number appended so that read XNF may be able
- to buss them. If the NetNet objects connected to the Q
- output of the DFF have an initial value, the write an INIT=
- parameter to set the power-up value. */
-
- for (unsigned idx = 0 ; idx < net->width() ; idx += 1) {
-
- verinum::V ival = link_get_ival(net->pin_Q(idx));
-
- out_ << "SYM, " << mangle(net->name()) << "<" << idx << ">, DFF, ";
-
- switch (ival) {
- case verinum::V0:
- out_ << "INIT=R, ";
- break;
- case verinum::V1:
- out_ << "INIT=S, ";
- break;
-
- default:
- break;
- }
-
- out_ << "LIBVER=2.0.0" << endl;
- draw_pin(out_, "Q", net->pin_Q(idx));
- draw_pin(out_, "D", net->pin_Data(idx));
-
- if (net->attribute(perm_string::literal("Clock:LPM_Polarity")) == verinum("INVERT"))
- draw_pin(out_, "~C", net->pin_Clock());
- else
- draw_pin(out_, "C", net->pin_Clock());
-
- if (net->pin_Enable().is_linked())
- draw_pin(out_, "CE", net->pin_Enable());
-
- out_ << "END" << endl;
- }
-}
-
-/*
- * Generate an LPM_MUX.
- *
- * XXXX NOTE: For now, this only supports combinational LPM_MUX
- * devices that have a single select input. These are typically
- * generated from ?: expressions.
- */
-void target_xnf::lpm_mux(const NetMux*net)
-{
- assert(net->sel_width() == 1);
- assert(net->size() == 2);
-
- for (unsigned idx = 0 ; idx < net->width() ; idx += 1) {
-
- out_ << "SYM, " << mangle(net->name()) << "<" << idx << ">,"
- << " EQN, EQN=(I0 * I2) + (~I0 * I1)" << endl;
-
- draw_pin(out_, "I0", net->pin_Sel(0));
- draw_pin(out_, "I1", net->pin_Data(idx,0));
- draw_pin(out_, "I2", net->pin_Data(idx,1));
- draw_pin(out_, "O", net->pin_Result(idx));
-
- out_ << "END" << endl;
- }
-
-}
-
-void target_xnf::lpm_ram_dq(const NetRamDq*ram)
-{
- assert(ram->count_partners() == 1);
-
- for (unsigned idx = 0 ; idx < ram->width() ; idx += 1) {
- out_ << "SYM, " << mangle(ram->name())
- << "<" << idx << ">, RAMS" << endl;
-
- draw_pin(out_, "O", ram->pin_Q(idx));
- draw_pin(out_, "D", ram->pin_Data(idx));
- draw_pin(out_, "WE", ram->pin_WE());
- draw_pin(out_, "WCLK", ram->pin_InClock());
- for (unsigned adr = 0 ; adr < ram->awidth() ; adr += 1) {
- ostringstream tmp;
- tmp << "A" << adr;
- draw_pin(out_, tmp.str(), ram->pin_Address(adr));
- }
-
- out_ << "END" << endl;
- }
-}
-
-bool target_xnf::net_const(const NetConst*c)
-{
- unsigned x_bits = 0;
- for (unsigned idx = 0 ; idx < c->pin_count() ; idx += 1) {
- verinum::V v=c->value(idx);
- const Link& lnk = c->pin(idx);
-
- switch (v) {
- case verinum::V0:
- out_ << " PWR, 0, " << choose_sig_name(&lnk) << endl;
- break;
- case verinum::V1:
- out_ << " PWR, 1, " << choose_sig_name(&lnk) << endl;
- break;
- case verinum::Vz:
- break;
- default:
- x_bits += 1;
- if (x_bits == 1)
- cerr << "xnf: error: Unknown (x) const bit value"
- << " assigned to " << choose_sig_name(&lnk)
- << endl;
- break;
- }
- }
-
- return x_bits == 0;
-}
-
-/*
- * The logic gates I know so far can be translated directly into XNF
- * standard symbol types. This is a fairly obvious transformation.
- */
-void target_xnf::logic(const NetLogic*net)
-{
- // The XNF-LCA attribute overrides anything I might guess
- // about this object.
- string lca = net->attribute(perm_string::literal("XNF-LCA")).as_string();
- if (lca != "") {
- draw_sym_with_lcaname(out_, lca, net);
- return;
- }
-
- out_ << "SYM, " << mangle(net->name()) << ", ";
- switch (net->type()) {
- case NetLogic::AND:
- out_ << "AND";
- break;
- case NetLogic::BUF:
- out_ << "BUF";
- break;
- case NetLogic::NAND:
- out_ << "NAND";
- break;
- case NetLogic::NOR:
- out_ << "NOR";
- break;
- case NetLogic::NOT:
- out_ << "INV";
- break;
- case NetLogic::OR:
- out_ << "OR";
- break;
- case NetLogic::XNOR:
- out_ << "XNOR";
- break;
- case NetLogic::XOR:
- out_ << "XOR";
- break;
- case NetLogic::BUFIF0:
- case NetLogic::BUFIF1:
- out_ << "TBUF";
- break;
- default:
- cerr << "internal error: XNF: Unhandled logic type." << endl;
- break;
- }
- out_ << ", LIBVER=2.0.0" << endl;
-
- /* All of these kinds of devices have an output on pin 0. */
- draw_pin(out_, "O", net->pin(0));
-
- /* Most devices have inputs called I<N> for all the remaining
- pins. The TBUF devices are slightly different, but
- essentially the same structure. */
- switch (net->type()) {
-
- case NetLogic::BUFIF0:
- assert(net->pin_count() == 3);
- draw_pin(out_, "I", net->pin(1));
- draw_pin(out_, "~T", net->pin(2));
- break;
-
- case NetLogic::BUFIF1:
- assert(net->pin_count() == 3);
- draw_pin(out_, "I", net->pin(1));
- draw_pin(out_, "T", net->pin(2));
- break;
-
- default:
- if (net->pin_count() == 2) {
- draw_pin(out_, "I", net->pin(1));
- } else for (unsigned idx = 1; idx < net->pin_count(); idx += 1) {
- string name = "I";
- assert(net->pin_count() <= 11);
- name += (char)('0'+idx-1);
- draw_pin(out_, name, net->pin(idx));
- }
- break;
- }
-
- out_ << "END" << endl;
-}
-
-bool target_xnf::bufz(const NetBUFZ*net)
-{
- static int warned_once=0;
- if (!warned_once) {
- cerr << "0:0: internal warning: BUFZ objects found "
- << "in XNF netlist." << endl;
- cerr << "0:0: : I'll make BUFs for them."
- << endl;
- warned_once=1;
- }
- out_ << "SYM, " << mangle(net->name()) << ", BUF, LIBVER=2.0.0" << endl;
- assert(net->pin_count() == 2);
- draw_pin(out_, "O", net->pin(0));
- draw_pin(out_, "I", net->pin(1));
- out_ << "END" << endl;
-
- return true;
-}
-
-void target_xnf::udp(const NetUDP*net)
-{
- string lca = net->attribute(perm_string::literal("XNF-LCA")).as_string();
-
- // I only know how to draw a UDP if it has the XNF-LCA
- // attribute attached to it.
- if (lca == "") {
- cerr << "I don't understand this UDP." << endl;
- return;
- }
-
- draw_sym_with_lcaname(out_, lca, net);
-}
-
-static target_xnf target_xnf_obj;
-
-extern const struct target tgt_xnf = { "xnf", &target_xnf_obj };
-
-/*
- * $Log: t-xnf.cc,v $
- * Revision 1.52 2004/02/20 18:53:36 steve
- * Addtrbute keys are perm_strings.
- *
- * Revision 1.51 2004/02/18 17:11:58 steve
- * Use perm_strings for named langiage items.
- *
- * Revision 1.50 2003/11/10 20:59:04 steve
- * Design::get_flag returns const char* instead of string.
- *
- * Revision 1.49 2003/07/05 20:42:08 steve
- * Fix some enumeration warnings.
- *
- * Revision 1.48 2003/06/24 01:38:03 steve
- * Various warnings fixed.
- *
- * Revision 1.47 2003/01/30 16:23:08 steve
- * Spelling fixes.
- *
- * Revision 1.46 2003/01/14 21:16:18 steve
- * Move strstream to ostringstream for compatibility.
- *
- * Revision 1.45 2002/08/12 01:35:01 steve
- * conditional ident string using autoconfig.
- *
- * Revision 1.44 2002/05/23 03:08:52 steve
- * Add language support for Verilog-2001 attribute
- * syntax. Hook this support into existing $attribute
- * handling, and add number and void value types.
- *
- * Add to the ivl_target API new functions for access
- * of complex attributes attached to gates.
- *
- * Revision 1.43 2001/07/25 03:10:50 steve
- * Create a config.h.in file to hold all the config
- * junk, and support gcc 3.0. (Stephan Boettcher)
- *
- * Revision 1.42 2001/06/30 20:11:15 steve
- * typo in CYMODE=EXAMINE-CI string.
- *
- * Revision 1.41 2001/03/27 03:31:06 steve
- * Support error code from target_t::end_design method.
- *
- * Revision 1.40 2001/02/10 03:22:49 steve
- * Report errors when XNF code has constant X values. (PR#128)
- *
- * Revision 1.39 2000/11/29 23:15:54 steve
- * More informative BUFZ warning.
- *
- * Revision 1.38 2000/11/29 02:54:49 steve
- * Add XNF support for NE comparators.
- *
- * Revision 1.37 2000/11/29 01:34:17 steve
- * Typo writing I pins to AND gates in compare.
- *
- * Revision 1.36 2000/11/22 21:18:20 steve
- * Connect the CE if it is linked at all.
- *
- * Revision 1.35 2000/08/14 04:39:57 steve
- * add th t-dll functions for net_const, net_bufz and processes.
- *
- * Revision 1.34 2000/08/09 03:43:45 steve
- * Move all file manipulation out of target class.
- *
- * Revision 1.33 2000/08/08 01:50:42 steve
- * target methods need not take a file stream.
- *
- * Revision 1.32 2000/07/14 06:12:58 steve
- * Move inital value handling from NetNet to Nexus
- * objects. This allows better propogation of inital
- * values.
- *
- * Clean up constant propagation a bit to account
- * for regs that are not really values.
- *
- * Revision 1.31 2000/06/28 18:38:54 steve
- * Use nexus type to get nexus name.
- *
- * Revision 1.30 2000/06/25 19:59:42 steve
- * Redesign Links to include the Nexus class that
- * carries properties of the connected set of links.
- *
- * Revision 1.29 2000/05/14 17:55:04 steve
- * Support initialization of FF Q value.
- *
- * Revision 1.28 2000/05/08 05:29:43 steve
- * no need for nobufz functor.
- *
- * Revision 1.27 2000/05/07 04:37:56 steve
- * Carry strength values from Verilog source to the
- * pform and netlist for gates.
- *
- * Change vvm constants to use the driver_t to drive
- * a constant value. This works better if there are
- * multiple drivers on a signal.
- *
- * Revision 1.26 2000/04/23 23:03:13 steve
- * automatically generate macro interface code.
- *
- * Revision 1.25 2000/04/23 21:15:07 steve
- * Emit code for the bufif devices.
- *
- * Revision 1.24 2000/04/20 02:34:47 steve
- * Generate code for identity compare. Use gates.
- *
- * Revision 1.23 2000/02/23 02:56:55 steve
- * Macintosh compilers do not support ident.
- *
- * Revision 1.22 1999/12/17 03:38:46 steve
- * NetConst can now hold wide constants.
- *
- * Revision 1.21 1999/12/16 18:54:32 steve
- * Capture the carry out of carry-chain addition.
- *
- * Revision 1.20 1999/12/16 02:42:15 steve
- * Simulate carry output on adders.
- *
- * Revision 1.19 1999/12/05 19:30:43 steve
- * Generate XNF RAMS from synthesized memories.
- *
- * Revision 1.18 1999/11/19 03:02:25 steve
- * Detect flip-flops connected to opads and turn
- * them into OUTFF devices. Inprove support for
- * the XNF-LCA attribute in the process.
- *
- * Revision 1.17 1999/11/17 18:52:09 steve
- * Add algorithm for choosing nexus name from attached signals.
- *
- * Revision 1.16 1999/11/17 01:31:28 steve
- * Clean up warnings that add_sub got from Alliance
- *
- * Revision 1.15 1999/11/06 04:51:42 steve
- * Support writing some XNF things into an NCF file.
- *
- * Revision 1.14 1999/11/05 18:43:12 steve
- * fix syntax of EQN record.
- *
- * Revision 1.13 1999/11/05 07:10:45 steve
- * Include the obvious XOR gates in the adders.
- *
- * Revision 1.12 1999/11/05 04:40:40 steve
- * Patch to synthesize LPM_ADD_SUB from expressions,
- * Thanks to Larry Doolittle. Also handle constants
- * in expressions.
- *
- * Synthesize adders in XNF, based on a patch from
- * Larry. Accept synthesis of constants from Larry
- * as is.
- *
- * Revision 1.11 1999/11/04 03:53:26 steve
- * Patch to synthesize unary ~ and the ternary operator.
- * Thanks to Larry Doolittle <LRDoolittle@lbl.gov>.
- *
- * Add the LPM_MUX device, and integrate it with the
- * ternary synthesis from Larry. Replace the lpm_mux
- * generator in t-xnf.cc to use XNF EQU devices to
- * put muxs into function units.
- *
- * Rewrite elaborate_net for the PETernary class to
- * also use the LPM_MUX device.
- *
- * Revision 1.10 1999/11/02 04:55:34 steve
- * Add the synthesize method to NetExpr to handle
- * synthesis of expressions, and use that method
- * to improve r-value handling of LPM_FF synthesis.
- *
- * Modify the XNF target to handle LPM_FF objects.
- *
- * Revision 1.9 1999/08/25 22:22:08 steve
- * handle bufz in XNF backend.
- *
- * Revision 1.8 1999/08/18 04:00:02 steve
- * Fixup spelling and some error messages. <LRDoolittle@lbl.gov>
- *
- * Revision 1.7 1999/07/17 03:39:11 steve
- * simplified process scan for targets.
- *
- * Revision 1.6 1998/12/09 02:43:19 steve
- * Fix 2pin logic gates.
- *
- * Revision 1.5 1998/12/07 04:53:17 steve
- * Generate OBUF or IBUF attributes (and the gates
- * to garry them) where a wire is a pad. This involved
- * figuring out enough of the netlist to know when such
- * was needed, and to generate new gates and signales
- * to handle what's missing.
- *
- * Revision 1.4 1998/12/02 04:37:13 steve
- * Add the nobufz function to eliminate bufz objects,
- * Object links are marked with direction,
- * constant propagation is more careful will wide links,
- * Signal folding is aware of attributes, and
- * the XNF target can dump UDP objects based on LCA
- * attributes.
- *
- * Revision 1.3 1998/11/23 00:20:24 steve
- * NetAssign handles lvalues as pin links
- * instead of a signal pointer,
- * Wire attributes added,
- * Ability to parse UDP descriptions added,
- * XNF generates EXT records for signals with
- * the PAD attribute.
- *
- * Revision 1.2 1998/11/18 04:25:22 steve
- * Add -f flags for generic flag key/values.
- *
- * Revision 1.1 1998/11/16 05:03:53 steve
- * Add the sigfold function that unlinks excess
- * signal nodes, and add the XNF target.
- *
- */
-
View
54 targets.cc
@@ -16,68 +16,14 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
-#ifdef HAVE_CVS_IDENT
-#ident "$Id: targets.cc,v 1.12 2004/12/11 02:31:28 steve Exp $"
-#endif
# include "config.h"
# include "target.h"
extern const struct target tgt_dll;
-#ifdef WITH_T_XNF
-extern const struct target tgt_xnf;
-#endif
const struct target *target_table[] = {
&tgt_dll,
-#ifdef WITH_T_XNF
- &tgt_xnf,
-#endif
0
};
-
-/*
- * $Log: targets.cc,v $
- * Revision 1.12 2004/12/11 02:31:28 steve
- * Rework of internals to carry vectors through nexus instead
- * of single bits. Make the ivl, tgt-vvp and vvp initial changes
- * down this path.
- *
- * Revision 1.11 2002/08/12 01:35:01 steve
- * conditional ident string using autoconfig.
- *
- * Revision 1.10 2002/08/11 23:39:33 steve
- * Remove VVM option.
- *
- * Revision 1.9 2002/02/16 03:18:54 steve
- * Make vvm optional, normally off.
- *
- * Revision 1.8 2001/07/25 03:10:50 steve
- * Create a config.h.in file to hold all the config
- * junk, and support gcc 3.0. (Stephan Boettcher)
- *
- * Revision 1.7 2000/12/02 04:50:32 steve
- * Make the null target into a loadable target.
- *
- * Revision 1.6 2000/08/12 16:34:37 steve
- * Start stub for loadable targets.
- *
- * Revision 1.5 2000/02/23 02:56:56 steve
- * Macintosh compilers do not support ident.
- *
- * Revision 1.4 1999/05/01 02:57:53 steve
- * Handle much more complex event expressions.
- *
- * Revision 1.3 1999/01/24 01:35:36 steve
- * Support null target for generating no output.
- *
- * Revision 1.2 1998/11/16 05:03:53 steve
- * Add the sigfold function that unlinks excess
- * signal nodes, and add the XNF target.
- *
- * Revision 1.1 1998/11/03 23:29:07 steve
- * Introduce verilog to CVS.
- *
- */
-
View
6 xnf-s.conf
@@ -1,6 +0,0 @@
-functor:synth
-functor:syn-rules
-functor:xnfio
-functor:cprop
-functor:nodangle
--t:xnf
View
6 xnf.conf
@@ -1,6 +0,0 @@
-functor:synth
-functor:syn-rules
-functor:xnfio
-functor:cprop
-functor:nodangle
--t:xnf
View
298 xnf.txt
@@ -1,298 +0,0 @@
-
-WHAT IS XNF
-
-XNF is the Xilinx Netlist Format. This is somewhat specific to the
-Xilinx tool chain, but it is sufficiently ubiquitous that it's still
-worth it. This format can be fed to place and route tools and
-simulators. Since some third party simulators accept XNF, the format
-may be useful even independent of Xilinx parts.
-
-Icarus Verilog supports XNF as specified by the Xilinx Netlist Format
-Specification, Version 6.1.
-
-GENERATE XNF OUTPUT -- THE SHORT STORY
-
-The easiest way to compile for XNF output is with the "verilog"
-command (man verilog) and the -X switch:
-
- % iverilog -fpart=4010e -fncf=prog.ncf -txnf prog.v
-
-This generates from the prog.v Verilog source file the prog.xnf output
-and the prog.ncf netlist constraints file. The Verilog program
-arranges to call the preprocessor and the ivl compiler with all the
-correct switches for generating XNF.
-
-GENERATING XNF MACROS
-
-Icarus Verilog can be used to generate XNF implementations of devices
-that are written in Verilog and used by schematic editors such as
-OrCAD. The trick here is that the code generator automatically notices
-ports to the root module and generates the PIN= attributes needed so
-that external tools can link to the generated XNF.
-
-Icarus Verilog chooses a name for the pin. The name it chooses is the
-port name of the module. If the port is a vector, a pin is generated
-for all the bits of the vector with the bit number appended. For
-example:
-
- module foo(in);
- input [3:0] in;
-
-causes the single bit ports ``in0'' through ``in3'' be
-generated. Internally, the XNF file uses the bussed names instead of
-the pin name.
-
-The implication of this is that there is a chance of name collision
-with the generated XNF macro if the port names are chosen badly. It is
-best to not end a port name with decimal digits, as that can cause
-trouble at link time. Also, XNF is not case sensitive and that should
-be accounted for as well.
-
-XNF PADS IN VERILOG SOURCE
-
-You can assign wires to pads using the Icarus Verilog $attribute
-extension. Attach to a scalar signal (wire or register) the PAD
-attribute with the value that specifies the direction and pin
-number. For example:
-
- wire foo, bar, bid;
- $attribute(foo, "PAD", "i1"); // Input pad on pin 1
- $attribute(bar, "PAD", "o2"); // Output pad on pin 2
- $attribute(bid, "PAD", "b3"); // Bi-directional pad on pin 3
-
-The XNFIO function uses these attributes to locate signals that are
-connected to pads, and generates XNF I/O block devices to connect to
-the pad to do the FPGA pin buffering that is needed. So the Verilog
-programmer need not in general specify the IBUF/OBUF buffers.
-
-If the programmer does connect buffers to pads, the compiler will
-notice them and convert them to I/OBUFs automatically. For example:
-
- buf b1 (sig, foo);
-
-connects to pad foo, so will be converted into an XNF IBUF
-device. Also:
-
- bufif1 bt (bar, value, en);
-
-connects to pad bar so will automatically be converted into an OBUFT
-device. Icarus Verilog understands OBUF, IBUF and OBUFT (with optionally
-inverted enable) devices and will convert Verilog devices from the
-source, or generate missing devices.
-
-In addition, the Verilog programmer may explicitly declare a device as
-an I/OBUF by attaching an attribute to the device, like so:
-
- buf b1 (sig, foo);
- $attribute(b1, "XNF-LCA", "OBUF:O,I");
-
-This latter feature is not entirely recommended as it expects that the
-programmer really knows how the pins of the XNF device are to be
-connected. It also bypasses the efforts of the compiler, so is not
-checked for correctness.
-
-XNF STORAGE ELEMENTS
-
-Storage elements in XNF include flip-flops, latches and CLB
-rams. These devices are generated from the LPM equivalents that the
--Fsynth functor synthesizes from behavioral descriptions.
-
-Flip-flops, or more specifically DFF devices, are generated to
-implement behavioral code like this:
-
- reg Q;
- always @(posedge clk) Q <= <expr>;
-
-The edge can be positive or negative, and the expression can be any
-synthesizable expression. Furthermore, the register "Q" can have
-width, which will cause the appropriate number of flip-flops to be
-created. A clock enable expression can also be added like so:
-
- reg Q;
- always @(posedge clk) if (<ce>) Q <= <expr>;
-
-The <ce> expression can be any synthesizable expression.
-
-With or without the CE, the generated DFF devices are written into the
-XNF output one bit at a time, with the clock input inverted if necessary.
-
-Xilinx parts also support CLB circuitry as synchronous RAMS. These
-devices are created from Verilog memories if the properties are
-right. The behavioral description that the -Fsynth functor matches to
-get a synchronous RAM looks very similar to that for a DFF:
-
- reg [15:0] M;
- always @(posedge clk) if (<we>) M[<addr>] <= <expr>;
-
-Note that in this case the l-value of the assignment is an addressed
-memory. This statement models writes into the memory. Reads from the
-device can be modeled with ordinary structural code, i.e.:
-
- assign foo <= M[<addr>];
-
-For the memory to be synthesizable in the XNF target, the address
-lines for writes and reads must be connected. This corresponds to the
-limitations of the real hardware.
-
-OTHER XNF SPECIAL DEVICES
-
-There are certain special devices in XNF that Verilog does not
-naturally represent, although there are similar more generic Verilog
-devices. The most obvious and useful example is the clock driver,
-otherwise known as the global buffer BUFG. As with pads, Icarus
-Verilog uses the $attribute extension to allow you to specify special
-devices.
-
-The $attribute statement can be applied to devices much the same way
-one applies them to wires. For example, to turn a buffer into a clock
-buffer:
-
- wire iclk, clk;
- buf BUFG (clk, iclk);
- $attribute(iclk, "PAD", "i1");
- $attribute(BUFG, "XNF-LCA", "BUFG:O,I");
-
-The above statements cause the buffer BUFG to be emitted in the XNF
-output as a BUFG device with the first signal called "O" and the
-second called "I". The rest of this example connects the input of the
-BUFG to a signal from the input pin #1 and connects the output to the
-internal wire "clk". Incidentally, this example will cause an IBUF to
-be generated to connect the iclk signal to input pin #1.
-
-SUMMARY OF IVL SUPPORT FOR XNF
-
-Icarus Verilog has a code generator and synthesis functions that
-support generation of XNF netlists. The XNF modules also allow the
-programmer to use $attributes to control certain aspects of code
-generation.
-
-XNF code generation is enabled with the ``-t xnf'' flag on the command
-line. The code generator needs to know the type of part to generate
-code for, so the ``-fpart=<type>'' flag is also needed. For example,
-to generate code for the 4010E the command line might start out as:
-
- ivl -txnf -fpart=4010e -Fsynth -Fnodangle -Fxnfio [...]
-
-Icarus Verilog includes the functions ``synth'' and ``xnfio'' to
-perform transformations and optimizations on the design before code is
-generated. The ``synth'' function matches certain behavioral constructs
-to structural components, and the xnfio function generates pads and
-fills the IOBs.
-
-SUPPORTED FLAGS
-
- -fpart=<part>
- Specify the type of part to target. This string is written
- literally into the PART, record of the XNF, and may also be
- used to control synthesis and placement.
-
- -fncf=<path>
- Cause the code generator to write into <path> the netlist
- constraints needed for controlling placement and timing. This
- switch is required if pin assignments are assigned in the
- Verilog source.
-
-THE SYNTH FUNCTION
-
-This function does synthesis transformations on the entered design,
-making it possible to generate XNF netlist components from certain
-behavioral constructs. This is needed in Verilog for example to model
-some of the synchronous components of the XNF library.
-
-It is a bit much to expect a Verilog compiler in general to generate
-components from arbitrary behavioral descriptions, so the synth
-function works by matching statements that have some documented
-structure, and substituting them for the equivalent XNF component. A
-fully synthesize-able design, then, is one where the behavioral
-statements can all be matched and substituted by the synth function.
-
-THE XNFIO FUNCTION
-
-The "xnfio" function transforms the netlist where the IOBs are
-concerned. The signals with PAD attributes are checked, and
-surrounding circuitry generated to conform to the logic available in
-the IOB.
-
-If the pad is an OPAD, the function will look for an existing buf or
-not gate connected to the PAD signal. If the gate is appropriately
-connected, the buf or not gate will be turned into an OBUF. This pulls
-the buf or inverter into the IOB, freeing a CLB and providing the
-required pin circuitry.
-
-If the pad is an IPAD, the function will look for a buf, and convert
-that to an IBUF. Since Xilinx IOBs cannot invert the output from an
-IBUF, NOT gates cannot be absorbed as in the OPAD case.
-
-
-/*
- * Copyright (c) 1998-1999 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
- */
-
-
- $Log: xnf.txt,v $
- Revision 1.16 2003/07/15 03:49:22 steve
- Spelling fixes.
-
- Revision 1.15 2003/01/30 16:23:08 steve
- Spelling fixes.
-
- Revision 1.14 2000/08/01 21:32:40 steve
- Use the iverilog command in documentation.
-
- Revision 1.13 2000/08/01 02:48:42 steve
- Support <= in synthesis of DFF and ram devices.
-
- Revision 1.12 2000/07/25 22:49:32 steve
- memory is not a data type in verilog.
-
- Revision 1.11 2000/04/23 23:03:13 steve
- automatically generate macro interface code.
-
- Revision 1.10 1999/12/05 19:30:43 steve
- Generate XNF RAMS from synthesized memories.
-
- Revision 1.9 1999/11/18 03:52:20 steve
- Turn NetTmp objects into normal local NetNet objects,
- and add the nodangle functor to clean up the local
- symbols generated by elaboration and other steps.
-
- Revision 1.8 1999/11/06 04:51:42 steve
- Support writing some XNF things into an NCF file.
-
- Revision 1.7 1999/11/03 05:18:18 steve
- XNF synthesis now uses the synth functor.
-
- Revision 1.6 1999/11/02 01:43:55 steve
- Fix iobuf and iobufif handling.
-
- Revision 1.5 1999/10/09 17:52:27 steve
- support XNF OBUFT devices.
-
- Revision 1.4 1999/08/14 22:48:21 steve
- Mention the sigfold function.
-
- Revision 1.3 1999/07/22 02:05:20 steve
- is_constant method for PEConcat.
-
- Revision 1.2 1999/07/18 21:17:51 steve
- Add support for CE input to XNF DFF, and do
- complete cleanup of replaced design nodes.
-
- Revision 1.1 1999/05/01 02:57:11 steve
- XNF target documentation.
-
View
26 xnf2pcf.sh
@@ -1,26 +0,0 @@
-#!/bin/sh
-
-# xnf2pcf
-
-# Converts perfectly good EXT records from an XNF file to
-# a .pcf file for the "par" step of the Xilinx toolchain.
-# Why on earth is this needed? Oh, well, the joys of working
-# with black-box-ware.
-
-# Usage: xnf2pcf <design.xnf >design.pcf
-
-# Refer to the resulting .pcf file in the invocation of "par", syntax:
-# par [options] infile[.ncd] outfile pcf_file[.pcf]
-
-# Tested (successfully!) with XNF from Icarus Verilog, see
-# http://www.geda.seul.org/tools/verilog/index.html
-# and Xilinx back end tools from Foundation 1.5
-
-# Author: Larry Doolittle <LRDoolittle@lbl.gov>
-# Date: August 19, 1999
-
-echo "SCHEMATIC START ;"
-echo "SCHEMATIC END ;"
-echo
-
-awk '/^EXT/{gsub(",",""); printf("COMP \"%s\" LOCATE = SITE \"P%s\" ;\n", $2, $4)}'
View
478 xnfio.cc
@@ -1,478 +0,0 @@
-/*
- * Copyright (c) 1998-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
- */
-#ifdef HAVE_CVS_IDENT
-#ident "$Id: xnfio.cc,v 1.30 2007/03/22 16:08:18 steve Exp $"
-#endif
-
-# include "config.h"
-
-# include <iostream>
-
-# include "functor.h"
-# include "netlist.h"
-# include "netmisc.h"
-
-class xnfio_f : public functor_t {
-
- public:
- void signal(Design*des, NetNet*sig);
- void lpm_compare(Design*des, NetCompare*dev);
-
- private:
- bool compare_sideb_const(Design*des, NetCompare*dev);
-};
-
-static bool is_a_pad(const NetNet*net)
-{
- if (net->attribute(perm_string::literal("PAD")) == verinum())
- return false;
-
- return true;
-}
-
-/*
- * The xnfio function looks for the PAD signals in the design, and
- * generates the needed IOB devices to handle being connected to the
- * actual FPGA PAD. This will add items to the netlist if needed.
- *
- * FIXME: If there is a DFF connected to the pad, try to convert it
- * to an IO DFF instead. This would save a CLB, and it is
- * really lame to not do the obvious optimization.
- */
-
-static NetLogic* make_obuf(Design*des, NetNet*net)
-{
- NetScope* scope = net->scope();
- assert(scope);
-
- assert(net->pin_count() == 1);
-
- /* FIXME: If there is nothing internally driving this PAD, I
- can connect the PAD to a pullup and disconnect it from the
- rest of the circuit. This would save routing resources. */
- if (count_outputs(net->pin(0)) <= 0) {
- cerr << net->get_line() << ":warning: No outputs to OPAD: "
- << net->name() << endl;
- return 0;
- }
-
- assert(count_outputs(net->pin(0)) > 0);
-
- /* Look for an existing OBUF connected to this signal. If it
- is there, then no need to add one. */
- Nexus*nex = net->pin(0).nexus();
- for (Link*idx = nex->first_nlink()
- ; idx ; idx = idx->next_nlink()) {
- NetLogic*tmp;
- if ((tmp = dynamic_cast<NetLogic*>(idx->get_obj())) == 0)
- continue;
-
- // Try to use an existing BUF as an OBUF. This moves the
- // BUF into the IOB.
- if ((tmp->type() == NetLogic::BUF)
- && (count_inputs(tmp->pin(0)) == 0)
- && (count_outputs(tmp->pin(0)) == 1)
- && (idx->get_pin() == 0) ) {
- tmp->attribute(perm_string::literal("XNF-LCA"),
- verinum("OBUF:O,I"));
- return tmp;
- }
-
- // Try to use an existing INV as an OBUF. Certain
- // technologies support inverting the input of an OBUF,
- // which looks just like an inverter. This uses the
- // available resources of an IOB to optimize away an
- // otherwise expensive inverter.
- if ((tmp->type() == NetLogic::NOT)
- && (count_inputs(tmp->pin(0)) == 0)
- && (count_outputs(tmp->pin(0)) == 1)
- && (idx->get_pin() == 0) ) {
- tmp->attribute(perm_string::literal("XNF-LCA"),
- verinum("OBUF:O,~I"));
- return tmp;
- }
-
- // Try to use an existing bufif1 as an OBUFT. Of course
- // this will only work if the output of the bufif1 is
- // connected only to the pad. Handle bufif0 the same
- // way, but the T input is inverted.
- if ((tmp->type() == NetLogic::BUFIF1)
- && (count_inputs(tmp->pin(0)) == 0)
- && (count_outputs(tmp->pin(0)) == 1)
- && (idx->get_pin() == 0) ) {
- tmp->attribute(perm_string::literal("XNF-LCA"),
- verinum("OBUFT:O,I,~T"));
- return tmp;
- }
-
- if ((tmp->type() == NetLogic::BUFIF0)
- && (count_inputs(tmp->pin(0)) == 0)
- && (count_outputs(tmp->pin(0)) == 1)
- && (idx->get_pin() == 0) ) {
- tmp->attribute(perm_string::literal("XNF-LCA"),
- verinum("OBUFT:O,I,T"));
- return tmp;
- }
- }
-
- // Can't seem to find a way to rearrange the existing netlist,
- // so I am stuck creating a new buffer, the OBUF.
- NetLogic*buf = new NetLogic(scope, scope->local_symbol(),
- 2, NetLogic::BUF);
- des->add_node(buf);
-
- buf->attribute(perm_string::literal("XNF-LCA"), verinum("OBUF:O,I"));
-
- // Put the buffer between this signal and the rest of the
- // netlist.
- connect(net->pin(0), buf->pin(1));
- net->pin(0).unlink();
- connect(net->pin(0), buf->pin(0));
-
- // It is possible, in putting an OBUF between net and the rest
- // of the netlist, to create a ring without a signal. Detect
- // this case and create a new signal.
- if (count_signals(buf->pin(1)) == 0) {
- NetNet*tmp = new NetNet(scope, scope->local_symbol(),
- NetNet::WIRE);
- tmp->local_flag(true);
- connect(buf->pin(1), tmp->pin(0));
- }
-
- return buf;
-}
-
-static void absorb_OFF(Design*des, NetLogic*buf)
-{
- /* If the nexus connects is not a simple point-to-point link,
- then I can't drag it into the IOB. Give up. */
- if (count_outputs(buf->pin(1)) != 1)
- return;
- if (count_inputs(buf->pin(1)) != 1)
- return;
- /* For now, only support OUTFF. */
- if (buf->type() != NetLogic::BUF)
- return;
-
- Link*drv = find_next_output(&buf->pin(1));
- assert(drv);
-
- /* Make sure the device is a FF with width 1. */
- NetFF*ff = dynamic_cast<NetFF*>(drv->get_obj());
- if (ff == 0)
- return;
- if (ff->width() != 1)
- return;
- if (ff->attribute(perm_string::literal("LPM_FFType")) != verinum("DFF"))
- return;
-
- /* Connect the flip-flop output to the buffer output and
- delete the buffer. The XNF OUTFF can buffer the pin. */
- connect(ff->pin_Q(0), buf->pin(0));
- delete buf;
-
- /* Finally, build up an XNF-LCA value that defines this
- devices as an OUTFF and gives each pin an XNF name. */
- char**names = new char*[ff->pin_count()];
- for (unsigned idx = 0 ; idx < ff->pin_count() ; idx += 1)
- names[idx] = "";
-
- if (ff->attribute(perm_string::literal("Clock:LPM_Polarity")) == verinum("INVERT"))
- names[ff->pin_Clock().get_pin()] = "~C";
- else
- names[ff->pin_Clock().get_pin()] = "C";
-
- names[ff->pin_Data(0).get_pin()] = "D";
- names[ff->pin_Q(0).get_pin()] = "Q";
-
- string lname = string("OUTFF:") + names[0];
- for (unsigned idx = 1 ; idx < ff->pin_count() ; idx += 1)
- lname = lname + "," + names[idx];
- delete[]names;
-
- ff->attribute(perm_string::literal("XNF-LCA"), lname);
-}
-
-static void make_ibuf(Design*des, NetNet*net)
-{
- NetScope*scope = net->scope();
- assert(scope);
-
- assert(net->pin_count() == 1);
- // XXXX For now, require at least one input.
- assert(count_inputs(net->pin(0)) > 0);
-
- /* Look for an existing BUF connected to this signal and
- suitably connected that I can use it as an IBUF. */
-
- Nexus*nex = net->pin(0).nexus();
- for (Link*idx = nex->first_nlink()
- ; idx ; idx = idx->next_nlink()) {
- NetLogic*tmp;
- if ((tmp = dynamic_cast<NetLogic*>(idx->get_obj())) == 0)
- continue;
-
- if (tmp->attribute(perm_string::literal("XNF-LCA")) != verinum())
- continue;
-
- // Found a BUF, it is only usable if the only input is
- // the signal and there are no other inputs.
- if ((tmp->type() == NetLogic::BUF) &&
- (count_inputs(tmp->pin(1)) == 1) &&
- (count_outputs(tmp->pin(1)) == 0)) {
- tmp->attribute(perm_string::literal("XNF-LCA"), verinum("IBUF:O,I"));
- return;
- }
-
- }
-
- // I give up, create an IBUF.
- NetLogic*buf = new NetLogic(scope, scope->local_symbol(),
- 2, NetLogic::BUF);
- des->add_node(buf);
-
- buf->attribute(perm_string::literal("XNF-LCA"), verinum("IBUF:O,I"));
-
- // Put the buffer between this signal and the rest of the
- // netlist.
- connect(net->pin(0), buf->pin(0));
- net->pin(0).unlink();
- connect(net->pin(0), buf->pin(1));
-
- // It is possible, in putting an OBUF between net and the rest
- // of the netlist, to create a ring without a signal. Detect
- // this case and create a new signal.
- if (count_signals(buf->pin(0)) == 0) {
- NetNet*tmp = new NetNet(scope,
- scope->local_symbol(),
- NetNet::WIRE);
- connect(buf->pin(0), tmp->pin(0));
- }
-}
-
-void xnfio_f::signal(Design*des, NetNet*net)
-{
- if (! is_a_pad(net))
- return;
-
- assert(net->pin_count() == 1);
- string pattr = net->attribute(perm_string::literal("PAD")).as_string();
-
- switch (pattr[0]) {
- case 'i':
- case 'I':
- make_ibuf(des, net);
- break;
- case 'o':
- case 'O': {
- NetLogic*buf = make_obuf(des, net);
- if (buf == 0) break;
- absorb_OFF(des, buf);
- break;
- }
-
- // FIXME: Only IPAD and OPAD supported. Need to
- // add support for IOPAD.
- default:
- assert(0);
- break;
- }
-}
-
-/*
- * Attempt some XNF specific optimizations on comparators.
- */
-void xnfio_f::lpm_compare(Design*des, NetCompare*dev)
-{
- if (compare_sideb_const(des, dev))
- return;
-
- return;
-}
-
-bool xnfio_f::compare_sideb_const(Design*des, NetCompare*dev)
-{
- /* Even if side B is all constant, if there are more than 4
- signals on side A we will not be able to fit the operation
- into a function unit, so we might as well accept a
- comparator. Give up. */
- if (dev->width() > 4)
- return false;
-
- NetScope*scope = dev->scope();
-
- verinum side (verinum::V0, dev->width());
-
- /* Is the B side all constant? */
- for (unsigned idx = 0 ; idx < dev->width() ; idx += 1) {
-
- if (! dev->pin_DataB(idx).nexus()->drivers_constant())
- return false;
-
- side.set(idx, dev->pin_DataB(idx).nexus()->driven_value());
- }
-
- /* Handle the special case of comparing A to 0. Use an N-input
- NOR gate to return 0 if any of the bits is not 0. */
- if ((side.as_ulong() == 0) && (count_inputs(dev->pin_AEB()) > 0)) {
- NetLogic*sub = new NetLogic(scope, dev->name(), dev->width()+1,
- NetLogic::NOR);
- connect(sub->pin(0), dev->pin_AEB());
- for (unsigned idx = 0 ; idx < dev->width() ; idx += 1)
- connect(sub->pin(idx+1), dev->pin_DataA(idx));
- delete dev;
- des->add_node(sub);
- return true;
- }
-
- /* Handle the special case of comparing A to 0. Use an N-input
- NOR gate to return 0 if any of the bits is not 0. */
- if ((side.as_ulong() == 0) && (count_inputs(dev->pin_ANEB()) > 0)) {
- NetLogic*sub = new NetLogic(scope, dev->name(), dev->width()+1,
- NetLogic::OR);
- connect(sub->pin(0), dev->pin_ANEB());
- for (unsigned idx = 0 ; idx < dev->width() ; idx += 1)
- connect(sub->pin(idx+1), dev->pin_DataA(idx));
- delete dev;
- des->add_node(sub);
- return true;
- }
-
- return false;
-}
-
-void xnfio(Design*des)
-{
- xnfio_f xnfio_obj;
- des->functor(&xnfio_obj);
-}
-
-/*
- * $Log: xnfio.cc,v $
- * Revision 1.30 2007/03/22 16:08:18 steve
- * Spelling fixes from Larry
- *
- * Revision 1.29 2004/02/20 18:53:36 steve
- * Addtrbute keys are perm_strings.
- *
- * Revision 1.28 2004/02/18 17:11:58 steve
- * Use perm_strings for named langiage items.
- *
- * Revision 1.27 2003/06/24 01:38:03 steve
- * Various warnings fixed.
- *
- * Revision 1.26 2003/03/06 00:28:42 steve
- * All NetObj objects have lex_string base names.
- *
- * Revision 1.25 2003/01/30 16:23:08 steve
- * Spelling fixes.
- *
- * Revision 1.24 2003/01/14 21:16:18 steve
- * Move strstream to ostringstream for compatibility.
- *
- * Revision 1.23 2002/08/12 01:35:01 steve
- * conditional ident string using autoconfig.
- *
- * Revision 1.22 2002/06/25 01:33:22 steve
- * Cache calculated driven value.
- *
- * Revision 1.21 2002/06/24 01:49:39 steve
- * Make link_drive_constant cache its results in
- * the Nexus, to improve cprop performance.
- *
- * Revision 1.20 2002/05/23 03:08:52 steve
- * Add language support for Verilog-2001 attribute
- * syntax. Hook this support into existing $attribute
- * handling, and add number and void value types.
- *
- * Add to the ivl_target API new functions for access
- * of complex attributes attached to gates.
- *
- * Revision 1.19 2001/10/20 05:21:51 steve
- * Scope/module names are char* instead of string.
- *
- * Revision 1.18 2001/07/25 03:10:50 steve
- * Create a config.h.in file to hold all the config
- * junk, and support gcc 3.0. (Stephan Boettcher)
- *
- * Revision 1.17 2000/11/20 00:58:40 steve
- * Add support for supply nets (PR#17)
- *
- * Revision 1.16 2000/10/07 19:45:43 steve
- * Put logic devices into scopes.
- *
- * Revision 1.15 2000/06/25 19:59:42 steve
- * Redesign Links to include the Nexus class that
- * carries properties of the connected set of links.
- *
- * Revision 1.14 2000/05/07 04:37:56 steve
- * Carry strength values from Verilog source to the
- * pform and netlist for gates.
- *
- * Change vvm constants to use the driver_t to drive
- * a constant value. This works better if there are
- * multiple drivers on a signal.
- *
- * Revision 1.13 2000/05/02 00:58:12 steve
- * Move signal tables to the NetScope class.
- *
- * Revision 1.12 2000/04/20 00:28:03 steve
- * Catch some simple identity compareoptimizations.
- *
- * Revision 1.11 2000/02/23 02:56:56 steve
- * Macintosh compilers do not support ident.
- *
- * Revision 1.10 1999/12/11 05:45:41 steve
- * Fix support for attaching attributes to primitive gates.
- *
- * Revision 1.9 1999/11/27 19:07:58 steve
- * Support the creation of scopes.
- *
- * Revision 1.8 1999/11/19 05:02:15 steve
- * Handle inverted clock into OUTFF.
- *
- * Revision 1.7 1999/11/19 03:02:25 steve
- * Detect flip-flops connected to opads and turn
- * them into OUTFF devices. Inprove support for
- * the XNF-LCA attribute in the process.
- *
- * Revision 1.6 1999/11/18 02:58:37 steve
- * Handle (with a warning) unconnected opads.
- *
- * Revision 1.5 1999/11/02 04:55:01 steve
- * repair the sense of T from bufif01
- *
- * Revision 1.4 1999/11/02 01:43:55 steve
- * Fix iobuf and iobufif handling.
- *
- * Revision 1.3 1999/10/09 17:52:27 steve
- * support XNF OBUFT devices.
- *
- * Revision 1.2 1999/07/17 22:01:14 steve
- * Add the functor interface for functor transforms.
- *
- * Revision 1.1 1998/12/07 04:53:17 steve
- * Generate OBUF or IBUF attributes (and the gates
- * to garry them) where a wire is a pad. This involved
- * figuring out enough of the netlist to know when such
- * was needed, and to generate new gates and signales
- * to handle what's missing.
- *
- */
-
Please sign in to comment.
Something went wrong with that request. Please try again.