Support combinatorial comparators.

This commit is contained in:
steve 1999-11-14 23:43:45 +00:00
parent 1624afe1ba
commit 513ade9b95
9 changed files with 377 additions and 131 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.56 1999/11/14 20:24:28 steve Exp $"
#ident "$Id: design_dump.cc,v 1.57 1999/11/14 23:43:45 steve Exp $"
#endif
/*
@ -138,6 +138,14 @@ void NetCLShift::dump_node(ostream&o, unsigned ind) const
dump_obj_attr(o, ind+4);
}
void NetCompare::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "LPM_COMPARE (NetCompare): " <<
name() << endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
}
void NetMux::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "Multiplexer (NetMux): " << name() << endl;
@ -826,6 +834,9 @@ void Design::dump(ostream&o) const
/*
* $Log: design_dump.cc,v $
* Revision 1.57 1999/11/14 23:43:45 steve
* Support combinatorial comparators.
*
* Revision 1.56 1999/11/14 20:24:28 steve
* Add support for the LPM_CLSHIFT device.
*

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.5 1999/11/14 20:24:28 steve Exp $"
#ident "$Id: elab_net.cc,v 1.6 1999/11/14 23:43:45 steve Exp $"
#endif
# include "PExpr.h"
@ -41,6 +41,10 @@ NetNet* PEBinary::elaborate_net(Design*des, const string&path,
case 'E':
case 'e':
case 'n':
case '<':
case '>':
case 'L': // <=
case 'G': // >=
return elaborate_net_cmp_(des, path, width, rise, fall, decay);
case 'l': // <<
case 'r': // >>
@ -165,6 +169,10 @@ NetNet* PEBinary::elaborate_net(Design*des, const string&path,
case 'E': // === (Case equals)
case 'e': // ==
case 'n': // !=
case '<':
case '>':
case 'G': // >=
case 'L': // <=
assert(0);
break;
@ -305,6 +313,34 @@ NetNet* PEBinary::elaborate_net_cmp_(Design*des, const string&path,
NetNode*gate_t;
switch (op_) {
case '<':
case '>':
case 'L':
case 'G': {
NetCompare*cmp = new NetCompare(des->local_symbol(path),
lsig->pin_count());
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1) {
connect(cmp->pin_DataA(idx), lsig->pin(idx));
connect(cmp->pin_DataB(idx), rsig->pin(idx));
}
switch (op_) {
case '<':
connect(cmp->pin_ALB(), osig->pin(0));
break;
case '>':
connect(cmp->pin_AGB(), osig->pin(0));
break;
case 'L':
connect(cmp->pin_ALEB(), osig->pin(0));
break;
case 'G':
connect(cmp->pin_AGEB(), osig->pin(0));
break;
}
gate = cmp;
break;
}
case 'E': // Case equals (===)
// The comparison generates gates to bitwise compare
// each pair, and AND all the comparison results.
@ -528,6 +564,9 @@ NetNet* PETernary::elaborate_net(Design*des, const string&path,
/*
* $Log: elab_net.cc,v $
* Revision 1.6 1999/11/14 23:43:45 steve
* Support combinatorial comparators.
*
* Revision 1.5 1999/11/14 20:24:28 steve
* Add support for the LPM_CLSHIFT device.
*

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.27 1999/11/14 20:24:28 steve Exp $"
#ident "$Id: emit.cc,v 1.28 1999/11/14 23:43:45 steve Exp $"
#endif
/*
@ -70,6 +70,11 @@ void NetCLShift::emit_node(ostream&o, struct target_t*tgt) const
tgt->lpm_clshift(o, this);
}
void NetCompare::emit_node(ostream&o, struct target_t*tgt) const
{
tgt->lpm_compare(o, this);
}
void NetConst::emit_node(ostream&o, struct target_t*tgt) const
{
tgt->net_const(o, this);
@ -372,6 +377,9 @@ bool emit(ostream&o, const Design*des, const char*type)
/*
* $Log: emit.cc,v $
* Revision 1.28 1999/11/14 23:43:45 steve
* Support combinatorial comparators.
*
* Revision 1.27 1999/11/14 20:24:28 steve
* Add support for the LPM_CLSHIFT device.
*

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.85 1999/11/14 20:24:28 steve Exp $"
#ident "$Id: netlist.cc,v 1.86 1999/11/14 23:43:45 steve Exp $"
#endif
# include <cassert>
@ -700,6 +700,134 @@ const NetObj::Link& NetCLShift::pin_Distance(unsigned idx) const
return pin(3+2*width_+idx);
}
NetCompare::NetCompare(const string&n, unsigned wi)
: NetNode(n, 8+2*wi), width_(wi)
{
pin(0).set_dir(NetObj::Link::INPUT); pin(0).set_name("Aclr");
pin(1).set_dir(NetObj::Link::INPUT); pin(1).set_name("Clock");
pin(2).set_dir(NetObj::Link::OUTPUT); pin(2).set_name("AGB");
pin(3).set_dir(NetObj::Link::OUTPUT); pin(3).set_name("AGEB");
pin(4).set_dir(NetObj::Link::OUTPUT); pin(4).set_name("AEB");
pin(5).set_dir(NetObj::Link::OUTPUT); pin(5).set_name("ANEB");
pin(6).set_dir(NetObj::Link::OUTPUT); pin(6).set_name("ALB");
pin(7).set_dir(NetObj::Link::OUTPUT); pin(7).set_name("ALEB");
for (unsigned idx = 0 ; idx < width_ ; idx += 1) {
pin(8+idx).set_dir(NetObj::Link::INPUT);
pin(8+idx).set_name("DataA", idx);
pin(8+width_+idx).set_dir(NetObj::Link::INPUT);
pin(8+width_+idx).set_name("DataB", idx);
}
}
NetCompare::~NetCompare()
{
}
unsigned NetCompare::width() const
{
return width_;
}
NetObj::Link& NetCompare::pin_Aclr()
{
return pin(0);
}
const NetObj::Link& NetCompare::pin_Aclr() const
{
return pin(0);
}
NetObj::Link& NetCompare::pin_Clock()
{
return pin(1);
}
const NetObj::Link& NetCompare::pin_Clock() const
{
return pin(1);
}
NetObj::Link& NetCompare::pin_AGB()
{
return pin(2);
}
const NetObj::Link& NetCompare::pin_AGB() const
{
return pin(2);
}
NetObj::Link& NetCompare::pin_AGEB()
{
return pin(3);
}
const NetObj::Link& NetCompare::pin_AGEB() const
{
return pin(3);
}
NetObj::Link& NetCompare::pin_AEB()
{
return pin(4);
}
const NetObj::Link& NetCompare::pin_AEB() const
{
return pin(4);
}
NetObj::Link& NetCompare::pin_ANEB()
{
return pin(5);
}
const NetObj::Link& NetCompare::pin_ANEB() const
{
return pin(5);
}
NetObj::Link& NetCompare::pin_ALB()
{
return pin(6);
}
const NetObj::Link& NetCompare::pin_ALB() const
{
return pin(6);
}
NetObj::Link& NetCompare::pin_ALEB()
{
return pin(7);
}
const NetObj::Link& NetCompare::pin_ALEB() const
{
return pin(7);
}
NetObj::Link& NetCompare::pin_DataA(unsigned idx)
{
return pin(8+idx);
}
const NetObj::Link& NetCompare::pin_DataA(unsigned idx) const
{
return pin(8+idx);
}
NetObj::Link& NetCompare::pin_DataB(unsigned idx)
{
return pin(8+width_+idx);
}
const NetObj::Link& NetCompare::pin_DataB(unsigned idx) const
{
return pin(8+width_+idx);
}
/*
* The NetMux class represents an LPM_MUX device. The pinout is assigned
* like so:
@ -2214,6 +2342,9 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*))
/*
* $Log: netlist.cc,v $
* Revision 1.86 1999/11/14 23:43:45 steve
* Support combinatorial comparators.
*
* Revision 1.85 1999/11/14 20:24:28 steve
* Add support for the LPM_CLSHIFT device.
*

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.87 1999/11/14 20:24:28 steve Exp $"
#ident "$Id: netlist.h,v 1.88 1999/11/14 23:43:45 steve Exp $"
#endif
/*
@ -359,6 +359,52 @@ class NetCLShift : public NetNode {
unsigned width_dist_;
};
/*
* This class supports the LPM_COMPARE device.
*
* NOTE: This is not the same as the device used to support case
* compare. Case comparisons handle Vx and Vz values, whereas this
* device need not.
*/
class NetCompare : public NetNode {
public:
NetCompare(const string&n, unsigned width);
~NetCompare();
unsigned width() const;
NetObj::Link& pin_Aclr();
NetObj::Link& pin_Clock();
NetObj::Link& pin_AGB();
NetObj::Link& pin_AGEB();
NetObj::Link& pin_AEB();
NetObj::Link& pin_ANEB();
NetObj::Link& pin_ALB();
NetObj::Link& pin_ALEB();
NetObj::Link& pin_DataA(unsigned idx);
NetObj::Link& pin_DataB(unsigned idx);
const NetObj::Link& pin_Aclr() const;
const NetObj::Link& pin_Clock() const;
const NetObj::Link& pin_AGB() const;
const NetObj::Link& pin_AGEB() const;
const NetObj::Link& pin_AEB() const;
const NetObj::Link& pin_ANEB() const;
const NetObj::Link& pin_ALB() const;
const NetObj::Link& pin_ALEB() const;
const NetObj::Link& pin_DataA(unsigned idx) const;
const NetObj::Link& pin_DataB(unsigned idx) const;
virtual void dump_node(ostream&, unsigned ind) const;
virtual void emit_node(ostream&, struct target_t*) const;
private:
unsigned width_;
};
/*
* This class represents an LPM_FF device. There is no literal gate
* type in Verilog that maps, but gates of this type can be inferred.
@ -1892,6 +1938,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
* Revision 1.88 1999/11/14 23:43:45 steve
* Support combinatorial comparators.
*
* Revision 1.87 1999/11/14 20:24:28 steve
* Add support for the LPM_CLSHIFT device.
*

150
t-vvm.cc
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.75 1999/11/14 20:24:28 steve Exp $"
#ident "$Id: t-vvm.cc,v 1.76 1999/11/14 23:43:45 steve Exp $"
#endif
# include <iostream>
@ -61,6 +61,7 @@ class target_vvm : public target_t {
virtual void lpm_add_sub(ostream&os, const NetAddSub*);
virtual void lpm_clshift(ostream&os, const NetCLShift*);
virtual void lpm_compare(ostream&os, const NetCompare*);
virtual void lpm_ff(ostream&os, const NetFF*);
virtual void lpm_mux(ostream&os, const NetMux*);
@ -884,6 +885,28 @@ void target_vvm::lpm_clshift(ostream&os, const NetCLShift*gate)
}
}
void target_vvm::lpm_compare(ostream&os, const NetCompare*gate)
{
os << "static vvm_compare<" << gate->width() << "> " <<
mangle(gate->name()) << ";" << endl;
if (gate->pin_ALEB().is_linked()) {
unsigned pin = gate->pin_ALEB().get_pin();
string outfun = defn_gate_outputfun_(os, gate, pin);
init_code << " " << mangle(gate->name()) <<
".config_ALEB_out(&" << outfun << ");" << endl;
emit_gate_outputfun_(gate, pin);
}
if (gate->pin_AGEB().is_linked()) {
unsigned pin = gate->pin_AGEB().get_pin();
string outfun = defn_gate_outputfun_(os, gate, pin);
init_code << " " << mangle(gate->name()) <<
".config_AGEB_out(&" << outfun << ");" << endl;
emit_gate_outputfun_(gate, pin);
}
}
void target_vvm::lpm_ff(ostream&os, const NetFF*gate)
{
string mname = mangle(gate->name());
@ -1879,6 +1902,9 @@ extern const struct target tgt_vvm = {
};
/*
* $Log: t-vvm.cc,v $
* Revision 1.76 1999/11/14 23:43:45 steve
* Support combinatorial comparators.
*
* Revision 1.75 1999/11/14 20:24:28 steve
* Add support for the LPM_CLSHIFT device.
*
@ -1948,127 +1974,5 @@ extern const struct target tgt_vvm = {
*
* Revision 1.55 1999/10/01 03:58:37 steve
* More resilient assignment to memory location.
*
* Revision 1.54 1999/10/01 03:15:00 steve
* Rewrite vvm output to separateclass declarations
* from method definitions. This is required to allow
* for mutual referencing, for example by tasks.
*
* Revision 1.53 1999/09/30 21:26:59 steve
* Remember to declare the calee_ member.
*
* Revision 1.52 1999/09/29 18:36:04 steve
* Full case support
*
* Revision 1.51 1999/09/29 00:42:25 steve
* Comment on where binary operator came from.
*
* Revision 1.50 1999/09/28 23:45:09 steve
* Use files instead of strstreams for delayed output,
* and fix a missing ends in case output code.
*
* Revision 1.49 1999/09/28 03:11:09 steve
* save the thread class name so that behaviors in tasks have it.
*
* Revision 1.48 1999/09/28 01:53:37 steve
* Generate code for repeat concatenations.
*
* Revision 1.47 1999/09/28 01:21:27 steve
* Proper syntax for method pointers.
*
* Revision 1.46 1999/09/28 01:13:15 steve
* Support in vvm > and >= behavioral operators.
*
* Revision 1.45 1999/09/23 03:56:57 steve
* Support shift operators.
*
* Revision 1.44 1999/09/22 16:57:24 steve
* Catch parallel blocks in vvm emit.
*
* Revision 1.43 1999/09/22 04:30:04 steve
* Parse and elaborate named for/join blocks.
*
* Revision 1.42 1999/09/16 04:18:15 steve
* elaborate concatenation repeats.
*
* Revision 1.41 1999/09/11 04:43:17 steve
* Support ternary and <= operators in vvm.
*
* Revision 1.40 1999/09/08 02:24:39 steve
* Empty conditionals (pmonta@imedia.com)
*
* Revision 1.39 1999/09/04 19:11:46 steve
* Add support for delayed non-blocking assignments.
*
* Revision 1.38 1999/09/04 01:57:15 steve
* Generate fake adder code in vvm.
*
* Revision 1.37 1999/09/01 20:46:19 steve
* Handle recursive functions and arbitrary function
* references to other functions, properly pass
* function parameters and save function results.
*
* Revision 1.36 1999/08/31 22:38:29 steve
* Elaborate and emit to vvm procedural functions.
*
* Revision 1.35 1999/08/15 01:23:56 steve
* Convert vvm to implement system tasks with vpi.
*
* Revision 1.34 1999/08/02 00:19:16 steve
* Get rid of excess set/init of NetESignal objects.
*
* Revision 1.33 1999/08/01 16:34:50 steve
* Parse and elaborate rise/fall/decay times
* for gates, and handle the rules for partial
* lists of times.
*
* Revision 1.32 1999/07/18 21:17:51 steve
* Add support for CE input to XNF DFF, and do
* complete cleanup of replaced design nodes.
*
* Revision 1.31 1999/07/17 03:39:11 steve
* simplified process scan for targets.
*
* Revision 1.30 1999/07/10 03:00:05 steve
* Proper initialization of registers.
*
* Revision 1.29 1999/07/10 01:02:08 steve
* Handle number constants as parameters.
*
* Revision 1.28 1999/07/07 04:20:57 steve
* Emit vvm for user defined tasks.
*
* Revision 1.27 1999/07/03 02:12:52 steve
* Elaborate user defined tasks.
*
* Revision 1.26 1999/06/24 04:21:45 steve
* Add the === and !== binary operators.
*
* Revision 1.25 1999/06/19 21:06:16 steve
* Elaborate and supprort to vvm the forever
* and repeat statements.
*
* Revision 1.24 1999/06/10 04:03:43 steve
* Do not bother trying to print lvalue name in comment.
*
* Revision 1.23 1999/06/09 03:00:06 steve
* Add support for procedural concatenation expression.
*
* Revision 1.22 1999/06/07 02:23:31 steve
* Support non-blocking assignment down to vvm.
*
* Revision 1.21 1999/05/12 04:03:19 steve
* emit NetAssignMem objects in vvm target.
*
* Revision 1.20 1999/05/03 01:51:29 steve
* Restore support for wait event control.
*
* Revision 1.19 1999/05/01 20:43:55 steve
* Handle wide events, such as @(a) where a has
* many bits in it.
*
* Add to vvm the binary ^ and unary & operators.
*
* Dump events a bit more completely.
*/

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.24 1999/11/14 20:24:28 steve Exp $"
#ident "$Id: target.cc,v 1.25 1999/11/14 23:43:45 steve Exp $"
#endif
# include "target.h"
@ -81,6 +81,12 @@ void target_t::lpm_clshift(ostream&, const NetCLShift*)
"Unhandled NetCLShift." << endl;
}
void target_t::lpm_compare(ostream&, const NetCompare*)
{
cerr << "target (" << typeid(*this).name() << "): "
"Unhandled NetCompare." << endl;
}
void target_t::lpm_ff(ostream&, const NetFF*)
{
cerr << "target (" << typeid(*this).name() << "): "
@ -293,6 +299,9 @@ void expr_scan_t::expr_binary(const NetEBinary*ex)
/*
* $Log: target.cc,v $
* Revision 1.25 1999/11/14 23:43:45 steve
* Support combinatorial comparators.
*
* Revision 1.24 1999/11/14 20:24:28 steve
* Add support for the LPM_CLSHIFT device.
*

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.23 1999/11/14 20:24:28 steve Exp $"
#ident "$Id: target.h,v 1.24 1999/11/14 23:43:46 steve Exp $"
#endif
# include "netlist.h"
@ -68,6 +68,7 @@ struct target_t {
/* LPM style components are handled here. */
virtual void lpm_add_sub(ostream&os, const NetAddSub*);
virtual void lpm_clshift(ostream&os, const NetCLShift*);
virtual void lpm_compare(ostream&os, const NetCompare*);
virtual void lpm_ff(ostream&os, const NetFF*);
virtual void lpm_mux(ostream&os, const NetMux*);
@ -140,6 +141,9 @@ extern const struct target *target_table[];
/*
* $Log: target.h,v $
* Revision 1.24 1999/11/14 23:43:46 steve
* Support combinatorial comparators.
*
* Revision 1.23 1999/11/14 20:24:28 steve
* Add support for the LPM_CLSHIFT device.
*

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.21 1999/11/14 20:24:28 steve Exp $"
#ident "$Id: vvm_gates.h,v 1.22 1999/11/14 23:43:46 steve Exp $"
#endif
# include "vvm.h"
@ -244,6 +244,94 @@ template <unsigned WIDTH, unsigned WDIST> class vvm_clshift {
}
};
template <unsigned WIDTH> class vvm_compare {
public:
explicit vvm_compare()
{ out_lt_ = 0;
out_le_ = 0;
gt_ = Vx;
lt_ = Vx;
for (unsigned idx = 0 ; idx < WIDTH ; idx += 1) {
a_[idx] = Vx;
b_[idx] = Vx;
}
}
~vvm_compare() { }
void init_DataA(unsigned idx, vpip_bit_t val)
{ a_[idx] = val; }
void init_DataB(unsigned idx, vpip_bit_t val)
{ b_[idx] = val; }
void set_DataA(vvm_simulation*sim, unsigned idx, vpip_bit_t val)
{ if (a_[idx] == val) return;
a_[idx] = val;
compute_(sim);
}
void set_DataB(vvm_simulation*sim, unsigned idx, vpip_bit_t val)
{ if (b_[idx] == val) return;
b_[idx] = val;
compute_(sim);
}
void config_ALB_out(vvm_out_event::action_t o)
{ out_lt_ = o; }
void config_ALEB_out(vvm_out_event::action_t o)
{ out_le_ = o; }
void config_AGB_out(vvm_out_event::action_t o)
{ out_gt_ = o; }
void config_AGEB_out(vvm_out_event::action_t o)
{ out_ge_ = o; }
private:
vpip_bit_t a_[WIDTH];
vpip_bit_t b_[WIDTH];
vpip_bit_t gt_;
vpip_bit_t lt_;
vvm_out_event::action_t out_lt_;
vvm_out_event::action_t out_le_;
vvm_out_event::action_t out_gt_;
vvm_out_event::action_t out_ge_;
void compute_(vvm_simulation*sim)
{ vpip_bit_t gt = V0;
vpip_bit_t lt = V0;
vvm_event*ev;
for (unsigned idx = 0 ; idx < WIDTH ; idx += 1) {
gt = greater_with_cascade(a_[idx], b_[idx], gt);
lt = less_with_cascade(a_[idx], b_[idx], lt);
}
if ((gt_ == gt) || (lt_ == lt)) return;
gt_ = gt;
lt_ = lt;
if (out_lt_) {
ev = new vvm_out_event(sim, lt_, out_lt_);
sim->active_event(ev);
}
if (out_le_) {
ev = new vvm_out_event(sim, not(gt_), out_le_);
sim->active_event(ev);
}
if (out_gt_) {
ev = new vvm_out_event(sim, gt_, out_gt_);
sim->active_event(ev);
}
if (out_ge_) {
ev = new vvm_out_event(sim, not(lt_), out_ge_);
sim->active_event(ev);
}
}
};
/*
* This class simulates the LPM flip-flop device.
* XXXX Inverted clock not yet supported.
@ -832,6 +920,9 @@ template <unsigned WIDTH> class vvm_pevent {
/*
* $Log: vvm_gates.h,v $
* Revision 1.22 1999/11/14 23:43:46 steve
* Support combinatorial comparators.
*
* Revision 1.21 1999/11/14 20:24:28 steve
* Add support for the LPM_CLSHIFT device.
*