trunk/src/mame/drivers/pong.c
| r26594 | r26595 | |
| 521 | 521 | //NETDEV_LOG(log1, C1.1) |
| 522 | 522 | #endif |
| 523 | 523 | |
| 524 | | |
| 525 | 524 | #define tt(_n) \ |
| 526 | 525 | NETDEV_R(R ## _n, 1000) \ |
| 527 | 526 | NETDEV_D(D ## _n) \ |
| r26594 | r26595 | |
| 602 | 601 | //NETDEV_LOG(logC, Q.C) |
| 603 | 602 | #endif |
| 604 | 603 | |
| 604 | #if 0 |
| 605 | NETDEV_VCVS(VV) |
| 606 | NETDEV_R(R1, 1000) |
| 607 | NETDEV_R(R2, 10000) |
| 605 | 608 | |
| 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) |
| 606 | 616 | |
| 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 | |
| 607 | 721 | NETLIST_END |
| 608 | 722 | |
| 609 | 723 | static NETLIST_START(pong) |
trunk/src/emu/netlist/nl_base.h
| r26594 | r26595 | |
| 270 | 270 | CAPACITOR = 5, // Capacitor |
| 271 | 271 | DIODE = 6, // Diode |
| 272 | 272 | BJT_SWITCH = 7, // BJT(Switch) |
| 273 | VCVS = 8, // Voltage controlled voltage source |
| 274 | VCCS = 9, // Voltage controlled voltage source |
| 273 | 275 | }; |
| 274 | 276 | |
| 275 | 277 | ATTR_COLD netlist_object_t(const type_t atype, const family_t afamily); |
| r26594 | r26595 | |
| 362 | 364 | ATTR_COLD netlist_terminal_t(); |
| 363 | 365 | |
| 364 | 366 | 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 |
| 366 | 369 | |
| 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 | |
| 367 | 391 | netlist_terminal_t *m_otherterm; |
| 368 | 392 | }; |
| 369 | 393 | |
| r26594 | r26595 | |
| 834 | 858 | |
| 835 | 859 | ATTR_COLD virtual void init(netlist_setup_t &setup, const pstring &name); |
| 836 | 860 | |
| 837 | | ATTR_COLD const netlist_setup_t *setup() const { return m_setup; } |
| 861 | ATTR_COLD netlist_setup_t *setup() const { return m_setup; } |
| 838 | 862 | |
| 839 | 863 | ATTR_COLD bool variable_input_count() { return m_variable_input_count; } |
| 840 | 864 | |
trunk/src/emu/netlist/devices/nld_system.c
| r26594 | r26595 | |
| 103 | 103 | m_steps.add(&p->netdev()); |
| 104 | 104 | break; |
| 105 | 105 | case netlist_device_t::DIODE: |
| 106 | //case netlist_device_t::VCVS: |
| 106 | 107 | //case netlist_device_t::BJT_SWITCH: |
| 107 | 108 | if (!m_dynamic.contains(&p->netdev())) |
| 108 | 109 | m_dynamic.add(&p->netdev()); |
| r26594 | r26595 | |
| 153 | 154 | netlist_net_t *net = pn->object(); |
| 154 | 155 | |
| 155 | 156 | double gtot = 0; |
| 157 | double gabs = 0; |
| 156 | 158 | double iIdr = 0; |
| 157 | 159 | const netlist_net_t::terminal_list_t &terms = net->m_terms; |
| 158 | 160 | #if 1 |
| r26594 | r26595 | |
| 161 | 163 | case 1: |
| 162 | 164 | { |
| 163 | 165 | 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(); |
| 166 | 169 | } |
| 167 | 170 | break; |
| 168 | 171 | case 2: |
| 169 | 172 | { |
| 170 | 173 | const netlist_terminal_t *pt1 = terms.first()->object(); |
| 171 | 174 | 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(); |
| 175 | 179 | } |
| 176 | 180 | break; |
| 177 | 181 | case 3: |
| r26594 | r26595 | |
| 179 | 183 | const netlist_terminal_t *pt1 = terms.first()->object(); |
| 180 | 184 | const netlist_terminal_t *pt2 = terms.item(1)->object(); |
| 181 | 185 | 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(); |
| 186 | 191 | } |
| 187 | 192 | break; |
| 188 | 193 | default: |
| 189 | 194 | for (netlist_net_t::terminal_list_t::entry_t *e = terms.first(); e != NULL; e = terms.next(e)) |
| 190 | 195 | { |
| 191 | 196 | 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(); |
| 194 | 200 | } |
| 195 | 201 | break; |
| 196 | 202 | } |
| r26594 | r26595 | |
| 198 | 204 | for (netlist_net_t::terminal_list_t::entry_t *e = terms.first(); e != NULL; e = terms.next(e)) |
| 199 | 205 | { |
| 200 | 206 | 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(); |
| 203 | 210 | } |
| 204 | 211 | #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 | |
| 206 | 219 | if (fabs(new_val - net->m_cur.Analog) > m_accuracy) |
| 207 | 220 | resched = true; |
| 208 | 221 | net->m_cur.Analog = net->m_new.Analog = new_val; |
| r26594 | r26595 | |
| 261 | 274 | m_inc = netlist_time::from_hz(m_freq.Value()); |
| 262 | 275 | |
| 263 | 276 | register_param("ACCURACY", m_accuracy, 1e-3); |
| 277 | register_param("CONVERG", m_convergence, 0.3); |
| 264 | 278 | |
| 265 | 279 | register_link_internal(m_fb_sync, m_Q_sync, netlist_input_t::STATE_INP_ACTIVE); |
| 266 | 280 | register_link_internal(m_fb_step, m_Q_step, netlist_input_t::STATE_INP_ACTIVE); |
| r26594 | r26595 | |
| 329 | 343 | { |
| 330 | 344 | netlist_matrix_solver_t *ms = new netlist_matrix_solver_t; |
| 331 | 345 | ms->m_accuracy = m_accuracy.Value(); |
| 346 | ms->m_convergence_factor = m_convergence.Value(); |
| 332 | 347 | ms->setup(groups[i]); |
| 333 | 348 | m_mat_solvers.add(ms); |
| 334 | 349 | printf("%d ==> %d nets %s\n", i, groups[i].count(), groups[i].first()->object()->m_head->name().cstr()); |
| r26594 | r26595 | |
| 367 | 382 | } while ((resched && (resched_cnt < 5)) || (resched_cnt <= 1)); |
| 368 | 383 | global_resched = global_resched || resched; |
| 369 | 384 | } |
| 385 | //if (global_resched) |
| 386 | // printf("rescheduled\n"); |
| 370 | 387 | if (global_resched) |
| 371 | | printf("rescheduled\n"); |
| 372 | | if (global_resched) |
| 373 | 388 | { |
| 374 | 389 | schedule(); |
| 375 | 390 | } |
trunk/src/emu/netlist/devices/nld_twoterm.c
| r26594 | r26595 | |
| 195 | 195 | template NETLIB_START(QBJT_switch<NETLIB_NAME(Q)::BJT_PNP>); |
| 196 | 196 | template NETLIB_UPDATE_PARAM(QBJT_switch<NETLIB_NAME(Q)::BJT_NPN>); |
| 197 | 197 | template NETLIB_UPDATE_PARAM(QBJT_switch<NETLIB_NAME(Q)::BJT_PNP>); |
| 198 | |
| 199 | // ---------------------------------------------------------------------------------------- |
| 200 | // nld_VCCS |
| 201 | // ---------------------------------------------------------------------------------------- |
| 202 | |
| 203 | NETLIB_START(VCCS) |
| 204 | { |
| 205 | configure(1.0, NETLIST_GMIN); |
| 206 | } |
| 207 | |
| 208 | ATTR_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 | |
| 241 | NETLIB_UPDATE_PARAM(VCCS) |
| 242 | { |
| 243 | } |
| 244 | |
| 245 | NETLIB_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 | |
| 255 | NETLIB_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 | |
| 275 | NETLIB_UPDATE_PARAM(VCVS) |
| 276 | { |
| 277 | } |
| 278 | |
trunk/src/emu/netlist/devices/nld_twoterm.h
| r26594 | r26595 | |
| 76 | 76 | |
| 77 | 77 | ATTR_HOT inline void set(const double G, const double V, const double I) |
| 78 | 78 | { |
| 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; |
| 80 | 80 | m_N.m_Idr = ( -V) * G + I; |
| 81 | 81 | m_P.m_Idr = ( V) * G - I; |
| 82 | 82 | } |
| r26594 | r26595 | |
| 243 | 243 | ATTR_COLD NETLIB_NAME(QBJT_switch)() |
| 244 | 244 | : NETLIB_NAME(QBJT)(_type, BJT_SWITCH), m_gB(NETLIST_GMIN), m_gC(NETLIST_GMIN), m_V(0.0), m_state_on(0) { } |
| 245 | 245 | |
| 246 | | #if 1 |
| 247 | 246 | NETLIB_UPDATEI() |
| 248 | 247 | { |
| 249 | 248 | double vE = INPANALOG(m_EV); |
| r26594 | r26595 | |
| 271 | 270 | } |
| 272 | 271 | |
| 273 | 272 | } |
| 274 | | #endif |
| 275 | 273 | |
| 276 | 274 | NETLIB_NAME(R) m_RB; |
| 277 | 275 | NETLIB_NAME(R) m_RC; |
| r26594 | r26595 | |
| 295 | 293 | typedef NETLIB_NAME(QBJT_switch)<NETLIB_NAME(Q)::BJT_PNP> NETLIB_NAME(QPNP_switch); |
| 296 | 294 | typedef NETLIB_NAME(QBJT_switch)<NETLIB_NAME(Q)::BJT_NPN> NETLIB_NAME(QNPN_switch); |
| 297 | 295 | |
| 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 | |
| 322 | class NETLIB_NAME(VCCS) : public netlist_device_t |
| 323 | { |
| 324 | public: |
| 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 | |
| 330 | protected: |
| 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 | |
| 382 | class NETLIB_NAME(VCVS) : public NETLIB_NAME(VCCS) |
| 383 | { |
| 384 | public: |
| 385 | ATTR_COLD NETLIB_NAME(VCVS)() |
| 386 | : NETLIB_NAME(VCCS)(VCVS) { } |
| 387 | |
| 388 | protected: |
| 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 | |
| 298 | 402 | #endif /* NLD_TWOTERM_H_ */ |