Add support for force assignment.

This commit is contained in:
steve 2000-04-22 04:20:19 +00:00
parent ad8811282b
commit 44838f8973
18 changed files with 413 additions and 46 deletions

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include "Statement.h" # include "Statement.h"
@ -167,6 +167,17 @@ void PEventStatement::set_statement(Statement*st)
statement_ = st; statement_ = st;
} }
PForce::PForce(PExpr*l, PExpr*r)
: lval_(l), expr_(r)
{
}
PForce::~PForce()
{
delete lval_;
delete expr_;
}
PForever::PForever(Statement*s) PForever::PForever(Statement*s)
: statement_(s) : statement_(s)
{ {
@ -182,6 +193,16 @@ PProcess::~PProcess()
delete statement_; delete statement_;
} }
PRelease::PRelease(PExpr*l)
: lval_(l)
{
}
PRelease::~PRelease()
{
delete lval_;
}
PRepeat::PRepeat(PExpr*e, Statement*s) PRepeat::PRepeat(PExpr*e, Statement*s)
: expr_(e), statement_(s) : expr_(e), statement_(s)
{ {
@ -210,6 +231,9 @@ PWhile::~PWhile()
/* /*
* $Log: Statement.cc,v $ * $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 * Revision 1.19 2000/04/12 04:23:57 steve
* Named events really should be expressed with PEIdent * Named events really should be expressed with PEIdent
* objects in the pform, * objects in the pform,

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include <string> # include <string>
@ -288,6 +288,20 @@ class PEventStatement : public Statement {
Statement*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 { class PForever : public Statement {
public: public:
explicit PForever(Statement*s); explicit PForever(Statement*s);
@ -346,6 +360,19 @@ class PRepeat : public Statement {
Statement*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 * The PTrigger statement sends a trigger to a named event. Take the
* name here. * name here.
@ -381,6 +408,9 @@ class PWhile : public Statement {
/* /*
* $Log: Statement.h,v $ * $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 * Revision 1.24 2000/04/12 04:23:57 steve
* Named events really should be expressed with PEIdent * Named events really should be expressed with PEIdent
* objects in the pform, * objects in the pform,

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
/* /*
@ -154,6 +154,12 @@ void NetDivide::dump_node(ostream&o, unsigned ind) const
dump_obj_attr(o, ind+4); 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 void NetMult::dump_node(ostream&o, unsigned ind) const
{ {
o << setw(ind) << "" << "LPM_MULT (NetMult): " << name() << endl; 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; 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 void NetForever::dump(ostream&o, unsigned ind) const
{ {
o << setw(ind) << "" << "forever" << endl; o << setw(ind) << "" << "forever" << endl;
@ -890,6 +902,9 @@ void Design::dump(ostream&o) const
/* /*
* $Log: design_dump.cc,v $ * $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 * Revision 1.76 2000/04/12 20:02:52 steve
* Finally remove the NetNEvent and NetPEvent classes, * Finally remove the NetNEvent and NetPEvent classes,
* Get synthesis working with the NetEvWait class, * Get synthesis working with the NetEvWait class,

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
/* /*
@ -1802,6 +1802,32 @@ NetProc* PForever::elaborate(Design*des, const string&path) const
return proc; 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 * elaborate the for loop as the equivalent while loop. This eases the
* task for the target code generator. The structure is: * 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); 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 NetProc* PRepeat::elaborate(Design*des, const string&path) const
{ {
NetScope*scope = des->find_scope(path); NetScope*scope = des->find_scope(path);
@ -2228,6 +2261,9 @@ Design* elaborate(const map<string,Module*>&modules,
/* /*
* $Log: elaborate.cc,v $ * $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 * Revision 1.160 2000/04/21 04:38:15 steve
* Bit padding in assignment to memory. * Bit padding in assignment to memory.
* *

15
emit.cc
View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
/* /*
@ -95,6 +95,11 @@ void NetFF::emit_node(ostream&o, struct target_t*tgt) const
tgt->lpm_ff(o, this); 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 void NetMult::emit_node(ostream&o, struct target_t*tgt) const
{ {
tgt->lpm_mult(o, this); tgt->lpm_mult(o, this);
@ -167,6 +172,11 @@ bool NetCondit::emit_proc(ostream&o, struct target_t*tgt) const
return true; 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 bool NetForever::emit_proc(ostream&o, struct target_t*tgt) const
{ {
tgt->proc_forever(o, this); tgt->proc_forever(o, this);
@ -416,6 +426,9 @@ bool emit(ostream&o, const Design*des, const char*type)
/* /*
* $Log: emit.cc,v $ * $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 * Revision 1.39 2000/04/12 04:23:58 steve
* Named events really should be expressed with PEIdent * Named events really should be expressed with PEIdent
* objects in the pform, * objects in the pform,

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include <cassert> # include <cassert>
@ -1735,6 +1735,25 @@ verinum::V NetConst::value(unsigned idx) const
return value_[idx]; 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) NetFuncDef::NetFuncDef(NetScope*s, const svector<NetNet*>&po)
: scope_(s), statement_(0), ports_(po) : scope_(s), statement_(0), ports_(po)
{ {
@ -2483,6 +2502,9 @@ bool NetUDP::sequ_glob_(string input, char output)
/* /*
* $Log: netlist.cc,v $ * $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 * Revision 1.116 2000/04/18 01:02:54 steve
* Minor cleanup of NetTaskDef. * Minor cleanup of NetTaskDef.
* *

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
/* /*
@ -1401,6 +1401,33 @@ class NetEvProbe : public NetNode {
NetEvProbe*enext_; 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 * A forever statement is executed over and over again forever. Or
* until its block is disabled. * until its block is disabled.
@ -2391,6 +2418,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
/* /*
* $Log: netlist.h,v $ * $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 * Revision 1.126 2000/04/20 00:28:03 steve
* Catch some simple identity compareoptimizations. * Catch some simple identity compareoptimizations.
* *

14
parse.y
View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include "parse_misc.h" # include "parse_misc.h"
@ -1671,8 +1671,10 @@ statement
$$ = 0; $$ = 0;
} }
| K_force lavalue '=' expression ';' | K_force lavalue '=' expression ';'
{ yyerror(@1, "sorry: procedural force assign not supported."); { PForce*tmp = new PForce($2, $4);
$$ = 0; tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
$$ = tmp;
} }
| K_TRIGGER IDENTIFIER ';' | K_TRIGGER IDENTIFIER ';'
{ PTrigger*tmp = new PTrigger($2); { PTrigger*tmp = new PTrigger($2);
@ -1718,8 +1720,10 @@ statement
$$ = tmp; $$ = tmp;
} }
| K_release lavalue ';' | K_release lavalue ';'
{ yyerror(@1, "sorry: release not supported."); { PRelease*tmp = new PRelease($2);
$$ = 0; tmp->set_file(@1.text);
tmp->set_lineno(@1.first_line);
$$ = tmp;
} }
| K_repeat '(' expression ')' statement | K_repeat '(' expression ')' statement
{ PRepeat*tmp = new PRepeat($3, $5); { PRepeat*tmp = new PRepeat($3, $5);

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #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 void PForever::dump(ostream&out, unsigned ind) const
{ {
out << setw(ind) << "" << "forever /* " << get_line() << " */" << endl; out << setw(ind) << "" << "forever /* " << get_line() << " */" << endl;
@ -512,6 +518,12 @@ void PFunction::dump(ostream&out, unsigned ind) const
out << setw(ind) << "" << "/* NOOP */" << endl; 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 void PRepeat::dump(ostream&out, unsigned ind) const
{ {
out << setw(ind) << "" << "repeat (" << *expr_ << ")" << endl; out << setw(ind) << "" << "repeat (" << *expr_ << ")" << endl;
@ -733,6 +745,9 @@ void PUdp::dump(ostream&out) const
/* /*
* $Log: pform_dump.cc,v $ * $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 * Revision 1.54 2000/04/12 20:02:53 steve
* Finally remove the NetNEvent and NetPEvent classes, * Finally remove the NetNEvent and NetPEvent classes,
* Get synthesis working with the NetEvWait class, * Get synthesis working with the NetEvWait class,

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include <iostream> # include <iostream>
@ -80,6 +80,7 @@ class target_vvm : public target_t {
virtual void net_assign_nb(ostream&os, const NetAssignNB*); virtual void net_assign_nb(ostream&os, const NetAssignNB*);
virtual void net_case_cmp(ostream&os, const NetCaseCmp*); virtual void net_case_cmp(ostream&os, const NetCaseCmp*);
virtual void net_const(ostream&os, const NetConst*); 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 void net_probe(ostream&os, const NetEvProbe*);
virtual bool process(ostream&os, const NetProcTop*); virtual bool process(ostream&os, const NetProcTop*);
virtual void proc_assign(ostream&os, const NetAssign*); 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); void proc_case_fun(ostream&os, const NetCase*net);
virtual void proc_condit(ostream&os, const NetCondit*); virtual void proc_condit(ostream&os, const NetCondit*);
void proc_condit_fun(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_forever(ostream&os, const NetForever*);
virtual void proc_repeat(ostream&os, const NetRepeat*); virtual void proc_repeat(ostream&os, const NetRepeat*);
virtual void proc_stask(ostream&os, const NetSTask*); 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[" << os << "static struct __vpiNumberConst number_table[" <<
number_counter+1 << "];" << endl; number_counter+1 << "];" << endl;
if (nexus_wire_counter > 0) if (nexus_wire_counter > 0)
os << "static vvm_nexus_wire nexus_wire_table[" << os << "static vvm_nexus nexus_wire_table[" <<
nexus_wire_counter << "];" << endl; nexus_wire_counter << "];" << endl;
if (signal_bit_counter > 0) if (signal_bit_counter > 0)
os << "static vpip_bit_t signal_bit_table[" << 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) void target_vvm::net_probe(ostream&os, const NetEvProbe*net)
{ {
string mname = mangle(net->name()); string mname = mangle(net->name());
@ -2310,6 +2330,21 @@ void target_vvm::proc_condit_fun(ostream&os, const NetCondit*net)
defn << " }" << endl; 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 forever loop is implemented by starting a basic block, handing
* the statement, and putting in a goto to the beginning of the block. * 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 $ * $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 * Revision 1.137 2000/04/15 19:51:30 steve
* fork-join support in vvm. * fork-join support in vvm.
* *

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include "target.h" # include "target.h"
@ -155,6 +155,13 @@ void target_t::net_const(ostream&os, const NetConst*)
"Unhandled CONSTANT node." << endl; "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) void target_t::net_probe(ostream&os, const NetEvProbe*net)
{ {
cerr << "target (" << typeid(*this).name() << "): " cerr << "target (" << typeid(*this).name() << "): "
@ -218,6 +225,13 @@ void target_t::proc_delay(ostream&os, const NetPDelay*)
"Unhandled proc_delay." << endl; "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*) void target_t::proc_forever(ostream&os, const NetForever*)
{ {
cerr << "target (" << typeid(*this).name() << "): " cerr << "target (" << typeid(*this).name() << "): "
@ -339,6 +353,9 @@ void expr_scan_t::expr_binary(const NetEBinary*ex)
/* /*
* $Log: target.cc,v $ * $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 * Revision 1.35 2000/04/12 04:23:58 steve
* Named events really should be expressed with PEIdent * Named events really should be expressed with PEIdent
* objects in the pform, * objects in the pform,

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include "netlist.h" # include "netlist.h"
@ -91,6 +91,7 @@ struct target_t {
virtual void net_assign_nb(ostream&os, const NetAssignNB*); virtual void net_assign_nb(ostream&os, const NetAssignNB*);
virtual void net_case_cmp(ostream&os, const NetCaseCmp*); virtual void net_case_cmp(ostream&os, const NetCaseCmp*);
virtual void net_const(ostream&os, const NetConst*); 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 void net_probe(ostream&os, const NetEvProbe*);
/* Output a process (called for each process). It is up to the /* 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 bool proc_block(ostream&os, const NetBlock*);
virtual void proc_case(ostream&os, const NetCase*); virtual void proc_case(ostream&os, const NetCase*);
virtual void proc_condit(ostream&os, const NetCondit*); 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_forever(ostream&os, const NetForever*);
virtual void proc_repeat(ostream&os, const NetRepeat*); virtual void proc_repeat(ostream&os, const NetRepeat*);
virtual bool proc_trigger(ostream&os, const NetEvTrig*); virtual bool proc_trigger(ostream&os, const NetEvTrig*);
@ -152,6 +154,9 @@ extern const struct target *target_table[];
/* /*
* $Log: target.h,v $ * $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 * Revision 1.34 2000/04/12 04:23:58 steve
* Named events really should be expressed with PEIdent * Named events really should be expressed with PEIdent
* objects in the pform, * objects in the pform,

View File

@ -18,7 +18,7 @@
# 59 Temple Place - Suite 330 # 59 Temple Place - Suite 330
# Boston, MA 02111-1307, USA # 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 SHELL = /bin/sh
@ -59,7 +59,7 @@ all: libvvm.a
mv $*.d dep mv $*.d dep
O = vvm_add_sub.o vvm_bit.o vvm_calltf.o vvm_clshift.o vvm_compare.o \ 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_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 vvm_nexus.o vvm_pevent.o vvm_signal.o vvm_thread.o vvm_udp.o vpip.o

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
/* /*
@ -51,6 +51,8 @@ struct __vpirt;
* 1xxx0xxx - Logic X * 1xxx0xxx - Logic X
* 00001000 - Logic Z * 00001000 - Logic Z
* *
* 00000000 - Invalid/No signal
*
* So as you can see, logic values can be quickly compared by masking * So as you can see, logic values can be quickly compared by masking
* the strength bits. * the strength bits.
* *
@ -342,6 +344,9 @@ extern int vpip_finished();
/* /*
* $Log: vpi_priv.h,v $ * $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 * Revision 1.14 2000/03/31 07:08:39 steve
* allow cancelling of cbValueChange events. * allow cancelling of cbValueChange events.
* *

72
vvm/vvm_force.cc Normal file
View File

@ -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.
*
*/

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include "vvm.h" # include "vvm.h"
@ -279,6 +279,35 @@ class vvm_ff : public vvm_nexus::recvr_t {
vvm_ff& operator= (const vvm_ff&); 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 * This class behaves like a combinational divider. There isn't really
* such a practical device, but this is useful for simulating code * 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 $ * $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 * Revision 1.57 2000/04/15 02:25:32 steve
* Support chained events. * Support chained events.
* *

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include "vvm_nexus.h" # include "vvm_nexus.h"
@ -128,10 +128,20 @@ void vvm_nexus::reg_assign(vpip_bit_t val)
{ {
assert(drivers_ == 0); assert(drivers_ == 0);
value_ = val; value_ = val;
if (force_ != 0)
return;
for (recvr_cell*cur = recvrs_; cur ; cur = cur->next) for (recvr_cell*cur = recvrs_; cur ; cur = cur->next)
cur->dev->take_value(cur->key, value_); 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 * This method is invoked when something interesting happens at one of
* the drivers. It collects all the driver values, resolves them into * the drivers. It collects all the driver values, resolves them into
@ -159,6 +169,9 @@ void vvm_nexus::run_values()
if (value_ == val) return; if (value_ == val) return;
value_ = val; value_ = val;
if (force_ != 0)
return;
/* Now deliver that output value to all the receivers /* Now deliver that output value to all the receivers
connected to this nexus. */ connected to this nexus. */
for (recvr_cell*cur = recvrs_; cur ; cur = cur->next) 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() vpip_bit_t vvm_nexus::resolution_function(const vpip_bit_t*bits,
{ unsigned nbits) const
}
vvm_nexus_wire::~vvm_nexus_wire()
{
}
vpip_bit_t vvm_nexus_wire::resolution_function(const vpip_bit_t*bits,
unsigned nbits) const
{ {
if (nbits == 0) return HiZ; if (nbits == 0) return HiZ;
return vpip_bits_resolve(bits, nbits); 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 $ * $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 * Revision 1.5 2000/03/22 05:16:38 steve
* Integrate drive resolution function. * Integrate drive resolution function.
* *

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #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 #endif
# include "vvm.h" # include "vvm.h"
@ -85,7 +85,7 @@ class vvm_nexus {
public: public:
vvm_nexus(); vvm_nexus();
virtual ~vvm_nexus() =0; ~vvm_nexus();
// These methods support connecting the receiver and driver to // These methods support connecting the receiver and driver to
// the nexus. // the nexus.
@ -100,12 +100,17 @@ class vvm_nexus {
// to procedural assignments to the node, as if it where a reg. // to procedural assignments to the node, as if it where a reg.
void reg_assign(vpip_bit_t val); 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 // The run_values() method collects all the current driver
// values and, with the aid of the resolution_function, // values and, with the aid of the resolution_function,
// generates the current value for the nexus. It also passes // generates the current value for the nexus. It also passes
// that value on to the receuvers. // that value on to the receuvers.
void run_values(); 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: private:
vpip_bit_t value_; vpip_bit_t value_;
@ -119,31 +124,27 @@ class vvm_nexus {
vpip_bit_t*ival_; vpip_bit_t*ival_;
unsigned nival_; unsigned nival_;
vpip_bit_t force_;
private: // not implemented private: // not implemented
vvm_nexus(const vvm_nexus&); vvm_nexus(const vvm_nexus&);
vvm_nexus& operator= (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 * 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 * creates all the events needed to make it happen after the specified
* delay. * delay.
*/ */
void vvm_delayed_assign(vvm_nexus&l_val, vpip_bit_t r_val, extern void vvm_delayed_assign(vvm_nexus&l_val, vpip_bit_t r_val,
unsigned long delay); unsigned long delay);
/* /*
* $Log: vvm_nexus.h,v $ * $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 * Revision 1.1 2000/03/16 19:03:04 steve
* Revise the VVM backend to use nexus objects so that * Revise the VVM backend to use nexus objects so that
* drivers and resolution functions can be used, and * drivers and resolution functions can be used, and