mirror of
https://github.com/mamedev/mame.git
synced 2024-11-16 07:48:32 +01:00
Preliminary support for LTE dynamic time-stepping based on Local truncation error. This enables the possibility to connect a capacitor between ground and a TTL output and get a e.g. 100 ns delay with a 1nF capacitor.
Added an example circuit (cdelay.c) Changed the log device to support nano-second granularity. LTE is not yet enabled due to it's ugly test-state.
This commit is contained in:
parent
3b5b4fd0ea
commit
f3cf3a8e78
8 changed files with 102 additions and 20 deletions
1
.gitattributes
vendored
1
.gitattributes
vendored
|
@ -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
|
||||
|
|
31
nl_examples/cdelay.c
Normal file
31
nl_examples/cdelay.c
Normal file
|
@ -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()
|
|
@ -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 (xx<m_xx) m_xx = xx;
|
||||
}
|
||||
if (m_xx < 2e-9) m_xx = 2e-9;
|
||||
//printf("%20s %f us\n", name().cstr(), m_xx * 1000000.0);
|
||||
|
||||
#endif
|
||||
#if NEW_INPUT
|
||||
// avoid recursive calls. Inputs are updated outside this call
|
||||
for (netlist_analog_output_t * const *p = m_inps.first(); p != NULL; p = m_inps.next(p))
|
||||
|
@ -133,7 +152,7 @@ ATTR_HOT void netlist_matrix_solver_t::update_inputs()
|
|||
(*p)->net().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();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)()
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue