Structural case equals device.

This commit is contained in:
steve 1999-10-10 01:59:54 +00:00
parent 7201865554
commit 70a1236626
10 changed files with 235 additions and 12 deletions

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.49 1999/10/08 02:00:35 steve Exp $"
#ident "$Id: design_dump.cc,v 1.50 1999/10/10 01:59:54 steve Exp $"
#endif
/*
@ -153,6 +153,12 @@ void NetBUFZ::dump_node(ostream&o, unsigned ind) const
dump_node_pins(o, ind+4);
}
void NetCaseCmp::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "case compare === : " << name() << endl;
dump_node_pins(o, ind+4);
}
void NetConst::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "constant " << value_ << ": " << name() << endl;
@ -789,6 +795,9 @@ void Design::dump(ostream&o) const
/*
* $Log: design_dump.cc,v $
* Revision 1.50 1999/10/10 01:59:54 steve
* Structural case equals device.
*
* Revision 1.49 1999/10/08 02:00:35 steve
* Fix dump of sase statements.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: elaborate.cc,v 1.115 1999/10/09 21:30:16 steve Exp $"
#ident "$Id: elaborate.cc,v 1.116 1999/10/10 01:59:54 steve Exp $"
#endif
/*
@ -720,6 +720,76 @@ NetNet* PEBinary::elaborate_net(Design*des, const string&path,
des->add_signal(osig);
break;
case 'a': // && (logical AND)
gate = new NetLogic(des->local_symbol(path), 3, NetLogic::AND);
// The first OR gate returns 1 if the left value is true...
if (lsig->pin_count() > 1) {
gate_t = new NetLogic(des->local_symbol(path),
1+lsig->pin_count(), NetLogic::OR);
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1)
connect(gate_t->pin(idx+1), lsig->pin(idx));
connect(gate->pin(1), gate_t->pin(0));
des->add_node(gate_t);
} else {
connect(gate->pin(1), lsig->pin(0));
}
// The second OR gate returns 1 if the right value is true...
if (rsig->pin_count() > 1) {
gate_t = new NetLogic(des->local_symbol(path),
1+rsig->pin_count(), NetLogic::OR);
for (unsigned idx = 0 ; idx < rsig->pin_count() ; idx += 1)
connect(gate_t->pin(idx+1), rsig->pin(idx));
connect(gate->pin(2), gate_t->pin(0));
des->add_node(gate_t);
} else {
connect(gate->pin(2), rsig->pin(0));
}
// The output is the AND of the two logic values.
osig = new NetNet(des->local_symbol(path), NetNet::WIRE);
osig->local_flag(true);
connect(gate->pin(0), osig->pin(0));
des->add_signal(osig);
gate->rise_time(rise);
gate->fall_time(fall);
gate->decay_time(decay);
des->add_node(gate);
break;
case 'E': // === (Case equals)
// The comparison generates gates to bitwise compare
// each pair, and AND all the comparison results.
assert(lsig->pin_count() == rsig->pin_count());
osig = new NetNet(des->local_symbol(path), NetNet::WIRE);
osig->local_flag(true);
gate = new NetLogic(des->local_symbol(path),
1+lsig->pin_count(),
NetLogic::AND);
connect(gate->pin(0), osig->pin(0));
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1) {
gate_t = new NetCaseCmp(des->local_symbol(path));
connect(gate_t->pin(1), lsig->pin(idx));
connect(gate_t->pin(2), rsig->pin(idx));
connect(gate_t->pin(0), gate->pin(idx+1));
des->add_node(gate_t);
// Attach a label to this intermediate wire
NetNet*tmp = new NetNet(des->local_symbol(path),
NetNet::WIRE);
tmp->local_flag(true);
connect(gate_t->pin(0), tmp->pin(0));
des->add_signal(tmp);
}
des->add_signal(osig);
gate->rise_time(rise);
gate->fall_time(fall);
gate->decay_time(decay);
des->add_node(gate);
break;
case 'e': // ==
assert(lsig->pin_count() == rsig->pin_count());
osig = new NetNet(des->local_symbol(path), NetNet::WIRE);
@ -2614,6 +2684,9 @@ Design* elaborate(const map<string,Module*>&modules,
/*
* $Log: elaborate.cc,v $
* Revision 1.116 1999/10/10 01:59:54 steve
* Structural case equals device.
*
* Revision 1.115 1999/10/09 21:30:16 steve
* Support parameters in continuous assignments.
*

10
emit.cc
View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: emit.cc,v 1.23 1999/09/22 16:57:23 steve Exp $"
#ident "$Id: emit.cc,v 1.24 1999/10/10 01:59:54 steve Exp $"
#endif
/*
@ -60,6 +60,11 @@ void NetAssignNB::emit_node(ostream&o, struct target_t*tgt) const
tgt->net_assign_nb(o, this);
}
void NetCaseCmp::emit_node(ostream&o, struct target_t*tgt) const
{
tgt->net_case_cmp(o, this);
}
void NetConst::emit_node(ostream&o, struct target_t*tgt) const
{
tgt->net_const(o, this);
@ -352,6 +357,9 @@ bool emit(ostream&o, const Design*des, const char*type)
/*
* $Log: emit.cc,v $
* Revision 1.24 1999/10/10 01:59:54 steve
* Structural case equals device.
*
* Revision 1.23 1999/09/22 16:57:23 steve
* Catch parallel blocks in vvm emit.
*

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.75 1999/10/07 05:25:34 steve Exp $"
#ident "$Id: netlist.cc,v 1.76 1999/10/10 01:59:55 steve Exp $"
#endif
# include <cassert>
@ -599,6 +599,18 @@ void NetCase::set_case(unsigned idx, NetExpr*e, NetProc*p)
items_[idx].guard->set_width(expr_->expr_width());
}
NetCaseCmp::NetCaseCmp(const string&n)
: NetNode(n, 3)
{
pin(0).set_dir(Link::OUTPUT);
pin(1).set_dir(Link::INPUT);
pin(2).set_dir(Link::INPUT);
}
NetCaseCmp::~NetCaseCmp()
{
}
NetCondit::NetCondit(NetExpr*ex, NetProc*i, NetProc*e)
: expr_(ex), if_(i), else_(e)
{
@ -631,6 +643,16 @@ NetProc* NetCondit::else_clause()
return else_;
}
NetConst::NetConst(const string&n, verinum::V v)
: NetNode(n, 1), value_(v)
{
pin(0).set_dir(Link::OUTPUT);
}
NetConst::~NetConst()
{
}
NetFuncDef::NetFuncDef(const string&n, const svector<NetNet*>&po)
: name_(n), statement_(0), ports_(po)
{
@ -1732,6 +1754,9 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*))
/*
* $Log: netlist.cc,v $
* Revision 1.76 1999/10/10 01:59:55 steve
* Structural case equals device.
*
* Revision 1.75 1999/10/07 05:25:34 steve
* Add non-const bit select in l-value of assignment.
*

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.78 1999/10/07 05:25:34 steve Exp $"
#ident "$Id: netlist.h,v 1.79 1999/10/10 01:59:55 steve Exp $"
#endif
/*
@ -431,11 +431,33 @@ class NetBUFZ : public NetNode {
virtual void emit_node(ostream&, struct target_t*) const;
};
/*
* This node is used to represent case equality in combinational
* logic. Although this is not normally synthesizeable, it makes sense
* to support an abstract gate that can compare x and z.
*
* This pins are assigned as:
*
* 0 -- Output (always returns 0 or 1)
* 1 -- Input
* 2 -- Input
*/
class NetCaseCmp : public NetNode {
public:
explicit NetCaseCmp(const string&n);
~NetCaseCmp();
virtual void dump_node(ostream&, unsigned ind) const;
virtual void emit_node(ostream&, struct target_t*) const;
};
class NetConst : public NetNode {
public:
explicit NetConst(const string&n, verinum::V v)
: NetNode(n, 1), value_(v) { pin(0).set_dir(Link::OUTPUT); }
explicit NetConst(const string&n, verinum::V v);
~NetConst();
verinum::V value() const { return value_; }
@ -1711,6 +1733,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
* Revision 1.79 1999/10/10 01:59:55 steve
* Structural case equals device.
*
* Revision 1.78 1999/10/07 05:25:34 steve
* Add non-const bit select in l-value of assignment.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: pform_dump.cc,v 1.44 1999/09/30 02:43:02 steve Exp $"
#ident "$Id: pform_dump.cc,v 1.45 1999/10/10 01:59:55 steve Exp $"
#endif
/*
@ -132,6 +132,9 @@ void PEBinary::dump(ostream&out) const
{
out << "(" << *left_ << ")";
switch (op_) {
case 'a':
out << "&&";
break;
case 'e':
out << "==";
break;
@ -672,6 +675,9 @@ void PUdp::dump(ostream&out) const
/*
* $Log: pform_dump.cc,v $
* Revision 1.45 1999/10/10 01:59:55 steve
* Structural case equals device.
*
* Revision 1.44 1999/09/30 02:43:02 steve
* Elaborate ~^ and ~| operators.
*

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.61 1999/10/08 02:00:48 steve Exp $"
#ident "$Id: t-vvm.cc,v 1.62 1999/10/10 01:59:55 steve Exp $"
#endif
# include <iostream>
@ -55,6 +55,7 @@ class target_vvm : public target_t {
virtual void bufz(ostream&os, const NetBUFZ*);
virtual void udp(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*);
virtual void net_esignal(ostream&os, const NetESignal*);
virtual void net_event(ostream&os, const NetNEvent*);
@ -1008,6 +1009,22 @@ void target_vvm::net_assign_nb(ostream&os, const NetAssignNB*net)
delayed << "}" << endl;
}
void target_vvm::net_case_cmp(ostream&os, const NetCaseCmp*gate)
{
os << "static void " << mangle(gate->name()) <<
"_output_fun(vvm_simulation*, vvm_bit_t);" << endl;
assert(gate->pin_count() == 3);
os << "static vvm_eeq" << "<" << gate->rise_time() << "> "
<< mangle(gate->name()) << "(&" << mangle(gate->name()) <<
"_output_fun);" << endl;
emit_gate_outputfun_(gate);
start_code << " " << mangle(gate->name()) <<
".start(&sim);" << endl;
}
/*
* The NetConst is a synthetic device created to represent constant
* values. I represent them in the output as a vvm_bufz object that
@ -1727,6 +1744,9 @@ extern const struct target tgt_vvm = {
};
/*
* $Log: t-vvm.cc,v $
* Revision 1.62 1999/10/10 01:59:55 steve
* Structural case equals device.
*
* Revision 1.61 1999/10/08 02:00:48 steve
* vvm supports unary | operator.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: target.cc,v 1.20 1999/09/22 16:57:24 steve Exp $"
#ident "$Id: target.cc,v 1.21 1999/10/10 01:59:55 steve Exp $"
#endif
# include "target.h"
@ -85,6 +85,12 @@ void target_t::net_assign_nb(ostream&os, const NetAssignNB*)
"Unhandled non-blocking assignment node." << endl;
}
void target_t::net_case_cmp(ostream&os, const NetCaseCmp*)
{
cerr << "target (" << typeid(*this).name() << "): "
"Unhandled case compare node." << endl;
}
void target_t::net_const(ostream&os, const NetConst*)
{
cerr << "target (" << typeid(*this).name() << "): "
@ -269,6 +275,9 @@ void expr_scan_t::expr_binary(const NetEBinary*ex)
/*
* $Log: target.cc,v $
* Revision 1.21 1999/10/10 01:59:55 steve
* Structural case equals device.
*
* Revision 1.20 1999/09/22 16:57:24 steve
* Catch parallel blocks in vvm emit.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: target.h,v 1.19 1999/09/22 16:57:24 steve Exp $"
#ident "$Id: target.h,v 1.20 1999/10/10 01:59:55 steve Exp $"
#endif
# include "netlist.h"
@ -74,6 +74,7 @@ struct target_t {
virtual void udp(ostream&os, const NetUDP*);
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*);
virtual void net_const(ostream&os, const NetConst*);
virtual void net_esignal(ostream&os, const NetESignal*);
virtual void net_event(ostream&os, const NetNEvent*);
@ -136,6 +137,9 @@ extern const struct target *target_table[];
/*
* $Log: target.h,v $
* Revision 1.20 1999/10/10 01:59:55 steve
* Structural case equals device.
*
* Revision 1.19 1999/09/22 16:57:24 steve
* Catch parallel blocks in vvm emit.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
#ident "$Id: vvm_gates.h,v 1.13 1999/10/09 19:24:36 steve Exp $"
#ident "$Id: vvm_gates.h,v 1.14 1999/10/10 01:59:55 steve Exp $"
#endif
# include "vvm.h"
@ -346,6 +346,47 @@ template <unsigned WIDTH, unsigned long DELAY> class vvm_xor {
vvm_out_event::action_t output_;
};
/*
* This gate has only 3 pins, the output at pin 0 and two inputs. The
* output is 1 or 0 if the two inputs are exactly equal or not.
*/
template <unsigned long DELAY> class vvm_eeq {
public:
explicit vvm_eeq(vvm_out_event::action_t o)
: output_(o) { }
void init(unsigned idx, vvm_bit_t val)
{ input_[idx-1] = val; }
void start(vvm_simulation*sim)
{ vvm_event*ev = new vvm_out_event(sim, compute_(), output_);
if (DELAY > 0)
sim->insert_event(DELAY, ev);
else
sim->active_event(ev);
}
void set(vvm_simulation*sim, unsigned idx, vvm_bit_t val)
{ if (input_[idx-1] == val)
return;
input_[idx-1] = val;
start(sim);
}
private:
vvm_bit_t compute_() const
{ vvm_bit_t outval = V0;
if (input_[0] == input_[1])
outval = V1;
return outval;
}
vvm_bit_t input_[2];
vvm_out_event::action_t output_;
};
/*
* A Sequential UDP has a more complex truth table, and handles
* edges. Pin 0 is an output, and all the remaining pins are
@ -496,6 +537,9 @@ template <unsigned WIDTH> class vvm_pevent {
/*
* $Log: vvm_gates.h,v $
* Revision 1.14 1999/10/10 01:59:55 steve
* Structural case equals device.
*
* Revision 1.13 1999/10/09 19:24:36 steve
* NOR device.
*