3 * (c)2010 felix salfelder
7 // das ist die version, die es nicht geschafft hat, weil ein sprung in tau ist.
12 // #include "d_mos_base.h"
17 #include "d_rcd_sym_v2.h"
19 /*--------------------------------------------------------------------------*/
20 void MODEL_BUILT_IN_RCD_SYM_V2::do_stress_apply( COMPONENT
* ) const
24 /*--------------------------------------------------------------------------*/
25 void DEV_BUILT_IN_RCD_SYM_V2::tr_stress()
28 unreachable(); // obsolet....
30 const COMMON_BUILT_IN_RCD
* c
= static_cast<const COMMON_BUILT_IN_RCD
*>(common());
33 const MODEL_BUILT_IN_RCD
* m
= prechecked_cast
<const MODEL_BUILT_IN_RCD
*>(c
->model());
40 ///*--------------------------------------------------------------------------*/
41 namespace MODEL_BUILT_IN_RCD_DISPATCHER
43 static DEV_BUILT_IN_RCD_SYM_V2 p3d
;
44 static MODEL_BUILT_IN_RCD_SYM_V2
p3(&p3d
);
45 static DISPATCHER
<MODEL_CARD
>::INSTALL
46 d2(&model_dispatcher
, "rcdsym_v2", &p3
);
48 ///*--------------------------------------------------------------------------*/
49 void MODEL_BUILT_IN_RCD_SYM_V2::do_expand( COMPONENT
* c
) const
51 DEV_BUILT_IN_RCD_SYM_V2
* d
= dynamic_cast<DEV_BUILT_IN_RCD_SYM_V2
*>(c
);
56 /*--------------------------------------------------------------------------*/
57 std::string
MODEL_BUILT_IN_RCD_SYM_V2::dev_type()const
61 /*--------------------------------------------------------------------------*/
62 MODEL_BUILT_IN_RCD_SYM_V2::MODEL_BUILT_IN_RCD_SYM_V2(const BASE_SUBCKT
* p
)
63 : MODEL_BUILT_IN_RCD_SYM(p
)
67 /*--------------------------------------------------------------------------*/
68 MODEL_BUILT_IN_RCD_SYM_V2::MODEL_BUILT_IN_RCD_SYM_V2(const MODEL_BUILT_IN_RCD_SYM_V2
& p
)
69 : MODEL_BUILT_IN_RCD_SYM(p
)
73 /*--------------------------------------------------------------------------*/
74 void DEV_BUILT_IN_RCD_SYM_V2::expand()
78 const COMMON_BUILT_IN_RCD
* c
= static_cast<const COMMON_BUILT_IN_RCD
*>(common());
81 const MODEL_BUILT_IN_RCD
* m
= prechecked_cast
<const MODEL_BUILT_IN_RCD
*>(c
->model());
84 const SDP_BUILT_IN_RCD
* s
= prechecked_cast
<const SDP_BUILT_IN_RCD
*>(c
->sdp());
87 trace0("DEV_BUILT_IN_RCD_SYM_V2::expand()");
89 if (_sim
->is_first_expand()) {
93 //assert(!(_n[n_ic].n_()));
94 //BUG// this assert fails on a repeat elaboration after a change.
95 //not sure of consequences when new_model_node called twice.
97 if (!(_n
[n_ic
].n_())) {
101 _n
[n_ic
].new_model_node("." + long_label() + ".ic", this);
105 assert(_n
[n_ic
] == _n
[n_b
]);
107 //_n[n_ic].new_model_node("ic." + long_label(), this);
113 /*--------------------------------------------------------------------------*/
114 void MODEL_BUILT_IN_RCD_SYM_V2::do_tr_stress( const COMPONENT
* brh
) const
116 const MODEL_BUILT_IN_RCD_SYM_V2
* m
= this;
117 const DEV_BUILT_IN_RCD
* c
= (const DEV_BUILT_IN_RCD
*) brh
;
118 const COMMON_BUILT_IN_RCD
* cc
= static_cast<const COMMON_BUILT_IN_RCD
*>(c
->common());
119 //double fill = _n[n_ic].v0();
121 double fill
= c
->_Ccgfill
->get_total();
122 double uin
= c
->involts();
124 trace2("MODEL_BUILT_IN_RCD_SYM_V2::do_tr_stress ", fill
, uin
);
125 trace1("MODEL_BUILT_IN_RCD_SYM_V2::tr_stress ", c
->involts() );
127 if (fill
> 1.000001 ){
128 error(bDANGER
, " RCD_V2 fill %f too big\n", fill
);
133 if ( c
->_Ccgfill
->get_total() < 0 ){
134 trace1(("DEV_BUILT_IN_RCD_SYM_V2::tr_stress fill is negative: " +
135 short_label()).c_str() , c
->_Ccgfill
->get_total() );
137 if ( c
->involts() < -1e-10 ){
138 trace1(("DEV_BUILT_IN_RCD_SYM_V2::tr_stress input is negative: " +
139 short_label()).c_str() , c
->involts() );
143 assert(!m
->use_net());
145 //double fill = _n[n_ic].v0();
149 //trace3("DEV_BUILT_IN_RCD_SYM_V2::tr_stress ", _n[n_b].v0(), _n[n_u].v0(), _n[n_ic].v0() );
150 // use positive values for pmos
152 double h
= _sim
->_dt0
;
154 double tau_e_here
= m
->__Re( uin
, cc
);
155 double tau_c_here
= m
->__Rc( uin
, cc
);
157 double uend
=1/(1+tau_e_here
/tau_c_here
);
167 switch(_sim
->_stepno
){ incomplete();
171 newfill
= (fill
- uend
) * exp(-h
/tau
) + uend
;
178 trace4("DEV_BUILT_IN_RCD_SYM_V2::tr_stress ", tau_c_here
, tau_e_here
, _sim
->_Time0
, _sim
->_time0
);
179 trace6("DEV_BUILT_IN_RCD_SYM_V2::tr_stress ", fill
, h
, tau
, newfill
, uin
, uend
);
181 c
->_Ccgfill
->tr_add(newfill
-fill
);
182 trace4("DEV_BUILT_IN_RCD_SYM_V2::tr_stress ", fill
, h
, tau
, (newfill
-fill
)/h
);
183 assert(newfill
>= 0 );
185 if (newfill
> 1.000001 ){
186 error(bDANGER
, ("* RCD_V2 %f too big\n" + long_label() ).c_str() , newfill
);
189 assert(newfill
==newfill
);
192 /*--------------------------------------------------------------------------*/
193 /*--------------------------------------------------------------------------*/
194 double MODEL_BUILT_IN_RCD_SYM_V2::dvth(const COMPONENT
* brh
) const{
195 const DEV_BUILT_IN_RCD
* c
= prechecked_cast
<const DEV_BUILT_IN_RCD
*>(brh
);
196 const COMMON_BUILT_IN_RCD
* cc
= prechecked_cast
<const COMMON_BUILT_IN_RCD
*>(c
->common());
199 if (_sim
->analysis_is_tt()){
200 return (c
->_Ccgfill
->tt()+ cc
->_wcorr
)* cc
->_weight
;
202 assert(is_number( c
->_Ccgfill
->get_total()+ cc
->_wcorr
)* cc
->_weight
);
203 return (c
->_Ccgfill
->get_total()+ cc
->_wcorr
)* cc
->_weight
;
206 /*--------------------------------------------------------------------------*/
207 double MODEL_BUILT_IN_RCD_SYM_V2::__Re(double uin
, const COMMON_COMPONENT
* c
) const {
209 const COMMON_BUILT_IN_RCD
* cc
= dynamic_cast<const COMMON_BUILT_IN_RCD
*>(c
) ;
210 double Y
= cc
->Recommon0
* exp(cc
->Uref
* cc
->_lambda
) ;
211 trace2(" " , Y
, cc
->_Re0
);
212 assert( Y
= cc
->_Re0
);
213 return cc
->_Re0
/ exp( cc
->_lambda
* uin
);
215 /*--------------------------------------------------------------------------*/
216 double MODEL_BUILT_IN_RCD_SYM_V2::__Rc(double uin
, const COMMON_COMPONENT
* c
) const {
217 const COMMON_BUILT_IN_RCD
* cc
= dynamic_cast<const COMMON_BUILT_IN_RCD
*>(c
) ;
218 double X
= cc
->Rccommon0
;
219 return X
* exp( cc
->_lambda
* uin
);
221 /*--------------------------------------------------------------------------*/
222 double MODEL_BUILT_IN_RCD_SYM_V2::__Ge(double uin
, const COMMON_COMPONENT
* c
) const {
223 const COMMON_BUILT_IN_RCD
* cc
= dynamic_cast<const COMMON_BUILT_IN_RCD
*>(c
) ;
226 /*--------------------------------------------------------------------------*/
227 DEV_BUILT_IN_RCD_SYM_V2::DEV_BUILT_IN_RCD_SYM_V2()
228 :DEV_BUILT_IN_RCD() {
230 // attach_common(&Default_BUILT_IN_RCD);
235 /*--------------------------------------------------------------------------*/
236 int MODEL_BUILT_IN_RCD_SYM_V2::tt_region(const COMPONENT
* brh
) const{
237 const DEV_BUILT_IN_RCD
* c
= (const DEV_BUILT_IN_RCD
*) brh
;
240 return ( (c
->_Ccgfill
)->region() );
242 /*--------------------------------------------------------------------------*/
243 void MODEL_BUILT_IN_RCD_SYM_V2::do_precalc_last(COMMON_COMPONENT
* ccmp
, const CARD_LIST
*)const{
244 COMMON_BUILT_IN_RCD
* cc
= dynamic_cast<COMMON_BUILT_IN_RCD
*>(ccmp
);
245 const MODEL_BUILT_IN_RCD_SYM_V2
* m
=this;
247 cc
->_Rc0
= cc
->Rccommon0
;
249 cc
->X
= cc
->Rccommon0
;
250 cc
->_Re0
= cc
->Recommon0
* exp(cc
->Uref
* cc
->_lambda
) ;
252 double re_0
= m
->__Re(0.0,cc
);
253 double rc_0
= m
->__Rc(0.0,cc
);
254 double rc_uref
= m
->__Rc(cc
->Uref
,cc
);
255 double re_uref
= m
->__Re(cc
->Uref
,cc
);
257 double uend_uref
= (1 / ( re_uref
/ rc_uref
+1));
259 // vth(e ) = (e+_wcorr) * _wt
261 cc
->_wcorr
= - 1/ (1+re_0
/rc_0
);
262 cc
->_zero
= 1/ (1+re_0
/rc_0
);
264 // vth(e(uref))=! Uref*weight
265 // vth( uend_uref ) = ( uend_uref+_wcorr ) * wt;
266 cc
->_weight
= cc
->weight
* cc
->Uref
/ ( uend_uref
+cc
->_wcorr
);
268 //double test = ( rc / ( 1+rc*ge ) ) ;
270 //trace6("COMMON_BUILT_IN_RCD::precalc_last v2", Recommon, Rccommon0, rc, X, _wcorr, test);
271 trace6("MODEL_BUILT_IN_RCD_SYM_V2::do_precalc_last" , uend_uref
, cc
->weight
, cc
->_weight
, re_0
, re_uref
, m
->uref
);
272 trace2("MODEL_BUILT_IN_RCD_SYM_V2::do_precalc_last", re_0
, re_uref
);
273 trace5("MODEL_BUILT_IN_RCD_SYM_V2::do_precalc_last", rc_0
, rc_uref
, cc
->Recommon0
, cc
->__Re(cc
->Uref
), cc
->Uref
);
274 assert(rc_0
<= rc_uref
); // incresging...
275 assert(re_0
>= re_uref
); // decreasing...
276 assert( fabs(cc
->Recommon0
- cc
->__Re(cc
->Uref
))/cc
->Recommon0
< 1e-12);
277 assert( abs(cc
->Uref
*cc
->weight
- (uend_uref
+ cc
->_wcorr
) * cc
->_weight
) < 1e-12);
280 /*--------------------------------------------------------------------------*/
281 //ADP_NODE_RCD* MODEL_BUILT_IN_RCD_SYM_V2::new_adp_node(const COMPONENT* c) const{
282 // return new ADP_NODE_RCD(c);