Add the sigfold function that unlinks excess
signal nodes, and add the XNF target.
This commit is contained in:
parent
3d6d334f80
commit
4661006e4b
6
Makefile
6
Makefile
|
|
@ -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
28
main.cc
|
|
@ -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.
|
||||
|
|
|
|||
34
netlist.cc
34
netlist.cc
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue