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
164
165
166
167
|
// license:GPL-2.0+
// copyright-holders:Couriersud
///
/// \file param.h
///
#ifndef NL_CORE_ANALOG_H_
#define NL_CORE_ANALOG_H_
#include "../nltypes.h"
#include "base_objects.h"
#include "nets.h"
#include "../plib/plists.h"
#include "../plib/pstring.h"
#include <array>
#include <utility>
namespace netlist
{
// -----------------------------------------------------------------------------
// analog_t
// -----------------------------------------------------------------------------
class analog_t : public detail::core_terminal_t
{
public:
analog_t(core_device_t &dev, const pstring &aname, state_e state,
nldelegate delegate);
const analog_net_t & net() const noexcept
{
return plib::downcast<const analog_net_t &>(core_terminal_t::net());
}
analog_net_t & net() noexcept
{
return plib::downcast<analog_net_t &>(core_terminal_t::net());
}
solver::matrix_solver_t *solver() const noexcept;
};
/// \brief Base class for terminals.
///
/// Each \ref nld_twoterm object consists of two terminals. Terminals
/// are at the core of analog netlists and are connected to \ref net_t
/// objects.
///
class terminal_t : public analog_t
{
public:
/// \brief constructor
///
/// @param dev core_devict_t object owning the terminal
/// @param aname name of this terminal
/// @param otherterm pointer to the sibling terminal
terminal_t(core_device_t &dev, const pstring &aname, terminal_t *otherterm, nldelegate delegate);
/// \brief Returns voltage of connected net
///
/// @return voltage of net this terminal is connected to
nl_fptype operator ()() const noexcept
{
return net().Q_Analog();
}
/// @brief sets conductivity value of this terminal
///
/// @param G Conductivity
void set_conductivity(nl_fptype G) const noexcept
{
set_go_gt_I(-G, G, nlconst::zero());
}
void set_go_gt(nl_fptype GO, nl_fptype GT) const noexcept
{
set_go_gt_I(GO, GT, nlconst::zero());
}
void set_go_gt_I(nl_fptype GO, nl_fptype GT, nl_fptype I) const noexcept
{
// Check for rail nets ...
if (m_go != nullptr)
{
*m_Idr = I;
*m_go = GO;
*m_gt = GT;
}
}
void set_ptrs(nl_fptype *gt, nl_fptype *go, nl_fptype *Idr) noexcept(false);
private:
nl_fptype *m_Idr; ///< drive current
nl_fptype *m_go; ///< conductance for Voltage from other term
nl_fptype *m_gt; ///< conductance for total conductance
};
// -----------------------------------------------------------------------------
// analog_input_t
// -----------------------------------------------------------------------------
/// \brief terminal providing analog input voltage.
///
/// This terminal class provides a voltage measurement. The conductance against
/// ground is infinite.
class analog_input_t : public analog_t
{
public:
/// \brief Constructor
analog_input_t(core_device_t &dev, ///< owning device
const pstring &aname, ///< name of terminal
nldelegate delegate ///< delegate
);
/// \brief returns voltage at terminal.
/// \returns voltage at terminal.
nl_fptype operator()() const noexcept { return Q_Analog(); }
/// \brief returns voltage at terminal.
/// \returns voltage at terminal.
nl_fptype Q_Analog() const noexcept
{
return net().Q_Analog();
}
};
// -----------------------------------------------------------------------------
// analog_output_t
// -----------------------------------------------------------------------------
class analog_output_t : public analog_t
{
public:
analog_output_t(core_device_t &dev, const pstring &aname);
void push(nl_fptype val) noexcept
{
if (val != m_my_net.Q_Analog())
{
m_my_net.set_Q_Analog(val);
m_my_net.toggle_and_push_to_queue(netlist_time::quantum());
}
}
void initial(nl_fptype val) noexcept;
private:
analog_net_t m_my_net;
};
inline solver::matrix_solver_t *analog_t::solver() const noexcept
{
return (this->has_net() ? net().solver() : nullptr);
}
} // namespace netlist
#endif // NL_CORE_ANALOG_H_
|