diff --git a/Makefile.in b/Makefile.in index c3a506d68..f5de24c36 100644 --- a/Makefile.in +++ b/Makefile.in @@ -16,7 +16,7 @@ # 59 Temple Place - Suite 330 # Boston, MA 02111-1307, USA # -#ident "$Id: Makefile.in,v 1.115 2002/02/16 03:18:53 steve Exp $" +#ident "$Id: Makefile.in,v 1.116 2002/03/09 02:10:22 steve Exp $" # # SHELL = /bin/sh @@ -126,7 +126,8 @@ elab_lval.o elab_net.o elab_anet.o elab_pexpr.o elab_scope.o \ elab_sig.o emit.o eval.o eval_rconst.o \ eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \ load_module.o mangle.o netlist.o netmisc.o net_assign.o \ -net_design.o net_event.o net_expr.o net_force.o net_link.o net_modulo.o \ +net_design.o net_event.o net_expr.o net_force.o net_func.o \ +net_link.o net_modulo.o \ net_proc.o net_scope.o net_udp.o pad_to_width.o \ parse.o parse_misc.o pform.o pform_dump.o \ set_width.o \ diff --git a/PExpr.h b/PExpr.h index 528fcac82..86e0e4df0 100644 --- a/PExpr.h +++ b/PExpr.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: PExpr.h,v 1.54 2001/12/30 21:32:03 steve Exp $" +#ident "$Id: PExpr.h,v 1.55 2002/03/09 02:10:22 steve Exp $" #endif # include @@ -443,7 +443,8 @@ class PETernary : public PExpr { /* * This class represents a parsed call to a function, including calls - * to system functions. + * to system functions. The parameters in the parms list are the + * expressions that are passed as input to the ports of the function. */ class PECallFunction : public PExpr { public: @@ -452,17 +453,29 @@ class PECallFunction : public PExpr { ~PECallFunction(); virtual void dump(ostream &) const; + virtual NetNet* elaborate_net(Design*des, NetScope*scope, + unsigned width, + unsigned long rise, + unsigned long fall, + unsigned long decay, + Link::strength_t drive0, + Link::strength_t drive1) const; virtual NetExpr*elaborate_expr(Design*des, NetScope*scope) const; private: hname_t path_; svector parms_; + bool check_call_matches_definition_(Design*des, NetScope*dscope) const; + NetExpr* elaborate_sfunc_(Design*des, NetScope*scope) const; }; /* * $Log: PExpr.h,v $ + * Revision 1.55 2002/03/09 02:10:22 steve + * Add the NetUserFunc netlist node. + * * Revision 1.54 2001/12/30 21:32:03 steve * Support elaborate_net for PEString objects. * diff --git a/design_dump.cc b/design_dump.cc index c522877a8..c568d8cb6 100644 --- a/design_dump.cc +++ b/design_dump.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: design_dump.cc,v 1.121 2001/12/31 00:03:05 steve Exp $" +#ident "$Id: design_dump.cc,v 1.122 2002/03/09 02:10:22 steve Exp $" #endif # include "config.h" @@ -353,6 +353,14 @@ void NetRamDq::dump_node(ostream&o, unsigned ind) const dump_obj_attr(o, ind+4); } +void NetUserFunc::dump_node(ostream&o, unsigned ind) const +{ + o << setw(ind) << "" << def_->name() << "("; + o << ")" << endl; + dump_node_pins(o, ind+4); + dump_obj_attr(o, ind+4); +} + void NetTaskDef::dump(ostream&o, unsigned ind) const { o << setw(ind) << "" << "task " << name_ << ";" << endl; @@ -972,6 +980,9 @@ void Design::dump(ostream&o) const /* * $Log: design_dump.cc,v $ + * Revision 1.122 2002/03/09 02:10:22 steve + * Add the NetUserFunc netlist node. + * * Revision 1.121 2001/12/31 00:03:05 steve * Include s indicator in dump of signed numbers. * diff --git a/elab_expr.cc b/elab_expr.cc index d7bced28e..c471a4894 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: elab_expr.cc,v 1.50 2002/01/28 00:52:41 steve Exp $" +#ident "$Id: elab_expr.cc,v 1.51 2002/03/09 02:10:22 steve Exp $" #endif # include "config.h" @@ -258,30 +258,14 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope) const NetScope*dscope = def->scope(); assert(dscope); - /* How many parameters have I got? Normally the size of the - list is correct, but there is the special case of a list of - 1 nil pointer. This is how the parser tells me of no - parameter. In other words, ``func()'' is 1 nil parameter. */ + if (! check_call_matches_definition_(des, dscope)) + return 0; unsigned parms_count = parms_.count(); if ((parms_count == 1) && (parms_[0] == 0)) parms_count = 0; - if (dscope->type() != NetScope::FUNC) { - cerr << get_line() << ": error: Attempt to call scope " - << dscope->name() << " as a function." << endl; - des->errors += 1; - return 0; - } - - if ((parms_count+1) != dscope->func_def()->port_count()) { - cerr << get_line() << ": error: Function " << dscope->name() - << " expects " << (dscope->func_def()->port_count()-1) - << " parameters, you passed " << parms_count << "." - << endl; - des->errors += 1; - return 0; - } + svector parms (parms_count); @@ -690,6 +674,9 @@ NetEUnary* PEUnary::elaborate_expr(Design*des, NetScope*scope) const /* * $Log: elab_expr.cc,v $ + * Revision 1.51 2002/03/09 02:10:22 steve + * Add the NetUserFunc netlist node. + * * Revision 1.50 2002/01/28 00:52:41 steve * Add support for bit select of parameters. * This leads to a NetESelect node and the diff --git a/elab_net.cc b/elab_net.cc index 043d00da9..9b19c86f1 100644 --- a/elab_net.cc +++ b/elab_net.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: elab_net.cc,v 1.86 2002/01/23 05:23:17 steve Exp $" +#ident "$Id: elab_net.cc,v 1.87 2002/03/09 02:10:22 steve Exp $" #endif # include "config.h" @@ -970,6 +970,95 @@ NetNet* PEBinary::elaborate_net_shift_(Design*des, NetScope*scope, return osig; } +/* + * This method elaborates a call to a function in the context of a + * continuous assignment. + */ +NetNet* PECallFunction::elaborate_net(Design*des, NetScope*scope, unsigned, + unsigned long, + unsigned long, + unsigned long, + Link::strength_t, + Link::strength_t) const +{ + unsigned errors = 0; + unsigned func_pins = 0; + + /* Look up the function definition. */ + NetFuncDef*def = des->find_function(scope, path_); + if (def == 0) { + cerr << get_line() << ": error: No function " << path_ << + " in this context (" << scope->name() << ")." << endl; + des->errors += 1; + return 0; + } + assert(def); + + NetScope*dscope = def->scope(); + assert(dscope); + + /* check the validity of the parameters. */ + if (! check_call_matches_definition_(des, dscope)) + return 0; + + /* Elaborate all the parameters of the function call, + and collect the resulting NetNet objects. All the + parameters take on the size of the target port. */ + + svector eparms (def->port_count()-1); + for (unsigned idx = 0 ; idx < eparms.count() ; idx += 1) { + const NetNet* port_reg = def->port(idx+1); + NetNet*tmp = parms_[idx]->elaborate_net(des, scope, + port_reg->pin_count(), + 0, 0, 0, + Link::STRONG, + Link::STRONG); + if (tmp == 0) { + cerr << get_line() << ": error: Unable to elaborate " + << "port " << idx << " of call to " << path_ << + "." << endl; + errors += 1; + continue; + } + + func_pins += tmp->pin_count(); + eparms[idx] = tmp; + } + + if (errors > 0) + return 0; + + + NetUserFunc*net = new NetUserFunc(scope, + scope->local_hsymbol().c_str(), + dscope); + des->add_node(net); + + /* Create an output signal and connect it to the output pins + of the function net. */ + NetNet*osig = new NetNet(scope, scope->local_hsymbol(), + NetNet::WIRE, + def->port(0)->pin_count()); + osig->local_flag(true); + + for (unsigned idx = 0 ; idx < osig->pin_count() ; idx += 1) + connect(net->port_pin(0, idx), osig->pin(idx)); + + /* Connect the parameter pins to the parameter expressions. */ + for (unsigned idx = 0 ; idx < eparms.count() ; idx += 1) { + const NetNet* port = def->port(idx+1); + NetNet*cur = eparms[idx]; + + NetNet*tmp = pad_to_width(des, cur, port->pin_count()); + + for (unsigned pin = 0 ; pin < port->pin_count() ; pin += 1) + connect(net->port_pin(idx+1, pin), tmp->pin(pin)); + } + + return osig; +} + + /* * The concatenation operator, as a net, is a wide signal that is * connected to all the pins of the elaborated expression nets. @@ -1481,7 +1570,6 @@ NetNet* PEIdent::elaborate_port(Design*des, NetScope*scope) const return sig; } - /* * Elaborate a number as a NetConst object. */ @@ -1974,6 +2062,9 @@ NetNet* PEUnary::elaborate_net(Design*des, NetScope*scope, /* * $Log: elab_net.cc,v $ + * Revision 1.87 2002/03/09 02:10:22 steve + * Add the NetUserFunc netlist node. + * * Revision 1.86 2002/01/23 05:23:17 steve * No implicit declaration in assign l-values. * diff --git a/emit.cc b/emit.cc index 76a0ae5d9..a232a182c 100644 --- a/emit.cc +++ b/emit.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: emit.cc,v 1.65 2002/01/28 00:52:41 steve Exp $" +#ident "$Id: emit.cc,v 1.66 2002/03/09 02:10:22 steve Exp $" #endif # include "config.h" @@ -128,6 +128,11 @@ bool NetRamDq::emit_node(struct target_t*tgt) const return true; } +bool NetUserFunc::emit_node(struct target_t*tgt) const +{ + return tgt->net_function(this); +} + bool NetBUFZ::emit_node(struct target_t*tgt) const { return tgt->bufz(this); @@ -482,6 +487,9 @@ bool emit(const Design*des, const char*type) /* * $Log: emit.cc,v $ + * Revision 1.66 2002/03/09 02:10:22 steve + * Add the NetUserFunc netlist node. + * * Revision 1.65 2002/01/28 00:52:41 steve * Add support for bit select of parameters. * This leads to a NetESelect node and the diff --git a/ivl_target.h b/ivl_target.h index 54451ccbd..e7364a3e4 100644 --- a/ivl_target.h +++ b/ivl_target.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: ivl_target.h,v 1.92 2002/01/28 00:52:41 steve Exp $" +#ident "$Id: ivl_target.h,v 1.93 2002/03/09 02:10:22 steve Exp $" #endif #ifdef __cplusplus @@ -217,7 +217,8 @@ typedef enum ivl_lpm_type_e { IVL_LPM_SHIFTL = 6, IVL_LPM_SHIFTR = 7, IVL_LPM_SUB = 8, - IVL_LPM_RAM = 9 + IVL_LPM_RAM = 9, + IVL_LPM_UFUNC = 14 } ivl_lpm_type_t; /* Processes are initial or always blocks with a statement. This is @@ -570,7 +571,8 @@ extern ivl_nexus_t ivl_lpm_data(ivl_lpm_t net, unsigned idx); extern ivl_nexus_t ivl_lpm_datab(ivl_lpm_t net, unsigned idx); /* IVL_LPM_MUX */ extern ivl_nexus_t ivl_lpm_data2(ivl_lpm_t net, unsigned sdx, unsigned idx); - /* IVL_LPM_ADD IVL_LPM_FF IVL_LPM_MULT IVL_LPM_RAM IVL_LPM_SUB */ + /* IVL_LPM_ADD IVL_LPM_FF IVL_LPM_MULT IVL_LPM_RAM IVL_LPM_SUB + IVL_LPM_UFUNC */ extern ivl_nexus_t ivl_lpm_q(ivl_lpm_t net, unsigned idx); /* IVL_LPM_MUX IVL_LPM_RAM */ extern unsigned ivl_lpm_selects(ivl_lpm_t net); @@ -726,8 +728,25 @@ extern ivl_signal_t ivl_nexus_ptr_sig(ivl_nexus_ptr_t net); * generally when a module is instantiated, though they also come from * named blocks, tasks and functions. * - * (NOTE: Module scopes are *instances* of modules, and not the module - * definition. A definition may apply to many instances.) + * - module instances (IVL_SCT_MODULE) + * A module instance scope may contain events, logic gates, lpm + * nodes, signals, and possibly children. The children are further + * instances, or function/task scopes. Module instances do *not* + * contain a definition. + * + * - function scopes (IVL_SCT_FUNCTION) + * These scopes represent functions. A function may not be a root, + * so it is contained within a module instance scope. A function is + * required to have a definition (in the form of a statement) and a + * signal (IVL_SIG_REG) that is its return value. + * + * A single function scope is created each time the module with the + * definition is instantiated. + * + * + * - task scopes (IVL_SCT_TASK) + * [...] + * * * ivl_scope_children * A scope may in turn contain other scopes. This method iterates @@ -752,6 +771,11 @@ extern ivl_signal_t ivl_nexus_ptr_sig(ivl_nexus_ptr_t net); * Scopes have 0 or more logic devices in them. A logic device is * represented by ivl_logic_t. * + * ivl_scope_lpm + * ivl_scope_lpms + * Scopes have 0 or more LPM devices in them. These functions acess + * those devices. + * * ivl_scope_name * ivl_scope_basename * Every scope has a hierarchical name. This name is also a prefix @@ -978,6 +1002,9 @@ _END_DECL /* * $Log: ivl_target.h,v $ + * Revision 1.93 2002/03/09 02:10:22 steve + * Add the NetUserFunc netlist node. + * * Revision 1.92 2002/01/28 00:52:41 steve * Add support for bit select of parameters. * This leads to a NetESelect node and the @@ -995,261 +1022,5 @@ _END_DECL * * Revision 1.88 2001/11/14 03:28:49 steve * DLL target support for force and release. - * - * Revision 1.87 2001/11/01 04:25:31 steve - * ivl_target support for cassign. - * - * Revision 1.86 2001/10/31 05:24:52 steve - * ivl_target support for assign/deassign. - * - * Revision 1.85 2001/10/19 21:53:24 steve - * Support multiple root modules (Philip Blundell) - * - * Revision 1.84 2001/10/16 02:19:27 steve - * Support IVL_LPM_DIVIDE for structural divide. - * - * Revision 1.83 2001/09/30 16:45:10 steve - * Fix some Cygwin DLL handling. (Venkat Iyer) - * - * Revision 1.82 2001/09/16 22:19:42 steve - * Support attributes to logic gates. - * - * Revision 1.81 2001/09/09 22:21:57 steve - * pin down some enumerated constants. - * - * Revision 1.80 2001/09/01 01:57:31 steve - * Make constants available through the design root - * - * Revision 1.79 2001/08/31 22:58:39 steve - * Support DFF CE inputs. - * - * Revision 1.78 2001/08/28 04:07:17 steve - * Add some ivl_target convenience functions. - * - * Revision 1.77 2001/08/25 23:50:03 steve - * Change the NetAssign_ class to refer to the signal - * instead of link into the netlist. This is faster - * and uses less space. Make the NetAssignNB carry - * the delays instead of the NetAssign_ lval objects. - * - * Change the vvp code generator to support multiple - * l-values, i.e. concatenations of part selects. - * - * Revision 1.76 2001/08/10 00:40:45 steve - * tgt-vvp generates code that skips nets as inputs. - * - * Revision 1.75 2001/07/27 04:51:44 steve - * Handle part select expressions as variants of - * NetESignal/IVL_EX_SIGNAL objects, instead of - * creating new and useless temporary signals. - * - * Revision 1.74 2001/07/27 02:41:55 steve - * Fix binding of dangling function ports. do not elide them. - * - * Revision 1.73 2001/07/22 00:17:49 steve - * Support the NetESubSignal expressions in vvp.tgt. - * - * Revision 1.72 2001/07/19 04:55:06 steve - * Support calculated delays in vvp.tgt. - * - * Revision 1.71 2001/07/04 22:59:25 steve - * handle left shifter in dll output. - * - * Revision 1.70 2001/06/30 23:03:16 steve - * support fast programming by only writing the bits - * that are listed in the input file. - * - * Revision 1.69 2001/06/19 03:01:10 steve - * Add structural EEQ gates (Stephan Boettcher) - * - * Revision 1.68 2001/06/16 23:45:05 steve - * Add support for structural multiply in t-dll. - * Add code generators and vvp support for both - * structural and behavioral multiply. - * - * Revision 1.67 2001/06/16 02:41:41 steve - * Generate code to support memory access in continuous - * assignment statements. (Stephan Boettcher) - * - * Revision 1.66 2001/06/15 04:14:18 steve - * Generate vvp code for GT and GE comparisons. - * - * Revision 1.65 2001/06/07 03:09:37 steve - * support subtraction in tgt-vvp. - * - * Revision 1.64 2001/06/07 02:12:43 steve - * Support structural addition. - * - * Revision 1.63 2001/05/20 01:06:16 steve - * stub ivl_expr_parms for sfunctions. - * - * Revision 1.62 2001/05/17 04:37:02 steve - * Behavioral ternary operators for vvp. - * - * Revision 1.61 2001/05/12 03:18:44 steve - * Make sure LPM devices have drives on outputs. - * - * Revision 1.60 2001/05/08 23:59:33 steve - * Add ivl and vvp.tgt support for memories in - * expressions and l-values. (Stephan Boettcher) - * - * Revision 1.59 2001/05/08 04:13:12 steve - * sort enumeration values. - * - * Revision 1.58 2001/05/06 17:48:20 steve - * Support memory objects. (Stephan Boettcher) - * - * Revision 1.57 2001/04/29 23:17:38 steve - * Carry drive strengths in the ivl_nexus_ptr_t, and - * handle constant devices in targets.' - * - * Revision 1.56 2001/04/29 20:19:10 steve - * Add pullup and pulldown devices. - * - * Revision 1.55 2001/04/26 05:12:02 steve - * Implement simple MUXZ for ?: operators. - * - * Revision 1.54 2001/04/22 23:09:46 steve - * More UDP consolidation from Stephan Boettcher. - * - * Revision 1.53 2001/04/21 00:55:46 steve - * Generate code for disable. - * - * Revision 1.52 2001/04/15 02:58:11 steve - * vvp support for <= with internal delay. - * - * Revision 1.51 2001/04/07 19:24:36 steve - * Add the disable statemnent. - * - * Revision 1.50 2001/04/06 02:28:02 steve - * Generate vvp code for functions with ports. - * - * Revision 1.49 2001/04/05 03:20:57 steve - * Generate vvp code for the repeat statement. - * - * Revision 1.48 2001/04/05 01:12:27 steve - * Get signed compares working correctly in vvp. - * - * Revision 1.47 2001/04/04 04:50:35 steve - * Support forever loops in the tgt-vvp target. - * - * Revision 1.46 2001/04/03 04:50:37 steve - * Support non-blocking assignments. - * - * Revision 1.45 2001/04/02 02:28:12 steve - * Generate code for task calls. - * - * Revision 1.44 2001/04/02 00:28:35 steve - * Support the scope expression node. - * - * Revision 1.43 2001/04/01 06:52:27 steve - * support the NetWhile statement. - * - * Revision 1.42 2001/04/01 04:38:17 steve - * dead cruft. - * - * Revision 1.41 2001/04/01 01:48:21 steve - * Redesign event information to support arbitrary edge combining. - * - * Revision 1.40 2001/03/31 17:36:38 steve - * Generate vvp code for case statements. - * - * Revision 1.39 2001/03/30 05:49:52 steve - * Generate code for fork/join statements. - * - * Revision 1.38 2001/03/29 02:52:39 steve - * Add unary ~ operator to tgt-vvp. - * - * Revision 1.37 2001/03/28 06:07:39 steve - * Add the ivl_event_t to ivl_target, and use that to generate - * .event statements in vvp way ahead of the thread that uses it. - * - * Revision 1.36 2001/03/27 06:27:40 steve - * Generate code for simple @ statements. - * - * Revision 1.35 2001/03/20 01:44:13 steve - * Put processes in the proper scope. - * - * Revision 1.34 2001/01/15 22:05:14 steve - * Declare ivl_scope_type functions. - * - * Revision 1.33 2001/01/15 00:47:01 steve - * Pass scope type information to the target module. - * - * Revision 1.32 2001/01/15 00:05:39 steve - * Add client data pointer for scope and process scanners. - * - * Revision 1.31 2001/01/06 06:31:58 steve - * declaration initialization for time variables. - * - * Revision 1.30 2000/12/05 06:29:33 steve - * Make signal attributes available to ivl_target API. - * - * Revision 1.29 2000/11/12 17:47:29 steve - * flip-flop pins for ivl_target API. - * - * Revision 1.28 2000/11/11 01:52:09 steve - * change set for support of nmos, pmos, rnmos, rpmos, notif0, and notif1 - * change set to correct behavior of bufif0 and bufif1 - * (Tim Leight) - * - * Also includes fix for PR#27 - * - * Revision 1.27 2000/11/11 00:03:36 steve - * Add support for the t-dll backend grabing flip-flops. - * - * Revision 1.26 2000/10/31 17:49:02 steve - * Support time variables. - * - * Revision 1.25 2000/10/28 22:32:34 steve - * API for concatenation expressions. - * - * Revision 1.24 2000/10/28 17:55:03 steve - * stub for the concat operator. - * - * Revision 1.23 2000/10/25 05:41:24 steve - * Get target signal from nexus_ptr. - * - * Revision 1.22 2000/10/21 16:49:45 steve - * Reduce the target entry points to the target_design. - * - * Revision 1.21 2000/10/18 20:04:39 steve - * Add ivl_lval_t and support for assignment l-values. - * - * Revision 1.20 2000/10/15 04:46:23 steve - * Scopes and processes are accessible randomly from - * the design, and signals and logic are accessible - * from scopes. Remove the target calls that are no - * longer needed. - * - * Add the ivl_nexus_ptr_t and the means to get at - * them from nexus objects. - * - * Give names to methods that manipulate the ivl_design_t - * type more consistent names. - * - * Revision 1.19 2000/10/13 03:39:27 steve - * Include constants in nexus targets. - * - * Revision 1.18 2000/10/08 04:01:54 steve - * Back pointers in the nexus objects into the devices - * that point to it. - * - * Collect threads into a list in the design. - * - * Revision 1.17 2000/10/07 19:45:43 steve - * Put logic devices into scopes. - * - * Revision 1.16 2000/10/06 23:46:50 steve - * ivl_target updates, including more complete - * handling of ivl_nexus_t objects. Much reduced - * dependencies on pointers to netlist objects. - * - * Revision 1.15 2000/10/05 05:03:01 steve - * xor and constant devices. - * - * Revision 1.14 2000/09/30 02:18:15 steve - * ivl_expr_t support for binary operators, - * Create a proper ivl_scope_t object. */ #endif diff --git a/ivl_target.txt b/ivl_target.txt new file mode 100644 index 000000000..f15ed97c1 --- /dev/null +++ b/ivl_target.txt @@ -0,0 +1,39 @@ + +Icarus Verilog LOADABLE TARGET API (ivl_target) + + Copyright 2002 Stephen Williams + $Id: ivl_target.txt,v 1.1 2002/03/09 02:10:22 steve Exp $ + + +The ivl_target API is the interface available to modules that the +Icarus Verilog compiler loads to act as a code generator. The API +provides an interface to the elaborated, possibly synthesized, design +for code generators that are intended to write netlist files or +executable programs. + +The functions and types of the API are summarized in the ivl_target.h +header file. This ducument describes how the functions and types of +the API are used to access and interpret the netlist of the design. + + +LPM DEVICES + +All LPM devices support a small set of common LPM functions, as +described in the ivl_target header file. + +* IVL_LPM_UFUNC + +This LPM represents a user defined function. It is a way to connect +behavioral code into a structural network. The UFUNC device has a +vector output and a set of inputs. + +The output vector is accessible through the ivl_lpm_q, and the output +has the width defined by ivl_lpm_width. This similar to most every +other LPM device with outputs. + + + +$Log: ivl_target.txt,v $ +Revision 1.1 2002/03/09 02:10:22 steve + Add the NetUserFunc netlist node. + diff --git a/net_func.cc b/net_func.cc new file mode 100644 index 000000000..6a8ebbb6d --- /dev/null +++ b/net_func.cc @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2002 Stephen Williams (steve@icarus.com) + * + * This source code is free software; you can redistribute it + * and/or modify it in source code form under the terms of the GNU + * General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ +#if !defined(WINNT) +#ident "$Id: net_func.cc,v 1.1 2002/03/09 02:10:22 steve Exp $" +#endif + +# include "netlist.h" +# include "PExpr.h" + +static unsigned count_def_pins(const NetFuncDef*def) +{ + unsigned sum = 0; + for (unsigned idx = 0 ; idx < def->port_count() ; idx += 1) + sum += def->port(idx)->pin_count(); + + return sum; +} + +NetUserFunc::NetUserFunc(NetScope*s, const char*n, NetScope*d) +: NetNode(s, n, count_def_pins(d->func_def())), def_(d) +{ + NetFuncDef*def = def_->func_def(); + + unsigned port_wid = port_width(0); + for (unsigned idx = 0 ; idx < port_wid ; idx += 1) { + pin(idx).set_dir(Link::OUTPUT); + pin(idx).set_name(def_->basename(), idx); + } + + unsigned pin_base = port_wid; + for (unsigned idx = 1 ; idx < port_count() ; idx += 1) { + + const NetNet*port_sig = def->port(idx); + unsigned bits = port_width(idx); + for (unsigned bit = 0; bit < bits; bit += 1) { + pin(pin_base+bit).set_dir(Link::INPUT); + pin(pin_base+bit).set_name(port_sig->name(), bit); + pin(pin_base+bit).drive0(Link::HIGHZ); + pin(pin_base+bit).drive1(Link::HIGHZ); + } + + pin_base += bits; + } +} + +NetUserFunc::~NetUserFunc() +{ +} + +unsigned NetUserFunc::port_count() const +{ + return def_->func_def()->port_count(); +} + +unsigned NetUserFunc::port_width(unsigned port) const +{ + NetFuncDef*def = def_->func_def(); + + assert(port < def->port_count()); + const NetNet*port_sig = def->port(port); + + return port_sig->pin_count(); +} + +Link& NetUserFunc::port_pin(unsigned port, unsigned idx) +{ + NetFuncDef*def = def_->func_def(); + unsigned pin_base = 0; + const NetNet*port_sig; + + assert(port < def->port_count()); + + for (unsigned port_idx = 0 ; port_idx < port ; port_idx += 1) { + port_sig = def->port(port_idx); + pin_base += port_sig->pin_count(); + } + + port_sig = def->port(port); + assert(idx < port_sig->pin_count()); + assert((pin_base+idx) < pin_count()); + + return pin(pin_base+idx); +} + + +const NetScope* NetUserFunc::def() const +{ + return def_; +} + +/* + * This method of the PECallFunction class checks that the parameters + * of the PECallFunction match the function definition. This is used + * during elaboration to validate the parameters before using them. + */ +bool PECallFunction::check_call_matches_definition_(Design*des, NetScope*dscope) const +{ + assert(dscope); + + /* How many parameters have I got? Normally the size of the + list is correct, but there is the special case of a list of + 1 nil pointer. This is how the parser tells me of no + parameter. In other words, ``func()'' is 1 nil parameter. */ + + unsigned parms_count = parms_.count(); + if ((parms_count == 1) && (parms_[0] == 0)) + parms_count = 0; + + if (dscope->type() != NetScope::FUNC) { + cerr << get_line() << ": error: Attempt to call scope " + << dscope->name() << " as a function." << endl; + des->errors += 1; + return false; + } + + if ((parms_count+1) != dscope->func_def()->port_count()) { + cerr << get_line() << ": error: Function " << dscope->name() + << " expects " << (dscope->func_def()->port_count()-1) + << " parameters, you passed " << parms_count << "." + << endl; + des->errors += 1; + return false; + } + + return true; +} + +/* + * $Log: net_func.cc,v $ + * Revision 1.1 2002/03/09 02:10:22 steve + * Add the NetUserFunc netlist node. + * + */ + diff --git a/netlist.h b/netlist.h index e3d733d2c..f984b400c 100644 --- a/netlist.h +++ b/netlist.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: netlist.h,v 1.231 2002/01/28 00:52:41 steve Exp $" +#ident "$Id: netlist.h,v 1.232 2002/03/09 02:10:22 steve Exp $" #endif /* @@ -52,6 +52,7 @@ class NetProcTop; class NetScope; class NetExpr; class NetESignal; +class NetFuncDef; struct target; @@ -819,6 +820,29 @@ class NetRamDq : public NetNode { }; +/* + * This node represents the call of a user defined function in a + * structural context. + */ +class NetUserFunc : public NetNode { + + public: + NetUserFunc(NetScope*s, const char*n, NetScope*def); + ~NetUserFunc(); + + unsigned port_count() const; + unsigned port_width(unsigned port) const; + Link& port_pin(unsigned port, unsigned idx); + + const NetScope* def() const; + + virtual void dump_node(ostream&, unsigned ind) const; + virtual bool emit_node(struct target_t*) const; + + private: + NetScope*def_; +}; + /* ========= * There are cases where expressions need to be represented. The * NetExpr class is the root of a heirarchy that serves that purpose. @@ -1734,10 +1758,15 @@ class NetForever : public NetProc { }; /* - * A funciton definition is elaborated just like a task, though by now + * A function definition is elaborated just like a task, though by now * it is certain that the first parameter (a phantom parameter) is the * output and all the remaining parameters are the inputs. This makes - * for easy code generation in targets that support behavioral descriptions. + * for easy code generation in targets that support behavioral + * descriptions. + * + * The NetNet array that is passed in as a parameter is the set of + * signals that make up its parameter list. These are all internal to + * the scope of the function. */ class NetFuncDef { @@ -2891,6 +2920,9 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.232 2002/03/09 02:10:22 steve + * Add the NetUserFunc netlist node. + * * Revision 1.231 2002/01/28 00:52:41 steve * Add support for bit select of parameters. * This leads to a NetESelect node and the @@ -2901,255 +2933,5 @@ extern ostream& operator << (ostream&, NetNet::Type); * * Revision 1.229 2002/01/19 19:02:08 steve * Pass back target errors processing conditionals. - * - * Revision 1.228 2001/12/31 00:08:14 steve - * Support $signed cast of expressions. - * - * Revision 1.227 2001/12/03 04:47:15 steve - * Parser and pform use hierarchical names as hname_t - * objects instead of encoded strings. - * - * Revision 1.226 2001/11/29 01:58:18 steve - * Handle part selects in l-values of DFF devices. - * - * Revision 1.225 2001/11/19 04:26:46 steve - * Unary reduction operators are all 1-bit results. - * - * Revision 1.224 2001/11/14 03:28:49 steve - * DLL target support for force and release. - * - * Revision 1.223 2001/11/09 03:43:26 steve - * Spelling errors. - * - * Revision 1.222 2001/11/08 05:15:51 steve - * Remove string paths from PExpr elaboration. - * - * Revision 1.221 2001/11/06 04:32:37 steve - * shift expressions can have definite widths. - * - * Revision 1.220 2001/10/31 05:24:52 steve - * ivl_target support for assign/deassign. - * - * Revision 1.219 2001/10/28 01:14:53 steve - * NetObj constructor finally requires a scope. - * - * Revision 1.218 2001/10/20 05:21:51 steve - * Scope/module names are char* instead of string. - * - * Revision 1.217 2001/10/19 21:53:24 steve - * Support multiple root modules (Philip Blundell) - * - * Revision 1.216 2001/10/16 02:19:27 steve - * Support IVL_LPM_DIVIDE for structural divide. - * - * Revision 1.215 2001/10/07 03:38:08 steve - * parameter names do not have defined size. - * - * Revision 1.214 2001/08/25 23:50:03 steve - * Change the NetAssign_ class to refer to the signal - * instead of link into the netlist. This is faster - * and uses less space. Make the NetAssignNB carry - * the delays instead of the NetAssign_ lval objects. - * - * Change the vvp code generator to support multiple - * l-values, i.e. concatenations of part selects. - * - * Revision 1.213 2001/07/27 04:51:44 steve - * Handle part select expressions as variants of - * NetESignal/IVL_EX_SIGNAL objects, instead of - * creating new and useless temporary signals. - * - * Revision 1.212 2001/07/22 00:17:49 steve - * Support the NetESubSignal expressions in vvp.tgt. - * - * Revision 1.211 2001/07/04 22:59:25 steve - * handle left shifter in dll output. - * - * Revision 1.210 2001/07/01 00:27:34 steve - * Make NetFF constructor take const char* for the name. - * - * Revision 1.209 2001/06/16 23:45:05 steve - * Add support for structural multiply in t-dll. - * Add code generators and vvp support for both - * structural and behavioral multiply. - * - * Revision 1.208 2001/06/15 04:14:18 steve - * Generate vvp code for GT and GE comparisons. - * - * Revision 1.207 2001/06/07 02:12:43 steve - * Support structural addition. - * - * Revision 1.206 2001/05/08 23:59:33 steve - * Add ivl and vvp.tgt support for memories in - * expressions and l-values. (Stephan Boettcher) - * - * Revision 1.205 2001/04/29 20:19:10 steve - * Add pullup and pulldown devices. - * - * Revision 1.204 2001/04/24 02:23:58 steve - * Support for UDP devices in VVP (Stephen Boettcher) - * - * Revision 1.203 2001/04/22 23:09:46 steve - * More UDP consolidation from Stephan Boettcher. - * - * Revision 1.202 2001/04/06 02:28:02 steve - * Generate vvp code for functions with ports. - * - * Revision 1.201 2001/04/02 02:28:12 steve - * Generate code for task calls. - * - * Revision 1.200 2001/03/29 02:52:01 steve - * Add const probe method to NetEvent. - * - * Revision 1.199 2001/02/15 06:59:36 steve - * FreeBSD port has a maintainer now. - * - * Revision 1.198 2001/02/10 21:20:38 steve - * Binary operators with operands of indefinite width - * has itself an indefinite width. - * - * Revision 1.197 2001/02/10 20:29:39 steve - * In the context of range declarations, use elab_and_eval instead - * of the less robust eval_const methods. - * - * Revision 1.196 2001/02/09 05:44:23 steve - * support evaluation of constant < in expressions. - * - * Revision 1.195 2001/01/18 03:16:35 steve - * NetMux needs a scope. (PR#115) - * - * Revision 1.194 2001/01/16 02:44:18 steve - * Use the iosfwd header if available. - * - * Revision 1.193 2001/01/06 06:31:58 steve - * declaration initialization for time variables. - * - * Revision 1.192 2001/01/06 02:29:36 steve - * Support arrays of integers. - * - * Revision 1.191 2001/01/04 16:49:50 steve - * Evaluate constant === and !== expressions. - * - * Revision 1.190 2001/01/02 04:21:14 steve - * Support a bunch of unary operators in parameter expressions. - * - * Revision 1.189 2001/01/02 03:23:40 steve - * Evaluate constant &, | and unary ~. - * - * Revision 1.188 2000/12/16 19:03:30 steve - * Evaluate <= and ?: in parameter expressions (PR#81) - * - * Revision 1.187 2000/12/16 01:45:48 steve - * Detect recursive instantiations (PR#2) - * - * Revision 1.186 2000/12/11 00:31:43 steve - * Add support for signed reg variables, - * simulate in t-vvm signed comparisons. - * - * Revision 1.185 2000/12/05 06:29:33 steve - * Make signal attributes available to ivl_target API. - * - * Revision 1.184 2000/12/04 17:37:04 steve - * Add Attrib class for holding NetObj attributes. - * - * Revision 1.183 2000/12/02 05:08:04 steve - * Spelling error in comment. - * - * Revision 1.182 2000/11/29 05:24:00 steve - * synthesis for unary reduction ! and N operators. - * - * Revision 1.181 2000/11/29 02:09:53 steve - * Add support for || synthesis (PR#53) - * - * Revision 1.180 2000/11/20 00:58:40 steve - * Add support for supply nets (PR#17) - * - * Revision 1.179 2000/11/11 01:52:09 steve - * change set for support of nmos, pmos, rnmos, rpmos, notif0, and notif1 - * change set to correct behavior of bufif0 and bufif1 - * (Tim Leight) - * - * Also includes fix for PR#27 - * - * Revision 1.178 2000/11/11 00:03:36 steve - * Add support for the t-dll backend grabing flip-flops. - * - * Revision 1.177 2000/11/04 06:36:24 steve - * Apply sequential UDP rework from Stephan Boettcher (PR#39) - * - * Revision 1.176 2000/10/31 17:49:02 steve - * Support time variables. - * - * Revision 1.175 2000/10/28 00:51:42 steve - * Add scope to threads in vvm, pass that scope - * to vpi sysTaskFunc objects, and add vpi calls - * to access that information. - * - * $display displays scope in %m (PR#1) - * - * Revision 1.174 2000/10/18 20:04:39 steve - * Add ivl_lval_t and support for assignment l-values. - * - * Revision 1.173 2000/10/07 19:45:43 steve - * Put logic devices into scopes. - * - * Revision 1.172 2000/10/06 23:46:50 steve - * ivl_target updates, including more complete - * handling of ivl_nexus_t objects. Much reduced - * dependencies on pointers to netlist objects. - * - * Revision 1.171 2000/10/05 05:03:01 steve - * xor and constant devices. - * - * Revision 1.170 2000/10/04 16:30:39 steve - * Use char8 instead of string to store name. - * - * Revision 1.169 2000/09/29 04:43:09 steve - * Cnstant evaluation of NE. - * - * Revision 1.168 2000/09/26 05:05:58 steve - * Detect indefinite widths where definite widths are required. - * - * Revision 1.167 2000/09/26 01:35:42 steve - * Remove the obsolete NetEIdent class. - * - * Revision 1.166 2000/09/24 17:41:13 steve - * fix null pointer when elaborating undefined task. - * - * Revision 1.165 2000/09/24 15:44:44 steve - * Move some NetNet method out of the header file. - * - * Revision 1.164 2000/09/22 03:58:30 steve - * Access to the name of a system task call. - * - * Revision 1.163 2000/09/17 21:26:15 steve - * Add support for modulus (Eric Aardoom) - * - * Revision 1.162 2000/09/10 02:18:16 steve - * elaborate complex l-values - * - * Revision 1.161 2000/09/07 00:06:53 steve - * encapsulate access to the l-value expected width. - * - * Revision 1.160 2000/09/02 23:40:13 steve - * Pull NetAssign_ creation out of constructors. - * - * Revision 1.159 2000/09/02 20:54:20 steve - * Rearrange NetAssign to make NetAssign_ separate. - * - * Revision 1.158 2000/08/27 15:51:50 steve - * t-dll iterates signals, and passes them to the - * target module. - * - * Some of NetObj should return char*, not string. - * - * Revision 1.157 2000/08/26 00:54:03 steve - * Get at gate information for ivl_target interface. - * - * Revision 1.156 2000/08/14 04:39:57 steve - * add th t-dll functions for net_const, net_bufz and processes. - * - * Revision 1.155 2000/08/09 03:43:45 steve - * Move all file manipulation out of target class. */ #endif diff --git a/t-dll-api.cc b/t-dll-api.cc index d8a11bc76..39eb1b0a8 100644 --- a/t-dll-api.cc +++ b/t-dll-api.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: t-dll-api.cc,v 1.75 2002/01/28 00:52:41 steve Exp $" +#ident "$Id: t-dll-api.cc,v 1.76 2002/03/09 02:10:22 steve Exp $" #endif # include "config.h" @@ -674,6 +674,10 @@ extern "C" ivl_nexus_t ivl_lpm_q(ivl_lpm_t net, unsigned idx) assert(idx < net->u_.shift.width); return net->u_.shift.q[idx]; + case IVL_LPM_UFUNC: + assert(idx < net->u_.ufunc.port_wid[0]); + return net->u_.ufunc.pins[idx]; + default: assert(0); return 0; @@ -768,6 +772,8 @@ extern "C" unsigned ivl_lpm_width(ivl_lpm_t net) case IVL_LPM_SHIFTL: case IVL_LPM_SHIFTR: return net->u_.shift.width; + case IVL_LPM_UFUNC: + return net->u_.ufunc.port_wid[0]; default: assert(0); return 0; @@ -1452,6 +1458,9 @@ extern "C" ivl_statement_t ivl_stmt_sub_stmt(ivl_statement_t net) /* * $Log: t-dll-api.cc,v $ + * Revision 1.76 2002/03/09 02:10:22 steve + * Add the NetUserFunc netlist node. + * * Revision 1.75 2002/01/28 00:52:41 steve * Add support for bit select of parameters. * This leads to a NetESelect node and the diff --git a/t-dll.cc b/t-dll.cc index 688236052..0f6d6202c 100644 --- a/t-dll.cc +++ b/t-dll.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 Stephen Williams (steve@icarus.com) + * Copyright (c) 2000-2002 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 @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: t-dll.cc,v 1.79 2002/01/23 04:54:37 steve Exp $" +#ident "$Id: t-dll.cc,v 1.80 2002/03/09 02:10:22 steve Exp $" #endif # include "config.h" @@ -788,6 +788,59 @@ bool dll_target::net_force(const NetForce*net) return true; } +/* + * An IVL_LPM_UFUNC represents a node in a combinational expression + * that calls a user defined function. I create an LPM object that has + * the right connections, and refers to the ivl_scope_t of the + * definition. + */ +bool dll_target::net_function(const NetUserFunc*net) +{ + struct ivl_lpm_s*obj = new struct ivl_lpm_s; + obj->type = IVL_LPM_UFUNC; + obj->name = strdup(net->name()); + obj->scope = find_scope(des_, net->scope()); + assert(obj->scope); + + /* Get the definition of the function and save it. */ + const NetScope*def = net->def(); + assert(def); + + obj->u_.ufunc.def = lookup_scope_(def); + + /* Save information about the ports in the ivl_lpm_s + structure. Note that port 0 is the return value. */ + obj->u_.ufunc.ports = net->port_count(); + obj->u_.ufunc.port_wid = new unsigned short[net->port_count()]; + for (unsigned idx = 0 ; idx < obj->u_.ufunc.ports ; idx += 1) + obj->u_.ufunc.port_wid[idx] = net->port_width(idx); + + /* Now collect all the pins and connect them to the nexa of + the net. The output pins have strong drive, and the + remaining input pins are HiZ. */ + + unsigned pin_count = net->pin_count(); + obj->u_.ufunc.pins = new ivl_nexus_t[pin_count]; + + for (unsigned idx = 0 ; idx < pin_count ; idx += 1) { + const Nexus*nex = net->pin(idx).nexus(); + assert(nex->t_cookie()); + ivl_nexus_t nn = (ivl_nexus_t)nex->t_cookie(); + assert(nn); + + obj->u_.ufunc.pins[idx] = nn; + ivl_drive_t drive = idx < obj->u_.ufunc.port_wid[0] + ? IVL_DR_STRONG + : IVL_DR_HiZ; + nexus_lpm_add(obj->u_.ufunc.pins[idx], obj, idx, drive, drive); + } + + /* All done. Add this LPM to the scope. */ + scope_add_lpm(obj->scope, obj); + + return true; +} + void dll_target::udp(const NetUDP*net) { struct ivl_net_logic_s *obj = new struct ivl_net_logic_s; @@ -1876,6 +1929,9 @@ extern const struct target tgt_dll = { "dll", &dll_target_obj }; /* * $Log: t-dll.cc,v $ + * Revision 1.80 2002/03/09 02:10:22 steve + * Add the NetUserFunc netlist node. + * * Revision 1.79 2002/01/23 04:54:37 steve * Load modules with RTLD_LAZY * @@ -1906,114 +1962,5 @@ extern const struct target tgt_dll = { "dll", &dll_target_obj }; * * Revision 1.70 2001/11/14 03:28:49 steve * DLL target support for force and release. - * - * Revision 1.69 2001/10/30 02:52:07 steve - * Stubs for assign/deassign for t-dll. - * - * Revision 1.68 2001/10/22 02:05:21 steve - * Handle activating tasks in another root. - * - * Revision 1.67 2001/10/19 21:53:24 steve - * Support multiple root modules (Philip Blundell) - * - * Revision 1.66 2001/10/16 02:19:27 steve - * Support IVL_LPM_DIVIDE for structural divide. - * - * Revision 1.65 2001/10/11 00:13:19 steve - * Initialize attributes for bufz devices. - * - * Revision 1.64 2001/09/16 22:19:42 steve - * Support attributes to logic gates. - * - * Revision 1.63 2001/09/15 18:27:04 steve - * Make configure detect malloc.h - * - * Revision 1.62 2001/09/09 16:49:04 steve - * Connect right ANEB pin when doing NE comparator. - * - * Revision 1.61 2001/09/08 01:23:21 steve - * No code for unlinked constants. - * - * Revision 1.60 2001/09/01 01:57:31 steve - * Make constants available through the design root - * - * Revision 1.59 2001/08/31 22:58:39 steve - * Support DFF CE inputs. - * - * Revision 1.58 2001/08/28 04:07:41 steve - * Add some ivl_target convenience functions. - * - * Revision 1.57 2001/08/10 00:40:45 steve - * tgt-vvp generates code that skips nets as inputs. - * - * Revision 1.56 2001/07/25 03:10:50 steve - * Create a config.h.in file to hold all the config - * junk, and support gcc 3.0. (Stephan Boettcher) - * - * Revision 1.55 2001/07/22 00:17:49 steve - * Support the NetESubSignal expressions in vvp.tgt. - * - * Revision 1.54 2001/07/07 03:01:37 steve - * Detect and make available to t-dll the right shift. - * - * Revision 1.53 2001/07/04 22:59:25 steve - * handle left shifter in dll output. - * - * Revision 1.52 2001/06/30 23:03:16 steve - * support fast programming by only writing the bits - * that are listed in the input file. - * - * Revision 1.51 2001/06/19 03:01:10 steve - * Add structural EEQ gates (Stephan Boettcher) - * - * Revision 1.50 2001/06/18 03:25:20 steve - * RAM_DQ pins are inputs, so connect HiZ to the nexus. - * - * Revision 1.49 2001/06/16 23:45:05 steve - * Add support for structural multiply in t-dll. - * Add code generators and vvp support for both - * structural and behavioral multiply. - * - * Revision 1.48 2001/06/16 02:41:42 steve - * Generate code to support memory access in continuous - * assignment statements. (Stephan Boettcher) - * - * Revision 1.47 2001/06/15 05:01:09 steve - * support LE and LT comparators. - * - * Revision 1.46 2001/06/15 04:14:19 steve - * Generate vvp code for GT and GE comparisons. - * - * Revision 1.45 2001/06/07 04:20:10 steve - * Account for carry out on add devices. - * - * Revision 1.44 2001/06/07 03:09:37 steve - * support subtraction in tgt-vvp. - * - * Revision 1.43 2001/06/07 02:12:43 steve - * Support structural addition. - * - * Revision 1.42 2001/05/20 15:09:39 steve - * Mingw32 support (Venkat Iyer) - * - * Revision 1.41 2001/05/12 03:18:45 steve - * Make sure LPM devices have drives on outputs. - * - * Revision 1.40 2001/05/08 23:59:33 steve - * Add ivl and vvp.tgt support for memories in - * expressions and l-values. (Stephan Boettcher) - * - * Revision 1.39 2001/05/03 01:52:45 steve - * dll build of many probes forgot to index the probe. - * - * Revision 1.38 2001/04/29 23:17:38 steve - * Carry drive strengths in the ivl_nexus_ptr_t, and - * handle constant devices in targets.' - * - * Revision 1.37 2001/04/29 20:19:10 steve - * Add pullup and pulldown devices. - * - * Revision 1.36 2001/04/26 05:12:02 steve - * Implement simple MUXZ for ?: operators. */ diff --git a/t-dll.h b/t-dll.h index fa8989aa3..a2d6161a0 100644 --- a/t-dll.h +++ b/t-dll.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: t-dll.h,v 1.75 2002/01/28 00:52:41 steve Exp $" +#ident "$Id: t-dll.h,v 1.76 2002/03/09 02:10:22 steve Exp $" #endif # include "target.h" @@ -82,6 +82,7 @@ struct dll_target : public target_t, public expr_scan_t { void net_assign(const NetAssign_*); bool net_cassign(const NetCAssign*); bool net_force(const NetForce*); + bool net_function(const NetUserFunc*); bool net_const(const NetConst*); void net_probe(const NetEvProbe*); @@ -301,6 +302,13 @@ struct ivl_lpm_s { unsigned short width; ivl_nexus_t*q, *a, *b; } arith; + + struct ivl_lpm_ufunc_s { + ivl_scope_t def; + unsigned short ports; + unsigned short*port_wid; + ivl_nexus_t*pins; + } ufunc; } u_; }; @@ -591,6 +599,9 @@ struct ivl_statement_s { /* * $Log: t-dll.h,v $ + * Revision 1.76 2002/03/09 02:10:22 steve + * Add the NetUserFunc netlist node. + * * Revision 1.75 2002/01/28 00:52:41 steve * Add support for bit select of parameters. * This leads to a NetESelect node and the @@ -616,86 +627,5 @@ struct ivl_statement_s { * * Revision 1.68 2001/10/31 05:24:52 steve * ivl_target support for assign/deassign. - * - * Revision 1.67 2001/10/30 02:52:07 steve - * Stubs for assign/deassign for t-dll. - * - * Revision 1.66 2001/10/19 21:53:24 steve - * Support multiple root modules (Philip Blundell) - * - * Revision 1.65 2001/10/16 02:19:27 steve - * Support IVL_LPM_DIVIDE for structural divide. - * - * Revision 1.64 2001/09/16 22:19:42 steve - * Support attributes to logic gates. - * - * Revision 1.63 2001/09/01 01:57:31 steve - * Make constants available through the design root - * - * Revision 1.62 2001/08/31 22:58:40 steve - * Support DFF CE inputs. - * - * Revision 1.61 2001/08/28 04:07:41 steve - * Add some ivl_target convenience functions. - * - * Revision 1.60 2001/08/25 23:50:03 steve - * Change the NetAssign_ class to refer to the signal - * instead of link into the netlist. This is faster - * and uses less space. Make the NetAssignNB carry - * the delays instead of the NetAssign_ lval objects. - * - * Change the vvp code generator to support multiple - * l-values, i.e. concatenations of part selects. - * - * Revision 1.59 2001/08/10 00:40:45 steve - * tgt-vvp generates code that skips nets as inputs. - * - * Revision 1.58 2001/07/27 04:51:44 steve - * Handle part select expressions as variants of - * NetESignal/IVL_EX_SIGNAL objects, instead of - * creating new and useless temporary signals. - * - * Revision 1.57 2001/07/27 02:41:56 steve - * Fix binding of dangling function ports. do not elide them. - * - * Revision 1.56 2001/07/22 00:17:50 steve - * Support the NetESubSignal expressions in vvp.tgt. - * - * Revision 1.55 2001/07/19 04:55:06 steve - * Support calculated delays in vvp.tgt. - * - * Revision 1.54 2001/07/07 20:20:10 steve - * Pass parameters to system functions. - * - * Revision 1.53 2001/07/04 22:59:25 steve - * handle left shifter in dll output. - * - * Revision 1.52 2001/06/30 23:03:16 steve - * support fast programming by only writing the bits - * that are listed in the input file. - * - * Revision 1.51 2001/06/30 21:07:26 steve - * Support non-const right shift (unsigned). - * - * Revision 1.50 2001/06/19 03:01:10 steve - * Add structural EEQ gates (Stephan Boettcher) - * - * Revision 1.49 2001/06/16 23:45:05 steve - * Add support for structural multiply in t-dll. - * Add code generators and vvp support for both - * structural and behavioral multiply. - * - * Revision 1.48 2001/06/16 02:41:42 steve - * Generate code to support memory access in continuous - * assignment statements. (Stephan Boettcher) - * - * Revision 1.47 2001/06/15 04:14:19 steve - * Generate vvp code for GT and GE comparisons. - * - * Revision 1.46 2001/06/07 02:12:43 steve - * Support structural addition. - * - * Revision 1.45 2001/05/20 15:09:39 steve - * Mingw32 support (Venkat Iyer) */ #endif diff --git a/target.cc b/target.cc index 2c5809763..2e2ad85c6 100644 --- a/target.cc +++ b/target.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2000 Stephen Williams + * Copyright (c) 1998-2002 Stephen Williams * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: target.cc,v 1.59 2002/01/28 00:52:41 steve Exp $" +#ident "$Id: target.cc,v 1.60 2002/03/09 02:10:22 steve Exp $" #endif # include "config.h" @@ -158,6 +158,13 @@ bool target_t::net_force(const NetForce*dev) return false; } +bool target_t::net_function(const NetUserFunc*net) +{ + cerr << "target (" << typeid(*this).name() << "): " + "Unhandled NetUserFunc node." << endl; + return false; +} + void target_t::net_probe(const NetEvProbe*net) { cerr << "target (" << typeid(*this).name() << "): " @@ -390,6 +397,9 @@ void expr_scan_t::expr_binary(const NetEBinary*ex) /* * $Log: target.cc,v $ + * Revision 1.60 2002/03/09 02:10:22 steve + * Add the NetUserFunc netlist node. + * * Revision 1.59 2002/01/28 00:52:41 steve * Add support for bit select of parameters. * This leads to a NetESelect node and the diff --git a/target.h b/target.h index 8ef9cf674..30e8ca4e5 100644 --- a/target.h +++ b/target.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: target.h,v 1.56 2002/01/28 00:52:41 steve Exp $" +#ident "$Id: target.h,v 1.57 2002/03/09 02:10:22 steve Exp $" #endif # include "netlist.h" @@ -91,6 +91,7 @@ struct target_t { virtual bool net_cassign(const NetCAssign*); virtual bool net_const(const NetConst*); virtual bool net_force(const NetForce*); + virtual bool net_function(const NetUserFunc*); virtual void net_probe(const NetEvProbe*); /* Output a process (called for each process). It is up to the @@ -163,6 +164,9 @@ extern const struct target *target_table[]; /* * $Log: target.h,v $ + * Revision 1.57 2002/03/09 02:10:22 steve + * Add the NetUserFunc netlist node. + * * Revision 1.56 2002/01/28 00:52:41 steve * Add support for bit select of parameters. * This leads to a NetESelect node and the diff --git a/tgt-vvp/vvp_scope.c b/tgt-vvp/vvp_scope.c index d7dec5ba6..8cf60ef75 100644 --- a/tgt-vvp/vvp_scope.c +++ b/tgt-vvp/vvp_scope.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: vvp_scope.c,v 1.64 2002/01/12 17:49:41 steve Exp $" +#ident "$Id: vvp_scope.c,v 1.65 2002/03/09 02:10:22 steve Exp $" #endif # include "vvp_priv.h" @@ -319,6 +319,7 @@ static const char* draw_net_input_drive(ivl_nexus_t nex, ivl_nexus_ptr_t nptr) case IVL_LPM_MULT: case IVL_LPM_DIVIDE: case IVL_LPM_MOD: + case IVL_LPM_UFUNC: for (idx = 0 ; idx < ivl_lpm_width(lpm) ; idx += 1) if (ivl_lpm_q(lpm, idx) == nex) { sprintf(result, "L_%s[%u]", @@ -1278,6 +1279,14 @@ static void draw_lpm_shiftl(ivl_lpm_t net) fprintf(vvp_out, ";\n"); } +static void draw_lpm_ufunc(ivl_lpm_t net) +{ + fprintf(stderr, "tgt-vvp: ivl_ufunc not yet supported.\n"); + fprintf(vvp_out, "L_%s .func %u %u;\n", + vvp_mangle_id(ivl_lpm_name(net)), + ivl_lpm_width(net), 0); +} + static void draw_lpm_in_scope(ivl_lpm_t net) { switch (ivl_lpm_type(net)) { @@ -1313,6 +1322,10 @@ static void draw_lpm_in_scope(ivl_lpm_t net) draw_lpm_shiftl(net); return; + case IVL_LPM_UFUNC: + draw_lpm_ufunc(net); + return; + default: fprintf(stderr, "XXXX LPM not supported: %s\n", ivl_lpm_name(net)); @@ -1410,6 +1423,9 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent) /* * $Log: vvp_scope.c,v $ + * Revision 1.65 2002/03/09 02:10:22 steve + * Add the NetUserFunc netlist node. + * * Revision 1.64 2002/01/12 17:49:41 steve * Handle constants with drive strength z *