Add support for system functions in continuous assignments.
This commit is contained in:
parent
71faebd6df
commit
80f30be9d0
12
PExpr.h
12
PExpr.h
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
122
elab_net.cc
122
elab_net.cc
|
|
@ -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
|
||||||
|
|
|
||||||
9
emit.cc
9
emit.cc
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
29
ivl_target.h
29
ivl_target.h
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
40
net_func.cc
40
net_func.cc
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
27
netlist.h
27
netlist.h
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
69
t-dll-api.cc
69
t-dll-api.cc
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
79
t-dll.cc
79
t-dll.cc
|
|
@ -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
23
t-dll.h
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
12
target.cc
12
target.cc
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
6
target.h
6
target.h
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
11
vvp/parse.y
11
vvp/parse.y
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
135
vvp/vpi_tasks.cc
135
vvp/vpi_tasks.cc
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue