Merge branch 'master' of steve-icarus@icarus.com:git/verilog
[iverilog.git] / link_const.cc
blob60b68afa6585d73b907955b8debdda9fa218e2fd
1 /*
2 * Copyright (c) 2000 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: link_const.cc,v 1.18 2007/04/14 03:10:51 steve Exp $"
21 #endif
23 # include "config.h"
25 # include "netlist.h"
26 # include "netmisc.h"
29 * Scan the link for drivers. If there are only constant drivers, then
30 * the nexus has a known constant value. If there is a supply net,
31 * then the nexus again has a known constant value.
33 bool Nexus::drivers_constant() const
35 if (driven_ == VAR)
36 return false;
37 if (driven_ != NO_GUESS)
38 return true;
40 for (const Link*cur = list_ ; cur ; cur = cur->next_) {
41 const NetNet*sig;
42 Link::DIR cur_dir;
44 cur_dir = cur->get_dir();
45 if (cur_dir == Link::INPUT)
46 continue;
48 /* If this is an input or inout port of a root module,
49 then the is probably not a constant value. I
50 certainly don't know what the value is, anyhow. This
51 can happen in cases like this:
53 module main(sig);
54 input sig;
55 endmodule
57 If main is a root module (it has no parent) then sig
58 is not constant because it connects to an unspecified
59 outside world. */
61 if (cur_dir == Link::PASSIVE) {
63 const NetObj*obj = cur->get_obj();
64 if (obj->scope()->parent() != 0)
65 continue;
67 sig = dynamic_cast<const NetNet*>(cur->get_obj());
68 assert(sig);
70 if (sig->port_type() == NetNet::NOT_A_PORT)
71 continue;
73 if (sig->port_type() == NetNet::POUTPUT)
74 continue;
76 driven_ = VAR;
77 return false;
81 /* If there is a supply net, then this nexus will have a
82 constant value independent of any drivers. */
83 if (const NetNet*sig = dynamic_cast<const NetNet*>(cur->get_obj()))
84 switch (sig->type()) {
85 case NetNet::SUPPLY0:
86 driven_ = V0;
87 return true;
88 case NetNet::SUPPLY1:
89 driven_ = V1;
90 return true;
91 default:
92 break;
95 if (! dynamic_cast<const NetConst*>(cur->get_obj())) {
96 driven_ = VAR;
97 return false;
101 return true;
104 verinum::V Nexus::driven_value() const
106 switch (driven_) {
107 case V0:
108 return verinum::V0;
109 case V1:
110 return verinum::V1;
111 case Vx:
112 return verinum::Vx;
113 case Vz:
114 return verinum::Vz;
115 case VAR:
116 assert(0);
117 break;
118 case NO_GUESS:
119 break;
122 const Link*cur = list_;
124 verinum::V val = verinum::Vz;
126 for (cur = list_ ; cur ; cur = cur->next_) {
128 const NetConst*obj;
129 const NetNet*sig;
130 if ((obj = dynamic_cast<const NetConst*>(cur->get_obj()))) {
131 val = obj->value(cur->get_pin());
133 } else if ((sig = dynamic_cast<const NetNet*>(cur->get_obj()))) {
135 // If we find an attached SUPPLY0/1, the we know
136 // from that what the driven value is. Stop now.
137 if (sig->type() == NetNet::SUPPLY0) {
138 driven_ = V0;
139 return verinum::V0;
141 if (sig->type() == NetNet::SUPPLY1) {
142 driven_ = V1;
143 return verinum::V1;
146 // If we find an attached TRI0/1, then this is a
147 // good guess for the driven value, but keep
148 // looking for something better.
149 if (sig->type() == NetNet::TRI0) {
150 val = verinum::V0;
152 if (sig->type() == NetNet::TRI1) {
153 val = verinum::V1;
158 /* Cache the result. */
159 switch (val) {
160 case verinum::V0:
161 driven_ = V0;
162 break;
163 case verinum::V1:
164 driven_ = V1;
165 break;
166 case verinum::Vx:
167 driven_ = Vx;
168 break;
169 case verinum::Vz:
170 driven_ = Vz;
171 break;
174 return val;
178 * $Log: link_const.cc,v $
179 * Revision 1.18 2007/04/14 03:10:51 steve
180 * Properly account for tri0 connected to otherwise open mux input.
182 * Revision 1.17 2004/10/04 01:10:53 steve
183 * Clean up spurious trailing white space.
185 * Revision 1.16 2003/06/21 01:21:43 steve
186 * Harmless fixup of warnings.
188 * Revision 1.15 2002/08/12 01:34:59 steve
189 * conditional ident string using autoconfig.
191 * Revision 1.14 2002/06/25 01:33:22 steve
192 * Cache calculated driven value.
194 * Revision 1.13 2002/06/24 01:49:39 steve
195 * Make link_drive_constant cache its results in
196 * the Nexus, to improve cprop performance.
198 * Revision 1.12 2002/06/19 04:18:46 steve
199 * Shuffle link_drivers_constant for speed.
201 * Revision 1.11 2001/08/25 23:50:03 steve
202 * Change the NetAssign_ class to refer to the signal
203 * instead of link into the netlist. This is faster
204 * and uses less space. Make the NetAssignNB carry
205 * the delays instead of the NetAssign_ lval objects.
207 * Change the vvp code generator to support multiple
208 * l-values, i.e. concatenations of part selects.
210 * Revision 1.10 2001/07/25 03:10:49 steve
211 * Create a config.h.in file to hold all the config
212 * junk, and support gcc 3.0. (Stephan Boettcher)
214 * Revision 1.9 2001/07/07 03:01:37 steve
215 * Detect and make available to t-dll the right shift.
217 * Revision 1.8 2001/02/16 03:27:07 steve
218 * links to root inputs are not constant.
220 * Revision 1.7 2000/11/20 01:41:12 steve
221 * Whoops, return the calculated constant value rom driven_value.
223 * Revision 1.6 2000/11/20 00:58:40 steve
224 * Add support for supply nets (PR#17)
226 * Revision 1.5 2000/07/14 06:12:57 steve
227 * Move inital value handling from NetNet to Nexus
228 * objects. This allows better propogation of inital
229 * values.
231 * Clean up constant propagation a bit to account
232 * for regs that are not really values.
234 * Revision 1.4 2000/06/25 19:59:42 steve
235 * Redesign Links to include the Nexus class that
236 * carries properties of the connected set of links.
238 * Revision 1.3 2000/05/14 17:55:04 steve
239 * Support initialization of FF Q value.
241 * Revision 1.2 2000/05/07 04:37:56 steve
242 * Carry strength values from Verilog source to the
243 * pform and netlist for gates.
245 * Change vvm constants to use the driver_t to drive
246 * a constant value. This works better if there are
247 * multiple drivers on a signal.
249 * Revision 1.1 2000/04/20 00:28:03 steve
250 * Catch some simple identity compareoptimizations.