mirror of
https://github.com/holub/mame
synced 2025-04-20 15:32:45 +03:00
netlist:
- code maintenance. - added a parameter to various calls to indicate we are doing a newton-raphson. Preparation for relaxation. - rename plinearlist_t to plist_t - added parray_t - minor renames (nw)
This commit is contained in:
parent
0ca552d593
commit
ea1a9f0793
@ -556,7 +556,7 @@ void netlist_mame_sound_device_t::device_start()
|
||||
|
||||
// Configure outputs
|
||||
|
||||
plinearlist_t<nld_sound_out *> outdevs = netlist().get_device_list<nld_sound_out>();
|
||||
plist_t<nld_sound_out *> outdevs = netlist().get_device_list<nld_sound_out>();
|
||||
if (outdevs.count() == 0)
|
||||
fatalerror("No output devices");
|
||||
|
||||
@ -582,7 +582,7 @@ void netlist_mame_sound_device_t::device_start()
|
||||
m_num_inputs = 0;
|
||||
m_in = NULL;
|
||||
|
||||
plinearlist_t<nld_sound_in *> indevs = netlist().get_device_list<nld_sound_in>();
|
||||
plist_t<nld_sound_in *> indevs = netlist().get_device_list<nld_sound_in>();
|
||||
if (indevs.count() > 1)
|
||||
fatalerror("A maximum of one input device is allowed!");
|
||||
if (indevs.count() == 1)
|
||||
|
@ -66,27 +66,6 @@
|
||||
#define NETDEV_ANALOG_CALLBACK_MEMBER(_name) \
|
||||
void _name(const double data, const attotime &time)
|
||||
|
||||
|
||||
#if 0
|
||||
#define NETDEV_ANALOG_CALLBACK(_name, _IN, _class, _member, _tag) \
|
||||
{ \
|
||||
NETLIB_NAME(analog_callback) *dev = downcast<NETLIB_NAME(analog_callback) *>(netlist.register_dev(NET_NEW(analog_callback), # _name)); \
|
||||
netlist_analog_output_delegate d = netlist_analog_output_delegate(& _class :: _member, # _class "::" # _member, _tag, (_class *) 0); \
|
||||
dev->register_callback(d); \
|
||||
} \
|
||||
NET_CONNECT(_name, IN, _IN)
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#define NETDEV_SOUND_OUT(_name, _v, _m) \
|
||||
NET_REGISTER_DEV(sound_out, _name) \
|
||||
PARAM(_name.CHAN, _v) \
|
||||
PARAM(_name.MULT, _m)
|
||||
|
||||
#define NETDEV_SOUND_IN(_name) \
|
||||
NET_REGISTER_DEV(sound_in, _name)
|
||||
#endif
|
||||
|
||||
class netlist_mame_device_t;
|
||||
|
||||
class netlist_mame_t : public netlist_base_t
|
||||
@ -518,7 +497,7 @@ class NETLIB_NAME(analog_callback) : public netlist_device_t
|
||||
{
|
||||
public:
|
||||
NETLIB_NAME(analog_callback)()
|
||||
: netlist_device_t(), m_cpu_device(NULL) { }
|
||||
: netlist_device_t(), m_cpu_device(NULL), m_last(0) { }
|
||||
|
||||
ATTR_COLD void start()
|
||||
{
|
||||
|
@ -25,14 +25,14 @@ public:
|
||||
|
||||
ATTR_HOT inline int N() const { return (m_N == 0 ? m_dim : m_N); }
|
||||
|
||||
ATTR_HOT inline int vsolve_non_dynamic();
|
||||
ATTR_HOT inline int vsolve_non_dynamic(const bool newton_raphson);
|
||||
|
||||
protected:
|
||||
ATTR_COLD virtual void add_term(int net_idx, netlist_terminal_t *term);
|
||||
|
||||
ATTR_HOT virtual nl_double vsolve();
|
||||
|
||||
ATTR_HOT int solve_non_dynamic();
|
||||
ATTR_HOT int solve_non_dynamic(const bool newton_raphson);
|
||||
ATTR_HOT void build_LE_A();
|
||||
ATTR_HOT void build_LE_RHS();
|
||||
ATTR_HOT void LE_solve();
|
||||
@ -394,7 +394,7 @@ ATTR_HOT nl_double netlist_matrix_solver_direct_t<m_N, _storage_N>::vsolve()
|
||||
|
||||
|
||||
template <int m_N, int _storage_N>
|
||||
ATTR_HOT int netlist_matrix_solver_direct_t<m_N, _storage_N>::solve_non_dynamic()
|
||||
ATTR_HOT int netlist_matrix_solver_direct_t<m_N, _storage_N>::solve_non_dynamic(const bool newton_raphson)
|
||||
{
|
||||
nl_double new_v[_storage_N]; // = { 0.0 };
|
||||
|
||||
@ -416,13 +416,13 @@ ATTR_HOT int netlist_matrix_solver_direct_t<m_N, _storage_N>::solve_non_dynamic(
|
||||
}
|
||||
|
||||
template <int m_N, int _storage_N>
|
||||
ATTR_HOT inline int netlist_matrix_solver_direct_t<m_N, _storage_N>::vsolve_non_dynamic()
|
||||
ATTR_HOT inline int netlist_matrix_solver_direct_t<m_N, _storage_N>::vsolve_non_dynamic(const bool newton_raphson)
|
||||
{
|
||||
this->build_LE_A();
|
||||
this->build_LE_RHS();
|
||||
this->LE_solve();
|
||||
|
||||
return this->solve_non_dynamic();
|
||||
return this->solve_non_dynamic(newton_raphson);
|
||||
}
|
||||
|
||||
template <int m_N, int _storage_N>
|
||||
|
@ -18,7 +18,7 @@ public:
|
||||
netlist_matrix_solver_direct1_t(const netlist_solver_parameters_t ¶ms)
|
||||
: netlist_matrix_solver_direct_t<1, 1>(params, 1)
|
||||
{}
|
||||
ATTR_HOT inline int vsolve_non_dynamic();
|
||||
ATTR_HOT inline int vsolve_non_dynamic(const bool newton_raphson);
|
||||
protected:
|
||||
ATTR_HOT virtual nl_double vsolve();
|
||||
private:
|
||||
@ -34,7 +34,7 @@ ATTR_HOT nl_double netlist_matrix_solver_direct1_t::vsolve()
|
||||
return this->compute_next_timestep();
|
||||
}
|
||||
|
||||
ATTR_HOT inline int netlist_matrix_solver_direct1_t::vsolve_non_dynamic()
|
||||
ATTR_HOT inline int netlist_matrix_solver_direct1_t::vsolve_non_dynamic(const bool newton_raphson)
|
||||
{
|
||||
netlist_analog_net_t *net = m_nets[0];
|
||||
this->build_LE_A();
|
||||
|
@ -20,7 +20,7 @@ public:
|
||||
netlist_matrix_solver_direct2_t(const netlist_solver_parameters_t ¶ms)
|
||||
: netlist_matrix_solver_direct_t<2, 2>(params, 2)
|
||||
{}
|
||||
ATTR_HOT inline int vsolve_non_dynamic();
|
||||
ATTR_HOT inline int vsolve_non_dynamic(const bool newton_raphson);
|
||||
protected:
|
||||
ATTR_HOT virtual nl_double vsolve();
|
||||
private:
|
||||
@ -36,7 +36,7 @@ ATTR_HOT nl_double netlist_matrix_solver_direct2_t::vsolve()
|
||||
return this->compute_next_timestep();
|
||||
}
|
||||
|
||||
ATTR_HOT inline int netlist_matrix_solver_direct2_t::vsolve_non_dynamic()
|
||||
ATTR_HOT inline int netlist_matrix_solver_direct2_t::vsolve_non_dynamic(const bool newton_raphson)
|
||||
{
|
||||
build_LE_A();
|
||||
build_LE_RHS();
|
||||
|
@ -39,7 +39,7 @@ public:
|
||||
|
||||
ATTR_COLD virtual void log_stats();
|
||||
|
||||
ATTR_HOT virtual int vsolve_non_dynamic();
|
||||
ATTR_HOT virtual int vsolve_non_dynamic(const bool newton_raphson);
|
||||
protected:
|
||||
ATTR_HOT virtual nl_double vsolve();
|
||||
|
||||
@ -83,7 +83,7 @@ ATTR_HOT nl_double netlist_matrix_solver_SOR_t<m_N, _storage_N>::vsolve()
|
||||
}
|
||||
|
||||
template <int m_N, int _storage_N>
|
||||
ATTR_HOT inline int netlist_matrix_solver_SOR_t<m_N, _storage_N>::vsolve_non_dynamic()
|
||||
ATTR_HOT inline int netlist_matrix_solver_SOR_t<m_N, _storage_N>::vsolve_non_dynamic(const bool newton_raphson)
|
||||
{
|
||||
const int iN = this->N();
|
||||
bool resched = false;
|
||||
@ -181,8 +181,17 @@ ATTR_HOT inline int netlist_matrix_solver_SOR_t<m_N, _storage_N>::vsolve_non_dyn
|
||||
resched_cnt++;
|
||||
} while (resched && (resched_cnt < this->m_params.m_gs_loops));
|
||||
|
||||
for (int k = 0; k < iN; k++)
|
||||
this->m_nets[k]->m_cur_Analog = new_V[k];
|
||||
if (newton_raphson)
|
||||
{
|
||||
//printf("here %s\n", this->name().cstr());
|
||||
for (int k = 0; k < iN; k++)
|
||||
this->m_nets[k]->m_cur_Analog += 1.0 * (new_V[k] - this->m_nets[k]->m_cur_Analog);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int k = 0; k < iN; k++)
|
||||
this->m_nets[k]->m_cur_Analog = new_V[k];
|
||||
}
|
||||
|
||||
this->m_gs_total += resched_cnt;
|
||||
this->m_stat_calculations++;
|
||||
@ -191,7 +200,7 @@ ATTR_HOT inline int netlist_matrix_solver_SOR_t<m_N, _storage_N>::vsolve_non_dyn
|
||||
{
|
||||
// Fallback to direct solver ...
|
||||
this->m_gs_fail++;
|
||||
return netlist_matrix_solver_direct_t<m_N, _storage_N>::vsolve_non_dynamic();
|
||||
return netlist_matrix_solver_direct_t<m_N, _storage_N>::vsolve_non_dynamic(newton_raphson);
|
||||
}
|
||||
else {
|
||||
return resched_cnt;
|
||||
|
@ -40,7 +40,7 @@ public:
|
||||
|
||||
ATTR_COLD virtual void log_stats();
|
||||
|
||||
ATTR_HOT inline int vsolve_non_dynamic();
|
||||
ATTR_HOT inline int vsolve_non_dynamic(const bool newton_raphson);
|
||||
protected:
|
||||
ATTR_HOT virtual nl_double vsolve();
|
||||
|
||||
@ -126,7 +126,7 @@ ATTR_HOT nl_double netlist_matrix_solver_SOR_mat_t<m_N, _storage_N>::vsolve()
|
||||
}
|
||||
|
||||
template <int m_N, int _storage_N>
|
||||
ATTR_HOT inline int netlist_matrix_solver_SOR_mat_t<m_N, _storage_N>::vsolve_non_dynamic()
|
||||
ATTR_HOT inline int netlist_matrix_solver_SOR_mat_t<m_N, _storage_N>::vsolve_non_dynamic(const bool newton_raphson)
|
||||
{
|
||||
/* The matrix based code looks a lot nicer but actually is 30% slower than
|
||||
* the optimized code which works directly on the data structures.
|
||||
@ -293,7 +293,7 @@ ATTR_HOT inline int netlist_matrix_solver_SOR_mat_t<m_N, _storage_N>::vsolve_non
|
||||
|
||||
this->LE_solve();
|
||||
this->m_stat_calculations++;
|
||||
return netlist_matrix_solver_direct_t<m_N, _storage_N>::solve_non_dynamic();
|
||||
return netlist_matrix_solver_direct_t<m_N, _storage_N>::solve_non_dynamic(newton_raphson);
|
||||
}
|
||||
else {
|
||||
this->m_stat_calculations++;
|
||||
|
@ -236,7 +236,7 @@ void netlist_matrix_solver_t::solve_base(C *p)
|
||||
{
|
||||
update_dynamic();
|
||||
// Gauss-Seidel will revert to Gaussian elemination if steps exceeded.
|
||||
this_resched = p->vsolve_non_dynamic();
|
||||
this_resched = p->vsolve_non_dynamic(true);
|
||||
newton_loops++;
|
||||
} while (this_resched > 1 && newton_loops < m_params.m_nr_loops);
|
||||
|
||||
@ -250,7 +250,7 @@ void netlist_matrix_solver_t::solve_base(C *p)
|
||||
}
|
||||
else
|
||||
{
|
||||
p->vsolve_non_dynamic();
|
||||
p->vsolve_non_dynamic(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,18 +75,18 @@ class ATTR_ALIGNED(64) terms_t
|
||||
int m_railstart;
|
||||
|
||||
private:
|
||||
plinearlist_t<netlist_terminal_t *> m_term;
|
||||
plinearlist_t<int> m_net_other;
|
||||
plinearlist_t<nl_double> m_go;
|
||||
plinearlist_t<nl_double> m_gt;
|
||||
plinearlist_t<nl_double> m_Idr;
|
||||
plinearlist_t<nl_double *> m_other_curanalog;
|
||||
plist_t<netlist_terminal_t *> m_term;
|
||||
plist_t<int> m_net_other;
|
||||
plist_t<nl_double> m_go;
|
||||
plist_t<nl_double> m_gt;
|
||||
plist_t<nl_double> m_Idr;
|
||||
plist_t<nl_double *> m_other_curanalog;
|
||||
};
|
||||
|
||||
class netlist_matrix_solver_t : public netlist_device_t
|
||||
{
|
||||
public:
|
||||
typedef plinearlist_t<netlist_matrix_solver_t *> list_t;
|
||||
typedef plist_t<netlist_matrix_solver_t *> list_t;
|
||||
typedef netlist_core_device_t::list_t dev_list_t;
|
||||
|
||||
enum eSolverType
|
||||
@ -134,8 +134,8 @@ protected:
|
||||
|
||||
ATTR_COLD virtual void add_term(int net_idx, netlist_terminal_t *term) = 0;
|
||||
|
||||
plinearlist_t<netlist_analog_net_t *> m_nets;
|
||||
plinearlist_t<netlist_analog_output_t *> m_inps;
|
||||
plist_t<netlist_analog_net_t *> m_nets;
|
||||
plist_t<netlist_analog_output_t *> m_inps;
|
||||
|
||||
int m_stat_calculations;
|
||||
int m_stat_newton_raphson;
|
||||
|
@ -62,8 +62,7 @@ UINT32 truthtable_desc_t::get_ignored_extended(UINT32 i)
|
||||
* may change the output
|
||||
*/
|
||||
int bits = (1<<count_bits(nign));
|
||||
plinearlist_t<int> t;
|
||||
t.set_count(bits);
|
||||
parray_t<int> t(bits);
|
||||
|
||||
for (UINT32 j=1; j<bits; j++)
|
||||
{
|
||||
@ -172,8 +171,7 @@ ATTR_COLD void truthtable_desc_t::setup(const char **truthtable, UINT32 disabled
|
||||
nl_assert_always(times.count() == m_NO, "timing count not matching");
|
||||
|
||||
UINT16 val = 0;
|
||||
plinearlist_t<UINT8> tindex;
|
||||
tindex.set_count(m_NO);
|
||||
parray_t<UINT8> tindex(m_NO);
|
||||
|
||||
for (int j=0; j<m_NO; j++)
|
||||
{
|
||||
@ -196,8 +194,7 @@ ATTR_COLD void truthtable_desc_t::setup(const char **truthtable, UINT32 disabled
|
||||
}
|
||||
|
||||
// determine ignore
|
||||
plinearlist_t<UINT32> ign;
|
||||
ign.set_count(m_size);
|
||||
parray_t<UINT32> ign(m_size);
|
||||
|
||||
for (int j=0; j < m_size; j++)
|
||||
ign[j] = -1;
|
||||
|
@ -421,7 +421,7 @@ class netlist_core_terminal_t : public netlist_owned_object_t, public plinkedlis
|
||||
NETLIST_PREVENT_COPYING(netlist_core_terminal_t)
|
||||
public:
|
||||
|
||||
typedef plinearlist_t<netlist_core_terminal_t *> list_t;
|
||||
typedef plist_t<netlist_core_terminal_t *> list_t;
|
||||
|
||||
/* needed here ... */
|
||||
|
||||
@ -477,7 +477,7 @@ class ATTR_ALIGN netlist_terminal_t : public netlist_core_terminal_t
|
||||
NETLIST_PREVENT_COPYING(netlist_terminal_t)
|
||||
public:
|
||||
|
||||
typedef plinearlist_t<netlist_terminal_t * RESTRICT> list_t;
|
||||
typedef plist_t<netlist_terminal_t * RESTRICT> list_t;
|
||||
|
||||
ATTR_COLD netlist_terminal_t();
|
||||
|
||||
@ -598,7 +598,7 @@ class netlist_net_t : public netlist_object_t
|
||||
NETLIST_PREVENT_COPYING(netlist_net_t)
|
||||
public:
|
||||
|
||||
typedef plinearlist_t<netlist_net_t *> list_t;
|
||||
typedef plist_t<netlist_net_t *> list_t;
|
||||
|
||||
ATTR_COLD netlist_net_t(const family_t afamily);
|
||||
ATTR_COLD virtual ~netlist_net_t();
|
||||
@ -636,7 +636,7 @@ public:
|
||||
|
||||
ATTR_COLD void move_connections(netlist_net_t *new_net);
|
||||
|
||||
plinearlist_t<netlist_core_terminal_t *> m_core_terms; // save post-start m_list ...
|
||||
plist_t<netlist_core_terminal_t *> m_core_terms; // save post-start m_list ...
|
||||
|
||||
ATTR_HOT inline void set_Q_time(const netlist_sig_t &newQ, const netlist_time &at)
|
||||
{
|
||||
@ -678,7 +678,7 @@ class netlist_logic_net_t : public netlist_net_t
|
||||
NETLIST_PREVENT_COPYING(netlist_logic_net_t)
|
||||
public:
|
||||
|
||||
typedef plinearlist_t<netlist_logic_net_t *> list_t;
|
||||
typedef plist_t<netlist_logic_net_t *> list_t;
|
||||
|
||||
ATTR_COLD netlist_logic_net_t();
|
||||
ATTR_COLD virtual ~netlist_logic_net_t() { };
|
||||
@ -739,7 +739,7 @@ class netlist_analog_net_t : public netlist_net_t
|
||||
NETLIST_PREVENT_COPYING(netlist_analog_net_t)
|
||||
public:
|
||||
|
||||
typedef plinearlist_t<netlist_analog_net_t *> list_t;
|
||||
typedef plist_t<netlist_analog_net_t *> list_t;
|
||||
|
||||
ATTR_COLD netlist_analog_net_t();
|
||||
ATTR_COLD virtual ~netlist_analog_net_t() { };
|
||||
@ -962,7 +962,7 @@ class netlist_core_device_t : public netlist_object_t, public netlist_logic_fami
|
||||
NETLIST_PREVENT_COPYING(netlist_core_device_t)
|
||||
public:
|
||||
|
||||
typedef plinearlist_t<netlist_core_device_t *> list_t;
|
||||
typedef plist_t<netlist_core_device_t *> list_t;
|
||||
|
||||
ATTR_COLD netlist_core_device_t(const family_t afamily);
|
||||
|
||||
@ -1067,7 +1067,7 @@ public:
|
||||
|
||||
ATTR_COLD void connect(netlist_core_terminal_t &t1, netlist_core_terminal_t &t2);
|
||||
|
||||
plinearlist_t<pstring, 20> m_terminals;
|
||||
plist_t<pstring> m_terminals;
|
||||
|
||||
protected:
|
||||
|
||||
@ -1149,9 +1149,9 @@ public:
|
||||
ATTR_COLD void log(const char *format, ...) const ATTR_PRINTF(2,3);
|
||||
|
||||
template<class _C>
|
||||
plinearlist_t<_C *> get_device_list()
|
||||
plist_t<_C *> get_device_list()
|
||||
{
|
||||
plinearlist_t<_C *> tmp;
|
||||
plist_t<_C *> tmp;
|
||||
for (netlist_device_t * const *entry = m_devices.first(); entry != NULL; entry = m_devices.next(entry))
|
||||
{
|
||||
_C *dev = dynamic_cast<_C *>(*entry);
|
||||
|
@ -87,7 +87,7 @@
|
||||
// Solver defines
|
||||
//============================================================
|
||||
|
||||
#define USE_MATRIX_GS (1)
|
||||
#define USE_MATRIX_GS (0)
|
||||
#define USE_PIVOT_SEARCH (0)
|
||||
#define USE_GABS (1)
|
||||
// savings are eaten up by effort
|
||||
|
@ -68,7 +68,7 @@ public:
|
||||
class netlist_factory_t
|
||||
{
|
||||
public:
|
||||
typedef plinearlist_t<net_device_t_base_factory *> list_t;
|
||||
typedef plist_t<net_device_t_base_factory *> list_t;
|
||||
|
||||
ATTR_COLD netlist_factory_t();
|
||||
ATTR_COLD ~netlist_factory_t();
|
||||
|
@ -194,7 +194,7 @@ ATTR_COLD void ptokenizer::error(const char *format, ...)
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
|
||||
pstring errmsg1 =pstring(format).vprintf(ap);
|
||||
pstring errmsg1 = pstring(format).vprintf(ap);
|
||||
va_end(ap);
|
||||
|
||||
verror(errmsg1, currentline_no(), currentline_str());
|
||||
|
@ -127,7 +127,7 @@ private:
|
||||
|
||||
pstring m_identifier_chars;
|
||||
pstring m_number_chars;
|
||||
plinearlist_t<pstring> m_tokens;
|
||||
plist_t<pstring> m_tokens;
|
||||
pstring m_whitespace;
|
||||
char m_string;
|
||||
|
||||
@ -182,7 +182,7 @@ private:
|
||||
class netlist_source_t
|
||||
{
|
||||
public:
|
||||
typedef plinearlist_t<netlist_source_t> list_t;
|
||||
typedef plist_t<netlist_source_t> list_t;
|
||||
|
||||
enum source_e
|
||||
{
|
||||
|
@ -104,7 +104,7 @@ public:
|
||||
typedef pnamedlist_t<link_t> tagmap_nstring_t;
|
||||
typedef pnamedlist_t<netlist_param_t *> tagmap_param_t;
|
||||
typedef pnamedlist_t<netlist_core_terminal_t *> tagmap_terminal_t;
|
||||
typedef plinearlist_t<link_t> tagmap_link_t;
|
||||
typedef plist_t<link_t> tagmap_link_t;
|
||||
|
||||
netlist_setup_t(netlist_base_t &netlist);
|
||||
~netlist_setup_t();
|
||||
@ -167,7 +167,7 @@ private:
|
||||
|
||||
netlist_factory_t *m_factory;
|
||||
|
||||
plinearlist_t<pstring> m_models;
|
||||
plist_t<pstring> m_models;
|
||||
|
||||
int m_proxy_cnt;
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
#define NLTIME_H_
|
||||
|
||||
#include "nl_config.h"
|
||||
#include "pstate.h"
|
||||
|
||||
//============================================================
|
||||
// MACROS
|
||||
@ -72,6 +73,11 @@ protected:
|
||||
INTERNALTYPE m_time;
|
||||
};
|
||||
|
||||
template<> ATTR_COLD inline void pstate_manager_t::save_item(netlist_time &nlt, const void *owner, const pstring &stname)
|
||||
{
|
||||
save_state_ptr(stname, DT_INT64, owner, sizeof(netlist_time::INTERNALTYPE), 1, nlt.get_internaltype_ptr(), false);
|
||||
}
|
||||
|
||||
ATTR_HOT inline const netlist_time operator-(const netlist_time &left, const netlist_time &right)
|
||||
{
|
||||
return netlist_time::from_raw(left.m_time - right.m_time);
|
||||
|
@ -19,7 +19,7 @@ private:
|
||||
nl_util() {};
|
||||
|
||||
public:
|
||||
typedef plinearlist_t<pstring, 10> pstring_list;
|
||||
typedef plist_t<pstring> pstring_list;
|
||||
|
||||
static pstring_list split(const pstring &str, const pstring &onstr, bool ignore_empty = false)
|
||||
{
|
||||
|
@ -14,31 +14,101 @@
|
||||
#include "pstring.h"
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// plinearlist_t: a simple list
|
||||
// parray_t: dynamic array
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <class _ListClass, int _NumElem = 0>
|
||||
class plinearlist_t
|
||||
template <class _ListClass>
|
||||
class parray_t
|
||||
{
|
||||
public:
|
||||
|
||||
ATTR_COLD plinearlist_t(int numElements = _NumElem)
|
||||
ATTR_COLD parray_t(int numElements)
|
||||
: m_list(0), m_capacity(0)
|
||||
{
|
||||
m_num_elements = numElements;
|
||||
if (m_num_elements == 0)
|
||||
set_capacity(numElements);
|
||||
}
|
||||
|
||||
ATTR_COLD parray_t(const parray_t &rhs)
|
||||
: m_list(0), m_capacity(0)
|
||||
{
|
||||
set_capacity(rhs.capacity());
|
||||
for (int i=0; i<m_capacity; i++)
|
||||
m_list[i] = rhs[i];
|
||||
}
|
||||
|
||||
ATTR_COLD parray_t &operator=(const parray_t &rhs)
|
||||
{
|
||||
set_capacity(rhs.capacity());
|
||||
for (int i=0; i<m_capacity; i++)
|
||||
m_list[i] = rhs[i];
|
||||
return *this;
|
||||
}
|
||||
|
||||
ATTR_COLD ~parray_t()
|
||||
{
|
||||
if (m_list != NULL)
|
||||
nl_free_array(m_list);
|
||||
m_list = NULL;
|
||||
}
|
||||
|
||||
ATTR_HOT inline operator _ListClass * () { return m_list; }
|
||||
ATTR_HOT inline operator const _ListClass * () const { return m_list; }
|
||||
|
||||
/* using the [] operator will not allow gcc to vectorize code because
|
||||
* basically a pointer is returned.
|
||||
* array works around this.
|
||||
*/
|
||||
|
||||
ATTR_HOT inline _ListClass *array() { return m_list; }
|
||||
|
||||
ATTR_HOT inline _ListClass& operator[](const int index) { return m_list[index]; }
|
||||
ATTR_HOT inline const _ListClass& operator[](const int index) const { return m_list[index]; }
|
||||
|
||||
ATTR_HOT inline int capacity() const { return m_capacity; }
|
||||
|
||||
protected:
|
||||
ATTR_COLD void set_capacity(const int new_capacity)
|
||||
{
|
||||
if (m_list != NULL)
|
||||
nl_free_array(m_list);
|
||||
if (new_capacity > 0)
|
||||
m_list = nl_alloc_array(_ListClass, new_capacity);
|
||||
else
|
||||
m_list = NULL;
|
||||
m_capacity = new_capacity;
|
||||
}
|
||||
|
||||
private:
|
||||
_ListClass * m_list;
|
||||
int m_capacity;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// plinearlist_t: a simple list
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <class _ListClass>
|
||||
class plist_t
|
||||
{
|
||||
public:
|
||||
|
||||
ATTR_COLD plist_t(const int numElements = 0)
|
||||
{
|
||||
m_capacity = numElements;
|
||||
if (m_capacity == 0)
|
||||
m_list = NULL;
|
||||
else
|
||||
m_list = nl_alloc_array(_ListClass, m_num_elements);
|
||||
m_list = nl_alloc_array(_ListClass, m_capacity);
|
||||
m_count = 0;
|
||||
}
|
||||
|
||||
ATTR_COLD plinearlist_t(const plinearlist_t &rhs)
|
||||
ATTR_COLD plist_t(const plist_t &rhs)
|
||||
{
|
||||
m_num_elements = rhs.capacity();
|
||||
if (m_num_elements == 0)
|
||||
m_capacity = rhs.capacity();
|
||||
if (m_capacity == 0)
|
||||
m_list = NULL;
|
||||
else
|
||||
m_list = nl_alloc_array(_ListClass, m_num_elements);
|
||||
m_list = nl_alloc_array(_ListClass, m_capacity);
|
||||
m_count = 0;
|
||||
for (int i=0; i<rhs.count(); i++)
|
||||
{
|
||||
@ -46,7 +116,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
ATTR_COLD plinearlist_t &operator=(const plinearlist_t &rhs)
|
||||
ATTR_COLD plist_t &operator=(const plist_t &rhs)
|
||||
{
|
||||
this->clear();
|
||||
for (int i=0; i<rhs.count(); i++)
|
||||
@ -57,7 +127,7 @@ public:
|
||||
}
|
||||
|
||||
|
||||
ATTR_COLD ~plinearlist_t()
|
||||
ATTR_COLD ~plist_t()
|
||||
{
|
||||
if (m_list != NULL)
|
||||
nl_free_array(m_list);
|
||||
@ -79,11 +149,11 @@ public:
|
||||
|
||||
ATTR_HOT inline void add(const _ListClass &elem)
|
||||
{
|
||||
if (m_count >= m_num_elements){
|
||||
int new_size = m_num_elements * 2;
|
||||
if (m_count >= m_capacity){
|
||||
int new_size = m_capacity * 2;
|
||||
if (new_size < 32)
|
||||
new_size = 32;
|
||||
resize(new_size);
|
||||
set_capacity(new_size);
|
||||
}
|
||||
|
||||
m_list[m_count++] = elem;
|
||||
@ -151,7 +221,7 @@ public:
|
||||
ATTR_HOT inline int count() const { return m_count; }
|
||||
ATTR_HOT inline bool is_empty() const { return (m_count == 0); }
|
||||
ATTR_HOT inline void clear() { m_count = 0; }
|
||||
ATTR_HOT inline int capacity() const { return m_num_elements; }
|
||||
ATTR_HOT inline int capacity() const { return m_capacity; }
|
||||
|
||||
ATTR_COLD void clear_and_free()
|
||||
{
|
||||
@ -162,28 +232,17 @@ public:
|
||||
clear();
|
||||
}
|
||||
|
||||
ATTR_COLD void set_count(const int new_count)
|
||||
{
|
||||
if (new_count < m_count)
|
||||
m_count = new_count;
|
||||
else
|
||||
{
|
||||
resize(new_count);
|
||||
m_count = new_count;
|
||||
}
|
||||
|
||||
}
|
||||
private:
|
||||
ATTR_COLD void resize(const int new_size)
|
||||
ATTR_COLD void set_capacity(const int new_capacity)
|
||||
{
|
||||
int cnt = count();
|
||||
if (new_size > 0)
|
||||
if (new_capacity > 0)
|
||||
{
|
||||
_ListClass *m_new = nl_alloc_array(_ListClass, new_size);
|
||||
_ListClass *m_new = nl_alloc_array(_ListClass, new_capacity);
|
||||
_ListClass *pd = m_new;
|
||||
|
||||
if (cnt > new_size)
|
||||
cnt = new_size;
|
||||
if (cnt > new_capacity)
|
||||
cnt = new_capacity;
|
||||
for (_ListClass *ps = m_list; ps < m_list + cnt; ps++, pd++)
|
||||
*pd = *ps;
|
||||
if (m_list != NULL)
|
||||
@ -198,55 +257,52 @@ private:
|
||||
m_list = NULL;
|
||||
m_count = 0;
|
||||
}
|
||||
m_num_elements = new_size;
|
||||
m_capacity = new_capacity;
|
||||
}
|
||||
|
||||
int m_count;
|
||||
_ListClass * m_list /* ATTR_ALIGN */;
|
||||
int m_num_elements;
|
||||
int m_capacity;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// pnamedlist_t: a simple list
|
||||
// pnamedlist_t: a simple list of elements which have a name() interface
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
#if (defined(__sun__) && defined(__svr4__)) || defined(__ANDROID__) || defined(__OpenBSD__)
|
||||
#undef _C
|
||||
#endif
|
||||
|
||||
template <class _C>
|
||||
class pnamedlist_t : public plinearlist_t<_C>
|
||||
template <class _ListClass>
|
||||
class pnamedlist_t : public plist_t<_ListClass>
|
||||
{
|
||||
public:
|
||||
_C find(const pstring name) const
|
||||
_ListClass find(const pstring &name) const
|
||||
{
|
||||
for (int i=0; i < this->count(); i++)
|
||||
if (get_name((*this)[i]) == name)
|
||||
return (*this)[i];
|
||||
return _C(NULL);
|
||||
return _ListClass(NULL);
|
||||
}
|
||||
|
||||
void remove_by_name(const pstring name)
|
||||
void remove_by_name(const pstring &name)
|
||||
{
|
||||
plinearlist_t<_C>::remove(find(name));
|
||||
plist_t<_ListClass>::remove(find(name));
|
||||
}
|
||||
|
||||
bool add(_C dev, bool allow_duplicate)
|
||||
bool add(_ListClass dev, bool allow_duplicate)
|
||||
{
|
||||
if (allow_duplicate)
|
||||
plinearlist_t<_C>::add(dev);
|
||||
plist_t<_ListClass>::add(dev);
|
||||
else
|
||||
{
|
||||
if (!(this->find(get_name(dev)) == _C(NULL)))
|
||||
if (!(this->find(get_name(dev)) == _ListClass(NULL)))
|
||||
return false;
|
||||
plinearlist_t<_C>::add(dev);
|
||||
plist_t<_ListClass>::add(dev);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename T> static const pstring get_name(T &elem) { return elem.name(); }
|
||||
template <typename T> static const pstring get_name(const T *elem) { return elem->name(); }
|
||||
template <typename T> static const pstring get_name(T *elem) { return elem->name(); }
|
||||
template <typename T> static const pstring get_name(const T &elem) { return elem.name(); }
|
||||
|
||||
};
|
||||
|
||||
@ -255,12 +311,12 @@ private:
|
||||
// pstack_t: a simple stack
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <class _StackClass, int _NumElem = 128>
|
||||
template <class _StackClass>
|
||||
class pstack_t
|
||||
{
|
||||
public:
|
||||
|
||||
ATTR_COLD pstack_t(int numElements = _NumElem)
|
||||
ATTR_COLD pstack_t(const int numElements = 128)
|
||||
: m_list(numElements)
|
||||
{
|
||||
}
|
||||
@ -304,7 +360,7 @@ public:
|
||||
ATTR_HOT inline int capacity() const { return m_list.capacity(); }
|
||||
|
||||
private:
|
||||
plinearlist_t<_StackClass, _NumElem> m_list;
|
||||
plist_t<_StackClass> m_list;
|
||||
};
|
||||
|
||||
template <class _ListClass>
|
||||
|
@ -8,8 +8,8 @@
|
||||
#ifndef PSTATE_H_
|
||||
#define PSTATE_H_
|
||||
|
||||
#include "nl_config.h"
|
||||
#include "nl_time.h"
|
||||
//#include "nl_config.h"
|
||||
//#include "nl_time.h"
|
||||
#include "plists.h"
|
||||
#include "pstring.h"
|
||||
|
||||
@ -79,7 +79,7 @@ class pstate_manager_t;
|
||||
class pstate_callback_t
|
||||
{
|
||||
public:
|
||||
typedef plinearlist_t<pstate_callback_t *> list_t;
|
||||
typedef plist_t<pstate_callback_t *> list_t;
|
||||
|
||||
virtual ~pstate_callback_t() { };
|
||||
|
||||
@ -91,7 +91,7 @@ protected:
|
||||
|
||||
struct pstate_entry_t
|
||||
{
|
||||
typedef plinearlist_t<pstate_entry_t *> list_t;
|
||||
typedef plist_t<pstate_entry_t *> list_t;
|
||||
|
||||
pstate_entry_t(const pstring &stname, const pstate_data_type_e dt, const void *owner,
|
||||
const int size, const int count, void *ptr, bool is_ptr)
|
||||
@ -157,11 +157,5 @@ private:
|
||||
|
||||
template<> ATTR_COLD void pstate_manager_t::save_item(pstate_callback_t &state, const void *owner, const pstring &stname);
|
||||
|
||||
template<> ATTR_COLD inline void pstate_manager_t::save_item(netlist_time &nlt, const void *owner, const pstring &stname)
|
||||
{
|
||||
save_state_ptr(stname, DT_INT64, owner, sizeof(netlist_time::INTERNALTYPE), 1, nlt.get_internaltype_ptr(), false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* PSTATE_H_ */
|
||||
|
@ -261,12 +261,6 @@ NETDEV_ANALOG_CALLBACK_MEMBER(fixedfreq_device::update_vid)
|
||||
col = rgb_t(colv, colv, colv);
|
||||
}
|
||||
|
||||
while (0 && pixels >= m_htotal)
|
||||
{
|
||||
bm->plot_box(m_last_x, m_last_y + m_sig_field * has_fields, m_htotal - 1 - m_last_x, 1, col);
|
||||
pixels -= m_htotal;
|
||||
m_last_x = 0;
|
||||
}
|
||||
bm->plot_box(m_last_x, m_last_y + m_sig_field * has_fields, pixels - m_last_x, 1, col);
|
||||
m_last_x = pixels;
|
||||
}
|
||||
@ -286,7 +280,7 @@ NETDEV_ANALOG_CALLBACK_MEMBER(fixedfreq_device::update_vid)
|
||||
|
||||
if (sync & 1)
|
||||
{
|
||||
m_last_y = m_vbackporch - m_vsync; // 6; // FIXME: needed for pong - need to be able to adjust screen parameters
|
||||
m_last_y = m_vbackporch - m_vsync;
|
||||
// toggle bitmap
|
||||
m_cur_bm ^= 1;
|
||||
update_screen_parameters(time - m_last_vsync_time);
|
||||
|
@ -108,8 +108,6 @@ public:
|
||||
|
||||
NETDEV_ANALOG_CALLBACK_MEMBER(sound_cb)
|
||||
{
|
||||
//printf("snd %f\n", newval);
|
||||
//dac_w(m_dac, 0, newval*64);
|
||||
m_dac->write_unsigned8(64*data);
|
||||
}
|
||||
|
||||
|
@ -148,7 +148,7 @@ public:
|
||||
|
||||
void init()
|
||||
{
|
||||
m_setup = new netlist_setup_t(*this);
|
||||
m_setup = nl_alloc(netlist_setup_t, *this);
|
||||
this->init_object(*this, "netlist");
|
||||
m_setup->init();
|
||||
}
|
||||
@ -302,181 +302,183 @@ static void listdevices()
|
||||
convert - convert a spice netlist
|
||||
-------------------------------------------------*/
|
||||
|
||||
struct sp_net_t
|
||||
class convert_t
|
||||
{
|
||||
public:
|
||||
sp_net_t(const pstring &aname)
|
||||
: m_name(aname), m_no_export(false) {}
|
||||
|
||||
const pstring &name() { return m_name;}
|
||||
nl_util::pstring_list &terminals() { return m_terminals; }
|
||||
void set_no_export() { m_no_export = true; }
|
||||
bool is_no_export() { return m_no_export; }
|
||||
|
||||
private:
|
||||
pstring m_name;
|
||||
bool m_no_export;
|
||||
nl_util::pstring_list m_terminals;
|
||||
};
|
||||
|
||||
struct sp_dev_t
|
||||
{
|
||||
public:
|
||||
sp_dev_t(const pstring atype, const pstring aname, const pstring amodel)
|
||||
: m_type(atype), m_name(aname), m_model(amodel), m_val(0), m_has_val(false)
|
||||
{}
|
||||
|
||||
sp_dev_t(const pstring atype, const pstring aname, double aval)
|
||||
: m_type(atype), m_name(aname), m_model(""), m_val(aval), m_has_val(true)
|
||||
{}
|
||||
|
||||
const pstring &name() { return m_name;}
|
||||
const pstring &type() { return m_type;}
|
||||
const pstring &model() { return m_model;}
|
||||
const double &value() { return m_val;}
|
||||
|
||||
bool has_model() { return m_model != ""; }
|
||||
bool has_value() { return m_has_val; }
|
||||
|
||||
private:
|
||||
pstring m_type;
|
||||
pstring m_name;
|
||||
pstring m_model;
|
||||
double m_val;
|
||||
bool m_has_val;
|
||||
};
|
||||
|
||||
static pnamedlist_t<sp_net_t *> nets;
|
||||
static pnamedlist_t<sp_dev_t *> devs;
|
||||
static plinearlist_t<pstring> alias;
|
||||
|
||||
static void add_term(pstring netname, pstring termname)
|
||||
{
|
||||
sp_net_t * net = nets.find(netname);
|
||||
if (net == NULL)
|
||||
void convert(pstring contents)
|
||||
{
|
||||
net = new sp_net_t(netname);
|
||||
nets.add(net, false);
|
||||
nl_util::pstring_list spnl = nl_util::split(contents, "\n");
|
||||
|
||||
// Add gnd net
|
||||
|
||||
nets.add(nl_alloc(sp_net_t, "0"), false);
|
||||
nets[0]->terminals().add("GND");
|
||||
|
||||
pstring line = "";
|
||||
|
||||
for (int i=0; i < spnl.count(); i++)
|
||||
{
|
||||
// Basic preprocessing
|
||||
pstring inl = spnl[i].trim().ucase();
|
||||
if (inl.startsWith("+"))
|
||||
line = line + inl.substr(1);
|
||||
else
|
||||
{
|
||||
process_line(line);
|
||||
line = inl;
|
||||
}
|
||||
}
|
||||
process_line(line);
|
||||
dump_nl();
|
||||
}
|
||||
net->terminals().add(termname);
|
||||
}
|
||||
|
||||
static struct {
|
||||
pstring sp_unit;
|
||||
pstring nl_func;
|
||||
double mult;
|
||||
} sp_units[] = {
|
||||
{"T", "", 1.0e12 },
|
||||
{"G", "", 1.0e9 },
|
||||
{"MEG", "RES_M(%g)", 1.0e6 },
|
||||
{"K", "RES_K(%g)", 1.0e3 },
|
||||
{"", "%g", 1.0e0 },
|
||||
{"M", "CAP_M(%g)", 1.0e-3 },
|
||||
{"U", "CAP_U(%g)", 1.0e-6 },
|
||||
{"µ", "CAP_U(%g)", 1.0e-6 },
|
||||
{"N", "CAP_N(%g)", 1.0e-9 },
|
||||
{"P", "CAP_P(%g)", 1.0e-12},
|
||||
{"F", "%ge-15", 1.0e-15},
|
||||
protected:
|
||||
struct sp_net_t
|
||||
{
|
||||
public:
|
||||
sp_net_t(const pstring &aname)
|
||||
: m_name(aname), m_no_export(false) {}
|
||||
|
||||
{"MIL", "%e", 25.4e-6},
|
||||
const pstring &name() { return m_name;}
|
||||
nl_util::pstring_list &terminals() { return m_terminals; }
|
||||
void set_no_export() { m_no_export = true; }
|
||||
bool is_no_export() { return m_no_export; }
|
||||
|
||||
{"-", "%g", 1.0 }
|
||||
};
|
||||
private:
|
||||
pstring m_name;
|
||||
bool m_no_export;
|
||||
nl_util::pstring_list m_terminals;
|
||||
};
|
||||
|
||||
static const pstring get_nl_val(const double val)
|
||||
{
|
||||
struct sp_dev_t
|
||||
{
|
||||
public:
|
||||
sp_dev_t(const pstring atype, const pstring aname, const pstring amodel)
|
||||
: m_type(atype), m_name(aname), m_model(amodel), m_val(0), m_has_val(false)
|
||||
{}
|
||||
|
||||
sp_dev_t(const pstring atype, const pstring aname, double aval)
|
||||
: m_type(atype), m_name(aname), m_model(""), m_val(aval), m_has_val(true)
|
||||
{}
|
||||
|
||||
const pstring &name() { return m_name;}
|
||||
const pstring &type() { return m_type;}
|
||||
const pstring &model() { return m_model;}
|
||||
const double &value() { return m_val;}
|
||||
|
||||
bool has_model() { return m_model != ""; }
|
||||
bool has_value() { return m_has_val; }
|
||||
|
||||
private:
|
||||
pstring m_type;
|
||||
pstring m_name;
|
||||
pstring m_model;
|
||||
double m_val;
|
||||
bool m_has_val;
|
||||
};
|
||||
|
||||
struct sp_unit {
|
||||
pstring sp_unit;
|
||||
pstring nl_func;
|
||||
double mult;
|
||||
};
|
||||
|
||||
|
||||
void add_term(pstring netname, pstring termname)
|
||||
{
|
||||
sp_net_t * net = nets.find(netname);
|
||||
if (net == NULL)
|
||||
{
|
||||
net = nl_alloc(sp_net_t, netname);
|
||||
nets.add(net, false);
|
||||
}
|
||||
net->terminals().add(termname);
|
||||
}
|
||||
|
||||
const pstring get_nl_val(const double val)
|
||||
{
|
||||
{
|
||||
int i = 0;
|
||||
while (m_sp_units[i].sp_unit != "-" )
|
||||
{
|
||||
if (m_sp_units[i].mult <= nl_math::abs(val))
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
return pstring::sprintf(m_sp_units[i].nl_func.cstr(), val / m_sp_units[i].mult);
|
||||
}
|
||||
}
|
||||
double get_sp_unit(const pstring &unit)
|
||||
{
|
||||
int i = 0;
|
||||
while (sp_units[i].sp_unit != "-" )
|
||||
while (m_sp_units[i].sp_unit != "-")
|
||||
{
|
||||
if (sp_units[i].mult <= nl_math::abs(val))
|
||||
break;
|
||||
if (m_sp_units[i].sp_unit == unit)
|
||||
return m_sp_units[i].mult;
|
||||
i++;
|
||||
}
|
||||
return pstring::sprintf(sp_units[i].nl_func.cstr(), val / sp_units[i].mult);
|
||||
fprintf(stderr, "Unit %s unknown\n", unit.cstr());
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
static double get_sp_unit(const pstring &unit)
|
||||
{
|
||||
int i = 0;
|
||||
while (sp_units[i].sp_unit != "-")
|
||||
{
|
||||
if (sp_units[i].sp_unit == unit)
|
||||
return sp_units[i].mult;
|
||||
i++;
|
||||
}
|
||||
fprintf(stderr, "Unit %s unknown\n", unit.cstr());
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
static double get_sp_val(const pstring &sin)
|
||||
{
|
||||
int p = sin.len() - 1;
|
||||
while (p>=0 && (sin.substr(p,1) < "0" || sin.substr(p,1) > "9"))
|
||||
p--;
|
||||
pstring val = sin.substr(0,p + 1);
|
||||
pstring unit = sin.substr(p + 1);
|
||||
double get_sp_val(const pstring &sin)
|
||||
{
|
||||
int p = sin.len() - 1;
|
||||
while (p>=0 && (sin.substr(p,1) < "0" || sin.substr(p,1) > "9"))
|
||||
p--;
|
||||
pstring val = sin.substr(0,p + 1);
|
||||
pstring unit = sin.substr(p + 1);
|
||||
|
||||
double ret = get_sp_unit(unit) * val.as_double();
|
||||
//printf("<%s> %s %d ==> %f\n", sin.cstr(), unit.cstr(), p, ret);
|
||||
return ret;
|
||||
}
|
||||
double ret = get_sp_unit(unit) * val.as_double();
|
||||
//printf("<%s> %s %d ==> %f\n", sin.cstr(), unit.cstr(), p, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void convert_dump_nl()
|
||||
{
|
||||
for (int i=0; i<alias.count(); i++)
|
||||
void dump_nl()
|
||||
{
|
||||
sp_net_t *net = nets.find(alias[i]);
|
||||
// use the first terminal ...
|
||||
printf("ALIAS(%s, %s)\n", alias[i].cstr(), net->terminals()[0].cstr());
|
||||
// if the aliased net only has this one terminal connected ==> don't dump
|
||||
if (net->terminals().count() == 1)
|
||||
net->set_no_export();
|
||||
}
|
||||
for (int i=0; i<devs.count(); i++)
|
||||
{
|
||||
if (devs[i]->has_value())
|
||||
printf("%s(%s, %s)\n", devs[i]->type().cstr(),
|
||||
devs[i]->name().cstr(), get_nl_val(devs[i]->value()).cstr());
|
||||
else if (devs[i]->has_model())
|
||||
printf("%s(%s, \"%s\")\n", devs[i]->type().cstr(),
|
||||
devs[i]->name().cstr(), devs[i]->model().cstr());
|
||||
else
|
||||
printf("%s(%s)\n", devs[i]->type().cstr(),
|
||||
devs[i]->name().cstr());
|
||||
}
|
||||
// print nets
|
||||
for (int i=0; i<nets.count(); i++)
|
||||
{
|
||||
sp_net_t * net = nets[i];
|
||||
if (!net->is_no_export())
|
||||
for (int i=0; i<alias.count(); i++)
|
||||
{
|
||||
//printf("Net %s\n", net->name().cstr());
|
||||
printf("NET_C(%s", net->terminals()[0].cstr() );
|
||||
for (int j=1; j<net->terminals().count(); j++)
|
||||
{
|
||||
printf(", %s", net->terminals()[j].cstr() );
|
||||
}
|
||||
printf(")\n");
|
||||
sp_net_t *net = nets.find(alias[i]);
|
||||
// use the first terminal ...
|
||||
printf("ALIAS(%s, %s)\n", alias[i].cstr(), net->terminals()[0].cstr());
|
||||
// if the aliased net only has this one terminal connected ==> don't dump
|
||||
if (net->terminals().count() == 1)
|
||||
net->set_no_export();
|
||||
}
|
||||
for (int i=0; i<devs.count(); i++)
|
||||
{
|
||||
if (devs[i]->has_value())
|
||||
printf("%s(%s, %s)\n", devs[i]->type().cstr(),
|
||||
devs[i]->name().cstr(), get_nl_val(devs[i]->value()).cstr());
|
||||
else if (devs[i]->has_model())
|
||||
printf("%s(%s, \"%s\")\n", devs[i]->type().cstr(),
|
||||
devs[i]->name().cstr(), devs[i]->model().cstr());
|
||||
else
|
||||
printf("%s(%s)\n", devs[i]->type().cstr(),
|
||||
devs[i]->name().cstr());
|
||||
}
|
||||
// print nets
|
||||
for (int i=0; i<nets.count(); i++)
|
||||
{
|
||||
sp_net_t * net = nets[i];
|
||||
if (!net->is_no_export())
|
||||
{
|
||||
//printf("Net %s\n", net->name().cstr());
|
||||
printf("NET_C(%s", net->terminals()[0].cstr() );
|
||||
for (int j=1; j<net->terminals().count(); j++)
|
||||
{
|
||||
printf(", %s", net->terminals()[j].cstr() );
|
||||
}
|
||||
printf(")\n");
|
||||
}
|
||||
}
|
||||
devs.clear_and_free();
|
||||
nets.clear_and_free();
|
||||
alias.clear();
|
||||
}
|
||||
alias.clear();
|
||||
devs.clear();
|
||||
nets.clear();
|
||||
}
|
||||
static void convert(core_options &opts)
|
||||
{
|
||||
pstring spnlf = filetobuf(opts.value("f"));
|
||||
nl_util::pstring_list spnl = nl_util::split(spnlf.replace("\n+",""), "\n");
|
||||
|
||||
// Add gnd net
|
||||
|
||||
nets.add(new sp_net_t("0"), false);
|
||||
nets[0]->terminals().add("GND");
|
||||
|
||||
for (int i=0; i < spnl.count(); i++)
|
||||
void process_line(const pstring &line)
|
||||
{
|
||||
pstring line = spnl[i].trim().ucase();
|
||||
if (line != "")
|
||||
{
|
||||
nl_util::pstring_list tt = nl_util::split(line, " ", true);
|
||||
@ -497,7 +499,7 @@ static void convert(core_options &opts)
|
||||
}
|
||||
else if (tt[0].equals(".ENDS"))
|
||||
{
|
||||
convert_dump_nl();
|
||||
dump_nl();
|
||||
printf("NETLIST_END()\n");
|
||||
}
|
||||
else
|
||||
@ -511,21 +513,21 @@ static void convert(core_options &opts)
|
||||
*/
|
||||
int nval =tt[4].as_long(&cerr);
|
||||
if ((!cerr || tt[4].startsWith("N")) && tt.count() > 5)
|
||||
devs.add(new sp_dev_t("QBJT", tt[0], tt[5]), false);
|
||||
devs.add(nl_alloc(sp_dev_t, "QBJT", tt[0], tt[5]), false);
|
||||
else
|
||||
devs.add(new sp_dev_t("QBJT", tt[0], tt[4]), false);
|
||||
devs.add(nl_alloc(sp_dev_t, "QBJT", tt[0], tt[4]), false);
|
||||
add_term(tt[1], tt[0] + ".C");
|
||||
add_term(tt[2], tt[0] + ".B");
|
||||
add_term(tt[3], tt[0] + ".E");
|
||||
}
|
||||
break;
|
||||
case 'R':
|
||||
devs.add(new sp_dev_t("RES", tt[0], get_sp_val(tt[3])), false);
|
||||
devs.add(nl_alloc(sp_dev_t, "RES", tt[0], get_sp_val(tt[3])), false);
|
||||
add_term(tt[1], tt[0] + ".1");
|
||||
add_term(tt[2], tt[0] + ".2");
|
||||
break;
|
||||
case 'C':
|
||||
devs.add(new sp_dev_t("CAP", tt[0], get_sp_val(tt[3])), false);
|
||||
devs.add(nl_alloc(sp_dev_t, "CAP", tt[0], get_sp_val(tt[3])), false);
|
||||
add_term(tt[1], tt[0] + ".1");
|
||||
add_term(tt[2], tt[0] + ".2");
|
||||
break;
|
||||
@ -533,7 +535,7 @@ static void convert(core_options &opts)
|
||||
// just simple Voltage sources ....
|
||||
if (tt[2].equals("0"))
|
||||
{
|
||||
devs.add(new sp_dev_t("ANALOG_INPUT", tt[0], get_sp_val(tt[3])), false);
|
||||
devs.add(nl_alloc(sp_dev_t, "ANALOG_INPUT", tt[0], get_sp_val(tt[3])), false);
|
||||
add_term(tt[1], tt[0] + ".Q");
|
||||
//add_term(tt[2], tt[0] + ".2");
|
||||
}
|
||||
@ -542,7 +544,7 @@ static void convert(core_options &opts)
|
||||
break;
|
||||
case 'D':
|
||||
// FIXME: Rewrite resistor value
|
||||
devs.add(new sp_dev_t("DIODE", tt[0], tt[3]), false);
|
||||
devs.add(nl_alloc(sp_dev_t, "DIODE", tt[0], tt[3]), false);
|
||||
add_term(tt[1], tt[0] + ".A");
|
||||
add_term(tt[2], tt[0] + ".K");
|
||||
break;
|
||||
@ -551,8 +553,33 @@ static void convert(core_options &opts)
|
||||
}
|
||||
}
|
||||
}
|
||||
convert_dump_nl();
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
pnamedlist_t<sp_net_t *> nets;
|
||||
pnamedlist_t<sp_dev_t *> devs;
|
||||
plist_t<pstring> alias;
|
||||
|
||||
static sp_unit m_sp_units[];
|
||||
};
|
||||
|
||||
convert_t::sp_unit convert_t::m_sp_units[] = {
|
||||
{"T", "", 1.0e12 },
|
||||
{"G", "", 1.0e9 },
|
||||
{"MEG", "RES_M(%g)", 1.0e6 },
|
||||
{"K", "RES_K(%g)", 1.0e3 },
|
||||
{"", "%g", 1.0e0 },
|
||||
{"M", "CAP_M(%g)", 1.0e-3 },
|
||||
{"U", "CAP_U(%g)", 1.0e-6 },
|
||||
{"µ", "CAP_U(%g)", 1.0e-6 },
|
||||
{"N", "CAP_N(%g)", 1.0e-9 },
|
||||
{"P", "CAP_P(%g)", 1.0e-12},
|
||||
{"F", "%ge-15", 1.0e-15},
|
||||
|
||||
{"MIL", "%e", 25.4e-6},
|
||||
|
||||
{"-", "%g", 1.0 }
|
||||
};
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
@ -585,7 +612,11 @@ int main(int argc, char *argv[])
|
||||
else if (cmd == "run")
|
||||
run(opts);
|
||||
else if (cmd == "convert")
|
||||
convert(opts);
|
||||
{
|
||||
pstring contents = filetobuf(opts.value("f"));
|
||||
convert_t converter;
|
||||
converter.convert(contents);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Unknown command %s\n", cmd.cstr());
|
||||
|
Loading…
Reference in New Issue
Block a user