Import MCD support from Stephen Tell, and add

system function parameter support to the IVL core.
This commit is contained in:
steve 2000-05-07 18:20:07 +00:00
parent b90cda1f3f
commit b28f258463
14 changed files with 572 additions and 139 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: design_dump.cc,v 1.83 2000/05/07 04:37:56 steve Exp $" #ident "$Id: design_dump.cc,v 1.84 2000/05/07 18:20:07 steve Exp $"
#endif #endif
/* /*
@ -850,7 +850,12 @@ void NetEScope::dump(ostream&o) const
void NetESFunc::dump(ostream&o) const void NetESFunc::dump(ostream&o) const
{ {
o << name_ << "()"; o << name_ << "(";
if (nparms() > 0)
o << *parm(0);
for (unsigned idx = 1 ; idx < nparms() ; idx += 1)
o << ", " << *parm(idx);
o << ")";
} }
void NetESignal::dump(ostream&o) const void NetESignal::dump(ostream&o) const
@ -955,6 +960,10 @@ void Design::dump(ostream&o) const
/* /*
* $Log: design_dump.cc,v $ * $Log: design_dump.cc,v $
* Revision 1.84 2000/05/07 18:20:07 steve
* Import MCD support from Stephen Tell, and add
* system function parameter support to the IVL core.
*
* Revision 1.83 2000/05/07 04:37:56 steve * Revision 1.83 2000/05/07 04:37:56 steve
* Carry strength values from Verilog source to the * Carry strength values from Verilog source to the
* pform and netlist for gates. * pform and netlist for gates.

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: dup_expr.cc,v 1.3 2000/05/04 03:37:58 steve Exp $" #ident "$Id: dup_expr.cc,v 1.4 2000/05/07 18:20:07 steve Exp $"
#endif #endif
# include "netlist.h" # include "netlist.h"
@ -31,11 +31,19 @@ NetEScope* NetEScope::dup_expr() const
NetESFunc* NetESFunc::dup_expr() const NetESFunc* NetESFunc::dup_expr() const
{ {
return new NetESFunc(name_, expr_width()); NetESFunc*tmp = new NetESFunc(name_, expr_width(), nparms());
for (unsigned idx = 0 ; idx < nparms() ; idx += 1)
tmp->parm(idx, tmp->parm(idx)->dup_expr());
return tmp;
} }
/* /*
* $Log: dup_expr.cc,v $ * $Log: dup_expr.cc,v $
* Revision 1.4 2000/05/07 18:20:07 steve
* Import MCD support from Stephen Tell, and add
* system function parameter support to the IVL core.
*
* Revision 1.3 2000/05/04 03:37:58 steve * Revision 1.3 2000/05/04 03:37:58 steve
* Add infrastructure for system functions, move * Add infrastructure for system functions, move
* $time to that structure and add $random. * $time to that structure and add $random.

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: elab_expr.cc,v 1.24 2000/05/04 03:37:58 steve Exp $" #ident "$Id: elab_expr.cc,v 1.25 2000/05/07 18:20:07 steve Exp $"
#endif #endif
@ -142,25 +142,21 @@ NetEBinary* PEBinary::elaborate_expr_base_(Design*des,
return tmp; return tmp;
} }
NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*) const NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
{ {
if (parms_.count() > 0) { unsigned wid = 32;
cerr << get_line() << ": sorry: system function "
"parmaeters not supported." << endl;
des->errors += 1;
return 0;
}
if (name_ == "$time") if (name_ == "$time")
return new NetESFunc(name_, 64); wid = 64;
if (name_ == "$random") NetESFunc*fun = new NetESFunc(name_, wid, parms_.count());
return new NetESFunc(name_, 32); for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
PExpr*expr = parms_[idx];
NetExpr*tmp = expr->elaborate_expr(des, scope);
fun->parm(idx, tmp);
}
cerr << get_line() << ": sorry: system function " << name_ return fun;
<< " not supported." << endl;
des->errors += 1;
return 0;
} }
NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope) const NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope) const
@ -467,6 +463,10 @@ NetEUnary* PEUnary::elaborate_expr(Design*des, NetScope*scope) const
/* /*
* $Log: elab_expr.cc,v $ * $Log: elab_expr.cc,v $
* Revision 1.25 2000/05/07 18:20:07 steve
* Import MCD support from Stephen Tell, and add
* system function parameter support to the IVL core.
*
* Revision 1.24 2000/05/04 03:37:58 steve * Revision 1.24 2000/05/04 03:37:58 steve
* Add infrastructure for system functions, move * Add infrastructure for system functions, move
* $time to that structure and add $random. * $time to that structure and add $random.

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.123 2000/05/07 04:37:56 steve Exp $" #ident "$Id: netlist.cc,v 1.124 2000/05/07 18:20:07 steve Exp $"
#endif #endif
# include <cassert> # include <cassert>
@ -2234,14 +2234,22 @@ const NetScope* NetEScope::scope() const
return scope_; return scope_;
} }
NetESFunc::NetESFunc(const string&n, unsigned width) NetESFunc::NetESFunc(const string&n, unsigned width, unsigned np)
: name_(n) : name_(n)
{ {
expr_width(width); expr_width(width);
nparms_ = np;
parms_ = new NetExpr*[np];
for (unsigned idx = 0 ; idx < nparms_ ; idx += 1)
parms_[idx] = 0;
} }
NetESFunc::~NetESFunc() NetESFunc::~NetESFunc()
{ {
for (unsigned idx = 0 ; idx < nparms_ ; idx += 1)
if (parms_[idx]) delete parms_[idx];
delete[]parms_;
} }
const string& NetESFunc::name() const const string& NetESFunc::name() const
@ -2249,6 +2257,31 @@ const string& NetESFunc::name() const
return name_; return name_;
} }
unsigned NetESFunc::nparms() const
{
return nparms_;
}
void NetESFunc::parm(unsigned idx, NetExpr*v)
{
assert(idx < nparms_);
if (parms_[idx])
delete parms_[idx];
parms_[idx] = v;
}
const NetExpr* NetESFunc::parm(unsigned idx) const
{
assert(idx < nparms_);
return parms_[idx];
}
NetExpr* NetESFunc::parm(unsigned idx)
{
assert(idx < nparms_);
return parms_[idx];
}
NetESignal::NetESignal(NetNet*n) NetESignal::NetESignal(NetNet*n)
: NetExpr(n->pin_count()), net_(n) : NetExpr(n->pin_count()), net_(n)
{ {
@ -2604,6 +2637,10 @@ bool NetUDP::sequ_glob_(string input, char output)
/* /*
* $Log: netlist.cc,v $ * $Log: netlist.cc,v $
* Revision 1.124 2000/05/07 18:20:07 steve
* Import MCD support from Stephen Tell, and add
* system function parameter support to the IVL core.
*
* Revision 1.123 2000/05/07 04:37:56 steve * Revision 1.123 2000/05/07 04:37:56 steve
* Carry strength values from Verilog source to the * Carry strength values from Verilog source to the
* pform and netlist for gates. * pform and netlist for gates.

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.136 2000/05/07 04:37:56 steve Exp $" #ident "$Id: netlist.h,v 1.137 2000/05/07 18:20:07 steve Exp $"
#endif #endif
/* /*
@ -2035,18 +2035,21 @@ class NetEScope : public NetExpr {
/* /*
* This node represents a system function call in an expression. The * This node represents a system function call in an expression. The
* object contains the name of the system function, which the backend * object contains the name of the system function, which the backend
* uses to to VPI matching. * uses to do VPI matching.
*
* XXXX NOTE: parameters are not net supported.
*/ */
class NetESFunc : public NetExpr { class NetESFunc : public NetExpr {
public: public:
NetESFunc(const string&name, unsigned width); NetESFunc(const string&name, unsigned width, unsigned nprms);
~NetESFunc(); ~NetESFunc();
const string& name() const; const string& name() const;
unsigned nparms() const;
void parm(unsigned idx, NetExpr*expr);
NetExpr* parm(unsigned idx);
const NetExpr* parm(unsigned idx) const;
virtual bool set_width(unsigned); virtual bool set_width(unsigned);
virtual void dump(ostream&) const; virtual void dump(ostream&) const;
@ -2055,6 +2058,8 @@ class NetESFunc : public NetExpr {
private: private:
string name_; string name_;
unsigned nparms_;
NetExpr**parms_;
private: // not implemented private: // not implemented
NetESFunc(const NetESFunc&); NetESFunc(const NetESFunc&);
@ -2510,6 +2515,10 @@ extern ostream& operator << (ostream&, NetNet::Type);
/* /*
* $Log: netlist.h,v $ * $Log: netlist.h,v $
* Revision 1.137 2000/05/07 18:20:07 steve
* Import MCD support from Stephen Tell, and add
* system function parameter support to the IVL core.
*
* Revision 1.136 2000/05/07 04:37:56 steve * Revision 1.136 2000/05/07 04:37:56 steve
* Carry strength values from Verilog source to the * Carry strength values from Verilog source to the
* pform and netlist for gates. * pform and netlist for gates.

178
t-vvm.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: t-vvm.cc,v 1.144 2000/05/07 04:37:56 steve Exp $" #ident "$Id: t-vvm.cc,v 1.145 2000/05/07 18:20:07 steve Exp $"
#endif #endif
# include <iostream> # include <iostream>
@ -94,7 +94,7 @@ class target_vvm : public target_t {
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 bool proc_force(ostream&os, const NetForce*);
virtual void proc_forever(ostream&os, const NetForever*); virtual void proc_forever(ostream&os, const NetForever*);
virtual bool target_vvm::proc_release(ostream&os, const NetRelease*); virtual bool proc_release(ostream&os, const NetRelease*);
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*);
virtual bool proc_trigger(ostream&os, const NetEvTrig*); virtual bool proc_trigger(ostream&os, const NetEvTrig*);
@ -222,14 +222,14 @@ target_vvm::~target_vvm()
class vvm_proc_rval : public expr_scan_t { class vvm_proc_rval : public expr_scan_t {
public: public:
explicit vvm_proc_rval(ostream&os, unsigned i) explicit vvm_proc_rval(ostream&os, target_vvm*t)
: result(""), os_(os), indent_(i) { } : result(""), os_(os), tgt_(t) { }
string result; string result;
private: private:
ostream&os_; ostream&os_;
unsigned indent_; target_vvm*tgt_;
private: private:
virtual void expr_const(const NetEConst*); virtual void expr_const(const NetEConst*);
@ -245,6 +245,34 @@ class vvm_proc_rval : public expr_scan_t {
virtual void expr_ufunc(const NetEUFunc*); virtual void expr_ufunc(const NetEUFunc*);
}; };
/*
* The vvm_parm_rval class scans expressions for the purpose of making
* parameters for system tasks/functions. Thus, the generated code is
* geared towards making the handles needed to make the call.
*
* The result of any parm rval scan is a vpiHandle, or a string that
* automatically converts to a vpiHandle on assignment.
*/
class vvm_parm_rval : public expr_scan_t {
public:
explicit vvm_parm_rval(ostream&o, target_vvm*t)
: result(""), os_(o), tgt_(t) { }
string result;
private:
virtual void expr_const(const NetEConst*);
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:
ostream&os_;
target_vvm*tgt_;
};
/* /*
* Handle the concatenation operator in a procedural r-value * Handle the concatenation operator in a procedural r-value
* expression. Evaluate the concatenation into a temporary variable * expression. Evaluate the concatenation into a temporary variable
@ -269,7 +297,7 @@ void vvm_proc_rval::expr_concat(const NetEConcat*expr)
pp->expr_scan(this); pp->expr_scan(this);
for (unsigned bit = 0 ; bit < pp->expr_width() ; bit += 1) { for (unsigned bit = 0 ; bit < pp->expr_width() ; bit += 1) {
os_ << setw(indent_) << "" << tname << "[" << pos << os_ << " " << tname << "[" << pos <<
"] = " << result << "[" << bit << "];" << "] = " << result << "[" << bit << "];" <<
endl; endl;
pos+= 1; pos+= 1;
@ -359,10 +387,38 @@ void vvm_proc_rval::expr_sfunc(const NetESFunc*fun)
const string retval = make_temp(); const string retval = make_temp();
const unsigned retwid = fun->expr_width(); const unsigned retwid = fun->expr_width();
/* Make any parameters that might be needed to be passed to
the function. */
const string parmtab = make_temp();
if (fun->nparms() > 0) {
os_ << " vpiHandle " << parmtab
<< "["<<fun->nparms()<<"];" << endl;
for (unsigned idx = 0 ; idx < fun->nparms() ; idx += 1) {
vvm_parm_rval scan(os_, tgt_);
fun->parm(idx)->expr_scan(&scan);
os_ << " " << parmtab <<"["<<idx<<"] = "
<< scan.result << ";" << endl;
}
}
/* Draw the call to the function. Create a vpip_bit_t array to
receive the return value, and make it into a vvm_bitset_t
when the call returns. */
os_ << " vpip_bit_t " << retval << "_bits["<<retwid<<"];" << endl; os_ << " vpip_bit_t " << retval << "_bits["<<retwid<<"];" << endl;
os_ << " vpip_callfunc(\"" << fun->name() << "\", " os_ << " vpip_callfunc(\"" << fun->name() << "\", "
<< retval<<"_bits, " << retwid << ");" << endl; << retwid << ", " << retval<<"_bits";
if (fun->nparms() == 0)
os_ << ", 0, 0";
else
os_ << ", " << fun->nparms() << ", " << parmtab;
os_ << ");" << endl;
os_ << " vvm_bitset_t " << retval << "(" << retval<<"_bits, " os_ << " vvm_bitset_t " << retval << "(" << retval<<"_bits, "
<< retwid << ");" << endl; << retwid << ");" << endl;
@ -555,87 +611,87 @@ void vvm_proc_rval::expr_binary(const NetEBinary*expr)
switch (expr->op()) { switch (expr->op()) {
case 'a': // logical and (&&) case 'a': // logical and (&&)
os_ << setw(indent_) << "" << result << "[0] = vvm_binop_land(" os_ << " " << result << "[0] = vvm_binop_land("
<< lres << "," << rres << ");" << endl; << lres << "," << rres << ");" << endl;
break; break;
case 'E': // === case 'E': // ===
os_ << setw(indent_) << "" << result << "[0] = vvm_binop_eeq(" os_ << " " << result << "[0] = vvm_binop_eeq("
<< lres << "," << rres << ");" << endl; << lres << "," << rres << ");" << endl;
break; break;
case 'e': // == case 'e': // ==
os_ << setw(indent_) << "" << result << "[0] = vvm_binop_eq(" os_ << " " << result << "[0] = vvm_binop_eq("
<< lres << "," << rres << ");" << endl; << lres << "," << rres << ");" << endl;
break; break;
case 'G': // >= case 'G': // >=
os_ << setw(indent_) << "" << result << "[0] = vvm_binop_ge(" os_ << " " << result << "[0] = vvm_binop_ge("
<< lres << "," << rres << ");" << endl; << lres << "," << rres << ");" << endl;
break; break;
case 'l': // left shift(<<) case 'l': // left shift(<<)
os_ << setw(indent_) << "" << "vvm_binop_shiftl(" << result os_ << " " << "vvm_binop_shiftl(" << result
<< ", " << lres << "," << rres << ");" << endl; << ", " << lres << "," << rres << ");" << endl;
break; break;
case 'L': // <= case 'L': // <=
os_ << setw(indent_) << "" << result << "[0] = vvm_binop_le(" os_ << " " << result << "[0] = vvm_binop_le("
<< lres << "," << rres << ");" << endl; << lres << "," << rres << ");" << endl;
break; break;
case 'N': // !== case 'N': // !==
os_ << setw(indent_) << "" << result << "[0] = vvm_binop_nee(" os_ << " " << result << "[0] = vvm_binop_nee("
<< lres << "," << rres << ");" << endl; << lres << "," << rres << ");" << endl;
break; break;
case 'n': case 'n':
os_ << setw(indent_) << "" << result << "[0] = vvm_binop_ne(" os_ << " " << result << "[0] = vvm_binop_ne("
<< lres << "," << rres << ");" << endl; << lres << "," << rres << ");" << endl;
break; break;
case '<': case '<':
os_ << setw(indent_) << "" << result << "[0] = vvm_binop_lt(" os_ << " " << result << "[0] = vvm_binop_lt("
<< lres << "," << rres << ");" << endl; << lres << "," << rres << ");" << endl;
break; break;
case '>': case '>':
os_ << setw(indent_) << "" << result << "[0] = vvm_binop_gt(" os_ << " " << result << "[0] = vvm_binop_gt("
<< lres << "," << rres << ");" << endl; << lres << "," << rres << ");" << endl;
break; break;
case 'o': // logical or (||) case 'o': // logical or (||)
os_ << setw(indent_) << "" << result << "[0] = vvm_binop_lor(" os_ << " " << result << "[0] = vvm_binop_lor("
<< lres << "," << rres << ");" << endl; << lres << "," << rres << ");" << endl;
break; break;
case 'r': // right shift(>>) case 'r': // right shift(>>)
os_ << setw(indent_) << "" << "vvm_binop_shiftr(" << result os_ << " " << "vvm_binop_shiftr(" << result
<< ", " << lres << "," << rres << ");" << endl; << ", " << lres << "," << rres << ");" << endl;
break; break;
case 'X': case 'X':
os_ << setw(indent_) << "" << "vvm_binop_xnor(" << result os_ << " " << "vvm_binop_xnor(" << result
<< ", " << lres << "," << rres << ");" << endl; << ", " << lres << "," << rres << ");" << endl;
break; break;
case '+': case '+':
os_ << setw(indent_) << "" << "vvm_binop_plus(" << result os_ << " " << "vvm_binop_plus(" << result
<< ", " << lres << "," << rres << ");" << endl; << ", " << lres << "," << rres << ");" << endl;
break; break;
case '-': case '-':
os_ << setw(indent_) << "" << "vvm_binop_minus(" << result os_ << " " << "vvm_binop_minus(" << result
<< ", " << lres << "," << rres << ");" << endl; << ", " << lres << "," << rres << ");" << endl;
break; break;
case '&': case '&':
os_ << setw(indent_) << "" << "vvm_binop_and(" << result os_ << " " << "vvm_binop_and(" << result
<< ", " << lres << ", " << rres << ");" << endl; << ", " << lres << ", " << rres << ");" << endl;
break; break;
case '|': case '|':
os_ << setw(indent_) << "" << "vvm_binop_or(" << result os_ << " " << "vvm_binop_or(" << result
<< ", " << lres << ", " << rres << ");" << endl; << ", " << lres << ", " << rres << ");" << endl;
break; break;
case '^': case '^':
os_ << setw(indent_) << "" << "vvm_binop_xor(" << result os_ << " " << "vvm_binop_xor(" << result
<< ", " << lres << ", " << rres << ");" << endl; << ", " << lres << ", " << rres << ");" << endl;
break; break;
case '*': case '*':
os_ << setw(indent_) << "" << "vvm_binop_mult(" << result os_ << " " << "vvm_binop_mult(" << result
<< "," << lres << "," << rres << ");" << endl; << "," << lres << "," << rres << ");" << endl;
break; break;
case '/': case '/':
os_ << setw(indent_) << "" << "vvm_binop_idiv(" << result os_ << " " << "vvm_binop_idiv(" << result
<< "," << lres << "," << rres << ");" << endl; << "," << lres << "," << rres << ");" << endl;
break; break;
case '%': case '%':
os_ << setw(indent_) << "" << "vvm_binop_imod(" << result os_ << " " << "vvm_binop_imod(" << result
<< "," << lres << "," << rres << ");" << endl; << "," << lres << "," << rres << ");" << endl;
break; break;
default: default:
@ -648,41 +704,13 @@ void vvm_proc_rval::expr_binary(const NetEBinary*expr)
} }
} }
static string emit_proc_rval(ostream&os, unsigned indent, const NetExpr*expr) static string emit_proc_rval(ostream&os, target_vvm*tgt, const NetExpr*expr)
{ {
vvm_proc_rval scan (os, indent); vvm_proc_rval scan (os, tgt);
expr->expr_scan(&scan); expr->expr_scan(&scan);
return scan.result; return scan.result;
} }
/*
* The vvm_parm_rval class scans expressions for the purpose of making
* parameters for system tasks/functions. Thus, the generated code is
* geared towards making the handles needed to make the call.
*
* The result of any parm rval scan is a vpiHandle, or a string that
* automatically converts to a vpiHandle on assignment.
*/
class vvm_parm_rval : public expr_scan_t {
public:
explicit vvm_parm_rval(ostream&o, target_vvm*t)
: result(""), os_(o), tgt_(t) { }
string result;
private:
virtual void expr_const(const NetEConst*);
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:
ostream&os_;
target_vvm*tgt_;
};
void vvm_parm_rval::expr_const(const NetEConst*expr) void vvm_parm_rval::expr_const(const NetEConst*expr)
{ {
if (expr->value().is_string()) { if (expr->value().is_string()) {
@ -770,7 +798,7 @@ void vvm_parm_rval::expr_memory(const NetEMemory*mem)
/* Otherwise, evaluate the index at run time and use /* Otherwise, evaluate the index at run time and use
that to select the memory word. */ that to select the memory word. */
string rval = emit_proc_rval(tgt_->defn, 6, mem->index()); string rval = emit_proc_rval(tgt_->defn, tgt_, mem->index());
result = "vpi_handle_by_index(&" + mangle(mem->name()) + result = "vpi_handle_by_index(&" + mangle(mem->name()) +
".base, " + rval + ".as_unsigned())"; ".base, " + rval + ".as_unsigned())";
} }
@ -1934,7 +1962,7 @@ void target_vvm::proc_assign(ostream&os, const NetAssign*net)
return; return;
} }
string rval = emit_proc_rval(defn, 8, net->rval()); string rval = emit_proc_rval(defn, this, net->rval());
defn << " // " << net->get_line() << ": " << endl; defn << " // " << net->get_line() << ": " << endl;
@ -1942,7 +1970,7 @@ void target_vvm::proc_assign(ostream&os, const NetAssign*net)
// This is a bit select. Assign the low bit of the rval // This is a bit select. Assign the low bit of the rval
// to the selected bit of the lval. // to the selected bit of the lval.
string bval = emit_proc_rval(defn, 8, net->bmux()); string bval = emit_proc_rval(defn, this, net->bmux());
defn << " switch (" << bval << ".as_unsigned()) {" << endl; defn << " switch (" << bval << ".as_unsigned()) {" << endl;
@ -1997,7 +2025,7 @@ void target_vvm::proc_assign_mem(ostream&os, const NetAssignMem*amem)
<< mangle(amem->index()->name()) << ".nbits);" << endl; << mangle(amem->index()->name()) << ".nbits);" << endl;
/* Evaluate the rval that gets written into the memory word. */ /* Evaluate the rval that gets written into the memory word. */
string rval = emit_proc_rval(defn, 8, amem->rval()); string rval = emit_proc_rval(defn, this, amem->rval());
const NetMemory*mem = amem->memory(); const NetMemory*mem = amem->memory();
@ -2018,7 +2046,7 @@ void target_vvm::proc_assign_mem(ostream&os, const NetAssignMem*amem)
void target_vvm::proc_assign_nb(ostream&os, const NetAssignNB*net) void target_vvm::proc_assign_nb(ostream&os, const NetAssignNB*net)
{ {
string rval = emit_proc_rval(defn, 8, net->rval()); string rval = emit_proc_rval(defn, this, net->rval());
const unsigned long delay = net->rise_time(); const unsigned long delay = net->rise_time();
if (net->bmux()) { if (net->bmux()) {
@ -2030,7 +2058,7 @@ void target_vvm::proc_assign_nb(ostream&os, const NetAssignNB*net)
better generating a demux device and doing the assign better generating a demux device and doing the assign
to the device input. Food for thought. */ to the device input. Food for thought. */
string bval = emit_proc_rval(defn, 8, net->bmux()); string bval = emit_proc_rval(defn, this, net->bmux());
defn << " switch (" << bval << ".as_unsigned()) {" << endl; defn << " switch (" << bval << ".as_unsigned()) {" << endl;
for (unsigned idx = 0 ; idx < net->pin_count() ; idx += 1) { for (unsigned idx = 0 ; idx < net->pin_count() ; idx += 1) {
@ -2068,7 +2096,7 @@ void target_vvm::proc_assign_mem_nb(ostream&os, const NetAssignMemNB*amem)
/* Evaluate the rval that gets written into the memory word. */ /* Evaluate the rval that gets written into the memory word. */
string rval = emit_proc_rval(defn, 8, amem->rval()); string rval = emit_proc_rval(defn, this, amem->rval());
const NetMemory*mem = amem->memory(); const NetMemory*mem = amem->memory();
@ -2198,7 +2226,7 @@ void target_vvm::proc_case(ostream&os, const NetCase*net)
} }
defn << " /* case (" << *net->expr() << ") */" << endl; defn << " /* case (" << *net->expr() << ") */" << endl;
string expr = emit_proc_rval(defn, 8, net->expr()); string expr = emit_proc_rval(defn, this, net->expr());
unsigned exit_step = thread_step_ + 1; unsigned exit_step = thread_step_ + 1;
thread_step_ += 1; thread_step_ += 1;
@ -2219,7 +2247,7 @@ void target_vvm::proc_case(ostream&os, const NetCase*net)
thread_step_ += 1; thread_step_ += 1;
defn << " /* " << *net->expr(idx) << " */" << endl; defn << " /* " << *net->expr(idx) << " */" << endl;
string guard = emit_proc_rval(defn, 8, net->expr(idx)); string guard = emit_proc_rval(defn, this, net->expr(idx));
defn << " if (B_IS1(" << test_func << "(" << guard << "," defn << " if (B_IS1(" << test_func << "(" << guard << ","
<< expr << "))) {" << endl; << expr << "))) {" << endl;
@ -2323,7 +2351,7 @@ void target_vvm::proc_case_fun(ostream&os, const NetCase*net)
defn << " do {" << endl; defn << " do {" << endl;
string expr = emit_proc_rval(defn, 6, net->expr()); string expr = emit_proc_rval(defn, this, net->expr());
unsigned default_idx = net->nitems(); unsigned default_idx = net->nitems();
for (unsigned idx = 0 ; idx < net->nitems() ; idx += 1) { for (unsigned idx = 0 ; idx < net->nitems() ; idx += 1) {
@ -2335,7 +2363,7 @@ void target_vvm::proc_case_fun(ostream&os, const NetCase*net)
continue; continue;
} }
string guard = emit_proc_rval(defn, 6, net->expr(idx)); string guard = emit_proc_rval(defn, this, net->expr(idx));
defn << " if (B_IS1(" << test_func << "(" << defn << " if (B_IS1(" << test_func << "(" <<
guard << "," << expr << "))) {" << endl; guard << "," << expr << "))) {" << endl;
@ -2360,7 +2388,7 @@ void target_vvm::proc_condit(ostream&os, const NetCondit*net)
return; return;
} }
string expr = emit_proc_rval(defn, 8, net->expr()); string expr = emit_proc_rval(defn, this, net->expr());
unsigned if_step = ++thread_step_; unsigned if_step = ++thread_step_;
unsigned else_step = ++thread_step_; unsigned else_step = ++thread_step_;
@ -2408,7 +2436,7 @@ void target_vvm::proc_condit(ostream&os, const NetCondit*net)
void target_vvm::proc_condit_fun(ostream&os, const NetCondit*net) void target_vvm::proc_condit_fun(ostream&os, const NetCondit*net)
{ {
string expr = emit_proc_rval(defn, 8, net->expr()); string expr = emit_proc_rval(defn, this, net->expr());
defn << " // " << net->get_line() << ": conditional (if-else)" defn << " // " << net->get_line() << ": conditional (if-else)"
<< endl; << endl;
@ -2489,7 +2517,7 @@ bool target_vvm::proc_release(ostream&os, const NetRelease*dev)
void target_vvm::proc_repeat(ostream&os, const NetRepeat*net) void target_vvm::proc_repeat(ostream&os, const NetRepeat*net)
{ {
string expr = emit_proc_rval(defn, 8, net->expr()); string expr = emit_proc_rval(defn, this, net->expr());
unsigned top_step = ++thread_step_; unsigned top_step = ++thread_step_;
unsigned out_step = ++thread_step_; unsigned out_step = ++thread_step_;
@ -2696,7 +2724,7 @@ void target_vvm::proc_while(ostream&os, const NetWhile*net)
defn << "static bool " << thread_class_ << "_step_" defn << "static bool " << thread_class_ << "_step_"
<< head_step << "_(vvm_thread*thr) {" << endl; << head_step << "_(vvm_thread*thr) {" << endl;
string expr = emit_proc_rval(defn, 8, net->expr()); string expr = emit_proc_rval(defn, this, net->expr());
defn << "// " << net->expr()->get_line() << defn << "// " << net->expr()->get_line() <<
": test while condition." << endl; ": test while condition." << endl;
@ -2764,6 +2792,10 @@ extern const struct target tgt_vvm = {
}; };
/* /*
* $Log: t-vvm.cc,v $ * $Log: t-vvm.cc,v $
* Revision 1.145 2000/05/07 18:20:07 steve
* Import MCD support from Stephen Tell, and add
* system function parameter support to the IVL core.
*
* Revision 1.144 2000/05/07 04:37:56 steve * Revision 1.144 2000/05/07 04:37:56 steve
* Carry strength values from Verilog source to the * Carry strength values from Verilog source to the
* pform and netlist for gates. * pform and netlist for gates.

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: sys_display.c,v 1.13 2000/04/21 02:00:35 steve Exp $" #ident "$Id: sys_display.c,v 1.14 2000/05/07 18:20:07 steve Exp $"
#endif #endif
# include "vpi_user.h" # include "vpi_user.h"
@ -55,7 +55,7 @@ static void array_from_iterator(struct strobe_cb_info*info, vpiHandle argv)
* well so that I can look for arguments as I move forward through the * well so that I can look for arguments as I move forward through the
* string. * string.
*/ */
static int format_str(char*fmt, int argc, vpiHandle*argv) static int format_str(unsigned int mcd, char*fmt, int argc, vpiHandle*argv)
{ {
s_vpi_value value; s_vpi_value value;
char buf[256]; char buf[256];
@ -73,7 +73,7 @@ static int format_str(char*fmt, int argc, vpiHandle*argv)
cnt = sizeof buf - 1; cnt = sizeof buf - 1;
strncpy(buf, cp, cnt); strncpy(buf, cp, cnt);
buf[cnt] = 0; buf[cnt] = 0;
vpi_printf("%s", buf); vpi_mcd_printf(mcd, "%s", buf);
cp += cnt; cp += cnt;
} else if (*cp == '%') { } else if (*cp == '%') {
@ -90,14 +90,14 @@ static int format_str(char*fmt, int argc, vpiHandle*argv)
case 'B': case 'B':
value.format = vpiBinStrVal; value.format = vpiBinStrVal;
vpi_get_value(argv[idx++], &value); vpi_get_value(argv[idx++], &value);
vpi_printf("%s", value.value.str); vpi_mcd_printf(mcd, "%s", value.value.str);
cp += 1; cp += 1;
break; break;
case 'd': case 'd':
case 'D': case 'D':
value.format = vpiDecStrVal; value.format = vpiDecStrVal;
vpi_get_value(argv[idx++], &value); vpi_get_value(argv[idx++], &value);
vpi_printf("%s", value.value.str); vpi_mcd_printf(mcd, "%s", value.value.str);
cp += 1; cp += 1;
break; break;
case 'h': case 'h':
@ -110,11 +110,11 @@ static int format_str(char*fmt, int argc, vpiHandle*argv)
} }
value.format = vpiHexStrVal; value.format = vpiHexStrVal;
vpi_get_value(argv[idx++], &value); vpi_get_value(argv[idx++], &value);
vpi_printf("%s", value.value.str); vpi_mcd_printf(mcd, "%s", value.value.str);
cp += 1; cp += 1;
break; break;
case 'm': case 'm':
vpi_printf("%s", vpi_get_str(vpiFullName, argv[idx])); vpi_mcd_printf(mcd, "%s", vpi_get_str(vpiFullName, argv[idx]));
idx += 1; idx += 1;
cp += 1; cp += 1;
break; break;
@ -122,22 +122,22 @@ static int format_str(char*fmt, int argc, vpiHandle*argv)
case 'O': case 'O':
value.format = vpiOctStrVal; value.format = vpiOctStrVal;
vpi_get_value(argv[idx++], &value); vpi_get_value(argv[idx++], &value);
vpi_printf("%s", value.value.str); vpi_mcd_printf(mcd, "%s", value.value.str);
cp += 1; cp += 1;
break; break;
case 't': case 't':
case 'T': case 'T':
value.format = vpiDecStrVal; value.format = vpiDecStrVal;
vpi_get_value(argv[idx++], &value); vpi_get_value(argv[idx++], &value);
vpi_printf("%s", value.value.str); vpi_mcd_printf(mcd, "%s", value.value.str);
cp += 1; cp += 1;
break; break;
case '%': case '%':
vpi_printf("%%"); vpi_mcd_printf(mcd, "%%");
cp += 1; cp += 1;
break; break;
default: default:
vpi_printf("%c", *cp); vpi_mcd_printf(mcd, "%c", *cp);
cp += 1; cp += 1;
break; break;
} }
@ -149,11 +149,11 @@ static int format_str(char*fmt, int argc, vpiHandle*argv)
case 0: case 0:
break; break;
case 'n': case 'n':
vpi_printf("\n"); vpi_mcd_printf(mcd, "\n");
cp += 1; cp += 1;
break; break;
default: default:
vpi_printf("%c", *cp); vpi_mcd_printf(mcd, "%c", *cp);
cp += 1; cp += 1;
} }
} }
@ -162,7 +162,7 @@ static int format_str(char*fmt, int argc, vpiHandle*argv)
return idx; return idx;
} }
static void do_display(struct strobe_cb_info*info) static void do_display(unsigned int mcd, struct strobe_cb_info*info)
{ {
s_vpi_value value; s_vpi_value value;
int idx; int idx;
@ -173,20 +173,20 @@ static void do_display(struct strobe_cb_info*info)
switch (vpi_get(vpiType, item)) { switch (vpi_get(vpiType, item)) {
case 0: case 0:
vpi_printf(" "); vpi_mcd_printf(mcd, " ");
break; break;
case vpiConstant: case vpiConstant:
if (vpi_get(vpiConstType, item) == vpiStringConst) { if (vpi_get(vpiConstType, item) == vpiStringConst) {
value.format = vpiStringVal; value.format = vpiStringVal;
vpi_get_value(item, &value); vpi_get_value(item, &value);
idx += format_str(value.value.str, idx += format_str(mcd, value.value.str,
info->nitems-idx-1, info->nitems-idx-1,
info->items+idx+1); info->items+idx+1);
} else { } else {
value.format = vpiBinStrVal; value.format = vpiBinStrVal;
vpi_get_value(item, &value); vpi_get_value(item, &value);
vpi_printf("%s", value.value.str); vpi_mcd_printf(mcd, "%s", value.value.str);
} }
break; break;
@ -195,17 +195,17 @@ static void do_display(struct strobe_cb_info*info)
case vpiMemoryWord: case vpiMemoryWord:
value.format = vpiBinStrVal; value.format = vpiBinStrVal;
vpi_get_value(item, &value); vpi_get_value(item, &value);
vpi_printf("%s", value.value.str); vpi_mcd_printf(mcd, "%s", value.value.str);
break; break;
case vpiTimeVar: case vpiTimeVar:
value.format = vpiTimeVal; value.format = vpiTimeVal;
vpi_get_value(item, &value); vpi_get_value(item, &value);
vpi_printf("%u", value.value.time->low); vpi_mcd_printf(mcd, "%u", value.value.time->low);
break; break;
default: default:
vpi_printf("?"); vpi_mcd_printf(mcd, "?");
break; break;
} }
} }
@ -220,7 +220,7 @@ static int sys_display_calltf(char *name)
array_from_iterator(&info, argv); array_from_iterator(&info, argv);
do_display(&info); do_display(1, &info);
free(info.items); free(info.items);
@ -242,7 +242,7 @@ static int strobe_cb(p_cb_data cb)
{ {
struct strobe_cb_info*info = (struct strobe_cb_info*)cb->user_data; struct strobe_cb_info*info = (struct strobe_cb_info*)cb->user_data;
do_display(info); do_display(1, info);
vpi_printf("\n"); vpi_printf("\n");
@ -294,7 +294,7 @@ static vpiHandle *monitor_callbacks = 0;
static int monitor_cb_2(p_cb_data cb) static int monitor_cb_2(p_cb_data cb)
{ {
do_display(&monitor_info); do_display(1, &monitor_info);
vpi_printf("\n"); vpi_printf("\n");
monitor_scheduled = 0; monitor_scheduled = 0;
return 0; return 0;
@ -385,6 +385,126 @@ static int sys_monitor_calltf(char*name)
return 0; return 0;
} }
/*
* Implement the $fopen system function.
*/
static int sys_fopen_calltf(char *name)
{
s_vpi_value val, value;
vpiHandle call_handle = vpi_handle(vpiSysTfCall, 0);
vpiHandle argv = vpi_iterate(vpiArgument, call_handle);
vpiHandle item = vpi_scan(argv);
if (item == 0) {
vpi_printf("%s: file name parameter missing.\n", name);
return 0;
}
if (vpi_get(vpiType, item) != vpiConstant) {
vpi_printf("ERROR: %s parameter must be a constant\n", name);
vpi_free_object(argv);
return 0;
}
if (vpi_get(vpiConstType, item) != vpiStringConst) {
vpi_printf("ERROR: %s parameter must be a constant\n", name);
vpi_free_object(argv);
return 0;
}
value.format = vpiStringVal;
vpi_get_value(item, &value);
val.format = vpiIntVal;
val.value.integer = vpi_mcd_open( value.value.str );
vpi_put_value(call_handle, &val, 0, vpiNoDelay);
return 0;
}
static int sys_fopen_sizetf(char*x)
{
return 32;
}
/* Implement $fdisplay and $fwrite.
* Perhaps this could be merged into sys_display_calltf.
*/
static int sys_fdisplay_calltf(char *name)
{
struct strobe_cb_info info;
unsigned int mcd;
int type;
s_vpi_value value;
vpiHandle sys = vpi_handle(vpiSysTfCall, 0);
vpiHandle argv = vpi_iterate(vpiArgument, sys);
vpiHandle item = vpi_scan(argv);
if (item == 0) {
vpi_printf("%s: mcd parameter missing.\n", name);
return 0;
}
type = vpi_get(vpiType, item);
if (type != vpiReg && type != vpiReadVal) {
vpi_printf("ERROR: %s mcd parameter must be of integral, got vpiType=%d\n",
name, type);
vpi_free_object(argv);
return 0;
}
value.format = vpiIntVal;
vpi_get_value(item, &value);
mcd = value.value.integer;
array_from_iterator(&info, argv);
do_display(mcd, &info);
free(info.items);
if (strcmp(name,"$fdisplay") == 0)
vpi_mcd_printf(mcd, "\n");
return 0;
}
/*
* Implement $fclose system function
*/
static int sys_fclose_calltf(char *name)
{
unsigned int mcd;
int type;
s_vpi_value value;
vpiHandle sys = vpi_handle(vpiSysTfCall, 0);
vpiHandle argv = vpi_iterate(vpiArgument, sys);
vpiHandle item = vpi_scan(argv);
if (item == 0) {
vpi_printf("%s: mcd parameter missing.\n", name);
return 0;
}
type = vpi_get(vpiType, item);
if (type != vpiReg && type != vpiReadVal) {
vpi_printf("ERROR: %s mcd parameter must be of integral type, got vpiType=%d\n",
name, type);
vpi_free_object(argv);
return 0;
}
value.format = vpiIntVal;
vpi_get_value(item, &value);
mcd = value.value.integer;
vpi_printf("in fclose_calltf mcd=%d type=%d\n", mcd, value.format);
vpi_mcd_close(mcd);
return 0;
}
void sys_display_register() void sys_display_register()
{ {
s_vpi_systf_data tf_data; s_vpi_systf_data tf_data;
@ -420,11 +540,49 @@ void sys_display_register()
tf_data.sizetf = 0; tf_data.sizetf = 0;
tf_data.user_data = "$monitor"; tf_data.user_data = "$monitor";
vpi_register_systf(&tf_data); vpi_register_systf(&tf_data);
tf_data.type = vpiSysFunc;
tf_data.tfname = "$fopen";
tf_data.calltf = sys_fopen_calltf;
tf_data.compiletf = 0;
tf_data.sizetf = sys_fopen_sizetf;
tf_data.user_data = "$fopen";
vpi_register_systf(&tf_data);
tf_data.type = vpiSysTask;
tf_data.tfname = "$fclose";
tf_data.calltf = sys_fclose_calltf;
tf_data.compiletf = 0;
tf_data.sizetf = 0;
tf_data.user_data = "$fclose";
vpi_register_systf(&tf_data);
tf_data.type = vpiSysTask;
tf_data.tfname = "$fdisplay";
tf_data.calltf = sys_fdisplay_calltf;
tf_data.compiletf = 0;
tf_data.sizetf = 0;
tf_data.user_data = "$fdisplay";
vpi_register_systf(&tf_data);
tf_data.type = vpiSysTask;
tf_data.tfname = "$fwrite";
tf_data.calltf = sys_fdisplay_calltf;
tf_data.compiletf = 0;
tf_data.sizetf = 0;
tf_data.user_data = "$fwrite";
vpi_register_systf(&tf_data);
vpi_mcd_init();
} }
/* /*
* $Log: sys_display.c,v $ * $Log: sys_display.c,v $
* Revision 1.14 2000/05/07 18:20:07 steve
* Import MCD support from Stephen Tell, and add
* system function parameter support to the IVL core.
*
* Revision 1.13 2000/04/21 02:00:35 steve * Revision 1.13 2000/04/21 02:00:35 steve
* exit if hex value is missing. * exit if hex value is missing.
* *

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_user.h,v 1.15 2000/05/04 03:37:59 steve Exp $" #ident "$Id: vpi_user.h,v 1.16 2000/05/07 18:20:08 steve Exp $"
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
@ -145,6 +145,11 @@ typedef struct t_vpi_value {
extern void vpi_register_systf(const struct t_vpi_systf_data*ss); extern void vpi_register_systf(const struct t_vpi_systf_data*ss);
extern void vpi_printf(const char*fmt, ...); extern void vpi_printf(const char*fmt, ...);
extern unsigned int vpi_mcd_close(unsigned int mcd);
extern char *vpi_mcd_name(unsigned int mcd);
extern unsigned int vpi_mcd_open(char *name);
extern int vpi_mcd_printf(unsigned int mcd, const char*fmt, ...);
/* /*
* support for VPI callback functions. * support for VPI callback functions.
*/ */
@ -231,6 +236,10 @@ extern void (*vlog_startup_routines[])();
/* /*
* $Log: vpi_user.h,v $ * $Log: vpi_user.h,v $
* Revision 1.16 2000/05/07 18:20:08 steve
* Import MCD support from Stephen Tell, and add
* system function parameter support to the IVL core.
*
* Revision 1.15 2000/05/04 03:37:59 steve * Revision 1.15 2000/05/04 03:37:59 steve
* Add infrastructure for system functions, move * Add infrastructure for system functions, move
* $time to that structure and add $random. * $time to that structure and add $random.

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.29 2000/04/22 04:20:20 steve Exp $" #ident "$Id: Makefile.in,v 1.30 2000/05/07 18:20:08 steve Exp $"
# #
# #
SHELL = /bin/sh SHELL = /bin/sh
@ -65,7 +65,8 @@ vvm_nexus.o vvm_pevent.o vvm_signal.o vvm_thread.o vvm_udp.o vpip.o
P = vpi_bit.o vpi_callback.o \ P = vpi_bit.o vpi_callback.o \
vpi_const.o vpi_iter.o vpi_memory.o vpi_null.o \ vpi_const.o vpi_iter.o vpi_memory.o vpi_null.o \
vpi_priv.o vpi_scope.o vpi_signal.o vpi_simulation.o vpi_systask.o vpi_time.o vpi_priv.o vpi_scope.o vpi_signal.o vpi_simulation.o vpi_systask.o vpi_time.o \
vpi_mcd.o
libvvm.a: $O libvvm.a: $O
rm -f $@ rm -f $@

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: vpi_const.c,v 1.7 2000/03/22 04:26:41 steve Exp $" #ident "$Id: vpi_const.c,v 1.8 2000/05/07 18:20:08 steve Exp $"
#endif #endif
# include "vpi_priv.h" # include "vpi_priv.h"
@ -36,6 +36,7 @@ void vpip_bits_get_value(vpip_bit_t*bits, unsigned nbits, s_vpi_value*vp)
char*cp; char*cp;
unsigned val; unsigned val;
unsigned idx; unsigned idx;
int isx;
cp = buff; cp = buff;
@ -53,6 +54,8 @@ void vpip_bits_get_value(vpip_bit_t*bits, unsigned nbits, s_vpi_value*vp)
*cp++ = 'x'; *cp++ = 'x';
} }
vp->format = vpiBinStrVal; vp->format = vpiBinStrVal;
*cp++ = 0;
vp->value.str = buff;
break; break;
case vpiDecStrVal: case vpiDecStrVal:
@ -64,6 +67,8 @@ void vpip_bits_get_value(vpip_bit_t*bits, unsigned nbits, s_vpi_value*vp)
} }
sprintf(cp, "%u", val); sprintf(cp, "%u", val);
cp += strlen(cp); cp += strlen(cp);
*cp++ = 0;
vp->value.str = buff;
break; break;
case vpiOctStrVal: case vpiOctStrVal:
@ -123,6 +128,8 @@ void vpip_bits_get_value(vpip_bit_t*bits, unsigned nbits, s_vpi_value*vp)
else else
*cp++ = "01234567"[v]; *cp++ = "01234567"[v];
} }
*cp++ = 0;
vp->value.str = buff;
break; break;
case vpiHexStrVal: case vpiHexStrVal:
@ -184,17 +191,36 @@ void vpip_bits_get_value(vpip_bit_t*bits, unsigned nbits, s_vpi_value*vp)
else else
*cp++ = "0123456789abcdef"[v]; *cp++ = "0123456789abcdef"[v];
} }
*cp++ = 0;
vp->value.str = buff;
break;
case vpiIntVal:
val = 0;
isx = 0;
for (idx = 0 ; idx < nbits ; idx += 1) {
val *= 2;
if (B_ISXZ(bits[nbits-idx-1]))
isx = 1;
else if (B_IS1(bits[nbits-idx-1]))
val += 1;
}
if(isx)
vp->value.integer = 0;
else
vp->value.integer = val;
break; break;
default: default:
*cp++ = '('; *cp++ = '(';
*cp++ = '?'; *cp++ = '?';
*cp++ = ')'; *cp++ = ')';
*cp++ = 0;
vp->format = vpiStringVal;
vp->value.str = buff;
break; break;
} }
*cp++ = 0;
vp->value.str = buff;
} }
static int string_get(int code, vpiHandle ref) static int string_get(int code, vpiHandle ref)
@ -291,6 +317,10 @@ vpiHandle vpip_make_number_const(struct __vpiNumberConst*ref,
/* /*
* $Log: vpi_const.c,v $ * $Log: vpi_const.c,v $
* Revision 1.8 2000/05/07 18:20:08 steve
* Import MCD support from Stephen Tell, and add
* system function parameter support to the IVL core.
*
* Revision 1.7 2000/03/22 04:26:41 steve * Revision 1.7 2000/03/22 04:26:41 steve
* Replace the vpip_bit_t with a typedef and * Replace the vpip_bit_t with a typedef and
* define values for all the different bit * define values for all the different bit

123
vvm/vpi_mcd.c Normal file
View File

@ -0,0 +1,123 @@
/*
* Copyright (c) 2000 Stephen G. Tell <steve@telltronics.org>
*
* 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: vpi_mcd.c,v 1.1 2000/05/07 18:20:08 steve Exp $"
#endif
# include "vpi_priv.h"
# include <assert.h>
# include <stdarg.h>
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
struct mcd_entry {
FILE *fp;
char *filename;
};
static struct mcd_entry mcd_table[32];
/* Initialize mcd portion of vpi. Must be called before
* any vpi_mcd routines can be used.
*/
void vpi_mcd_init()
{
mcd_table[0].fp = stdout;
mcd_table[0].filename = "<stdout>";
mcd_table[1].fp = stderr;
mcd_table[1].filename = "<stderr>";
mcd_table[2].fp = stdout; /* TODO: initialize this to log file */
mcd_table[2].filename = "<stdlog>";
}
/*
* close one or more channels. we silently refuse to close the preopened ones.
*/
unsigned int vpi_mcd_close(unsigned int mcd)
{
int i;
int rc;
rc = 0;
for(i = 3; i < 31; i++) {
if( ((mcd>>i) & 1) && mcd_table[i].filename) {
if(fclose(mcd_table[i].fp) != 0)
rc |= 1<<i;
free(mcd_table[i].filename);
mcd_table[i].fp = NULL;
mcd_table[i].filename = NULL;
} else {
rc |= 1<<i;
}
}
return rc;
}
char *vpi_mcd_name(unsigned int mcd)
{
int i;
for(i = 0; i < 31; i++) {
if( (mcd>>i) & 1)
return mcd_table[i].filename;
}
return NULL;
}
unsigned int vpi_mcd_open(char *name)
{
int i;
for(i = 0; i < 31; i++) {
if(mcd_table[i].filename == NULL)
goto got_entry;
}
return 0; /* too many open mcd's */
got_entry:
mcd_table[i].fp = fopen(name, "w");
if(mcd_table[i].fp == NULL)
return 0;
mcd_table[i].filename = strdup(name);
return 1<<i;
}
int vpi_mcd_printf(unsigned int mcd, const char*fmt, ...)
{
int i;
int len;
int rc;
va_list ap;
rc = len = 0;
va_start(ap, fmt);
for(i = 0; i < 31; i++) {
if( (mcd>>i) & 1) {
if(mcd_table[i].fp)
len = vfprintf(mcd_table[i].fp, fmt, ap);
else
rc = EOF;
}
}
va_end(ap);
if(rc)
return rc;
else
return len;
}

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: vpi_priv.c,v 1.6 2000/05/04 03:37:59 steve Exp $" #ident "$Id: vpi_priv.c,v 1.7 2000/05/07 18:20:08 steve Exp $"
#endif #endif
# include "vpi_priv.h" # include "vpi_priv.h"
@ -75,16 +75,15 @@ void vpip_calltask(const char*fname, unsigned nparms, vpiHandle*parms)
/* /*
* System functions are kept in the same sort of table as the system * System functions are kept in the same sort of table as the system
* tasks, and we call them in a similar manner. * 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) void vpip_callfunc(const char*fname, unsigned nres, vpip_bit_t*res,
unsigned nparms, vpiHandle*parms)
{ {
struct systf_entry*idx; struct systf_entry*idx;
struct __vpiSysTaskCall cur_task; struct __vpiSysTaskCall cur_task;
cur_task.base.vpi_type = &vpip_sysfunc_rt; cur_task.base.vpi_type = &vpip_sysfunc_rt;
cur_task.args = 0; cur_task.args = parms;
cur_task.nargs = 0; cur_task.nargs = nparms;
cur_task.res = res; cur_task.res = res;
cur_task.nres = nres; cur_task.nres = nres;
@ -220,6 +219,10 @@ void vpi_register_systf(const struct t_vpi_systf_data*systf)
/* /*
* $Log: vpi_priv.c,v $ * $Log: vpi_priv.c,v $
* Revision 1.7 2000/05/07 18:20:08 steve
* Import MCD support from Stephen Tell, and add
* system function parameter support to the IVL core.
*
* Revision 1.6 2000/05/04 03:37:59 steve * Revision 1.6 2000/05/04 03:37:59 steve
* Add infrastructure for system functions, move * Add infrastructure for system functions, move
* $time to that structure and add $random. * $time to that structure and add $random.

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.17 2000/05/07 04:37:56 steve Exp $" #ident "$Id: vpi_priv.h,v 1.18 2000/05/07 18:20:08 steve Exp $"
#endif #endif
/* /*
@ -305,7 +305,8 @@ extern void vpip_calltask(const char*name, unsigned nparms, vpiHandle*parms);
* This calls a system function with a given name. The return value is * This calls a system function with a given name. The return value is
* taken by the res[] array. * taken by the res[] array.
*/ */
extern void vpip_callfunc(const char*name, vpip_bit_t*res, unsigned nres); extern void vpip_callfunc(const char*name, unsigned nres, vpip_bit_t*res,
unsigned nparms, vpiHandle*parms);
extern void vpip_run_value_changes(struct __vpiSignal*sig); extern void vpip_run_value_changes(struct __vpiSignal*sig);
@ -366,6 +367,10 @@ extern int vpip_finished();
/* /*
* $Log: vpi_priv.h,v $ * $Log: vpi_priv.h,v $
* Revision 1.18 2000/05/07 18:20:08 steve
* Import MCD support from Stephen Tell, and add
* system function parameter support to the IVL core.
*
* Revision 1.17 2000/05/07 04:37:56 steve * Revision 1.17 2000/05/07 04:37:56 steve
* Carry strength values from Verilog source to the * Carry strength values from Verilog source to the
* pform and netlist for gates. * pform and netlist for gates.

View File

@ -17,17 +17,22 @@
* 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_systask.c,v 1.4 2000/05/04 03:37:59 steve Exp $" #ident "$Id: vpi_systask.c,v 1.5 2000/05/07 18:20:08 steve Exp $"
#endif #endif
# include "vpi_priv.h" # include "vpi_priv.h"
# include <stdlib.h> # include <stdlib.h>
# include <assert.h> # include <assert.h>
/*
* the iter function only supports getting an iterator of the
* arguments. This works equally well for tasks and functions.
*/
static vpiHandle systask_iter(int type, vpiHandle ref) static vpiHandle systask_iter(int type, vpiHandle ref)
{ {
struct __vpiSysTaskCall*rfp = (struct __vpiSysTaskCall*)ref; struct __vpiSysTaskCall*rfp = (struct __vpiSysTaskCall*)ref;
assert(ref->vpi_type->type_code == vpiSysTaskCall); assert((ref->vpi_type->type_code == vpiSysTaskCall)
|| (ref->vpi_type->type_code == vpiSysFuncCall));
if (rfp->nargs == 0) if (rfp->nargs == 0)
return 0; return 0;
@ -88,6 +93,10 @@ const struct __vpirt vpip_sysfunc_rt = {
/* /*
* $Log: vpi_systask.c,v $ * $Log: vpi_systask.c,v $
* Revision 1.5 2000/05/07 18:20:08 steve
* Import MCD support from Stephen Tell, and add
* system function parameter support to the IVL core.
*
* Revision 1.4 2000/05/04 03:37:59 steve * Revision 1.4 2000/05/04 03:37:59 steve
* Add infrastructure for system functions, move * Add infrastructure for system functions, move
* $time to that structure and add $random. * $time to that structure and add $random.