Add the sigfold function that unlinks excess

signal nodes, and add the XNF target.
This commit is contained in:
steve 1998-11-16 05:03:52 +00:00
parent 3d6d334f80
commit 4661006e4b
7 changed files with 326 additions and 10 deletions

View File

@ -6,11 +6,11 @@ CXXFLAGS = -O -g -Wall -Wno-uninitialized
mv $*.d dep/$*.d
#TT = t-debug.o t-vvm.o
TT = t-verilog.o t-vvm.o
TT = t-verilog.o t-vvm.o t-xnf.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 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 sigfold.o stupid.o \
verinum.o target.o targets.o Module.o PExpr.o Statement.o $(TT)
vl: $O
$(CXX) $(CXXFLAGS) -o vl $O

28
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.3 1998/11/13 06:23:17 steve Exp $"
#ident "$Id: main.cc,v 1.4 1998/11/16 05:03:52 steve Exp $"
#endif
# include <stdio.h>
@ -39,6 +39,7 @@ extern Design* elaborate(const list<Module*>&modules, const string&root);
extern void emit(ostream&o, const Design*, const char*);
extern void cprop(Design*des);
extern void sigfold(Design*des);
extern void stupid(Design*des);
typedef void (*net_func)(Design*);
@ -46,8 +47,9 @@ static struct net_func_map {
const char*name;
void (*func)(Design*);
} func_table[] = {
{ "stupid", &stupid },
{ "cprop", &cprop },
{ "cprop", &cprop },
{ "sigfold", &sigfold },
{ "stupid", &stupid },
{ 0, 0 }
};
@ -64,12 +66,13 @@ net_func name_to_net_func(const string&name)
int main(int argc, char*argv[])
{
bool dump_flag = false;
bool help_flag = false;
const char* out_path = 0;
int opt;
unsigned flag_errors = 0;
queue<net_func> net_func_queue;
while ((opt = getopt(argc, argv, "DF:o:s:t:")) != EOF) switch (opt) {
while ((opt = getopt(argc, argv, "DF:ho:s:t:")) != EOF) switch (opt) {
case 'D':
dump_flag = true;
break;
@ -83,6 +86,9 @@ int main(int argc, char*argv[])
net_func_queue.push(tmp);
break;
}
case 'h':
help_flag = true;
break;
case 'o':
out_path = optarg;
break;
@ -100,6 +106,16 @@ int main(int argc, char*argv[])
if (flag_errors)
return flag_errors;
if (help_flag) {
cout << "Netlist functions:" << endl;
for (unsigned idx = 0 ; func_table[idx].name ; idx += 1)
cout << " " << func_table[idx].name << endl;
cout << "Target types:" << endl;
for (unsigned idx = 0 ; target_table[idx] ; idx += 1)
cout << " " << target_table[idx]->name << endl;
return 0;
}
if (optind == argc) {
cerr << "No input files." << endl;
return 1;
@ -176,6 +192,10 @@ int main(int argc, char*argv[])
/*
* $Log: main.cc,v $
* Revision 1.4 1998/11/16 05:03:52 steve
* Add the sigfold function that unlinks excess
* signal nodes, and add the XNF target.
*
* Revision 1.3 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: netlist.cc,v 1.5 1998/11/13 06:23:17 steve Exp $"
#ident "$Id: netlist.cc,v 1.6 1998/11/16 05:03:53 steve Exp $"
#endif
# include <cassert>
@ -315,6 +315,18 @@ void Design::clear_node_marks()
} while (cur != nodes_);
}
void Design::clear_signal_marks()
{
if (signals_ == 0)
return;
NetNet*cur = signals_;
do {
cur->set_mark(false);
cur = cur->sig_next_;
} while (cur != signals_);
}
NetNode* Design::find_node(bool (*func)(const NetNode*))
{
if (nodes_ == 0)
@ -331,8 +343,28 @@ NetNode* Design::find_node(bool (*func)(const NetNode*))
return 0;
}
NetNet* Design::find_signal(bool (*func)(const NetNet*))
{
if (signals_ == 0)
return 0;
NetNet*cur = signals_->sig_next_;
do {
if ((cur->test_mark() == false) && func(cur))
return cur;
cur = cur->sig_next_;
} while (cur != signals_->sig_next_);
return 0;
}
/*
* $Log: netlist.cc,v $
* Revision 1.6 1998/11/16 05:03:53 steve
* Add the sigfold function that unlinks excess
* signal nodes, and add the XNF target.
*
* Revision 1.5 1998/11/13 06:23:17 steve
* Introduce netlist optimizations with the
* cprop function to do constant propogation.

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.5 1998/11/13 06:23:17 steve Exp $"
#ident "$Id: netlist.h,v 1.6 1998/11/16 05:03:53 steve Exp $"
#endif
/*
@ -675,6 +675,9 @@ class Design {
void clear_node_marks();
NetNode*find_node(bool (*test)(const NetNode*));
void clear_signal_marks();
NetNet*find_signal(bool (*test)(const NetNet*));
private:
// List all the signals in the design.
NetNet*signals_;
@ -710,6 +713,10 @@ inline ostream& operator << (ostream&o, const NetExpr&exp)
/*
* $Log: netlist.h,v $
* Revision 1.6 1998/11/16 05:03:53 steve
* Add the sigfold function that unlinks excess
* signal nodes, and add the XNF target.
*
* Revision 1.5 1998/11/13 06:23:17 steve
* Introduce netlist optimizations with the
* cprop function to do constant propogation.

118
sigfold.cc Normal file
View File

@ -0,0 +1,118 @@
/*
* Copyright (c) 1998 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: sigfold.cc,v 1.1 1998/11/16 05:03:53 steve Exp $"
#endif
# include "netlist.h"
/*
* Some targets require that a list of connections include exactly one
* signal. This processing step deletes excess signals to meet that
* requirement.
*
* If there is a ring that has more then one signal connected
* together, the following heuristic is used to choose which signal to
* keep:
*
* If the name of signal X is deeper in the design hierarchy then
* signal Y, keep signal Y.
*
* Else, if X is a bus that is not as wide as Y, keep signal Y.
*
* 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.
*/
static unsigned depth(const string&sym)
{
unsigned cnt = 0;
for (unsigned idx = 0 ; idx < sym.length() ; idx += 1)
if (sym[idx] == '.')
cnt += 1;
return cnt;
}
static bool is_any_signal(const NetNet*)
{
return true;
}
static void clear_extra_signals(NetNet*net, unsigned npin)
{
const unsigned mydepth = depth(net->name());
NetObj*cur = net;
unsigned pin = npin;
for (net->pin(pin).next_link(cur, pin) ; cur != net ; ) {
NetNet*sig = dynamic_cast<NetNet*>(cur);
if ((sig == 0)
|| (depth(sig->name()) < mydepth)
|| (sig->pin_count() > net->pin_count())) {
cur->pin(pin).next_link(cur, pin);
continue;
}
NetObj*nxt;
unsigned pnxt;
cur->pin(pin).next_link(nxt, pnxt);
sig->pin(pin).unlink();
cur = nxt;
pin = pnxt;
}
}
static void delete_if_unconnected(NetNet*net)
{
for (unsigned idx = 0 ; idx < net->pin_count() ; idx += 1)
if (net->pin(idx).is_linked())
return;
delete net;
}
void sigfold(Design*des)
{
des->clear_signal_marks();
while (NetNet*obj = des->find_signal(&is_any_signal)) {
for (unsigned idx = 0 ; idx < obj->pin_count() ; idx += 1)
clear_extra_signals(obj, idx);
obj->set_mark();
}
// After the disconnect step, I may have signals that are not
// connected to anything. Delete those.
des->clear_signal_marks();
while (NetNet*obj = des->find_signal(&is_any_signal)) {
obj->set_mark();
delete_if_unconnected(obj);
}
}
/*
* $Log: sigfold.cc,v $
* Revision 1.1 1998/11/16 05:03:53 steve
* Add the sigfold function that unlinks excess
* signal nodes, and add the XNF target.
*
*/

132
t-xnf.cc Normal file
View File

@ -0,0 +1,132 @@
/*
* Copyright (c) 1998 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: t-xnf.cc,v 1.1 1998/11/16 05:03:53 steve Exp $"
#endif
# include "netlist.h"
# include "target.h"
class target_xnf : public target_t {
public:
void start_design(ostream&os, const Design*);
void end_design(ostream&os, const Design*);
void logic(ostream&os, const NetLogic*);
private:
static string mangle(const string&);
};
/*
* This function takes a signal name and mangles it into an equivilent
* 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;
}
void target_xnf::start_design(ostream&os, const Design*)
{
os << "LCANET,6" << endl;
os << "PROG,verilog,0.0,\"Steve's Verilog\"" << endl;
os << "PART,4000-10" << endl;
}
void target_xnf::end_design(ostream&os, const Design*)
{
os << "EOF" << endl;
}
void target_xnf::logic(ostream&os, const NetLogic*net)
{
os << "SYM," << net->name() << ", ";
switch (net->type()) {
case NetLogic::AND:
os << "AND";
break;
case NetLogic::NAND:
os << "NAND";
break;
case NetLogic::NOR:
os << "NOR";
break;
case NetLogic::OR:
os << "OR";
break;
case NetLogic::XNOR:
os << "XNOR";
break;
case NetLogic::XOR:
os << "XOR";
break;
}
os << 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" << idx-1 << ",I,";
os << mangle(sig->name());
if (sig->pin_count() > 1)
os << "<" << cpin << ">";
os << ",," << endl;
}
}
}
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.1 1998/11/16 05:03:53 steve
* Add the sigfold function that unlinks excess
* signal nodes, and add the XNF target.
*
*/

View File

@ -17,21 +17,28 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: targets.cc,v 1.1 1998/11/03 23:29:07 steve Exp $"
#ident "$Id: targets.cc,v 1.2 1998/11/16 05:03:53 steve Exp $"
#endif
# include "target.h"
extern const struct target tgt_verilog;
extern const struct target tgt_vvm;
extern const struct target tgt_xnf;
const struct target *target_table[] = {
&tgt_verilog,
&tgt_vvm,
&tgt_xnf,
0
};
/*
* $Log: targets.cc,v $
* 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.
*