mirror of
https://github.com/holub/mame
synced 2025-10-04 16:34:53 +03:00
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)
This commit is contained in:
parent
55c1991174
commit
3710459410
@ -786,6 +786,8 @@ void netlist_factory::initialize()
|
||||
ENTRY(R, NETDEV_R)
|
||||
ENTRY(C, NETDEV_C)
|
||||
ENTRY(D, NETDEV_D)
|
||||
ENTRY(VCVS, NETDEV_VCVS)
|
||||
ENTRY(VCCS, NETDEV_VCCS)
|
||||
ENTRY(QPNP_switch, NETDEV_QPNP)
|
||||
ENTRY(QNPN_switch, NETDEV_QNPN)
|
||||
ENTRY(ttl_const, NETDEV_TTL_CONST)
|
||||
|
@ -103,6 +103,7 @@ ATTR_COLD void netlist_matrix_solver_t::setup(netlist_net_t::list_t &nets)
|
||||
m_steps.add(&p->netdev());
|
||||
break;
|
||||
case netlist_device_t::DIODE:
|
||||
//case netlist_device_t::VCVS:
|
||||
//case netlist_device_t::BJT_SWITCH:
|
||||
if (!m_dynamic.contains(&p->netdev()))
|
||||
m_dynamic.add(&p->netdev());
|
||||
@ -153,6 +154,7 @@ ATTR_HOT inline bool netlist_matrix_solver_t::solve()
|
||||
netlist_net_t *net = pn->object();
|
||||
|
||||
double gtot = 0;
|
||||
double gabs = 0;
|
||||
double iIdr = 0;
|
||||
const netlist_net_t::terminal_list_t &terms = net->m_terms;
|
||||
#if 1
|
||||
@ -161,17 +163,19 @@ ATTR_HOT inline bool netlist_matrix_solver_t::solve()
|
||||
case 1:
|
||||
{
|
||||
const netlist_terminal_t *pt = terms.first()->object();
|
||||
gtot = pt->m_g;
|
||||
iIdr = pt->m_Idr + pt->m_g * pt->m_otherterm->net().Q_Analog();
|
||||
gtot = pt->m_gt;
|
||||
gabs = fabs(pt->m_go);
|
||||
iIdr = pt->m_Idr + pt->m_go * pt->m_otherterm->net().Q_Analog();
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
const netlist_terminal_t *pt1 = terms.first()->object();
|
||||
const netlist_terminal_t *pt2 = terms.item(1)->object();
|
||||
gtot = pt1->m_g + pt2->m_g;
|
||||
iIdr = pt1->m_Idr + pt1->m_g * pt1->m_otherterm->net().Q_Analog()
|
||||
+ pt2->m_Idr + pt2->m_g * pt2->m_otherterm->net().Q_Analog();
|
||||
gtot = pt1->m_gt + pt2->m_gt;
|
||||
gabs = fabs(pt1->m_go) + fabs(pt2->m_go);
|
||||
iIdr = pt1->m_Idr + pt1->m_go * pt1->m_otherterm->net().Q_Analog()
|
||||
+ pt2->m_Idr + pt2->m_go * pt2->m_otherterm->net().Q_Analog();
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
@ -179,18 +183,20 @@ ATTR_HOT inline bool netlist_matrix_solver_t::solve()
|
||||
const netlist_terminal_t *pt1 = terms.first()->object();
|
||||
const netlist_terminal_t *pt2 = terms.item(1)->object();
|
||||
const netlist_terminal_t *pt3 = terms.item(2)->object();
|
||||
gtot = pt1->m_g + pt2->m_g + pt3->m_g;
|
||||
iIdr = pt1->m_Idr + pt1->m_g * pt1->m_otherterm->net().Q_Analog()
|
||||
+ pt2->m_Idr + pt2->m_g * pt2->m_otherterm->net().Q_Analog()
|
||||
+ pt3->m_Idr + pt3->m_g * pt3->m_otherterm->net().Q_Analog();
|
||||
gtot = pt1->m_gt + pt2->m_gt + pt3->m_gt;
|
||||
gabs = fabs(pt1->m_go) + fabs(pt2->m_go) + fabs(pt3->m_go);
|
||||
iIdr = pt1->m_Idr + pt1->m_go * pt1->m_otherterm->net().Q_Analog()
|
||||
+ pt2->m_Idr + pt2->m_go * pt2->m_otherterm->net().Q_Analog()
|
||||
+ pt3->m_Idr + pt3->m_go * pt3->m_otherterm->net().Q_Analog();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
for (netlist_net_t::terminal_list_t::entry_t *e = terms.first(); e != NULL; e = terms.next(e))
|
||||
{
|
||||
netlist_terminal_t *pt = e->object();
|
||||
gtot += pt->m_g;
|
||||
iIdr += pt->m_Idr + pt->m_g * pt->m_otherterm->net().Q_Analog();
|
||||
gtot += pt->m_gt;
|
||||
gabs += fabs(pt->m_go);
|
||||
iIdr += pt->m_Idr + pt->m_go * pt->m_otherterm->net().Q_Analog();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -198,11 +204,18 @@ ATTR_HOT inline bool netlist_matrix_solver_t::solve()
|
||||
for (netlist_net_t::terminal_list_t::entry_t *e = terms.first(); e != NULL; e = terms.next(e))
|
||||
{
|
||||
netlist_terminal_t *pt = e->object();
|
||||
gtot += pt->m_g;
|
||||
iIdr += pt->m_Idr + pt->m_g * pt->m_otherterm->net().Q_Analog();
|
||||
gtot += pt->m_gt;
|
||||
gabs += fabs(pt->m_go);
|
||||
iIdr += pt->m_Idr + pt->m_go * pt->m_otherterm->net().Q_Analog();
|
||||
}
|
||||
#endif
|
||||
double new_val = iIdr / gtot;
|
||||
double new_val;
|
||||
gabs *= m_convergence_factor;
|
||||
if (gabs > gtot)
|
||||
new_val = (net->m_cur.Analog * gabs + iIdr) / (gtot + gabs);
|
||||
else
|
||||
new_val = iIdr / gtot;
|
||||
|
||||
if (fabs(new_val - net->m_cur.Analog) > m_accuracy)
|
||||
resched = true;
|
||||
net->m_cur.Analog = net->m_new.Analog = new_val;
|
||||
@ -261,6 +274,7 @@ NETLIB_START(solver)
|
||||
m_inc = netlist_time::from_hz(m_freq.Value());
|
||||
|
||||
register_param("ACCURACY", m_accuracy, 1e-3);
|
||||
register_param("CONVERG", m_convergence, 0.3);
|
||||
|
||||
register_link_internal(m_fb_sync, m_Q_sync, netlist_input_t::STATE_INP_ACTIVE);
|
||||
register_link_internal(m_fb_step, m_Q_step, netlist_input_t::STATE_INP_ACTIVE);
|
||||
@ -329,6 +343,7 @@ NETLIB_FUNC_VOID(solver, post_start, ())
|
||||
{
|
||||
netlist_matrix_solver_t *ms = new netlist_matrix_solver_t;
|
||||
ms->m_accuracy = m_accuracy.Value();
|
||||
ms->m_convergence_factor = m_convergence.Value();
|
||||
ms->setup(groups[i]);
|
||||
m_mat_solvers.add(ms);
|
||||
printf("%d ==> %d nets %s\n", i, groups[i].count(), groups[i].first()->object()->m_head->name().cstr());
|
||||
@ -367,8 +382,8 @@ NETLIB_UPDATE(solver)
|
||||
} while ((resched && (resched_cnt < 5)) || (resched_cnt <= 1));
|
||||
global_resched = global_resched || resched;
|
||||
}
|
||||
if (global_resched)
|
||||
printf("rescheduled\n");
|
||||
//if (global_resched)
|
||||
// printf("rescheduled\n");
|
||||
if (global_resched)
|
||||
{
|
||||
schedule();
|
||||
|
@ -94,6 +94,7 @@ public:
|
||||
ATTR_HOT inline bool is_dynamic() { return m_dynamic.count() > 0; }
|
||||
|
||||
double m_accuracy;
|
||||
double m_convergence_factor;
|
||||
|
||||
private:
|
||||
netlist_net_t::list_t m_nets;
|
||||
@ -114,6 +115,7 @@ NETLIB_DEVICE_WITH_PARAMS(solver,
|
||||
netlist_param_double_t m_freq;
|
||||
netlist_param_double_t m_sync_delay;
|
||||
netlist_param_double_t m_accuracy;
|
||||
netlist_param_double_t m_convergence;
|
||||
|
||||
netlist_time m_inc;
|
||||
netlist_time m_last_step;
|
||||
|
@ -195,3 +195,84 @@ template NETLIB_START(QBJT_switch<NETLIB_NAME(Q)::BJT_NPN>);
|
||||
template NETLIB_START(QBJT_switch<NETLIB_NAME(Q)::BJT_PNP>);
|
||||
template NETLIB_UPDATE_PARAM(QBJT_switch<NETLIB_NAME(Q)::BJT_NPN>);
|
||||
template NETLIB_UPDATE_PARAM(QBJT_switch<NETLIB_NAME(Q)::BJT_PNP>);
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// nld_VCCS
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
NETLIB_START(VCCS)
|
||||
{
|
||||
configure(1.0, NETLIST_GMIN);
|
||||
}
|
||||
|
||||
ATTR_COLD void NETLIB_NAME(VCCS)::configure(const double Gfac, const double GI)
|
||||
{
|
||||
|
||||
register_param("G", m_G, 1.0);
|
||||
|
||||
register_terminal("IP", m_IP);
|
||||
register_terminal("IN", m_IN);
|
||||
register_terminal("OP", m_OP);
|
||||
register_terminal("ON", m_ON);
|
||||
|
||||
m_OP1.init_object(*this, "OP1", netlist_core_terminal_t::STATE_INP_ACTIVE);
|
||||
m_ON1.init_object(*this, "ON1", netlist_core_terminal_t::STATE_INP_ACTIVE);
|
||||
|
||||
const double m_mult = m_G.Value() * Gfac; // 1.0 ==> 1V ==> 1A
|
||||
m_IP.set(GI);
|
||||
m_IP.m_otherterm = &m_IN; // <= this should be NULL and terminal be filtered out prior to solving...
|
||||
m_IN.set(GI);
|
||||
m_IN.m_otherterm = &m_IP; // <= this should be NULL and terminal be filtered out prior to solving...
|
||||
|
||||
m_OP.set(m_mult, 0.0);
|
||||
m_OP.m_otherterm = &m_IP;
|
||||
m_OP1.set(-m_mult, 0.0);
|
||||
m_OP1.m_otherterm = &m_IN;
|
||||
|
||||
m_ON.set(-m_mult, 0.0);
|
||||
m_ON.m_otherterm = &m_IP;
|
||||
m_ON1.set(m_mult, 0.0);
|
||||
m_ON1.m_otherterm = &m_IN;
|
||||
|
||||
m_setup->connect(m_OP, m_OP1);
|
||||
m_setup->connect(m_ON, m_ON1);
|
||||
}
|
||||
|
||||
NETLIB_UPDATE_PARAM(VCCS)
|
||||
{
|
||||
}
|
||||
|
||||
NETLIB_UPDATE(VCCS)
|
||||
{
|
||||
/* only called if connected to a rail net ==> notify the solver to recalculate */
|
||||
netlist().solver()->schedule();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// nld_VCVS
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
NETLIB_START(VCVS)
|
||||
{
|
||||
register_param("RO", m_RO, 1.0);
|
||||
|
||||
const double gRO = 1.0 / m_RO.Value();
|
||||
|
||||
configure(gRO, NETLIST_GMIN);
|
||||
|
||||
m_OP2.init_object(*this, "OP2", netlist_core_terminal_t::STATE_INP_ACTIVE);
|
||||
m_ON2.init_object(*this, "ON2", netlist_core_terminal_t::STATE_INP_ACTIVE);
|
||||
|
||||
m_OP2.set(gRO);
|
||||
m_ON2.set(gRO);
|
||||
m_OP2.m_otherterm = &m_ON2;
|
||||
m_ON2.m_otherterm = &m_OP2;
|
||||
|
||||
setup()->connect(m_OP2, m_OP1);
|
||||
setup()->connect(m_ON2, m_ON1);
|
||||
}
|
||||
|
||||
NETLIB_UPDATE_PARAM(VCVS)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -76,7 +76,7 @@ public:
|
||||
|
||||
ATTR_HOT inline void set(const double G, const double V, const double I)
|
||||
{
|
||||
m_P.m_g = m_N.m_g = G;
|
||||
m_P.m_go = m_N.m_go = m_P.m_gt = m_N.m_gt = G;
|
||||
m_N.m_Idr = ( -V) * G + I;
|
||||
m_P.m_Idr = ( V) * G - I;
|
||||
}
|
||||
@ -243,7 +243,6 @@ public:
|
||||
ATTR_COLD NETLIB_NAME(QBJT_switch)()
|
||||
: NETLIB_NAME(QBJT)(_type, BJT_SWITCH), m_gB(NETLIST_GMIN), m_gC(NETLIST_GMIN), m_V(0.0), m_state_on(0) { }
|
||||
|
||||
#if 1
|
||||
NETLIB_UPDATEI()
|
||||
{
|
||||
double vE = INPANALOG(m_EV);
|
||||
@ -271,7 +270,6 @@ public:
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
NETLIB_NAME(R) m_RB;
|
||||
NETLIB_NAME(R) m_RC;
|
||||
@ -295,4 +293,110 @@ private:
|
||||
typedef NETLIB_NAME(QBJT_switch)<NETLIB_NAME(Q)::BJT_PNP> NETLIB_NAME(QPNP_switch);
|
||||
typedef NETLIB_NAME(QBJT_switch)<NETLIB_NAME(Q)::BJT_NPN> NETLIB_NAME(QNPN_switch);
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// nld_VCCS
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* Voltage controlled current source
|
||||
*
|
||||
* IP ---+ +------> OP
|
||||
* | |
|
||||
* RI I
|
||||
* RI => G => I IOut = (V(IP)-V(IN)) * G
|
||||
* RI I
|
||||
* | |
|
||||
* IN ---+ +------< ON
|
||||
*
|
||||
* G=1 ==> 1V ==> 1A
|
||||
*
|
||||
* RI = 1 / NETLIST_GMIN
|
||||
*
|
||||
*/
|
||||
|
||||
#define NETDEV_VCCS(_name) \
|
||||
NET_REGISTER_DEV(VCCS, _name) \
|
||||
|
||||
//NETDEV_PARAMI(_name, model, _model)
|
||||
|
||||
class NETLIB_NAME(VCCS) : public netlist_device_t
|
||||
{
|
||||
public:
|
||||
ATTR_COLD NETLIB_NAME(VCCS)()
|
||||
: netlist_device_t(VCCS) { }
|
||||
ATTR_COLD NETLIB_NAME(VCCS)(const family_t afamily)
|
||||
: netlist_device_t(afamily) { }
|
||||
|
||||
protected:
|
||||
ATTR_COLD virtual void start();
|
||||
ATTR_COLD virtual void update_param();
|
||||
ATTR_HOT ATTR_ALIGN void update();
|
||||
|
||||
ATTR_COLD void configure(const double Gfac, const double GI);
|
||||
|
||||
netlist_terminal_t m_OP;
|
||||
netlist_terminal_t m_ON;
|
||||
|
||||
netlist_terminal_t m_IP;
|
||||
netlist_terminal_t m_IN;
|
||||
|
||||
netlist_terminal_t m_OP1;
|
||||
netlist_terminal_t m_ON1;
|
||||
|
||||
netlist_param_double_t m_G;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// nld_VCVS
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* Voltage controlled voltage source
|
||||
*
|
||||
* Parameters:
|
||||
* G Default: 1
|
||||
* RO Default: 1 (would be typically 50 for an op-amp
|
||||
*
|
||||
* IP ---+ +--+---- OP
|
||||
* | | |
|
||||
* RI I RO
|
||||
* RI => G => I RO V(OP) - V(ON) = (V(IP)-V(IN)) * G
|
||||
* RI I RO
|
||||
* | | |
|
||||
* IN ---+ +--+---- ON
|
||||
*
|
||||
* G=1 ==> 1V ==> 1V
|
||||
*
|
||||
* RI = 1 / NETLIST_GMIN
|
||||
*
|
||||
* Internal GI = G / RO
|
||||
*
|
||||
*/
|
||||
|
||||
#define NETDEV_VCVS(_name) \
|
||||
NET_REGISTER_DEV(VCVS, _name) \
|
||||
|
||||
//NETDEV_PARAMI(_name, model, _model)
|
||||
|
||||
|
||||
class NETLIB_NAME(VCVS) : public NETLIB_NAME(VCCS)
|
||||
{
|
||||
public:
|
||||
ATTR_COLD NETLIB_NAME(VCVS)()
|
||||
: NETLIB_NAME(VCCS)(VCVS) { }
|
||||
|
||||
protected:
|
||||
ATTR_COLD virtual void start();
|
||||
ATTR_COLD virtual void update_param();
|
||||
//ATTR_HOT ATTR_ALIGN void update();
|
||||
|
||||
netlist_terminal_t m_OP2;
|
||||
netlist_terminal_t m_ON2;
|
||||
|
||||
double m_mult;
|
||||
|
||||
netlist_param_double_t m_RO;
|
||||
};
|
||||
|
||||
|
||||
#endif /* NLD_TWOTERM_H_ */
|
||||
|
@ -484,7 +484,8 @@ ATTR_COLD netlist_core_terminal_t::netlist_core_terminal_t(const type_t atype, c
|
||||
ATTR_COLD netlist_terminal_t::netlist_terminal_t()
|
||||
: netlist_core_terminal_t(TERMINAL, ANALOG)
|
||||
, m_Idr(0.0)
|
||||
, m_g(NETLIST_GMIN)
|
||||
, m_go(NETLIST_GMIN)
|
||||
, m_gt(NETLIST_GMIN)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -270,6 +270,8 @@ public:
|
||||
CAPACITOR = 5, // Capacitor
|
||||
DIODE = 6, // Diode
|
||||
BJT_SWITCH = 7, // BJT(Switch)
|
||||
VCVS = 8, // Voltage controlled voltage source
|
||||
VCCS = 9, // Voltage controlled voltage source
|
||||
};
|
||||
|
||||
ATTR_COLD netlist_object_t(const type_t atype, const family_t afamily);
|
||||
@ -362,7 +364,29 @@ public:
|
||||
ATTR_COLD netlist_terminal_t();
|
||||
|
||||
double m_Idr; // drive current
|
||||
double m_g; // conductance
|
||||
double m_go; // conductance for Voltage from other term
|
||||
double m_gt; // conductance for total conductance
|
||||
|
||||
ATTR_HOT inline void set(const double G)
|
||||
{
|
||||
m_Idr = 0;
|
||||
m_go = m_gt = G;
|
||||
}
|
||||
|
||||
ATTR_HOT inline void set(const double GO, const double GT)
|
||||
{
|
||||
m_Idr = 0;
|
||||
m_go = GO;
|
||||
m_gt = GT;
|
||||
}
|
||||
|
||||
ATTR_HOT inline void set(const double GO, const double GT, const double I)
|
||||
{
|
||||
m_Idr = I;
|
||||
m_go = GO;
|
||||
m_gt = GT;
|
||||
}
|
||||
|
||||
|
||||
netlist_terminal_t *m_otherterm;
|
||||
};
|
||||
@ -834,7 +858,7 @@ public:
|
||||
|
||||
ATTR_COLD virtual void init(netlist_setup_t &setup, const pstring &name);
|
||||
|
||||
ATTR_COLD const netlist_setup_t *setup() const { return m_setup; }
|
||||
ATTR_COLD netlist_setup_t *setup() const { return m_setup; }
|
||||
|
||||
ATTR_COLD bool variable_input_count() { return m_variable_input_count; }
|
||||
|
||||
|
@ -521,7 +521,6 @@ static NETLIST_START(pong_schematics)
|
||||
//NETDEV_LOG(log1, C1.1)
|
||||
#endif
|
||||
|
||||
|
||||
#define tt(_n) \
|
||||
NETDEV_R(R ## _n, 1000) \
|
||||
NETDEV_D(D ## _n) \
|
||||
@ -602,7 +601,122 @@ static NETLIST_START(pong_schematics)
|
||||
//NETDEV_LOG(logC, Q.C)
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
NETDEV_VCVS(VV)
|
||||
NETDEV_R(R1, 1000)
|
||||
NETDEV_R(R2, 10000)
|
||||
|
||||
NET_C(V5, R1.1)
|
||||
NET_C(R1.2, VV.IN)
|
||||
NET_C(R2.1, VV.OP)
|
||||
NET_C(R2.2, VV.IN)
|
||||
NET_C(VV.ON, GND)
|
||||
NET_C(VV.IP, GND)
|
||||
NETDEV_LOG(logX, VV.OP)
|
||||
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
NETDEV_VCCS(VV)
|
||||
NETDEV_PARAM(VV.G, 100000) // typical OP-AMP amplification
|
||||
NETDEV_R(R1, 1000)
|
||||
NETDEV_R(R2, 1)
|
||||
NETDEV_R(R3, 10000)
|
||||
|
||||
NET_C(4V, R1.1)
|
||||
NET_C(R1.2, VV.IN)
|
||||
NET_C(R2.1, VV.OP)
|
||||
NET_C(R3.1, VV.IN)
|
||||
NET_C(R3.2, VV.OP)
|
||||
NET_C(R2.2, GND)
|
||||
NET_C(VV.ON, GND)
|
||||
NET_C(VV.IP, GND)
|
||||
//NETDEV_LOG(logX, VV.OP)
|
||||
//NETDEV_LOG(logY, 4V)
|
||||
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
NETDEV_VCVS(VV)
|
||||
NETDEV_PARAM(VV.G, 100000) // typical OP-AMP amplification
|
||||
NETDEV_PARAM(VV.RO, 50) // typical OP-AMP amplification
|
||||
NETDEV_R(R1, 1000)
|
||||
NETDEV_R(R3, 10000) // ==> 10x amplification (inverting)
|
||||
|
||||
NET_C(4V, R1.1)
|
||||
NET_C(R1.2, VV.IN)
|
||||
NET_C(R3.1, VV.IN)
|
||||
NET_C(R3.2, VV.OP)
|
||||
NET_C(VV.ON, GND)
|
||||
NET_C(VV.IP, GND)
|
||||
NETDEV_LOG(logX, VV.OP)
|
||||
NETDEV_LOG(logY, 4V)
|
||||
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
// Impedance converter with resistor
|
||||
NETDEV_VCVS(VV)
|
||||
NETDEV_PARAM(VV.G, 100000) // typical OP-AMP amplification
|
||||
NETDEV_PARAM(VV.RO, 50) // typical OP-AMP amplification
|
||||
NETDEV_R(R3, 10000)
|
||||
|
||||
NET_C(4V, VV.IP)
|
||||
NET_C(R3.1, VV.IN)
|
||||
NET_C(R3.2, VV.OP)
|
||||
NET_C(VV.ON, GND)
|
||||
NETDEV_LOG(logX, VV.OP)
|
||||
NETDEV_LOG(logY, 4V)
|
||||
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
// Impedance converter without resistor
|
||||
NETDEV_VCVS(VV)
|
||||
NETDEV_PARAM(VV.G, 100000) // typical OP-AMP amplification
|
||||
NETDEV_PARAM(VV.RO, 50) // typical OP-AMP amplification
|
||||
|
||||
NET_C(4V, VV.IP)
|
||||
NET_C(VV.IN, VV.OP)
|
||||
NET_C(VV.ON, GND)
|
||||
NETDEV_LOG(logX, VV.OP)
|
||||
NETDEV_LOG(logY, 4V)
|
||||
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/* Impedance converter current source opamp model from
|
||||
*
|
||||
* http://www.ecircuitcenter.com/Circuits/opmodel1/opmodel1.htm
|
||||
*
|
||||
* Bandwidth 10Mhz
|
||||
*
|
||||
*/
|
||||
NETDEV_VCCS(G1)
|
||||
NETDEV_PARAM(G1.G, 100) // typical OP-AMP amplification 100 * 1000 = 100000
|
||||
NETDEV_R(RP1, 1000)
|
||||
NETDEV_C(CP1, 1.59e-6) // <== change to 1.59e-3 for 10Khz bandwidth
|
||||
NETDEV_VCVS(EBUF)
|
||||
NETDEV_PARAM(EBUF.RO, 50)
|
||||
NETDEV_PARAM(EBUF.G, 1)
|
||||
|
||||
NET_C(G1.IP, 4V)
|
||||
NET_C(G1.IN, EBUF.OP)
|
||||
NET_C(EBUF.ON, GND)
|
||||
|
||||
NET_C(G1.ON, GND)
|
||||
NET_C(RP1.2, GND)
|
||||
NET_C(CP1.2, GND)
|
||||
NET_C(EBUF.IN, GND)
|
||||
|
||||
NET_C(RP1.1, G1.OP)
|
||||
NET_C(CP1.1, RP1.1)
|
||||
NET_C(EBUF.IP, RP1.1)
|
||||
|
||||
NETDEV_LOG(logX, EBUF.OP)
|
||||
NETDEV_LOG(logY, 4V)
|
||||
|
||||
#endif
|
||||
|
||||
NETLIST_END
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user