Fully elaborate Sequential UDP behavior.
This commit is contained in:
parent
45f45f73b7
commit
10b345bd16
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: design_dump.cc,v 1.7 1998/12/07 04:53:17 steve Exp $"
|
#ident "$Id: design_dump.cc,v 1.8 1998/12/14 02:01:34 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -167,9 +167,55 @@ void NetLogic::dump_node(ostream&o, unsigned ind) const
|
||||||
dump_obj_attr(o, ind+4);
|
dump_obj_attr(o, ind+4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetUDP::dump_node(ostream&o, unsigned ind) const
|
void NetUDP::dump_sequ_(ostream&o, unsigned ind) const
|
||||||
{
|
{
|
||||||
o << setw(ind) << "" << "UDP: ";
|
string tmp = "";
|
||||||
|
for (unsigned idx = 0 ; idx < ind ; idx += 1)
|
||||||
|
tmp += " ";
|
||||||
|
|
||||||
|
o << tmp << "Sequential UDP" << " #(" << delay1() <<
|
||||||
|
"," << delay2() << "," << delay3() << ") " << name() <<
|
||||||
|
endl;
|
||||||
|
|
||||||
|
for (FSM_::const_iterator ent = fsm_.begin()
|
||||||
|
; ent != fsm_.end() ; ent++) {
|
||||||
|
o << setw(ind+6) << "" << (*ent).first << " -->";
|
||||||
|
|
||||||
|
state_t_*st = (*ent).second;
|
||||||
|
assert((*ent).first[0] == st->out);
|
||||||
|
for (unsigned idx = 1 ; idx < pin_count() ; idx += 1) {
|
||||||
|
string tmp = (*ent).first;
|
||||||
|
if (st->pins[idx].zer) {
|
||||||
|
tmp[0] = st->pins[idx].zer->out;
|
||||||
|
tmp[idx] = '0';
|
||||||
|
o << " " << tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (st->pins[idx].one) {
|
||||||
|
tmp[0] = st->pins[idx].one->out;
|
||||||
|
tmp[idx] = '1';
|
||||||
|
o << " " << tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (st->pins[idx].xxx) {
|
||||||
|
tmp[0] = st->pins[idx].xxx->out;
|
||||||
|
tmp[idx] = 'x';
|
||||||
|
o << " " << tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
o << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
o << setw(ind+6) << "" << "initial value == " << init_ << endl;
|
||||||
|
|
||||||
|
dump_node_pins(o, ind+4);
|
||||||
|
dump_obj_attr(o, ind+4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetUDP::dump_comb_(ostream&o, unsigned ind) const
|
||||||
|
{
|
||||||
|
o << setw(ind) << "" << "Combinational UDP: ";
|
||||||
o << " #(" << delay1() << "," << delay2() << "," << delay3() <<
|
o << " #(" << delay1() << "," << delay2() << "," << delay3() <<
|
||||||
") " << name() << endl;
|
") " << name() << endl;
|
||||||
|
|
||||||
|
|
@ -177,6 +223,14 @@ void NetUDP::dump_node(ostream&o, unsigned ind) const
|
||||||
dump_obj_attr(o, ind+4);
|
dump_obj_attr(o, ind+4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NetUDP::dump_node(ostream&o, unsigned ind) const
|
||||||
|
{
|
||||||
|
if (sequential_)
|
||||||
|
dump_sequ_(o, ind);
|
||||||
|
else
|
||||||
|
dump_comb_(o, ind);
|
||||||
|
}
|
||||||
|
|
||||||
void NetPEvent::dump_node(ostream&o, unsigned ind) const
|
void NetPEvent::dump_node(ostream&o, unsigned ind) const
|
||||||
{
|
{
|
||||||
o << setw(ind) << "" << "event: ";
|
o << setw(ind) << "" << "event: ";
|
||||||
|
|
@ -407,6 +461,9 @@ void Design::dump(ostream&o) const
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: design_dump.cc,v $
|
* $Log: design_dump.cc,v $
|
||||||
|
* Revision 1.8 1998/12/14 02:01:34 steve
|
||||||
|
* Fully elaborate Sequential UDP behavior.
|
||||||
|
*
|
||||||
* Revision 1.7 1998/12/07 04:53:17 steve
|
* Revision 1.7 1998/12/07 04:53:17 steve
|
||||||
* Generate OBUF or IBUF attributes (and the gates
|
* Generate OBUF or IBUF attributes (and the gates
|
||||||
* to garry them) where a wire is a pad. This involved
|
* to garry them) where a wire is a pad. This involved
|
||||||
|
|
|
||||||
42
elaborate.cc
42
elaborate.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: elaborate.cc,v 1.9 1998/12/07 04:53:17 steve Exp $"
|
#ident "$Id: elaborate.cc,v 1.10 1998/12/14 02:01:34 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -255,12 +255,20 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, const string&path) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* From a UDP definition in the source, make a NetUDP
|
||||||
|
* object. Elaborate the pin expressions as netlists, then connect
|
||||||
|
* those networks to the pins.
|
||||||
|
*/
|
||||||
void PGModule::elaborate_udp_(Design*des, PUdp*udp, const string&path) const
|
void PGModule::elaborate_udp_(Design*des, PUdp*udp, const string&path) const
|
||||||
{
|
{
|
||||||
const string my_name = path+"."+get_name();
|
const string my_name = path+"."+get_name();
|
||||||
NetUDP*net = new NetUDP(my_name, udp->ports.size());
|
NetUDP*net = new NetUDP(my_name, udp->ports.size(), udp->sequential);
|
||||||
net->set_attributes(udp->attributes);
|
net->set_attributes(udp->attributes);
|
||||||
|
|
||||||
|
/* Run through the pins, making netlists for the pin
|
||||||
|
expressions and connecting them to the pin in question. All
|
||||||
|
of this is independent of the nature of the UDP. */
|
||||||
for (unsigned idx = 0 ; idx < net->pin_count() ; idx += 1) {
|
for (unsigned idx = 0 ; idx < net->pin_count() ; idx += 1) {
|
||||||
if (pin(idx) == 0)
|
if (pin(idx) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -274,10 +282,37 @@ void PGModule::elaborate_udp_(Design*des, PUdp*udp, const string&path) const
|
||||||
|
|
||||||
connect(sig->pin(0), net->pin(idx));
|
connect(sig->pin(0), net->pin(idx));
|
||||||
|
|
||||||
|
// Delete excess holding signal.
|
||||||
if (NetTmp*tmp = dynamic_cast<NetTmp*>(sig))
|
if (NetTmp*tmp = dynamic_cast<NetTmp*>(sig))
|
||||||
delete tmp;
|
delete tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Build up the truth table for the netlist from the input
|
||||||
|
strings. */
|
||||||
|
for (unsigned idx = 0 ; idx < udp->tinput.size() ; idx += 1) {
|
||||||
|
string input = udp->sequential
|
||||||
|
? (string("") + udp->tcurrent[idx] + udp->tinput[idx])
|
||||||
|
: udp->tinput[idx];
|
||||||
|
|
||||||
|
net->set_table(input, udp->toutput[idx]);
|
||||||
|
}
|
||||||
|
|
||||||
|
net->cleanup_table();
|
||||||
|
|
||||||
|
if (udp->sequential) switch (udp->initial) {
|
||||||
|
case verinum::V0:
|
||||||
|
net->set_initial('0');
|
||||||
|
break;
|
||||||
|
case verinum::V1:
|
||||||
|
net->set_initial('1');
|
||||||
|
break;
|
||||||
|
case verinum::Vx:
|
||||||
|
case verinum::Vz:
|
||||||
|
net->set_initial('x');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// All done. Add the object to the design.
|
||||||
des->add_node(net);
|
des->add_node(net);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -734,6 +769,9 @@ Design* elaborate(const map<string,Module*>&modules,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: elaborate.cc,v $
|
* $Log: elaborate.cc,v $
|
||||||
|
* Revision 1.10 1998/12/14 02:01:34 steve
|
||||||
|
* Fully elaborate Sequential UDP behavior.
|
||||||
|
*
|
||||||
* Revision 1.9 1998/12/07 04:53:17 steve
|
* Revision 1.9 1998/12/07 04:53:17 steve
|
||||||
* Generate OBUF or IBUF attributes (and the gates
|
* Generate OBUF or IBUF attributes (and the gates
|
||||||
* to garry them) where a wire is a pad. This involved
|
* to garry them) where a wire is a pad. This involved
|
||||||
|
|
|
||||||
210
netlist.cc
210
netlist.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: netlist.cc,v 1.11 1998/12/07 04:53:17 steve Exp $"
|
#ident "$Id: netlist.cc,v 1.12 1998/12/14 02:01:35 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include <cassert>
|
# include <cassert>
|
||||||
|
|
@ -423,12 +423,213 @@ NetLogic::NetLogic(const string&n, unsigned pins, TYPE t)
|
||||||
pin(idx).set_dir(Link::INPUT);
|
pin(idx).set_dir(Link::INPUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
NetUDP::NetUDP(const string&n, unsigned pins)
|
NetUDP::NetUDP(const string&n, unsigned pins, bool sequ)
|
||||||
: NetNode(n, pins)
|
: NetNode(n, pins), sequential_(sequ), init_('x')
|
||||||
{
|
{
|
||||||
pin(0).set_dir(Link::OUTPUT);
|
pin(0).set_dir(Link::OUTPUT);
|
||||||
for (unsigned idx = 1 ; idx < pins ; idx += 1)
|
for (unsigned idx = 1 ; idx < pins ; idx += 1)
|
||||||
pin(idx).set_dir(Link::INPUT);
|
pin(idx).set_dir(Link::INPUT);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
NetUDP::state_t_* NetUDP::find_state_(const string&str)
|
||||||
|
{
|
||||||
|
map<string,state_t_*>::iterator cur = fsm_.find(str);
|
||||||
|
if (cur != fsm_.end())
|
||||||
|
return (*cur).second;
|
||||||
|
|
||||||
|
state_t_*st = fsm_[str];
|
||||||
|
if (st == 0) {
|
||||||
|
st = new state_t_(pin_count());
|
||||||
|
st->out = str[0];
|
||||||
|
fsm_[str] = st;
|
||||||
|
}
|
||||||
|
|
||||||
|
return st;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This method takes the input string, which contains exactly one
|
||||||
|
* edge, and connects it to the correct output state. The output state
|
||||||
|
* will be generated if needed, and the value compared.
|
||||||
|
*/
|
||||||
|
bool NetUDP::set_sequ_(const string&input, char output)
|
||||||
|
{
|
||||||
|
if (output == '-')
|
||||||
|
output = input[0];
|
||||||
|
|
||||||
|
string frm = input;
|
||||||
|
string to = input;
|
||||||
|
to[0] = output;
|
||||||
|
|
||||||
|
unsigned edge = frm.find_first_not_of("01x");
|
||||||
|
assert(frm.find_last_not_of("01x") == edge);
|
||||||
|
|
||||||
|
switch (input[edge]) {
|
||||||
|
case 'r':
|
||||||
|
frm[edge] = '0';
|
||||||
|
to[edge] = '1';
|
||||||
|
break;
|
||||||
|
case 'R':
|
||||||
|
frm[edge] = 'x';
|
||||||
|
to[edge] = '1';
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
frm[edge] = '1';
|
||||||
|
to[edge] = '0';
|
||||||
|
break;
|
||||||
|
case 'F':
|
||||||
|
frm[edge] = 'x';
|
||||||
|
to[edge] = '0';
|
||||||
|
break;
|
||||||
|
case 'P':
|
||||||
|
frm[edge] = '0';
|
||||||
|
to[edge] = 'x';
|
||||||
|
break;
|
||||||
|
case 'N':
|
||||||
|
frm[edge] = '1';
|
||||||
|
to[edge] = 'x';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
state_t_*sfrm = find_state_(frm);
|
||||||
|
state_t_*sto = find_state_(to);
|
||||||
|
|
||||||
|
switch (to[edge]) {
|
||||||
|
case '0':
|
||||||
|
assert(sfrm->pins[edge].zer == 0);
|
||||||
|
sfrm->pins[edge].zer = sto;
|
||||||
|
break;
|
||||||
|
case '1':
|
||||||
|
assert(sfrm->pins[edge].one == 0);
|
||||||
|
sfrm->pins[edge].one = sto;
|
||||||
|
break;
|
||||||
|
case 'x':
|
||||||
|
assert(sfrm->pins[edge].xxx == 0);
|
||||||
|
sfrm->pins[edge].xxx = sto;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NetUDP::sequ_glob_(string input, char output)
|
||||||
|
{
|
||||||
|
for (unsigned idx = 0 ; idx < input.length() ; idx += 1)
|
||||||
|
switch (input[idx]) {
|
||||||
|
case '0':
|
||||||
|
case '1':
|
||||||
|
case 'x':
|
||||||
|
case 'r':
|
||||||
|
case 'R':
|
||||||
|
case 'f':
|
||||||
|
case 'F':
|
||||||
|
case 'P':
|
||||||
|
case 'N':
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '?': // Iterate over all the levels
|
||||||
|
input[idx] = '0';
|
||||||
|
sequ_glob_(input, output);
|
||||||
|
input[idx] = '1';
|
||||||
|
sequ_glob_(input, output);
|
||||||
|
input[idx] = 'x';
|
||||||
|
sequ_glob_(input, output);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case '*': // Iterate over all the edges
|
||||||
|
input[idx] = 'r';
|
||||||
|
sequ_glob_(input, output);
|
||||||
|
input[idx] = 'R';
|
||||||
|
sequ_glob_(input, output);
|
||||||
|
input[idx] = 'f';
|
||||||
|
sequ_glob_(input, output);
|
||||||
|
input[idx] = 'F';
|
||||||
|
sequ_glob_(input, output);
|
||||||
|
input[idx] = 'P';
|
||||||
|
sequ_glob_(input, output);
|
||||||
|
input[idx] = 'N';
|
||||||
|
sequ_glob_(input, output);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return set_sequ_(input, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NetUDP::set_table(const string&input, char output)
|
||||||
|
{
|
||||||
|
assert((output == '0') || (output == '1') || (sequential_ &&
|
||||||
|
(output == '-')));
|
||||||
|
|
||||||
|
if (sequential_) {
|
||||||
|
assert(input.length() == pin_count());
|
||||||
|
/* XXXX Need to check to make sure that the input vector
|
||||||
|
contains a legal combination of characters. */
|
||||||
|
return sequ_glob_(input, output);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
assert(input.length() == (pin_count()-1));
|
||||||
|
/* XXXX Need to check to make sure that the input vector
|
||||||
|
contains a legal combination of characters. In
|
||||||
|
combinational UDPs, only 0, 1 and x are allowed. */
|
||||||
|
assert(0);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetUDP::cleanup_table()
|
||||||
|
{
|
||||||
|
for (FSM_::iterator idx = fsm_.begin() ; idx != fsm_.end() ; idx++) {
|
||||||
|
string str = (*idx).first;
|
||||||
|
state_t_*st = (*idx).second;
|
||||||
|
assert(str[0] == st->out);
|
||||||
|
|
||||||
|
for (unsigned pin = 0 ; pin < pin_count() ; pin += 1) {
|
||||||
|
if (st->pins[pin].zer && st->pins[pin].zer->out == 'x')
|
||||||
|
st->pins[pin].zer = 0;
|
||||||
|
if (st->pins[pin].one && st->pins[pin].one->out == 'x')
|
||||||
|
st->pins[pin].one = 0;
|
||||||
|
if (st->pins[pin].xxx && st->pins[pin].xxx->out == 'x')
|
||||||
|
st->pins[pin].xxx = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (FSM_::iterator idx = fsm_.begin() ; idx != fsm_.end() ; ) {
|
||||||
|
FSM_::iterator cur = idx;
|
||||||
|
idx ++;
|
||||||
|
|
||||||
|
state_t_*st = (*cur).second;
|
||||||
|
|
||||||
|
if (st->out != 'x')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (unsigned pin = 0 ; pin < pin_count() ; pin += 1) {
|
||||||
|
if (st->pins[pin].zer)
|
||||||
|
goto break_label;
|
||||||
|
if (st->pins[pin].one)
|
||||||
|
goto break_label;
|
||||||
|
if (st->pins[pin].xxx)
|
||||||
|
goto break_label;
|
||||||
|
}
|
||||||
|
|
||||||
|
//delete st;
|
||||||
|
fsm_.erase(cur);
|
||||||
|
|
||||||
|
break_label:;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetUDP::set_initial(char val)
|
||||||
|
{
|
||||||
|
assert(sequential_);
|
||||||
|
assert((val == '0') || (val == '1') || (val == 'x'));
|
||||||
|
init_ = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
string Design::get_flag(const string&key) const
|
string Design::get_flag(const string&key) const
|
||||||
|
|
@ -583,6 +784,9 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: netlist.cc,v $
|
* $Log: netlist.cc,v $
|
||||||
|
* Revision 1.12 1998/12/14 02:01:35 steve
|
||||||
|
* Fully elaborate Sequential UDP behavior.
|
||||||
|
*
|
||||||
* Revision 1.11 1998/12/07 04:53:17 steve
|
* Revision 1.11 1998/12/07 04:53:17 steve
|
||||||
* Generate OBUF or IBUF attributes (and the gates
|
* Generate OBUF or IBUF attributes (and the gates
|
||||||
* to garry them) where a wire is a pad. This involved
|
* to garry them) where a wire is a pad. This involved
|
||||||
|
|
|
||||||
84
netlist.h
84
netlist.h
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: netlist.h,v 1.11 1998/12/07 04:53:17 steve Exp $"
|
#ident "$Id: netlist.h,v 1.12 1998/12/14 02:01:35 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -338,14 +338,91 @@ class NetLogic : public NetNode {
|
||||||
* The UDP is a User Defined Primitive from the Verilog source. Do not
|
* The UDP is a User Defined Primitive from the Verilog source. Do not
|
||||||
* expand it out any further then this in the netlist, as this can be
|
* expand it out any further then this in the netlist, as this can be
|
||||||
* used to represent target device primitives.
|
* used to represent target device primitives.
|
||||||
|
*
|
||||||
|
* The UDP can be combinational or sequential. The sequentianl UDP
|
||||||
|
* includes the current output in the truth table, and supports edges,
|
||||||
|
* whereas the combinational does not and is entirely level sensitive.
|
||||||
|
* In any case, pin 0 is an output, and all the remaining pins are
|
||||||
|
* inputs.
|
||||||
|
*
|
||||||
|
* The truth table is canonically represented as a finite state
|
||||||
|
* machine with the current state representing the inputs and the
|
||||||
|
* current output, and the next state carrying the new output value to
|
||||||
|
* use. All the outgoing transitions from a state represent a single
|
||||||
|
* edge.
|
||||||
|
*
|
||||||
|
* Set_table takes as input a string with one letter per pin. The
|
||||||
|
* valid characters are:
|
||||||
|
*
|
||||||
|
* 0, 1, x -- The levels
|
||||||
|
* r -- (01)
|
||||||
|
* R -- (x1)
|
||||||
|
* f -- (10)
|
||||||
|
* F -- (x0)
|
||||||
|
* P -- (0x)
|
||||||
|
* N -- (1x)
|
||||||
|
*
|
||||||
|
* COMBINATIONAL
|
||||||
|
* The logic table is a map between the input levels and the
|
||||||
|
* output. Each input pin can have the value 0, 1 or x and the output
|
||||||
|
* can have the values 0 or 1. If the input matches nothing, the
|
||||||
|
* output is x. In canonical form, only the entries that generate 0 or
|
||||||
|
* 1 are listed.
|
||||||
|
*
|
||||||
|
* SEQUENTIAL
|
||||||
|
* These objects have a single bit of memory. The logic table includes
|
||||||
|
* an entry for the current value, and allows edges on the inputs. In
|
||||||
|
* canonical form, inly then entries that generate 0, 1 or - (no change)
|
||||||
|
* are listed.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
class NetUDP : public NetNode {
|
class NetUDP : public NetNode {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit NetUDP(const string&n, unsigned pins);
|
explicit NetUDP(const string&n, unsigned pins, bool sequ =false);
|
||||||
|
|
||||||
virtual void emit_node(ostream&, struct target_t*) const;
|
virtual void emit_node(ostream&, struct target_t*) const;
|
||||||
virtual void dump_node(ostream&, unsigned ind) const;
|
virtual void dump_node(ostream&, unsigned ind) const;
|
||||||
|
|
||||||
|
/* return false if the entry conflicts with an existing
|
||||||
|
entry. In any case, the new output overrides. */
|
||||||
|
bool set_table(const string&input, char output);
|
||||||
|
void cleanup_table();
|
||||||
|
|
||||||
|
void set_initial(char);
|
||||||
|
|
||||||
|
bool is_sequential() const { return sequential_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
const bool sequential_;
|
||||||
|
char init_;
|
||||||
|
|
||||||
|
struct state_t_;
|
||||||
|
struct pin_t_ {
|
||||||
|
state_t_*zer;
|
||||||
|
state_t_*one;
|
||||||
|
state_t_*xxx;
|
||||||
|
|
||||||
|
explicit pin_t_() : zer(0), one(0), xxx(0) { }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct state_t_ {
|
||||||
|
char out;
|
||||||
|
pin_t_*pins;
|
||||||
|
|
||||||
|
state_t_(unsigned n) : out(0), pins(new pin_t_[n]) {}
|
||||||
|
~state_t_() { delete[]pins; }
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef map<string,state_t_*> FSM_;
|
||||||
|
FSM_ fsm_;
|
||||||
|
bool set_sequ_(const string&in, char out);
|
||||||
|
bool sequ_glob_(string, char out);
|
||||||
|
|
||||||
|
state_t_*find_state_(const string&);
|
||||||
|
|
||||||
|
void dump_sequ_(ostream&o, unsigned ind) const;
|
||||||
|
void dump_comb_(ostream&o, unsigned ind) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* =========
|
/* =========
|
||||||
|
|
@ -811,6 +888,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: netlist.h,v $
|
* $Log: netlist.h,v $
|
||||||
|
* Revision 1.12 1998/12/14 02:01:35 steve
|
||||||
|
* Fully elaborate Sequential UDP behavior.
|
||||||
|
*
|
||||||
* Revision 1.11 1998/12/07 04:53:17 steve
|
* Revision 1.11 1998/12/07 04:53:17 steve
|
||||||
* Generate OBUF or IBUF attributes (and the gates
|
* Generate OBUF or IBUF attributes (and the gates
|
||||||
* to garry them) where a wire is a pad. This involved
|
* to garry them) where a wire is a pad. This involved
|
||||||
|
|
|
||||||
4
parse.y
4
parse.y
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: parse.y,v 1.8 1998/12/01 00:42:14 steve Exp $"
|
#ident "$Id: parse.y,v 1.9 1998/12/14 02:01:35 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "parse_misc.h"
|
# include "parse_misc.h"
|
||||||
|
|
@ -730,7 +730,7 @@ udp_input_sym
|
||||||
| 'b' { $$ = 'b'; }
|
| 'b' { $$ = 'b'; }
|
||||||
| '*' { $$ = '*'; }
|
| '*' { $$ = '*'; }
|
||||||
| 'f' { $$ = 'f'; }
|
| 'f' { $$ = 'f'; }
|
||||||
| 'r' { $$ = 'f'; }
|
| 'r' { $$ = 'r'; }
|
||||||
;
|
;
|
||||||
|
|
||||||
udp_output_sym
|
udp_output_sym
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue