Add support for system functions in continuous assignments.

This commit is contained in:
steve 2006-06-18 04:15:50 +00:00
parent 71faebd6df
commit 80f30be9d0
27 changed files with 918 additions and 156 deletions

12
PExpr.h
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
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: PExpr.h,v 1.82 2006/06/02 04:48:49 steve Exp $" #ident "$Id: PExpr.h,v 1.83 2006/06/18 04:15:50 steve Exp $"
#endif #endif
# include <string> # include <string>
@ -556,10 +556,20 @@ class PECallFunction : public PExpr {
bool check_call_matches_definition_(Design*des, NetScope*dscope) const; bool check_call_matches_definition_(Design*des, NetScope*dscope) const;
NetExpr* elaborate_sfunc_(Design*des, NetScope*scope) const; NetExpr* elaborate_sfunc_(Design*des, NetScope*scope) const;
NetNet* elaborate_net_sfunc_(Design*des, NetScope*scope,
unsigned width,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const;
}; };
/* /*
* $Log: PExpr.h,v $ * $Log: PExpr.h,v $
* Revision 1.83 2006/06/18 04:15:50 steve
* Add support for system functions in continuous assignments.
*
* Revision 1.82 2006/06/02 04:48:49 steve * Revision 1.82 2006/06/02 04:48:49 steve
* Make elaborate_expr methods aware of the width that the context * Make elaborate_expr methods aware of the width that the context
* requires of it. In the process, fix sizing of the width of unary * requires of it. In the process, fix sizing of the width of unary

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
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: design_dump.cc,v 1.165 2006/04/10 00:37:42 steve Exp $" #ident "$Id: design_dump.cc,v 1.166 2006/06/18 04:15:50 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -29,7 +29,7 @@
# include <iostream> # include <iostream>
# include <iomanip> # include <iomanip>
# include "netlist.h" # include "netlist.h"
# include "compiler.h"
static ostream& operator<< (ostream&o, NetBlock::Type t) static ostream& operator<< (ostream&o, NetBlock::Type t)
{ {
@ -462,6 +462,13 @@ void NetUReduce::dump_node(ostream&o, unsigned ind) const
dump_obj_attr(o, ind+4); dump_obj_attr(o, ind+4);
} }
void NetSysFunc::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << def_->name << "(...)" << endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
}
void NetUserFunc::dump_node(ostream&o, unsigned ind) const void NetUserFunc::dump_node(ostream&o, unsigned ind) const
{ {
o << setw(ind) << "" << def_->name() << "("; o << setw(ind) << "" << def_->name() << "(";
@ -1173,6 +1180,9 @@ void Design::dump(ostream&o) const
/* /*
* $Log: design_dump.cc,v $ * $Log: design_dump.cc,v $
* Revision 1.166 2006/06/18 04:15:50 steve
* Add support for system functions in continuous assignments.
*
* Revision 1.165 2006/04/10 00:37:42 steve * Revision 1.165 2006/04/10 00:37:42 steve
* Add support for generate loops w/ wires and gates. * Add support for generate loops w/ wires and 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
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: elab_net.cc,v 1.186 2006/06/02 04:48:50 steve Exp $" #ident "$Id: elab_net.cc,v 1.187 2006/06/18 04:15:50 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -1209,39 +1209,11 @@ NetNet* PECallFunction::elaborate_net(Design*des, NetScope*scope,
unsigned errors = 0; unsigned errors = 0;
unsigned func_pins = 0; unsigned func_pins = 0;
/* Handle the special case that the function call is to if (path_.peek_name(0)[0] == '$')
$signed. This takes a single expression argument, and return elaborate_net_sfunc_(des, scope,
forces it to be a signed result. Otherwise, it is as if the width, rise, fall, decay,
$signed did not exist. */ drive0, drive1);
if (strcmp(path_.peek_name(0), "$signed") == 0) {
if ((parms_.count() != 1) || (parms_[0] == 0)) {
cerr << get_line() << ": error: The $signed() function "
<< "takes exactly one(1) argument." << endl;
des->errors += 1;
return 0;
}
PExpr*expr = parms_[0];
NetNet*sub = expr->elaborate_net(des, scope, width, rise,
fall, decay, drive0, drive1);
sub->set_signed(true);
return sub;
}
/* handle $unsigned like $signed */
if (strcmp(path_.peek_name(0), "$unsigned") == 0) {
if ((parms_.count() != 1) || (parms_[0] == 0)) {
cerr << get_line() << ": error: The $unsigned() function "
<< "takes exactly one(1) argument." << endl;
des->errors += 1;
return 0;
}
PExpr*expr = parms_[0];
NetNet*sub = expr->elaborate_net(des, scope, width, rise,
fall, decay, drive0, drive1);
sub->set_signed(false);
return sub;
}
/* Look up the function definition. */ /* Look up the function definition. */
NetFuncDef*def = des->find_function(scope, path_); NetFuncDef*def = des->find_function(scope, path_);
@ -1319,6 +1291,87 @@ NetNet* PECallFunction::elaborate_net(Design*des, NetScope*scope,
return osig; return osig;
} }
NetNet* PECallFunction::elaborate_net_sfunc_(Design*des, NetScope*scope,
unsigned width,
const NetExpr* rise,
const NetExpr* fall,
const NetExpr* decay,
Link::strength_t drive0,
Link::strength_t drive1) const
{
/* Handle the special case that the function call is to
$signed. This takes a single expression argument, and
forces it to be a signed result. Otherwise, it is as if the
$signed did not exist. */
if (strcmp(path_.peek_name(0), "$signed") == 0) {
if ((parms_.count() != 1) || (parms_[0] == 0)) {
cerr << get_line() << ": error: The $signed() function "
<< "takes exactly one(1) argument." << endl;
des->errors += 1;
return 0;
}
PExpr*expr = parms_[0];
NetNet*sub = expr->elaborate_net(des, scope, width, rise,
fall, decay, drive0, drive1);
sub->set_signed(true);
return sub;
}
/* handle $unsigned like $signed */
if (strcmp(path_.peek_name(0), "$unsigned") == 0) {
if ((parms_.count() != 1) || (parms_[0] == 0)) {
cerr << get_line() << ": error: The $unsigned() function "
<< "takes exactly one(1) argument." << endl;
des->errors += 1;
return 0;
}
PExpr*expr = parms_[0];
NetNet*sub = expr->elaborate_net(des, scope, width, rise,
fall, decay, drive0, drive1);
sub->set_signed(false);
return sub;
}
const struct sfunc_return_type*def = lookup_sys_func(path_.peek_name(0));
if (def == 0) {
cerr << get_line() << ": error: System function "
<< path_.peek_name(0) << " not defined." << endl;
des->errors += 1;
return 0;
}
NetSysFunc*net = new NetSysFunc(scope, scope->local_symbol(),
def, 1+parms_.count());
des->add_node(net);
net->set_line(*this);
NetNet*osig = new NetNet(scope, scope->local_symbol(),
NetNet::WIRE, def->wid);
osig->local_flag(true);
osig->data_type(def->type);
osig->set_line(*this);
connect(net->pin(0), osig->pin(0));
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
NetNet*tmp = parms_[idx]->elaborate_net(des, scope, 0,
0, 0, 0,
Link::STRONG, Link::STRONG);
if (tmp == 0) {
cerr << get_line() << ": error: Unable to elaborate "
<< "port " << idx << " of call to " << path_ <<
"." << endl;
continue;
}
connect(net->pin(1+idx), tmp->pin(0));
}
return osig;
}
/* /*
* The concatenation operator, as a net, is a wide signal that is * The concatenation operator, as a net, is a wide signal that is
@ -2779,6 +2832,9 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope,
/* /*
* $Log: elab_net.cc,v $ * $Log: elab_net.cc,v $
* Revision 1.187 2006/06/18 04:15:50 steve
* Add support for system functions in continuous assignments.
*
* Revision 1.186 2006/06/02 04:48:50 steve * Revision 1.186 2006/06/02 04:48:50 steve
* Make elaborate_expr methods aware of the width that the context * Make elaborate_expr methods aware of the width that the context
* requires of it. In the process, fix sizing of the width of unary * requires of it. In the process, fix sizing of the width of unary

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
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: emit.cc,v 1.86 2005/07/11 16:56:50 steve Exp $" #ident "$Id: emit.cc,v 1.87 2006/06/18 04:15:50 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -146,6 +146,10 @@ bool NetUReduce::emit_node(struct target_t*tgt) const
return tgt->ureduce(this); return tgt->ureduce(this);
} }
bool NetSysFunc::emit_node(struct target_t*tgt) const
{
return tgt->net_sysfunction(this);
}
bool NetUserFunc::emit_node(struct target_t*tgt) const bool NetUserFunc::emit_node(struct target_t*tgt) const
{ {
@ -525,6 +529,9 @@ int emit(const Design*des, const char*type)
/* /*
* $Log: emit.cc,v $ * $Log: emit.cc,v $
* Revision 1.87 2006/06/18 04:15:50 steve
* Add support for system functions in continuous assignments.
*
* Revision 1.86 2005/07/11 16:56:50 steve * Revision 1.86 2005/07/11 16:56:50 steve
* Remove NetVariable and ivl_variable_t structures. * Remove NetVariable and ivl_variable_t structures.
* *

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
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: ivl_target.h,v 1.167 2006/04/16 00:15:43 steve Exp $" #ident "$Id: ivl_target.h,v 1.168 2006/06/18 04:15:50 steve Exp $"
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
@ -244,6 +244,7 @@ typedef enum ivl_lpm_type_e {
IVL_LPM_RE_XNOR= 24, IVL_LPM_RE_XNOR= 24,
IVL_LPM_RE_XOR = 25, IVL_LPM_RE_XOR = 25,
IVL_LPM_REPEAT = 26, IVL_LPM_REPEAT = 26,
IVL_LPM_SFUNC = 29,
IVL_LPM_SHIFTL = 6, IVL_LPM_SHIFTL = 6,
IVL_LPM_SHIFTR = 7, IVL_LPM_SHIFTR = 7,
IVL_LPM_SIGN_EXT=27, IVL_LPM_SIGN_EXT=27,
@ -991,6 +992,19 @@ extern const char* ivl_udp_name(ivl_udp_t net);
* the shift distance. The vector input is the same width as the * the shift distance. The vector input is the same width as the
* output, but the distance has its own width. * output, but the distance has its own width.
* *
* - System function call (IVL_LPM_SFUNC)
* This device represents a netlist call to a system function. The
* inputs to the device are passed to a system function, and the
* result is sent via the output. The ivl_lpm_q function returns the
* output nexus.
*
* The ivl_lpm_size function returns the number of arguments, and the
* ivl_lpm_data(net,N) returns the nexa for the argument.
*
* The ivl_lpm_string(net) function returns the name of the system
* function (i.e. "$display") that was found in the source code. The
* compiler does little checking of that name.
*
* - User Function Call (IVL_LPM_UFUNC) * - User Function Call (IVL_LPM_UFUNC)
* This device is special as it represents a call to a user defined * This device is special as it represents a call to a user defined
* function (behavioral code) within a netlist. The inputs to the * function (behavioral code) within a netlist. The inputs to the
@ -1039,14 +1053,6 @@ extern ivl_nexus_t ivl_lpm_enable(ivl_lpm_t net);
extern ivl_nexus_t ivl_lpm_data(ivl_lpm_t net, unsigned idx); extern ivl_nexus_t ivl_lpm_data(ivl_lpm_t net, unsigned idx);
/* IVL_LPM_ADD IVL_LPM_MULT IVL_LPM_SUB */ /* IVL_LPM_ADD IVL_LPM_MULT IVL_LPM_SUB */
extern ivl_nexus_t ivl_lpm_datab(ivl_lpm_t net, unsigned idx); extern ivl_nexus_t ivl_lpm_datab(ivl_lpm_t net, unsigned idx);
#if 0
/* IVL_LPM_UFUNC */
extern ivl_nexus_t ivl_lpm_data2(ivl_lpm_t net, unsigned sdx, unsigned idx);
#endif
#if 0
/* IVL_LPM_UFUNC */
extern unsigned ivl_lpm_data2_width(ivl_lpm_t net, unsigned sdx);
#endif
/* IVL_LPM_ADD IVL_LPM_FF IVL_LPM_MULT IVL_LPM_PART IVL_LPM_RAM /* IVL_LPM_ADD IVL_LPM_FF IVL_LPM_MULT IVL_LPM_PART IVL_LPM_RAM
IVL_LPM_SUB IVL_LPM_UFUNC */ IVL_LPM_SUB IVL_LPM_UFUNC */
extern ivl_nexus_t ivl_lpm_q(ivl_lpm_t net, unsigned idx); extern ivl_nexus_t ivl_lpm_q(ivl_lpm_t net, unsigned idx);
@ -1056,6 +1062,8 @@ extern unsigned ivl_lpm_selects(ivl_lpm_t net);
extern ivl_nexus_t ivl_lpm_select(ivl_lpm_t net); extern ivl_nexus_t ivl_lpm_select(ivl_lpm_t net);
/* IVL_LPM_CONCAT IVL_LPM_MUX IVL_LPM_REPEAT IVL_LPM_UFUNC */ /* IVL_LPM_CONCAT IVL_LPM_MUX IVL_LPM_REPEAT IVL_LPM_UFUNC */
extern unsigned ivl_lpm_size(ivl_lpm_t net); extern unsigned ivl_lpm_size(ivl_lpm_t net);
/* IVL_LPM_SFUNC */
extern const char*ivl_lpm_string(ivl_lpm_t net);
/* IVL_LPM_RAM */ /* IVL_LPM_RAM */
extern ivl_memory_t ivl_lpm_memory(ivl_lpm_t net); extern ivl_memory_t ivl_lpm_memory(ivl_lpm_t net);
@ -1706,6 +1714,9 @@ _END_DECL
/* /*
* $Log: ivl_target.h,v $ * $Log: ivl_target.h,v $
* Revision 1.168 2006/06/18 04:15:50 steve
* Add support for system functions in continuous assignments.
*
* Revision 1.167 2006/04/16 00:15:43 steve * Revision 1.167 2006/04/16 00:15:43 steve
* Fix part selects in l-values. * Fix part selects in l-values.
* *

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
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: net_func.cc,v 1.7 2005/03/18 02:56:03 steve Exp $" #ident "$Id: net_func.cc,v 1.8 2006/06/18 04:15:50 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -112,8 +112,46 @@ bool PECallFunction::check_call_matches_definition_(Design*des, NetScope*dscope)
return true; return true;
} }
NetSysFunc::NetSysFunc(NetScope*s, perm_string n,
const struct sfunc_return_type*def,
unsigned ports)
: NetNode(s, n, ports)
{
def_ = def;
pin(0).set_dir(Link::OUTPUT);
pin(0).set_name(perm_string::literal("Q"), 0);
for (unsigned idx = 1 ; idx < pin_count() ; idx += 1) {
pin(idx).set_dir(Link::INPUT);
pin(idx).set_name(perm_string::literal("D"), idx-1);
pin(idx).drive0(Link::HIGHZ);
pin(idx).drive1(Link::HIGHZ);
}
}
NetSysFunc::~NetSysFunc()
{
}
const char*NetSysFunc::func_name() const
{
return def_->name;
}
unsigned NetSysFunc::vector_width() const
{
return def_->wid;
}
/* /*
* $Log: net_func.cc,v $ * $Log: net_func.cc,v $
* Revision 1.8 2006/06/18 04:15:50 steve
* Add support for system functions in continuous assignments.
*
* Revision 1.7 2005/03/18 02:56:03 steve * Revision 1.7 2005/03/18 02:56:03 steve
* Add support for LPM_UFUNC user defined functions. * Add support for LPM_UFUNC user defined functions.
* *

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
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: netlist.h,v 1.357 2006/04/10 00:37:42 steve Exp $" #ident "$Id: netlist.h,v 1.358 2006/06/18 04:15:50 steve Exp $"
#endif #endif
/* /*
@ -1020,6 +1020,28 @@ class NetUserFunc : public NetNode {
NetScope*def_; NetScope*def_;
}; };
/*
* The number of ports includes the return value, so will always be at
* least 1.
*/
class NetSysFunc : public NetNode {
public:
NetSysFunc(NetScope*s, perm_string n,
const struct sfunc_return_type*def,
unsigned ports);
~NetSysFunc();
unsigned vector_width() const;
const char* func_name() const;
virtual void dump_node(ostream&, unsigned ind) const;
virtual bool emit_node(struct target_t*) const;
private:
const struct sfunc_return_type*def_;
};
/* ========= /* =========
* There are cases where expressions need to be represented. The * There are cases where expressions need to be represented. The
* NetExpr class is the root of a hierarchy that serves that purpose. * NetExpr class is the root of a hierarchy that serves that purpose.
@ -3464,6 +3486,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
/* /*
* $Log: netlist.h,v $ * $Log: netlist.h,v $
* Revision 1.358 2006/06/18 04:15:50 steve
* Add support for system functions in continuous assignments.
*
* Revision 1.357 2006/04/10 00:37:42 steve * Revision 1.357 2006/04/10 00:37:42 steve
* Add support for generate loops w/ wires and gates. * Add support for generate loops w/ wires and 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
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: t-dll-api.cc,v 1.133 2006/02/02 02:43:59 steve Exp $" #ident "$Id: t-dll-api.cc,v 1.134 2006/06/18 04:15:50 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -852,6 +852,11 @@ extern "C" ivl_nexus_t ivl_lpm_data(ivl_lpm_t net, unsigned idx)
assert(idx == 0); assert(idx == 0);
return net->u_.repeat.a; return net->u_.repeat.a;
case IVL_LPM_SFUNC:
// Skip the return port.
assert(idx < (net->u_.sfunc.ports-1));
return net->u_.sfunc.pins[idx+1];
case IVL_LPM_UFUNC: case IVL_LPM_UFUNC:
// Skip the return port. // Skip the return port.
assert(idx < (net->u_.ufunc.ports-1)); assert(idx < (net->u_.ufunc.ports-1));
@ -1005,6 +1010,10 @@ extern "C" ivl_nexus_t ivl_lpm_q(ivl_lpm_t net, unsigned idx)
assert(idx == 0); assert(idx == 0);
return net->u_.shift.q; return net->u_.shift.q;
case IVL_LPM_SFUNC:
assert(idx == 0);
return net->u_.sfunc.pins[0];
case IVL_LPM_UFUNC: case IVL_LPM_UFUNC:
assert(idx == 0); assert(idx == 0);
return net->u_.ufunc.pins[0]; return net->u_.ufunc.pins[0];
@ -1096,6 +1105,8 @@ extern "C" int ivl_lpm_signed(ivl_lpm_t net)
return net->u_.shift.signed_flag; return net->u_.shift.signed_flag;
case IVL_LPM_SIGN_EXT: // Sign extend is always signed. case IVL_LPM_SIGN_EXT: // Sign extend is always signed.
return 1; return 1;
case IVL_LPM_SFUNC:
return 0;
case IVL_LPM_UFUNC: case IVL_LPM_UFUNC:
return 0; return 0;
case IVL_LPM_CONCAT: // Concatenations are always unsigned case IVL_LPM_CONCAT: // Concatenations are always unsigned
@ -1117,6 +1128,8 @@ extern "C" unsigned ivl_lpm_size(ivl_lpm_t net)
switch (net->type) { switch (net->type) {
case IVL_LPM_MUX: case IVL_LPM_MUX:
return net->u_.mux.size; return net->u_.mux.size;
case IVL_LPM_SFUNC:
return net->u_.sfunc.ports - 1;
case IVL_LPM_UFUNC: case IVL_LPM_UFUNC:
return net->u_.ufunc.ports - 1; return net->u_.ufunc.ports - 1;
case IVL_LPM_REPEAT: case IVL_LPM_REPEAT:
@ -1127,6 +1140,12 @@ extern "C" unsigned ivl_lpm_size(ivl_lpm_t net)
} }
} }
extern "C" const char* ivl_lpm_string(ivl_lpm_t net)
{
assert(net->type == IVL_LPM_SFUNC);
return net->u_.sfunc.fun_name;
}
extern "C" ivl_lpm_type_t ivl_lpm_type(ivl_lpm_t net) extern "C" ivl_lpm_type_t ivl_lpm_type(ivl_lpm_t net)
{ {
return net->type; return net->type;
@ -1135,50 +1154,7 @@ extern "C" ivl_lpm_type_t ivl_lpm_type(ivl_lpm_t net)
extern "C" unsigned ivl_lpm_width(ivl_lpm_t net) extern "C" unsigned ivl_lpm_width(ivl_lpm_t net)
{ {
assert(net); assert(net);
switch (net->type) { return net->width;
case IVL_LPM_FF:
case IVL_LPM_RAM:
return net->u_.ff.width;
case IVL_LPM_MUX:
return net->u_.mux.width;
case IVL_LPM_ADD:
case IVL_LPM_CMP_EEQ:
case IVL_LPM_CMP_EQ:
case IVL_LPM_CMP_GE:
case IVL_LPM_CMP_GT:
case IVL_LPM_CMP_NE:
case IVL_LPM_CMP_NEE:
case IVL_LPM_DIVIDE:
case IVL_LPM_MOD:
case IVL_LPM_MULT:
case IVL_LPM_SUB:
return net->u_.arith.width;
case IVL_LPM_RE_AND:
case IVL_LPM_RE_OR:
case IVL_LPM_RE_XOR:
case IVL_LPM_RE_NAND:
case IVL_LPM_RE_NOR:
case IVL_LPM_RE_XNOR:
case IVL_LPM_SIGN_EXT:
return net->u_.reduce.width;
case IVL_LPM_SHIFTL:
case IVL_LPM_SHIFTR:
return net->u_.shift.width;
case IVL_LPM_UFUNC:
return net->u_.ufunc.width;
case IVL_LPM_CONCAT:
return net->u_.concat.width;
case IVL_LPM_PART_VP:
case IVL_LPM_PART_PV:
return net->u_.part.width;
case IVL_LPM_PART_BI:
return net->u_.part.width;
case IVL_LPM_REPEAT:
return net->u_.repeat.width;
default:
assert(0);
return 0;
}
} }
extern "C" ivl_memory_t ivl_lpm_memory(ivl_lpm_t net) extern "C" ivl_memory_t ivl_lpm_memory(ivl_lpm_t net)
@ -2033,6 +2009,9 @@ extern "C" ivl_statement_t ivl_stmt_sub_stmt(ivl_statement_t net)
/* /*
* $Log: t-dll-api.cc,v $ * $Log: t-dll-api.cc,v $
* Revision 1.134 2006/06/18 04:15:50 steve
* Add support for system functions in continuous assignments.
*
* Revision 1.133 2006/02/02 02:43:59 steve * Revision 1.133 2006/02/02 02:43:59 steve
* Allow part selects of memory words in l-values. * Allow part selects of memory words in l-values.
* *

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
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: t-dll.cc,v 1.156 2006/04/10 00:37:42 steve Exp $" #ident "$Id: t-dll.cc,v 1.157 2006/06/18 04:15:50 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -904,7 +904,7 @@ bool dll_target::sign_extend(const NetSignExtend*net)
{ {
struct ivl_lpm_s*obj = new struct ivl_lpm_s; struct ivl_lpm_s*obj = new struct ivl_lpm_s;
obj->type = IVL_LPM_SIGN_EXT; obj->type = IVL_LPM_SIGN_EXT;
obj->u_.reduce.width = net->width(); obj->width = net->width();
obj->name = net->name(); obj->name = net->name();
obj->scope = find_scope(des_, net->scope()); obj->scope = find_scope(des_, net->scope());
assert(obj->scope); assert(obj->scope);
@ -959,7 +959,7 @@ bool dll_target::ureduce(const NetUReduce*net)
obj->scope = find_scope(des_, net->scope()); obj->scope = find_scope(des_, net->scope());
assert(obj->scope); assert(obj->scope);
obj->u_.reduce.width = net->width(); obj->width = net->width();
const Nexus*nex; const Nexus*nex;
@ -988,7 +988,7 @@ void dll_target::net_case_cmp(const NetCaseCmp*net)
obj->scope = find_scope(des_, net->scope()); obj->scope = find_scope(des_, net->scope());
assert(obj->scope); assert(obj->scope);
obj->u_.arith.width = net->width(); obj->width = net->width();
obj->u_.arith.signed_flag = 0; obj->u_.arith.signed_flag = 0;
const Nexus*nex; const Nexus*nex;
@ -1014,6 +1014,46 @@ void dll_target::net_case_cmp(const NetCaseCmp*net)
scope_add_lpm(obj->scope, obj); scope_add_lpm(obj->scope, obj);
} }
bool dll_target::net_sysfunction(const NetSysFunc*net)
{
unsigned idx;
const Nexus*nex;
struct ivl_lpm_s*obj = new struct ivl_lpm_s;
obj->type = IVL_LPM_SFUNC;
obj->name = net->name();
obj->scope = find_scope(des_, net->scope());
assert(obj->scope);
obj->u_.sfunc.ports = net->pin_count();
assert(net->pin_count() >= 1);
obj->width = net->vector_width();
obj->u_.sfunc.fun_name = net->func_name();
obj->u_.sfunc.pins = new ivl_nexus_t[net->pin_count()];
nex = net->pin(0).nexus();
assert(nex->t_cookie());
obj->u_.sfunc.pins[0] = (ivl_nexus_t) nex->t_cookie();
nexus_lpm_add(obj->u_.sfunc.pins[0], obj, 0,
IVL_DR_STRONG, IVL_DR_STRONG);
for (idx = 1 ; idx < net->pin_count() ; idx += 1) {
nex = net->pin(idx).nexus();
assert(nex->t_cookie());
obj->u_.sfunc.pins[idx] = (ivl_nexus_t) nex->t_cookie();
nexus_lpm_add(obj->u_.sfunc.pins[idx], obj, 0,
IVL_DR_HiZ, IVL_DR_HiZ);
}
scope_add_lpm(obj->scope, obj);
return true;
}
/* /*
* An IVL_LPM_UFUNC represents a node in a combinational expression * An IVL_LPM_UFUNC represents a node in a combinational expression
* that calls a user defined function. I create an LPM object that has * that calls a user defined function. I create an LPM object that has
@ -1039,7 +1079,7 @@ bool dll_target::net_function(const NetUserFunc*net)
obj->u_.ufunc.ports = net->pin_count(); obj->u_.ufunc.ports = net->pin_count();
assert(net->pin_count() >= 1); assert(net->pin_count() >= 1);
obj->u_.ufunc.width = net->port_width(0); obj->width = net->port_width(0);
/* Now collect all the pins and connect them to the nexa of /* Now collect all the pins and connect them to the nexa of
the net. The output pins have strong drive, and the the net. The output pins have strong drive, and the
@ -1177,9 +1217,9 @@ void dll_target::lpm_add_sub(const NetAddSub*net)
/* Choose the width of the adder. If the carry bit is /* Choose the width of the adder. If the carry bit is
connected, then widen the adder by one and plan on leaving connected, then widen the adder by one and plan on leaving
the fake inputs unconnected. */ the fake inputs unconnected. */
obj->u_.arith.width = net->width(); obj->width = net->width();
if (net->pin_Cout().is_linked()) { if (net->pin_Cout().is_linked()) {
obj->u_.arith.width += 1; obj->width += 1;
} }
@ -1235,7 +1275,7 @@ void dll_target::lpm_clshift(const NetCLShift*net)
else else
obj->u_.shift.signed_flag = 0; obj->u_.shift.signed_flag = 0;
obj->u_.shift.width = net->width(); obj->width = net->width();
obj->u_.shift.select = net->width_dist(); obj->u_.shift.select = net->width_dist();
const Nexus*nex; const Nexus*nex;
@ -1276,7 +1316,7 @@ void dll_target::lpm_compare(const NetCompare*net)
bool swap_operands = false; bool swap_operands = false;
obj->u_.arith.width = net->width(); obj->width = net->width();
obj->u_.arith.signed_flag = net->get_signed()? 1 : 0; obj->u_.arith.signed_flag = net->get_signed()? 1 : 0;
const Nexus*nex; const Nexus*nex;
@ -1377,7 +1417,7 @@ void dll_target::lpm_divide(const NetDivide*net)
unsigned wid = net->width_r(); unsigned wid = net->width_r();
obj->u_.arith.width = wid; obj->width = wid;
obj->u_.arith.signed_flag = net->get_signed()? 1 : 0; obj->u_.arith.signed_flag = net->get_signed()? 1 : 0;
const Nexus*nex; const Nexus*nex;
@ -1415,7 +1455,7 @@ void dll_target::lpm_modulo(const NetModulo*net)
unsigned wid = net->width_r(); unsigned wid = net->width_r();
obj->u_.arith.width = wid; obj->width = wid;
obj->u_.arith.signed_flag = 0; obj->u_.arith.signed_flag = 0;
const Nexus*nex; const Nexus*nex;
@ -1449,7 +1489,7 @@ void dll_target::lpm_ff(const NetFF*net)
obj->scope = find_scope(des_, net->scope()); obj->scope = find_scope(des_, net->scope());
assert(obj->scope); assert(obj->scope);
obj->u_.ff.width = net->width(); obj->width = net->width();
scope_add_lpm(obj->scope, obj); scope_add_lpm(obj->scope, obj);
@ -1548,7 +1588,7 @@ void dll_target::lpm_ram_dq(const NetRamDq*net)
obj->scope = find_scope(des_, net->mem()->scope()); obj->scope = find_scope(des_, net->mem()->scope());
assert(obj->scope); assert(obj->scope);
obj->u_.ff.width = net->width(); obj->width = net->width();
obj->u_.ff.swid = net->awidth(); obj->u_.ff.swid = net->awidth();
scope_add_lpm(obj->scope, obj); scope_add_lpm(obj->scope, obj);
@ -1619,7 +1659,7 @@ void dll_target::lpm_mult(const NetMult*net)
unsigned wid = net->width_r(); unsigned wid = net->width_r();
obj->u_.arith.width = wid; obj->width = wid;
const Nexus*nex; const Nexus*nex;
@ -1657,7 +1697,7 @@ void dll_target::lpm_mux(const NetMux*net)
obj->scope = find_scope(des_, net->scope()); obj->scope = find_scope(des_, net->scope());
assert(obj->scope); assert(obj->scope);
obj->u_.mux.width = net->width(); obj->width = net->width();
obj->u_.mux.size = net->size(); obj->u_.mux.size = net->size();
obj->u_.mux.swid = net->sel_width(); obj->u_.mux.swid = net->sel_width();
@ -1701,7 +1741,7 @@ bool dll_target::concat(const NetConcat*net)
obj->scope = find_scope(des_, net->scope()); obj->scope = find_scope(des_, net->scope());
assert(obj->scope); assert(obj->scope);
obj->u_.concat.width = net->width(); obj->width = net->width();
obj->u_.concat.inputs = net->pin_count() - 1; obj->u_.concat.inputs = net->pin_count() - 1;
obj->u_.concat.pins = new ivl_nexus_t[obj->u_.concat.inputs+1]; obj->u_.concat.pins = new ivl_nexus_t[obj->u_.concat.inputs+1];
@ -1743,7 +1783,7 @@ bool dll_target::part_select(const NetPartSelect*net)
obj->u_.part.signed_flag = 0; obj->u_.part.signed_flag = 0;
/* Choose the width of the part select. */ /* Choose the width of the part select. */
obj->u_.part.width = net->width(); obj->width = net->width();
obj->u_.part.base = net->base(); obj->u_.part.base = net->base();
obj->u_.part.s = 0; obj->u_.part.s = 0;
@ -1834,7 +1874,7 @@ bool dll_target::replicate(const NetReplicate*net)
obj->scope = find_scope(des_, net->scope()); obj->scope = find_scope(des_, net->scope());
assert(obj->scope); assert(obj->scope);
obj->u_.repeat.width = net->width(); obj->width = net->width();
obj->u_.repeat.count = net->repeat(); obj->u_.repeat.count = net->repeat();
ivl_drive_t dr = IVL_DR_STRONG; ivl_drive_t dr = IVL_DR_STRONG;
@ -2167,6 +2207,9 @@ extern const struct target tgt_dll = { "dll", &dll_target_obj };
/* /*
* $Log: t-dll.cc,v $ * $Log: t-dll.cc,v $
* Revision 1.157 2006/06/18 04:15:50 steve
* Add support for system functions in continuous assignments.
*
* Revision 1.156 2006/04/10 00:37:42 steve * Revision 1.156 2006/04/10 00:37:42 steve
* Add support for generate loops w/ wires and gates. * Add support for generate loops w/ wires and gates.
* *

23
t-dll.h
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
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: t-dll.h,v 1.130 2006/02/02 02:43:59 steve Exp $" #ident "$Id: t-dll.h,v 1.131 2006/06/18 04:15:50 steve Exp $"
#endif #endif
# include "target.h" # include "target.h"
@ -86,6 +86,7 @@ struct dll_target : public target_t, public expr_scan_t {
bool part_select(const NetPartSelect*); bool part_select(const NetPartSelect*);
bool replicate(const NetReplicate*); bool replicate(const NetReplicate*);
void net_assign(const NetAssign_*); void net_assign(const NetAssign_*);
bool net_sysfunction(const NetSysFunc*);
bool net_function(const NetUserFunc*); bool net_function(const NetUserFunc*);
bool net_const(const NetConst*); bool net_const(const NetConst*);
bool net_literal(const NetLiteral*); bool net_literal(const NetLiteral*);
@ -282,10 +283,11 @@ struct ivl_lpm_s {
ivl_lpm_type_t type; ivl_lpm_type_t type;
ivl_scope_t scope; ivl_scope_t scope;
perm_string name; perm_string name;
// Value returned by ivl_lpm_width;
unsigned width;
union { union {
struct ivl_lpm_ff_s { struct ivl_lpm_ff_s {
unsigned width;
unsigned swid; // ram only unsigned swid; // ram only
ivl_nexus_t clk; ivl_nexus_t clk;
ivl_nexus_t we; ivl_nexus_t we;
@ -311,7 +313,6 @@ struct ivl_lpm_s {
} ff; } ff;
struct ivl_lpm_mux_s { struct ivl_lpm_mux_s {
unsigned width;
unsigned size; unsigned size;
unsigned swid; unsigned swid;
ivl_nexus_t*d; ivl_nexus_t*d;
@ -319,26 +320,22 @@ struct ivl_lpm_s {
} mux; } mux;
struct ivl_lpm_shift_s { struct ivl_lpm_shift_s {
unsigned width;
unsigned select; unsigned select;
unsigned signed_flag :1; unsigned signed_flag :1;
ivl_nexus_t q, d, s; ivl_nexus_t q, d, s;
} shift; } shift;
struct ivl_lpm_arith_s { struct ivl_lpm_arith_s {
unsigned width;
unsigned signed_flag :1; unsigned signed_flag :1;
ivl_nexus_t q, a, b; ivl_nexus_t q, a, b;
} arith; } arith;
struct ivl_concat_s { struct ivl_concat_s {
unsigned width;
unsigned inputs; unsigned inputs;
ivl_nexus_t*pins; ivl_nexus_t*pins;
} concat; } concat;
struct ivl_part_s { struct ivl_part_s {
unsigned width;
unsigned base; unsigned base;
unsigned signed_flag :1; unsigned signed_flag :1;
ivl_nexus_t q, a, s; ivl_nexus_t q, a, s;
@ -346,20 +343,23 @@ struct ivl_lpm_s {
// IVL_LPM_RE_* and IVL_LPM_SIGN_EXT use this. // IVL_LPM_RE_* and IVL_LPM_SIGN_EXT use this.
struct ivl_lpm_reduce_s { struct ivl_lpm_reduce_s {
unsigned width;
ivl_nexus_t q, a; ivl_nexus_t q, a;
} reduce; } reduce;
struct ivl_lpm_repeat_s { struct ivl_lpm_repeat_s {
unsigned width;
unsigned count; unsigned count;
ivl_nexus_t q, a; ivl_nexus_t q, a;
} repeat; } repeat;
struct ivl_lpm_sfunc_s {
const char* fun_name;
unsigned ports;
ivl_nexus_t*pins;
} sfunc;
struct ivl_lpm_ufunc_s { struct ivl_lpm_ufunc_s {
ivl_scope_t def; ivl_scope_t def;
unsigned ports; unsigned ports;
unsigned width;
ivl_nexus_t*pins; ivl_nexus_t*pins;
} ufunc; } ufunc;
} u_; } u_;
@ -671,6 +671,9 @@ struct ivl_statement_s {
/* /*
* $Log: t-dll.h,v $ * $Log: t-dll.h,v $
* Revision 1.131 2006/06/18 04:15:50 steve
* Add support for system functions in continuous assignments.
*
* Revision 1.130 2006/02/02 02:43:59 steve * Revision 1.130 2006/02/02 02:43:59 steve
* Allow part selects of memory words in l-values. * Allow part selects of memory words in l-values.
* *

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
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: target.cc,v 1.77 2005/07/11 16:56:51 steve Exp $" #ident "$Id: target.cc,v 1.78 2006/06/18 04:15:50 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -174,6 +174,13 @@ bool target_t::net_const(const NetConst*)
return false; return false;
} }
bool target_t::net_sysfunction(const NetSysFunc*net)
{
cerr << "target (" << typeid(*this).name() << "): "
"Unhandled NetSysFunc node." << endl;
return false;
}
bool target_t::net_function(const NetUserFunc*net) bool target_t::net_function(const NetUserFunc*net)
{ {
cerr << "target (" << typeid(*this).name() << "): " cerr << "target (" << typeid(*this).name() << "): "
@ -431,6 +438,9 @@ void expr_scan_t::expr_binary(const NetEBinary*ex)
/* /*
* $Log: target.cc,v $ * $Log: target.cc,v $
* Revision 1.78 2006/06/18 04:15:50 steve
* Add support for system functions in continuous assignments.
*
* Revision 1.77 2005/07/11 16:56:51 steve * Revision 1.77 2005/07/11 16:56:51 steve
* Remove NetVariable and ivl_variable_t structures. * Remove NetVariable and ivl_variable_t structures.
* *

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
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: target.h,v 1.74 2005/07/11 16:56:51 steve Exp $" #ident "$Id: target.h,v 1.75 2006/06/18 04:15:50 steve Exp $"
#endif #endif
# include "netlist.h" # include "netlist.h"
@ -94,6 +94,7 @@ struct target_t {
virtual void udp(const NetUDP*); virtual void udp(const NetUDP*);
virtual void net_case_cmp(const NetCaseCmp*); virtual void net_case_cmp(const NetCaseCmp*);
virtual bool net_const(const NetConst*); virtual bool net_const(const NetConst*);
virtual bool net_sysfunction(const NetSysFunc*);
virtual bool net_function(const NetUserFunc*); virtual bool net_function(const NetUserFunc*);
virtual bool net_literal(const NetLiteral*); virtual bool net_literal(const NetLiteral*);
virtual void net_probe(const NetEvProbe*); virtual void net_probe(const NetEvProbe*);
@ -170,6 +171,9 @@ extern const struct target *target_table[];
/* /*
* $Log: target.h,v $ * $Log: target.h,v $
* Revision 1.75 2006/06/18 04:15:50 steve
* Add support for system functions in continuous assignments.
*
* Revision 1.74 2005/07/11 16:56:51 steve * Revision 1.74 2005/07/11 16:56:51 steve
* Remove NetVariable and ivl_variable_t structures. * Remove NetVariable and ivl_variable_t structures.
* *

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
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: stub.c,v 1.138 2006/04/30 05:16:53 steve Exp $" #ident "$Id: stub.c,v 1.139 2006/06/18 04:15:50 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -83,11 +83,29 @@ unsigned width_of_nexus(ivl_nexus_t nex)
return 0; return 0;
} }
const char*vt_type_string(ivl_expr_t net) ivl_variable_type_t type_of_nexus(ivl_nexus_t net)
{
unsigned idx;
for (idx = 0 ; idx < ivl_nexus_ptrs(net); idx += 1) {
ivl_nexus_ptr_t ptr = ivl_nexus_ptr(net, idx);
ivl_signal_t sig = ivl_nexus_ptr_sig(ptr);
if (sig != 0) {
return ivl_signal_data_type(sig);
}
}
/* ERROR: A nexus should have at least one signal to carry
properties like the data type. */
return IVL_VT_NO_TYPE;
}
const char*data_type_string(ivl_variable_type_t vtype)
{ {
const char*vt = "??"; const char*vt = "??";
switch (ivl_expr_value(net)) { switch (vtype) {
case IVL_VT_NO_TYPE: case IVL_VT_NO_TYPE:
vt = "NO_TYPE"; vt = "NO_TYPE";
break; break;
@ -108,6 +126,11 @@ const char*vt_type_string(ivl_expr_t net)
return vt; return vt;
} }
const char*vt_type_string(ivl_expr_t net)
{
return data_type_string(ivl_expr_value(net));
}
void show_binary_expression(ivl_expr_t net, unsigned ind) void show_binary_expression(ivl_expr_t net, unsigned ind)
{ {
unsigned width = ivl_expr_width(net); unsigned width = ivl_expr_width(net);
@ -894,6 +917,34 @@ static void show_lpm_sub(ivl_lpm_t net)
show_lpm_arithmetic_pins(net); show_lpm_arithmetic_pins(net);
} }
static void show_lpm_sfunc(ivl_lpm_t net)
{
unsigned width = ivl_lpm_width(net);
unsigned ports = ivl_lpm_size(net);
ivl_variable_type_t data_type = type_of_nexus(ivl_lpm_q(net,0));
ivl_nexus_t nex;
unsigned idx;
fprintf(out, " LPM_SFUNC %s: <call=%s, width=%u, type=%s, ports=%u>\n",
ivl_lpm_basename(net), ivl_lpm_string(net),
width, data_type_string(data_type), ports);
nex = ivl_lpm_q(net, 0);
if (width != width_of_nexus(nex)) {
fprintf(out, " ERROR: Q output nexus width=%u "
" does not match part width\n", width_of_nexus(nex));
stub_errors += 1;
}
fprintf(out, " Q: %s\n", ivl_nexus_name(nex));
for (idx = 0 ; idx < ports ; idx += 1) {
nex = ivl_lpm_data(net, idx);
fprintf(out, " D%u: %s <width=%u, type=%s>\n", idx,
ivl_nexus_name(nex), width_of_nexus(nex),
data_type_string(type_of_nexus(nex)));
}
}
static void show_lpm_ufunc(ivl_lpm_t net) static void show_lpm_ufunc(ivl_lpm_t net)
{ {
unsigned width = ivl_lpm_width(net); unsigned width = ivl_lpm_width(net);
@ -1014,6 +1065,10 @@ static void show_lpm(ivl_lpm_t net)
show_lpm_repeat(net); show_lpm_repeat(net);
break; break;
case IVL_LPM_SFUNC:
show_lpm_sfunc(net);
break;
case IVL_LPM_UFUNC: case IVL_LPM_UFUNC:
show_lpm_ufunc(net); show_lpm_ufunc(net);
break; break;
@ -1591,6 +1646,9 @@ int target_design(ivl_design_t des)
/* /*
* $Log: stub.c,v $ * $Log: stub.c,v $
* Revision 1.139 2006/06/18 04:15:50 steve
* Add support for system functions in continuous assignments.
*
* Revision 1.138 2006/04/30 05:16:53 steve * Revision 1.138 2006/04/30 05:16:53 steve
* Dump *all* the reduction operator gates. * Dump *all* the reduction operator 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
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: vvp_scope.c,v 1.144 2006/04/22 04:27:36 steve Exp $" #ident "$Id: vvp_scope.c,v 1.145 2006/06/18 04:15:50 steve Exp $"
#endif #endif
# include "vvp_priv.h" # include "vvp_priv.h"
@ -611,6 +611,7 @@ static const char* draw_net_input_drive(ivl_nexus_t nex, ivl_nexus_ptr_t nptr)
case IVL_LPM_RE_NAND: case IVL_LPM_RE_NAND:
case IVL_LPM_RE_NOR: case IVL_LPM_RE_NOR:
case IVL_LPM_RE_XNOR: case IVL_LPM_RE_XNOR:
case IVL_LPM_SFUNC:
case IVL_LPM_SHIFTL: case IVL_LPM_SHIFTL:
case IVL_LPM_SHIFTR: case IVL_LPM_SHIFTR:
case IVL_LPM_SIGN_EXT: case IVL_LPM_SIGN_EXT:
@ -1801,6 +1802,43 @@ static void draw_lpm_shiftl(ivl_lpm_t net)
fprintf(vvp_out, ";\n"); fprintf(vvp_out, ";\n");
} }
static void draw_type_string_of_nex(ivl_nexus_t nex)
{
switch (data_type_of_nexus(nex)) {
case IVL_VT_REAL:
fprintf(vvp_out, "r");
break;
case IVL_VT_LOGIC:
fprintf(vvp_out, "v%d", width_of_nexus(nex));
break;
default:
assert(0);
break;
}
}
static void draw_lpm_sfunc(ivl_lpm_t net)
{
unsigned idx;
fprintf(vvp_out, "L_%p .sfunc \"%s\"", net, ivl_lpm_string(net));
/* Print the function type descriptor string. */
fprintf(vvp_out, ", \"");
draw_type_string_of_nex(ivl_lpm_q(net,0));
for (idx = 0 ; idx < ivl_lpm_size(net) ; idx += 1)
draw_type_string_of_nex(ivl_lpm_data(net,idx));
fprintf(vvp_out, "\"");
for (idx = 0 ; idx < ivl_lpm_size(net) ; idx += 1) {
fprintf(vvp_out, ", %s", draw_net_input(ivl_lpm_data(net,idx)));
}
fprintf(vvp_out, ";\n");
}
static void draw_lpm_ufunc(ivl_lpm_t net) static void draw_lpm_ufunc(ivl_lpm_t net)
{ {
unsigned idx; unsigned idx;
@ -2078,6 +2116,10 @@ static void draw_lpm_in_scope(ivl_lpm_t net)
draw_lpm_sign_ext(net); draw_lpm_sign_ext(net);
return; return;
case IVL_LPM_SFUNC:
draw_lpm_sfunc(net);
return;
case IVL_LPM_UFUNC: case IVL_LPM_UFUNC:
draw_lpm_ufunc(net); draw_lpm_ufunc(net);
return; return;
@ -2209,6 +2251,9 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent)
/* /*
* $Log: vvp_scope.c,v $ * $Log: vvp_scope.c,v $
* Revision 1.145 2006/06/18 04:15:50 steve
* Add support for system functions in continuous assignments.
*
* Revision 1.144 2006/04/22 04:27:36 steve * Revision 1.144 2006/04/22 04:27:36 steve
* Get tail counts right in nested concatenations. * Get tail counts right in nested concatenations.
* *

View File

@ -16,7 +16,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.69 2005/06/12 01:42:20 steve Exp $" #ident "$Id: Makefile.in,v 1.70 2006/06/18 04:15:50 steve Exp $"
# #
# #
SHELL = /bin/sh SHELL = /bin/sh
@ -82,7 +82,7 @@ vpi_memory.o vpi_vthr_vector.o vpip_bin.o vpip_hex.o vpip_oct.o \
vpip_to_dec.o vpip_format.o vvp_vpi.o vpip_to_dec.o vpip_format.o vvp_vpi.o
O = main.o parse.o parse_misc.o lexor.o arith.o bufif.o compile.o concat.o \ O = main.o parse.o parse_misc.o lexor.o arith.o bufif.o compile.o concat.o \
dff.o extend.o npmos.o part.o reduce.o resolv.o stop.o symbols.o \ dff.o extend.o npmos.o part.o reduce.o resolv.o sfunc.o stop.o symbols.o \
ufunc.o codes.o \ ufunc.o codes.o \
vthread.o schedule.o statistics.o tables.o udp.o vvp_net.o memory.o \ vthread.o schedule.o statistics.o tables.o udp.o vvp_net.o memory.o \
event.o logic.o delay.o words.o $V event.o logic.o delay.o words.o $V

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
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: compile.cc,v 1.219 2006/03/18 22:51:10 steve Exp $" #ident "$Id: compile.cc,v 1.220 2006/06/18 04:15:50 steve Exp $"
#endif #endif
# include "arith.h" # include "arith.h"
@ -1417,7 +1417,7 @@ void compile_vpi_call(char*label, char*name, unsigned argc, vpiHandle*argv)
/* Create a vpiHandle that bundles the call information, and /* Create a vpiHandle that bundles the call information, and
store that handle in the instruction. */ store that handle in the instruction. */
code->handle = vpip_build_vpi_call(name, 0, 0, argc, argv); code->handle = vpip_build_vpi_call(name, 0, 0, 0, argc, argv);
if (code->handle == 0) if (code->handle == 0)
compile_errors += 1; compile_errors += 1;
@ -1438,7 +1438,7 @@ void compile_vpi_func_call(char*label, char*name,
/* Create a vpiHandle that bundles the call information, and /* Create a vpiHandle that bundles the call information, and
store that handle in the instruction. */ store that handle in the instruction. */
code->handle = vpip_build_vpi_call(name, vbit, vwid, argc, argv); code->handle = vpip_build_vpi_call(name, vbit, vwid, 0, argc, argv);
if (code->handle == 0) if (code->handle == 0)
compile_errors += 1; compile_errors += 1;
@ -1495,6 +1495,9 @@ void compile_param_string(char*label, char*name, char*value)
/* /*
* $Log: compile.cc,v $ * $Log: compile.cc,v $
* Revision 1.220 2006/06/18 04:15:50 steve
* Add support for system functions in continuous assignments.
*
* Revision 1.219 2006/03/18 22:51:10 steve * Revision 1.219 2006/03/18 22:51:10 steve
* Syntax for carrying sign with parameter. * Syntax for carrying sign with parameter.
* *

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
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: compile.h,v 1.80 2006/03/18 22:51:10 steve Exp $" #ident "$Id: compile.h,v 1.81 2006/06/18 04:15:50 steve Exp $"
#endif #endif
# include <stdio.h> # include <stdio.h>
@ -169,6 +169,8 @@ extern void compile_reduce_xnor(char*label, struct symb_s arg);
extern void compile_extend_signed(char*label, long width, struct symb_s arg); extern void compile_extend_signed(char*label, long width, struct symb_s arg);
extern void compile_sfunc(char*label, char*name, char*format_string,
unsigned argc, struct symb_s*argv);
extern void compile_repeat(char*label, long width, long repeat, extern void compile_repeat(char*label, long width, long repeat,
struct symb_s arg); struct symb_s arg);
@ -343,6 +345,9 @@ extern void compile_alias_real(char*label, char*name,
/* /*
* $Log: compile.h,v $ * $Log: compile.h,v $
* Revision 1.81 2006/06/18 04:15:50 steve
* Add support for system functions in continuous assignments.
*
* Revision 1.80 2006/03/18 22:51:10 steve * Revision 1.80 2006/03/18 22:51:10 steve
* Syntax for carrying sign with parameter. * Syntax for carrying sign with parameter.
* *

View File

@ -21,7 +21,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
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: lexor.lex,v 1.60 2006/05/17 04:15:25 steve Exp $" #ident "$Id: lexor.lex,v 1.61 2006/06/18 04:15:50 steve Exp $"
#endif #endif
# include "parse_misc.h" # include "parse_misc.h"
@ -130,6 +130,7 @@
".repeat" { return K_REPEAT; } ".repeat" { return K_REPEAT; }
".resolv" { return K_RESOLV; } ".resolv" { return K_RESOLV; }
".scope" { return K_SCOPE; } ".scope" { return K_SCOPE; }
".sfunc" { return K_SFUNC; }
".shift/l" { return K_SHIFTL; } ".shift/l" { return K_SHIFTL; }
".shift/r" { return K_SHIFTR; } ".shift/r" { return K_SHIFTR; }
".thread" { return K_THREAD; } ".thread" { return K_THREAD; }
@ -208,6 +209,9 @@ int yywrap()
/* /*
* $Log: lexor.lex,v $ * $Log: lexor.lex,v $
* Revision 1.61 2006/06/18 04:15:50 steve
* Add support for system functions in continuous assignments.
*
* Revision 1.60 2006/05/17 04:15:25 steve * Revision 1.60 2006/05/17 04:15:25 steve
* Lexor os never interactive. * Lexor os never interactive.
* *

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
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: parse.y,v 1.82 2006/03/18 22:51:10 steve Exp $" #ident "$Id: parse.y,v 1.83 2006/06/18 04:15:50 steve Exp $"
#endif #endif
# include "parse_misc.h" # include "parse_misc.h"
@ -67,7 +67,7 @@ extern FILE*yyin;
%token K_PARAM_STR K_PARAM_L K_PART K_PART_PV %token K_PARAM_STR K_PARAM_L K_PART K_PART_PV
%token K_PART_V K_REDUCE_AND K_REDUCE_OR K_REDUCE_XOR %token K_PART_V K_REDUCE_AND K_REDUCE_OR K_REDUCE_XOR
%token K_REDUCE_NAND K_REDUCE_NOR K_REDUCE_XNOR K_REPEAT %token K_REDUCE_NAND K_REDUCE_NOR K_REDUCE_XNOR K_REPEAT
%token K_RESOLV K_SCOPE K_SHIFTL K_SHIFTR K_THREAD K_TIMESCALE K_UFUNC %token K_RESOLV K_SCOPE K_SFUNC K_SHIFTL K_SHIFTR K_THREAD K_TIMESCALE K_UFUNC
%token K_UDP K_UDP_C K_UDP_S %token K_UDP K_UDP_C K_UDP_S
%token K_MEM K_MEM_P K_MEM_I %token K_MEM K_MEM_P K_MEM_I
%token K_VAR K_VAR_S K_VAR_I K_VAR_R K_vpi_call K_vpi_func K_vpi_func_r %token K_VAR K_VAR_S K_VAR_I K_VAR_R K_vpi_call K_vpi_func K_vpi_func_r
@ -329,6 +329,10 @@ statement
| T_LABEL K_EXTEND_S T_NUMBER ',' symbol ';' | T_LABEL K_EXTEND_S T_NUMBER ',' symbol ';'
{ compile_extend_signed($1, $3, $5); } { compile_extend_signed($1, $3, $5); }
/* System function call */
| T_LABEL K_SFUNC T_STRING ',' T_STRING ',' symbols ';'
{ compile_sfunc($1, $3, $5, $7.cnt, $7.vect); }
/* Shift nodes. */ /* Shift nodes. */
| T_LABEL K_SHIFTL T_NUMBER ',' symbols ';' | T_LABEL K_SHIFTL T_NUMBER ',' symbols ';'
@ -739,6 +743,9 @@ int compile_design(const char*path)
/* /*
* $Log: parse.y,v $ * $Log: parse.y,v $
* Revision 1.83 2006/06/18 04:15:50 steve
* Add support for system functions in continuous assignments.
*
* Revision 1.82 2006/03/18 22:51:10 steve * Revision 1.82 2006/03/18 22:51:10 steve
* Syntax for carrying sign with parameter. * Syntax for carrying sign with parameter.
* *

160
vvp/sfunc.cc Normal file
View File

@ -0,0 +1,160 @@
/*
* Copyright (c) 2006 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
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: sfunc.cc,v 1.1 2006/06/18 04:15:50 steve Exp $"
#endif
# include "compile.h"
# include "sfunc.h"
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
# include <stdlib.h>
# include <string.h>
# include <iostream>
# include <assert.h>
sfunc_core::sfunc_core(vvp_net_t*net, vpiHandle sys,
unsigned argc, vpiHandle*argv)
: vvp_wide_fun_core(net, argc)
{
sys_ = sys;
argc_ = argc;
argv_ = argv;
}
sfunc_core::~sfunc_core()
{
}
void sfunc_core::recv_vec4_from_inputs(unsigned port)
{
vpiHandle vpi = argv_[port];
assert(vpi_get(vpiConstType,vpi) == vpiBinaryConst);
struct __vpiBinaryConst*obj
= (struct __vpiBinaryConst*)vpi;
obj->bits = value(port);
invoke_function_();
}
void sfunc_core::recv_real_from_inputs(unsigned port)
{
vpiHandle vpi = argv_[port];
assert(vpi_get(vpiConstType,vpi) == vpiRealConst);
struct __vpiRealConst*obj
= (struct __vpiRealConst*)vpi;
obj->value = value_r(port);
invoke_function_();
}
void sfunc_core::invoke_function_()
{
vpip_execute_vpi_call(0, sys_);
}
static int make_vpi_argv(unsigned argc, vpiHandle*vpi_argv,
const char*arg_string)
{
unsigned idx = 0;
const char*cp = arg_string;
int return_type = 0;
switch (*cp) {
case 'r': // real result
cp += 1;
return_type = -vpiRealConst;
break;
case 'v': // vector4_t
cp += 1;
return_type = strtoul(cp, 0, 10);
cp += strspn(cp, "0123456789");
break;
default:
assert(0);
break;
}
while (*cp) {
assert(idx < argc);
switch (*cp) {
case 'r': // real
cp += 1;
vpi_argv[idx] = vpip_make_real_const(0.0);
break;
case 'v': { // vector4_t (v<n>)
cp += 1;
unsigned wid = strtoul(cp, 0, 10);
cp += strspn(cp, "0123456789");
vpi_argv[idx] = vpip_make_binary_const(wid, "x");
break;
}
default:
assert(0);
}
idx += 1;
}
assert(idx == argc);
return return_type;
}
void compile_sfunc(char*label, char*name, char*format_string,
unsigned argc, struct symb_s*argv)
{
vpiHandle*vpi_argv = new vpiHandle[argc];
int width_code = make_vpi_argv(argc, vpi_argv, format_string);
free(format_string);
vvp_net_t*ptr = new vvp_net_t;
vpiHandle sys = vpip_build_vpi_call(name, 0, width_code, ptr,
argc, vpi_argv);
assert(sys);
/* Create and connect the functor to the label. */
sfunc_core*score = new sfunc_core(ptr, sys, argc, vpi_argv);
ptr->fun = score;
define_functor_symbol(label, ptr);
free(label);
/* Link the inputs to the functor. */
wide_inputs_connect(score, argc, argv);
free(argv);
}
/*
* $Log: sfunc.cc,v $
* Revision 1.1 2006/06/18 04:15:50 steve
* Add support for system functions in continuous assignments.
*
*/

51
vvp/sfunc.h Normal file
View File

@ -0,0 +1,51 @@
#ifndef __sfunc_H
#define __sfunc_H
/*
* Copyright (c) 2006 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
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: sfunc.h,v 1.1 2006/06/18 04:15:50 steve Exp $"
#endif
# include "pointers.h"
class sfunc_core : public vvp_wide_fun_core {
public:
sfunc_core(vvp_net_t*ptr, vpiHandle sys, unsigned argc, vpiHandle*argv);
~sfunc_core();
private:
void recv_vec4_from_inputs(unsigned port);
void recv_real_from_inputs(unsigned port);
void invoke_function_();
private:
vpiHandle sys_;
unsigned argc_;
vpiHandle*argv_;
};
/*
* $Log: sfunc.h,v $
* Revision 1.1 2006/06/18 04:15:50 steve
* Add support for system functions in continuous assignments.
*
*/
#endif

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
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: stop.cc,v 1.15 2005/11/25 18:35:38 steve Exp $" #ident "$Id: stop.cc,v 1.16 2006/06/18 04:15:50 steve Exp $"
#endif #endif
/* /*
@ -174,7 +174,7 @@ static void cmd_call(unsigned argc, char*argv[])
vpi task and execute that call. Free the call structure vpi task and execute that call. Free the call structure
when we finish. */ when we finish. */
if (errors == 0) { if (errors == 0) {
vpiHandle call_handle = vpip_build_vpi_call(argv[0], 0, 0, vpiHandle call_handle = vpip_build_vpi_call(argv[0], 0, 0, 0,
vpi_argc, vpi_argv); vpi_argc, vpi_argv);
if (call_handle == 0) if (call_handle == 0)
goto out; goto out;
@ -505,6 +505,9 @@ void stop_handler(int rc)
/* /*
* $Log: stop.cc,v $ * $Log: stop.cc,v $
* Revision 1.16 2006/06/18 04:15:50 steve
* Add support for system functions in continuous assignments.
*
* Revision 1.15 2005/11/25 18:35:38 steve * Revision 1.15 2005/11/25 18:35:38 steve
* stop/continue messages go through MCD for logging. * stop/continue messages go through MCD for logging.
* *

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
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: vpi_const.cc,v 1.35 2006/03/18 22:51:10 steve Exp $" #ident "$Id: vpi_const.cc,v 1.36 2006/06/18 04:15:50 steve Exp $"
#endif #endif
# include "vpi_priv.h" # include "vpi_priv.h"
@ -529,8 +529,69 @@ vpiHandle vpip_make_dec_const(int value)
} }
static int real_get(int code, vpiHandle ref)
{
switch (code) {
case vpiConstType:
return vpiRealConst;
case vpiSigned:
return 1;
default:
fprintf(stderr, "vvp error: get %d not supported "
"by vpiDecConst\n", code);
assert(0);
return 0;
}
}
static void real_value(vpiHandle ref, p_vpi_value vp)
{
struct __vpiRealConst*rfp = (struct __vpiRealConst*)ref;
assert(ref->vpi_type->type_code == vpiConstant);
switch (vp->format) {
case vpiObjTypeVal:
vp->format = vpiRealVal;
case vpiRealVal:
vp->value.real = rfp->value;
break;
default:
assert(0);
}
}
static const struct __vpirt vpip_real_rt = {
vpiConstant,
real_get,
0,
real_value,
0,
0,
0
};
vpiHandle vpip_make_real_const(struct __vpiRealConst*obj, double value)
{
obj->base.vpi_type = &vpip_real_rt;
obj->value = value;
return &(obj->base);
}
vpiHandle vpip_make_real_const(double value)
{
struct __vpiRealConst*obj;
obj =(struct __vpiRealConst*) malloc(sizeof (struct __vpiRealConst));
return vpip_make_real_const(obj, value);
}
/* /*
* $Log: vpi_const.cc,v $ * $Log: vpi_const.cc,v $
* Revision 1.36 2006/06/18 04:15:50 steve
* Add support for system functions in continuous assignments.
*
* Revision 1.35 2006/03/18 22:51:10 steve * Revision 1.35 2006/03/18 22:51:10 steve
* Syntax for carrying sign with parameter. * Syntax for carrying sign with parameter.
* *

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
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: vpi_priv.h,v 1.70 2006/03/18 22:51:10 steve Exp $" #ident "$Id: vpi_priv.h,v 1.71 2006/06/18 04:15:50 steve Exp $"
#endif #endif
# include "vpi_user.h" # include "vpi_user.h"
@ -257,6 +257,9 @@ struct __vpiUserSystf {
s_vpi_systf_data info; s_vpi_systf_data info;
}; };
extern struct __vpiUserSystf* vpip_find_systf(const char*name);
struct __vpiSysTaskCall { struct __vpiSysTaskCall {
struct __vpiHandle base; struct __vpiHandle base;
struct __vpiScope* scope; struct __vpiScope* scope;
@ -268,6 +271,7 @@ struct __vpiSysTaskCall {
/* These represent where in the vthread to put the return value. */ /* These represent where in the vthread to put the return value. */
unsigned vbit; unsigned vbit;
signed vwid; signed vwid;
class vvp_net_t*fnet;
}; };
extern struct __vpiSysTaskCall*vpip_cur_task; extern struct __vpiSysTaskCall*vpip_cur_task;
@ -309,6 +313,13 @@ struct __vpiDecConst {
vpiHandle vpip_make_dec_const(int value); vpiHandle vpip_make_dec_const(int value);
vpiHandle vpip_make_dec_const(struct __vpiDecConst*obj, int value); vpiHandle vpip_make_dec_const(struct __vpiDecConst*obj, int value);
struct __vpiRealConst {
struct __vpiHandle base;
double value;
};
vpiHandle vpip_make_real_const(double value);
/* /*
* This one looks like a constant, but really is a vector in the current * This one looks like a constant, but really is a vector in the current
* thread. * thread.
@ -350,6 +361,7 @@ extern unsigned vpip_module_path_cnt;
*/ */
extern vpiHandle vpip_build_vpi_call(const char*name, extern vpiHandle vpip_build_vpi_call(const char*name,
unsigned vbit, int vwid, unsigned vbit, int vwid,
class vvp_net_t*fnet,
unsigned argc, unsigned argc,
vpiHandle*argv); vpiHandle*argv);
@ -432,6 +444,9 @@ extern char *need_result_buf(unsigned cnt, vpi_rbuf_t type);
/* /*
* $Log: vpi_priv.h,v $ * $Log: vpi_priv.h,v $
* Revision 1.71 2006/06/18 04:15:50 steve
* Add support for system functions in continuous assignments.
*
* Revision 1.70 2006/03/18 22:51:10 steve * Revision 1.70 2006/03/18 22:51:10 steve
* Syntax for carrying sign with parameter. * Syntax for carrying sign with parameter.
* *

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
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: vpi_tasks.cc,v 1.31 2005/09/20 18:34:02 steve Exp $" #ident "$Id: vpi_tasks.cc,v 1.32 2006/06/18 04:15:50 steve Exp $"
#endif #endif
/* /*
@ -266,6 +266,92 @@ static vpiHandle sysfunc_put_real_value(vpiHandle ref, p_vpi_value vp)
return 0; return 0;
} }
static vpiHandle sysfunc_put_4net_value(vpiHandle ref, p_vpi_value vp)
{
assert(ref->vpi_type->type_code == vpiSysFuncCall);
struct __vpiSysTaskCall*rfp = (struct __vpiSysTaskCall*)ref;
unsigned vwid = (unsigned) rfp->vwid;
vvp_vector4_t val (vwid);
switch (vp->format) {
case vpiIntVal: {
long tmp = vp->value.integer;
for (unsigned idx = 0 ; idx < vwid ; idx += 1) {
val.set_bit(idx, (tmp&1)? BIT4_1 : BIT4_0);
tmp >>= 1;
}
break;
}
case vpiVectorVal:
for (unsigned wdx = 0 ; wdx < vwid ; wdx += 32) {
unsigned word = wdx / 32;
unsigned long aval = vp->value.vector[word].aval;
unsigned long bval = vp->value.vector[word].bval;
for (unsigned idx = 0 ; (wdx+idx) < vwid ; idx += 1) {
int bit = (aval&1) | ((bval<<1)&2);
vvp_bit4_t bit4;
switch (bit) {
case 0:
bit4 = BIT4_0;
break;
case 1:
bit4 = BIT4_1;
break;
case 2:
bit4 = BIT4_Z;
break;
case 3:
bit4 = BIT4_X;
break;
default:
assert(0);
}
val.set_bit(wdx+idx, bit4);
aval >>= 1;
bval >>= 1;
}
}
break;
default:
fprintf(stderr, "XXXX format=%d, vwid=%u\n", vp->format, rfp->vwid);
assert(0);
}
vvp_send_vec4(rfp->fnet->out, val);
return 0;
}
static vpiHandle sysfunc_put_rnet_value(vpiHandle ref, p_vpi_value vp)
{
assert(ref->vpi_type->type_code == vpiSysFuncCall);
struct __vpiSysTaskCall*rfp = (struct __vpiSysTaskCall*)ref;
double val;
switch (vp->format) {
case vpiRealVal:
val = vp->value.real;
break;
default:
assert(0);
}
vvp_send_real(rfp->fnet->out, val);
return 0;
}
static const struct __vpirt vpip_sysfunc_rt = { static const struct __vpirt vpip_sysfunc_rt = {
vpiSysFuncCall, vpiSysFuncCall,
@ -287,6 +373,26 @@ static const struct __vpirt vpip_sysfunc_real_rt = {
systask_iter systask_iter
}; };
static const struct __vpirt vpip_sysfunc_4net_rt = {
vpiSysFuncCall,
0,
systask_get_str,
0,
sysfunc_put_4net_value,
systask_handle,
systask_iter
};
static const struct __vpirt vpip_sysfunc_rnet_rt = {
vpiSysFuncCall,
0,
systask_get_str,
0,
sysfunc_put_rnet_value,
systask_handle,
systask_iter
};
/* **** Manipulate the internal datastructures. **** */ /* **** Manipulate the internal datastructures. **** */
static struct __vpiUserSystf**def_table = 0; static struct __vpiUserSystf**def_table = 0;
@ -315,7 +421,7 @@ static struct __vpiUserSystf* allocate_def(void)
} }
static struct __vpiUserSystf* vpip_find_systf(const char*name) struct __vpiUserSystf* vpip_find_systf(const char*name)
{ {
for (unsigned idx = 0 ; idx < def_count ; idx += 1) for (unsigned idx = 0 ; idx < def_count ; idx += 1)
if (strcmp(def_table[idx]->info.tfname, name) == 0) if (strcmp(def_table[idx]->info.tfname, name) == 0)
@ -337,6 +443,7 @@ static struct __vpiUserSystf* vpip_find_systf(const char*name)
* vbit is also a non-zero value, the address in thread space of the result. * vbit is also a non-zero value, the address in thread space of the result.
*/ */
vpiHandle vpip_build_vpi_call(const char*name, unsigned vbit, int vwid, vpiHandle vpip_build_vpi_call(const char*name, unsigned vbit, int vwid,
class vvp_net_t*fnet,
unsigned argc, vpiHandle*argv) unsigned argc, vpiHandle*argv)
{ {
struct __vpiUserSystf*defn = vpip_find_systf(name); struct __vpiUserSystf*defn = vpip_find_systf(name);
@ -348,7 +455,7 @@ vpiHandle vpip_build_vpi_call(const char*name, unsigned vbit, int vwid,
switch (defn->info.type) { switch (defn->info.type) {
case vpiSysTask: case vpiSysTask:
if (vwid != 0) { if (vwid != 0 || fnet != 0) {
fprintf(stderr, "%s: This is a system Task, " fprintf(stderr, "%s: This is a system Task, "
"you cannot call it as a Function\n", name); "you cannot call it as a Function\n", name);
return 0; return 0;
@ -357,7 +464,7 @@ vpiHandle vpip_build_vpi_call(const char*name, unsigned vbit, int vwid,
break; break;
case vpiSysFunc: case vpiSysFunc:
if (vwid == 0) { if (vwid == 0 && fnet == 0) {
fprintf(stderr, "%s: This is a system Function, " fprintf(stderr, "%s: This is a system Function, "
"you cannot call it as a Task\n", name); "you cannot call it as a Task\n", name);
return 0; return 0;
@ -376,18 +483,20 @@ vpiHandle vpip_build_vpi_call(const char*name, unsigned vbit, int vwid,
break; break;
case vpiSysFunc: case vpiSysFunc:
if (vwid > 0) { if (fnet && vwid == -vpiRealConst) {
obj->base.vpi_type = &vpip_sysfunc_rt; obj->base.vpi_type = &vpip_sysfunc_rnet_rt;
} else switch (vwid) { } else if (fnet && vwid > 0) {
obj->base.vpi_type = &vpip_sysfunc_4net_rt;
case -vpiRealConst: } else if (vwid == -vpiRealConst) {
obj->base.vpi_type = &vpip_sysfunc_real_rt; obj->base.vpi_type = &vpip_sysfunc_real_rt;
break;
default: } else if (vwid > 0) {
assert(0);
obj->base.vpi_type = &vpip_sysfunc_rt; obj->base.vpi_type = &vpip_sysfunc_rt;
} else {
assert(0);
} }
break; break;
} }
@ -398,6 +507,7 @@ vpiHandle vpip_build_vpi_call(const char*name, unsigned vbit, int vwid,
obj->args = argv; obj->args = argv;
obj->vbit = vbit; obj->vbit = vbit;
obj->vwid = vwid; obj->vwid = vwid;
obj->fnet = fnet;
obj->userdata = 0; obj->userdata = 0;
/* If there is a compiletf function, call it here. */ /* If there is a compiletf function, call it here. */
@ -487,6 +597,9 @@ void* vpi_get_userdata(vpiHandle ref)
/* /*
* $Log: vpi_tasks.cc,v $ * $Log: vpi_tasks.cc,v $
* Revision 1.32 2006/06/18 04:15:50 steve
* Add support for system functions in continuous assignments.
*
* Revision 1.31 2005/09/20 18:34:02 steve * Revision 1.31 2005/09/20 18:34:02 steve
* Clean up compiler warnings. * Clean up compiler warnings.
* *

View File

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ident "$Id: vvp_net.cc,v 1.52 2006/03/15 19:15:34 steve Exp $" #ident "$Id: vvp_net.cc,v 1.53 2006/06/18 04:15:50 steve Exp $"
# include "config.h" # include "config.h"
# include "vvp_net.h" # include "vvp_net.h"
@ -1709,12 +1709,14 @@ vvp_wide_fun_core::vvp_wide_fun_core(vvp_net_t*net, unsigned nports)
{ {
ptr_ = net; ptr_ = net;
nports_ = nports; nports_ = nports;
port_values_ = new vvp_vector4_t [nports_]; port_values_ = 0;
port_rvalues_ = 0;
} }
vvp_wide_fun_core::~vvp_wide_fun_core() vvp_wide_fun_core::~vvp_wide_fun_core()
{ {
delete[]port_values_; if (port_values_) delete[]port_values_;
if (port_rvalues_) delete[]port_rvalues_;
} }
void vvp_wide_fun_core::propagate_vec4(const vvp_vector4_t&bit, void vvp_wide_fun_core::propagate_vec4(const vvp_vector4_t&bit,
@ -1735,17 +1737,39 @@ unsigned vvp_wide_fun_core::port_count() const
vvp_vector4_t& vvp_wide_fun_core::value(unsigned idx) vvp_vector4_t& vvp_wide_fun_core::value(unsigned idx)
{ {
assert(idx < nports_); assert(idx < nports_);
assert(port_values_);
return port_values_[idx]; return port_values_[idx];
} }
double vvp_wide_fun_core::value_r(unsigned idx)
{
assert(idx < nports_);
return port_rvalues_? port_rvalues_[idx] : 0.0;
}
void vvp_wide_fun_core::recv_real_from_inputs(unsigned p)
{
assert(0);
}
void vvp_wide_fun_core::dispatch_vec4_from_input_(unsigned port, void vvp_wide_fun_core::dispatch_vec4_from_input_(unsigned port,
vvp_vector4_t bit) vvp_vector4_t bit)
{ {
assert(port < nports_); assert(port < nports_);
if (port_values_ == 0) port_values_ = new vvp_vector4_t [nports_];
port_values_[port] = bit; port_values_[port] = bit;
recv_vec4_from_inputs(port); recv_vec4_from_inputs(port);
} }
void vvp_wide_fun_core::dispatch_real_from_input_(unsigned port,
double bit)
{
assert(port < nports_);
if (port_rvalues_ == 0) port_rvalues_ = new double[nports_];
port_rvalues_[port] = bit;
recv_real_from_inputs(port);
}
vvp_wide_fun_t::vvp_wide_fun_t(vvp_wide_fun_core*c, unsigned base) vvp_wide_fun_t::vvp_wide_fun_t(vvp_wide_fun_core*c, unsigned base)
: core_(c), port_base_(base) : core_(c), port_base_(base)
{ {
@ -1761,6 +1785,12 @@ void vvp_wide_fun_t::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit)
core_->dispatch_vec4_from_input_(pidx, bit); core_->dispatch_vec4_from_input_(pidx, bit);
} }
void vvp_wide_fun_t::recv_real(vvp_net_ptr_t port, double bit)
{
unsigned pidx = port_base_ + port.port();
core_->dispatch_real_from_input_(pidx, bit);
}
/* **** vvp_scalar_t methods **** */ /* **** vvp_scalar_t methods **** */
@ -2163,6 +2193,9 @@ vvp_bit4_t compare_gtge_signed(const vvp_vector4_t&a,
/* /*
* $Log: vvp_net.cc,v $ * $Log: vvp_net.cc,v $
* Revision 1.53 2006/06/18 04:15:50 steve
* Add support for system functions in continuous assignments.
*
* Revision 1.52 2006/03/15 19:15:34 steve * Revision 1.52 2006/03/15 19:15:34 steve
* const/non-const clash. * const/non-const clash.
* *

View File

@ -18,7 +18,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ident "$Id: vvp_net.h,v 1.50 2006/03/08 05:29:42 steve Exp $" #ident "$Id: vvp_net.h,v 1.51 2006/06/18 04:15:50 steve Exp $"
# include "config.h" # include "config.h"
# include <stddef.h> # include <stddef.h>
@ -918,15 +918,19 @@ class vvp_wide_fun_core : public vvp_net_fun_t {
protected: protected:
void propagate_vec4(const vvp_vector4_t&bit, vvp_time64_t delay =0); void propagate_vec4(const vvp_vector4_t&bit, vvp_time64_t delay =0);
unsigned port_count() const; unsigned port_count() const;
vvp_vector4_t& value(unsigned); vvp_vector4_t& value(unsigned);
double value_r(unsigned);
private: private:
// the derived class implements this to receive an indication // the derived class implements this to receive an indication
// that one of the port input values changed. // that one of the port input values changed.
virtual void recv_vec4_from_inputs(unsigned port) =0; virtual void recv_vec4_from_inputs(unsigned port) =0;
virtual void recv_real_from_inputs(unsigned port);
friend class vvp_wide_fun_t; friend class vvp_wide_fun_t;
void dispatch_vec4_from_input_(unsigned port, vvp_vector4_t bit); void dispatch_vec4_from_input_(unsigned port, vvp_vector4_t bit);
void dispatch_real_from_input_(unsigned port, double bit);
private: private:
// Back-point to the vvp_net_t that points to me. // Back-point to the vvp_net_t that points to me.
@ -934,7 +938,7 @@ class vvp_wide_fun_core : public vvp_net_fun_t {
// Structure to track the input values from the input functors. // Structure to track the input values from the input functors.
unsigned nports_; unsigned nports_;
vvp_vector4_t*port_values_; vvp_vector4_t*port_values_;
double*port_rvalues_;
}; };
/* /*
@ -950,6 +954,7 @@ class vvp_wide_fun_t : public vvp_net_fun_t {
~vvp_wide_fun_t(); ~vvp_wide_fun_t();
void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit); void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit);
void recv_real(vvp_net_ptr_t port, double bit);
private: private:
vvp_wide_fun_core*core_; vvp_wide_fun_core*core_;
@ -1008,6 +1013,9 @@ inline void vvp_send_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&val,
/* /*
* $Log: vvp_net.h,v $ * $Log: vvp_net.h,v $
* Revision 1.51 2006/06/18 04:15:50 steve
* Add support for system functions in continuous assignments.
*
* Revision 1.50 2006/03/08 05:29:42 steve * Revision 1.50 2006/03/08 05:29:42 steve
* Add support for logic parameters. * Add support for logic parameters.
* *