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
|
// license:GPL-2.0+
// copyright-holders:Couriersud
/*
* nld_4020.c
*
*/
#include <devices/nlid_cmos.h>
#include "nld_4020.h"
namespace netlist
{
namespace devices
{
NETLIB_OBJECT(CD4020_sub)
{
NETLIB_CONSTRUCTOR(CD4020_sub)
NETLIB_FAMILY("CD4XXX")
, m_IP(*this, "IP")
, m_Q(*this, {{"Q1", "_Q2", "_Q3", "Q4", "Q5", "Q6", "Q7", "Q8", "Q9",
"Q10", "Q11", "Q12", "Q13", "Q14"}})
, m_cnt(*this, "m_cnt", 0)
{
}
NETLIB_RESETI()
{
m_IP.set_state(logic_t::STATE_INP_HL);
m_cnt = 0;
}
NETLIB_UPDATEI();
public:
void update_outputs(const unsigned cnt);
logic_input_t m_IP;
object_array_t<logic_output_t, 14> m_Q;
state_var<unsigned> m_cnt;
};
NETLIB_OBJECT(CD4020)
{
NETLIB_CONSTRUCTOR(CD4020)
NETLIB_FAMILY("CD4XXX")
, m_sub(*this, "sub")
, m_supply(*this, "supply")
, m_RESET(*this, "RESET")
{
register_subalias("IP", m_sub.m_IP);
register_subalias("Q1", m_sub.m_Q[0]);
register_subalias("Q4", m_sub.m_Q[3]);
register_subalias("Q5", m_sub.m_Q[4]);
register_subalias("Q6", m_sub.m_Q[5]);
register_subalias("Q7", m_sub.m_Q[6]);
register_subalias("Q8", m_sub.m_Q[7]);
register_subalias("Q9", m_sub.m_Q[8]);
register_subalias("Q10", m_sub.m_Q[9]);
register_subalias("Q11", m_sub.m_Q[10]);
register_subalias("Q12", m_sub.m_Q[11]);
register_subalias("Q13", m_sub.m_Q[12]);
register_subalias("Q14", m_sub.m_Q[13]);
register_subalias("VDD", m_supply.m_vdd);
register_subalias("VSS", m_supply.m_vss);
}
NETLIB_RESETI() { }
NETLIB_UPDATEI();
private:
NETLIB_SUB(CD4020_sub) m_sub;
NETLIB_SUB(vdd_vss) m_supply;
logic_input_t m_RESET;
};
NETLIB_UPDATE(CD4020_sub)
{
++m_cnt;
m_cnt &= 0x3fff;
update_outputs(m_cnt);
}
NETLIB_UPDATE(CD4020)
{
if (INPLOGIC(m_RESET))
{
m_sub.m_cnt = 0;
m_sub.m_IP.inactivate();
/* static */ const netlist_time reset_time = netlist_time::from_nsec(140);
OUTLOGIC(m_sub.m_Q[0], 0, reset_time);
for (int i=3; i<14; i++)
OUTLOGIC(m_sub.m_Q[i], 0, reset_time);
}
else
m_sub.m_IP.activate_hl();
}
inline NETLIB_FUNC_VOID(CD4020_sub, update_outputs, (const unsigned cnt))
{
/* static */ const netlist_time out_delayQn[14] = {
NLTIME_FROM_NS(180), NLTIME_FROM_NS(280),
NLTIME_FROM_NS(380), NLTIME_FROM_NS(480),
NLTIME_FROM_NS(580), NLTIME_FROM_NS(680),
NLTIME_FROM_NS(780), NLTIME_FROM_NS(880),
NLTIME_FROM_NS(980), NLTIME_FROM_NS(1080),
NLTIME_FROM_NS(1180), NLTIME_FROM_NS(1280),
NLTIME_FROM_NS(1380), NLTIME_FROM_NS(1480),
};
OUTLOGIC(m_Q[0], cnt & 1, out_delayQn[0]);
for (int i=3; i<14; i++)
OUTLOGIC(m_Q[i], (cnt >> i) & 1, out_delayQn[i]);
}
NETLIB_DEVICE_IMPL(CD4020)
} //namespace devices
} // namespace netlist
|