Logic gates can take part select inputs
[iverilog.git] / net_func.cc
blobb1091107b3e1734bf4b40e431d52f601f19c238b
1 /*
2 * Copyright (c) 2002-2004 Stephen Williams (steve@icarus.com)
4 * This source code is free software; you can redistribute it
5 * and/or modify it in source code form under the terms of the GNU
6 * General Public License as published by the Free Software
7 * Foundation; either version 2 of the License, or (at your option)
8 * any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 #ifdef HAVE_CVS_IDENT
20 #ident "$Id: net_func.cc,v 1.10 2007/06/02 03:42:13 steve Exp $"
21 #endif
23 # include "config.h"
24 # include "netlist.h"
25 # include "compiler.h"
26 # include "PExpr.h"
27 # include <iostream>
30 * To make a NetUserFunc device, make as many pins as there are ports
31 * in the function. Get the port count from the function definition,
32 * which accounts for all the inputs, plus one for the phantom output
33 * that is the result.
35 NetUserFunc::NetUserFunc(NetScope*s, perm_string n, NetScope*d)
36 : NetNode(s, n, d->func_def()->port_count()+1),
37 def_(d)
39 pin(0).set_dir(Link::OUTPUT);
40 pin(0).set_name(def_->basename(), 0);
42 for (unsigned idx = 1 ; idx < pin_count() ; idx += 1) {
44 pin(idx).set_dir(Link::INPUT);
45 pin(idx).set_name(perm_string::literal("D"), idx-1);
46 pin(idx).drive0(Link::HIGHZ);
47 pin(idx).drive1(Link::HIGHZ);
51 NetUserFunc::~NetUserFunc()
55 unsigned NetUserFunc::port_width(unsigned port) const
57 NetFuncDef*def = def_->func_def();
59 /* Port 0 is the return port. */
60 if (port == 0) {
61 const NetNet*sig = def->return_sig();
62 assert(sig);
63 return sig->vector_width();
66 port -= 1;
67 assert(port < def->port_count());
68 const NetNet*port_sig = def->port(port);
70 return port_sig->vector_width();
73 const NetScope* NetUserFunc::def() const
75 return def_;
79 * This method of the PECallFunction class checks that the parameters
80 * of the PECallFunction match the function definition. This is used
81 * during elaboration to validate the parameters before using them.
83 bool PECallFunction::check_call_matches_definition_(Design*des, NetScope*dscope) const
85 assert(dscope);
87 /* How many parameters have I got? Normally the size of the
88 list is correct, but there is the special case of a list of
89 1 nil pointer. This is how the parser tells me of no
90 parameter. In other words, ``func()'' is 1 nil parameter. */
92 unsigned parms_count = parms_.count();
93 if ((parms_count == 1) && (parms_[0] == 0))
94 parms_count = 0;
96 if (dscope->type() != NetScope::FUNC) {
97 cerr << get_line() << ": error: Attempt to call scope "
98 << scope_path(dscope) << " as a function." << endl;
99 des->errors += 1;
100 return false;
103 if (parms_count != dscope->func_def()->port_count()) {
104 cerr << get_line() << ": error: Function " << scope_path(dscope)
105 << " expects " << (dscope->func_def()->port_count())
106 << " arguments, you passed " << parms_count << "."
107 << endl;
108 des->errors += 1;
109 return false;
112 return true;
116 NetSysFunc::NetSysFunc(NetScope*s, perm_string n,
117 const struct sfunc_return_type*def,
118 unsigned ports)
119 : NetNode(s, n, ports)
121 def_ = def;
123 pin(0).set_dir(Link::OUTPUT);
124 pin(0).set_name(perm_string::literal("Q"), 0);
126 for (unsigned idx = 1 ; idx < pin_count() ; idx += 1) {
128 pin(idx).set_dir(Link::INPUT);
129 pin(idx).set_name(perm_string::literal("D"), idx-1);
130 pin(idx).drive0(Link::HIGHZ);
131 pin(idx).drive1(Link::HIGHZ);
135 NetSysFunc::~NetSysFunc()
139 const char*NetSysFunc::func_name() const
141 return def_->name;
144 unsigned NetSysFunc::vector_width() const
146 return def_->wid;
151 * $Log: net_func.cc,v $
152 * Revision 1.10 2007/06/02 03:42:13 steve
153 * Properly evaluate scope path expressions.
155 * Revision 1.9 2007/04/17 04:17:47 steve
156 * Fix argument count in function error message.
158 * Revision 1.8 2006/06/18 04:15:50 steve
159 * Add support for system functions in continuous assignments.
161 * Revision 1.7 2005/03/18 02:56:03 steve
162 * Add support for LPM_UFUNC user defined functions.
164 * Revision 1.6 2004/05/31 23:34:37 steve
165 * Rewire/generalize parsing an elaboration of
166 * function return values to allow for better
167 * speed and more type support.
169 * Revision 1.5 2004/02/18 17:11:56 steve
170 * Use perm_strings for named langiage items.
172 * Revision 1.4 2003/03/06 00:28:41 steve
173 * All NetObj objects have lex_string base names.
175 * Revision 1.3 2002/08/12 01:34:59 steve
176 * conditional ident string using autoconfig.
178 * Revision 1.2 2002/03/31 04:07:40 steve
179 * Update for gcc 3.0
181 * Revision 1.1 2002/03/09 02:10:22 steve
182 * Add the NetUserFunc netlist node.