Previous 199869 Revisions Next

r26578 Tuesday 10th December, 2013 at 19:14:05 UTC by Couriersud
Netlist:
- changed netlist_matrix_solver to be a class
- rewrote the "switch" BJT implementation
- minor bugfixes
[src/emu/netlist]nl_base.c nl_base.h
[src/emu/netlist/devices]nld_system.c nld_system.h nld_twoterm.c nld_twoterm.h

trunk/src/emu/netlist/nl_base.c
r26577r26578
552552
553553ATTR_COLD double netlist_param_multi_t::dValue(const pstring &entity, const double defval) const
554554{
555    pstring tmp = this->Value().ucase();
555    pstring tmp = this->Value();
556556    // .model 1N914 D(Is=2.52n Rs=.568 N=1.752 Cjo=4p M=.4 tt=20n Iave=200m Vpk=75 mfg=OnSemi type=silicon)
557    int p = tmp.find(entity.ucase() + "=");
557    int p = tmp.ucase().find(entity.ucase() + "=");
558558    if (p>=0)
559559    {
560560        int pblank = tmp.find(" ", p);
trunk/src/emu/netlist/nl_base.h
r26577r26578
188188#define NETLIB_FUNC_VOID(_chip, _name, _params) ATTR_HOT ATTR_ALIGN void NETLIB_NAME(_chip) :: _name _params
189189
190190#define NETLIB_UPDATE_TERMINALS() ATTR_HOT ATTR_ALIGN inline void update_terminals(void)
191#define NETLIB_UPDATEI() ATTR_HOT ATTR_ALIGN inline void update(void)
191192
192193#define NETLIB_DEVICE_BASE(_name, _pclass, _extra, _priv)                           \
193194    class _name : public _pclass                                                    \
trunk/src/emu/netlist/devices/nld_system.c
r26577r26578
103103                                m_steps.add(&p->netdev());
104104                            break;
105105                        case netlist_device_t::DIODE:
106                        case netlist_device_t::BJT_SWITCH:
106                        //case netlist_device_t::BJT_SWITCH:
107107                            if (!m_dynamic.contains(&p->netdev()))
108108                                m_dynamic.add(&p->netdev());
109109                            break;
r26577r26578
154154
155155        double gtot = 0;
156156        double iIdr = 0;
157
158        for (netlist_net_t::terminal_list_t::entry_t *e = net->m_terms.first(); e != NULL; e = net->m_terms.next(e))
157        const netlist_net_t::terminal_list_t &terms = net->m_terms;
158#if 1
159        switch (terms.count())
159160        {
161            case 1:
162                {
163                    const netlist_terminal_t *pt = terms.first()->object();
164                    gtot = pt->m_g;
165                    iIdr = pt->m_Idr + pt->m_g * pt->m_otherterm->net().Q_Analog();
166                }
167                break;
168            case 2:
169                {
170                    const netlist_terminal_t *pt1 = terms.first()->object();
171                    const netlist_terminal_t *pt2 = terms.item(1)->object();
172                    gtot = pt1->m_g + pt2->m_g;
173                    iIdr = pt1->m_Idr + pt1->m_g * pt1->m_otherterm->net().Q_Analog()
174                         + pt2->m_Idr + pt2->m_g * pt2->m_otherterm->net().Q_Analog();
175                }
176                break;
177            case 3:
178                {
179                    const netlist_terminal_t *pt1 = terms.first()->object();
180                    const netlist_terminal_t *pt2 = terms.item(1)->object();
181                    const netlist_terminal_t *pt3 = terms.item(2)->object();
182                    gtot = pt1->m_g + pt2->m_g + pt3->m_g;
183                    iIdr = pt1->m_Idr + pt1->m_g * pt1->m_otherterm->net().Q_Analog()
184                         + pt2->m_Idr + pt2->m_g * pt2->m_otherterm->net().Q_Analog()
185                         + pt3->m_Idr + pt3->m_g * pt3->m_otherterm->net().Q_Analog();
186                }
187                break;
188            default:
189                for (netlist_net_t::terminal_list_t::entry_t *e = terms.first(); e != NULL; e = terms.next(e))
190                {
191                    netlist_terminal_t *pt = e->object();
192                    gtot += pt->m_g;
193                    iIdr += pt->m_Idr + pt->m_g * pt->m_otherterm->net().Q_Analog();
194                }
195                break;
196        }
197#else
198        for (netlist_net_t::terminal_list_t::entry_t *e = terms.first(); e != NULL; e = terms.next(e))
199        {
160200            netlist_terminal_t *pt = e->object();
161201            gtot += pt->m_g;
162202            iIdr += pt->m_Idr + pt->m_g * pt->m_otherterm->net().Q_Analog();
163203        }
164
204#endif
165205        double new_val = iIdr / gtot;
166206        if (fabs(new_val - net->m_cur.Analog) > m_accuracy)
167207            resched = true;
r26577r26578
282322            process_net(groups, cur_group, pn->object());
283323        }
284324    }
285    printf("Found %d net groups in %d nets\n", cur_group + 1, m_nets.count());
286    for (int i = 0; i <= cur_group; i++)
287    {
288        printf("%d ==> %d nets %s\n", i, groups[i].count(), groups[i].first()->object()->m_head->name().cstr());
289    }
290325
291
292326    // setup the solvers
327    printf("Found %d net groups in %d nets\n", cur_group + 1, m_nets.count());
293328    for (int i = 0; i <= cur_group; i++)
294329    {
295330        netlist_matrix_solver_t *ms = new netlist_matrix_solver_t;
296331        ms->m_accuracy = m_accuracy.Value();
297332        ms->setup(groups[i]);
298333        m_mat_solvers.add(ms);
334        printf("%d ==> %d nets %s\n", i, groups[i].count(), groups[i].first()->object()->m_head->name().cstr());
335        printf("  has %s elements\n", ms->is_dynamic() ? "dynamic" : "no dynamic");
299336    }
300337
301338}
r26577r26578
323360    bool global_resched = false;
324361    for (netlist_matrix_solver_t::list_t::entry_t *e = m_mat_solvers.first(); e != NULL; e = m_mat_solvers.next(e))
325362    {
326        resched_cnt = 0;
363        resched_cnt = (e->object()->is_dynamic() ? 0 : 1);
327364        do {
328365            resched = e->object()->solve();
329366            resched_cnt++;
330        } while (resched && (resched_cnt < 5));
367        } while ((resched && (resched_cnt < 5)) || (resched_cnt <= 1));
331368        global_resched = global_resched || resched;
332369    }
333370    if (global_resched)
trunk/src/emu/netlist/devices/nld_system.h
r26577r26578
7979// solver
8080// ----------------------------------------------------------------------------------------
8181
82struct netlist_matrix_solver_t
82class netlist_matrix_solver_t
8383{
84public:
8485    typedef netlist_list_t<netlist_matrix_solver_t *> list_t;
8586    typedef netlist_core_device_t::list_t dev_list_t;
8687    ATTR_COLD void setup(netlist_net_t::list_t &nets);
r26577r26578
9091    ATTR_HOT void step(const netlist_time delta);
9192    ATTR_HOT void update_inputs();
9293
94    ATTR_HOT inline bool is_dynamic() { return m_dynamic.count() > 0; }
95
9396    double m_accuracy;
9497
9598private:
trunk/src/emu/netlist/devices/nld_twoterm.c
r26577r26578
3636    register_terminal("1", m_P);
3737    register_terminal("2", m_N);
3838
39    register_param("R", m_R, NETLIST_GMIN);
39    register_param("R", m_R, 1.0 / NETLIST_GMIN);
4040}
4141
4242NETLIB_UPDATE_PARAM(R)
r26577r26578
5858    register_terminal("1", m_P);
5959    register_terminal("2", m_N);
6060
61    register_param("C", m_C, NETLIST_GMIN);
61    register_param("C", m_C, 1e-6);
6262}
6363
6464NETLIB_UPDATE_PARAM(C)
r26577r26578
9595    m_Vcrit = m_Vt * log(m_Vt / m_Is / sqrt(2.0));
9696    m_VtInv = 1.0 / m_Vt;
9797    NL_VERBOSE_OUT(("VCutoff: %f\n", m_Vcrit));
98    printf("VCutoff: %f %f\n", m_Vcrit, m_Is);
9899}
99100
100101NETLIB_UPDATE(D)
r26577r26578
138139    register_param("model", m_model, "");
139140}
140141
141NETLIB_START(QBJT)
142template <NETLIB_NAME(Q)::q_type _type>
143NETLIB_START(QBJT_switch<_type>)
142144{
143145    NETLIB_NAME(Q)::start();
144146
145    register_terminal("B", m_B);
146    register_terminal("C", m_C);
147    register_terminal("E", m_E);
148    register_terminal("EB", m_EB);
147    register_sub(m_RB, "RB");
148    register_sub(m_RC, "RC");
149    register_input("BV", m_BV);
150    register_input("EV", m_EV);
149151
150    m_setup->connect(m_E, m_EB);
152    register_subalias("B", m_RB.m_P);
153    register_subalias("E", m_RB.m_N);
154    register_subalias("C", m_RC.m_P);
151155
152    m_B.m_otherterm = &m_EB;
153    m_EB.m_otherterm = &m_B;
154    m_C.m_otherterm = &m_E;
155    m_E.m_otherterm = &m_C;
156    m_setup->connect(m_RB.m_N, m_RC.m_N);
157    m_setup->connect(m_RB.m_P, m_BV);
158    m_setup->connect(m_RB.m_N, m_EV);
156159}
157160
158161NETLIB_UPDATE(Q)
r26577r26578
184187        m_gB = NETLIST_GMIN;
185188    m_gC = BF * m_gB; // very rough estimate
186189    printf("%f %f \n", m_V, m_gB);
190    m_RB.set(NETLIST_GMIN, 0.0, 0.0);
191    m_RC.set(NETLIST_GMIN, 0.0, 0.0);
187192}
188193
194template NETLIB_START(QBJT_switch<NETLIB_NAME(Q)::BJT_NPN>);
195template NETLIB_START(QBJT_switch<NETLIB_NAME(Q)::BJT_PNP>);
189196template NETLIB_UPDATE_PARAM(QBJT_switch<NETLIB_NAME(Q)::BJT_NPN>);
190197template NETLIB_UPDATE_PARAM(QBJT_switch<NETLIB_NAME(Q)::BJT_PNP>);
trunk/src/emu/netlist/devices/nld_twoterm.h
r26577r26578
230230    ATTR_COLD NETLIB_NAME(QBJT)(const q_type atype, const family_t afamily)
231231    : NETLIB_NAME(Q)(atype, afamily) { }
232232
233    netlist_terminal_t m_B;
234    netlist_terminal_t m_C;
235    netlist_terminal_t m_E;
236
237    netlist_terminal_t m_EB;
238
239233protected:
240    ATTR_COLD virtual void start();
241234
242235private:
243236};
r26577r26578
248241{
249242public:
250243    ATTR_COLD NETLIB_NAME(QBJT_switch)()
251    : NETLIB_NAME(QBJT)(_type, BJT_SWITCH), m_gB(NETLIST_GMIN), m_gC(NETLIST_GMIN), m_V(0.0) { }
244    : NETLIB_NAME(QBJT)(_type, BJT_SWITCH), m_gB(NETLIST_GMIN), m_gC(NETLIST_GMIN), m_V(0.0), m_state_on(0) { }
252245
253    NETLIB_UPDATE_TERMINALS()
246#if 1
247    NETLIB_UPDATEI()
254248    {
255        double gb = m_gB;
256        double gc = m_gC;
257        double v  = m_V;
258        double vE = m_E.net().Q_Analog();
259        double vB = m_B.net().Q_Analog();
249        double vE = INPANALOG(m_EV);
250        double vB = INPANALOG(m_BV);
260251
261        //printf("diff %f = %f - %f\n", vB - vE, vB, vE);
262        if (vB - vE < m_V )
252        //printf("diff %f %f = %f - %f\n", vB - vE, vB, vE, m_RB.m_N.m_g);
253        int new_state = (vB - vE > m_V ) ? 1 : 0;
254        if (m_state_on ^ new_state)
263255        {
264            // not conducting
265            gb = NETLIST_GMIN;
266            v = 0;
267            gc = NETLIST_GMIN;
256            double gb = m_gB;
257            double gc = m_gC;
258            double v  = m_V;
259            if (!new_state )
260            {
261                // not conducting
262                gb = NETLIST_GMIN;
263                v = 0;
264                gc = NETLIST_GMIN;
265            }
266            m_RB.set(gb, v,   0.0);
267            m_RC.set(gc, 0.0, 0.0);
268            m_state_on = new_state;
269            m_RB.update_dev();
270            m_RC.update_dev();
268271        }
269272
270        m_B.m_g = m_EB.m_g = gb;
271        m_C.m_g = m_E.m_g = gc;
272
273        m_B.m_Idr  = (  v) * gb;
274        m_EB.m_Idr = ( -v) * gb;
275        m_C.m_Idr  = 0.0;
276        m_E.m_Idr =  0.0;
277273    }
274#endif
278275
276    NETLIB_NAME(R) m_RB;
277    NETLIB_NAME(R) m_RC;
278
279    netlist_analog_input_t m_BV;
280    netlist_analog_input_t m_EV;
281
279282protected:
280283
284    ATTR_COLD virtual void start();
281285    ATTR_COLD void update_param();
282286
283287    double m_gB; // base conductance / switch on
284288    double m_gC; // collector conductance / switch on
285289    double m_V; // internal voltage source
290    int m_state_on;
286291
287292private:
288293};

Previous 199869 Revisions Next


© 1997-2024 The MAME Team