Added more device to netlist:

- R2R resistor network DAC.
- Dummy input device. This is used so that devices can exhibit terminals not yet used
  such as V+ for opamps.
- Added a very basic macro model for norton opamps (LM3900)
- Added a current controlled current source (CCCS)
This commit is contained in:
Couriersud 2014-06-29 19:07:59 +00:00
parent c52aeab839
commit 9f19e1446e
16 changed files with 362 additions and 77 deletions

4
.gitattributes vendored
View File

@ -2987,6 +2987,8 @@ src/emu/netlist/analog/nld_ms_direct.h svneol=native#text/plain
src/emu/netlist/analog/nld_ms_direct1.h svneol=native#text/plain
src/emu/netlist/analog/nld_ms_direct2.h svneol=native#text/plain
src/emu/netlist/analog/nld_ms_gauss_seidel.h svneol=native#text/plain
src/emu/netlist/analog/nld_opamps.c svneol=native#text/plain
src/emu/netlist/analog/nld_opamps.h svneol=native#text/plain
src/emu/netlist/analog/nld_solver.c svneol=native#text/plain
src/emu/netlist/analog/nld_solver.h svneol=native#text/plain
src/emu/netlist/analog/nld_switches.c svneol=native#text/plain
@ -3054,6 +3056,8 @@ src/emu/netlist/devices/nld_log.c svneol=native#text/plain
src/emu/netlist/devices/nld_log.h svneol=native#text/plain
src/emu/netlist/devices/nld_ne555.c svneol=native#text/plain
src/emu/netlist/devices/nld_ne555.h svneol=native#text/plain
src/emu/netlist/devices/nld_r2r_dac.c svneol=native#text/plain
src/emu/netlist/devices/nld_r2r_dac.h svneol=native#text/plain
src/emu/netlist/devices/nld_signal.h svneol=native#text/plain
src/emu/netlist/devices/nld_system.c svneol=native#text/plain
src/emu/netlist/devices/nld_system.h svneol=native#text/plain

View File

@ -13,32 +13,36 @@
NETLIB_START(VCCS)
{
register_param("G", m_G, 1.0);
register_param("RI", m_RI, 1.0 / netlist().gmin());
register_terminal("IP", m_IP);
register_terminal("IN", m_IN);
register_terminal("OP", m_OP);
register_terminal("ON", m_ON);
register_terminal("_OP1", m_OP1);
register_terminal("_ON1", m_ON1);
m_IP.m_otherterm = &m_IN; // <= this should be NULL and terminal be filtered out prior to solving...
m_IN.m_otherterm = &m_IP; // <= this should be NULL and terminal be filtered out prior to solving...
m_OP.m_otherterm = &m_IP;
m_OP1.m_otherterm = &m_IN;
m_ON.m_otherterm = &m_IP;
m_ON1.m_otherterm = &m_IN;
connect(m_OP, m_OP1);
connect(m_ON, m_ON1);
start_internal(1.0 / netlist().gmin());
m_gfac = 1.0;
}
void NETLIB_NAME(VCCS)::start_internal(const double def_RI)
{
register_param("G", m_G, 1.0);
register_param("RI", m_RI, def_RI);
register_terminal("IP", m_IP);
register_terminal("IN", m_IN);
register_terminal("OP", m_OP);
register_terminal("ON", m_ON);
register_terminal("_OP1", m_OP1);
register_terminal("_ON1", m_ON1);
m_IP.m_otherterm = &m_IN; // <= this should be NULL and terminal be filtered out prior to solving...
m_IN.m_otherterm = &m_IP; // <= this should be NULL and terminal be filtered out prior to solving...
m_OP.m_otherterm = &m_IP;
m_OP1.m_otherterm = &m_IN;
m_ON.m_otherterm = &m_IP;
m_ON1.m_otherterm = &m_IN;
connect(m_OP, m_OP1);
connect(m_ON, m_ON1);
}
NETLIB_RESET(VCCS)
{
const double m_mult = m_G.Value() * m_gfac; // 1.0 ==> 1V ==> 1A
@ -72,6 +76,31 @@ NETLIB_UPDATE(VCCS)
m_ON.schedule_solve();
}
// ----------------------------------------------------------------------------------------
// nld_CCCS
// ----------------------------------------------------------------------------------------
NETLIB_START(CCCS)
{
start_internal(1.0);
m_gfac = 1.0 / m_RI.Value();
}
NETLIB_RESET(CCCS)
{
NETLIB_NAME(VCCS)::reset();
}
NETLIB_UPDATE_PARAM(CCCS)
{
NETLIB_NAME(VCCS)::update_param();
}
NETLIB_UPDATE(CCCS)
{
NETLIB_NAME(VCCS)::update();
}
// ----------------------------------------------------------------------------------------
// nld_VCVS
// ----------------------------------------------------------------------------------------

View File

@ -17,34 +17,12 @@
#define VCCS(_name) \
NET_REGISTER_DEV(VCCS, _name)
#define CCCS(_name) \
NET_REGISTER_DEV(CCCS, _name)
#define VCVS(_name) \
NET_REGISTER_DEV(VCVS, _name)
// ----------------------------------------------------------------------------------------
// nld_CCCS
// ----------------------------------------------------------------------------------------
/*
* Current controlled current source
*
* IP ---+ +------> OP
* | |
* RI I
* RI => G => I IOut = (V(IP)-V(IN)) / RI * G
* RI I
* | |
* IN ---+ +------< ON
*
* G=1 ==> 1A ==> 1A
*
* RI = 1
*
* FIXME: This needs extremely high levels of accuracy to work
* With the current default of 1mv we can only measure
* currents of 1mA. Therefore not yet implemented.
*
*/
// ----------------------------------------------------------------------------------------
// nld_VCCS
@ -81,6 +59,8 @@ protected:
ATTR_COLD virtual void update_param();
ATTR_HOT ATTR_ALIGN void update();
ATTR_COLD void start_internal(const double def_RI);
netlist_terminal_t m_OP;
netlist_terminal_t m_ON;
@ -96,6 +76,49 @@ protected:
double m_gfac;
};
// ----------------------------------------------------------------------------------------
// nld_CCCS
// ----------------------------------------------------------------------------------------
/*
* Current controlled current source
*
* IP ---+ +------> OP
* | |
* RI I
* RI => G => I IOut = (V(IP)-V(IN)) / RI * G
* RI I
* | |
* IN ---+ +------< ON
*
* G=1 ==> 1A ==> 1A
*
* RI = 1
*
* FIXME: This needs extremely high levels of accuracy to work
* With the current default of 1mv we can only measure
* currents of 1mA.
*
*/
class NETLIB_NAME(CCCS) : public NETLIB_NAME(VCCS)
{
public:
ATTR_COLD NETLIB_NAME(CCCS)()
: NETLIB_NAME(VCCS)(CCCS), m_gfac(1.0) { }
//ATTR_COLD NETLIB_NAME(CCCS)(const family_t afamily)
//: netlist_device_t(afamily), m_gfac(1.0) { }
protected:
ATTR_COLD virtual void start();
ATTR_COLD virtual void reset();
ATTR_COLD virtual void update_param();
ATTR_HOT ATTR_ALIGN void update();
double m_gfac;
};
// ----------------------------------------------------------------------------------------
// nld_VCVS
// ----------------------------------------------------------------------------------------

View File

@ -144,8 +144,6 @@ ATTR_HOT inline int netlist_matrix_solver_gauss_seidel_t<m_N, _storage_N>::vsolv
if (s>rmax)
rmax = s;
}
//if (fabs(rmax) > 0.01)
// printf("rmin %f rmax %f\n", rmin, rmax);
#if 0
double frobA = sqrt(frob /(iN));
if (1 &&frobA < 1.0)
@ -167,6 +165,8 @@ ATTR_HOT inline int netlist_matrix_solver_gauss_seidel_t<m_N, _storage_N>::vsolv
ws = 2.0 / (1.0 + sqrt(1.0-rm));
else
ws = 1.0;
if (ws > 1.02 && rmax > 1.001)
printf("rmin %f rmax %f ws %f\n", rmin, rmax, ws);
#endif
}

View File

@ -0,0 +1,38 @@
/*
* nld_opamps.c
*
*/
#include "nld_opamps.h"
#include "../devices/net_lib.h"
NETLIST_START(opamp_lm3900)
/*
* Fast norton opamp model without bandwidth
*/
/* Terminal definitions for calling netlists */
ALIAS(PLUS, R1.1) // Positive input
ALIAS(MINUS, R2.1) // Negative input
ALIAS(OUT, G1.OP) // Opamp output ...
ALIAS(VM, G1.ON) // V- terminal
ALIAS(VP, DUMMY.I) // V+ terminal
DUMMY_INPUT(DUMMY)
/* The opamp model */
RES(R1, 1)
RES(R2, 1)
NET_C(R1.1, G1.IP)
NET_C(R2.1, G1.IN)
NET_C(R1.2, R2.2, G1.ON)
VCVS(G1)
PARAM(G1.G, 10000000)
//PARAM(G1.RI, 100)
PARAM(G1.RO, RES_K(8))
NETLIST_END()

View File

@ -0,0 +1,32 @@
// license:GPL-2.0+
// copyright-holders:Couriersud
/*
* nld_opamps.h
*
*/
#pragma once
#ifndef NLD_OPAMPS_H_
#define NLD_OPAMPS_H_
#include "../nl_base.h"
#include "../nl_setup.h"
#include "nld_twoterm.h"
// ----------------------------------------------------------------------------------------
// Macros
// ----------------------------------------------------------------------------------------
#define LM3900(_name) \
SUBMODEL(_name, opamp_lm3900)
// ----------------------------------------------------------------------------------------
// Devices ...
// ----------------------------------------------------------------------------------------
NETLIST_EXTERNAL(opamp_lm3900);
#endif /* NLD_OPAMPS_H_ */

View File

@ -46,6 +46,13 @@ ATTR_COLD NETLIB_NAME(twoterm)::NETLIB_NAME(twoterm)(const family_t afamily)
m_N.m_otherterm = &m_P;
}
ATTR_COLD NETLIB_NAME(twoterm)::NETLIB_NAME(twoterm)()
: netlist_device_t(TWOTERM)
{
m_P.m_otherterm = &m_N;
m_N.m_otherterm = &m_P;
}
NETLIB_START(twoterm)
{
}

View File

@ -88,6 +88,7 @@ class NETLIB_NAME(twoterm) : public netlist_device_t
{
public:
ATTR_COLD NETLIB_NAME(twoterm)(const family_t afamily);
ATTR_COLD NETLIB_NAME(twoterm)();
netlist_terminal_t m_P;
netlist_terminal_t m_N;

View File

@ -89,6 +89,8 @@ void netlist_factory_t::initialize()
ENTRY(D, DIODE, "model")
ENTRY(VCVS, VCVS, "-") // FIXME: STD parameters ?
ENTRY(VCCS, VCCS, "-")
ENTRY(CCCS, CCCS, "-")
ENTRY(dummy_input, DUMMY_INPUT, "-")
ENTRY(QBJT_EB, QBJT_EB, "model")
ENTRY(QBJT_switch, QBJT_SW, "model")
ENTRY(ttl_input, TTL_INPUT, "IN")
@ -129,6 +131,7 @@ void netlist_factory_t::initialize()
ENTRY(SN74LS629, SN74LS629, "CAP")
ENTRY(9316, TTL_9316, "+CLK,ENP,ENT,CLRQ,LOADQ,A,B,C,D")
ENTRY(NE555, NE555, "-")
ENTRY(r2r_dac, R2R_DAC, "+VIN,R,N")
ENTRY(4020_dip, CD_4020_DIP, "-")
ENTRY(4066_dip, CD_4066_DIP, "-")
ENTRY(7400_dip, TTL_7400_DIP, "-")

View File

@ -83,6 +83,8 @@
#include "nld_ne555.h"
#include "nld_r2r_dac.h"
#include "nld_log.h"
#include "../analog/nld_bjt.h"
@ -90,6 +92,7 @@
#include "../analog/nld_solver.h"
#include "../analog/nld_switches.h"
#include "../analog/nld_twoterm.h"
#include "../analog/nld_opamps.h"
#include "nld_legacy.h"

View File

@ -103,7 +103,7 @@ NETLIB_RESET(SN74LS629)
NETLIB_UPDATE(SN74LS629)
{
{
// recompute
// recompute
double freq;
double v_freq_2, v_freq_3, v_freq_4;
double v_freq = INPANALOG(m_FC);
@ -124,6 +124,7 @@ NETLIB_UPDATE(SN74LS629)
/* scale due to input resistance */
/* Polyfunctional3D_model created by zunzun.com using sum of squared absolute error */
v_freq_2 = v_freq * v_freq;
v_freq_3 = v_freq_2 * v_freq;
v_freq_4 = v_freq_3 * v_freq;

View File

@ -0,0 +1,39 @@
/*
* nld_R2R_dac.c
*
*/
#include "nld_r2r_dac.h"
NETLIB_START(r2r_dac)
{
NETLIB_NAME(twoterm)::start();
register_terminal("VOUT", m_P);
register_terminal("VGND", m_N);
register_param("R", m_R, 1.0);
register_param("VIN", m_VIN, 1.0);
register_param("N", m_num, 1);
register_param("VAL", m_val, 1);
}
NETLIB_RESET(r2r_dac)
{
NETLIB_NAME(twoterm)::reset();
}
NETLIB_UPDATE(r2r_dac)
{
NETLIB_NAME(twoterm)::update();
}
NETLIB_UPDATE_PARAM(r2r_dac)
{
//printf("updating %s to %f\n", name().cstr(), m_R.Value());
update_dev();
double V = m_VIN.Value() / (double) (1 << m_num.Value()) * (double) m_val.Value();
this->set(1.0 / m_R.Value(), V, 0.0);
}

View File

@ -0,0 +1,66 @@
// license:GPL-2.0+
// copyright-holders:Couriersud
/*
* nld_R2R_DAC.h
*
* DMR2R_DAC: R-2R DAC
*
* Generic R-2R DAC ... This is fast.
* 2R
* Bit n >----RRR----+---------> Vout
* |
* R
* R R
* R
* |
* .
* .
* 2R |
* Bit 2 >----RRR----+
* |
* R
* R R
* R
* |
* 2R |
* Bit 1 >----RRR----+
* |
* R
* R 2R
* R
* |
* V0
*
* Using Thevenin's Theorem, this can be written as
*
* +---RRR-----------> Vout
* |
* V
* V V = VAL / 2^n * Vin
* V
* |
* V0
*
*/
#ifndef NLD_R2R_DAC_H_
#define NLD_R2R_DAC_H_
#include "../nl_base.h"
#include "../analog/nld_twoterm.h"
#define R2R_DAC(_name, _VIN, _R, _N) \
NET_REGISTER_DEV(r2r_dac, _name) \
NETDEV_PARAMI(_name, VIN, _VIN) \
NETDEV_PARAMI(_name, R, _R) \
NETDEV_PARAMI(_name, N, _N)
NETLIB_DEVICE_WITH_PARAMS_DERIVED(r2r_dac, twoterm,
netlist_param_double_t m_VIN;
netlist_param_double_t m_R;
netlist_param_int_t m_num;
netlist_param_int_t m_val;
);
#endif /* NLD_R2R_DAC_H_ */

View File

@ -13,32 +13,35 @@
#include "../nl_base.h"
#include "../analog/nld_twoterm.h"
// ----------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// Macros
// ----------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------
#define TTL_INPUT(_name, _v) \
NET_REGISTER_DEV(ttl_input, _name) \
#define TTL_INPUT(_name, _v) \
NET_REGISTER_DEV(ttl_input, _name) \
PARAM(_name.IN, _v)
#define ANALOG_INPUT(_name, _v) \
NET_REGISTER_DEV(analog_input, _name) \
#define ANALOG_INPUT(_name, _v) \
NET_REGISTER_DEV(analog_input, _name) \
PARAM(_name.IN, _v)
#define MAINCLOCK(_name, _freq) \
NET_REGISTER_DEV(mainclock, _name) \
#define MAINCLOCK(_name, _freq) \
NET_REGISTER_DEV(mainclock, _name) \
PARAM(_name.FREQ, _freq)
#define CLOCK(_name, _freq) \
NET_REGISTER_DEV(clock, _name) \
#define CLOCK(_name, _freq) \
NET_REGISTER_DEV(clock, _name) \
PARAM(_name.FREQ, _freq)
#define GNDA() \
#define GNDA() \
NET_REGISTER_DEV(gnd, GND)
// ----------------------------------------------------------------------------------------
#define DUMMY_INPUT(_name) \
NET_REGISTER_DEV(dummy_input, _name)
// -----------------------------------------------------------------------------
// mainclock
// ----------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------
NETLIB_DEVICE_WITH_PARAMS(mainclock,
public:
@ -50,9 +53,9 @@ public:
ATTR_HOT inline static void mc_update(netlist_logic_net_t &net);
);
// ----------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// clock
// ----------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------
NETLIB_DEVICE_WITH_PARAMS(clock,
netlist_ttl_input_t m_feedback;
@ -63,9 +66,9 @@ NETLIB_DEVICE_WITH_PARAMS(clock,
);
// ----------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// Special support devices ...
// ----------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------
NETLIB_DEVICE_WITH_PARAMS(ttl_input,
netlist_ttl_output_t m_Q;
@ -79,17 +82,17 @@ NETLIB_DEVICE_WITH_PARAMS(analog_input,
netlist_param_double_t m_IN;
);
// ----------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// nld_gnd
// ----------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------
class nld_gnd : public netlist_device_t
class NETLIB_NAME(gnd) : public netlist_device_t
{
public:
ATTR_COLD nld_gnd()
ATTR_COLD NETLIB_NAME(gnd)()
: netlist_device_t(GND) { }
ATTR_COLD virtual ~nld_gnd() {}
ATTR_COLD virtual ~NETLIB_NAME(gnd)() {}
protected:
@ -112,10 +115,42 @@ private:
};
// -----------------------------------------------------------------------------
// nld_dummy_input
// -----------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
class NETLIB_NAME(dummy_input) : public netlist_device_t
{
public:
ATTR_COLD NETLIB_NAME(dummy_input)()
: netlist_device_t(DUMMY) { }
ATTR_COLD virtual ~NETLIB_NAME(dummy_input)() {}
protected:
ATTR_COLD void start()
{
register_input("I", m_I);
}
ATTR_COLD void reset()
{
}
ATTR_HOT ATTR_ALIGN void update()
{
}
private:
netlist_analog_input_t m_I;
};
// -----------------------------------------------------------------------------
// netdev_a_to_d
// ----------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------
class nld_a_to_d_proxy : public netlist_device_t
{
@ -155,9 +190,9 @@ protected:
};
// ----------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// nld_base_d_to_a_proxy
// ----------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------
class nld_base_d_to_a_proxy : public netlist_device_t
{

View File

@ -33,6 +33,7 @@ NETLISTOBJS+= \
$(NETLISTOBJ)/analog/nld_solver.o \
$(NETLISTOBJ)/analog/nld_switches.o \
$(NETLISTOBJ)/analog/nld_twoterm.o \
$(NETLISTOBJ)/analog/nld_opamps.o \
$(NETLISTOBJ)/devices/nld_4020.o \
$(NETLISTOBJ)/devices/nld_4066.o \
$(NETLISTOBJ)/devices/nld_7400.o \
@ -60,6 +61,7 @@ NETLISTOBJS+= \
$(NETLISTOBJ)/devices/nld_74ls629.o \
$(NETLISTOBJ)/devices/nld_9316.o \
$(NETLISTOBJ)/devices/nld_ne555.o \
$(NETLISTOBJ)/devices/nld_r2r_dac.o \
$(NETLISTOBJ)/devices/nld_legacy.o \
$(NETLISTOBJ)/devices/net_lib.o \
$(NETLISTOBJ)/devices/nld_log.o \

View File

@ -336,10 +336,12 @@ public:
RESISTOR, // Resistor
CAPACITOR, // Capacitor
DIODE, // Diode
DUMMY, // DUMMY device without function
BJT_EB, // BJT(Ebers-Moll)
BJT_SWITCH, // BJT(Switch)
VCVS, // Voltage controlled voltage source
VCCS, // Voltage controlled current source
CCCS, // Current controlled current source
GND, // GND device
};