1 /*
2 * CvcTypes.hh
3 *
4 * Copyright 2014-2018 D. Mitch Bailey cvc at shuharisystem dot com
5 *
6 * This file is part of cvc.
7 *
8 * cvc is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * cvc is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with cvc. If not, see <http://www.gnu.org/licenses/>.
20 *
21 * You can download cvc from https://github.com/d-m-bailey/cvc.git
22 */
23
24 #ifndef CVCTYPES_HH_
25 #define CVCTYPES_HH_
26
27 #include <cstdint>
28 #include <string>
29 #include <sstream>
30 #include <cstring>
31 #include <stdexcept>
32 #include <cstdlib>
33 #include <unordered_map>
34
35 #ifndef INT64_MAX
36 #define INT64_MAX INT32_MAX
37 #endif
38
39 typedef uint32_t netId_t;
40 typedef uint32_t deviceId_t;
41 typedef uint32_t instanceId_t;
42
43 typedef int16_t voltage_t;
44 typedef uint32_t resistance_t;
45 typedef int32_t eventKey_t;
46
47 // Max resistance is 1G. Anything over that truncates to 1G with a warning.
48 #define INFINITE_RESISTANCE (UINT32_MAX)
49 #define MAX_RESISTANCE ((UINT32_MAX >> 2) - 1)
50
51 #define VOLTAGE_SCALE 1000
52 #define MAX_VOLTAGE (INT16_MAX - 1)
53 #define MIN_VOLTAGE (INT16_MIN + 1)
54
55 #define MIN_EVENT_TIME (INT32_MIN)
56 #define MAX_EVENT_TIME (INT32_MAX)
57
58 #define MAX_NET (UINT32_MAX - 1)
59 #define MAX_DEVICE (UINT32_MAX - 1)
60 #define MAX_SUBCIRCUIT (UINT32_MAX - 1)
61
62 #define UNKNOWN_NET UINT32_MAX
63 #define UNKNOWN_SUBCIRCUIT UINT32_MAX
64 #define UNKNOWN_DEVICE UINT32_MAX
65 #define UNKNOWN_INSTANCE UINT32_MAX
66
67 #define UNKNOWN_VOLTAGE (INT16_MAX)
68
69 #define DEFAULT_MOS_RESISTANCE "L/W*7000"
70 #define DEFAULT_RESISTANCE "R"
71 #define DEFAULT_UNKNOWN_RESISTANCE 1100100
72
73 #define MAX_PARALLEL_CIRCUIT_PORT_LIMIT 10
74
75 #define HIERARCHY_DELIMITER "/"
76 #define ALIAS_DELIMITER "~>"
77
78 #define IsMos_(theDeviceType) ((theDeviceType) == NMOS || (theDeviceType) == PMOS || (theDeviceType) == LDDN || (theDeviceType) == LDDP)
79 #define IsNmos_(theDeviceType) ((theDeviceType) == NMOS || (theDeviceType) == LDDN)
80 #define IsPmos_(theDeviceType) ((theDeviceType) == PMOS || (theDeviceType) == LDDP)
81
82 #define IsLesserVoltage_(theFirstVoltage, theSecondVoltage) (theFirstVoltage != UNKNOWN_VOLTAGE && theSecondVoltage != UNKNOWN_VOLTAGE && theFirstVoltage < theSecondVoltage)
83 #define IsLesserOrEqualVoltage_(theFirstVoltage, theSecondVoltage) (theFirstVoltage != UNKNOWN_VOLTAGE && theSecondVoltage != UNKNOWN_VOLTAGE && theFirstVoltage <= theSecondVoltage)
84 #define IsEqualVoltage_(theFirstVoltage, theSecondVoltage) (theFirstVoltage != UNKNOWN_VOLTAGE && theSecondVoltage != UNKNOWN_VOLTAGE && theFirstVoltage == theSecondVoltage)
85 #define IsGreaterVoltage_(theFirstVoltage, theSecondVoltage) (theFirstVoltage != UNKNOWN_VOLTAGE && theSecondVoltage != UNKNOWN_VOLTAGE && theFirstVoltage > theSecondVoltage)
86 #define IsGreaterOrEqualVoltage_(theFirstVoltage, theSecondVoltage) (theFirstVoltage != UNKNOWN_VOLTAGE && theSecondVoltage != UNKNOWN_VOLTAGE && theFirstVoltage >= theSecondVoltage)
87
from_string(std::string const & s)88 template <typename T> T from_string(std::string const & s) {
89 std::stringstream ss(s);
90 T result;
91 static const std::unordered_map<std::string, float> SISuffix = {
92 {"a", 1e-18},
93 {"f", 1e-15},
94 {"p", 1e-12},
95 {"n", 1e-9},
96 {"u", 1e-6},
97 {"m", 1e-3},
98 {"K", 1e3},
99 {"M", 1e6},
100 {"G", 1e9},
101 {"T", 1e12},
102 {"P", 1e15},
103 {"E", 1e18}
104 };
105 std::string mySuffix = "";
106 ss >> result; // TODO handle errors
107 ss >> mySuffix;
108 if ( mySuffix != "" ) {
109 result = result * SISuffix.at(mySuffix);
110 }
111 return result;
112 }
113
to_string(T theValue)114 template <typename T> std::string to_string(T theValue) {
115 std::ostringstream convert;
116 convert << theValue;
117 return convert.str();
118 }
119
120 enum relation_t { equals, lessThan, greaterThan, notLessThan, notGreaterThan };
121
122 // also used as bit offset in source connection status. do not use any offsets after fuse
123 enum modelType_t { NMOS = 0, PMOS, RESISTOR, CAPACITOR, DIODE, BIPOLAR, FUSE_ON, FUSE_OFF,
124 SWITCH_ON, SWITCH_OFF, MOSFET, LDDN, LDDP, BOX, UNKNOWN };
125
126 enum eventQueue_t { SIM_QUEUE, MAX_QUEUE, MIN_QUEUE };
127
128 enum queueStatus_t { ENQUEUE, DEQUEUE };
129
130 enum deviceStatus_t { MIN_INACTIVE = 0, MIN_PENDING, MAX_INACTIVE, MAX_PENDING, SIM_INACTIVE, SIM_PENDING };
131
132 enum netStatus_t { ANALOG = 0, MIN_POWER, SIM_POWER, MAX_POWER, NEEDS_MIN_CHECK, NEEDS_MAX_CHECK, NEEDS_MIN_CONNECTION, NEEDS_MAX_CONNECTION };
133 // NEEDS_MIN/MAX_CHECK for min/max prop through pmos/nmos
134 // NEEDS_MIN/MAX_CONNECTION for pmos/nmos connected as diode
135
136 enum shortDirection_t { SOURCE_TO_MASTER_DRAIN, DRAIN_TO_MASTER_SOURCE };
137
138 enum terminal_t { GATE = 1, SOURCE = 2, GS, DRAIN = 4, GD, SD, GSD, BULK = 8, GB, SB, GSB, DB, GDB, SDB, GSDB };
139
140 enum propagation_t { POWER_NETS_ONLY = 1, ALL_NETS_NO_FUSE, ALL_NETS_AND_FUSE };
141
142 enum cvcError_t { LEAK = 0, HIZ_INPUT, FORWARD_DIODE, NMOS_SOURCE_BULK, NMOS_GATE_SOURCE, NMOS_POSSIBLE_LEAK,
143 PMOS_SOURCE_BULK, PMOS_GATE_SOURCE, PMOS_POSSIBLE_LEAK, OVERVOLTAGE_VBG, OVERVOLTAGE_VBS, OVERVOLTAGE_VDS,
144 OVERVOLTAGE_VGS, MODEL_CHECK, EXPECTED_VOLTAGE, LDD_SOURCE, MIN_VOLTAGE_CONFLICT, MAX_VOLTAGE_CONFLICT, FUSE_ERROR, ERROR_TYPE_COUNT };
145 // Flag Constants
146
147 #define PRINT_CIRCUIT_ON true
148 #define PRINT_CIRCUIT_OFF false
149 #define PRINT_HIERARCHY_ON true
150 #define PRINT_HIERARCHY_OFF false
151
152 #define PRINT_DEVICE_LIST_ON true
153 #define PRINT_DEVICE_LIST_OFF false
154
155 #define ZERO_DELAY 0
156
157 #define RESISTOR_ONLY 0x04
158
159 // teebuf from http://wordaligned.org/articles/cpp-streambufs
160
161 #include <streambuf>
162
163 class teebuf: public std::streambuf
164 {
165 public:
166 // Construct a streambuf which tees output to both input
167 // streambufs.
teebuf(std::streambuf * sb1,std::streambuf * sb2)168 teebuf(std::streambuf * sb1, std::streambuf * sb2)
169 : sb1(sb1)
170 , sb2(sb2)
171 {
172 }
173 private:
174 // This tee buffer has no buffer. So every character "overflows"
175 // and can be put directly into the teed buffers.
overflow(int c)176 virtual int overflow(int c)
177 {
178 if (c == traits_type::eof())
179 {
180 return !traits_type::eof();
181 }
182 else
183 {
184 int const r1 = sb1->sputc(c);
185 int const r2 = sb2->sputc(c);
186 return r1 == traits_type::eof() || r2 == traits_type::eof() ? traits_type::eof() : c;
187 }
188 }
189
190 // Sync both teed buffers.
sync()191 virtual int sync()
192 {
193 int const r1 = sb1->pubsync();
194 int const r2 = sb2->pubsync();
195 return r1 == 0 && r2 == 0 ? 0 : -1;
196 }
197 private:
198 std::streambuf * sb1;
199 std::streambuf * sb2;
200 };
201
202 class teestream : public std::ostream
203 {
204 public:
205 // Construct an ostream which tees output to the supplied
206 // ostreams.
teestream(std::ostream & o1,std::ostream & o2)207 teestream(std::ostream & o1, std::ostream & o2) : std::ostream(&tbuf), tbuf(o1.rdbuf(), o2.rdbuf()) {};
208 private:
209 teebuf tbuf;
210 };
211
212 // end teebuf
213
214 #endif /* CVCTYPES_HH_ */
215