1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
|
// license:GPL-2.0+
// copyright-holders:Couriersud
///
/// \file device.h
///
#ifndef NL_CORE_DEVICE_H_
#define NL_CORE_DEVICE_H_
#include "../nltypes.h"
#include "../plib/pstring.h"
#include "base_objects.h"
#include "logic_family.h"
#include "param.h"
namespace netlist
{
// -----------------------------------------------------------------------------
// core_device_t
// -----------------------------------------------------------------------------
// FIXME: belongs into detail namespace
class core_device_t : public detail::netlist_object_t
{
public:
core_device_t(netlist_state_t &owner, const pstring &name);
core_device_t(core_device_t &owner, const pstring &name);
PCOPYASSIGNMOVE(core_device_t, delete)
virtual ~core_device_t() noexcept = default;
void do_inc_active() noexcept
{
if (m_hint_deactivate)
{
if (++m_active_outputs == 1)
{
if (m_stats)
m_stats->m_stat_inc_active.inc();
inc_active();
}
}
}
void do_dec_active() noexcept
{
if (m_hint_deactivate)
if (--m_active_outputs == 0)
{
dec_active();
}
}
void set_hint_deactivate(bool v) noexcept { m_hint_deactivate = v; }
bool get_hint_deactivate() const noexcept { return m_hint_deactivate; }
// Has to be set in device reset
void set_active_outputs(int n) noexcept { m_active_outputs = n; }
// stats
struct stats_t
{
// NL_KEEP_STATISTICS
plib::pperftime_t<true> m_stat_total_time;
plib::pperfcount_t<true> m_stat_call_count;
plib::pperfcount_t<true> m_stat_inc_active;
};
stats_t * stats() const noexcept { return m_stats.get(); }
#if 0
virtual void update() noexcept { }
#endif
virtual void reset() { }
protected:
virtual void inc_active() noexcept { }
virtual void dec_active() noexcept { }
log_type & log();
public:
virtual void timestep(timestep_type ts_type, nl_fptype st) noexcept { plib::unused_var(ts_type, st); }
virtual void update_terminals() noexcept { }
virtual void update_param() noexcept {}
virtual bool is_dynamic() const noexcept { return false; }
virtual bool is_timestep() const noexcept { return false; }
private:
bool m_hint_deactivate;
state_var_s32 m_active_outputs;
device_arena::unique_ptr<stats_t> m_stats;
};
// -----------------------------------------------------------------------------
// base_device_t
// -----------------------------------------------------------------------------
class base_device_t : public core_device_t
{
public:
base_device_t(netlist_state_t &owner, const pstring &name);
base_device_t(base_device_t &owner, const pstring &name);
PCOPYASSIGNMOVE(base_device_t, delete)
~base_device_t() noexcept override = default;
template<class O, class C, typename... Args>
void create_and_register_subdevice(O& owner, const pstring &name, device_arena::unique_ptr<C> &dev, Args&&... args)
{
dev = state().make_pool_object<C>(owner, name, std::forward<Args>(args)...);
}
void register_subalias(const pstring &name, const detail::core_terminal_t &term);
void register_subalias(const pstring &name, const pstring &aliased);
void connect(const pstring &t1, const pstring &t2);
void connect(const detail::core_terminal_t &t1, const detail::core_terminal_t &t2);
protected:
//NETLIB_UPDATE_TERMINALSI() { }
private:
};
// -----------------------------------------------------------------------------
// device_t
// -----------------------------------------------------------------------------
class device_t : public base_device_t,
public logic_family_t
{
public:
device_t(netlist_state_t &owner, const pstring &name);
device_t(netlist_state_t &owner, const pstring &name,
const pstring &model);
// only needed by proxies
device_t(netlist_state_t &owner, const pstring &name,
const logic_family_desc_t *desc);
device_t(device_t &owner, const pstring &name);
// pass in a default model - this may be overwritten by PARAM(DEVICE.MODEL, "XYZ(...)")
device_t(device_t &owner, const pstring &name,
const pstring &model);
PCOPYASSIGNMOVE(device_t, delete)
~device_t() noexcept override = default;
protected:
//NETLIB_UPDATE_TERMINALSI() { }
private:
param_model_t m_model;
};
} // namespace netlist
#endif // NL_CORE_DEVICE_H_
|