1 /*$Id: d_subckt.cc,v 26.138 2013/04/24 03:03:11 al Exp $ -*- C++ -*-
2 * Copyright (C) 2001 Albert Davis
3 * Author: Albert Davis <aldavis@gnu.org>
5 * This file is part of "Gnucap", the Gnu Circuit Analysis Package
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3, or (at your option)
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 *------------------------------------------------------------------
23 * base class for other elements using internal subckts
25 * device: Xxxxx <nodelist> <subckt-name> <args>
26 * model: .subckt <subckt-name> <nodelist>
30 * the .subckt always has a comment at the hook point, so a for loop works
31 * the expansion (attact to the X) has all comments removed
32 * - need to process the entire ring - for doesn't work
34 //testing=script 2006.07.17
37 /*--------------------------------------------------------------------------*/
38 int DEV_SUBCKT::_count
= -1;
39 int COMMON_SUBCKT::_count
= -1;
40 int MODEL_SUBCKT::_count
= -1;
41 static COMMON_SUBCKT
Default_SUBCKT(CC_STATIC
);
42 /*--------------------------------------------------------------------------*/
44 static MODEL_SUBCKT p2
;
45 static DISPATCHER
<CARD
>::INSTALL
46 d1(&device_dispatcher
, "X|dev_subckt", &p1
),
47 d2(&device_dispatcher
, "subckt|macro", &p2
);
48 /*--------------------------------------------------------------------------*/
49 bool COMMON_SUBCKT::operator==(const COMMON_COMPONENT
& x
)const
51 const COMMON_SUBCKT
* p
= dynamic_cast<const COMMON_SUBCKT
*>(&x
);
53 && _params
== p
->_params
54 && COMMON_COMPONENT::operator==(x
);
57 /*--------------------------------------------------------------------------*/
58 bool COMMON_SUBCKT::param_is_printable(int i
)const
60 assert(i
< COMMON_SUBCKT::param_count());
61 if (i
>= COMMON_COMPONENT::param_count()) {
62 return _params
.is_printable(COMMON_SUBCKT::param_count() - 1 - i
);
64 return COMMON_COMPONENT::param_is_printable(i
);
67 /*--------------------------------------------------------------------------*/
68 std::string
COMMON_SUBCKT::param_name(int i
)const
70 assert(i
< COMMON_SUBCKT::param_count());
71 if (i
>= COMMON_COMPONENT::param_count()) {
72 return _params
.name(COMMON_SUBCKT::param_count() - 1 - i
);
74 return COMMON_COMPONENT::param_name(i
);
77 /*--------------------------------------------------------------------------*/
78 std::string
COMMON_SUBCKT::param_name(int i
, int j
)const
80 assert(i
< COMMON_SUBCKT::param_count());
81 if (j
== 0) {untested();
83 }else if (i
>= COMMON_COMPONENT::param_count()) {untested();
86 return COMMON_COMPONENT::param_name(i
);
89 /*--------------------------------------------------------------------------*/
90 std::string
COMMON_SUBCKT::param_value(int i
)const
92 assert(i
< COMMON_SUBCKT::param_count());
93 if (i
>= COMMON_COMPONENT::param_count()) {
94 return _params
.value(COMMON_SUBCKT::param_count() - 1 - i
);
96 return COMMON_COMPONENT::param_value(i
);
99 /*--------------------------------------------------------------------------*/
100 void COMMON_SUBCKT::precalc_first(const CARD_LIST
* Scope
)
103 COMMON_COMPONENT::precalc_first(Scope
);
105 for (PARAM_LIST::iterator i
= _params
.begin(); i
!= _params
.end(); ++i
) {
106 i
->second
.e_val(NOT_INPUT
,Scope
);
108 _mfactor
= _params
.deep_lookup("m");
110 /*--------------------------------------------------------------------------*/
111 void COMMON_SUBCKT::precalc_last(const CARD_LIST
* Scope
)
114 COMMON_COMPONENT::precalc_last(Scope
);
116 /*--------------------------------------------------------------------------*/
117 MODEL_SUBCKT::MODEL_SUBCKT()
124 /*--------------------------------------------------------------------------*/
125 MODEL_SUBCKT::MODEL_SUBCKT(const MODEL_SUBCKT
& p
)
128 for (int ii
= 0; ii
< max_nodes(); ++ii
) {
129 _nodes
[ii
] = p
._nodes
[ii
];
132 assert(p
.subckt()->is_empty()); // incomplete, but enough for now.
136 /*--------------------------------------------------------------------------*/
137 MODEL_SUBCKT::~MODEL_SUBCKT()
141 /*--------------------------------------------------------------------------*/
142 CARD
* MODEL_SUBCKT::clone_instance()const
144 DEV_SUBCKT
* new_instance
= dynamic_cast<DEV_SUBCKT
*>(p1
.clone());
145 new_instance
->_parent
= this;
148 /*--------------------------------------------------------------------------*/
149 DEV_SUBCKT::DEV_SUBCKT()
153 attach_common(&Default_SUBCKT
);
157 /*--------------------------------------------------------------------------*/
158 DEV_SUBCKT::DEV_SUBCKT(const DEV_SUBCKT
& p
)
162 //strcpy(modelname, p.modelname); in common
163 for (int ii
= 0; ii
< max_nodes(); ++ii
) {
164 _nodes
[ii
] = p
._nodes
[ii
];
169 /*--------------------------------------------------------------------------*/
170 void DEV_SUBCKT::expand()
172 BASE_SUBCKT::expand();
173 COMMON_SUBCKT
* c
= prechecked_cast
<COMMON_SUBCKT
*>(mutable_common());
176 const CARD
* model
= find_looking_out(c
->modelname());
177 if(!dynamic_cast<const MODEL_SUBCKT
*>(model
)) {
178 throw Exception_Type_Mismatch(long_label(), c
->modelname(), "subckt");
180 _parent
= prechecked_cast
<const MODEL_SUBCKT
*>(model
);
183 assert(find_looking_out(c
->modelname()) == _parent
);
186 assert(_parent
->subckt());
187 assert(_parent
->subckt()->params());
188 PARAM_LIST
* pl
= const_cast<PARAM_LIST
*>(_parent
->subckt()->params());
190 c
->_params
.set_try_again(pl
);
192 renew_subckt(_parent
, this, scope(), &(c
->_params
));
195 /*--------------------------------------------------------------------------*/
196 void DEV_SUBCKT::precalc_first()
198 BASE_SUBCKT::precalc_first();
201 COMMON_SUBCKT
* c
= prechecked_cast
<COMMON_SUBCKT
*>(mutable_common());
203 subckt()->attach_params(&(c
->_params
), scope());
204 subckt()->precalc_first();
207 assert(!is_constant()); /* because I have more work to do */
209 /*--------------------------------------------------------------------------*/
210 void DEV_SUBCKT::precalc_last()
212 BASE_SUBCKT::precalc_last();
214 COMMON_SUBCKT
* c
= prechecked_cast
<COMMON_SUBCKT
*>(mutable_common());
216 subckt()->attach_params(&(c
->_params
), scope());
217 subckt()->precalc_last();
219 assert(!is_constant()); /* because I have more work to do */
221 /*--------------------------------------------------------------------------*/
222 double DEV_SUBCKT::tr_probe_num(const std::string
& x
)const
224 if (Umatch(x
, "p ")) {untested();
227 for (CARD_LIST::const_iterator
228 ci
= subckt()->begin(); ci
!= subckt()->end(); ++ci
) {untested();
229 power
+= CARD::probe(*ci
,"P");
232 }else if (Umatch(x
, "pd ")) {untested();
235 for (CARD_LIST::const_iterator
236 ci
= subckt()->begin(); ci
!= subckt()->end(); ++ci
) {untested();
237 power
+= CARD::probe(*ci
,"PD");
240 }else if (Umatch(x
, "ps ")) {untested();
243 for (CARD_LIST::const_iterator
244 ci
= subckt()->begin(); ci
!= subckt()->end(); ++ci
) {untested();
245 power
+= CARD::probe(*ci
,"PS");
249 return COMPONENT::tr_probe_num(x
);
253 /*--------------------------------------------------------------------------*/
254 /*--------------------------------------------------------------------------*/
255 // vim:ts=8:sw=2:noet: