#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "boost_mpl_string.h" #define __NODE__(a) B4##a##Node typedef enum { __NODE__(d), __NODE__(g), __NODE__(s), __NODE__(b), __NODE__(gnd), __NODE__(dp), __NODE__(gp), __NODE__(gp1), __NODE__(sp), __NODE__(bp), __NODE__(bps), __NODE__(bpd), __NODE__(qn), TotalNodes } BSIM4_PinNumbers ; typedef boost::mpl::set< boost::mpl::integral_c, boost::mpl::integral_c >::type VGS; // base nlctrlv T_VBS (bp, sp) { }; typedef boost::mpl::set< boost::mpl::integral_c, boost::mpl::integral_c >::type VBS; // base nlctrlv T_VDS (dp, sp) { }; typedef boost::mpl::set< boost::mpl::integral_c, boost::mpl::integral_c >::type VDS; // base nlctrlv T_VDDP (d, dp) { }; // for drain resistors typedef boost::mpl::set< boost::mpl::integral_c, boost::mpl::integral_c >::type VDDP; // base nlctrlv T_VSSP (s, sp) { }; // for source resistors typedef boost::mpl::set< boost::mpl::integral_c, boost::mpl::integral_c >::type VSSP; // base nlctrlv T_VBPS (bps, sp) { }; // for source diode typedef boost::mpl::set< boost::mpl::integral_c, boost::mpl::integral_c >::type VBPS; // base nlctrlv T_VBPD (bpd, dp) { }; // for drain diode typedef boost::mpl::set< boost::mpl::integral_c, boost::mpl::integral_c >::type VBPD; // base nlctrlv T_VGMGP (gp1, gp) { }; // for gate resistor when caps are moved typedef boost::mpl::set< boost::mpl::integral_c, boost::mpl::integral_c >::type VGMG; // base nlctrlv T_QDEF (qn,0) { }; typedef boost::mpl::set< boost::mpl::integral_c >::type QDEF; // base nlcs idp (dp, 0) { active_in_stab=1, control_ref = [ VGS, VBS, VDS, QDEF] }; typedef boost::mpl::vector< boost::mpl::set< boost::mpl::integral_c >::type, boost::mpl::set::type, boost::mpl::bool_ >::type IDP; // base nlcs isp (sp, 0) { active_in_stab=1, control_ref = [ VGS, VBS, VDS, QDEF] }; typedef boost::mpl::vector< boost::mpl::set< boost::mpl::integral_c >::type, boost::mpl::set::type, boost::mpl::bool_ >::type ISP; // base nlcs igp (gp, 0) { control_ref = [ VGS, VBS, VDS, QDEF] }; typedef boost::mpl::vector< boost::mpl::set< boost::mpl::integral_c >::type, boost::mpl::set::type, boost::mpl::bool_ >::type IGP; // base nlcs ibp (bp, 0) { control_ref = [ VGS, VBS, VDS] }; typedef boost::mpl::vector< boost::mpl::set< boost::mpl::integral_c >::type, boost::mpl::set::type, boost::mpl::bool_ >::type IBP; //base nlcs ibps (bps, sp) { control_ref = [VBS, VBPS] }; typedef boost::mpl::vector< boost::mpl::set< boost::mpl::integral_c, boost::mpl::integral_c >::type, boost::mpl::set::type, boost::mpl::bool_ >::type IBPS; // base nlcs ibpd (bpd, dp) { control_ref = [VBS,VDS, VBPD] }; typedef boost::mpl::vector< boost::mpl::set< boost::mpl::integral_c, boost::mpl::integral_c >::type, boost::mpl::set::type, boost::mpl::bool_ >::type IBPD; // base nlcs isbias_dep (s, sp) { control_ref = [ VGS, VBS,VSSP] }; typedef boost::mpl::vector< boost::mpl::set< boost::mpl::integral_c, boost::mpl::integral_c >::type, boost::mpl::set::type, boost::mpl::bool_ >::type ISBIAS_DEP; // base nlcs idbias_dep (d, dp) { control_ref = [ VGS, VBS,VDS,VDDP] }; typedef boost::mpl::vector< boost::mpl::set< boost::mpl::integral_c, boost::mpl::integral_c >::type, boost::mpl::set::type, boost::mpl::bool_ >::type IDBIAS_DEP; // lumped g ig_eltd_g (g, gp1) { g=GATEvalue, addnoise = 0, hard_cut = HARD_CUT_RGATEMOD02 }; typedef boost::mpl::set< boost::mpl::integral_c, boost::mpl::integral_c >::type VGGP1; typedef boost::mpl::vector< boost::mpl::set< boost::mpl::integral_c, boost::mpl::integral_c >::type, boost::mpl::set::type, boost::mpl::bool_ >::type IG_ELTD_G; // base nlcs ig_eltd (gp1, gp) { control_ref = [ VGS, VBS, VDS, VGMG] }; typedef boost::mpl::vector< boost::mpl::set< boost::mpl::integral_c, boost::mpl::integral_c >::type, boost::mpl::set::type, boost::mpl::bool_ >::type IG_ELTD; // base nlqs qmid (gp1, sp) { control_ref = [ VGMG,VGS,VDS, VBS ] }; typedef boost::mpl::vector< boost::mpl::set< boost::mpl::integral_c, boost::mpl::integral_c >::type, boost::mpl::set::type, boost::mpl::bool_ >::type QMID; // lumped g RBPS (bp, bps) { g = GRBPSvalue, addnoise = OHMIC_NOISE, hard_cut = HARD_CUT_RSUBMOD }; typedef boost::mpl::set< boost::mpl::integral_c, boost::mpl::integral_c >::type VBPBPS; typedef boost::mpl::vector< boost::mpl::set< boost::mpl::integral_c, boost::mpl::integral_c >::type, boost::mpl::set::type, boost::mpl::bool_ >::type RBPS; // lumped g RBPD (bp, bpd) { g = GRBPDvalue, addnoise = OHMIC_NOISE, hard_cut = HARD_CUT_RSUBMOD }; typedef boost::mpl::set< boost::mpl::integral_c, boost::mpl::integral_c >::type VBPBPD; typedef boost::mpl::vector< boost::mpl::set< boost::mpl::integral_c, boost::mpl::integral_c >::type, boost::mpl::set::type, boost::mpl::bool_ >::type RBPD; // lumped g RBSB (bps, b) { g = GRBSBvalue, addnoise = OHMIC_NOISE }; typedef boost::mpl::set< boost::mpl::integral_c, boost::mpl::integral_c >::type VBPSB; typedef boost::mpl::vector< boost::mpl::set< boost::mpl::integral_c, boost::mpl::integral_c >::type, boost::mpl::set::type, boost::mpl::bool_ >::type RBSB; // lumped g RBDB (bpd, b) { g = GRBDBvalue, addnoise = OHMIC_NOISE }; typedef boost::mpl::set< boost::mpl::integral_c, boost::mpl::integral_c >::type VBPDB; typedef boost::mpl::vector< boost::mpl::set< boost::mpl::integral_c, boost::mpl::integral_c >::type, boost::mpl::set::type, boost::mpl::bool_ >::type RBDB; // lumped g RBPB (bp, b) { g = GRBPBvalue, addnoise = OHMIC_NOISE, hard_cut = HARD_CUT_RSUBMOD }; typedef boost::mpl::set< boost::mpl::integral_c, boost::mpl::integral_c >::type VBPB; typedef boost::mpl::vector< boost::mpl::set< boost::mpl::integral_c, boost::mpl::integral_c >::type, boost::mpl::set::type, boost::mpl::bool_ >::type RBPB; // // base nlqs qg (gp, sp) { control_ref = [ VGS, VBS, VDS] }; typedef boost::mpl::vector< boost::mpl::set< boost::mpl::integral_c, boost::mpl::integral_c >::type, boost::mpl::set::type, boost::mpl::bool_ >::type QG; // base nlqs qd (dp, sp) { control_ref = [ VGS, VBS, VDS,VGMG] }; typedef boost::mpl::vector< boost::mpl::set< boost::mpl::integral_c, boost::mpl::integral_c >::type, boost::mpl::set::type, boost::mpl::bool_ >::type QD; // base nlqs qb (bp, sp) { control_ref = [ VGS, VBS, VDS,VGMG] }; typedef boost::mpl::vector< boost::mpl::set< boost::mpl::integral_c, boost::mpl::integral_c >::type, boost::mpl::set::type, boost::mpl::bool_ >::type QB; // base nlqs qbs (bps, sp) { control_ref = [ VBPS ] }; typedef boost::mpl::vector< boost::mpl::set< boost::mpl::integral_c, boost::mpl::integral_c >::type, boost::mpl::set::type, boost::mpl::bool_ >::type QBS; // base nlqs qbd (bpd, dp) { control_ref = [ VBPD ] }; typedef boost::mpl::vector< boost::mpl::set< boost::mpl::integral_c, boost::mpl::integral_c >::type, boost::mpl::set::type, boost::mpl::bool_ >::type QBD; // lumped c cdum (qn,0) { c=CNQS} ; // for ddt(QDEF) typedef boost::mpl::vector< boost::mpl::set< boost::mpl::integral_c >::type, boost::mpl::set::type, boost::mpl::bool_ >::type CDUM; // base nlqs qnqs (qn,0) { control_ref = [ VGS, VBS, VDS] }; // for -ddt(Qchn) typedef boost::mpl::vector< boost::mpl::set< boost::mpl::integral_c >::type, boost::mpl::set::type, boost::mpl::bool_ >::type QNQS; // base nlcs rnqs (qn,0) {control_ref=[ VGS, VBS, VDS, QDEF] }; // for QDEF/TAU typedef boost::mpl::vector< boost::mpl::set< boost::mpl::integral_c >::type, boost::mpl::set::type, boost::mpl::bool_ >::type RNQS; typedef boost::mpl::set< IDP, ISP, IGP, IBP, IBPS, IBPD, ISBIAS_DEP, IDBIAS_DEP, IG_ELTD_G, IG_ELTD, RBPS, RBPD, RBSB, RBDB, RBPB, RNQS >::type NONLINEAR_CURRENTS; typedef boost::mpl::set< QMID, QG, QD, QB, QBS, QBD, CDUM, QNQS >::type NONLINEAR_CHARGES; template struct CGetSecond { typedef typename __PAIR__::second type; }; template struct CGetFirst { typedef typename __PAIR__::first type; }; template struct CConvertIntoArray { typedef typename boost::mpl::accumulate< __MAP__, typename boost::mpl::vector<>::type, typename boost::mpl::lambda< boost::mpl::push_back< boost::mpl::_1, boost::mpl::_2 > >::type >::type type; }; // creates a map of index to bool=false template struct CCreateBoolVector { typedef typename boost::mpl::accumulate< typename boost::mpl::range_c< long, 0, __NUMBER_OF_NODES__::value >::type, typename boost::mpl::map<>::type, typename boost::mpl::lambda< boost::mpl::insert< boost::mpl::_1, boost::mpl::pair< boost::mpl::_2, boost::mpl::bool_ > > >::type >::type type; }; // sets the entry for the node voltage to true template struct CForeachVoltage { typedef typename boost::mpl::accumulate< __VOLTAGE__, __BV__, typename boost::mpl::lambda< boost::mpl::insert< boost::mpl::_1, boost::mpl::pair< boost::mpl::_2, boost::mpl::bool_ > > >::type >::type type; }; // iterates over all the controls and sets the bool entries to true for the matching node voltage template struct CForeachControl { typedef typename boost::mpl::accumulate< typename boost::mpl::at<__SOURCE__, boost::mpl::integral_c >::type, typename CCreateBoolVector<__NUMBER_OF_NODES__>::type, typename boost::mpl::lambda< CForeachVoltage >::type >::type type; }; // two dimensional set template struct CInsert2 { BOOST_MPL_ASSERT(( boost::mpl::is_sequence<__MATRIX__> )); BOOST_MPL_ASSERT(( boost::mpl::equal< boost::mpl::size<__MATRIX__>, __NUMBER_OF_NODES__ >)); typedef typename boost::mpl::insert< typename boost::mpl::erase_key< __MATRIX__, __IX__ >::type, boost::mpl::pair< __IX__, typename boost::mpl::insert< typename boost::mpl::erase_key< typename boost::mpl::at< __MATRIX__, __IX__ >::type, __IY__ >::type, boost::mpl::pair< __IY__, __E__ > >::type > >::type type; BOOST_MPL_ASSERT(( boost::mpl::is_sequence )); BOOST_MPL_ASSERT(( boost::mpl::equal< boost::mpl::size, __NUMBER_OF_NODES__ >)); }; // set characters in two dimensional matrix template struct CReplaceMatrix { BOOST_MPL_ASSERT(( boost::mpl::is_sequence<__MAP__> )); BOOST_MPL_ASSERT(( boost::mpl::equal< boost::mpl::size<__MAP__>, __NUMBER_OF_NODES__ >)); typedef typename boost::mpl::at< __MAP__, __NODE__ >::type CNodeMap; BOOST_MPL_ASSERT(( boost::mpl::is_sequence )); BOOST_MPL_ASSERT(( boost::mpl::equal< boost::mpl::size, __NUMBER_OF_NODES__ >)); typedef typename boost::mpl::if_< typename boost::mpl::at< typename CForeachControl<__SOURCE__, __NUMBER_OF_NODES__>::type, __I__ >::type, typename boost::mpl::if_< typename boost::mpl::at<__SOURCE__, boost::mpl::integral_c >::type, typename CInsert2<__NODE__, __I__, __MAP__, boost::mpl::char_<'2'>, __NUMBER_OF_NODES__>::type, typename boost::mpl::if_< typename boost::mpl::equal_to< typename boost::mpl::at< CNodeMap, __I__ >::type, boost::mpl::char_<'2'> >::type, __MAP__, typename CInsert2< __NODE__, __I__, __MAP__, boost::mpl::char_<'1'>, __NUMBER_OF_NODES__ >::type >::type >::type, __MAP__ >::type type; BOOST_MPL_ASSERT(( boost::mpl::is_sequence )); BOOST_MPL_ASSERT(( boost::mpl::equal< boost::mpl::size, __NUMBER_OF_NODES__ >)); }; template struct CCreateEmptyString { typedef typename boost::mpl::accumulate< typename boost::mpl::range_c< long, 0, __NUMBER_OF_NODES__::value >::type, typename boost::mpl::map<>::type, typename boost::mpl::lambda< boost::mpl::insert< boost::mpl::_1, boost::mpl::pair< boost::mpl::_2, boost::mpl::char_<'.'> > > >::type >::type type; BOOST_MPL_ASSERT(( boost::mpl::is_sequence )); BOOST_MPL_ASSERT(( boost::mpl::equal< boost::mpl::size, __NUMBER_OF_NODES__ >)); }; template struct CCheckSubMap { typedef typename __PAIR__::second second; typedef __PAIR__ type; BOOST_MPL_ASSERT(( boost::mpl::is_sequence )); BOOST_MPL_ASSERT(( boost::mpl::equal< boost::mpl::size, __NUMBER_OF_NODES__ >)); }; template struct CCheckSubMaps { typedef typename boost::mpl::accumulate< __MAP__, boost::mpl::map<>, typename boost::mpl::lambda< boost::mpl::insert< boost::mpl::_1, CCheckSubMap > >::type >::type type; }; template struct CCreateMap { typedef typename CCreateEmptyString<__NUMBER_OF_NODES__>::type item; typedef typename boost::mpl::accumulate< typename boost::mpl::range_c< long, 0, __NUMBER_OF_NODES__::value >::type, typename boost::mpl::map<>::type, typename boost::mpl::lambda< boost::mpl::insert< boost::mpl::_1, boost::mpl::pair< boost::mpl::_2, item > > >::type >::type type; BOOST_MPL_ASSERT(( boost::mpl::is_sequence )); BOOST_MPL_ASSERT(( boost::mpl::equal< boost::mpl::size, __NUMBER_OF_NODES__ >)); typedef typename boost::mpl::at< type, boost::mpl::integral_c >::type CNodeMap; BOOST_MPL_ASSERT(( boost::mpl::is_sequence )); BOOST_MPL_ASSERT(( boost::mpl::equal< boost::mpl::size, __NUMBER_OF_NODES__ >)); /* typedef typename CCheckSubMaps::type check; BOOST_MPL_ASSERT(( boost::mpl::is_sequence )); BOOST_MPL_ASSERT(( boost::mpl::equal< boost::mpl::size, __NUMBER_OF_NODES__ >)); */ }; template struct CForThisNode { BOOST_MPL_ASSERT(( boost::mpl::is_sequence<__MAP__> )); BOOST_MPL_ASSERT(( boost::mpl::equal< boost::mpl::size<__MAP__>, __NUMBER_OF_NODES__ >)); /* void operator()(boost::mpl::integral_c) { for (size_t i = 0; i < __NUMBER_OF_NODES__; ++i) if (m_rV[i]) if (m_bNL) (*m_pap)[__NODE__][i] = '2'; else if ((*m_pap)[__NODE__][i] == '2') ; else (*m_pap)[__NODE__][i] = '1'; } */ typedef typename boost::mpl::at< __MAP__, __NODE__ >::type CNodeMap; BOOST_MPL_ASSERT(( boost::mpl::is_sequence )); BOOST_MPL_ASSERT(( boost::mpl::equal< boost::mpl::size, __NUMBER_OF_NODES__ >)); typedef typename boost::mpl::accumulate< typename boost::mpl::range_c< long, 0, __NUMBER_OF_NODES__::value >::type, __MAP__, typename boost::mpl::lambda< CReplaceMatrix<__NODE__, __SOURCE__, boost::mpl::_1, __NUMBER_OF_NODES__, boost::mpl::_2> >::type >::type type; BOOST_MPL_ASSERT(( boost::mpl::is_sequence )); BOOST_MPL_ASSERT(( boost::mpl::equal< boost::mpl::size, __NUMBER_OF_NODES__ >)); typedef typename boost::mpl::at< type, __NODE__ >::type CNodeMap1; BOOST_MPL_ASSERT(( boost::mpl::is_sequence )); BOOST_MPL_ASSERT(( boost::mpl::equal< boost::mpl::size, __NUMBER_OF_NODES__ >)); }; template struct CForOneSource { BOOST_MPL_ASSERT(( boost::mpl::is_sequence<__MAP__> )); BOOST_MPL_ASSERT(( boost::mpl::equal< boost::mpl::size<__MAP__>, __NUMBER_OF_NODES__ >)); typedef typename boost::mpl::accumulate< // for every node typename boost::mpl::at<__SOURCE__, boost::mpl::integral_c >::type, __MAP__, typename boost::mpl::lambda< CForThisNode< boost::mpl::_2, // node __SOURCE__, boost::mpl::_1, // map //typename boost::mpl::at<__SOURCE__, typename boost::mpl::integral_c >, __NUMBER_OF_NODES__ > >::type >::type type; BOOST_MPL_ASSERT(( boost::mpl::is_sequence )); BOOST_MPL_ASSERT(( boost::mpl::equal< boost::mpl::size, __NUMBER_OF_NODES__ >)); }; template struct CForAllSources { typedef typename boost::mpl::accumulate< __NL__, typename CCreateMap<__NUMBER_OF_NODES__>::type, typename boost::mpl::lambda< CForOneSource >::type >::type type; BOOST_MPL_ASSERT(( boost::mpl::is_sequence )); }; template struct push_back_second { typedef typename boost::mpl::push_back::type type; }; template struct CConvertIntoString { typedef typename boost::mpl::accumulate< __MAP__, boost::mpl::string<>, typename boost::mpl::lambda< boost::mpl::push_back< boost::mpl::_1, CGetSecond > >::type >::type type; }; //0123456789abc template struct CCreateArray { static const char *ap[__NUMBER_OF_NODES__::value]; struct CForeach { template void operator()(T) { ap[T::first::value] = CConvertIntoString::type::c_str; } }; const char *const *operator()(void) const { if (!ap[0]) boost::mpl::for_each<__MAP__>(CForeach()); return ap; } }; typedef CCreateArray< CForAllSources< NONLINEAR_CURRENTS, boost::mpl::integral_c >::type, boost::mpl::integral_c >::type_info CCurrents; typedef CCreateArray< CForAllSources< NONLINEAR_CHARGES, boost::mpl::integral_c >::type, boost::mpl::integral_c >::type_info CCharges; const char *CCurrents::ap[]; const char *CCharges::ap[]; static const char *const *const s_apCurrents = CCurrents()(); static const char *const *const s_apCharges = CCharges()(); #include int main(int argc, char **argv) { for (const char *const *p = s_apCurrents; p != s_apCurrents + TotalNodes; ++p) std::cout << *p << std::endl; return 0; }