Add support for integer division.
This commit is contained in:
parent
2dd010dc04
commit
694ff934af
10
PExpr.h
10
PExpr.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PExpr.h,v 1.33 2000/04/01 19:31:57 steve Exp $"
|
||||
#ident "$Id: PExpr.h,v 1.34 2000/04/01 21:40:22 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <string>
|
||||
|
|
@ -289,6 +289,11 @@ class PEBinary : public PExpr {
|
|||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay) const;
|
||||
NetNet* elaborate_net_div_(Design*des, const string&path,
|
||||
unsigned lwidth,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay) const;
|
||||
NetNet* elaborate_net_log_(Design*des, const string&path,
|
||||
unsigned lwidth,
|
||||
unsigned long rise,
|
||||
|
|
@ -353,6 +358,9 @@ class PECallFunction : public PExpr {
|
|||
|
||||
/*
|
||||
* $Log: PExpr.h,v $
|
||||
* Revision 1.34 2000/04/01 21:40:22 steve
|
||||
* Add support for integer division.
|
||||
*
|
||||
* Revision 1.33 2000/04/01 19:31:57 steve
|
||||
* Named events as far as the pform.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.70 2000/03/29 04:37:10 steve Exp $"
|
||||
#ident "$Id: design_dump.cc,v 1.71 2000/04/01 21:40:22 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -147,6 +147,13 @@ void NetCompare::dump_node(ostream&o, unsigned ind) const
|
|||
dump_obj_attr(o, ind+4);
|
||||
}
|
||||
|
||||
void NetDivide::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "NET_DIVIDE (NetDivide): " << name() << endl;
|
||||
dump_node_pins(o, ind+4);
|
||||
dump_obj_attr(o, ind+4);
|
||||
}
|
||||
|
||||
void NetMult::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "LPM_MULT (NetMult): " << name() << endl;
|
||||
|
|
@ -897,6 +904,9 @@ void Design::dump(ostream&o) const
|
|||
|
||||
/*
|
||||
* $Log: design_dump.cc,v $
|
||||
* Revision 1.71 2000/04/01 21:40:22 steve
|
||||
* Add support for integer division.
|
||||
*
|
||||
* Revision 1.70 2000/03/29 04:37:10 steve
|
||||
* New and improved combinational primitives.
|
||||
*
|
||||
|
|
|
|||
61
elab_net.cc
61
elab_net.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: elab_net.cc,v 1.28 2000/03/27 04:38:15 steve Exp $"
|
||||
#ident "$Id: elab_net.cc,v 1.29 2000/04/01 21:40:22 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "PExpr.h"
|
||||
|
|
@ -38,9 +38,10 @@ NetNet* PEBinary::elaborate_net(Design*des, const string&path,
|
|||
{
|
||||
switch (op_) {
|
||||
case '*':
|
||||
//case '/':
|
||||
//case '%':
|
||||
return elaborate_net_mul_(des, path, width, rise, fall, decay);
|
||||
//case '%':
|
||||
case '/':
|
||||
return elaborate_net_div_(des, path, width, rise, fall, decay);
|
||||
case '+':
|
||||
case '-':
|
||||
return elaborate_net_add_(des, path, width, rise, fall, decay);
|
||||
|
|
@ -500,6 +501,57 @@ NetNet* PEBinary::elaborate_net_cmp_(Design*des, const string&path,
|
|||
return osig;
|
||||
}
|
||||
|
||||
/*
|
||||
* Elaborate a divider gate.
|
||||
*/
|
||||
NetNet* PEBinary::elaborate_net_div_(Design*des, const string&path,
|
||||
unsigned lwidth,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay) const
|
||||
{
|
||||
NetNet*lsig = left_->elaborate_net(des, path, 0, 0, 0, 0);
|
||||
if (lsig == 0) return 0;
|
||||
NetNet*rsig = right_->elaborate_net(des, path, 0, 0, 0, 0);
|
||||
if (rsig == 0) return 0;
|
||||
|
||||
unsigned rwidth = lsig->pin_count();
|
||||
if (rsig->pin_count() > rwidth)
|
||||
rwidth = rsig->pin_count();
|
||||
NetDivide*div = new NetDivide(des->local_symbol(path), rwidth,
|
||||
lsig->pin_count(),
|
||||
rsig->pin_count());
|
||||
des->add_node(div);
|
||||
|
||||
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1)
|
||||
connect(div->pin_DataA(idx), lsig->pin(idx));
|
||||
for (unsigned idx = 0 ; idx < rsig->pin_count() ; idx += 1)
|
||||
connect(div->pin_DataB(idx), rsig->pin(idx));
|
||||
|
||||
if (lwidth == 0) lwidth = rwidth;
|
||||
NetNet*osig = new NetNet(0, des->local_symbol(path),
|
||||
NetNet::IMPLICIT, lwidth);
|
||||
osig->local_flag(true);
|
||||
des->add_signal(osig);
|
||||
|
||||
unsigned cnt = osig->pin_count();
|
||||
if (cnt > rwidth) cnt = rwidth;
|
||||
|
||||
for (unsigned idx = 0 ; idx < cnt ; idx += 1)
|
||||
connect(div->pin_Result(idx), osig->pin(idx));
|
||||
|
||||
/* If the lvalue is larger then the result, then pad the
|
||||
output with constant 0. */
|
||||
if (cnt < osig->pin_count()) {
|
||||
NetConst*tmp = new NetConst(des->local_symbol(path), verinum::V0);
|
||||
des->add_node(tmp);
|
||||
for (unsigned idx = cnt ; idx < osig->pin_count() ; idx += 1)
|
||||
connect(osig->pin(idx), tmp->pin(0));
|
||||
}
|
||||
|
||||
return osig;
|
||||
}
|
||||
|
||||
NetNet* PEBinary::elaborate_net_log_(Design*des, const string&path,
|
||||
unsigned lwidth,
|
||||
unsigned long rise,
|
||||
|
|
@ -1356,6 +1408,9 @@ NetNet* PEUnary::elaborate_net(Design*des, const string&path,
|
|||
|
||||
/*
|
||||
* $Log: elab_net.cc,v $
|
||||
* Revision 1.29 2000/04/01 21:40:22 steve
|
||||
* Add support for integer division.
|
||||
*
|
||||
* Revision 1.28 2000/03/27 04:38:15 steve
|
||||
* Speling error.
|
||||
*
|
||||
|
|
|
|||
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.35 2000/03/29 04:37:11 steve Exp $"
|
||||
#ident "$Id: emit.cc,v 1.36 2000/04/01 21:40:22 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -85,6 +85,11 @@ void NetConst::emit_node(ostream&o, struct target_t*tgt) const
|
|||
tgt->net_const(o, this);
|
||||
}
|
||||
|
||||
void NetDivide::emit_node(ostream&o, struct target_t*tgt) const
|
||||
{
|
||||
tgt->lpm_divide(o, this);
|
||||
}
|
||||
|
||||
void NetFF::emit_node(ostream&o, struct target_t*tgt) const
|
||||
{
|
||||
tgt->lpm_ff(o, this);
|
||||
|
|
@ -402,6 +407,9 @@ bool emit(ostream&o, const Design*des, const char*type)
|
|||
|
||||
/*
|
||||
* $Log: emit.cc,v $
|
||||
* Revision 1.36 2000/04/01 21:40:22 steve
|
||||
* Add support for integer division.
|
||||
*
|
||||
* Revision 1.35 2000/03/29 04:37:11 steve
|
||||
* New and improved combinational primitives.
|
||||
*
|
||||
|
|
|
|||
14
functor.cc
14
functor.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: functor.cc,v 1.12 2000/02/23 02:56:54 steve Exp $"
|
||||
#ident "$Id: functor.cc,v 1.13 2000/04/01 21:40:22 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "functor.h"
|
||||
|
|
@ -43,6 +43,10 @@ void functor_t::lpm_const(class Design*, class NetConst*)
|
|||
{
|
||||
}
|
||||
|
||||
void functor_t::lpm_divide(class Design*, class NetDivide*)
|
||||
{
|
||||
}
|
||||
|
||||
void functor_t::lpm_ff(class Design*, class NetFF*)
|
||||
{
|
||||
}
|
||||
|
|
@ -101,6 +105,11 @@ void NetConst::functor_node(Design*des, functor_t*fun)
|
|||
fun->lpm_const(des, this);
|
||||
}
|
||||
|
||||
void NetDivide::functor_node(Design*des, functor_t*fun)
|
||||
{
|
||||
fun->lpm_divide(des, this);
|
||||
}
|
||||
|
||||
void NetFF::functor_node(Design*des, functor_t*fun)
|
||||
{
|
||||
fun->lpm_ff(des, this);
|
||||
|
|
@ -180,6 +189,9 @@ int NetPEvent::match_proc(proc_match_t*that)
|
|||
|
||||
/*
|
||||
* $Log: functor.cc,v $
|
||||
* Revision 1.13 2000/04/01 21:40:22 steve
|
||||
* Add support for integer division.
|
||||
*
|
||||
* Revision 1.12 2000/02/23 02:56:54 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
|
|
|
|||
23
functor.h
23
functor.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: functor.h,v 1.9 2000/02/23 02:56:54 steve Exp $"
|
||||
#ident "$Id: functor.h,v 1.10 2000/04/01 21:40:22 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -48,6 +48,9 @@ struct functor_t {
|
|||
/* This method is called for each structural constant. */
|
||||
virtual void lpm_const(class Design*des, class NetConst*);
|
||||
|
||||
/* This method is called for each structural constant. */
|
||||
virtual void lpm_divide(class Design*des, class NetDivide*);
|
||||
|
||||
/* This method is called for each FF in the design. */
|
||||
virtual void lpm_ff(class Design*des, class NetFF*);
|
||||
|
||||
|
|
@ -71,6 +74,9 @@ struct proc_match_t {
|
|||
|
||||
/*
|
||||
* $Log: functor.h,v $
|
||||
* Revision 1.10 2000/04/01 21:40:22 steve
|
||||
* Add support for integer division.
|
||||
*
|
||||
* Revision 1.9 2000/02/23 02:56:54 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
|
|
@ -85,20 +91,5 @@ struct proc_match_t {
|
|||
*
|
||||
* Revision 1.5 1999/12/17 06:18:16 steve
|
||||
* Rewrite the cprop functor to use the functor_t interface.
|
||||
*
|
||||
* Revision 1.4 1999/12/05 02:24:08 steve
|
||||
* Synthesize LPM_RAM_DQ for writes into memories.
|
||||
*
|
||||
* Revision 1.3 1999/12/01 06:06:16 steve
|
||||
* Redo synth to use match_proc_t scanner.
|
||||
*
|
||||
* Revision 1.2 1999/11/01 02:07:40 steve
|
||||
* Add the synth functor to do generic synthesis
|
||||
* and add the LPM_FF device to handle rows of
|
||||
* flip-flops.
|
||||
*
|
||||
* Revision 1.1 1999/07/17 22:01:13 steve
|
||||
* Add the functor interface for functor transforms.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
|
|
|
|||
79
netlist.cc
79
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.109 2000/03/29 04:37:11 steve Exp $"
|
||||
#ident "$Id: netlist.cc,v 1.110 2000/04/01 21:40:22 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <cassert>
|
||||
|
|
@ -932,6 +932,80 @@ const NetObj::Link& NetCompare::pin_DataB(unsigned idx) const
|
|||
return pin(8+width_+idx);
|
||||
}
|
||||
|
||||
NetDivide::NetDivide(const string&n, unsigned wr,
|
||||
unsigned wa, unsigned wb)
|
||||
: NetNode(n, wr+wa+wb), width_r_(wr), width_a_(wa), width_b_(wb)
|
||||
{
|
||||
unsigned p = 0;
|
||||
for (unsigned idx = 0 ; idx < width_r_ ; idx += 1, p += 1) {
|
||||
pin(p).set_dir(NetObj::Link::OUTPUT);
|
||||
pin(p).set_name("Result", idx);
|
||||
}
|
||||
for (unsigned idx = 0 ; idx < width_a_ ; idx += 1, p += 1) {
|
||||
pin(p).set_dir(NetObj::Link::INPUT);
|
||||
pin(p).set_name("DataA", idx);
|
||||
}
|
||||
for (unsigned idx = 0 ; idx < width_b_ ; idx += 1, p += 1) {
|
||||
pin(p).set_dir(NetObj::Link::INPUT);
|
||||
pin(p).set_name("DataB", idx);
|
||||
}
|
||||
}
|
||||
|
||||
NetDivide::~NetDivide()
|
||||
{
|
||||
}
|
||||
|
||||
unsigned NetDivide::width_r() const
|
||||
{
|
||||
return width_r_;
|
||||
}
|
||||
|
||||
unsigned NetDivide::width_a() const
|
||||
{
|
||||
return width_a_;
|
||||
}
|
||||
|
||||
unsigned NetDivide::width_b() const
|
||||
{
|
||||
return width_b_;
|
||||
}
|
||||
|
||||
NetObj::Link& NetDivide::pin_Result(unsigned idx)
|
||||
{
|
||||
assert(idx < width_r_);
|
||||
return pin(idx);
|
||||
}
|
||||
|
||||
const NetObj::Link& NetDivide::pin_Result(unsigned idx) const
|
||||
{
|
||||
assert(idx < width_r_);
|
||||
return pin(idx);
|
||||
}
|
||||
|
||||
NetObj::Link& NetDivide::pin_DataA(unsigned idx)
|
||||
{
|
||||
assert(idx < width_a_);
|
||||
return pin(idx+width_r_);
|
||||
}
|
||||
|
||||
const NetObj::Link& NetDivide::pin_DataA(unsigned idx) const
|
||||
{
|
||||
assert(idx < width_a_);
|
||||
return pin(idx+width_r_);
|
||||
}
|
||||
|
||||
NetObj::Link& NetDivide::pin_DataB(unsigned idx)
|
||||
{
|
||||
assert(idx < width_b_);
|
||||
return pin(idx+width_r_+width_a_);
|
||||
}
|
||||
|
||||
const NetObj::Link& NetDivide::pin_DataB(unsigned idx) const
|
||||
{
|
||||
assert(idx < width_b_);
|
||||
return pin(idx+width_r_+width_a_);
|
||||
}
|
||||
|
||||
NetMult::NetMult(const string&n, unsigned wr, unsigned wa, unsigned wb,
|
||||
unsigned ws)
|
||||
: NetNode(n, 2+wr+wa+wb+ws), width_r_(wr), width_a_(wa), width_b_(wb),
|
||||
|
|
@ -2523,6 +2597,9 @@ bool NetUDP::sequ_glob_(string input, char output)
|
|||
|
||||
/*
|
||||
* $Log: netlist.cc,v $
|
||||
* Revision 1.110 2000/04/01 21:40:22 steve
|
||||
* Add support for integer division.
|
||||
*
|
||||
* Revision 1.109 2000/03/29 04:37:11 steve
|
||||
* New and improved combinational primitives.
|
||||
*
|
||||
|
|
|
|||
43
netlist.h
43
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.115 2000/03/29 04:37:11 steve Exp $"
|
||||
#ident "$Id: netlist.h,v 1.116 2000/04/01 21:40:22 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -411,6 +411,44 @@ class NetCompare : public NetNode {
|
|||
unsigned width_;
|
||||
};
|
||||
|
||||
/*
|
||||
* This class represents a theoretical (though not necessarily
|
||||
* practical) integer divider gate. This is not to represent any real
|
||||
* hardware, but to support the / operator in Verilog, when it shows
|
||||
* up in structural contexts.
|
||||
*
|
||||
* The operands of the operation are the DataA<i> and DataB<i> inputs,
|
||||
* and the Result<i> output reflects the value DataA/DataB.
|
||||
*/
|
||||
|
||||
class NetDivide : public NetNode {
|
||||
|
||||
public:
|
||||
NetDivide(const string&n, unsigned width, unsigned wa, unsigned wb);
|
||||
~NetDivide();
|
||||
|
||||
unsigned width_r() const;
|
||||
unsigned width_a() const;
|
||||
unsigned width_b() const;
|
||||
|
||||
NetObj::Link& pin_DataA(unsigned idx);
|
||||
NetObj::Link& pin_DataB(unsigned idx);
|
||||
NetObj::Link& pin_Result(unsigned idx);
|
||||
|
||||
const NetObj::Link& pin_DataA(unsigned idx) const;
|
||||
const NetObj::Link& pin_DataB(unsigned idx) const;
|
||||
const NetObj::Link& pin_Result(unsigned idx) const;
|
||||
|
||||
virtual void dump_node(ostream&, unsigned ind) const;
|
||||
virtual void emit_node(ostream&, struct target_t*) const;
|
||||
virtual void functor_node(Design*des, functor_t*fun);
|
||||
|
||||
private:
|
||||
unsigned width_r_;
|
||||
unsigned width_a_;
|
||||
unsigned width_b_;
|
||||
};
|
||||
|
||||
/*
|
||||
* 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.
|
||||
|
|
@ -2228,6 +2266,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
|
|||
|
||||
/*
|
||||
* $Log: netlist.h,v $
|
||||
* Revision 1.116 2000/04/01 21:40:22 steve
|
||||
* Add support for integer division.
|
||||
*
|
||||
* Revision 1.115 2000/03/29 04:37:11 steve
|
||||
* New and improved combinational primitives.
|
||||
*
|
||||
|
|
|
|||
52
t-vvm.cc
52
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.127 2000/03/29 04:37:11 steve Exp $"
|
||||
#ident "$Id: t-vvm.cc,v 1.128 2000/04/01 21:40:23 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <iostream>
|
||||
|
|
@ -65,6 +65,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_divide(ostream&os, const NetDivide*);
|
||||
virtual void lpm_ff(ostream&os, const NetFF*);
|
||||
virtual void lpm_mult(ostream&os, const NetMult*);
|
||||
virtual void lpm_mux(ostream&os, const NetMux*);
|
||||
|
|
@ -553,12 +554,12 @@ void vvm_proc_rval::expr_binary(const NetEBinary*expr)
|
|||
<< "," << lres << "," << rres << ");" << endl;
|
||||
break;
|
||||
case '/':
|
||||
os_ << setw(indent_) << "" << result << " = vvm_binop_idiv("
|
||||
<< lres << "," << rres << ");" << endl;
|
||||
os_ << setw(indent_) << "" << "vvm_binop_idiv(" << result
|
||||
<< "," << lres << "," << rres << ");" << endl;
|
||||
break;
|
||||
case '%':
|
||||
os_ << setw(indent_) << "" << result << " = vvm_binop_imod("
|
||||
<< lres << "," << rres << ");" << endl;
|
||||
os_ << setw(indent_) << "" << "vvm_binop_imod(" << result
|
||||
<< "," << lres << "," << rres << ");" << endl;
|
||||
break;
|
||||
default:
|
||||
cerr << "vvm: Unhandled binary op `" << expr->op() << "': "
|
||||
|
|
@ -1246,6 +1247,44 @@ void target_vvm::lpm_compare(ostream&os, const NetCompare*gate)
|
|||
}
|
||||
}
|
||||
|
||||
void target_vvm::lpm_divide(ostream&os, const NetDivide*mul)
|
||||
{
|
||||
string mname = mangle(mul->name());
|
||||
|
||||
os << "static vvm_idiv " << mname << "(" << mul->width_r() <<
|
||||
"," << mul->width_a() << "," << mul->width_b() << ");" << endl;
|
||||
|
||||
|
||||
/* Connect the DataA inputs... */
|
||||
for (unsigned idx = 0 ; idx < mul->width_a() ; idx += 1) {
|
||||
string nexus = nexus_from_link(&mul->pin_DataA(idx));
|
||||
unsigned ncode = nexus_wire_map[nexus];
|
||||
|
||||
init_code << " nexus_wire_table["<<ncode<<"].connect(&"
|
||||
<< mname << ", " << mname << ".key_DataA("
|
||||
<< idx << "));" << endl;
|
||||
}
|
||||
|
||||
/* Connect the DataB inputs... */
|
||||
for (unsigned idx = 0 ; idx < mul->width_b() ; idx += 1) {
|
||||
string nexus = nexus_from_link(&mul->pin_DataB(idx));
|
||||
unsigned ncode = nexus_wire_map[nexus];
|
||||
|
||||
init_code << " nexus_wire_table["<<ncode<<"].connect(&"
|
||||
<< mname << ", " << mname << ".key_DataB("
|
||||
<< idx << "));" << endl;
|
||||
}
|
||||
|
||||
/* Connect the output pins... */
|
||||
for (unsigned idx = 0 ; idx < mul->width_r() ; idx += 1) {
|
||||
string nexus = nexus_from_link(&mul->pin_Result(idx));
|
||||
unsigned ncode = nexus_wire_map[nexus];
|
||||
|
||||
init_code << " nexus_wire_table["<<ncode<<"].connect("
|
||||
<< mname << ".config_rout(" << idx << "));" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
void target_vvm::lpm_ff(ostream&os, const NetFF*gate)
|
||||
{
|
||||
string nexus;
|
||||
|
|
@ -2489,6 +2528,9 @@ extern const struct target tgt_vvm = {
|
|||
};
|
||||
/*
|
||||
* $Log: t-vvm.cc,v $
|
||||
* Revision 1.128 2000/04/01 21:40:23 steve
|
||||
* Add support for integer division.
|
||||
*
|
||||
* Revision 1.127 2000/03/29 04:37:11 steve
|
||||
* New and improved combinational primitives.
|
||||
*
|
||||
|
|
|
|||
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.31 2000/03/29 04:37:11 steve Exp $"
|
||||
#ident "$Id: target.cc,v 1.32 2000/04/01 21:40:23 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "target.h"
|
||||
|
|
@ -97,6 +97,12 @@ void target_t::lpm_compare(ostream&, const NetCompare*)
|
|||
"Unhandled NetCompare." << endl;
|
||||
}
|
||||
|
||||
void target_t::lpm_divide(ostream&, const NetDivide*)
|
||||
{
|
||||
cerr << "target (" << typeid(*this).name() << "): "
|
||||
"Unhandled NetDivide." << endl;
|
||||
}
|
||||
|
||||
void target_t::lpm_ff(ostream&, const NetFF*)
|
||||
{
|
||||
cerr << "target (" << typeid(*this).name() << "): "
|
||||
|
|
@ -320,6 +326,9 @@ void expr_scan_t::expr_binary(const NetEBinary*ex)
|
|||
|
||||
/*
|
||||
* $Log: target.cc,v $
|
||||
* Revision 1.32 2000/04/01 21:40:23 steve
|
||||
* Add support for integer division.
|
||||
*
|
||||
* Revision 1.31 2000/03/29 04:37:11 steve
|
||||
* New and improved combinational primitives.
|
||||
*
|
||||
|
|
|
|||
85
target.h
85
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.30 2000/03/29 04:37:11 steve Exp $"
|
||||
#ident "$Id: target.h,v 1.31 2000/04/01 21:40:23 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "netlist.h"
|
||||
|
|
@ -73,6 +73,7 @@ struct 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_divide(ostream&os, const NetDivide*);
|
||||
virtual void lpm_ff(ostream&os, const NetFF*);
|
||||
virtual void lpm_mult(ostream&os, const NetMult*);
|
||||
virtual void lpm_mux(ostream&os, const NetMux*);
|
||||
|
|
@ -148,6 +149,9 @@ extern const struct target *target_table[];
|
|||
|
||||
/*
|
||||
* $Log: target.h,v $
|
||||
* Revision 1.31 2000/04/01 21:40:23 steve
|
||||
* Add support for integer division.
|
||||
*
|
||||
* Revision 1.30 2000/03/29 04:37:11 steve
|
||||
* New and improved combinational primitives.
|
||||
*
|
||||
|
|
@ -192,84 +196,5 @@ extern const struct target *target_table[];
|
|||
*
|
||||
* 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.
|
||||
*
|
||||
* Revision 1.18 1999/09/15 01:55:06 steve
|
||||
* Elaborate non-blocking assignment to memories.
|
||||
*
|
||||
* Revision 1.17 1999/09/03 04:28:38 steve
|
||||
* elaborate the binary plus operator.
|
||||
*
|
||||
* Revision 1.16 1999/08/31 22:38:29 steve
|
||||
* Elaborate and emit to vvm procedural functions.
|
||||
*
|
||||
* Revision 1.15 1999/07/17 19:51:00 steve
|
||||
* netlist support for ternary operator.
|
||||
*
|
||||
* Revision 1.14 1999/07/17 03:39:11 steve
|
||||
* simplified process scan for targets.
|
||||
*
|
||||
* Revision 1.13 1999/07/03 02:12:52 steve
|
||||
* Elaborate user defined tasks.
|
||||
*
|
||||
* Revision 1.12 1999/06/19 21:06:16 steve
|
||||
* Elaborate and supprort to vvm the forever
|
||||
* and repeat statements.
|
||||
*
|
||||
* Revision 1.11 1999/06/09 03:00:06 steve
|
||||
* Add support for procedural concatenation expression.
|
||||
*
|
||||
* Revision 1.10 1999/06/06 20:45:39 steve
|
||||
* Add parse and elaboration of non-blocking assignments,
|
||||
* Replace list<PCase::Item*> with an svector version,
|
||||
* Add integer support.
|
||||
*
|
||||
* Revision 1.9 1999/05/12 04:03:20 steve
|
||||
* emit NetAssignMem objects in vvm target.
|
||||
*
|
||||
* Revision 1.8 1999/05/01 02:57:53 steve
|
||||
* Handle much more complex event expressions.
|
||||
*
|
||||
* Revision 1.7 1999/04/25 00:44:10 steve
|
||||
* Core handles subsignal expressions.
|
||||
*
|
||||
* Revision 1.6 1999/04/19 01:59:37 steve
|
||||
* Add memories to the parse and elaboration phases.
|
||||
*
|
||||
* Revision 1.5 1999/02/08 02:49:56 steve
|
||||
* Turn the NetESignal into a NetNode so
|
||||
* that it can connect to the netlist.
|
||||
* Implement the case statement.
|
||||
* Convince t-vvm to output code for
|
||||
* the case statement.
|
||||
*
|
||||
* Revision 1.4 1998/12/01 00:42:15 steve
|
||||
* Elaborate UDP devices,
|
||||
* Support UDP type attributes, and
|
||||
* pass those attributes to nodes that
|
||||
* are instantiated by elaboration,
|
||||
* Put modules into a map instead of
|
||||
* a simple list.
|
||||
*
|
||||
* Revision 1.3 1998/11/09 18:55:35 steve
|
||||
* Add procedural while loops,
|
||||
* Parse procedural for loops,
|
||||
* Add procedural wait statements,
|
||||
* Add constant nodes,
|
||||
* Add XNOR logic gate,
|
||||
* Make vvm output look a bit prettier.
|
||||
*
|
||||
* Revision 1.2 1998/11/07 17:05:06 steve
|
||||
* Handle procedural conditional, and some
|
||||
* of the conditional expressions.
|
||||
*
|
||||
* Elaborate signals and identifiers differently,
|
||||
* allowing the netlist to hold signal information.
|
||||
*
|
||||
* Revision 1.1 1998/11/03 23:29:06 steve
|
||||
* Introduce verilog to CVS.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.27 2000/03/29 04:37:11 steve Exp $"
|
||||
#ident "$Id: Makefile.in,v 1.28 2000/04/01 21:40:23 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
|
@ -60,7 +60,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_func.o vvm_gates.o vvm_idiv.o vvm_mult.o vvm_mux.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 \
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: vvm_func.h,v 1.27 2000/03/26 16:55:41 steve Exp $"
|
||||
#ident "$Id: vvm_func.h,v 1.28 2000/04/01 21:40:23 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vvm.h"
|
||||
|
|
@ -86,6 +86,13 @@ extern void vvm_binop_plus(vvm_bitset_t&v,
|
|||
const vvm_bitset_t&l,
|
||||
const vvm_bitset_t&r);
|
||||
|
||||
/*
|
||||
* Integer division.
|
||||
*/
|
||||
extern void vvm_binop_idiv(vvm_bitset_t&v,
|
||||
const vvm_bitset_t&l,
|
||||
const vvm_bitset_t&r);
|
||||
|
||||
/*
|
||||
* The binary - operator is turned into + by doing 2's complement
|
||||
* arithmetic. l-r == l+~r+1. The "+1" is accomplished by adding in a
|
||||
|
|
@ -196,6 +203,9 @@ extern void vvm_ternary(vvm_bitset_t&v, vpip_bit_t c,
|
|||
|
||||
/*
|
||||
* $Log: vvm_func.h,v $
|
||||
* Revision 1.28 2000/04/01 21:40:23 steve
|
||||
* Add support for integer division.
|
||||
*
|
||||
* Revision 1.27 2000/03/26 16:55:41 steve
|
||||
* Remove the vvm_bits_t abstract class.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.53 2000/03/29 04:37:11 steve Exp $"
|
||||
#ident "$Id: vvm_gates.h,v 1.54 2000/04/01 21:40:23 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vvm.h"
|
||||
|
|
@ -279,6 +279,34 @@ class vvm_ff : public vvm_nexus::recvr_t {
|
|||
vvm_ff& operator= (const vvm_ff&);
|
||||
};
|
||||
|
||||
/*
|
||||
* This class behaves like a combinational divider. There isn't really
|
||||
* such a practical device, but this is useful for simulating code
|
||||
* that includes a / operator in structural contexts.
|
||||
*/
|
||||
class vvm_idiv : public vvm_nexus::recvr_t {
|
||||
|
||||
public:
|
||||
explicit vvm_idiv(unsigned rwid, unsigned awid, unsigned bwid);
|
||||
~vvm_idiv();
|
||||
|
||||
void init_DataA(unsigned idx, vpip_bit_t val);
|
||||
void init_DataB(unsigned idx, vpip_bit_t val);
|
||||
|
||||
vvm_nexus::drive_t* config_rout(unsigned idx);
|
||||
unsigned key_DataA(unsigned idx) const;
|
||||
unsigned key_DataB(unsigned idx) const;
|
||||
|
||||
private:
|
||||
void take_value(unsigned key, vpip_bit_t val);
|
||||
|
||||
unsigned rwid_;
|
||||
unsigned awid_;
|
||||
unsigned bwid_;
|
||||
vpip_bit_t*bits_;
|
||||
vvm_nexus::drive_t*out_;
|
||||
};
|
||||
|
||||
/*
|
||||
* This class behaves like a combinational multiplier. The device
|
||||
* behaves like the LPM_MULT device.
|
||||
|
|
@ -839,6 +867,9 @@ template <unsigned WIDTH> class vvm_pevent : public vvm_nexus::recvr_t {
|
|||
|
||||
/*
|
||||
* $Log: vvm_gates.h,v $
|
||||
* Revision 1.54 2000/04/01 21:40:23 steve
|
||||
* Add support for integer division.
|
||||
*
|
||||
* Revision 1.53 2000/03/29 04:37:11 steve
|
||||
* New and improved combinational primitives.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* 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_idiv.cc,v 1.1 2000/04/01 21:40:23 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vvm_func.h"
|
||||
# include "vvm_gates.h"
|
||||
# include <assert.h>
|
||||
|
||||
void vvm_binop_idiv(vvm_bitset_t&v, const vvm_bitset_t&l, const vvm_bitset_t&r)
|
||||
{
|
||||
assert(v.get_width() <= 8*sizeof(unsigned long));
|
||||
assert(l.get_width() <= 8*sizeof(unsigned long));
|
||||
assert(r.get_width() <= 8*sizeof(unsigned long));
|
||||
|
||||
unsigned long lv = 0, rv = 0;
|
||||
unsigned long vv;
|
||||
|
||||
for (unsigned idx = 0 ; idx < l.get_width() ; idx += 1) {
|
||||
|
||||
if (B_ISXZ(l[idx]))
|
||||
goto unknown_result;
|
||||
|
||||
if (B_IS1(l[idx]))
|
||||
lv |= 1 << idx;
|
||||
}
|
||||
|
||||
for (unsigned idx = 0 ; idx < r.get_width() ; idx += 1) {
|
||||
|
||||
if (B_ISXZ(r[idx]))
|
||||
goto unknown_result;
|
||||
|
||||
if (B_IS1(r[idx]))
|
||||
rv |= 1 << idx;
|
||||
}
|
||||
|
||||
if (rv == 0)
|
||||
goto unknown_result;
|
||||
|
||||
vv = lv / rv;
|
||||
|
||||
for (unsigned idx = 0 ; idx < v.get_width() ; idx += 1) {
|
||||
|
||||
if (vv & 1)
|
||||
v[idx] = St1;
|
||||
else
|
||||
v[idx] = St0;
|
||||
|
||||
vv >>= 1;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
unknown_result:
|
||||
for (unsigned idx= 0 ; idx < v.get_width() ; idx += 1)
|
||||
v[idx] = StX;
|
||||
}
|
||||
|
||||
|
||||
vvm_idiv::vvm_idiv(unsigned rwid, unsigned awid, unsigned bwid)
|
||||
: rwid_(rwid), awid_(awid), bwid_(bwid)
|
||||
{
|
||||
bits_ = new vpip_bit_t[rwid_+awid_+bwid_];
|
||||
for (unsigned idx = 0 ; idx < rwid_+awid_+bwid_ ; idx += 1)
|
||||
bits_[idx] = StX;
|
||||
|
||||
out_ = new vvm_nexus::drive_t[rwid];
|
||||
}
|
||||
|
||||
vvm_idiv::~vvm_idiv()
|
||||
{
|
||||
delete[]out_;
|
||||
delete[]bits_;
|
||||
}
|
||||
|
||||
void vvm_idiv::init_DataA(unsigned idx, vpip_bit_t val)
|
||||
{
|
||||
assert(idx < awid_);
|
||||
bits_[rwid_+idx] = val;
|
||||
}
|
||||
|
||||
void vvm_idiv::init_DataB(unsigned idx, vpip_bit_t val)
|
||||
{
|
||||
assert(idx < bwid_);
|
||||
bits_[rwid_+awid_+idx] = val;
|
||||
}
|
||||
|
||||
vvm_nexus::drive_t* vvm_idiv::config_rout(unsigned idx)
|
||||
{
|
||||
assert(idx < rwid_);
|
||||
return out_+idx;
|
||||
}
|
||||
|
||||
unsigned vvm_idiv::key_DataA(unsigned idx) const
|
||||
{
|
||||
assert(idx < awid_);
|
||||
return rwid_+idx;
|
||||
}
|
||||
|
||||
unsigned vvm_idiv::key_DataB(unsigned idx) const
|
||||
{
|
||||
assert(idx < bwid_);
|
||||
return rwid_+awid_+idx;
|
||||
}
|
||||
|
||||
void vvm_idiv::take_value(unsigned key, vpip_bit_t val)
|
||||
{
|
||||
if (B_EQ(bits_[key], val)) {
|
||||
bits_[key] = val;
|
||||
return;
|
||||
}
|
||||
|
||||
bits_[key] = val;
|
||||
|
||||
vvm_bitset_t r (bits_, rwid_);
|
||||
vvm_bitset_t a (bits_+rwid_, awid_);
|
||||
vvm_bitset_t b (bits_+rwid_+awid_, bwid_);
|
||||
vvm_binop_idiv(r, a, b);
|
||||
|
||||
for (unsigned idx = 0 ; idx < rwid_ ; idx += 1)
|
||||
out_[idx].set_value(bits_[idx]);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: vvm_idiv.cc,v $
|
||||
* Revision 1.1 2000/04/01 21:40:23 steve
|
||||
* Add support for integer division.
|
||||
*
|
||||
*/
|
||||
|
||||
Loading…
Reference in New Issue