Adder and comparator in nexus style.
This commit is contained in:
parent
38fd245767
commit
51e96a2d8b
100
t-vvm.cc
100
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.112 2000/03/17 03:05:13 steve Exp $"
|
||||
#ident "$Id: t-vvm.cc,v 1.113 2000/03/17 17:25:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <iostream>
|
||||
|
|
@ -1014,8 +1014,8 @@ void target_vvm::emit_gate_outputfun_(const NetNode*gate, unsigned gpin)
|
|||
|
||||
void target_vvm::lpm_add_sub(ostream&os, const NetAddSub*gate)
|
||||
{
|
||||
os << "static vvm_add_sub<" << gate->width() << "> " <<
|
||||
mangle(gate->name()) << ";" << endl;
|
||||
os << "static vvm_add_sub " <<
|
||||
mangle(gate->name()) << "(" << gate->width() << ");" << endl;
|
||||
|
||||
/* Connect the DataA inputs. */
|
||||
|
||||
|
|
@ -1103,39 +1103,50 @@ 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;
|
||||
string mname = mangle(gate->name());
|
||||
|
||||
if (gate->pin_ALB().is_linked()) {
|
||||
unsigned pin = gate->pin_ALB().get_pin();
|
||||
string outfun = defn_gate_outputfun_(os,gate,pin);
|
||||
init_code << " " << mangle(gate->name()) <<
|
||||
".config_ALB_out(&" << outfun << ");" << endl;
|
||||
emit_gate_outputfun_(gate,pin);
|
||||
os << "static vvm_compare " << mname << "(" << gate->width() <<
|
||||
");" << endl;
|
||||
|
||||
/* Connect DataA inputs... */
|
||||
for (unsigned idx = 0 ; idx < gate->width() ; idx += 1) {
|
||||
string nexus = mangle(nexus_from_link(&gate->pin_DataA(idx)));
|
||||
init_code << " " << nexus << "_nex.connect(&" << mname
|
||||
<< ", " << mname << ".key_DataA(" << idx
|
||||
<< "));" << 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);
|
||||
/* Connect DataB inputs... */
|
||||
for (unsigned idx = 0 ; idx < gate->width() ; idx += 1) {
|
||||
string nexus = mangle(nexus_from_link(&gate->pin_DataB(idx)));
|
||||
init_code << " " << nexus << "_nex.connect(&" << mname
|
||||
<< ", " << mname << ".key_DataB(" << idx
|
||||
<< "));" << endl;
|
||||
}
|
||||
|
||||
if (gate->pin_ALB().is_linked()) {
|
||||
string nexus = mangle(nexus_from_link(&gate->pin_ALB()));
|
||||
init_code << " " << nexus << "_nex.connect(" << mname
|
||||
<< ".config_ALB_out());" << endl;
|
||||
}
|
||||
|
||||
if (gate->pin_AGB().is_linked()) {
|
||||
unsigned pin = gate->pin_AGB().get_pin();
|
||||
string outfun = defn_gate_outputfun_(os,gate,pin);
|
||||
init_code << " " << mangle(gate->name()) <<
|
||||
".config_AGB_out(&" << outfun << ");" << endl;
|
||||
emit_gate_outputfun_(gate,pin);
|
||||
string nexus = mangle(nexus_from_link(&gate->pin_AGB()));
|
||||
init_code << " " << nexus << "_nex.connect(" << mname
|
||||
<< ".config_AGB_out());" << endl;
|
||||
}
|
||||
|
||||
|
||||
if (gate->pin_ALEB().is_linked()) {
|
||||
string nexus = mangle(nexus_from_link(&gate->pin_ALEB()));
|
||||
init_code << " " << nexus << "_nex.connect(" << mname
|
||||
<< ".config_ALEB_out());" << endl;
|
||||
}
|
||||
|
||||
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);
|
||||
string nexus = mangle(nexus_from_link(&gate->pin_AGEB()));
|
||||
init_code << " " << nexus << "_nex.connect(" << mname
|
||||
<< ".config_AGEB_out());" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1510,6 +1521,38 @@ void target_vvm::start_process(ostream&os, const NetProcTop*proc)
|
|||
*/
|
||||
void target_vvm::proc_assign(ostream&os, const NetAssign*net)
|
||||
{
|
||||
|
||||
/* Detect the very special (and very common) case that the
|
||||
rvalue is a constant in this assignment. I this case, there
|
||||
is no reason to go scan the expression, and in the process
|
||||
generate bunches of temporaries. */
|
||||
|
||||
if (const NetEConst*rc = dynamic_cast<const NetEConst*>(net->rval())) {
|
||||
assert(net->bmux() == 0);
|
||||
const verinum value = rc->value();
|
||||
|
||||
for (unsigned idx = 0 ; idx < net->pin_count() ; idx += 1) {
|
||||
string nexus = mangle(nexus_from_link(&net->pin(idx)));
|
||||
defn << " " << nexus << "_nex.reg_assign(";
|
||||
switch (value.get(idx)) {
|
||||
case verinum::V0:
|
||||
defn << "V0";
|
||||
break;
|
||||
case verinum::V1:
|
||||
defn << "V1";
|
||||
break;
|
||||
case verinum::Vx:
|
||||
defn << "Vx";
|
||||
break;
|
||||
case verinum::Vz:
|
||||
defn << "Vz";
|
||||
break;
|
||||
}
|
||||
defn << ");" << endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
string rval = emit_proc_rval(defn, 8, net->rval());
|
||||
|
||||
defn << " // " << net->get_line() << ": " << endl;
|
||||
|
|
@ -2196,6 +2239,9 @@ extern const struct target tgt_vvm = {
|
|||
};
|
||||
/*
|
||||
* $Log: t-vvm.cc,v $
|
||||
* Revision 1.113 2000/03/17 17:25:53 steve
|
||||
* Adder and comparator in nexus style.
|
||||
*
|
||||
* Revision 1.112 2000/03/17 03:05:13 steve
|
||||
* Update vvm_mult to nexus style.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.22 2000/03/17 02:22:03 steve Exp $"
|
||||
#ident "$Id: Makefile.in,v 1.23 2000/03/17 17:25:53 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
|
@ -58,8 +58,9 @@ all: libvvm.a
|
|||
$(CC) -Wall $(CPPFLAGS) $(CFLAGS) -MD -c $< -o $*.o
|
||||
mv $*.d dep
|
||||
|
||||
O = vvm_bit.o vvm_calltf.o vvm_clshift.o vvm_event.o vvm_func.o \
|
||||
vvm_gates.o vvm_mult.o \
|
||||
O = vvm_add_sub.o vvm_bit.o vvm_calltf.o vvm_clshift.o vvm_compare.o \
|
||||
vvm_event.o \
|
||||
vvm_func.o vvm_gates.o vvm_mult.o \
|
||||
vvm_nexus.o vvm_pevent.o vvm_signal.o vvm_thread.o vpip.o
|
||||
|
||||
P = vpi_callback.o \
|
||||
|
|
|
|||
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* 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_add_sub.cc,v 1.1 2000/03/17 17:25:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vvm_gates.h"
|
||||
# include <assert.h>
|
||||
|
||||
vvm_add_sub::vvm_add_sub(unsigned wid)
|
||||
: width_(wid), ndir_(V0)
|
||||
{
|
||||
ibits_ = new vpip_bit_t[width_*3];
|
||||
ro_ = new vvm_nexus::drive_t[width_];
|
||||
|
||||
c_ = Vx;
|
||||
for (unsigned idx = 0 ; idx < width_*3 ; idx += 1)
|
||||
ibits_[idx] = Vx;
|
||||
}
|
||||
|
||||
vvm_add_sub::~vvm_add_sub()
|
||||
{
|
||||
delete[]ro_;
|
||||
delete[]ibits_;
|
||||
}
|
||||
|
||||
vvm_nexus::drive_t* vvm_add_sub::config_rout(unsigned idx)
|
||||
{
|
||||
assert(idx < width_);
|
||||
return ro_+idx;
|
||||
}
|
||||
|
||||
vvm_nexus::drive_t* vvm_add_sub::config_cout()
|
||||
{
|
||||
return &co_;
|
||||
}
|
||||
|
||||
unsigned vvm_add_sub::key_DataA(unsigned idx) const
|
||||
{
|
||||
assert(idx < width_);
|
||||
return idx;
|
||||
}
|
||||
|
||||
unsigned vvm_add_sub::key_DataB(unsigned idx) const
|
||||
{
|
||||
assert(idx < width_);
|
||||
return idx+width_;
|
||||
}
|
||||
|
||||
void vvm_add_sub::init_DataA(unsigned idx, vpip_bit_t val)
|
||||
{
|
||||
assert(idx < width_);
|
||||
ibits_[idx] = val;
|
||||
}
|
||||
|
||||
void vvm_add_sub::init_DataB(unsigned idx, vpip_bit_t val)
|
||||
{
|
||||
assert(idx < width_);
|
||||
ibits_[width_+idx] = val;
|
||||
}
|
||||
|
||||
void vvm_add_sub::init_Add_Sub(unsigned, vpip_bit_t val)
|
||||
{
|
||||
ndir_ = v_not(val);
|
||||
}
|
||||
|
||||
void vvm_add_sub::start()
|
||||
{
|
||||
compute_();
|
||||
}
|
||||
|
||||
void vvm_add_sub::take_value(unsigned key, vpip_bit_t val)
|
||||
{
|
||||
if (ibits_[key] == val) return;
|
||||
ibits_[key] = val;
|
||||
compute_();
|
||||
}
|
||||
|
||||
void vvm_add_sub::compute_()
|
||||
{
|
||||
vpip_bit_t carry = ndir_;
|
||||
|
||||
vpip_bit_t*a = ibits_;
|
||||
vpip_bit_t*b = ibits_+width_;
|
||||
vpip_bit_t*r = ibits_+2*width_;
|
||||
|
||||
for (unsigned idx = 0 ; idx < width_ ; idx += 1) {
|
||||
vpip_bit_t val;
|
||||
val = add_with_carry(a[idx], b[idx] ^ ndir_, carry);
|
||||
if (val == r[idx]) continue;
|
||||
r[idx] = val;
|
||||
vvm_event*ev = new vvm_out_event(val, ro_+idx);
|
||||
ev->schedule();
|
||||
}
|
||||
if (carry != c_)
|
||||
(new vvm_out_event(carry, &co_)) -> schedule();
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: vvm_add_sub.cc,v $
|
||||
* Revision 1.1 2000/03/17 17:25:53 steve
|
||||
* Adder and comparator in nexus style.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* 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_compare.cc,v 1.1 2000/03/17 17:25:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vvm_gates.h"
|
||||
# include <assert.h>
|
||||
|
||||
vvm_compare::vvm_compare(unsigned wid)
|
||||
: width_(wid)
|
||||
{
|
||||
gt_ = Vx;
|
||||
lt_ = Vx;
|
||||
|
||||
ibits_ = new vpip_bit_t[2*width_];
|
||||
for (unsigned idx = 0 ; idx < 2*width_ ; idx += 1)
|
||||
ibits_[idx] = Vx;
|
||||
}
|
||||
|
||||
vvm_compare::~vvm_compare()
|
||||
{
|
||||
delete[]ibits_;
|
||||
}
|
||||
|
||||
void vvm_compare::init_DataA(unsigned idx, vpip_bit_t val)
|
||||
{
|
||||
assert(idx < width_);
|
||||
ibits_[idx] = val;
|
||||
}
|
||||
|
||||
void vvm_compare::init_DataB(unsigned idx, vpip_bit_t val)
|
||||
{
|
||||
assert(idx < width_);
|
||||
ibits_[width_+idx] = val;
|
||||
}
|
||||
|
||||
vvm_nexus::drive_t* vvm_compare::config_ALB_out()
|
||||
{
|
||||
return &out_lt_;
|
||||
}
|
||||
|
||||
vvm_nexus::drive_t* vvm_compare::config_ALEB_out()
|
||||
{
|
||||
return &out_le_;
|
||||
}
|
||||
|
||||
vvm_nexus::drive_t* vvm_compare::config_AGB_out()
|
||||
{
|
||||
return &out_gt_;
|
||||
}
|
||||
|
||||
vvm_nexus::drive_t* vvm_compare::config_AGEB_out()
|
||||
{
|
||||
return &out_ge_;
|
||||
}
|
||||
|
||||
unsigned vvm_compare::key_DataA(unsigned idx) const
|
||||
{
|
||||
assert(idx < width_);
|
||||
return idx;
|
||||
}
|
||||
|
||||
unsigned vvm_compare::key_DataB(unsigned idx) const
|
||||
{
|
||||
assert(idx < width_);
|
||||
return width_ + idx;
|
||||
}
|
||||
|
||||
void vvm_compare::take_value(unsigned key, vpip_bit_t val)
|
||||
{
|
||||
if (ibits_[key] == val)
|
||||
return;
|
||||
|
||||
ibits_[key] = val;
|
||||
compute_();
|
||||
}
|
||||
|
||||
void vvm_compare::compute_()
|
||||
{
|
||||
vpip_bit_t gt = V0;
|
||||
vpip_bit_t lt = V0;
|
||||
|
||||
vpip_bit_t*a = ibits_;
|
||||
vpip_bit_t*b = ibits_+width_;
|
||||
|
||||
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;
|
||||
out_lt_.set_value(lt_);
|
||||
out_le_.set_value(v_not(gt_));
|
||||
out_gt_.set_value(gt_);
|
||||
out_ge_.set_value(v_not(lt_));
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: vvm_compare.cc,v $
|
||||
* Revision 1.1 2000/03/17 17:25:53 steve
|
||||
* Adder and comparator in nexus style.
|
||||
*
|
||||
*/
|
||||
|
||||
186
vvm/vvm_gates.h
186
vvm/vvm_gates.h
|
|
@ -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.43 2000/03/17 03:36:07 steve Exp $"
|
||||
#ident "$Id: vvm_gates.h,v 1.44 2000/03/17 17:25:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vvm.h"
|
||||
|
|
@ -74,88 +74,52 @@ class vvm_1bit_out : public vvm_nexus::drive_t {
|
|||
};
|
||||
|
||||
/*
|
||||
* This template implements the LPM_ADD_SUB device type. The width of
|
||||
* the device is a template parameter. The device handles addition and
|
||||
* This class implements the LPM_ADD_SUB device type. The width of
|
||||
* the device is a constructor parameter. The device handles addition and
|
||||
* subtraction, selectable by the Add_Sub input. When configured as a
|
||||
* subtractor, the device works by adding the 2s complement of
|
||||
* DataB.
|
||||
*/
|
||||
template <unsigned WIDTH> class vvm_add_sub : public vvm_nexus::recvr_t {
|
||||
class vvm_add_sub : public vvm_nexus::recvr_t {
|
||||
|
||||
public:
|
||||
vvm_add_sub() : ndir_(V0) { }
|
||||
explicit vvm_add_sub(unsigned width);
|
||||
~vvm_add_sub();
|
||||
|
||||
vvm_nexus::drive_t* config_rout(unsigned idx)
|
||||
{ r_[idx] = Vx;
|
||||
assert(idx < WIDTH);
|
||||
return ro_+idx;
|
||||
}
|
||||
vvm_nexus::drive_t* config_rout(unsigned idx);
|
||||
vvm_nexus::drive_t* config_cout();
|
||||
|
||||
vvm_nexus::drive_t* config_cout()
|
||||
{ c_ = Vx;
|
||||
return &co_;
|
||||
}
|
||||
unsigned key_DataA(unsigned idx) const;
|
||||
unsigned key_DataB(unsigned idx) const;
|
||||
|
||||
unsigned key_DataA(unsigned idx) const { return idx; }
|
||||
unsigned key_DataB(unsigned idx) const { return idx|0x10000; }
|
||||
void init_DataA(unsigned idx, vpip_bit_t val);
|
||||
void init_DataB(unsigned idx, vpip_bit_t val);
|
||||
void init_Add_Sub(unsigned, vpip_bit_t val);
|
||||
|
||||
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 init_Add_Sub(unsigned, vpip_bit_t val)
|
||||
{ ndir_ = v_not(val);
|
||||
}
|
||||
|
||||
void start() { compute_(); }
|
||||
|
||||
void set_DataA(unsigned idx, vpip_bit_t val)
|
||||
{ a_[idx] = val;
|
||||
compute_();
|
||||
}
|
||||
void set_DataB(unsigned idx, vpip_bit_t val)
|
||||
{ b_[idx] = val;
|
||||
compute_();
|
||||
}
|
||||
void start();
|
||||
|
||||
private:
|
||||
void take_value(unsigned key, vpip_bit_t val)
|
||||
{ if (key&0x10000) set_DataB(key&0xffff, val);
|
||||
else set_DataA(key&0xffff, val);
|
||||
}
|
||||
void take_value(unsigned key, vpip_bit_t val);
|
||||
|
||||
private:
|
||||
vpip_bit_t a_[WIDTH];
|
||||
vpip_bit_t b_[WIDTH];
|
||||
vpip_bit_t r_[WIDTH];
|
||||
unsigned width_;
|
||||
vpip_bit_t*ibits_;
|
||||
vpip_bit_t c_;
|
||||
|
||||
// this is the inverse of the Add_Sub port. It is 0 for add,
|
||||
// and 1 for subtract.
|
||||
vpip_bit_t ndir_;
|
||||
|
||||
vvm_nexus::drive_t ro_[WIDTH];
|
||||
vvm_nexus::drive_t*ro_;
|
||||
vvm_nexus::drive_t co_;
|
||||
|
||||
void compute_()
|
||||
{ vpip_bit_t carry = ndir_;
|
||||
for (unsigned idx = 0 ; idx < WIDTH ; idx += 1) {
|
||||
vpip_bit_t val;
|
||||
val = add_with_carry(a_[idx], b_[idx] ^ ndir_, carry);
|
||||
if (val == r_[idx]) continue;
|
||||
r_[idx] = val;
|
||||
vvm_event*ev = new vvm_out_event(val, ro_+idx);
|
||||
ev->schedule();
|
||||
}
|
||||
if (carry != c_)
|
||||
(new vvm_out_event(carry, &co_)) -> schedule();
|
||||
}
|
||||
void compute_();
|
||||
|
||||
private: // not implemented
|
||||
vvm_add_sub(const vvm_add_sub&);
|
||||
vvm_add_sub& operator= (const vvm_add_sub&);
|
||||
};
|
||||
|
||||
|
||||
template <unsigned WIDTH>
|
||||
class vvm_and : public vvm_1bit_out, public vvm_nexus::recvr_t {
|
||||
|
||||
|
|
@ -218,91 +182,46 @@ class vvm_clshift : public vvm_nexus::recvr_t {
|
|||
};
|
||||
|
||||
|
||||
template <unsigned WIDTH> class vvm_compare {
|
||||
/*
|
||||
* This class implements structural comparators, specifically the
|
||||
* LPM_COMPARE device type.
|
||||
*/
|
||||
class vvm_compare : public vvm_nexus::recvr_t {
|
||||
|
||||
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() { }
|
||||
explicit vvm_compare(unsigned w);
|
||||
~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 init_DataA(unsigned idx, vpip_bit_t val);
|
||||
void init_DataB(unsigned idx, vpip_bit_t val);
|
||||
|
||||
void set_DataA(unsigned idx, vpip_bit_t val)
|
||||
{ if (a_[idx] == val) return;
|
||||
a_[idx] = val;
|
||||
compute_();
|
||||
}
|
||||
unsigned key_DataA(unsigned idx) const;
|
||||
unsigned key_DataB(unsigned idx) const;
|
||||
|
||||
void set_DataB(unsigned idx, vpip_bit_t val)
|
||||
{ if (b_[idx] == val) return;
|
||||
b_[idx] = val;
|
||||
compute_();
|
||||
}
|
||||
|
||||
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; }
|
||||
vvm_nexus::drive_t* config_ALB_out();
|
||||
vvm_nexus::drive_t* config_ALEB_out();
|
||||
vvm_nexus::drive_t* config_AGB_out();
|
||||
vvm_nexus::drive_t* config_AGEB_out();
|
||||
|
||||
private:
|
||||
vpip_bit_t a_[WIDTH];
|
||||
vpip_bit_t b_[WIDTH];
|
||||
void take_value(unsigned key, vpip_bit_t val);
|
||||
|
||||
unsigned width_;
|
||||
vpip_bit_t*ibits_;
|
||||
|
||||
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_;
|
||||
vvm_nexus::drive_t out_lt_;
|
||||
vvm_nexus::drive_t out_le_;
|
||||
vvm_nexus::drive_t out_gt_;
|
||||
vvm_nexus::drive_t out_ge_;
|
||||
|
||||
void compute_()
|
||||
{ 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);
|
||||
}
|
||||
void compute_();
|
||||
|
||||
if ((gt_ == gt) && (lt_ == lt)) return;
|
||||
gt_ = gt;
|
||||
lt_ = lt;
|
||||
if (out_lt_) {
|
||||
ev = new vvm_out_event(lt_, out_lt_);
|
||||
ev->schedule();
|
||||
}
|
||||
if (out_le_) {
|
||||
ev = new vvm_out_event(v_not(gt_), out_le_);
|
||||
ev->schedule();
|
||||
}
|
||||
if (out_gt_) {
|
||||
ev = new vvm_out_event(gt_, out_gt_);
|
||||
ev->schedule();
|
||||
}
|
||||
if (out_ge_) {
|
||||
ev = new vvm_out_event(v_not(lt_), out_ge_);
|
||||
ev->schedule();
|
||||
}
|
||||
}
|
||||
private: // not implemented
|
||||
vvm_compare(const vvm_compare&);
|
||||
vvm_compare& operator= (const vvm_compare&);
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -895,6 +814,9 @@ template <unsigned WIDTH> class vvm_pevent : public vvm_nexus::recvr_t {
|
|||
|
||||
/*
|
||||
* $Log: vvm_gates.h,v $
|
||||
* Revision 1.44 2000/03/17 17:25:53 steve
|
||||
* Adder and comparator in nexus style.
|
||||
*
|
||||
* Revision 1.43 2000/03/17 03:36:07 steve
|
||||
* Remove some useless template parameters.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue