Previous 199869 Revisions Next

r26595 Wednesday 11th December, 2013 at 23:50:28 UTC by Couriersud
Netlist:

- added VCCS and VCVS components.
- added over-relaxation on demand to the iterative solver.
- added a slightly more complex opamp model example to pong (commented out)
[src/emu/netlist]nl_base.c nl_base.h
[src/emu/netlist/devices]net_lib.c nld_system.c nld_system.h nld_twoterm.c nld_twoterm.h
[src/mame/drivers]pong.c

trunk/src/mame/drivers/pong.c
r26594r26595
521521    //NETDEV_LOG(log1, C1.1)
522522#endif
523523
524
525524#define tt(_n) \
526525    NETDEV_R(R ## _n, 1000) \
527526   NETDEV_D(D ## _n) \
r26594r26595
602601    //NETDEV_LOG(logC, Q.C)
603602#endif
604603
604#if 0
605    NETDEV_VCVS(VV)
606    NETDEV_R(R1, 1000)
607    NETDEV_R(R2, 10000)
605608
609    NET_C(V5, R1.1)
610    NET_C(R1.2, VV.IN)
611    NET_C(R2.1, VV.OP)
612    NET_C(R2.2, VV.IN)
613    NET_C(VV.ON, GND)
614    NET_C(VV.IP, GND)
615    NETDEV_LOG(logX, VV.OP)
606616
617#endif
618
619#if 0
620    NETDEV_VCCS(VV)
621    NETDEV_PARAM(VV.G, 100000)  // typical OP-AMP amplification
622    NETDEV_R(R1, 1000)
623    NETDEV_R(R2, 1)
624    NETDEV_R(R3, 10000)
625
626    NET_C(4V, R1.1)
627    NET_C(R1.2, VV.IN)
628    NET_C(R2.1, VV.OP)
629    NET_C(R3.1, VV.IN)
630    NET_C(R3.2, VV.OP)
631    NET_C(R2.2, GND)
632    NET_C(VV.ON, GND)
633    NET_C(VV.IP, GND)
634    //NETDEV_LOG(logX, VV.OP)
635    //NETDEV_LOG(logY, 4V)
636
637#endif
638
639#if 0
640    NETDEV_VCVS(VV)
641    NETDEV_PARAM(VV.G, 100000)  // typical OP-AMP amplification
642    NETDEV_PARAM(VV.RO, 50)  // typical OP-AMP amplification
643    NETDEV_R(R1, 1000)
644    NETDEV_R(R3, 10000) // ==> 10x amplification (inverting)
645
646    NET_C(4V, R1.1)
647    NET_C(R1.2, VV.IN)
648    NET_C(R3.1, VV.IN)
649    NET_C(R3.2, VV.OP)
650    NET_C(VV.ON, GND)
651    NET_C(VV.IP, GND)
652    NETDEV_LOG(logX, VV.OP)
653    NETDEV_LOG(logY, 4V)
654
655#endif
656
657#if 0
658    // Impedance converter with resistor
659    NETDEV_VCVS(VV)
660    NETDEV_PARAM(VV.G, 100000)  // typical OP-AMP amplification
661    NETDEV_PARAM(VV.RO, 50)  // typical OP-AMP amplification
662    NETDEV_R(R3, 10000)
663
664    NET_C(4V, VV.IP)
665    NET_C(R3.1, VV.IN)
666    NET_C(R3.2, VV.OP)
667    NET_C(VV.ON, GND)
668    NETDEV_LOG(logX, VV.OP)
669    NETDEV_LOG(logY, 4V)
670
671#endif
672
673#if 0
674    // Impedance converter without resistor
675    NETDEV_VCVS(VV)
676    NETDEV_PARAM(VV.G, 100000)  // typical OP-AMP amplification
677    NETDEV_PARAM(VV.RO, 50)  // typical OP-AMP amplification
678
679    NET_C(4V, VV.IP)
680    NET_C(VV.IN, VV.OP)
681    NET_C(VV.ON, GND)
682    NETDEV_LOG(logX, VV.OP)
683    NETDEV_LOG(logY, 4V)
684
685#endif
686
687#if 0
688    /* Impedance converter current source opamp model from
689     *
690     * http://www.ecircuitcenter.com/Circuits/opmodel1/opmodel1.htm
691     *
692     * Bandwidth 10Mhz
693     *
694     */
695    NETDEV_VCCS(G1)
696    NETDEV_PARAM(G1.G, 100)  // typical OP-AMP amplification 100 * 1000 = 100000
697    NETDEV_R(RP1, 1000)
698    NETDEV_C(CP1, 1.59e-6)   // <== change to 1.59e-3 for 10Khz bandwidth
699    NETDEV_VCVS(EBUF)
700    NETDEV_PARAM(EBUF.RO, 50)
701    NETDEV_PARAM(EBUF.G, 1)
702
703    NET_C(G1.IP, 4V)
704    NET_C(G1.IN, EBUF.OP)
705    NET_C(EBUF.ON, GND)
706
707    NET_C(G1.ON, GND)
708    NET_C(RP1.2, GND)
709    NET_C(CP1.2, GND)
710    NET_C(EBUF.IN, GND)
711
712    NET_C(RP1.1, G1.OP)
713    NET_C(CP1.1, RP1.1)
714    NET_C(EBUF.IP, RP1.1)
715
716    NETDEV_LOG(logX, EBUF.OP)
717    NETDEV_LOG(logY, 4V)
718
719#endif
720
607721NETLIST_END
608722
609723static NETLIST_START(pong)
trunk/src/emu/netlist/nl_base.h
r26594r26595
270270        CAPACITOR = 5,   // Capacitor
271271        DIODE     = 6,   // Diode
272272        BJT_SWITCH = 7,  // BJT(Switch)
273        VCVS       = 8,  // Voltage controlled voltage source
274        VCCS       = 9,  // Voltage controlled voltage source
273275    };
274276
275277   ATTR_COLD netlist_object_t(const type_t atype, const family_t afamily);
r26594r26595
362364    ATTR_COLD netlist_terminal_t();
363365
364366    double m_Idr; // drive current
365    double m_g; // conductance
367    double m_go;  // conductance for Voltage from other term
368    double m_gt;  // conductance for total conductance
366369
370    ATTR_HOT inline void set(const double G)
371    {
372        m_Idr = 0;
373        m_go = m_gt = G;
374    }
375
376    ATTR_HOT inline void set(const double GO, const double GT)
377    {
378        m_Idr = 0;
379        m_go = GO;
380        m_gt = GT;
381    }
382
383    ATTR_HOT inline void set(const double GO, const double GT, const double I)
384    {
385        m_Idr = I;
386        m_go = GO;
387        m_gt = GT;
388    }
389
390
367391    netlist_terminal_t *m_otherterm;
368392};
369393
r26594r26595
834858
835859   ATTR_COLD virtual void init(netlist_setup_t &setup, const pstring &name);
836860
837   ATTR_COLD const netlist_setup_t *setup() const { return m_setup; }
861   ATTR_COLD netlist_setup_t *setup() const { return m_setup; }
838862
839863   ATTR_COLD bool variable_input_count() { return m_variable_input_count; }
840864
trunk/src/emu/netlist/devices/nld_system.c
r26594r26595
103103                                m_steps.add(&p->netdev());
104104                            break;
105105                        case netlist_device_t::DIODE:
106                        //case netlist_device_t::VCVS:
106107                        //case netlist_device_t::BJT_SWITCH:
107108                            if (!m_dynamic.contains(&p->netdev()))
108109                                m_dynamic.add(&p->netdev());
r26594r26595
153154        netlist_net_t *net = pn->object();
154155
155156        double gtot = 0;
157        double gabs = 0;
156158        double iIdr = 0;
157159        const netlist_net_t::terminal_list_t &terms = net->m_terms;
158160#if 1
r26594r26595
161163            case 1:
162164                {
163165                    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                    gtot = pt->m_gt;
167                    gabs = fabs(pt->m_go);
168                    iIdr = pt->m_Idr + pt->m_go * pt->m_otherterm->net().Q_Analog();
166169                }
167170                break;
168171            case 2:
169172                {
170173                    const netlist_terminal_t *pt1 = terms.first()->object();
171174                    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                    gtot = pt1->m_gt + pt2->m_gt;
176                    gabs = fabs(pt1->m_go) + fabs(pt2->m_go);
177                    iIdr = pt1->m_Idr + pt1->m_go * pt1->m_otherterm->net().Q_Analog()
178                         + pt2->m_Idr + pt2->m_go * pt2->m_otherterm->net().Q_Analog();
175179                }
176180                break;
177181            case 3:
r26594r26595
179183                    const netlist_terminal_t *pt1 = terms.first()->object();
180184                    const netlist_terminal_t *pt2 = terms.item(1)->object();
181185                    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                    gtot = pt1->m_gt + pt2->m_gt + pt3->m_gt;
187                    gabs = fabs(pt1->m_go) + fabs(pt2->m_go) + fabs(pt3->m_go);
188                    iIdr = pt1->m_Idr + pt1->m_go * pt1->m_otherterm->net().Q_Analog()
189                         + pt2->m_Idr + pt2->m_go * pt2->m_otherterm->net().Q_Analog()
190                         + pt3->m_Idr + pt3->m_go * pt3->m_otherterm->net().Q_Analog();
186191                }
187192                break;
188193            default:
189194                for (netlist_net_t::terminal_list_t::entry_t *e = terms.first(); e != NULL; e = terms.next(e))
190195                {
191196                    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();
197                    gtot += pt->m_gt;
198                    gabs += fabs(pt->m_go);
199                    iIdr += pt->m_Idr + pt->m_go * pt->m_otherterm->net().Q_Analog();
194200                }
195201                break;
196202        }
r26594r26595
198204        for (netlist_net_t::terminal_list_t::entry_t *e = terms.first(); e != NULL; e = terms.next(e))
199205        {
200206            netlist_terminal_t *pt = e->object();
201            gtot += pt->m_g;
202            iIdr += pt->m_Idr + pt->m_g * pt->m_otherterm->net().Q_Analog();
207            gtot += pt->m_gt;
208            gabs += fabs(pt->m_go);
209            iIdr += pt->m_Idr + pt->m_go * pt->m_otherterm->net().Q_Analog();
203210        }
204211#endif
205        double new_val = iIdr / gtot;
212        double new_val;
213        gabs *= m_convergence_factor;
214        if (gabs > gtot)
215            new_val = (net->m_cur.Analog * gabs + iIdr) / (gtot + gabs);
216        else
217            new_val = iIdr / gtot;
218
206219        if (fabs(new_val - net->m_cur.Analog) > m_accuracy)
207220            resched = true;
208221        net->m_cur.Analog = net->m_new.Analog = new_val;
r26594r26595
261274    m_inc = netlist_time::from_hz(m_freq.Value());
262275
263276    register_param("ACCURACY", m_accuracy, 1e-3);
277    register_param("CONVERG", m_convergence, 0.3);
264278
265279    register_link_internal(m_fb_sync, m_Q_sync, netlist_input_t::STATE_INP_ACTIVE);
266280    register_link_internal(m_fb_step, m_Q_step, netlist_input_t::STATE_INP_ACTIVE);
r26594r26595
329343    {
330344        netlist_matrix_solver_t *ms = new netlist_matrix_solver_t;
331345        ms->m_accuracy = m_accuracy.Value();
346        ms->m_convergence_factor = m_convergence.Value();
332347        ms->setup(groups[i]);
333348        m_mat_solvers.add(ms);
334349        printf("%d ==> %d nets %s\n", i, groups[i].count(), groups[i].first()->object()->m_head->name().cstr());
r26594r26595
367382        } while ((resched && (resched_cnt < 5)) || (resched_cnt <= 1));
368383        global_resched = global_resched || resched;
369384    }
385    //if (global_resched)
386    //    printf("rescheduled\n");
370387    if (global_resched)
371        printf("rescheduled\n");
372    if (global_resched)
373388    {
374389        schedule();
375390    }
trunk/src/emu/netlist/devices/nld_system.h
r26594r26595
9494    ATTR_HOT inline bool is_dynamic() { return m_dynamic.count() > 0; }
9595
9696    double m_accuracy;
97    double m_convergence_factor;
9798
9899private:
99100    netlist_net_t::list_t m_nets;
r26594r26595
114115        netlist_param_double_t m_freq;
115116        netlist_param_double_t m_sync_delay;
116117        netlist_param_double_t m_accuracy;
118        netlist_param_double_t m_convergence;
117119
118120        netlist_time m_inc;
119121        netlist_time m_last_step;
trunk/src/emu/netlist/devices/nld_twoterm.c
r26594r26595
195195template NETLIB_START(QBJT_switch<NETLIB_NAME(Q)::BJT_PNP>);
196196template NETLIB_UPDATE_PARAM(QBJT_switch<NETLIB_NAME(Q)::BJT_NPN>);
197197template NETLIB_UPDATE_PARAM(QBJT_switch<NETLIB_NAME(Q)::BJT_PNP>);
198
199// ----------------------------------------------------------------------------------------
200// nld_VCCS
201// ----------------------------------------------------------------------------------------
202
203NETLIB_START(VCCS)
204{
205    configure(1.0, NETLIST_GMIN);
206}
207
208ATTR_COLD void NETLIB_NAME(VCCS)::configure(const double Gfac, const double GI)
209{
210
211    register_param("G", m_G, 1.0);
212
213    register_terminal("IP", m_IP);
214    register_terminal("IN", m_IN);
215    register_terminal("OP", m_OP);
216    register_terminal("ON", m_ON);
217
218    m_OP1.init_object(*this, "OP1", netlist_core_terminal_t::STATE_INP_ACTIVE);
219    m_ON1.init_object(*this, "ON1", netlist_core_terminal_t::STATE_INP_ACTIVE);
220
221    const double m_mult = m_G.Value() * Gfac; // 1.0 ==> 1V ==> 1A
222    m_IP.set(GI);
223    m_IP.m_otherterm = &m_IN; // <= this should be NULL and terminal be filtered out prior to solving...
224    m_IN.set(GI);
225    m_IN.m_otherterm = &m_IP; // <= this should be NULL and terminal be filtered out prior to solving...
226
227    m_OP.set(m_mult, 0.0);
228    m_OP.m_otherterm = &m_IP;
229    m_OP1.set(-m_mult, 0.0);
230    m_OP1.m_otherterm = &m_IN;
231
232    m_ON.set(-m_mult, 0.0);
233    m_ON.m_otherterm = &m_IP;
234    m_ON1.set(m_mult, 0.0);
235    m_ON1.m_otherterm = &m_IN;
236
237    m_setup->connect(m_OP, m_OP1);
238    m_setup->connect(m_ON, m_ON1);
239}
240
241NETLIB_UPDATE_PARAM(VCCS)
242{
243}
244
245NETLIB_UPDATE(VCCS)
246{
247    /* only called if connected to a rail net ==> notify the solver to recalculate */
248    netlist().solver()->schedule();
249}
250
251// ----------------------------------------------------------------------------------------
252// nld_VCVS
253// ----------------------------------------------------------------------------------------
254
255NETLIB_START(VCVS)
256{
257    register_param("RO", m_RO, 1.0);
258
259    const double gRO = 1.0 / m_RO.Value();
260
261    configure(gRO, NETLIST_GMIN);
262
263    m_OP2.init_object(*this, "OP2", netlist_core_terminal_t::STATE_INP_ACTIVE);
264    m_ON2.init_object(*this, "ON2", netlist_core_terminal_t::STATE_INP_ACTIVE);
265
266    m_OP2.set(gRO);
267    m_ON2.set(gRO);
268    m_OP2.m_otherterm = &m_ON2;
269    m_ON2.m_otherterm = &m_OP2;
270
271    setup()->connect(m_OP2, m_OP1);
272    setup()->connect(m_ON2, m_ON1);
273}
274
275NETLIB_UPDATE_PARAM(VCVS)
276{
277}
278
trunk/src/emu/netlist/devices/nld_twoterm.h
r26594r26595
7676
7777    ATTR_HOT inline void set(const double G, const double V, const double I)
7878    {
79        m_P.m_g = m_N.m_g = G;
79        m_P.m_go = m_N.m_go = m_P.m_gt = m_N.m_gt = G;
8080        m_N.m_Idr = ( -V) * G + I;
8181        m_P.m_Idr = (  V) * G - I;
8282    }
r26594r26595
243243    ATTR_COLD NETLIB_NAME(QBJT_switch)()
244244    : NETLIB_NAME(QBJT)(_type, BJT_SWITCH), m_gB(NETLIST_GMIN), m_gC(NETLIST_GMIN), m_V(0.0), m_state_on(0) { }
245245
246#if 1
247246    NETLIB_UPDATEI()
248247    {
249248        double vE = INPANALOG(m_EV);
r26594r26595
271270        }
272271
273272    }
274#endif
275273
276274    NETLIB_NAME(R) m_RB;
277275    NETLIB_NAME(R) m_RC;
r26594r26595
295293typedef NETLIB_NAME(QBJT_switch)<NETLIB_NAME(Q)::BJT_PNP> NETLIB_NAME(QPNP_switch);
296294typedef NETLIB_NAME(QBJT_switch)<NETLIB_NAME(Q)::BJT_NPN> NETLIB_NAME(QNPN_switch);
297295
296// ----------------------------------------------------------------------------------------
297// nld_VCCS
298// ----------------------------------------------------------------------------------------
299
300/*
301 *   Voltage controlled current source
302 *
303 *   IP ---+           +------> OP
304 *         |           |
305 *         RI          I
306 *         RI => G =>  I    IOut = (V(IP)-V(IN)) * G
307 *         RI          I
308 *         |           |
309 *   IN ---+           +------< ON
310 *
311 *   G=1 ==> 1V ==> 1A
312 *
313 *   RI = 1 / NETLIST_GMIN
314 *
315 */
316
317#define NETDEV_VCCS(_name)                                                         \
318        NET_REGISTER_DEV(VCCS, _name)                                              \
319
320//NETDEV_PARAMI(_name, model, _model)
321
322class NETLIB_NAME(VCCS) : public netlist_device_t
323{
324public:
325    ATTR_COLD NETLIB_NAME(VCCS)()
326    : netlist_device_t(VCCS) {  }
327    ATTR_COLD NETLIB_NAME(VCCS)(const family_t afamily)
328    : netlist_device_t(afamily) {  }
329
330protected:
331    ATTR_COLD virtual void start();
332    ATTR_COLD virtual void update_param();
333    ATTR_HOT ATTR_ALIGN void update();
334
335    ATTR_COLD void configure(const double Gfac, const double GI);
336
337    netlist_terminal_t m_OP;
338    netlist_terminal_t m_ON;
339
340    netlist_terminal_t m_IP;
341    netlist_terminal_t m_IN;
342
343    netlist_terminal_t m_OP1;
344    netlist_terminal_t m_ON1;
345
346    netlist_param_double_t m_G;
347};
348
349// ----------------------------------------------------------------------------------------
350// nld_VCVS
351// ----------------------------------------------------------------------------------------
352
353/*
354 *   Voltage controlled voltage source
355 *
356 *   Parameters:
357 *     G        Default: 1
358 *     RO       Default: 1  (would be typically 50 for an op-amp
359 *
360 *   IP ---+           +--+---- OP
361 *         |           |  |
362 *         RI          I  RO
363 *         RI => G =>  I  RO              V(OP) - V(ON) = (V(IP)-V(IN)) * G
364 *         RI          I  RO
365 *         |           |  |
366 *   IN ---+           +--+---- ON
367 *
368 *   G=1 ==> 1V ==> 1V
369 *
370 *   RI = 1 / NETLIST_GMIN
371 *
372 *   Internal GI = G / RO
373 *
374 */
375
376#define NETDEV_VCVS(_name)                                                         \
377        NET_REGISTER_DEV(VCVS, _name)                                              \
378
379//NETDEV_PARAMI(_name, model, _model)
380
381
382class NETLIB_NAME(VCVS) : public NETLIB_NAME(VCCS)
383{
384public:
385    ATTR_COLD NETLIB_NAME(VCVS)()
386    : NETLIB_NAME(VCCS)(VCVS) { }
387
388protected:
389    ATTR_COLD virtual void start();
390    ATTR_COLD virtual void update_param();
391    //ATTR_HOT ATTR_ALIGN void update();
392
393    netlist_terminal_t m_OP2;
394    netlist_terminal_t m_ON2;
395
396    double m_mult;
397
398    netlist_param_double_t m_RO;
399};
400
401
298402#endif /* NLD_TWOTERM_H_ */
trunk/src/emu/netlist/devices/net_lib.c
r26594r26595
786786    ENTRY(R,                    NETDEV_R)
787787    ENTRY(C,                    NETDEV_C)
788788    ENTRY(D,                    NETDEV_D)
789    ENTRY(VCVS,                 NETDEV_VCVS)
790    ENTRY(VCCS,                 NETDEV_VCCS)
789791    ENTRY(QPNP_switch,          NETDEV_QPNP)
790792    ENTRY(QNPN_switch,          NETDEV_QNPN)
791793    ENTRY(ttl_const,            NETDEV_TTL_CONST)
trunk/src/emu/netlist/nl_base.c
r26594r26595
484484ATTR_COLD netlist_terminal_t::netlist_terminal_t()
485485: netlist_core_terminal_t(TERMINAL, ANALOG)
486486, m_Idr(0.0)
487, m_g(NETLIST_GMIN)
487, m_go(NETLIST_GMIN)
488, m_gt(NETLIST_GMIN)
488489{
489490
490491}

Previous 199869 Revisions Next


© 1997-2024 The MAME Team