New and improved combinational primitives.
This commit is contained in:
parent
995f7e89d1
commit
d97ab9be23
|
|
@ -18,7 +18,7 @@
|
|||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.40 2000/03/21 05:08:32 steve Exp $"
|
||||
#ident "$Id: Makefile.in,v 1.41 2000/03/29 04:37:10 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
|
@ -72,7 +72,7 @@ FF = nobufz.o nodangle.o propinit.o synth.o xnfio.o xnfsyn.o
|
|||
O = main.o cprop.o design_dump.o dup_expr.o elaborate.o elab_expr.o \
|
||||
elab_net.o elab_pexpr.o elab_scope.o emit.o eval.o eval_tree.o \
|
||||
expr_synth.o functor.o lexor.o lexor_keyword.o mangle.o netlist.o \
|
||||
net_design.o nexus_from_link.o pad_to_width.o \
|
||||
net_design.o net_udp.o nexus_from_link.o pad_to_width.o \
|
||||
parse.o parse_misc.o pform.o pform_dump.o \
|
||||
set_width.o \
|
||||
verinum.o verireal.o target.o targets.o Module.o PDelays.o PExpr.o PGate.o \
|
||||
|
|
|
|||
8
PGate.h
8
PGate.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PGate.h,v 1.15 2000/03/08 04:36:53 steve Exp $"
|
||||
#ident "$Id: PGate.h,v 1.16 2000/03/29 04:37:10 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "svector.h"
|
||||
|
|
@ -194,12 +194,16 @@ class PGModule : public PGate {
|
|||
PExpr*lsb_;
|
||||
|
||||
void elaborate_mod_(Design*, Module*mod, const string&path) const;
|
||||
void elaborate_udp_(Design*, PUdp *udp, const string&path) const;
|
||||
void elaborate_sudp_(Design*, PUdp *udp, const string&path) const;
|
||||
void elaborate_cudp_(Design*, PUdp *udp, const string&path) const;
|
||||
void elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const;
|
||||
};
|
||||
|
||||
/*
|
||||
* $Log: PGate.h,v $
|
||||
* Revision 1.16 2000/03/29 04:37:10 steve
|
||||
* New and improved combinational primitives.
|
||||
*
|
||||
* Revision 1.15 2000/03/08 04:36:53 steve
|
||||
* Redesign the implementation of scopes and parameters.
|
||||
* I now generate the scopes and notice the parameters
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: design_dump.cc,v 1.69 2000/03/12 17:09:40 steve Exp $"
|
||||
#ident "$Id: design_dump.cc,v 1.70 2000/03/29 04:37:10 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -336,18 +336,7 @@ void NetUDP::dump_sequ_(ostream&o, unsigned ind) const
|
|||
|
||||
void NetUDP::dump_comb_(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "Combinational UDP: ";
|
||||
o << " #(" << rise_time() << "," << fall_time() << "," << decay_time() <<
|
||||
") " << name() << endl;
|
||||
|
||||
for (CM_::const_iterator ent = cm_.begin()
|
||||
; ent != cm_.end() ; ent++) {
|
||||
o << setw(ind+6) << "" << (*ent).first << " --> " <<
|
||||
(*ent).second << endl;
|
||||
}
|
||||
|
||||
dump_node_pins(o, ind+4);
|
||||
dump_obj_attr(o, ind+4);
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void NetUDP::dump_node(ostream&o, unsigned ind) const
|
||||
|
|
@ -358,6 +347,22 @@ void NetUDP::dump_node(ostream&o, unsigned ind) const
|
|||
dump_comb_(o, ind);
|
||||
}
|
||||
|
||||
void NetUDP_COMB::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "Combinational primitive: ";
|
||||
o << " #(" << rise_time() << "," << fall_time() << "," << decay_time() <<
|
||||
") " << name() << endl;
|
||||
|
||||
for (map<string,char>::const_iterator ent = cm_.begin()
|
||||
; ent != cm_.end() ; ent++) {
|
||||
o << setw(ind+6) << "" << (*ent).first << " --> " <<
|
||||
(*ent).second << endl;
|
||||
}
|
||||
|
||||
dump_node_pins(o, ind+4);
|
||||
dump_obj_attr(o, ind+4);
|
||||
}
|
||||
|
||||
void NetNEvent::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "event: ";
|
||||
|
|
@ -892,6 +897,9 @@ void Design::dump(ostream&o) const
|
|||
|
||||
/*
|
||||
* $Log: design_dump.cc,v $
|
||||
* Revision 1.70 2000/03/29 04:37:10 steve
|
||||
* New and improved combinational primitives.
|
||||
*
|
||||
* Revision 1.69 2000/03/12 17:09:40 steve
|
||||
* Support localparam.
|
||||
*
|
||||
|
|
|
|||
60
elaborate.cc
60
elaborate.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: elaborate.cc,v 1.150 2000/03/20 15:28:58 steve Exp $"
|
||||
#ident "$Id: elaborate.cc,v 1.151 2000/03/29 04:37:11 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -535,12 +535,53 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, const string&path) const
|
|||
}
|
||||
}
|
||||
|
||||
void PGModule::elaborate_cudp_(Design*des, PUdp*udp, const string&path) const
|
||||
{
|
||||
const string my_name = path+"."+get_name();
|
||||
NetUDP_COMB*net = new NetUDP_COMB(my_name, udp->ports.count());
|
||||
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) {
|
||||
if (pin(idx) == 0)
|
||||
continue;
|
||||
|
||||
NetNet*sig = pin(idx)->elaborate_net(des, path, 1, 0, 0, 0);
|
||||
if (sig == 0) {
|
||||
cerr << "internal error: Expression too complicated "
|
||||
"for elaboration:" << *pin(idx) << endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
connect(sig->pin(0), net->pin(idx));
|
||||
|
||||
// Delete excess holding signal.
|
||||
if (NetTmp*tmp = dynamic_cast<NetTmp*>(sig))
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
/* Build up the truth table for the netlist from the input
|
||||
strings. */
|
||||
for (unsigned idx = 0 ; idx < udp->tinput.count() ; idx += 1) {
|
||||
string input = udp->tinput[idx];
|
||||
|
||||
net->set_table(input, udp->toutput[idx]);
|
||||
}
|
||||
|
||||
net->cleanup_table();
|
||||
|
||||
// All done. Add the object to the design.
|
||||
des->add_node(net);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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_sudp_(Design*des, PUdp*udp, const string&path) const
|
||||
{
|
||||
const string my_name = path+"."+get_name();
|
||||
NetUDP*net = new NetUDP(my_name, udp->ports.count(), udp->sequential);
|
||||
|
|
@ -570,16 +611,13 @@ void PGModule::elaborate_udp_(Design*des, PUdp*udp, const string&path) const
|
|||
/* Build up the truth table for the netlist from the input
|
||||
strings. */
|
||||
for (unsigned idx = 0 ; idx < udp->tinput.count() ; idx += 1) {
|
||||
string input = udp->sequential
|
||||
? (string("") + udp->tcurrent[idx] + udp->tinput[idx])
|
||||
: udp->tinput[idx];
|
||||
|
||||
string input = string("") + udp->tcurrent[idx] + udp->tinput[idx];
|
||||
net->set_table(input, udp->toutput[idx]);
|
||||
}
|
||||
|
||||
net->cleanup_table();
|
||||
|
||||
if (udp->sequential) switch (udp->initial) {
|
||||
switch (udp->initial) {
|
||||
case verinum::V0:
|
||||
net->set_initial('0');
|
||||
break;
|
||||
|
|
@ -608,7 +646,10 @@ void PGModule::elaborate(Design*des, const string&path) const
|
|||
// Try a primitive type
|
||||
map<string,PUdp*>::const_iterator udp = udplist->find(type_);
|
||||
if (udp != udplist->end()) {
|
||||
elaborate_udp_(des, (*udp).second, path);
|
||||
if ((*udp).second->sequential)
|
||||
elaborate_sudp_(des, (*udp).second, path);
|
||||
else
|
||||
elaborate_cudp_(des, (*udp).second, path);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1962,6 +2003,9 @@ Design* elaborate(const map<string,Module*>&modules,
|
|||
|
||||
/*
|
||||
* $Log: elaborate.cc,v $
|
||||
* Revision 1.151 2000/03/29 04:37:11 steve
|
||||
* New and improved combinational primitives.
|
||||
*
|
||||
* Revision 1.150 2000/03/20 15:28:58 steve
|
||||
* Fix lval part select of non-blocking assign.
|
||||
*
|
||||
|
|
|
|||
10
emit.cc
10
emit.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: emit.cc,v 1.34 2000/03/08 04:36:53 steve Exp $"
|
||||
#ident "$Id: emit.cc,v 1.35 2000/03/29 04:37:11 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -40,6 +40,11 @@ void NetLogic::emit_node(ostream&o, struct target_t*tgt) const
|
|||
tgt->logic(o, this);
|
||||
}
|
||||
|
||||
void NetUDP_COMB::emit_node(ostream&o, struct target_t*tgt) const
|
||||
{
|
||||
tgt->udp_comb(o, this);
|
||||
}
|
||||
|
||||
void NetUDP::emit_node(ostream&o, struct target_t*tgt) const
|
||||
{
|
||||
tgt->udp(o, this);
|
||||
|
|
@ -397,6 +402,9 @@ bool emit(ostream&o, const Design*des, const char*type)
|
|||
|
||||
/*
|
||||
* $Log: emit.cc,v $
|
||||
* Revision 1.35 2000/03/29 04:37:11 steve
|
||||
* New and improved combinational primitives.
|
||||
*
|
||||
* Revision 1.34 2000/03/08 04:36:53 steve
|
||||
* Redesign the implementation of scopes and parameters.
|
||||
* I now generate the scopes and notice the parameters
|
||||
|
|
|
|||
|
|
@ -0,0 +1,205 @@
|
|||
/*
|
||||
* Copyright (c) 2000 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) && !defined(macintosh)
|
||||
#ident "$Id: net_udp.cc,v 1.1 2000/03/29 04:37:11 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "netlist.h"
|
||||
|
||||
NetUDP::NetUDP(const string&n, unsigned pins, bool sequ)
|
||||
: NetNode(n, pins), sequential_(sequ), init_('x')
|
||||
{
|
||||
pin(0).set_dir(Link::OUTPUT);
|
||||
for (unsigned idx = 1 ; idx < pins ; idx += 1)
|
||||
pin(idx).set_dir(Link::INPUT);
|
||||
|
||||
}
|
||||
|
||||
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. */
|
||||
cm_[input] = output;
|
||||
|
||||
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:;
|
||||
}
|
||||
}
|
||||
|
||||
char NetUDP::table_lookup(const string&from, char to, unsigned pin) const
|
||||
{
|
||||
assert(pin <= pin_count());
|
||||
assert(from.length() == pin_count());
|
||||
FSM_::const_iterator idx = fsm_.find(from);
|
||||
if (idx == fsm_.end())
|
||||
return 'x';
|
||||
|
||||
state_t_*next;
|
||||
switch (to) {
|
||||
case '0':
|
||||
next = (*idx).second->pins[pin].zer;
|
||||
break;
|
||||
case '1':
|
||||
next = (*idx).second->pins[pin].one;
|
||||
break;
|
||||
case 'x':
|
||||
next = (*idx).second->pins[pin].xxx;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
next = 0;
|
||||
}
|
||||
|
||||
return next? next->out : 'x';
|
||||
}
|
||||
|
||||
void NetUDP::set_initial(char val)
|
||||
{
|
||||
assert(sequential_);
|
||||
assert((val == '0') || (val == '1') || (val == 'x'));
|
||||
init_ = val;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
NetUDP_COMB::NetUDP_COMB(const string&n, unsigned pins)
|
||||
: NetNode(n, pins)
|
||||
{
|
||||
pin(0).set_dir(Link::OUTPUT);
|
||||
pin(0).set_name("O", 0);
|
||||
for (unsigned idx = 1 ; idx < pins ; idx += 1) {
|
||||
pin(idx).set_dir(Link::INPUT);
|
||||
pin(idx).set_name("I", idx-1);
|
||||
}
|
||||
}
|
||||
|
||||
void NetUDP_COMB::set_table(const string&input, char output)
|
||||
{
|
||||
assert((output == '0') || (output == '1'));
|
||||
|
||||
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. */
|
||||
cm_[input] = output;
|
||||
|
||||
}
|
||||
|
||||
void NetUDP_COMB::cleanup_table()
|
||||
{
|
||||
}
|
||||
|
||||
bool NetUDP_COMB::first(string&inp, char&out) const
|
||||
{
|
||||
idx_ = cm_.begin();
|
||||
if (idx_ == cm_.end())
|
||||
return false;
|
||||
|
||||
inp = (*idx_).first;
|
||||
out = (*idx_).second;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetUDP_COMB::next(string&inp, char&out) const
|
||||
{
|
||||
idx_ ++;
|
||||
if (idx_ == cm_.end())
|
||||
return false;
|
||||
|
||||
inp = (*idx_).first;
|
||||
out = (*idx_).second;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: net_udp.cc,v $
|
||||
* Revision 1.1 2000/03/29 04:37:11 steve
|
||||
* New and improved combinational primitives.
|
||||
*
|
||||
*/
|
||||
|
||||
156
netlist.cc
156
netlist.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: netlist.cc,v 1.108 2000/03/12 17:09:41 steve Exp $"
|
||||
#ident "$Id: netlist.cc,v 1.109 2000/03/29 04:37:11 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <cassert>
|
||||
|
|
@ -2374,31 +2374,6 @@ NetNet* NetTaskDef::port(unsigned idx)
|
|||
return ports_[idx];
|
||||
}
|
||||
|
||||
NetUDP::NetUDP(const string&n, unsigned pins, bool sequ)
|
||||
: NetNode(n, pins), sequential_(sequ), init_('x')
|
||||
{
|
||||
pin(0).set_dir(Link::OUTPUT);
|
||||
for (unsigned idx = 1 ; idx < pins ; idx += 1)
|
||||
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
|
||||
|
|
@ -2546,106 +2521,11 @@ bool NetUDP::sequ_glob_(string input, char output)
|
|||
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. */
|
||||
cm_[input] = output;
|
||||
|
||||
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:;
|
||||
}
|
||||
}
|
||||
|
||||
char NetUDP::table_lookup(const string&from, char to, unsigned pin) const
|
||||
{
|
||||
assert(pin <= pin_count());
|
||||
assert(from.length() == pin_count());
|
||||
FSM_::const_iterator idx = fsm_.find(from);
|
||||
if (idx == fsm_.end())
|
||||
return 'x';
|
||||
|
||||
state_t_*next;
|
||||
switch (to) {
|
||||
case '0':
|
||||
next = (*idx).second->pins[pin].zer;
|
||||
break;
|
||||
case '1':
|
||||
next = (*idx).second->pins[pin].one;
|
||||
break;
|
||||
case 'x':
|
||||
next = (*idx).second->pins[pin].xxx;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
next = 0;
|
||||
}
|
||||
|
||||
return next? next->out : 'x';
|
||||
}
|
||||
|
||||
void NetUDP::set_initial(char val)
|
||||
{
|
||||
assert(sequential_);
|
||||
assert((val == '0') || (val == '1') || (val == 'x'));
|
||||
init_ = val;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: netlist.cc,v $
|
||||
* Revision 1.109 2000/03/29 04:37:11 steve
|
||||
* New and improved combinational primitives.
|
||||
*
|
||||
* Revision 1.108 2000/03/12 17:09:41 steve
|
||||
* Support localparam.
|
||||
*
|
||||
|
|
@ -2670,33 +2550,5 @@ void NetUDP::set_initial(char val)
|
|||
*
|
||||
* Revision 1.102 1999/12/30 04:19:12 steve
|
||||
* Propogate constant 0 in low bits of adders.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Revision 1.99 1999/12/05 19:30:43 steve
|
||||
* Generate XNF RAMS from synthesized memories.
|
||||
*
|
||||
* Revision 1.98 1999/12/05 02:24:09 steve
|
||||
* Synthesize LPM_RAM_DQ for writes into memories.
|
||||
*
|
||||
* Revision 1.97 1999/12/02 16:58:58 steve
|
||||
* Update case comparison (Eric Aardoom).
|
||||
*
|
||||
* Revision 1.96 1999/11/28 23:42:02 steve
|
||||
* NetESignal object no longer need to be NetNode
|
||||
* objects. Let them keep a pointer to NetNet objects.
|
||||
*
|
||||
* Revision 1.95 1999/11/28 01:16:18 steve
|
||||
* gate outputs need to set signal values.
|
||||
*
|
||||
* Revision 1.94 1999/11/27 19:07:57 steve
|
||||
* Support the creation of scopes.
|
||||
*
|
||||
* Revision 1.93 1999/11/24 04:01:59 steve
|
||||
* Detect and list scope names.
|
||||
*/
|
||||
|
||||
|
|
|
|||
38
netlist.h
38
netlist.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: netlist.h,v 1.114 2000/03/12 17:09:41 steve Exp $"
|
||||
#ident "$Id: netlist.h,v 1.115 2000/03/29 04:37:11 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -919,6 +919,39 @@ class NetUDP : public NetNode {
|
|||
void dump_comb_(ostream&o, unsigned ind) const;
|
||||
};
|
||||
|
||||
class NetUDP_COMB : public NetNode {
|
||||
|
||||
public:
|
||||
explicit NetUDP_COMB(const string&n, unsigned pins);
|
||||
|
||||
virtual void emit_node(ostream&, struct target_t*) const;
|
||||
virtual void dump_node(ostream&, unsigned ind) const;
|
||||
|
||||
/* append a new truth table row. */
|
||||
void set_table(const string&input, char output);
|
||||
|
||||
/* After the primitive is built up, this method is called to
|
||||
clean up redundancies, and possibly optimize the table. */
|
||||
void cleanup_table();
|
||||
|
||||
/* Use these methods to scan the truth table of the
|
||||
device. "first" returns the first item in the table, and
|
||||
"next" returns the next item in the table. The method will
|
||||
return false when the scan is done. */
|
||||
bool first(string&inp, char&out) const;
|
||||
bool next(string&inp, char&out) const;
|
||||
|
||||
private:
|
||||
|
||||
// A combinational primitive is more simply represented as a
|
||||
// simple map of input signals to a single output.
|
||||
map<string,char> cm_;
|
||||
|
||||
mutable map<string,char>::const_iterator idx_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* =========
|
||||
* A process is a behavioral-model description. A process is a
|
||||
* statement that may be compound. the various statement types may
|
||||
|
|
@ -2195,6 +2228,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
|
|||
|
||||
/*
|
||||
* $Log: netlist.h,v $
|
||||
* Revision 1.115 2000/03/29 04:37:11 steve
|
||||
* New and improved combinational primitives.
|
||||
*
|
||||
* Revision 1.114 2000/03/12 17:09:41 steve
|
||||
* Support localparam.
|
||||
*
|
||||
|
|
|
|||
54
t-vvm.cc
54
t-vvm.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: t-vvm.cc,v 1.126 2000/03/26 16:28:31 steve Exp $"
|
||||
#ident "$Id: t-vvm.cc,v 1.127 2000/03/29 04:37:11 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <iostream>
|
||||
|
|
@ -73,6 +73,8 @@ class target_vvm : public target_t {
|
|||
virtual void logic(ostream&os, const NetLogic*);
|
||||
virtual void bufz(ostream&os, const NetBUFZ*);
|
||||
virtual void udp(ostream&os, const NetUDP*);
|
||||
virtual void udp_comb(ostream&os, const NetUDP_COMB*);
|
||||
void udp_sequ_(ostream&os, const NetUDP*);
|
||||
virtual void net_assign_nb(ostream&os, const NetAssignNB*);
|
||||
virtual void net_case_cmp(ostream&os, const NetCaseCmp*);
|
||||
virtual void net_const(ostream&os, const NetConst*);
|
||||
|
|
@ -1527,6 +1529,47 @@ void target_vvm::bufz(ostream&os, const NetBUFZ*gate)
|
|||
|
||||
}
|
||||
|
||||
void target_vvm::udp_comb(ostream&os, const NetUDP_COMB*gate)
|
||||
{
|
||||
string mname = mangle(gate->name());
|
||||
string nexus;
|
||||
unsigned ncode;
|
||||
|
||||
|
||||
os << "static const char*" << mname << "_ctab =" << endl;
|
||||
|
||||
string inp;
|
||||
char out;
|
||||
for (bool rc = gate->first(inp, out)
|
||||
; rc ; rc = gate->next(inp,out)) {
|
||||
|
||||
os << " \"" << inp << out << "\"" << endl;
|
||||
}
|
||||
os << " ;" << endl;
|
||||
|
||||
os << "static vvm_udp_comb " << mname << "("
|
||||
<< (gate->pin_count()-1) << ", " << mname<<"_ctab);" << endl;
|
||||
|
||||
/* Connect the output of the device... */
|
||||
nexus = nexus_from_link(&gate->pin(0));
|
||||
ncode = nexus_wire_map[nexus];
|
||||
init_code << " nexus_wire_table["<<ncode<<"].connect(&" <<
|
||||
mname << ");" << endl;
|
||||
|
||||
/* Connect the inputs of the device... */
|
||||
for (unsigned idx = 1 ; idx < gate->pin_count() ; idx += 1) {
|
||||
if (! gate->pin(idx).is_linked())
|
||||
continue;
|
||||
|
||||
nexus = nexus_from_link(&gate->pin(idx));
|
||||
ncode = nexus_wire_map[nexus];
|
||||
|
||||
init_code << " nexus_wire_table["<<ncode<<"].connect(&"
|
||||
<< mname << "," << (idx-1) << ");" << endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static string state_to_string(unsigned state, unsigned npins)
|
||||
{
|
||||
static const char cur_table[3] = { '0', '1', 'x' };
|
||||
|
|
@ -1541,6 +1584,12 @@ static string state_to_string(unsigned state, unsigned npins)
|
|||
}
|
||||
|
||||
void target_vvm::udp(ostream&os, const NetUDP*gate)
|
||||
{
|
||||
assert(gate->is_sequential());
|
||||
udp_sequ_(os, gate);
|
||||
}
|
||||
|
||||
void target_vvm::udp_sequ_(ostream&os, const NetUDP*gate)
|
||||
{
|
||||
assert(gate->pin_count() <= 9);
|
||||
assert(gate->is_sequential());
|
||||
|
|
@ -2440,6 +2489,9 @@ extern const struct target tgt_vvm = {
|
|||
};
|
||||
/*
|
||||
* $Log: t-vvm.cc,v $
|
||||
* Revision 1.127 2000/03/29 04:37:11 steve
|
||||
* New and improved combinational primitives.
|
||||
*
|
||||
* Revision 1.126 2000/03/26 16:28:31 steve
|
||||
* vvm_bitset_t is no longer a template.
|
||||
*
|
||||
|
|
|
|||
11
target.cc
11
target.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: target.cc,v 1.30 2000/02/23 02:56:56 steve Exp $"
|
||||
#ident "$Id: target.cc,v 1.31 2000/03/29 04:37:11 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "target.h"
|
||||
|
|
@ -73,6 +73,12 @@ void target_t::udp(ostream&os, const NetUDP*)
|
|||
"Unhandled UDP." << endl;
|
||||
}
|
||||
|
||||
void target_t::udp_comb(ostream&os, const NetUDP_COMB*)
|
||||
{
|
||||
cerr << "target (" << typeid(*this).name() << "): "
|
||||
"Unhandled combinational primitive." << endl;
|
||||
}
|
||||
|
||||
void target_t::lpm_add_sub(ostream&, const NetAddSub*)
|
||||
{
|
||||
cerr << "target (" << typeid(*this).name() << "): "
|
||||
|
|
@ -314,6 +320,9 @@ void expr_scan_t::expr_binary(const NetEBinary*ex)
|
|||
|
||||
/*
|
||||
* $Log: target.cc,v $
|
||||
* Revision 1.31 2000/03/29 04:37:11 steve
|
||||
* New and improved combinational primitives.
|
||||
*
|
||||
* Revision 1.30 2000/02/23 02:56:56 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
|
|
|
|||
6
target.h
6
target.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: target.h,v 1.29 2000/02/23 02:56:56 steve Exp $"
|
||||
#ident "$Id: target.h,v 1.30 2000/03/29 04:37:11 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "netlist.h"
|
||||
|
|
@ -82,6 +82,7 @@ struct target_t {
|
|||
virtual void logic(ostream&os, const NetLogic*);
|
||||
virtual void bufz(ostream&os, const NetBUFZ*);
|
||||
virtual void udp(ostream&os, const NetUDP*);
|
||||
virtual void udp_comb(ostream&os, const NetUDP_COMB*);
|
||||
virtual void net_assign(ostream&os, const NetAssign*);
|
||||
virtual void net_assign_nb(ostream&os, const NetAssignNB*);
|
||||
virtual void net_case_cmp(ostream&os, const NetCaseCmp*);
|
||||
|
|
@ -147,6 +148,9 @@ extern const struct target *target_table[];
|
|||
|
||||
/*
|
||||
* $Log: target.h,v $
|
||||
* Revision 1.30 2000/03/29 04:37:11 steve
|
||||
* New and improved combinational primitives.
|
||||
*
|
||||
* Revision 1.29 2000/02/23 02:56:56 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.26 2000/03/22 05:16:38 steve Exp $"
|
||||
#ident "$Id: Makefile.in,v 1.27 2000/03/29 04:37:11 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
|
@ -61,7 +61,7 @@ all: libvvm.a
|
|||
O = vvm_add_sub.o vvm_bit.o vvm_calltf.o vvm_clshift.o vvm_compare.o \
|
||||
vvm_event.o vvm_ff.o \
|
||||
vvm_func.o vvm_gates.o vvm_mult.o vvm_mux.o \
|
||||
vvm_nexus.o vvm_pevent.o vvm_signal.o vvm_thread.o vpip.o
|
||||
vvm_nexus.o vvm_pevent.o vvm_signal.o vvm_thread.o vvm_udp.o vpip.o
|
||||
|
||||
P = vpi_bit.o vpi_callback.o \
|
||||
vpi_const.o vpi_iter.o vpi_memory.o vpi_null.o \
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: vvm_gates.h,v 1.52 2000/03/26 16:28:31 steve Exp $"
|
||||
#ident "$Id: vvm_gates.h,v 1.53 2000/03/29 04:37:11 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vvm.h"
|
||||
|
|
@ -640,6 +640,49 @@ class vvm_eeq : public vvm_1bit_out, public vvm_nexus::recvr_t {
|
|||
vpip_bit_t input_[2];
|
||||
};
|
||||
|
||||
/*
|
||||
* This class allows programmers to define combinational primitives at
|
||||
* truth tables. The device has a single bit output, and any fixed
|
||||
* width.
|
||||
*
|
||||
* The truth table is specified as a string of characters organized as
|
||||
* a table. Every width+1 characters represents one row, including the
|
||||
* set of inputs and the output that they generated. There can be any
|
||||
* number of rows in the table, which is terminated by a nul byte. The
|
||||
* table is passed to the constructor as a constant string.
|
||||
*
|
||||
* This is a simple example of a truth table for an inverter. The
|
||||
* width is 1, so there are two characters in each row. The last
|
||||
* character in each row is the output if all the other characters in
|
||||
* the row match the input. As you can see, this table inverts its
|
||||
* input and outputs 'x' if the input is unknown.
|
||||
*
|
||||
* const char*invert_table =
|
||||
* "01"
|
||||
* "10"
|
||||
* "xx";
|
||||
*
|
||||
* The valid input characters are '0', '1' and 'x'. The valid output
|
||||
* characters are '0', '1', 'x' and 'z'. (The last is not supported by
|
||||
* Verilog primitives, so ivl will never generate it.)
|
||||
*/
|
||||
class vvm_udp_comb : public vvm_1bit_out, public vvm_nexus::recvr_t {
|
||||
|
||||
public:
|
||||
explicit vvm_udp_comb(unsigned w, const char*t);
|
||||
~vvm_udp_comb();
|
||||
|
||||
void init_I(unsigned idx, vpip_bit_t val);
|
||||
void start();
|
||||
|
||||
private:
|
||||
void take_value(unsigned key, vpip_bit_t val);
|
||||
vpip_bit_t*ibits_;
|
||||
|
||||
unsigned width_;
|
||||
const char*table_;
|
||||
};
|
||||
|
||||
/*
|
||||
* A Sequential UDP has a more complex truth table, and handles
|
||||
* edges. Pin 0 is an output, and all the remaining pins are
|
||||
|
|
@ -796,6 +839,9 @@ template <unsigned WIDTH> class vvm_pevent : public vvm_nexus::recvr_t {
|
|||
|
||||
/*
|
||||
* $Log: vvm_gates.h,v $
|
||||
* Revision 1.53 2000/03/29 04:37:11 steve
|
||||
* New and improved combinational primitives.
|
||||
*
|
||||
* Revision 1.52 2000/03/26 16:28:31 steve
|
||||
* vvm_bitset_t is no longer a template.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright (c) 2000 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) && !defined(macintosh)
|
||||
#ident "$Id: vvm_udp.cc,v 1.1 2000/03/29 04:37:11 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vvm_gates.h"
|
||||
|
||||
vvm_udp_comb::vvm_udp_comb(unsigned w, const char*t)
|
||||
: vvm_1bit_out(0), width_(w), table_(t)
|
||||
{
|
||||
ibits_ = new vpip_bit_t[width_];
|
||||
}
|
||||
|
||||
vvm_udp_comb::~vvm_udp_comb()
|
||||
{
|
||||
delete[]ibits_;
|
||||
}
|
||||
|
||||
void vvm_udp_comb::init_I(unsigned idx, vpip_bit_t val)
|
||||
{
|
||||
assert(idx < width_);
|
||||
ibits_[idx] = val;
|
||||
}
|
||||
|
||||
void vvm_udp_comb::take_value(unsigned key, vpip_bit_t val)
|
||||
{
|
||||
if (ibits_[key] == val)
|
||||
return;
|
||||
|
||||
ibits_[key] = val;
|
||||
char bit;
|
||||
if (B_IS1(val))
|
||||
bit = '1';
|
||||
else if (B_IS0(val))
|
||||
bit = '0';
|
||||
else
|
||||
bit = 'x';
|
||||
|
||||
|
||||
for (const char*row = table_ ; row[0] ; row += width_+1) {
|
||||
|
||||
unsigned idx;
|
||||
for (idx = 0 ; idx < width_ ; idx += 1)
|
||||
if (row[idx] != bit)
|
||||
break;
|
||||
|
||||
if (idx == width_) switch (row[width_]) {
|
||||
|
||||
case '0':
|
||||
output(St0);
|
||||
return;
|
||||
case '1':
|
||||
output(St1);
|
||||
return;
|
||||
case 'z':
|
||||
output(HiZ);
|
||||
return;
|
||||
default:
|
||||
output(StX);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
output(StX);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* $Log: vvm_udp.cc,v $
|
||||
* Revision 1.1 2000/03/29 04:37:11 steve
|
||||
* New and improved combinational primitives.
|
||||
*
|
||||
*/
|
||||
|
||||
Loading…
Reference in New Issue