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.
This commit is contained in:
steve 1998-12-02 04:37:13 +00:00
parent e097c999d5
commit ada45acb0c
10 changed files with 417 additions and 87 deletions

View File

@ -7,10 +7,11 @@ CXXFLAGS = -O -g -Wall -Wno-uninitialized
#TT = t-debug.o t-vvm.o
TT = t-verilog.o t-vvm.o t-xnf.o
FF = nobufz.o sigfold.o stupid.o
O = main.o cprop.o design_dump.o elaborate.o emit.o eval.o lexor.o mangle.o \
netlist.o parse.o parse_misc.o pform.o pform_dump.o sigfold.o stupid.o \
verinum.o target.o targets.o Module.o PExpr.o Statement.o $(TT)
netlist.o parse.o parse_misc.o pform.o pform_dump.o verinum.o target.o \
targets.o Module.o PExpr.o Statement.o $(FF) $(TT)
vl: $O
$(CXX) $(CXXFLAGS) -o vl $O

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: cprop.cc,v 1.1 1998/11/13 06:23:17 steve Exp $"
#ident "$Id: cprop.cc,v 1.2 1998/12/02 04:37:13 steve Exp $"
#endif
# include "netlist.h"
@ -149,15 +149,17 @@ static void look_for_core_logic(Design*des, NetConst*obj)
*/
static void dangling_const(Design*des, NetConst*obj)
{
// If there are any links that take input, abort this
// operation.
if (count_inputs(obj->pin(0)) > 0)
return;
// If there are no other drivers, delete all the signals that
// are also dangling.
if (count_outputs(obj->pin(0)) == 1) {
NetObj*cur;
unsigned pin;
for (obj->pin(0).next_link(cur, pin)
; cur != obj
; cur->pin(pin).next_link(cur, pin)) {
if (! dynamic_cast<NetNet*>(cur))
return;
}
obj->pin(0).next_link(cur, pin);
while (cur != obj) {
cerr << "cprop: delete dangling signal " << cur->name() <<
@ -165,6 +167,9 @@ static void dangling_const(Design*des, NetConst*obj)
delete cur;
obj->pin(0).next_link(cur, pin);
}
}
// Done. Delete me.
delete obj;
}
@ -182,6 +187,14 @@ void cprop(Design*des)
/*
* $Log: cprop.cc,v $
* Revision 1.2 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.1 1998/11/13 06:23:17 steve
* Introduce netlist optimizations with the
* cprop function to do constant propogation.

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: design_dump.cc,v 1.5 1998/12/01 00:42:13 steve Exp $"
#ident "$Id: design_dump.cc,v 1.6 1998/12/02 04:37:13 steve Exp $"
#endif
/*
@ -75,7 +75,19 @@ void NetNode::dump_node(ostream&o, unsigned ind) const
void NetObj::dump_node_pins(ostream&o, unsigned ind) const
{
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
o << setw(ind) << "" << idx << ":";
o << setw(ind) << "" << idx;
switch (pin(idx).get_dir()) {
case Link::PASSIVE:
o << " p";
break;
case Link::INPUT:
o << " I";
break;
case Link::OUTPUT:
o << " O";
break;
}
o << ":";
unsigned cpin;
const NetObj*cur;
@ -392,6 +404,14 @@ void Design::dump(ostream&o) const
/*
* $Log: design_dump.cc,v $
* Revision 1.6 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.5 1998/12/01 00:42:13 steve
* Elaborate UDP devices,
* Support UDP type attributes, and

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: elaborate.cc,v 1.7 1998/12/01 00:42:14 steve Exp $"
#ident "$Id: elaborate.cc,v 1.8 1998/12/02 04:37:13 steve Exp $"
#endif
/*
@ -260,6 +260,9 @@ void PGModule::elaborate_udp_(Design*des, PUdp*udp, const string&path) const
net->set_attributes(udp->attributes);
for (unsigned idx = 0 ; idx < net->pin_count() ; idx += 1) {
if (pin(idx) == 0)
continue;
NetNet*sig = pin(idx)->elaborate_net(des, path);
if (sig == 0) {
cerr << "Expression too complicated for elaboration:"
@ -729,6 +732,14 @@ Design* elaborate(const map<string,Module*>&modules,
/*
* $Log: elaborate.cc,v $
* Revision 1.8 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.7 1998/12/01 00:42:14 steve
* Elaborate UDP devices,
* Support UDP type attributes, and

12
main.cc
View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: main.cc,v 1.7 1998/12/01 00:42:14 steve Exp $"
#ident "$Id: main.cc,v 1.8 1998/12/02 04:37:13 steve Exp $"
#endif
# include <stdio.h>
@ -63,6 +63,7 @@ extern void emit(ostream&o, const Design*, const char*);
extern void cprop(Design*des);
extern void sigfold(Design*des);
extern void stupid(Design*des);
extern void nobufz(Design*des);
typedef void (*net_func)(Design*);
static struct net_func_map {
@ -70,6 +71,7 @@ static struct net_func_map {
void (*func)(Design*);
} func_table[] = {
{ "cprop", &cprop },
{ "nobufz", &nobufz },
{ "sigfold", &sigfold },
{ "stupid", &stupid },
{ 0, 0 }
@ -227,6 +229,14 @@ int main(int argc, char*argv[])
/*
* $Log: main.cc,v $
* Revision 1.8 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.7 1998/12/01 00:42:14 steve
* Elaborate UDP devices,
* Support UDP type attributes, and

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: netlist.cc,v 1.9 1998/12/01 00:42:14 steve Exp $"
#ident "$Id: netlist.cc,v 1.10 1998/12/02 04:37:13 steve Exp $"
#endif
# include <cassert>
@ -115,6 +115,36 @@ bool connected(const NetObj&l, const NetObj&r)
return true;
}
unsigned count_inputs(const NetObj::Link&pin)
{
unsigned count = (pin.get_dir() == NetObj::Link::INPUT)? 1 : 0;
const NetObj*cur;
unsigned cpin;
pin.next_link(cur, cpin);
while (cur->pin(cpin) != pin) {
if (cur->pin(cpin).get_dir() == NetObj::Link::INPUT)
count += 1;
cur->pin(cpin).next_link(cur, cpin);
}
return count;
}
unsigned count_outputs(const NetObj::Link&pin)
{
unsigned count = (pin.get_dir() == NetObj::Link::OUTPUT)? 1 : 0;
const NetObj*cur;
unsigned cpin;
pin.next_link(cur, cpin);
while (cur->pin(cpin) != pin) {
if (cur->pin(cpin).get_dir() == NetObj::Link::OUTPUT)
count += 1;
cur->pin(cpin).next_link(cur, cpin);
}
return count;
}
const NetNet* find_link_signal(const NetObj*net, unsigned pin, unsigned&bidx)
{
const NetObj*cur;
@ -163,6 +193,23 @@ string NetObj::attribute(const string&key) const
return (*idx).second;
}
bool NetObj::has_compat_attributes(const NetObj&that) const
{
map<string,string>::const_iterator idx;
for (idx = that.attributes_.begin()
; idx != that.attributes_.end() ; idx ++) {
map<string,string>::const_iterator cur;
cur = attributes_.find((*idx).first);
if (cur == attributes_.end())
return false;
if ((*cur).second != (*idx).second)
return false;
}
return true;
}
NetNode::~NetNode()
{
if (design_)
@ -344,6 +391,22 @@ void NetEUnary::set_width(unsigned w)
expr_width(w);
}
NetLogic::NetLogic(const string&n, unsigned pins, TYPE t)
: NetNode(n, pins), type_(t)
{
pin(0).set_dir(Link::OUTPUT);
for (unsigned idx = 1 ; idx < pins ; idx += 1)
pin(idx).set_dir(Link::INPUT);
}
NetUDP::NetUDP(const string&n, unsigned pins)
: NetNode(n, pins)
{
pin(0).set_dir(Link::OUTPUT);
for (unsigned idx = 1 ; idx < pins ; idx += 1)
pin(idx).set_dir(Link::INPUT);
}
string Design::get_flag(const string&key) const
{
map<string,string>::const_iterator tmp = flags_.find(key);
@ -496,6 +559,14 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*))
/*
* $Log: netlist.cc,v $
* Revision 1.10 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.9 1998/12/01 00:42:14 steve
* Elaborate UDP devices,
* Support UDP type attributes, and

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: netlist.h,v 1.9 1998/12/01 00:42:14 steve Exp $"
#ident "$Id: netlist.h,v 1.10 1998/12/02 04:37:13 steve Exp $"
#endif
/*
@ -49,6 +49,10 @@ struct target;
* The web of nodes that makes up a circuit is held together by the
* Link class. There is a link for each pin. All mutually connected
* pins form a ring of links.
*
* A link can be INPUT, OUTPUT or PASSIVE. An input never drives the
* signal, and PASSIVE never receives the value of the signal. Wires
* are PASSIVE, for example.
*/
class NetObj {
@ -58,9 +62,14 @@ class NetObj {
friend class NetObj;
public:
Link() : next_(this), prev_(this) { }
enum DIR { PASSIVE, INPUT, OUTPUT };
Link() : dir_(PASSIVE), next_(this), prev_(this) { }
~Link() { unlink(); }
// Manipulate the link direction.
void set_dir(DIR d) { dir_ = d; }
DIR get_dir() const { return dir_; }
void cur_link(NetObj*&net, unsigned &pin)
{ net = node_;
pin = pin_;
@ -101,6 +110,7 @@ class NetObj {
// NetNode so that following the links can get me here.
NetObj *node_;
unsigned pin_;
DIR dir_;
private:
Link *next_;
@ -130,6 +140,10 @@ class NetObj {
void set_attributes(const map<string,string>&);
string attribute(const string&key) const;
// Return true if this has all the attributes in that and they
// all have the same values.
bool has_compat_attributes(const NetObj&that) const;
bool test_mark() const { return mark_; }
void set_mark(bool flag=true) { mark_ = flag; }
@ -266,7 +280,10 @@ class NetBUFZ : public NetNode {
public:
explicit NetBUFZ(const string&n)
: NetNode(n, 2) { }
: NetNode(n, 2)
{ pin(0).set_dir(Link::OUTPUT);
pin(1).set_dir(Link::INPUT);
}
virtual void dump_node(ostream&, unsigned ind) const;
virtual void emit_node(ostream&, struct target_t*) const;
@ -276,7 +293,7 @@ class NetConst : public NetNode {
public:
explicit NetConst(const string&n, verinum::V v)
: NetNode(n, 1), value_(v) { }
: NetNode(n, 1), value_(v) { pin(0).set_dir(Link::OUTPUT); }
verinum::V value() const { return value_; }
@ -288,15 +305,15 @@ class NetConst : public NetNode {
};
/*
* This class represents all manner of logic gates.
* This class represents all manner of logic gates. Pin 0 is OUTPUT and
* all the remaining pins are INPUT
*/
class NetLogic : public NetNode {
public:
enum TYPE { AND, NAND, NOR, NOT, OR, XNOR, XOR };
explicit NetLogic(const string&n, unsigned pins, TYPE t)
: NetNode(n, pins), type_(t) { }
explicit NetLogic(const string&n, unsigned pins, TYPE t);
TYPE type() const { return type_; }
@ -315,9 +332,7 @@ class NetLogic : public NetNode {
class NetUDP : public NetNode {
public:
explicit NetUDP(const string&n, unsigned pins)
: NetNode(n, pins) { }
explicit NetUDP(const string&n, unsigned pins);
virtual void emit_node(ostream&, struct target_t*) const;
virtual void dump_node(ostream&, unsigned ind) const;
@ -752,6 +767,7 @@ inline bool operator != (const NetObj::Link&l, const NetObj::Link&r)
connected to other things, connect is transitive. */
extern void connect(NetObj::Link&, NetObj::Link&);
/* Return true if l and r are connected. */
inline bool connected(const NetObj::Link&l, const NetObj::Link&r)
{ return l.is_linked(r); }
@ -760,6 +776,9 @@ inline bool connected(const NetObj::Link&l, const NetObj::Link&r)
checking signal vectors. */
extern bool connected(const NetObj&l, const NetObj&r);
extern unsigned count_inputs(const NetObj::Link&pin);
extern unsigned count_outputs(const NetObj::Link&pin);
/* Find the signal connected to the given node pin. There should
always be exactly one signal. The bidx parameter get filled with
the signal index of the Net, in case it is a vector. */
@ -773,6 +792,14 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
* Revision 1.10 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.9 1998/12/01 00:42:14 steve
* Elaborate UDP devices,
* Support UDP type attributes, and

73
nobufz.cc Normal file
View File

@ -0,0 +1,73 @@
/*
* Copyright (c) 1998 Stephen Williams (steve@picturel.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: nobufz.cc,v 1.1 1998/12/02 04:37:13 steve Exp $"
#endif
/* NOBUFZ Function
* This function transforms the netlist by removing BUFZ nodes that
* have no obvious effect. The assumption here is that the BUFZ node
* transmits information perfectly in one direction, and not at all in
* the other.
*
* A BUFZ will *not* be eliminated if the output link is connected to
* other outputs. The BUFZ protects its input link from the
* double-driving on its output, so the bufz is not meaningless and
* cannot be removed.
*/
# include "netlist.h"
# include <assert.h>
static bool is_a_bufz_node(const NetNode*obj)
{
return dynamic_cast<const NetBUFZ*>(obj);
}
void nobufz(Design*des)
{
des->clear_node_marks();
while (NetNode*obj = des->find_node(&is_a_bufz_node)) {
NetBUFZ*cur = dynamic_cast<NetBUFZ*>(obj);
assert(cur);
/* If there are more output pins on the output size of
the BUFZ, then the BUFZ has a real effect (it
protects its input side) and cannot be eliminated. */
if (count_outputs(cur->pin(0)) == 1) {
connect(cur->pin(0), cur->pin(1));
delete cur;
} else {
cur->set_mark();
}
}
}
/*
* $Log: nobufz.cc,v $
* Revision 1.1 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.
*
*/

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: sigfold.cc,v 1.1 1998/11/16 05:03:53 steve Exp $"
#ident "$Id: sigfold.cc,v 1.2 1998/12/02 04:37:13 steve Exp $"
#endif
# include "netlist.h"
@ -39,6 +39,17 @@
* The result of this should be that signals of enclosing modules will
* be preferred over signals of instantiated modules, and bussed
* signals (vectors) will be preferred over scaler signals.
*
* The presence of attributes modifies the folding process, by placing
* restrictions on what is allowed.
*
* If two signals have an attribute key X, they can be folded
* only if X has the same value for both signals.
*
* If signal A has attribute X and signal B does not, then
* signals can be folded if B can take the attribute.
*
* All the pins in a vector have identical attributes.
*/
static unsigned depth(const string&sym)
@ -63,18 +74,49 @@ static void clear_extra_signals(NetNet*net, unsigned npin)
unsigned pin = npin;
for (net->pin(pin).next_link(cur, pin) ; cur != net ; ) {
// sig is the node I am going to try to subsume.
NetNet*sig = dynamic_cast<NetNet*>(cur);
if ((sig == 0)
|| (depth(sig->name()) < mydepth)
|| (sig->pin_count() > net->pin_count())) {
// Skip the node if it isn't even a signal.
if (sig == 0) {
cur->pin(pin).next_link(cur, pin);
continue;
}
// Skip the node if it has incompatible attributes.
if (! net->has_compat_attributes(*sig)) {
// SPECIAL CASE!
if (sig->has_compat_attributes(*net)) {
net->pin(npin).unlink();
return;
}
cur->pin(pin).next_link(cur, pin);
continue;
}
// Skip the node if it is higher up.
if (depth(sig->name()) < mydepth) {
cur->pin(pin).next_link(cur, pin);
continue;
}
// Skip the node if it is a larger vector.
if (sig->pin_count() > net->pin_count()) {
cur->pin(pin).next_link(cur, pin);
continue;
}
// save the next link, ...
NetObj*nxt;
unsigned pnxt;
cur->pin(pin).next_link(nxt, pnxt);
// disconnect the target signal, ...
sig->pin(pin).unlink();
// And onward.
cur = nxt;
pin = pnxt;
}
@ -110,6 +152,14 @@ void sigfold(Design*des)
/*
* $Log: sigfold.cc,v $
* Revision 1.2 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.1 1998/11/16 05:03:53 steve
* Add the sigfold function that unlinks excess
* signal nodes, and add the XNF target.

148
t-xnf.cc
View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: t-xnf.cc,v 1.3 1998/11/23 00:20:24 steve Exp $"
#ident "$Id: t-xnf.cc,v 1.4 1998/12/02 04:37:13 steve Exp $"
#endif
/* XNF BACKEND
@ -31,7 +31,24 @@
* 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
* receiving tools.
*
* 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 UDP node. The lname
* is the name of the symbol to use (i.e. DFF) and the comma
* seperated list is the names of the pins, in the order they
* appear in the verilog source.
*/
# include "netlist.h"
@ -44,9 +61,12 @@ class target_xnf : public target_t {
void end_design(ostream&os, const Design*);
void signal(ostream&os, const NetNet*);
void logic(ostream&os, const NetLogic*);
void udp(ostream&os, const NetUDP*);
private:
static string mangle(const string&);
static void draw_pin(ostream&os, const string&name, char type,
const NetObj::Link&lnk);
};
/*
@ -69,6 +89,27 @@ string target_xnf::mangle(const string&name)
return result;
}
void target_xnf::draw_pin(ostream&os, const string&name, char type,
const NetObj::Link&lnk)
{
unsigned cpin;
const NetObj*cur;
for (lnk.next_link(cur, cpin)
; cur->pin(cpin) != lnk
; cur->pin(cpin).next_link(cur, cpin)) {
const NetNet*sig = dynamic_cast<const NetNet*>(cur);
if (sig) {
os << " PIN, " << name << ", " << type << ", "
<< mangle(sig->name());
if (sig->pin_count() > 1)
os << "<" << cpin << ">";
os << endl;
}
}
}
void target_xnf::start_design(ostream&os, const Design*des)
{
@ -82,11 +123,13 @@ void target_xnf::end_design(ostream&os, const Design*)
os << "EOF" << endl;
}
void scrape_pad_info(string&str, char&dir, unsigned&num)
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':
@ -109,6 +152,7 @@ void scrape_pad_info(string&str, char&dir, unsigned&num)
break;
}
// Get the number part.
str = str.substr(1);
unsigned val = 0;
while (str.size() && isdigit(str[0])) {
@ -116,13 +160,6 @@ void scrape_pad_info(string&str, char&dir, unsigned&num)
str = str.substr(1);
}
num = val;
while (str.size() && str[0] == ' ')
str = str.substr(1);
if (str.size() && str[0] == ',')
str = str.substr(1);
}
/*
@ -139,24 +176,20 @@ void scrape_pad_info(string&str, char&dir, unsigned&num)
void target_xnf::signal(ostream&os, const NetNet*net)
{
string pad = net->attribute("PAD");
if (pad != "") {
if (pad == "")
return;
if (net->pin_count() > 1) {
cerr << "Signal ``" << net->name() << "'' with PAD=" <<
pad << " is a vector." << endl;
return;
}
if (net->pin_count() == 1) {
char dir;
unsigned num;
scrape_pad_info(pad, dir, num);
os << "EXT, " << mangle(net->name()) << ", " << dir
<< ", " << num << endl;
} else for (unsigned idx = net->pin_count(); idx > 0; idx -= 1) {
char dir;
unsigned num;
scrape_pad_info(pad, dir, num);
os << "EXT, " << mangle(net->name()) << "<" << (idx-1)
<< ">, " << dir << ", " << num << endl;
}
}
}
/*
@ -188,45 +221,66 @@ void target_xnf::logic(ostream&os, const NetLogic*net)
case NetLogic::XOR:
os << "XOR";
break;
default:
cerr << "XNF: Unhandled logic type." << endl;
break;
}
os << ", LIBVER=2.0.0" << endl;
for (unsigned idx = 0 ; idx < net->pin_count() ; idx += 1) {
unsigned cpin;
const NetObj*cur;
for (net->pin(idx).next_link(cur, cpin)
; (cur != net) || (cpin != idx)
; cur->pin(cpin).next_link(cur, cpin)) {
const NetNet*sig = dynamic_cast<const NetNet*>(cur);
if (sig) {
os << " PIN, ";
if (idx == 0) {
os << "O, O, ";
} else {
os << "I";
if (net->pin_count() > 2)
os << idx-1;
os << ", I, ";
}
os << mangle(sig->name());
if (sig->pin_count() > 1)
os << "<" << cpin << ">";
os << endl;
}
}
draw_pin(os, "O", 'O', net->pin(0));
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(os, name, 'I', net->pin(idx));
}
os << "END" << 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;
}
void target_xnf::udp(ostream&os, const NetUDP*net)
{
string lca = net->attribute("XNF-LCA");
if (lca == "") {
cerr << "I don't understand this UDP." << endl;
return;
}
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;
draw_pin(os, scrape_pin_name(lca), 'O', net->pin(0));
for (idx = 1 ; idx < net->pin_count() ; idx += 1) {
draw_pin(os, scrape_pin_name(lca), 'I', net->pin(idx));
}
os << "END" << endl;
}
static target_xnf target_xnf_obj;
extern const struct target tgt_xnf = { "xnf", &target_xnf_obj };
/*
* $Log: t-xnf.cc,v $
* 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,