diff --git a/PExpr.cc b/PExpr.cc index 3aa9bd86b..0680defb1 100644 --- a/PExpr.cc +++ b/PExpr.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: PExpr.cc,v 1.16 2000/04/12 04:23:57 steve Exp $" +#ident "$Id: PExpr.cc,v 1.17 2000/05/04 03:37:58 steve Exp $" #endif # include "PExpr.h" @@ -64,11 +64,16 @@ bool PEBinary::is_constant(Module*mod) const return left_->is_constant(mod) && right_->is_constant(mod); } -PECallFunction::PECallFunction(const string &n, const svector &parms) +PECallFunction::PECallFunction(const char*n, const svector &parms) : name_(n), parms_(parms) { } +PECallFunction::PECallFunction(const char*n) +: name_(n) +{ +} + PECallFunction::~PECallFunction() { } @@ -207,6 +212,10 @@ bool PETernary::is_constant(Module*) const /* * $Log: PExpr.cc,v $ + * Revision 1.17 2000/05/04 03:37:58 steve + * Add infrastructure for system functions, move + * $time to that structure and add $random. + * * Revision 1.16 2000/04/12 04:23:57 steve * Named events really should be expressed with PEIdent * objects in the pform, diff --git a/PExpr.h b/PExpr.h index 06fc51dff..ab0bf5877 100644 --- a/PExpr.h +++ b/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.35 2000/04/12 04:23:57 steve Exp $" +#ident "$Id: PExpr.h,v 1.36 2000/05/04 03:37:58 steve Exp $" #endif # include @@ -339,25 +339,31 @@ class PETernary : public PExpr { }; /* - * This class represents a parsed call to a function. + * This class represents a parsed call to a function, including calls + * to system functions. */ class PECallFunction : public PExpr { public: - explicit PECallFunction(const string &n, const svector &parms); + explicit PECallFunction(const char*n, const svector &parms); + explicit PECallFunction(const char*n); ~PECallFunction(); virtual void dump(ostream &) const; - virtual NetExpr*elaborate_expr(Design*des, NetScope*) const; + virtual NetExpr*elaborate_expr(Design*des, NetScope*scope) const; private: string name_; svector parms_; - NetESFunc* elaborate_sfunc_(Design*des, NetScope*scope) const; + NetExpr* elaborate_sfunc_(Design*des, NetScope*scope) const; }; /* * $Log: PExpr.h,v $ + * Revision 1.36 2000/05/04 03:37:58 steve + * Add infrastructure for system functions, move + * $time to that structure and add $random. + * * Revision 1.35 2000/04/12 04:23:57 steve * Named events really should be expressed with PEIdent * objects in the pform, diff --git a/design_dump.cc b/design_dump.cc index 46e44b7b1..bc3fc4818 100644 --- a/design_dump.cc +++ b/design_dump.cc @@ -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.81 2000/05/02 03:13:30 steve Exp $" +#ident "$Id: design_dump.cc,v 1.82 2000/05/04 03:37:58 steve Exp $" #endif /* @@ -822,6 +822,11 @@ void NetEScope::dump(ostream&o) const o << "name() << ">"; } +void NetESFunc::dump(ostream&o) const +{ + o << name_ << "()"; +} + void NetESignal::dump(ostream&o) const { o << name(); @@ -924,6 +929,10 @@ void Design::dump(ostream&o) const /* * $Log: design_dump.cc,v $ + * Revision 1.82 2000/05/04 03:37:58 steve + * Add infrastructure for system functions, move + * $time to that structure and add $random. + * * Revision 1.81 2000/05/02 03:13:30 steve * Move memories to the NetScope object. * diff --git a/dup_expr.cc b/dup_expr.cc index cb017412e..3d5191d75 100644 --- a/dup_expr.cc +++ b/dup_expr.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: dup_expr.cc,v 1.2 2000/02/23 02:56:54 steve Exp $" +#ident "$Id: dup_expr.cc,v 1.3 2000/05/04 03:37:58 steve Exp $" #endif # include "netlist.h" @@ -29,8 +29,17 @@ NetEScope* NetEScope::dup_expr() const return 0; } +NetESFunc* NetESFunc::dup_expr() const +{ + return new NetESFunc(name_, expr_width()); +} + /* * $Log: dup_expr.cc,v $ + * Revision 1.3 2000/05/04 03:37:58 steve + * Add infrastructure for system functions, move + * $time to that structure and add $random. + * * Revision 1.2 2000/02/23 02:56:54 steve * Macintosh compilers do not support ident. * diff --git a/elab_expr.cc b/elab_expr.cc index 845816abd..98ad43576 100644 --- a/elab_expr.cc +++ b/elab_expr.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_expr.cc,v 1.23 2000/05/02 03:13:30 steve Exp $" +#ident "$Id: elab_expr.cc,v 1.24 2000/05/04 03:37:58 steve Exp $" #endif @@ -142,10 +142,23 @@ NetEBinary* PEBinary::elaborate_expr_base_(Design*des, return tmp; } -NetESFunc* PECallFunction::elaborate_sfunc_(Design*des, NetScope*) const +NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*) const { - cerr << get_line() << ": sorry: system functions not supported." - << endl; + if (parms_.count() > 0) { + cerr << get_line() << ": sorry: system function " + "parmaeters not supported." << endl; + des->errors += 1; + return 0; + } + + if (name_ == "$time") + return new NetESFunc(name_, 64); + + if (name_ == "$random") + return new NetESFunc(name_, 32); + + cerr << get_line() << ": sorry: system function " << name_ + << " not supported." << endl; des->errors += 1; return 0; } @@ -240,9 +253,7 @@ NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope) const NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const { - // System identifiers show up in the netlist as identifiers. - if (text_[0] == '$') - return new NetEIdent(text_, 64); + assert(text_[0] != '$'); //string name = path+"."+text_; assert(scope); @@ -456,6 +467,10 @@ NetEUnary* PEUnary::elaborate_expr(Design*des, NetScope*scope) const /* * $Log: elab_expr.cc,v $ + * Revision 1.24 2000/05/04 03:37:58 steve + * Add infrastructure for system functions, move + * $time to that structure and add $random. + * * Revision 1.23 2000/05/02 03:13:30 steve * Move memories to the NetScope object. * diff --git a/emit.cc b/emit.cc index 3417094d4..1e5e60886 100644 --- a/emit.cc +++ b/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.43 2000/05/02 03:13:31 steve Exp $" +#ident "$Id: emit.cc,v 1.44 2000/05/04 03:37:58 steve Exp $" #endif /* @@ -391,6 +391,11 @@ void NetEScope::expr_scan(struct expr_scan_t*tgt) const tgt->expr_scope(this); } +void NetESFunc::expr_scan(struct expr_scan_t*tgt) const +{ + tgt->expr_sfunc(this); +} + void NetEUFunc::expr_scan(struct expr_scan_t*tgt) const { tgt->expr_ufunc(this); @@ -429,6 +434,10 @@ bool emit(ostream&o, const Design*des, const char*type) /* * $Log: emit.cc,v $ + * Revision 1.44 2000/05/04 03:37:58 steve + * Add infrastructure for system functions, move + * $time to that structure and add $random. + * * Revision 1.43 2000/05/02 03:13:31 steve * Move memories to the NetScope object. * @@ -565,49 +574,5 @@ bool emit(ostream&o, const Design*des, const char*type) * * Revision 1.8 1999/04/25 00:44:10 steve * Core handles subsignal expressions. - * - * Revision 1.7 1999/04/19 01:59:36 steve - * Add memories to the parse and elaboration phases. - * - * Revision 1.6 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.5 1999/02/01 00:26:49 steve - * Carry some line info to the netlist, - * Dump line numbers for processes. - * Elaborate prints errors about port vector - * width mismatch - * Emit better handles null statements. - * - * Revision 1.4 1998/12/01 00:42:14 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:34 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:05 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:28:57 steve - * Introduce verilog to CVS. - * */ diff --git a/netlist.cc b/netlist.cc index 81bc4dcb4..cabc3708c 100644 --- a/netlist.cc +++ b/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.121 2000/05/02 03:13:31 steve Exp $" +#ident "$Id: netlist.cc,v 1.122 2000/05/04 03:37:58 steve Exp $" #endif # include @@ -2197,6 +2197,21 @@ const NetScope* NetEScope::scope() const return scope_; } +NetESFunc::NetESFunc(const string&n, unsigned width) +: name_(n) +{ + expr_width(width); +} + +NetESFunc::~NetESFunc() +{ +} + +const string& NetESFunc::name() const +{ + return name_; +} + NetESignal::NetESignal(NetNet*n) : NetExpr(n->pin_count()), net_(n) { @@ -2552,6 +2567,10 @@ bool NetUDP::sequ_glob_(string input, char output) /* * $Log: netlist.cc,v $ + * Revision 1.122 2000/05/04 03:37:58 steve + * Add infrastructure for system functions, move + * $time to that structure and add $random. + * * Revision 1.121 2000/05/02 03:13:31 steve * Move memories to the NetScope object. * diff --git a/netlist.h b/netlist.h index 1e35ac7b2..6bacaddf1 100644 --- a/netlist.h +++ b/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.134 2000/05/02 03:13:31 steve Exp $" +#ident "$Id: netlist.h,v 1.135 2000/05/04 03:37:58 steve Exp $" #endif /* @@ -2027,19 +2027,17 @@ class NetEScope : public NetExpr { * This node represents a system function call in an expression. The * object contains the name of the system function, which the backend * uses to to VPI matching. + * + * XXXX NOTE: parameters are not net supported. */ class NetESFunc : public NetExpr { public: - NetESFunc(const string&name, NetESignal*, svector&); + NetESFunc(const string&name, unsigned width); ~NetESFunc(); const string& name() const; - const NetESignal*result() const; - unsigned parm_count() const; - const NetExpr* parm(unsigned idx) const; - virtual bool set_width(unsigned); virtual void dump(ostream&) const; @@ -2048,8 +2046,6 @@ class NetESFunc : public NetExpr { private: string name_; - NetESignal*result_; - svector parms_; private: // not implemented NetESFunc(const NetESFunc&); @@ -2505,6 +2501,10 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.135 2000/05/04 03:37:58 steve + * Add infrastructure for system functions, move + * $time to that structure and add $random. + * * Revision 1.134 2000/05/02 03:13:31 steve * Move memories to the NetScope object. * diff --git a/parse.y b/parse.y index 4c59205a9..08f3bb67f 100644 --- a/parse.y +++ b/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.92 2000/04/22 04:20:19 steve Exp $" +#ident "$Id: parse.y,v 1.93 2000/05/04 03:37:59 steve Exp $" #endif # include "parse_misc.h" @@ -723,11 +723,11 @@ expr_primary delete $1; } | SYSTEM_IDENTIFIER - { PEIdent*tmp = new PEIdent($1); + { PECallFunction*tmp = new PECallFunction($1); tmp->set_file(@1.text); tmp->set_lineno(@1.first_line); $$ = tmp; - delete $1; + delete $1 } | identifier '[' expression ']' { PEIdent*tmp = new PEIdent($1); diff --git a/pform_dump.cc b/pform_dump.cc index 7262f971c..3955be209 100644 --- a/pform_dump.cc +++ b/pform_dump.cc @@ -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.55 2000/04/22 04:20:19 steve Exp $" +#ident "$Id: pform_dump.cc,v 1.56 2000/05/04 03:37:59 steve Exp $" #endif /* @@ -71,10 +71,13 @@ void PEConcat::dump(ostream&out) const void PECallFunction::dump(ostream &out) const { out << name_ << "("; - parms_[0]->dump(out); - for (unsigned idx = 1; idx < parms_.count(); ++idx) { - out << ", "; - parms_[idx]->dump(out); + + if (parms_.count() > 0) { + parms_[0]->dump(out); + for (unsigned idx = 1; idx < parms_.count(); ++idx) { + out << ", "; + parms_[idx]->dump(out); + } } out << ")"; } @@ -745,6 +748,10 @@ void PUdp::dump(ostream&out) const /* * $Log: pform_dump.cc,v $ + * Revision 1.56 2000/05/04 03:37:59 steve + * Add infrastructure for system functions, move + * $time to that structure and add $random. + * * Revision 1.55 2000/04/22 04:20:19 steve * Add support for force assignment. * diff --git a/set_width.cc b/set_width.cc index 19cb1d53f..ccf1842c8 100644 --- a/set_width.cc +++ b/set_width.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: set_width.cc,v 1.12 2000/04/28 18:43:23 steve Exp $" +#ident "$Id: set_width.cc,v 1.13 2000/05/04 03:37:59 steve Exp $" #endif /* @@ -237,6 +237,11 @@ bool NetEParam::set_width(unsigned) return false; } +bool NetESFunc::set_width(unsigned w) +{ + return w == expr_width(); +} + /* * The signal should automatically pad with zeros to get to th desired * width. Do not allow signal bits to be truncated, however. @@ -295,6 +300,10 @@ bool NetEUnary::set_width(unsigned w) /* * $Log: set_width.cc,v $ + * Revision 1.13 2000/05/04 03:37:59 steve + * Add infrastructure for system functions, move + * $time to that structure and add $random. + * * Revision 1.12 2000/04/28 18:43:23 steve * integer division in expressions properly get width. * diff --git a/t-vvm.cc b/t-vvm.cc index 5729e5d7b..e56c7c2ca 100644 --- a/t-vvm.cc +++ b/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.142 2000/05/02 00:58:12 steve Exp $" +#ident "$Id: t-vvm.cc,v 1.143 2000/05/04 03:37:59 steve Exp $" #endif # include @@ -171,7 +171,8 @@ target_vvm::~target_vvm() /* * This class emits code for the rvalue of a procedural * assignment. The expression is evaluated to fit the width - * specified. + * specified. The result is a vvm_bitset_t or equivilent that can be + * used for reading values out. */ class vvm_proc_rval : public expr_scan_t { @@ -190,6 +191,7 @@ class vvm_proc_rval : public expr_scan_t { virtual void expr_concat(const NetEConcat*); virtual void expr_ident(const NetEIdent*); virtual void expr_memory(const NetEMemory*mem); + virtual void expr_sfunc(const NetESFunc*); virtual void expr_signal(const NetESignal*); virtual void expr_subsignal(const NetESubSignal*sig); virtual void expr_ternary(const NetETernary*); @@ -305,6 +307,24 @@ void vvm_proc_rval::expr_memory(const NetEMemory*mem) result = tname; } +void vvm_proc_rval::expr_sfunc(const NetESFunc*fun) +{ + os_ << " // " << fun->get_line() << endl; + + const string retval = make_temp(); + const unsigned retwid = fun->expr_width(); + + os_ << " vpip_bit_t " << retval << "_bits["<name() << "\", " + << retval<<"_bits, " << retwid << ");" << endl; + + os_ << " vvm_bitset_t " << retval << "(" << retval<<"_bits, " + << retwid << ");" << endl; + + result = retval; +} + /* * A bitset reference to a signal can be done simply by referring to * the same bits as the signal. We onlt need to copy the bits pointer @@ -608,9 +628,9 @@ class vvm_parm_rval : public expr_scan_t { private: virtual void expr_const(const NetEConst*); - virtual void expr_ident(const NetEIdent*); virtual void expr_memory(const NetEMemory*); virtual void expr_scope(const NetEScope*); + virtual void expr_sfunc(const NetESFunc*); virtual void expr_signal(const NetESignal*); private: @@ -673,7 +693,7 @@ void vvm_parm_rval::expr_const(const NetEConst*expr) return; } -void vvm_parm_rval::expr_ident(const NetEIdent*expr) +void vvm_parm_rval::expr_sfunc(const NetESFunc*expr) { if (expr->name() == "$time") { result = string("vpip_sim_time()"); @@ -2692,6 +2712,10 @@ extern const struct target tgt_vvm = { }; /* * $Log: t-vvm.cc,v $ + * Revision 1.143 2000/05/04 03:37:59 steve + * Add infrastructure for system functions, move + * $time to that structure and add $random. + * * Revision 1.142 2000/05/02 00:58:12 steve * Move signal tables to the NetScope class. * diff --git a/target.cc b/target.cc index d122d8b4a..065a0cac0 100644 --- a/target.cc +++ b/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.37 2000/04/23 03:45:24 steve Exp $" +#ident "$Id: target.cc,v 1.38 2000/05/04 03:37:59 steve Exp $" #endif # include "target.h" @@ -323,6 +323,12 @@ void expr_scan_t::expr_scope(const NetEScope*) "unhandled expr_scope." << endl; } +void expr_scan_t::expr_sfunc(const NetESFunc*) +{ + cerr << "expr_scan_t (" << typeid(*this).name() << "): " + "unhandled expr_sfunc." << endl; +} + void expr_scan_t::expr_signal(const NetESignal*) { cerr << "expr_scan_t (" << typeid(*this).name() << "): " @@ -361,6 +367,10 @@ void expr_scan_t::expr_binary(const NetEBinary*ex) /* * $Log: target.cc,v $ + * Revision 1.38 2000/05/04 03:37:59 steve + * Add infrastructure for system functions, move + * $time to that structure and add $random. + * * Revision 1.37 2000/04/23 03:45:24 steve * Add support for the procedural release statement. * diff --git a/target.h b/target.h index 9641a2abc..1dc677299 100644 --- a/target.h +++ b/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.36 2000/04/23 03:45:25 steve Exp $" +#ident "$Id: target.h,v 1.37 2000/05/04 03:37:59 steve Exp $" #endif # include "netlist.h" @@ -130,6 +130,7 @@ struct expr_scan_t { virtual void expr_ident(const NetEIdent*); virtual void expr_memory(const NetEMemory*); virtual void expr_scope(const NetEScope*); + virtual void expr_sfunc(const NetESFunc*); virtual void expr_signal(const NetESignal*); virtual void expr_subsignal(const NetESubSignal*); virtual void expr_ternary(const NetETernary*); @@ -155,6 +156,10 @@ extern const struct target *target_table[]; /* * $Log: target.h,v $ + * Revision 1.37 2000/05/04 03:37:59 steve + * Add infrastructure for system functions, move + * $time to that structure and add $random. + * * Revision 1.36 2000/04/23 03:45:25 steve * Add support for the procedural release statement. * @@ -185,47 +190,5 @@ extern const struct target *target_table[]; * * Revision 1.30 2000/03/29 04:37:11 steve * New and improved combinational primitives. - * - * Revision 1.29 2000/02/23 02:56:56 steve - * Macintosh compilers do not support ident. - * - * Revision 1.28 2000/01/13 03:35:35 steve - * Multiplication all the way to simulation. - * - * Revision 1.27 1999/11/28 23:42:03 steve - * NetESignal object no longer need to be NetNode - * objects. Let them keep a pointer to NetNet objects. - * - * Revision 1.26 1999/11/27 19:07:58 steve - * Support the creation of scopes. - * - * Revision 1.25 1999/11/21 00:13:09 steve - * Support memories in continuous assignments. - * - * Revision 1.24 1999/11/14 23:43:46 steve - * Support combinatorial comparators. - * - * Revision 1.23 1999/11/14 20:24:28 steve - * Add support for the LPM_CLSHIFT device. - * - * Revision 1.22 1999/11/04 03:53:26 steve - * Patch to synthesize unary ~ and the ternary operator. - * Thanks to Larry Doolittle . - * - * Add the LPM_MUX device, and integrate it with the - * ternary synthesis from Larry. Replace the lpm_mux - * generator in t-xnf.cc to use XNF EQU devices to - * put muxs into function units. - * - * Rewrite elaborate_net for the PETernary class to - * also use the LPM_MUX device. - * - * Revision 1.21 1999/11/01 02:07:41 steve - * Add the synth functor to do generic synthesis - * and add the LPM_FF device to handle rows of - * flip-flops. - * - * Revision 1.20 1999/10/10 01:59:55 steve - * Structural case equals device. */ #endif diff --git a/vpi/Makefile.in b/vpi/Makefile.in index 8d7ba2396..a041e1cd9 100644 --- a/vpi/Makefile.in +++ b/vpi/Makefile.in @@ -18,7 +18,7 @@ # 59 Temple Place - Suite 330 # Boston, MA 02111-1307, USA # -#ident "$Id: Makefile.in,v 1.9 2000/01/23 23:54:36 steve Exp $" +#ident "$Id: Makefile.in,v 1.10 2000/05/04 03:37:59 steve Exp $" # # SHELL = /bin/sh @@ -52,8 +52,8 @@ all: system.vpi $(CC) -Wall $(CPPFLAGS) -I$(srcdir) -MD -c $< -o $*.o mv $*.d dep -O = sys_table.o sys_display.o sys_finish.o sys_readmem.o sys_readmem_lex.o \ -sys_vcd.o +O = sys_table.o sys_display.o sys_finish.o sys_random.o \ +sys_readmem.o sys_readmem_lex.o sys_vcd.o system.vpi: $O $(CC) -shared -o $@ $O diff --git a/vpi/sys_random.c b/vpi/sys_random.c new file mode 100644 index 000000000..1889b7592 --- /dev/null +++ b/vpi/sys_random.c @@ -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: sys_random.c,v 1.1 2000/05/04 03:37:59 steve Exp $" +#endif + +# include +# include +# include + +/* + * Implement the $random system function. For now, ignore any + * parameters and only produce a random number. + */ +static int sys_random_calltf(char*name) +{ + s_vpi_value val; + vpiHandle call_handle; + + call_handle = vpi_handle(vpiSysTfCall, 0); + assert(call_handle); + + val.format = vpiIntVal; + val.value.integer = random(); + + vpi_put_value(call_handle, &val, 0, vpiNoDelay); + + return 0; +} + +static int sys_random_sizetf(char*x) +{ + return 32; +} + +void sys_random_register() +{ + s_vpi_systf_data tf_data; + + tf_data.type = vpiSysFunc; + tf_data.tfname = "$random"; + tf_data.calltf = sys_random_calltf; + tf_data.compiletf = 0; + tf_data.sizetf = sys_random_sizetf; + tf_data.user_data = "$random"; + vpi_register_systf(&tf_data); +} + +/* + * $Log: sys_random.c,v $ + * Revision 1.1 2000/05/04 03:37:59 steve + * Add infrastructure for system functions, move + * $time to that structure and add $random. + * + */ + diff --git a/vpi/sys_table.c b/vpi/sys_table.c index 692d1c218..9bbdecb23 100644 --- a/vpi/sys_table.c +++ b/vpi/sys_table.c @@ -17,17 +17,19 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: sys_table.c,v 1.4 2000/02/23 02:56:56 steve Exp $" +#ident "$Id: sys_table.c,v 1.5 2000/05/04 03:37:59 steve Exp $" #endif extern void sys_finish_register(); extern void sys_display_register(); +extern void sys_random_register(); extern void sys_readmem_register(); extern void sys_vcd_register(); void (*vlog_startup_routines[])() = { sys_finish_register, sys_display_register, + sys_random_register, sys_readmem_register, sys_vcd_register, 0 @@ -36,6 +38,10 @@ void (*vlog_startup_routines[])() = { /* * $Log: sys_table.c,v $ + * Revision 1.5 2000/05/04 03:37:59 steve + * Add infrastructure for system functions, move + * $time to that structure and add $random. + * * Revision 1.4 2000/02/23 02:56:56 steve * Macintosh compilers do not support ident. * diff --git a/vpi/vpi_user.h b/vpi/vpi_user.h index 3307e216b..8d71306d4 100644 --- a/vpi/vpi_user.h +++ b/vpi/vpi_user.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: vpi_user.h,v 1.14 2000/03/08 04:36:54 steve Exp $" +#ident "$Id: vpi_user.h,v 1.15 2000/05/04 03:37:59 steve Exp $" #endif #ifdef __cplusplus @@ -108,6 +108,7 @@ typedef struct t_vpi_value { #define vpiNamedFork 35 #define vpiNet 36 #define vpiReg 48 +#define vpiSysFuncCall 56 #define vpiSysTaskCall 57 #define vpiTask 59 #define vpiTimeVar 63 @@ -230,6 +231,10 @@ extern void (*vlog_startup_routines[])(); /* * $Log: vpi_user.h,v $ + * Revision 1.15 2000/05/04 03:37:59 steve + * Add infrastructure for system functions, move + * $time to that structure and add $random. + * * Revision 1.14 2000/03/08 04:36:54 steve * Redesign the implementation of scopes and parameters. * I now generate the scopes and notice the parameters diff --git a/vvm/vpi_priv.c b/vvm/vpi_priv.c index 9127fbb33..8f51ab785 100644 --- a/vvm/vpi_priv.c +++ b/vvm/vpi_priv.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: vpi_priv.c,v 1.5 2000/02/23 02:56:56 steve Exp $" +#ident "$Id: vpi_priv.c,v 1.6 2000/05/04 03:37:59 steve Exp $" #endif # include "vpi_priv.h" @@ -38,7 +38,8 @@ struct systf_entry { s_vpi_systf_data systf_data; }; -static struct systf_entry*systf_list = 0; +static struct systf_entry*systf_func_list = 0; +static struct systf_entry*systf_task_list = 0; /* This is the handle of the task currently being called. */ static struct __vpiSysTaskCall*vpip_cur_task; @@ -49,13 +50,15 @@ void vpip_calltask(const char*fname, unsigned nparms, vpiHandle*parms) struct systf_entry*idx; struct __vpiSysTaskCall cur_task; cur_task.base.vpi_type = &vpip_systask_rt; - cur_task.args = parms; + cur_task.args = parms; cur_task.nargs = nparms; + cur_task.res = 0; + cur_task.nres = 0; vpip_cur_task = &cur_task; /* Look for a systf function to invoke. */ - for (idx = systf_list ; idx ; idx = idx->next) + for (idx = systf_task_list ; idx ; idx = idx->next) if (strcmp(fname, idx->systf_data.tfname) == 0) { cur_task.info = &idx->systf_data; idx->systf_data.calltf(idx->systf_data.user_data); @@ -69,6 +72,39 @@ void vpip_calltask(const char*fname, unsigned nparms, vpiHandle*parms) vpi_printf("Call %s\n", fname); } +/* + * System functions are kept in the same sort of table as the system + * tasks, and we call them in a similar manner. + * + * XXXX Haven't handled the return value yet. + */ +void vpip_callfunc(const char*fname, vpip_bit_t*res, unsigned nres) +{ + struct systf_entry*idx; + struct __vpiSysTaskCall cur_task; + cur_task.base.vpi_type = &vpip_sysfunc_rt; + cur_task.args = 0; + cur_task.nargs = 0; + cur_task.res = res; + cur_task.nres = nres; + + vpip_cur_task = &cur_task; + + /* Look for a systf function to invoke. */ + for (idx = systf_func_list ; idx ; idx = idx->next) + if (strcmp(fname, idx->systf_data.tfname) == 0) { + cur_task.info = &idx->systf_data; + idx->systf_data.calltf(idx->systf_data.user_data); + return; + } + + + /* Finally, if nothing is found then something is not + right. Print out the function name all the parameters + passed, so that someone can deal with it. */ + vpi_printf("Call %s with width==%u\n", fname, nres); +} + int vpi_free_object(vpiHandle ref) { @@ -168,12 +204,26 @@ void vpi_register_systf(const struct t_vpi_systf_data*systf) struct systf_entry*cur = calloc(1, sizeof(struct systf_entry)); cur->systf_data = *systf; cur->systf_data.tfname = strdup(systf->tfname); - cur->next = systf_list; - systf_list = cur; + switch (systf->type) { + case vpiSysFunc: + cur->next = systf_func_list; + systf_func_list = cur; + break; + case vpiSysTask: + cur->next = systf_task_list; + systf_task_list = cur; + break; + default: + assert(0); + } } /* * $Log: vpi_priv.c,v $ + * Revision 1.6 2000/05/04 03:37:59 steve + * Add infrastructure for system functions, move + * $time to that structure and add $random. + * * Revision 1.5 2000/02/23 02:56:56 steve * Macintosh compilers do not support ident. * diff --git a/vvm/vpi_priv.h b/vvm/vpi_priv.h index eb402d70f..19c3f5432 100644 --- a/vvm/vpi_priv.h +++ b/vvm/vpi_priv.h @@ -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.15 2000/04/22 04:20:20 steve Exp $" +#ident "$Id: vpi_priv.h,v 1.16 2000/05/04 03:37:59 steve Exp $" #endif /* @@ -217,6 +217,7 @@ struct __vpiSignal { extern const struct __vpirt vpip_systask_rt; +extern const struct __vpirt vpip_sysfunc_rt; struct __vpiSysTaskCall { struct __vpiHandle base; @@ -224,6 +225,9 @@ struct __vpiSysTaskCall { vpiHandle*args; unsigned nargs; + vpip_bit_t*res; + unsigned nres; + const char*file; unsigned lineno; int subtype; @@ -285,6 +289,12 @@ extern vpiHandle vpip_make_time_var(struct __vpiTimeVar*ref, /* Use this function to call a registered task. */ extern void vpip_calltask(const char*name, unsigned nparms, vpiHandle*parms); +/* + * This calls a system function with a given name. The return value is + * taken by the res[] array. + */ +extern void vpip_callfunc(const char*name, vpip_bit_t*res, unsigned nres); + extern void vpip_run_value_changes(struct __vpiSignal*sig); /* @@ -344,6 +354,10 @@ extern int vpip_finished(); /* * $Log: vpi_priv.h,v $ + * Revision 1.16 2000/05/04 03:37:59 steve + * Add infrastructure for system functions, move + * $time to that structure and add $random. + * * Revision 1.15 2000/04/22 04:20:20 steve * Add support for force assignment. * diff --git a/vvm/vpi_systask.c b/vvm/vpi_systask.c index 159c78e25..9a8f4b4de 100644 --- a/vvm/vpi_systask.c +++ b/vvm/vpi_systask.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: vpi_systask.c,v 1.3 2000/02/23 02:56:56 steve Exp $" +#ident "$Id: vpi_systask.c,v 1.4 2000/05/04 03:37:59 steve Exp $" #endif # include "vpi_priv.h" @@ -45,8 +45,53 @@ const struct __vpirt vpip_systask_rt = { systask_iter }; +/* + * A value *can* be put to a vpiSysFuncCall object. This is how the + * return value is set. The value that is given should be converted to + * bits and set into the return value bit array. + */ +static vpiHandle sysfunc_put_value(vpiHandle ref, p_vpi_value val, + p_vpi_time t, int flag) +{ + long tmp; + int idx; + + struct __vpiSysTaskCall*rfp = (struct __vpiSysTaskCall*)ref; + assert(ref->vpi_type->type_code == vpiSysFuncCall); + + /* There *must* be a return value array. */ + assert(rfp->res); + assert(rfp->nres > 0); + + /* XXXX For now, only support very specific formats. */ + assert(val->format == vpiIntVal); + assert(rfp->nres <= (8*sizeof val->value.integer)); + + tmp = val->value.integer; + for (idx = 0 ; idx < rfp->nres ; idx += 1) { + rfp->res[idx] = (tmp&1) ? St1 : St0; + tmp >>= 1; + } + + return 0; +} + +const struct __vpirt vpip_sysfunc_rt = { + vpiSysFuncCall, + 0, + 0, + 0, + sysfunc_put_value, + 0, + systask_iter +}; + /* * $Log: vpi_systask.c,v $ + * Revision 1.4 2000/05/04 03:37:59 steve + * Add infrastructure for system functions, move + * $time to that structure and add $random. + * * Revision 1.3 2000/02/23 02:56:56 steve * Macintosh compilers do not support ident. *