diff --git a/.gitattributes b/.gitattributes index c73f4459191..b3a0a682188 100644 --- a/.gitattributes +++ b/.gitattributes @@ -370,6 +370,7 @@ nl_examples/bjt_eb.c svneol=native#text/plain nl_examples/bjt_eb_pnp.c svneol=native#text/plain nl_examples/breakout.c svneol=native#text/plain nl_examples/cd4066.c svneol=native#text/plain +nl_examples/cdelay.c svneol=native#text/plain nl_examples/msx_mixer_stage.c svneol=native#text/plain nl_examples/ne555_astable.c svneol=native#text/plain nl_examples/opamp.c svneol=native#text/plain diff --git a/nl_examples/cdelay.c b/nl_examples/cdelay.c new file mode 100644 index 00000000000..9a6bdcc1aff --- /dev/null +++ b/nl_examples/cdelay.c @@ -0,0 +1,31 @@ +/* + * cdelay.c + * + */ + +#include "netlist/devices/net_lib.h" + +NETLIST_START(7400_astable) + + /* + * delay circuit + * + */ + + /* Standard stuff */ + + SOLVER(Solver, 48000) + PARAM(Solver.ACCURACY, 1e-20) + CLOCK(clk, 5000) + + TTL_7400_NAND(n1,clk,clk) + CAP(C, 1e-9) + NET_C(n1.Q, C.2) + NET_C(GND, C.1) + TTL_7400_NAND(n2,n1.Q, n1.Q) + + LOG(logclk, clk) + LOG(logn1Q, C.2) + LOG(logn2Q, n2.Q) + +NETLIST_END() diff --git a/src/emu/netlist/analog/nld_solver.c b/src/emu/netlist/analog/nld_solver.c index 7ede33a2664..4c1cf33fcc8 100644 --- a/src/emu/netlist/analog/nld_solver.c +++ b/src/emu/netlist/analog/nld_solver.c @@ -106,9 +106,28 @@ ATTR_COLD void netlist_matrix_solver_t::setup(netlist_net_t::list_t &nets, NETLI } } -ATTR_HOT void netlist_matrix_solver_t::update_inputs() +ATTR_HOT double netlist_matrix_solver_t::update_inputs(const double hn) { + double m_xx = 0.0001; +#if NEW_LTE + for (netlist_analog_output_t * const *p = m_inps.first(); p != NULL; p = m_inps.next(p)) + { + netlist_net_t *n = (*p)->m_proxied_net; + double DD_n = (n->m_cur_Analog - n->m_last_Analog) / hn; + double DD2 = (DD_n - n->m_DD_n_m_1) / (hn + n->m_h_n_m_1); + n->m_DD_n_m_1 = DD_n; + n->m_h_n_m_1 = hn; + double xx; + if (fabs(DD2) > 1e-100) + xx=sqrt(1.0e-3/fabs(0.5*DD2)); + else + xx=0.0001; + if (xxnet().m_last_Analog = (*p)->net().m_cur_Analog; } #endif - + return m_xx; } @@ -159,8 +178,14 @@ ATTR_HOT void netlist_matrix_solver_t::schedule() if (!m_Q_sync.net().is_queued()) m_Q_sync.net().push_to_queue(m_params.m_nt_sync_delay); #else - if (solve()) - update_inputs(); +#if NEW_LTE + double xx = solve(); + if (xx<10e-6) + if (!m_Q_sync.net().is_queued()) + m_Q_sync.net().push_to_queue(netlist_time::from_double(xx)); +#else + solve(); +#endif #endif } @@ -178,8 +203,14 @@ ATTR_COLD void netlist_matrix_solver_t::reset() ATTR_COLD void netlist_matrix_solver_t::update() { - if (solve()) - update_inputs(); +#if NEW_LTE + double xx = solve(); + if (xx<10e-6) + if (!m_Q_sync.net().is_queued()) + m_Q_sync.net().push_to_queue(netlist_time::from_double(xx)); +#else + solve(); +#endif } @@ -190,7 +221,7 @@ ATTR_HOT void netlist_matrix_solver_t::step(const netlist_time delta) m_steps[k]->step_time(dd); } -ATTR_HOT bool netlist_matrix_solver_t::solve() +ATTR_HOT double netlist_matrix_solver_t::solve() { netlist_time now = owner().netlist().time(); @@ -198,7 +229,7 @@ ATTR_HOT bool netlist_matrix_solver_t::solve() // We are already up to date. Avoid oscillations. if (delta < netlist_time::from_nsec(1)) - return true; + return 1.0; NL_VERBOSE_OUT(("Step!\n")); /* update all terminals for new time step */ @@ -223,7 +254,7 @@ ATTR_HOT bool netlist_matrix_solver_t::solve() { owner().netlist().warning("NEWTON_LOOPS exceeded ... reschedule"); m_Q_sync.net().push_to_queue(m_params.m_nt_sync_delay); - return false; + return 1.0; } } else @@ -231,7 +262,7 @@ ATTR_HOT bool netlist_matrix_solver_t::solve() while (solve_non_dynamic() > m_params.m_gs_loops) owner().netlist().warning("Non-Dynamic Solve iterations exceeded .. Consider increasing RESCHED_LOOPS"); } - return true; + return update_inputs(delta.as_double()); } // ---------------------------------------------------------------------------------------- @@ -770,25 +801,33 @@ NETLIB_UPDATE(solver) this_resched[i] = m_mat_solvers[i]->solve(); } #else + // FIXME: parameter + double m_xx = m_inc.as_double() * 100; for (int i = 0; i < t_cnt; i++) { if (m_mat_solvers[i]->is_timestep()) - if (m_mat_solvers[i]->solve()) - m_mat_solvers[i]->update_inputs(); + { + double xx = m_mat_solvers[i]->solve(); + if (m_xx > xx) + m_xx = xx; + } } #endif /* step circuit */ if (!m_Q_step.net().is_queued()) +#if NEW_LTE + m_Q_step.net().push_to_queue(netlist_time::from_double(m_xx)); +#else m_Q_step.net().push_to_queue(m_inc); +#endif } ATTR_COLD void NETLIB_NAME(solver)::solve_all() { for (int i = 0; i < m_mat_solvers.count(); i++) //m_mat_solvers[i]->m_Q_sync.net().push_to_queue(m_mat_solvers[i]->m_params.m_nt_sync_delay); - if (m_mat_solvers[i]->solve()) - m_mat_solvers[i]->update_inputs(); + m_mat_solvers[i]->solve(); } diff --git a/src/emu/netlist/analog/nld_solver.h b/src/emu/netlist/analog/nld_solver.h index 5d592cbd0f5..12e1863f475 100644 --- a/src/emu/netlist/analog/nld_solver.h +++ b/src/emu/netlist/analog/nld_solver.h @@ -9,8 +9,6 @@ #include "../nl_setup.h" #include "../nl_base.h" -#define NEW_INPUT (1) - // ---------------------------------------------------------------------------------------- // Macros // ---------------------------------------------------------------------------------------- @@ -51,9 +49,9 @@ public: ATTR_HOT virtual int solve_non_dynamic() = 0; ATTR_HOT virtual void step(const netlist_time delta); - ATTR_HOT bool solve(); + ATTR_HOT double solve(); - ATTR_HOT void update_inputs(); + ATTR_HOT double update_inputs(const double hn); ATTR_HOT void update_dynamic(); ATTR_HOT void schedule(); diff --git a/src/emu/netlist/devices/nld_log.c b/src/emu/netlist/devices/nld_log.c index b98076e26cb..608e01a3a87 100644 --- a/src/emu/netlist/devices/nld_log.c +++ b/src/emu/netlist/devices/nld_log.c @@ -22,7 +22,7 @@ NETLIB_RESET(log) NETLIB_UPDATE(log) { - fprintf(m_file, "%e %e\n", netlist().time().as_double(), INPANALOG(m_I)); + fprintf(m_file, "%20.9e %e\n", netlist().time().as_double(), INPANALOG(m_I)); } NETLIB_NAME(log)::~NETLIB_NAME(log)() diff --git a/src/emu/netlist/devices/nld_system.c b/src/emu/netlist/devices/nld_system.c index 962261458c7..b49e1392ffb 100644 --- a/src/emu/netlist/devices/nld_system.c +++ b/src/emu/netlist/devices/nld_system.c @@ -91,7 +91,9 @@ ATTR_HOT ATTR_ALIGN void nld_d_to_a_proxy::update() { double R = INPLOGIC(m_I) ? m_family_desc->m_R_high : m_family_desc->m_R_low; double V = INPLOGIC(m_I) ? m_family_desc->m_high_V : m_family_desc->m_low_V; - //printf("%f %f\n", R, V); +#if NEW_LTE + m_R.update_dev(); +#endif OUTANALOG(m_Q, V); m_R.set_R(R); } diff --git a/src/emu/netlist/nl_base.c b/src/emu/netlist/nl_base.c index b274bde868b..8170ced7771 100644 --- a/src/emu/netlist/nl_base.c +++ b/src/emu/netlist/nl_base.c @@ -473,6 +473,10 @@ ATTR_COLD netlist_net_t::netlist_net_t(const type_t atype, const family_t afamil , m_time(netlist_time::zero) , m_active(0) , m_in_queue(2) +#if NEW_LTE + , m_DD_n_m_1(0.0) + , m_h_n_m_1(1e-6) +#endif { m_last_Q = 0; m_new_Q = 0; diff --git a/src/emu/netlist/nl_base.h b/src/emu/netlist/nl_base.h index cd820bf1c27..baacd515331 100644 --- a/src/emu/netlist/nl_base.h +++ b/src/emu/netlist/nl_base.h @@ -157,6 +157,9 @@ #include "pstring.h" #include "pstate.h" +#define NEW_INPUT (1) +#define NEW_LTE (0) + // ---------------------------------------------------------------------------------------- // Type definitions // ---------------------------------------------------------------------------------------- @@ -651,6 +654,10 @@ public: double m_last_Analog; double m_cur_Analog; double m_new_Analog; +#if NEW_LTE + double m_DD_n_m_1; + double m_h_n_m_1; +#endif };