summaryrefslogtreecommitdiffstats
path: root/src/lib/netlist/core/logic_family.h
blob: 97084dd4dc0229d7b619c6550ebc5a766696bea8 (plain) (blame)
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
// license:BSD-3-Clause
// copyright-holders:Couriersud

///
/// \file logic_family.h
///

#ifndef NL_CORE_LOGIC_FAMILY_H_
#define NL_CORE_LOGIC_FAMILY_H_

#include "../nltypes.h"

#include "../plib/pstring.h"

namespace netlist
{
	/// \brief Logic families descriptors are used to create proxy devices.
	///  The logic family describes the analog capabilities of logic devices,
	///  inputs and outputs.

	class logic_family_desc_t
	{
	public:
		// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init,
		// modernize-use-equals-default)
		logic_family_desc_t() = default;

		logic_family_desc_t(const logic_family_desc_t &) = delete;
		logic_family_desc_t &operator=(const logic_family_desc_t &) = delete;

		// FOXME: Should be move constructible
		logic_family_desc_t(logic_family_desc_t &&) noexcept = delete;
		logic_family_desc_t &operator=(
			logic_family_desc_t &&) noexcept = delete;

		virtual ~logic_family_desc_t() noexcept = default;

		virtual device_arena::unique_ptr<devices::nld_base_d_to_a_proxy>
		create_d_a_proxy(netlist_state_t &anetlist, const pstring &name,
			const logic_output_t *proxied) const = 0;
		virtual device_arena::unique_ptr<devices::nld_base_a_to_d_proxy>
		create_a_d_proxy(netlist_state_t &anetlist, const pstring &name,
			const logic_input_t *proxied) const = 0;

		nl_fptype low_threshold_V(nl_fptype VN, nl_fptype VP) const noexcept
		{
			return VN + (VP - VN) * m_low_threshold_PCNT;
		}
		nl_fptype high_threshold_V(nl_fptype VN, nl_fptype VP) const noexcept
		{
			return VN + (VP - VN) * m_high_threshold_PCNT;
		}
		nl_fptype low_offset_V() const noexcept { return m_low_VO; }
		nl_fptype high_offset_V() const noexcept { return m_high_VO; }
		nl_fptype R_low() const noexcept { return m_R_low; }
		nl_fptype R_high() const noexcept { return m_R_high; }

		bool is_above_high_threshold_V(nl_fptype V, nl_fptype VN,
			nl_fptype VP) const noexcept
		{
			return V > high_threshold_V(VN, VP);
		}

		bool is_below_low_threshold_V(nl_fptype V, nl_fptype VN,
			nl_fptype VP) const noexcept
		{
			return V < low_threshold_V(VN, VP);
		}

		pstring vcc_pin() const { return pstring(m_vcc); }
		pstring gnd_pin() const { return pstring(m_gnd); }

		nl_fptype m_low_threshold_PCNT;  //!< low input threshold offset. If the
										 //!< input voltage is below this value
										 //!< times supply voltage, a "0" input
										 //!< is signalled
		nl_fptype m_high_threshold_PCNT; //!< high input threshold offset. If
										 //!< the input voltage is above the
										 //!< value times supply voltage, a "0"
										 //!< input is signalled
		nl_fptype m_low_VO;  //!< low output voltage offset. This voltage is
							 //!< output if the ouput is "0"
		nl_fptype m_high_VO; //!< high output voltage offset. The supply voltage
							 //!< minus this offset is output if the ouput is
							 //!< "1"
		nl_fptype m_R_low;  //!< low output resistance. Value of series resistor
							//!< used for low output
		nl_fptype m_R_high; //!< high output resistance. Value of series
							//!< resistor used for high output
		const char *m_vcc;  //!< default power pin name for positive supply
		const char *m_gnd;  //!< default power pin name for negative supply
	};

	/// \brief Base class for devices, terminals, outputs and inputs which
	/// support
	///  logic families.
	///  This class is a storage container to store the logic family for a
	///  netlist object. You will not directly use it. Please refer to
	///  \ref NETLIB_FAMILY to learn how to define a logic family for a device.
	///
	/// All terminals inherit the family description from the device
	/// The default is the ttl family, but any device can override the family.
	/// For individual terminals, the family can be overwritten as well.
	///

	class logic_family_t
	{
	public:
		logic_family_t()
		: m_logic_family(nullptr)
		{
		}
		logic_family_t(const logic_family_desc_t *d)
		: m_logic_family(d)
		{
		}

		logic_family_t(const logic_family_t &) = delete;
		logic_family_t &operator=(const logic_family_t &) = delete;

		// FIXME: logic family can be move constructible.
		logic_family_t(logic_family_t &&) noexcept = delete;
		logic_family_t &operator=(logic_family_t &&) noexcept = delete;

		const logic_family_desc_t *logic_family() const noexcept
		{
			return m_logic_family;
		}
		void set_logic_family(const logic_family_desc_t *fam) noexcept
		{
			m_logic_family = fam;
		}

	protected:
		~logic_family_t() noexcept = default; // prohibit polymorphic
											  // destruction
	private:
		const logic_family_desc_t *m_logic_family;
	};

} // namespace netlist

#endif // NL_CORE_LOGIC_FAMILY_H_