Add support for force assignment.
This commit is contained in:
parent
ad8811282b
commit
44838f8973
26
Statement.cc
26
Statement.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: Statement.cc,v 1.19 2000/04/12 04:23:57 steve Exp $"
|
||||
#ident "$Id: Statement.cc,v 1.20 2000/04/22 04:20:19 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "Statement.h"
|
||||
|
|
@ -167,6 +167,17 @@ void PEventStatement::set_statement(Statement*st)
|
|||
statement_ = st;
|
||||
}
|
||||
|
||||
PForce::PForce(PExpr*l, PExpr*r)
|
||||
: lval_(l), expr_(r)
|
||||
{
|
||||
}
|
||||
|
||||
PForce::~PForce()
|
||||
{
|
||||
delete lval_;
|
||||
delete expr_;
|
||||
}
|
||||
|
||||
PForever::PForever(Statement*s)
|
||||
: statement_(s)
|
||||
{
|
||||
|
|
@ -182,6 +193,16 @@ PProcess::~PProcess()
|
|||
delete statement_;
|
||||
}
|
||||
|
||||
PRelease::PRelease(PExpr*l)
|
||||
: lval_(l)
|
||||
{
|
||||
}
|
||||
|
||||
PRelease::~PRelease()
|
||||
{
|
||||
delete lval_;
|
||||
}
|
||||
|
||||
PRepeat::PRepeat(PExpr*e, Statement*s)
|
||||
: expr_(e), statement_(s)
|
||||
{
|
||||
|
|
@ -210,6 +231,9 @@ PWhile::~PWhile()
|
|||
|
||||
/*
|
||||
* $Log: Statement.cc,v $
|
||||
* Revision 1.20 2000/04/22 04:20:19 steve
|
||||
* Add support for force assignment.
|
||||
*
|
||||
* Revision 1.19 2000/04/12 04:23:57 steve
|
||||
* Named events really should be expressed with PEIdent
|
||||
* objects in the pform,
|
||||
|
|
|
|||
32
Statement.h
32
Statement.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: Statement.h,v 1.24 2000/04/12 04:23:57 steve Exp $"
|
||||
#ident "$Id: Statement.h,v 1.25 2000/04/22 04:20:19 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <string>
|
||||
|
|
@ -288,6 +288,20 @@ class PEventStatement : public Statement {
|
|||
Statement*statement_;
|
||||
};
|
||||
|
||||
class PForce : public Statement {
|
||||
|
||||
public:
|
||||
explicit PForce(PExpr*l, PExpr*r);
|
||||
~PForce();
|
||||
|
||||
virtual NetProc* elaborate(Design*des, const string&path) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
PExpr*lval_;
|
||||
PExpr*expr_;
|
||||
};
|
||||
|
||||
class PForever : public Statement {
|
||||
public:
|
||||
explicit PForever(Statement*s);
|
||||
|
|
@ -346,6 +360,19 @@ class PRepeat : public Statement {
|
|||
Statement*statement_;
|
||||
};
|
||||
|
||||
class PRelease : public Statement {
|
||||
|
||||
public:
|
||||
explicit PRelease(PExpr*l);
|
||||
~PRelease();
|
||||
|
||||
virtual NetProc* elaborate(Design*des, const string&path) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
PExpr*lval_;
|
||||
};
|
||||
|
||||
/*
|
||||
* The PTrigger statement sends a trigger to a named event. Take the
|
||||
* name here.
|
||||
|
|
@ -381,6 +408,9 @@ class PWhile : public Statement {
|
|||
|
||||
/*
|
||||
* $Log: Statement.h,v $
|
||||
* Revision 1.25 2000/04/22 04:20:19 steve
|
||||
* Add support for force assignment.
|
||||
*
|
||||
* Revision 1.24 2000/04/12 04:23:57 steve
|
||||
* Named events really should be expressed with PEIdent
|
||||
* objects in 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.76 2000/04/12 20:02:52 steve Exp $"
|
||||
#ident "$Id: design_dump.cc,v 1.77 2000/04/22 04:20:19 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -154,6 +154,12 @@ void NetDivide::dump_node(ostream&o, unsigned ind) const
|
|||
dump_obj_attr(o, ind+4);
|
||||
}
|
||||
|
||||
void NetForce::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "force " << lval_->name() << endl;
|
||||
dump_node_pins(o, ind+4);
|
||||
}
|
||||
|
||||
void NetMult::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "LPM_MULT (NetMult): " << name() << endl;
|
||||
|
|
@ -546,6 +552,12 @@ void NetEvWait::dump(ostream&o, unsigned ind) const
|
|||
o << setw(ind+2) << "" << "/* noop */ ;" << endl;
|
||||
}
|
||||
|
||||
void NetForce::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "force " << lval_->name() << " = "
|
||||
<< name() << ";" << endl;
|
||||
}
|
||||
|
||||
void NetForever::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "forever" << endl;
|
||||
|
|
@ -890,6 +902,9 @@ void Design::dump(ostream&o) const
|
|||
|
||||
/*
|
||||
* $Log: design_dump.cc,v $
|
||||
* Revision 1.77 2000/04/22 04:20:19 steve
|
||||
* Add support for force assignment.
|
||||
*
|
||||
* Revision 1.76 2000/04/12 20:02:52 steve
|
||||
* Finally remove the NetNEvent and NetPEvent classes,
|
||||
* Get synthesis working with the NetEvWait class,
|
||||
|
|
|
|||
38
elaborate.cc
38
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.160 2000/04/21 04:38:15 steve Exp $"
|
||||
#ident "$Id: elaborate.cc,v 1.161 2000/04/22 04:20:19 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -1802,6 +1802,32 @@ NetProc* PForever::elaborate(Design*des, const string&path) const
|
|||
return proc;
|
||||
}
|
||||
|
||||
NetProc* PForce::elaborate(Design*des, const string&path) const
|
||||
{
|
||||
NetScope*scope = des->find_scope(path);
|
||||
assert(scope);
|
||||
|
||||
NetNet*lval = lval_->elaborate_net(des, path, 0, 0, 0, 0);
|
||||
if (lval == 0)
|
||||
return 0;
|
||||
|
||||
NetNet*rval = expr_->elaborate_net(des, path, lval->pin_count(),
|
||||
0, 0, 0);
|
||||
if (rval == 0)
|
||||
return 0;
|
||||
|
||||
if (rval->pin_count() < lval->pin_count())
|
||||
rval = pad_to_width(des, path, rval, lval->pin_count());
|
||||
|
||||
NetForce* dev = new NetForce(des->local_symbol(path), lval);
|
||||
des->add_node(dev);
|
||||
|
||||
for (unsigned idx = 0 ; idx < dev->pin_count() ; idx += 1)
|
||||
connect(dev->pin(idx), rval->pin(idx));
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
/*
|
||||
* elaborate the for loop as the equivalent while loop. This eases the
|
||||
* task for the target code generator. The structure is:
|
||||
|
|
@ -1941,6 +1967,13 @@ void PFunction::elaborate_2(Design*des, NetScope*scope) const
|
|||
def->set_proc(st);
|
||||
}
|
||||
|
||||
NetProc* PRelease::elaborate(Design*des, const string&path) const
|
||||
{
|
||||
cerr << get_line() << ": sorry: I do not elaborate release yet."
|
||||
<< endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetProc* PRepeat::elaborate(Design*des, const string&path) const
|
||||
{
|
||||
NetScope*scope = des->find_scope(path);
|
||||
|
|
@ -2228,6 +2261,9 @@ Design* elaborate(const map<string,Module*>&modules,
|
|||
|
||||
/*
|
||||
* $Log: elaborate.cc,v $
|
||||
* Revision 1.161 2000/04/22 04:20:19 steve
|
||||
* Add support for force assignment.
|
||||
*
|
||||
* Revision 1.160 2000/04/21 04:38:15 steve
|
||||
* Bit padding in assignment to memory.
|
||||
*
|
||||
|
|
|
|||
15
emit.cc
15
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.39 2000/04/12 04:23:58 steve Exp $"
|
||||
#ident "$Id: emit.cc,v 1.40 2000/04/22 04:20:19 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -95,6 +95,11 @@ void NetFF::emit_node(ostream&o, struct target_t*tgt) const
|
|||
tgt->lpm_ff(o, this);
|
||||
}
|
||||
|
||||
void NetForce::emit_node(ostream&o, struct target_t*tgt) const
|
||||
{
|
||||
tgt->net_force(o, this);
|
||||
}
|
||||
|
||||
void NetMult::emit_node(ostream&o, struct target_t*tgt) const
|
||||
{
|
||||
tgt->lpm_mult(o, this);
|
||||
|
|
@ -167,6 +172,11 @@ bool NetCondit::emit_proc(ostream&o, struct target_t*tgt) const
|
|||
return true;
|
||||
}
|
||||
|
||||
bool NetForce::emit_proc(ostream&o, struct target_t*tgt) const
|
||||
{
|
||||
return tgt->proc_force(o, this);
|
||||
}
|
||||
|
||||
bool NetForever::emit_proc(ostream&o, struct target_t*tgt) const
|
||||
{
|
||||
tgt->proc_forever(o, this);
|
||||
|
|
@ -416,6 +426,9 @@ bool emit(ostream&o, const Design*des, const char*type)
|
|||
|
||||
/*
|
||||
* $Log: emit.cc,v $
|
||||
* Revision 1.40 2000/04/22 04:20:19 steve
|
||||
* Add support for force assignment.
|
||||
*
|
||||
* Revision 1.39 2000/04/12 04:23:58 steve
|
||||
* Named events really should be expressed with PEIdent
|
||||
* objects in the pform,
|
||||
|
|
|
|||
24
netlist.cc
24
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.116 2000/04/18 01:02:54 steve Exp $"
|
||||
#ident "$Id: netlist.cc,v 1.117 2000/04/22 04:20:19 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <cassert>
|
||||
|
|
@ -1735,6 +1735,25 @@ verinum::V NetConst::value(unsigned idx) const
|
|||
return value_[idx];
|
||||
}
|
||||
|
||||
NetForce::NetForce(const string&n, NetNet*l)
|
||||
: NetNode(n, l->pin_count()), lval_(l)
|
||||
{
|
||||
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
|
||||
pin(idx).set_dir(Link::INPUT);
|
||||
pin(idx).set_name("I", idx);
|
||||
}
|
||||
}
|
||||
|
||||
NetForce::~NetForce()
|
||||
{
|
||||
}
|
||||
|
||||
const NetObj::Link& NetForce::lval_pin(unsigned idx) const
|
||||
{
|
||||
assert(idx < lval_->pin_count());
|
||||
return lval_->pin(idx);
|
||||
}
|
||||
|
||||
NetFuncDef::NetFuncDef(NetScope*s, const svector<NetNet*>&po)
|
||||
: scope_(s), statement_(0), ports_(po)
|
||||
{
|
||||
|
|
@ -2483,6 +2502,9 @@ bool NetUDP::sequ_glob_(string input, char output)
|
|||
|
||||
/*
|
||||
* $Log: netlist.cc,v $
|
||||
* Revision 1.117 2000/04/22 04:20:19 steve
|
||||
* Add support for force assignment.
|
||||
*
|
||||
* Revision 1.116 2000/04/18 01:02:54 steve
|
||||
* Minor cleanup of NetTaskDef.
|
||||
*
|
||||
|
|
|
|||
32
netlist.h
32
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.126 2000/04/20 00:28:03 steve Exp $"
|
||||
#ident "$Id: netlist.h,v 1.127 2000/04/22 04:20:19 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -1401,6 +1401,33 @@ class NetEvProbe : public NetNode {
|
|||
NetEvProbe*enext_;
|
||||
};
|
||||
|
||||
/*
|
||||
* The force statement causes the r-val net to be forced onto the
|
||||
* l-val net when it is executed. The code generator is expected to
|
||||
* know what that means. All the expressions are structural and behave
|
||||
* like nets.
|
||||
*
|
||||
* This class is a NetProc because it it turned on by procedural
|
||||
* behavior. However, it is also a NetNode because it connects to
|
||||
* nets, and when activated follows the net values.
|
||||
*/
|
||||
class NetForce : public NetProc, public NetNode {
|
||||
|
||||
public:
|
||||
explicit NetForce(const string&n, NetNet*l);
|
||||
~NetForce();
|
||||
|
||||
const NetObj::Link& lval_pin(unsigned) const;
|
||||
|
||||
virtual void dump(ostream&, unsigned ind) const;
|
||||
virtual bool emit_proc(ostream&, struct target_t*) const;
|
||||
virtual void dump_node(ostream&, unsigned ind) const;
|
||||
virtual void emit_node(ostream&, struct target_t*) const;
|
||||
|
||||
private:
|
||||
NetNet*lval_;
|
||||
};
|
||||
|
||||
/*
|
||||
* A forever statement is executed over and over again forever. Or
|
||||
* until its block is disabled.
|
||||
|
|
@ -2391,6 +2418,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
|
|||
|
||||
/*
|
||||
* $Log: netlist.h,v $
|
||||
* Revision 1.127 2000/04/22 04:20:19 steve
|
||||
* Add support for force assignment.
|
||||
*
|
||||
* Revision 1.126 2000/04/20 00:28:03 steve
|
||||
* Catch some simple identity compareoptimizations.
|
||||
*
|
||||
|
|
|
|||
14
parse.y
14
parse.y
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: parse.y,v 1.91 2000/04/21 03:22:18 steve Exp $"
|
||||
#ident "$Id: parse.y,v 1.92 2000/04/22 04:20:19 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "parse_misc.h"
|
||||
|
|
@ -1671,8 +1671,10 @@ statement
|
|||
$$ = 0;
|
||||
}
|
||||
| K_force lavalue '=' expression ';'
|
||||
{ yyerror(@1, "sorry: procedural force assign not supported.");
|
||||
$$ = 0;
|
||||
{ PForce*tmp = new PForce($2, $4);
|
||||
tmp->set_file(@1.text);
|
||||
tmp->set_lineno(@1.first_line);
|
||||
$$ = tmp;
|
||||
}
|
||||
| K_TRIGGER IDENTIFIER ';'
|
||||
{ PTrigger*tmp = new PTrigger($2);
|
||||
|
|
@ -1718,8 +1720,10 @@ statement
|
|||
$$ = tmp;
|
||||
}
|
||||
| K_release lavalue ';'
|
||||
{ yyerror(@1, "sorry: release not supported.");
|
||||
$$ = 0;
|
||||
{ PRelease*tmp = new PRelease($2);
|
||||
tmp->set_file(@1.text);
|
||||
tmp->set_lineno(@1.first_line);
|
||||
$$ = tmp;
|
||||
}
|
||||
| K_repeat '(' expression ')' statement
|
||||
{ PRepeat*tmp = new PRepeat($3, $5);
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: pform_dump.cc,v 1.54 2000/04/12 20:02:53 steve Exp $"
|
||||
#ident "$Id: pform_dump.cc,v 1.55 2000/04/22 04:20:19 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -483,6 +483,12 @@ void PEventStatement::dump(ostream&out, unsigned ind) const
|
|||
}
|
||||
}
|
||||
|
||||
void PForce::dump(ostream&out, unsigned ind) const
|
||||
{
|
||||
out << setw(ind) << "" << "force " << *lval_ << " = " << *expr_
|
||||
<< "; /* " << get_line() << " */" << endl;
|
||||
}
|
||||
|
||||
void PForever::dump(ostream&out, unsigned ind) const
|
||||
{
|
||||
out << setw(ind) << "" << "forever /* " << get_line() << " */" << endl;
|
||||
|
|
@ -512,6 +518,12 @@ void PFunction::dump(ostream&out, unsigned ind) const
|
|||
out << setw(ind) << "" << "/* NOOP */" << endl;
|
||||
}
|
||||
|
||||
void PRelease::dump(ostream&out, unsigned ind) const
|
||||
{
|
||||
out << setw(ind) << "" << "release " << *lval_ << "; /* "
|
||||
<< get_line() << " */" << endl;
|
||||
}
|
||||
|
||||
void PRepeat::dump(ostream&out, unsigned ind) const
|
||||
{
|
||||
out << setw(ind) << "" << "repeat (" << *expr_ << ")" << endl;
|
||||
|
|
@ -733,6 +745,9 @@ void PUdp::dump(ostream&out) const
|
|||
|
||||
/*
|
||||
* $Log: pform_dump.cc,v $
|
||||
* Revision 1.55 2000/04/22 04:20:19 steve
|
||||
* Add support for force assignment.
|
||||
*
|
||||
* Revision 1.54 2000/04/12 20:02:53 steve
|
||||
* Finally remove the NetNEvent and NetPEvent classes,
|
||||
* Get synthesis working with the NetEvWait class,
|
||||
|
|
|
|||
42
t-vvm.cc
42
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.137 2000/04/15 19:51:30 steve Exp $"
|
||||
#ident "$Id: t-vvm.cc,v 1.138 2000/04/22 04:20:19 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <iostream>
|
||||
|
|
@ -80,6 +80,7 @@ class target_vvm : public target_t {
|
|||
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 bool net_force(ostream&os, const NetForce*);
|
||||
virtual void net_probe(ostream&os, const NetEvProbe*);
|
||||
virtual bool process(ostream&os, const NetProcTop*);
|
||||
virtual void proc_assign(ostream&os, const NetAssign*);
|
||||
|
|
@ -91,6 +92,7 @@ class target_vvm : public target_t {
|
|||
void proc_case_fun(ostream&os, const NetCase*net);
|
||||
virtual void proc_condit(ostream&os, const NetCondit*);
|
||||
void proc_condit_fun(ostream&os, const NetCondit*);
|
||||
virtual bool proc_force(ostream&os, const NetForce*);
|
||||
virtual void proc_forever(ostream&os, const NetForever*);
|
||||
virtual void proc_repeat(ostream&os, const NetRepeat*);
|
||||
virtual void proc_stask(ostream&os, const NetSTask*);
|
||||
|
|
@ -802,7 +804,7 @@ void target_vvm::end_design(ostream&os, const Design*mod)
|
|||
os << "static struct __vpiNumberConst number_table[" <<
|
||||
number_counter+1 << "];" << endl;
|
||||
if (nexus_wire_counter > 0)
|
||||
os << "static vvm_nexus_wire nexus_wire_table[" <<
|
||||
os << "static vvm_nexus nexus_wire_table[" <<
|
||||
nexus_wire_counter << "];" << endl;
|
||||
if (signal_bit_counter > 0)
|
||||
os << "static vpip_bit_t signal_bit_table[" <<
|
||||
|
|
@ -1734,6 +1736,24 @@ void target_vvm::net_const(ostream&os, const NetConst*gate)
|
|||
}
|
||||
|
||||
|
||||
bool target_vvm::net_force(ostream&os, const NetForce*dev)
|
||||
{
|
||||
string mname = mangle(dev->name());
|
||||
|
||||
os << "static vvm_force " << mname << "(" << dev->pin_count()
|
||||
<< ");" << endl;
|
||||
|
||||
for (unsigned idx = 0 ; idx < dev->pin_count() ; idx += 1) {
|
||||
string nexus = nexus_from_link(&dev->pin(idx));
|
||||
unsigned ncode = nexus_wire_map[nexus];
|
||||
|
||||
init_code << " nexus_wire_table["<<ncode<<"].connect(&"
|
||||
<< mname << ", " << idx << ");" << endl;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void target_vvm::net_probe(ostream&os, const NetEvProbe*net)
|
||||
{
|
||||
string mname = mangle(net->name());
|
||||
|
|
@ -2310,6 +2330,21 @@ void target_vvm::proc_condit_fun(ostream&os, const NetCondit*net)
|
|||
defn << " }" << endl;
|
||||
}
|
||||
|
||||
bool target_vvm::proc_force(ostream&os, const NetForce*dev)
|
||||
{
|
||||
const string mname = mangle(dev->name());
|
||||
|
||||
for (unsigned idx = 0 ; idx < dev->pin_count() ; idx += 1) {
|
||||
string nexus = nexus_from_link(&dev->lval_pin(idx));
|
||||
unsigned ncode = nexus_wire_map[nexus];
|
||||
|
||||
defn << " " << mname << ".force("<<idx<<", "
|
||||
<< "nexus_wire_table+"<<ncode << ");" << endl;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* The forever loop is implemented by starting a basic block, handing
|
||||
* the statement, and putting in a goto to the beginning of the block.
|
||||
|
|
@ -2626,6 +2661,9 @@ extern const struct target tgt_vvm = {
|
|||
};
|
||||
/*
|
||||
* $Log: t-vvm.cc,v $
|
||||
* Revision 1.138 2000/04/22 04:20:19 steve
|
||||
* Add support for force assignment.
|
||||
*
|
||||
* Revision 1.137 2000/04/15 19:51:30 steve
|
||||
* fork-join support in vvm.
|
||||
*
|
||||
|
|
|
|||
19
target.cc
19
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.35 2000/04/12 04:23:58 steve Exp $"
|
||||
#ident "$Id: target.cc,v 1.36 2000/04/22 04:20:19 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "target.h"
|
||||
|
|
@ -155,6 +155,13 @@ void target_t::net_const(ostream&os, const NetConst*)
|
|||
"Unhandled CONSTANT node." << endl;
|
||||
}
|
||||
|
||||
bool target_t::net_force(ostream&os, const NetForce*dev)
|
||||
{
|
||||
cerr << "target (" << typeid(*this).name() << "): "
|
||||
"Unhandled NetForce node." << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
void target_t::net_probe(ostream&os, const NetEvProbe*net)
|
||||
{
|
||||
cerr << "target (" << typeid(*this).name() << "): "
|
||||
|
|
@ -218,6 +225,13 @@ void target_t::proc_delay(ostream&os, const NetPDelay*)
|
|||
"Unhandled proc_delay." << endl;
|
||||
}
|
||||
|
||||
bool target_t::proc_force(ostream&os, const NetForce*dev)
|
||||
{
|
||||
cerr << "target (" << typeid(*this).name() << "): "
|
||||
"Unhandled proc_force." << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
void target_t::proc_forever(ostream&os, const NetForever*)
|
||||
{
|
||||
cerr << "target (" << typeid(*this).name() << "): "
|
||||
|
|
@ -339,6 +353,9 @@ void expr_scan_t::expr_binary(const NetEBinary*ex)
|
|||
|
||||
/*
|
||||
* $Log: target.cc,v $
|
||||
* Revision 1.36 2000/04/22 04:20:19 steve
|
||||
* Add support for force assignment.
|
||||
*
|
||||
* Revision 1.35 2000/04/12 04:23:58 steve
|
||||
* Named events really should be expressed with PEIdent
|
||||
* objects in the pform,
|
||||
|
|
|
|||
7
target.h
7
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.34 2000/04/12 04:23:58 steve Exp $"
|
||||
#ident "$Id: target.h,v 1.35 2000/04/22 04:20:20 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "netlist.h"
|
||||
|
|
@ -91,6 +91,7 @@ struct target_t {
|
|||
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 bool net_force(ostream&os, const NetForce*);
|
||||
virtual void net_probe(ostream&os, const NetEvProbe*);
|
||||
|
||||
/* Output a process (called for each process). It is up to the
|
||||
|
|
@ -105,6 +106,7 @@ struct target_t {
|
|||
virtual bool proc_block(ostream&os, const NetBlock*);
|
||||
virtual void proc_case(ostream&os, const NetCase*);
|
||||
virtual void proc_condit(ostream&os, const NetCondit*);
|
||||
virtual bool proc_force(ostream&os, const NetForce*);
|
||||
virtual void proc_forever(ostream&os, const NetForever*);
|
||||
virtual void proc_repeat(ostream&os, const NetRepeat*);
|
||||
virtual bool proc_trigger(ostream&os, const NetEvTrig*);
|
||||
|
|
@ -152,6 +154,9 @@ extern const struct target *target_table[];
|
|||
|
||||
/*
|
||||
* $Log: target.h,v $
|
||||
* Revision 1.35 2000/04/22 04:20:20 steve
|
||||
* Add support for force assignment.
|
||||
*
|
||||
* Revision 1.34 2000/04/12 04:23:58 steve
|
||||
* Named events really should be expressed with PEIdent
|
||||
* objects in the pform,
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.28 2000/04/01 21:40:23 steve Exp $"
|
||||
#ident "$Id: Makefile.in,v 1.29 2000/04/22 04:20:20 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
|
@ -59,7 +59,7 @@ all: libvvm.a
|
|||
mv $*.d dep
|
||||
|
||||
O = vvm_add_sub.o vvm_bit.o vvm_calltf.o vvm_clshift.o vvm_compare.o \
|
||||
vvm_event.o vvm_ff.o \
|
||||
vvm_event.o vvm_ff.o vvm_force.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
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: vpi_priv.h,v 1.14 2000/03/31 07:08:39 steve Exp $"
|
||||
#ident "$Id: vpi_priv.h,v 1.15 2000/04/22 04:20:20 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -51,6 +51,8 @@ struct __vpirt;
|
|||
* 1xxx0xxx - Logic X
|
||||
* 00001000 - Logic Z
|
||||
*
|
||||
* 00000000 - Invalid/No signal
|
||||
*
|
||||
* So as you can see, logic values can be quickly compared by masking
|
||||
* the strength bits.
|
||||
*
|
||||
|
|
@ -342,6 +344,9 @@ extern int vpip_finished();
|
|||
|
||||
/*
|
||||
* $Log: vpi_priv.h,v $
|
||||
* Revision 1.15 2000/04/22 04:20:20 steve
|
||||
* Add support for force assignment.
|
||||
*
|
||||
* Revision 1.14 2000/03/31 07:08:39 steve
|
||||
* allow cancelling of cbValueChange events.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* 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_force.cc,v 1.1 2000/04/22 04:20:20 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vvm_gates.h"
|
||||
# include <assert.h>
|
||||
|
||||
vvm_force::vvm_force(unsigned w)
|
||||
: width_(w)
|
||||
{
|
||||
bits_ = new vpip_bit_t[width_];
|
||||
target_ = new vvm_nexus*[width_];
|
||||
for (unsigned idx = 0 ; idx < width_ ; idx += 1)
|
||||
target_[idx] = 0;
|
||||
}
|
||||
|
||||
vvm_force::~vvm_force()
|
||||
{
|
||||
delete[]bits_;
|
||||
delete[]target_;
|
||||
}
|
||||
|
||||
void vvm_force::init_I(unsigned key, vpip_bit_t val)
|
||||
{
|
||||
assert(key < width_);
|
||||
bits_[key] = val;
|
||||
}
|
||||
|
||||
void vvm_force::take_value(unsigned key, vpip_bit_t val)
|
||||
{
|
||||
assert(key < width_);
|
||||
if (bits_[key] == val)
|
||||
return;
|
||||
|
||||
bits_[key] = val;
|
||||
target_[key]->force_assign(val);
|
||||
}
|
||||
|
||||
void vvm_force::force(unsigned key, vvm_nexus*tgt)
|
||||
{
|
||||
assert(key < width_);
|
||||
assert(target_[key] == 0);
|
||||
target_[key] = tgt;
|
||||
target_[key]->force_assign(bits_[key]);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* $Log: vvm_force.cc,v $
|
||||
* Revision 1.1 2000/04/22 04:20:20 steve
|
||||
* Add support for force assignment.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -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.57 2000/04/15 02:25:32 steve Exp $"
|
||||
#ident "$Id: vvm_gates.h,v 1.58 2000/04/22 04:20:20 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vvm.h"
|
||||
|
|
@ -279,6 +279,35 @@ class vvm_ff : public vvm_nexus::recvr_t {
|
|||
vvm_ff& operator= (const vvm_ff&);
|
||||
};
|
||||
|
||||
/*
|
||||
* This class supports the handling of the procedural force
|
||||
* assignment. It is a device on the netlist that receives a bit value
|
||||
* and forces it onto the target vvm_nexus. That target is enabled by
|
||||
* the execution of the force statement in behavioral code.
|
||||
*/
|
||||
class vvm_force : public vvm_nexus::recvr_t {
|
||||
|
||||
public:
|
||||
explicit vvm_force(unsigned w);
|
||||
~vvm_force();
|
||||
|
||||
void init_I(unsigned key, vpip_bit_t val);
|
||||
|
||||
void force(unsigned key, vvm_nexus*tgt);
|
||||
void release();
|
||||
|
||||
private:
|
||||
void take_value(unsigned key, vpip_bit_t val);
|
||||
|
||||
unsigned width_;
|
||||
vpip_bit_t*bits_;
|
||||
vvm_nexus**target_;
|
||||
|
||||
private: // not implemented
|
||||
vvm_force(const vvm_force&);
|
||||
vvm_force& operator= (const vvm_force&);
|
||||
};
|
||||
|
||||
/*
|
||||
* This class behaves like a combinational divider. There isn't really
|
||||
* such a practical device, but this is useful for simulating code
|
||||
|
|
@ -887,6 +916,9 @@ class vvm_posedge : public vvm_nexus::recvr_t {
|
|||
|
||||
/*
|
||||
* $Log: vvm_gates.h,v $
|
||||
* Revision 1.58 2000/04/22 04:20:20 steve
|
||||
* Add support for force assignment.
|
||||
*
|
||||
* Revision 1.57 2000/04/15 02:25:32 steve
|
||||
* Support chained events.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: vvm_nexus.cc,v 1.5 2000/03/22 05:16:38 steve Exp $"
|
||||
#ident "$Id: vvm_nexus.cc,v 1.6 2000/04/22 04:20:20 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vvm_nexus.h"
|
||||
|
|
@ -128,10 +128,20 @@ void vvm_nexus::reg_assign(vpip_bit_t val)
|
|||
{
|
||||
assert(drivers_ == 0);
|
||||
value_ = val;
|
||||
if (force_ != 0)
|
||||
return;
|
||||
|
||||
for (recvr_cell*cur = recvrs_; cur ; cur = cur->next)
|
||||
cur->dev->take_value(cur->key, value_);
|
||||
}
|
||||
|
||||
void vvm_nexus::force_assign(vpip_bit_t val)
|
||||
{
|
||||
force_ = val;
|
||||
for (recvr_cell*cur = recvrs_; cur ; cur = cur->next)
|
||||
cur->dev->take_value(cur->key, force_);
|
||||
}
|
||||
|
||||
/*
|
||||
* This method is invoked when something interesting happens at one of
|
||||
* the drivers. It collects all the driver values, resolves them into
|
||||
|
|
@ -159,6 +169,9 @@ void vvm_nexus::run_values()
|
|||
if (value_ == val) return;
|
||||
value_ = val;
|
||||
|
||||
if (force_ != 0)
|
||||
return;
|
||||
|
||||
/* Now deliver that output value to all the receivers
|
||||
connected to this nexus. */
|
||||
for (recvr_cell*cur = recvrs_; cur ; cur = cur->next)
|
||||
|
|
@ -197,16 +210,8 @@ vvm_nexus::recvr_t::~recvr_t()
|
|||
{
|
||||
}
|
||||
|
||||
vvm_nexus_wire::vvm_nexus_wire()
|
||||
{
|
||||
}
|
||||
|
||||
vvm_nexus_wire::~vvm_nexus_wire()
|
||||
{
|
||||
}
|
||||
|
||||
vpip_bit_t vvm_nexus_wire::resolution_function(const vpip_bit_t*bits,
|
||||
unsigned nbits) const
|
||||
vpip_bit_t vvm_nexus::resolution_function(const vpip_bit_t*bits,
|
||||
unsigned nbits) const
|
||||
{
|
||||
if (nbits == 0) return HiZ;
|
||||
return vpip_bits_resolve(bits, nbits);
|
||||
|
|
@ -233,6 +238,9 @@ void vvm_delayed_assign(vvm_nexus&l_val, vpip_bit_t r_val,
|
|||
|
||||
/*
|
||||
* $Log: vvm_nexus.cc,v $
|
||||
* Revision 1.6 2000/04/22 04:20:20 steve
|
||||
* Add support for force assignment.
|
||||
*
|
||||
* Revision 1.5 2000/03/22 05:16:38 steve
|
||||
* Integrate drive resolution function.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: vvm_nexus.h,v 1.1 2000/03/16 19:03:04 steve Exp $"
|
||||
#ident "$Id: vvm_nexus.h,v 1.2 2000/04/22 04:20:20 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vvm.h"
|
||||
|
|
@ -85,7 +85,7 @@ class vvm_nexus {
|
|||
|
||||
public:
|
||||
vvm_nexus();
|
||||
virtual ~vvm_nexus() =0;
|
||||
~vvm_nexus();
|
||||
|
||||
// These methods support connecting the receiver and driver to
|
||||
// the nexus.
|
||||
|
|
@ -100,12 +100,17 @@ class vvm_nexus {
|
|||
// to procedural assignments to the node, as if it where a reg.
|
||||
void reg_assign(vpip_bit_t val);
|
||||
|
||||
// This method causes the specified value to be forced onto
|
||||
// the nexus. This overrides all drivers that are attached.
|
||||
void force_assign(vpip_bit_t val);
|
||||
void release();
|
||||
|
||||
// The run_values() method collects all the current driver
|
||||
// values and, with the aid of the resolution_function,
|
||||
// generates the current value for the nexus. It also passes
|
||||
// that value on to the receuvers.
|
||||
void run_values();
|
||||
virtual vpip_bit_t resolution_function(const vpip_bit_t*, unsigned) const =0;
|
||||
vpip_bit_t resolution_function(const vpip_bit_t*, unsigned) const;
|
||||
|
||||
private:
|
||||
vpip_bit_t value_;
|
||||
|
|
@ -119,31 +124,27 @@ class vvm_nexus {
|
|||
vpip_bit_t*ival_;
|
||||
unsigned nival_;
|
||||
|
||||
vpip_bit_t force_;
|
||||
|
||||
private: // not implemented
|
||||
vvm_nexus(const vvm_nexus&);
|
||||
vvm_nexus& operator= (const vvm_nexus&);
|
||||
};
|
||||
|
||||
|
||||
class vvm_nexus_wire : public vvm_nexus {
|
||||
|
||||
public:
|
||||
vvm_nexus_wire();
|
||||
~vvm_nexus_wire();
|
||||
vpip_bit_t resolution_function(const vpip_bit_t*, unsigned) const;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* This function arranges for a non-blocking reg_assign to a nexus. It
|
||||
* creates all the events needed to make it happen after the specified
|
||||
* delay.
|
||||
*/
|
||||
void vvm_delayed_assign(vvm_nexus&l_val, vpip_bit_t r_val,
|
||||
unsigned long delay);
|
||||
extern void vvm_delayed_assign(vvm_nexus&l_val, vpip_bit_t r_val,
|
||||
unsigned long delay);
|
||||
|
||||
/*
|
||||
* $Log: vvm_nexus.h,v $
|
||||
* Revision 1.2 2000/04/22 04:20:20 steve
|
||||
* Add support for force assignment.
|
||||
*
|
||||
* Revision 1.1 2000/03/16 19:03:04 steve
|
||||
* Revise the VVM backend to use nexus objects so that
|
||||
* drivers and resolution functions can be used, and
|
||||
|
|
|
|||
Loading…
Reference in New Issue