NetConst can now hold wide constants.

This commit is contained in:
steve 1999-12-17 03:38:46 +00:00
parent d355270c2d
commit 65ae92859c
8 changed files with 156 additions and 111 deletions

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.2 1998/12/02 04:37:13 steve Exp $"
#ident "$Id: cprop.cc,v 1.3 1999/12/17 03:38:46 steve Exp $"
#endif
# include "netlist.h"
@ -35,7 +35,7 @@ static bool is_a_const_node(const NetNode*obj)
return dynamic_cast<const NetConst*>(obj);
}
static bool const_into_xnor(Design*des, NetConst*obj,
static bool const_into_xnor(Design*des, verinum::V cval,
NetLogic*log, unsigned pin)
{
assert(pin > 0);
@ -44,7 +44,7 @@ static bool const_into_xnor(Design*des, NetConst*obj,
the device is simply buffering the constant value. */
if (log->pin_count() == 2) {
cerr << "cprop: delete gate " << log->name() <<
" and propogate " << obj->value() << "." << endl;
" and propogate " << cval << "." << endl;
assert(pin == 1);
connect(log->pin(0), log->pin(1));
@ -55,7 +55,7 @@ static bool const_into_xnor(Design*des, NetConst*obj,
/* If this is a constant 0, then replace the gate with one
1-pin smaller. Skip this pin. */
if (obj->value() == verinum::V0) {
if (cval == verinum::V0) {
cerr << "cprop: disconnect pin " << pin << " from gate "
<< log->name() << "." << endl;
@ -78,7 +78,7 @@ static bool const_into_xnor(Design*des, NetConst*obj,
/* If this is a constant 1, then replace the gate with an XOR
that is 1-pin smaller. Removing the constant 1 causes the
sense of the output to change. */
if (obj->value() == verinum::V1) {
if (cval == verinum::V1) {
cerr << "cprop: disconnect pin " << pin << " from gate "
<< log->name() << "." << endl;
@ -101,7 +101,7 @@ static bool const_into_xnor(Design*des, NetConst*obj,
/* If this is a constant X or Z, then the gate is certain to
generate an X. Replace the gate with a constant X. This may
cause other signals all over to become dangling. */
if ((obj->value() == verinum::Vx) || (obj->value() == verinum::Vz)) {
if ((cval == verinum::Vx) || (cval == verinum::Vz)) {
cerr << "cprop: replace gate " << log->name() << " with "
"a constant X." << endl;
@ -115,11 +115,11 @@ static bool const_into_xnor(Design*des, NetConst*obj,
return false;
}
static void look_for_core_logic(Design*des, NetConst*obj)
static void look_for_core_logic(Design*des, NetConst*obj, unsigned cpin)
{
NetObj*cur = obj;
unsigned pin = 0;
for (obj->pin(0).next_link(cur, pin)
for (obj->pin(cpin).next_link(cur, pin)
; cur != obj
; cur->pin(pin).next_link(cur, pin)) {
@ -130,7 +130,7 @@ static void look_for_core_logic(Design*des, NetConst*obj)
bool flag = false;
switch (log->type()) {
case NetLogic::XNOR:
flag = const_into_xnor(des, obj, log, pin);
flag = const_into_xnor(des, obj->value(cpin), log, pin);
break;
default:
break;
@ -151,23 +151,25 @@ 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;
for (unsigned idx = 0 ; idx < obj->pin_count() ; idx += 1)
if (count_inputs(obj->pin(idx)) > 0)
return;
// If there are no other drivers, delete all the signals that
// are also dangling.
if (count_outputs(obj->pin(0)) == 1) {
for (unsigned idx = 0 ; idx < obj->pin_count() ; idx += 1)
if (count_outputs(obj->pin(idx)) == 1) {
NetObj*cur;
unsigned pin;
obj->pin(0).next_link(cur, pin);
while (cur != obj) {
cerr << "cprop: delete dangling signal " << cur->name() <<
"." << endl;
delete cur;
obj->pin(0).next_link(cur, pin);
NetObj*cur;
unsigned pin;
obj->pin(idx).next_link(cur, pin);
while (cur != obj) {
cerr << "cprop: delete dangling signal " <<
cur->name() << "." << endl;
delete cur;
obj->pin(idx).next_link(cur, pin);
}
}
}
// Done. Delete me.
delete obj;
@ -178,7 +180,8 @@ void cprop(Design*des)
des->clear_node_marks();
while (NetNode*obj = des->find_node(&is_a_const_node)) {
NetConst*cur = dynamic_cast<NetConst*>(obj);
look_for_core_logic(des, cur);
for (unsigned idx = 0 ; idx < cur->pin_count() ; idx += 1)
look_for_core_logic(des, cur, idx);
cur->set_mark();
dangling_const(des, cur);
}
@ -187,6 +190,9 @@ void cprop(Design*des)
/*
* $Log: cprop.cc,v $
* Revision 1.3 1999/12/17 03:38:46 steve
* NetConst can now hold wide constants.
*
* Revision 1.2 1998/12/02 04:37:13 steve
* Add the nobufz function to eliminate bufz objects,
* Object links are marked with direction,

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.63 1999/12/12 06:03:14 steve Exp $"
#ident "$Id: design_dump.cc,v 1.64 1999/12/17 03:38:46 steve Exp $"
#endif
/*
@ -189,7 +189,10 @@ void NetCaseCmp::dump_node(ostream&o, unsigned ind) const
void NetConst::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "constant " << value_ << ": " << name() << endl;
o << setw(ind) << "" << "constant ";
for (unsigned idx = pin_count() ; idx > 0 ; idx -= 1)
o << value_[idx-1];
o << ": " << name() << endl;
dump_node_pins(o, ind+4);
}
@ -862,6 +865,9 @@ void Design::dump(ostream&o) const
/*
* $Log: design_dump.cc,v $
* Revision 1.64 1999/12/17 03:38:46 steve
* NetConst can now hold wide constants.
*
* Revision 1.63 1999/12/12 06:03:14 steve
* Allow memories without indices in expressions.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: elab_net.cc,v 1.13 1999/12/16 03:46:39 steve Exp $"
#ident "$Id: elab_net.cc,v 1.14 1999/12/17 03:38:46 steve Exp $"
#endif
# include "PExpr.h"
@ -641,12 +641,11 @@ NetNet* PEIdent::elaborate_net(Design*des, const string&path,
verinum pvalue = pc->value();
sig = new NetNet(0, path+"."+text_, NetNet::IMPLICIT,
pc->expr_width());
for (unsigned idx = 0; idx < sig->pin_count(); idx += 1) {
NetConst*cp = new NetConst(des->local_symbol(path),
pvalue[idx]);
connect(sig->pin(idx), cp->pin(0));
des->add_node(cp);
}
NetConst*cp = new NetConst(des->local_symbol(path), pvalue);
des->add_node(cp);
des->add_signal(sig);
for (unsigned idx = 0; idx < sig->pin_count(); idx += 1)
connect(sig->pin(idx), cp->pin(idx));
} else {
@ -886,13 +885,11 @@ NetNet* PENumber::elaborate_net(Design*des, const string&path,
NetNet*net = new NetNet(0, des->local_symbol(path),
NetNet::IMPLICIT, width);
net->local_flag(true);
for (unsigned idx = 0 ; idx < width ; idx += 1) {
NetConst*tmp = new NetConst(des->local_symbol(path),
value_->get(idx));
des->add_node(tmp);
connect(net->pin(idx), tmp->pin(0));
}
NetConst*tmp = new NetConst(des->local_symbol(path), *value_);
for (unsigned idx = 0 ; idx < width ; idx += 1)
connect(net->pin(idx), tmp->pin(idx));
des->add_node(tmp);
des->add_signal(net);
return net;
}
@ -941,6 +938,9 @@ NetNet* PETernary::elaborate_net(Design*des, const string&path,
/*
* $Log: elab_net.cc,v $
* Revision 1.14 1999/12/17 03:38:46 steve
* NetConst can now hold wide constants.
*
* Revision 1.13 1999/12/16 03:46:39 steve
* Structural logical or.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: expr_synth.cc,v 1.6 1999/11/28 23:42:02 steve Exp $"
#ident "$Id: expr_synth.cc,v 1.7 1999/12/17 03:38:46 steve Exp $"
#endif
# include "netlist.h"
@ -125,12 +125,11 @@ NetNet* NetEConst::synthesize(Design*des)
unsigned width=expr_width();
NetNet*osig = new NetNet(0, path, NetNet::IMPLICIT, width);
for (unsigned idx = 0 ; idx < width; idx += 1) {
string oname = des->local_symbol(path);
NetConst *c = new NetConst(oname, value().get(idx));
connect(osig->pin(idx), c->pin(0));
des->add_node(c);
}
NetConst*con = new NetConst(des->local_symbol(path), value());
for (unsigned idx = 0 ; idx < width; idx += 1)
connect(osig->pin(idx), con->pin(idx));
des->add_node(con);
des->add_signal(osig);
return osig;
}
@ -200,6 +199,9 @@ NetNet* NetESignal::synthesize(Design*des)
/*
* $Log: expr_synth.cc,v $
* Revision 1.7 1999/12/17 03:38:46 steve
* NetConst can now hold wide constants.
*
* Revision 1.6 1999/11/28 23:42:02 steve
* NetESignal object no longer need to be NetNode
* objects. Let them keep a pointer to NetNet objects.

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.100 1999/12/16 02:42:15 steve Exp $"
#ident "$Id: netlist.cc,v 1.101 1999/12/17 03:38:46 steve Exp $"
#endif
# include <cassert>
@ -1489,14 +1489,34 @@ NetProc* NetCondit::else_clause()
}
NetConst::NetConst(const string&n, verinum::V v)
: NetNode(n, 1), value_(v)
: NetNode(n, 1)
{
pin(0).set_dir(Link::OUTPUT);
pin(0).set_name("O", 0);
value_ = new verinum::V[1];
value_[0] = v;
}
NetConst::NetConst(const string&n, const verinum&val)
: NetNode(n, val.len())
{
value_ = new verinum::V[pin_count()];
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
pin(idx).set_dir(Link::OUTPUT);
pin(idx).set_name("O", idx);
value_[idx] = val.get(idx);
}
}
NetConst::~NetConst()
{
delete[]value_;
}
verinum::V NetConst::value(unsigned idx) const
{
assert(idx < pin_count());
return value_[idx];
}
NetFuncDef::NetFuncDef(const string&n, const svector<NetNet*>&po)
@ -2744,6 +2764,9 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*))
/*
* $Log: netlist.cc,v $
* Revision 1.101 1999/12/17 03:38:46 steve
* NetConst can now hold wide constants.
*
* Revision 1.100 1999/12/16 02:42:15 steve
* Simulate carry output on adders.
*

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.102 1999/12/16 02:42:15 steve Exp $"
#ident "$Id: netlist.h,v 1.103 1999/12/17 03:38:46 steve Exp $"
#endif
/*
@ -707,20 +707,28 @@ class NetCaseCmp : public NetNode {
virtual void emit_node(ostream&, struct target_t*) const;
};
/*
* This class represents instances of the LPM_CONSTANT device. The
* node has only outputs and a constant value. The width is available
* by getting the pin_count(), and the value bits are available one at
* a time. There is no meaning to the aggregation of bits to form a
* wide NetConst object, although some targets may have an easier time
* detecting interesting constructs if they are combined.
*/
class NetConst : public NetNode {
public:
explicit NetConst(const string&n, verinum::V v);
explicit NetConst(const string&n, const verinum&val);
~NetConst();
verinum::V value() const { return value_; }
verinum::V value(unsigned idx) const;
virtual void emit_node(ostream&, struct target_t*) const;
virtual void dump_node(ostream&, unsigned ind) const;
private:
verinum::V value_;
verinum::V*value_;
};
/*
@ -2070,6 +2078,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
* Revision 1.103 1999/12/17 03:38:46 steve
* NetConst can now hold wide constants.
*
* Revision 1.102 1999/12/16 02:42:15 steve
* Simulate carry output on adders.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: t-vvm.cc,v 1.91 1999/12/16 02:42:15 steve Exp $"
#ident "$Id: t-vvm.cc,v 1.92 1999/12/17 03:38:46 steve Exp $"
#endif
# include <iostream>
@ -94,6 +94,7 @@ class target_vvm : public target_t {
void end_process(ostream&os, const NetProcTop*);
private:
void emit_init_value_(const NetObj::Link&lnk, verinum::V val);
void emit_gate_outputfun_(const NetNode*, unsigned);
string defn_gate_outputfun_(ostream&os, const NetNode*, unsigned);
@ -745,36 +746,12 @@ void target_vvm::signal(ostream&os, const NetNet*sig)
if (sig->get_ival(idx) == verinum::Vz)
continue;
map<string,bool>written;
init_code << " " << mangle(sig->name()) << ".init_P("
<< idx << ", V" << sig->get_ival(idx) << ");"
<< endl;
for (const NetObj::Link*lnk = sig->pin(idx).next_link()
; (*lnk) != sig->pin(idx) ; lnk = lnk->next_link()) {
if (lnk->get_dir() == NetObj::Link::OUTPUT)
continue;
// Check to see if the name has already been
// written to. This can happen if the object is a
// NetESignal, because there can be many of them
// with the same name.
if (written[lnk->get_obj()->name()])
continue;
written[lnk->get_obj()->name()] = true;
if (dynamic_cast<const NetNode*>(lnk->get_obj())) {
init_code << " " <<
mangle(lnk->get_obj()->name()) <<
".init_" << lnk->get_name() << "(" <<
lnk->get_inst() << ", V" <<
sig->get_ival(idx) << ");" << endl;
}
}
// Propogate the initial value to inputs throughout.
emit_init_value_(sig->pin(idx), sig->get_ival(idx));
}
}
@ -857,6 +834,36 @@ string target_vvm::defn_gate_outputfun_(ostream&os,
return name;
}
void target_vvm::emit_init_value_(const NetObj::Link&lnk, verinum::V val)
{
map<string,bool>written;
for (const NetObj::Link*cur = lnk.next_link()
; (*cur) != lnk ; cur = cur->next_link()) {
if (cur->get_dir() == NetObj::Link::OUTPUT)
continue;
// Check to see if the name has already been
// written to. This can happen if the object is a
// NetESignal, because there can be many of them
// with the same name.
if (written[cur->get_obj()->name()])
continue;
written[cur->get_obj()->name()] = true;
// Write initial values to nodes and nets.
if (dynamic_cast<const NetObj*>(cur->get_obj())) {
init_code << " " <<
mangle(cur->get_obj()->name()) <<
".init_" << cur->get_name() << "(" <<
cur->get_inst() << ", V" << val << ");" <<
endl;
}
}
}
/*
* This method handles writing output functions for gates that have a
* single output (at pin 0). This writes the output_fun method into
@ -878,7 +885,11 @@ void target_vvm::emit_gate_outputfun_(const NetNode*gate, unsigned gpin)
const NetObj*cur;
unsigned pin;
gate->pin(gpin).next_link(cur, pin);
while (cur != gate) {
for ( ; cur != gate ; cur->pin(pin).next_link(cur, pin)) {
// Skip pins that are output only.
if (cur->pin(pin).get_dir() == NetObj::Link::OUTPUT)
continue;
if (cur->pin(pin).get_name() != "") {
@ -892,7 +903,6 @@ void target_vvm::emit_gate_outputfun_(const NetNode*gate, unsigned gpin)
<< pin << ", val);" << endl;
}
cur->pin(pin).next_link(cur, pin);
}
delayed << "}" << endl;
@ -1290,29 +1300,8 @@ void target_vvm::net_case_cmp(ostream&os, const NetCaseCmp*gate)
*/
void target_vvm::net_const(ostream&os, const NetConst*gate)
{
string outfun = defn_gate_outputfun_(os, gate, 0);
os << "static vvm_bufz " << mangle(gate->name()) << "(&" <<
outfun << ");" << endl;
init_code << " " << mangle(gate->name()) << ".set(1, ";
switch (gate->value()) {
case verinum::V0:
init_code << "V0";
break;
case verinum::V1:
init_code << "V1";
break;
case verinum::Vx:
init_code << "Vx";
break;
case verinum::Vz:
init_code << "Vz";
break;
}
init_code << ");" << endl;
emit_gate_outputfun_(gate, 0);
for (unsigned idx = 0 ; idx < gate->pin_count() ; idx += 1)
emit_init_value_(gate->pin(idx), gate->value(idx));
}
/*
@ -1965,6 +1954,9 @@ extern const struct target tgt_vvm = {
};
/*
* $Log: t-vvm.cc,v $
* Revision 1.92 1999/12/17 03:38:46 steve
* NetConst can now hold wide constants.
*
* Revision 1.91 1999/12/16 02:42:15 steve
* Simulate carry output on adders.
*

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.21 1999/12/16 18:54:32 steve Exp $"
#ident "$Id: t-xnf.cc,v 1.22 1999/12/17 03:38:46 steve Exp $"
#endif
/* XNF BACKEND
@ -603,15 +603,17 @@ void target_xnf::lpm_ram_dq(ostream&os, const NetRamDq*ram)
void target_xnf::net_const(ostream&os, const NetConst*c)
{
verinum::V v=c->value();
assert(v==verinum::V0 || v==verinum::V1);
const NetObj::Link& lnk = c->pin(0);
// Code parallels draw_pin above, some smart c++ guru should
// find a way to make a method out of this.
unsigned cpin;
const NetObj*cur;
for (unsigned idx = 0 ; idx < c->pin_count() ; idx += 1) {
verinum::V v=c->value(idx);
assert(v==verinum::V0 || v==verinum::V1);
const NetObj::Link& lnk = c->pin(idx);
// Code parallels draw_pin above, some smart c++ guru should
// find a way to make a method out of this.
unsigned cpin;
const NetObj*cur;
os << " PWR, " << v << ", " << choose_sig_name(&lnk) << endl;
os << " PWR, " << v << ", " << choose_sig_name(&lnk) << endl;
}
}
/*
@ -709,6 +711,9 @@ extern const struct target tgt_xnf = { "xnf", &target_xnf_obj };
/*
* $Log: t-xnf.cc,v $
* 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.
*