origen_std_lib 0.10.1 → 0.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/config/application.rb +7 -19
- data/config/commands.rb +9 -0
- data/config/version.rb +1 -2
- data/lib/origen_std_lib/v93k.rb +17 -1
- data/{stdlib/v93k → src/advantest/smt7}/origen/.cproject +0 -0
- data/{stdlib/v93k → src/advantest/smt7}/origen/.project +0 -0
- data/src/advantest/smt7/origen/origen/helpers/console.cpp +94 -0
- data/src/advantest/smt7/origen/origen/helpers/misc.cpp +456 -0
- data/src/advantest/smt7/origen/origen/helpers/time.cpp +64 -0
- data/{stdlib/v93k → src/advantest/smt7}/origen/origen/helpers.hpp +25 -8
- data/src/advantest/smt7/origen/origen/site.cpp +237 -0
- data/src/advantest/smt7/origen/origen/site.hpp +50 -0
- data/src/advantest/smt7/origen/origen/test_method/base.cpp +231 -0
- data/src/advantest/smt7/origen/origen/test_method/base.hpp +155 -0
- data/src/advantest/smt7/origen/origen/test_method/dc_measurement.cpp +266 -0
- data/src/advantest/smt7/origen/origen/test_method/dc_measurement.hpp +58 -0
- data/src/advantest/smt7/origen/origen/test_method/empty.cpp +13 -0
- data/src/advantest/smt7/origen/origen/test_method/empty.hpp +24 -0
- data/src/advantest/smt7/origen/origen/test_method/frequency_measurement.cpp +133 -0
- data/src/advantest/smt7/origen/origen/test_method/frequency_measurement.hpp +46 -0
- data/src/advantest/smt7/origen/origen/test_method/functional_test.cpp +168 -0
- data/src/advantest/smt7/origen/origen/test_method/functional_test.hpp +53 -0
- data/{stdlib/v93k → src/advantest/smt7}/origen/origen/test_method.hpp +1 -3
- data/src/advantest/smt7/origen/origen/utils/version.cpp +72 -0
- data/{stdlib/v93k → src/advantest/smt7}/origen/origen/utils/version.hpp +20 -21
- data/{stdlib/v93k → src/advantest/smt7}/origen/origen/utils.hpp +1 -3
- data/src/advantest/smt7/origen/origen.cpp +18 -0
- data/{stdlib/v93k → src/advantest/smt7}/origen/origen.hpp +3 -3
- data/src/advantest/smt7/origen/test_methods/ApplyBin.cpp +37 -0
- data/src/advantest/smt7/origen/test_methods/DCMeasurement.cpp +90 -0
- data/src/advantest/smt7/origen/test_methods/FrequencyMeasurement.cpp +50 -0
- data/src/advantest/smt7/origen/test_methods/FunctionalTest.cpp +24 -0
- data/src/advantest/smt7/origen/test_methods/RecordBin.cpp +39 -0
- data/src/advantest/smt8/origen/common/Origen.java +334 -0
- data/src/advantest/smt8/origen/common/OrigenData.java +391 -0
- data/src/advantest/smt8/origen/common/OrigenHelpers.java +170 -0
- data/src/advantest/smt8/origen/test_methods/Base.java +265 -0
- data/src/advantest/smt8/origen/test_methods/DC_Measurement.java +302 -0
- data/src/advantest/smt8/origen/test_methods/Empty.java +12 -0
- data/src/advantest/smt8/origen/test_methods/Functional_test.java +474 -0
- data/templates/web/faq.md.erb +1 -52
- data/templates/web/guides/intro.md.erb +8 -0
- data/templates/web/guides/{v93k/intro.md.erb → v93ksmt7/capture.md.erb} +0 -2
- data/templates/web/guides/v93ksmt7/complete.md.erb +68 -0
- data/templates/web/guides/v93ksmt7/customizable.md.erb +139 -0
- data/templates/web/guides/v93ksmt7/helpers.md.erb +3 -0
- data/templates/web/guides/{v93k → v93ksmt7}/install.md.erb +1 -1
- data/templates/web/guides/v93ksmt7/integration.md.erb +3 -0
- data/templates/web/guides/v93ksmt7/intro.md.erb +8 -0
- data/templates/web/guides/v93ksmt7/patching.md.erb +3 -0
- data/templates/web/guides/v93ksmt8/intro.md.erb +9 -0
- data/templates/web/index.md.erb +23 -6
- data/templates/web/layouts/_guides.html.erb +15 -3
- data/templates/web/partials/_common_args.md.erb +13 -0
- data/templates/web/partials/_navbar.html.erb +2 -2
- metadata +52 -33
- data/stdlib/v93k/origen/origen/helpers/console.cpp +0 -105
- data/stdlib/v93k/origen/origen/helpers/misc.cpp +0 -311
- data/stdlib/v93k/origen/origen/site.cpp +0 -220
- data/stdlib/v93k/origen/origen/site.hpp +0 -51
- data/stdlib/v93k/origen/origen/test_method/base.hpp +0 -156
- data/stdlib/v93k/origen/origen/test_method/dc_measurement.cpp +0 -182
- data/stdlib/v93k/origen/origen/test_method/dc_measurement.hpp +0 -59
- data/stdlib/v93k/origen/origen/test_method/frequency_measurement.cpp +0 -107
- data/stdlib/v93k/origen/origen/test_method/frequency_measurement.hpp +0 -48
- data/stdlib/v93k/origen/origen/test_method/functional_test.cpp +0 -125
- data/stdlib/v93k/origen/origen/test_method/functional_test.hpp +0 -52
- data/stdlib/v93k/origen/origen/utils/version.cpp +0 -79
- data/stdlib/v93k/origen/origen.cpp +0 -22
- data/stdlib/v93k/origen/test_methods/ApplyBin.cpp +0 -41
- data/stdlib/v93k/origen/test_methods/DCMeasurement.cpp +0 -129
- data/stdlib/v93k/origen/test_methods/FrequencyMeasurement.cpp +0 -93
- data/stdlib/v93k/origen/test_methods/FunctionalTest.cpp +0 -94
- data/stdlib/v93k/origen/test_methods/RecordBin.cpp +0 -48
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/** @file */
|
|
2
|
+
#include <stdlib.h>
|
|
3
|
+
#include <cerrno>
|
|
4
|
+
#include "../../origen.hpp"
|
|
5
|
+
#include "../helpers.hpp"
|
|
6
|
+
|
|
7
|
+
using namespace std;
|
|
8
|
+
|
|
9
|
+
namespace Origen {
|
|
10
|
+
|
|
11
|
+
namespace Time {
|
|
12
|
+
|
|
13
|
+
static bool timeSet = false;
|
|
14
|
+
static int _month;
|
|
15
|
+
static int _day;
|
|
16
|
+
static int _hour;
|
|
17
|
+
static int _minute;
|
|
18
|
+
static int _second;
|
|
19
|
+
|
|
20
|
+
static time_t rawtime;
|
|
21
|
+
static struct tm* timeinfo;
|
|
22
|
+
|
|
23
|
+
void initTime(bool reset) {
|
|
24
|
+
if ((!timeSet) || reset) {
|
|
25
|
+
time(&rawtime);
|
|
26
|
+
timeinfo = localtime(&rawtime);
|
|
27
|
+
_month = (timeinfo->tm_mon + 1);
|
|
28
|
+
_day = timeinfo->tm_mday;
|
|
29
|
+
_hour = timeinfo->tm_hour;
|
|
30
|
+
_minute = timeinfo->tm_min;
|
|
31
|
+
_second = timeinfo->tm_sec;
|
|
32
|
+
timeSet = true;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/// Get the Month.
|
|
37
|
+
int month() {
|
|
38
|
+
initTime(); // set the time if not already
|
|
39
|
+
return _month;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/// Get the Day.
|
|
43
|
+
int day() {
|
|
44
|
+
initTime(); // set the time if not already
|
|
45
|
+
return _day;
|
|
46
|
+
}
|
|
47
|
+
/// Get the Hour.
|
|
48
|
+
int hour() {
|
|
49
|
+
initTime(); // set the time if not already
|
|
50
|
+
return _hour;
|
|
51
|
+
}
|
|
52
|
+
/// Get the Minute.
|
|
53
|
+
int minute() {
|
|
54
|
+
initTime(); // set the time if not already
|
|
55
|
+
return _minute;
|
|
56
|
+
}
|
|
57
|
+
/// Get the Second.
|
|
58
|
+
int second() {
|
|
59
|
+
initTime(); // set the time if not already
|
|
60
|
+
return _second;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
} // end namespace Time
|
|
64
|
+
} // end namespace Origen
|
|
@@ -1,28 +1,33 @@
|
|
|
1
1
|
#ifndef ORIGEN_HELPERS_INCLUDED
|
|
2
2
|
#define ORIGEN_HELPERS_INCLUDED
|
|
3
3
|
|
|
4
|
+
#include <stdlib.h>
|
|
5
|
+
#include <cerrno>
|
|
6
|
+
#include <string>
|
|
7
|
+
#include "../origen.hpp"
|
|
4
8
|
#include "mapi.hpp"
|
|
5
9
|
#include "rdi.hpp"
|
|
6
|
-
#include <string>
|
|
7
10
|
|
|
8
11
|
using namespace std;
|
|
9
12
|
|
|
10
13
|
namespace Origen {
|
|
11
14
|
|
|
12
15
|
string extractPinsFromGroup(const string&);
|
|
16
|
+
bool pinExists(const string& pinName);
|
|
13
17
|
void synchronize(double = 1);
|
|
14
18
|
double calculateFrequency(const ARRAY_I&, double);
|
|
15
19
|
double calculatePeriod(const ARRAY_I&, double);
|
|
20
|
+
void overlaySubroutineOutput(string, string, uint64_t, int, int, int);
|
|
16
21
|
void overlaySubroutine(string, string, uint64_t, int);
|
|
17
22
|
void reverseOverlaySubroutine(string, string, uint64_t, int);
|
|
18
23
|
int numberOfOnes(uint32_t);
|
|
19
24
|
int numberOfZeros(uint32_t);
|
|
20
|
-
int64_t toInt
|
|
21
|
-
uint64_t toUInt
|
|
25
|
+
int64_t toInt(string, int = 0);
|
|
26
|
+
uint64_t toUInt(string, int = 0);
|
|
22
27
|
vector<string> split(const string&, char);
|
|
23
28
|
void split(const string&, char, vector<string>&);
|
|
24
|
-
string toHex
|
|
25
|
-
string toStr
|
|
29
|
+
string toHex(const uint64_t&);
|
|
30
|
+
string toStr(const uint64_t&);
|
|
26
31
|
void initializeSites();
|
|
27
32
|
void logParametricTest(string, int, double, LIMIT, string);
|
|
28
33
|
void logFunctionalTest(string, int, bool, string);
|
|
@@ -30,16 +35,28 @@ bool isPass(double, LIMIT);
|
|
|
30
35
|
string loStr(LIMIT);
|
|
31
36
|
string hiStr(LIMIT);
|
|
32
37
|
string upcase(string);
|
|
38
|
+
string downcase(string);
|
|
33
39
|
string lpad(string, int, char);
|
|
34
40
|
string rpad(string, int, char);
|
|
35
41
|
bool isEven(uint64_t);
|
|
36
42
|
bool isOdd(uint64_t);
|
|
37
43
|
LIMIT noLimits();
|
|
38
44
|
uint64_t flip(uint64_t, int);
|
|
39
|
-
string ltrim(string, const char
|
|
40
|
-
string rtrim(string, const char
|
|
41
|
-
string trim(string, const char
|
|
45
|
+
string ltrim(string, const char* remove_chars = " \n\t\r\f\v");
|
|
46
|
+
string rtrim(string, const char* remove_chars = " \n\t\r\f\v");
|
|
47
|
+
string trim(string, const char* remove_chars = " \n\t\r\f\v");
|
|
48
|
+
double getUnitMultiplier(const string& units);
|
|
49
|
+
string getLabelFromBurst(const string& burst, const string& port);
|
|
50
|
+
string checksum16bits(const string&);
|
|
42
51
|
|
|
52
|
+
namespace Time {
|
|
53
|
+
void initTime(bool = false);
|
|
54
|
+
int month();
|
|
55
|
+
int day();
|
|
56
|
+
int hour();
|
|
57
|
+
int minute();
|
|
58
|
+
int second();
|
|
59
|
+
}
|
|
43
60
|
}
|
|
44
61
|
|
|
45
62
|
#endif
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
#include "site.hpp"
|
|
2
|
+
#include <libcicpi.h>
|
|
3
|
+
#include <iostream>
|
|
4
|
+
#include "helpers.hpp"
|
|
5
|
+
using namespace std;
|
|
6
|
+
|
|
7
|
+
namespace Origen {
|
|
8
|
+
|
|
9
|
+
Site::Site(int number) {
|
|
10
|
+
_number = number;
|
|
11
|
+
lotidSet = false;
|
|
12
|
+
waferSet = false;
|
|
13
|
+
xSet = false;
|
|
14
|
+
ySet = false;
|
|
15
|
+
binSet = false;
|
|
16
|
+
softbinSet = false;
|
|
17
|
+
}
|
|
18
|
+
Site::~Site() {}
|
|
19
|
+
|
|
20
|
+
/// Set the lot ID to the given value, e.g. "ABC1234"
|
|
21
|
+
void Site::lotid(string val) {
|
|
22
|
+
lotidSet = true;
|
|
23
|
+
_lotid = val;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/// Set the lot ID based on the integer representation returned from lotidInt
|
|
27
|
+
void Site::lotid(uint64_t val) {
|
|
28
|
+
string id = "";
|
|
29
|
+
|
|
30
|
+
for (int i = 0; i < 8; i++) {
|
|
31
|
+
int ch = val >> (8 * (7 - i));
|
|
32
|
+
if (ch != 0) {
|
|
33
|
+
id = id + (char)ch;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
lotid(id);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/// Get the lot ID. If it has not previously been set to a value it will be
|
|
41
|
+
/// automatically queried from the test system.
|
|
42
|
+
string Site::lotid() {
|
|
43
|
+
if (!lotidSet) {
|
|
44
|
+
char value[CI_CPI_MAX_MODL_STRING_LEN * 2];
|
|
45
|
+
if (!GetModelfileString(const_cast<char*>("LOT_ID"), value)) {
|
|
46
|
+
_lotid = (string)value;
|
|
47
|
+
} else {
|
|
48
|
+
_lotid = "Undefined";
|
|
49
|
+
}
|
|
50
|
+
lotidSet = true;
|
|
51
|
+
}
|
|
52
|
+
return _lotid;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/// Returns the lot ID as a 64-bit integer that is suitable for programming to
|
|
56
|
+
/// the device.
|
|
57
|
+
/// Each character in the lotID is converted to its ASCII code.
|
|
58
|
+
/// An error will be raised if the length of the current lotID overflows
|
|
59
|
+
/// 64-bits.
|
|
60
|
+
uint64_t Site::lotidInt() {
|
|
61
|
+
string id = lotid();
|
|
62
|
+
stringstream val;
|
|
63
|
+
|
|
64
|
+
// If the ID is > 8 chars then lose the upper chars, making the assuming that
|
|
65
|
+
// the lower ones are
|
|
66
|
+
// the more significant ones for the purposes of identifying a particular lot
|
|
67
|
+
if (id.length() > 8) {
|
|
68
|
+
id = id.substr(id.length() - 8, 8);
|
|
69
|
+
}
|
|
70
|
+
if (id.length() > 0) val << toHex((int)id.at(0));
|
|
71
|
+
if (id.length() > 1) val << toHex((int)id.at(1));
|
|
72
|
+
if (id.length() > 2) val << toHex((int)id.at(2));
|
|
73
|
+
if (id.length() > 3) val << toHex((int)id.at(3));
|
|
74
|
+
if (id.length() > 4) val << toHex((int)id.at(4));
|
|
75
|
+
if (id.length() > 5) val << toHex((int)id.at(5));
|
|
76
|
+
if (id.length() > 6) val << toHex((int)id.at(6));
|
|
77
|
+
if (id.length() > 7) val << toHex((int)id.at(7));
|
|
78
|
+
|
|
79
|
+
// if conversion was wrong for any reason setup val to a default value to
|
|
80
|
+
// ensure fail.
|
|
81
|
+
if (val.str().length() > 16) {
|
|
82
|
+
val.str("FFFFFFFFFFFFFFFE");
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return toUInt(val.str(), 16);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/// Set the wafer number to the given value
|
|
89
|
+
void Site::wafer(int val) {
|
|
90
|
+
waferSet = true;
|
|
91
|
+
if (val < 0 || val > 255) {
|
|
92
|
+
cout << "ERROR: Wafer is out of the range of a UInt8: " << val << endl;
|
|
93
|
+
ERROR_EXIT(TM::EXIT_FLOW);
|
|
94
|
+
}
|
|
95
|
+
_wafer = (uint8_t)val;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/// Get the wafer number. If it has not previously been set to a value it will
|
|
99
|
+
/// be automatically queried from the test system.
|
|
100
|
+
int Site::wafer() {
|
|
101
|
+
if (!waferSet) {
|
|
102
|
+
char value[CI_CPI_MAX_MODL_STRING_LEN * 2];
|
|
103
|
+
|
|
104
|
+
// if (!GetModelfileString(const_cast<char*>("WAFER_ID"), value)) {
|
|
105
|
+
// Expect to return something like "AB1234-15AA", where 15 is the wafer
|
|
106
|
+
// number
|
|
107
|
+
// wafer(toInt(split((string) value, '-')[1].substr(0, 2)));
|
|
108
|
+
if (!GetModelfileString(const_cast<char*>("WAFER_NUMBER"), value)) {
|
|
109
|
+
wafer(toInt((string)value));
|
|
110
|
+
} else {
|
|
111
|
+
wafer(0xFF);
|
|
112
|
+
}
|
|
113
|
+
waferSet = true;
|
|
114
|
+
}
|
|
115
|
+
return _wafer;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/// Set the X co-ordinate to the given value
|
|
119
|
+
void Site::x(int val) {
|
|
120
|
+
xSet = true;
|
|
121
|
+
_x = val;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/// Get the X co-ord. If it has not previously been set to a value it will be
|
|
125
|
+
/// automatically queried from the test system.
|
|
126
|
+
int Site::x() {
|
|
127
|
+
if (!xSet) {
|
|
128
|
+
long lx, ly;
|
|
129
|
+
GetDiePosXYOfSite(_number, &lx, &ly);
|
|
130
|
+
if (lx < -32768 || lx > 32767) {
|
|
131
|
+
cout << "ERROR: X is out of the range of an Int16: " << lx << endl;
|
|
132
|
+
ERROR_EXIT(TM::EXIT_FLOW);
|
|
133
|
+
}
|
|
134
|
+
if (ly < -32768 || ly > 32767) {
|
|
135
|
+
cout << "ERROR: Y is out of the range of an Int16: " << ly << endl;
|
|
136
|
+
ERROR_EXIT(TM::EXIT_FLOW);
|
|
137
|
+
}
|
|
138
|
+
_x = (int)lx;
|
|
139
|
+
_y = (int)ly;
|
|
140
|
+
xSet = true;
|
|
141
|
+
ySet = true;
|
|
142
|
+
}
|
|
143
|
+
return _x;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/// Set the Y co-ordinate to the given value
|
|
147
|
+
void Site::y(int val) {
|
|
148
|
+
ySet = true;
|
|
149
|
+
_y = val;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/// Get the Y co-ord. If it has not previously been set to a value it will be
|
|
153
|
+
/// automatically queried from the test system.
|
|
154
|
+
int Site::y() {
|
|
155
|
+
if (!ySet) {
|
|
156
|
+
long lx, ly;
|
|
157
|
+
GetDiePosXYOfSite(_number, &lx, &ly);
|
|
158
|
+
if (lx < -32768 || lx > 32767) {
|
|
159
|
+
cout << "ERROR: X is out of the range of an Int16: " << lx << endl;
|
|
160
|
+
ERROR_EXIT(TM::EXIT_FLOW);
|
|
161
|
+
}
|
|
162
|
+
if (ly < -32768 || ly > 32767) {
|
|
163
|
+
cout << "ERROR: Y is out of the range of an Int16: " << ly << endl;
|
|
164
|
+
ERROR_EXIT(TM::EXIT_FLOW);
|
|
165
|
+
}
|
|
166
|
+
_x = (int)lx;
|
|
167
|
+
_y = (int)ly;
|
|
168
|
+
xSet = true;
|
|
169
|
+
ySet = true;
|
|
170
|
+
}
|
|
171
|
+
return _y;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/// Set the site's bin to the given value, but only if a bin has not already
|
|
175
|
+
/// been set.
|
|
176
|
+
/// Note that this does not actually bin out the site but just records the bin
|
|
177
|
+
/// assignment
|
|
178
|
+
/// in a variable that can be retrieved by calling bin().
|
|
179
|
+
void Site::bin(int val) {
|
|
180
|
+
if (!binSet) {
|
|
181
|
+
binSet = true;
|
|
182
|
+
_bin = val;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/// Set the site's bin to the given value, but only if a bin has not already
|
|
187
|
+
/// been set or
|
|
188
|
+
/// if the force argument is set to true, in which case it will overwrite any
|
|
189
|
+
/// previous
|
|
190
|
+
/// assignment.
|
|
191
|
+
/// Note that this does not actually bin out the site but just records the bin
|
|
192
|
+
/// assignment
|
|
193
|
+
/// in a variable that can be retrieved by calling bin().
|
|
194
|
+
void Site::bin(int val, bool force) {
|
|
195
|
+
if (!binSet || force) {
|
|
196
|
+
binSet = true;
|
|
197
|
+
_bin = val;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/// Returns the bin that has been assigned to the site by previously calling
|
|
202
|
+
/// bin(int), if no
|
|
203
|
+
/// bin has been assigned then it will return 0.
|
|
204
|
+
int Site::bin() { return (binSet) ? _bin : 0; }
|
|
205
|
+
|
|
206
|
+
/// Set the site's softbin to the given value, but only if a softbin has not
|
|
207
|
+
/// already been set.
|
|
208
|
+
/// Note that this does not actually bin out the site but just records the
|
|
209
|
+
/// softbin assignment
|
|
210
|
+
/// in a variable that can be retrieved by calling softbin().
|
|
211
|
+
void Site::softbin(int val) {
|
|
212
|
+
if (!softbinSet) {
|
|
213
|
+
softbinSet = true;
|
|
214
|
+
_softbin = val;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/// Set the site's softbin to the given value, but only if a softbin a has not
|
|
219
|
+
/// already been set or
|
|
220
|
+
/// if the force argument is set to true, in which case it will overwrite any
|
|
221
|
+
/// previous
|
|
222
|
+
/// assignment.
|
|
223
|
+
/// Note that this does not actually bin out the site but just records the
|
|
224
|
+
/// softbin assignment
|
|
225
|
+
/// in a variable that can be retrieved by calling softbin().
|
|
226
|
+
void Site::softbin(int val, bool force) {
|
|
227
|
+
if (!softbinSet || force) {
|
|
228
|
+
softbinSet = true;
|
|
229
|
+
_softbin = val;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/// Returns the bin that has been assigned to the site by previously calling
|
|
234
|
+
/// bin(int), if no
|
|
235
|
+
/// bin has been assigned then it will return 0.
|
|
236
|
+
int Site::softbin() { return (softbinSet) ? _softbin : 0; }
|
|
237
|
+
} /* namespace Origen */
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#ifndef ORIGEN_SITE_HPP_
|
|
2
|
+
#define ORIGEN_SITE_HPP_
|
|
3
|
+
|
|
4
|
+
#include <string>
|
|
5
|
+
#include <inttypes.h>
|
|
6
|
+
using namespace std;
|
|
7
|
+
|
|
8
|
+
namespace Origen {
|
|
9
|
+
|
|
10
|
+
class Site {
|
|
11
|
+
string _lotid;
|
|
12
|
+
bool lotidSet;
|
|
13
|
+
int _wafer;
|
|
14
|
+
bool waferSet;
|
|
15
|
+
int _x;
|
|
16
|
+
bool xSet;
|
|
17
|
+
int _y;
|
|
18
|
+
bool ySet;
|
|
19
|
+
int _number;
|
|
20
|
+
int _bin;
|
|
21
|
+
int _softbin;
|
|
22
|
+
bool binSet;
|
|
23
|
+
bool softbinSet;
|
|
24
|
+
|
|
25
|
+
public:
|
|
26
|
+
Site(int);
|
|
27
|
+
virtual ~Site();
|
|
28
|
+
string lotid();
|
|
29
|
+
uint64_t lotidInt();
|
|
30
|
+
void lotid(string);
|
|
31
|
+
void lotid(uint64_t);
|
|
32
|
+
int wafer();
|
|
33
|
+
void wafer(int);
|
|
34
|
+
int x();
|
|
35
|
+
void x(int);
|
|
36
|
+
int y();
|
|
37
|
+
void y(int);
|
|
38
|
+
int bin();
|
|
39
|
+
void bin(int);
|
|
40
|
+
void bin(int, bool);
|
|
41
|
+
int softbin();
|
|
42
|
+
void softbin(int);
|
|
43
|
+
void softbin(int, bool);
|
|
44
|
+
|
|
45
|
+
/// Returns the site number associated with the given site object
|
|
46
|
+
int number() { return _number; }
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
} /* namespace Origen */
|
|
50
|
+
#endif
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
#include "base.hpp"
|
|
2
|
+
|
|
3
|
+
using namespace std;
|
|
4
|
+
|
|
5
|
+
namespace Origen {
|
|
6
|
+
namespace TestMethod {
|
|
7
|
+
|
|
8
|
+
Base::Base() {
|
|
9
|
+
async(false);
|
|
10
|
+
syncup(false);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
Base::~Base() {}
|
|
14
|
+
|
|
15
|
+
/// Returns 1 when running in offline mode
|
|
16
|
+
int Base::offline() {
|
|
17
|
+
int flag;
|
|
18
|
+
GET_SYSTEM_FLAG("offline", &flag);
|
|
19
|
+
return flag;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
void Base::initialize() {
|
|
23
|
+
addParameter("testName", "string", &_testName,
|
|
24
|
+
testmethod::TM_PARAMETER_INPUT);
|
|
25
|
+
addParameter("forcePass", "int", &_forcePass, testmethod::TM_PARAMETER_INPUT);
|
|
26
|
+
addParameter("onPassFlag", "string", &_onPassFlag,
|
|
27
|
+
testmethod::TM_PARAMETER_INPUT);
|
|
28
|
+
addParameter("onFailFlag", "string", &_onFailFlag,
|
|
29
|
+
testmethod::TM_PARAMETER_INPUT);
|
|
30
|
+
|
|
31
|
+
bFirstRun = true;
|
|
32
|
+
|
|
33
|
+
init();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
void Base::run() {
|
|
37
|
+
ARRAY_I sites;
|
|
38
|
+
|
|
39
|
+
RDI_INIT();
|
|
40
|
+
|
|
41
|
+
ON_FIRST_INVOCATION_BEGIN();
|
|
42
|
+
|
|
43
|
+
enableHiddenUpload();
|
|
44
|
+
|
|
45
|
+
GET_ACTIVE_SITES(activeSites);
|
|
46
|
+
numberOfPhysicalSites = GET_CONFIGURED_SITES(sites);
|
|
47
|
+
GET_TESTSUITE_NAME(suiteName);
|
|
48
|
+
suiteFailed.resize(numberOfPhysicalSites + 1);
|
|
49
|
+
|
|
50
|
+
_setup();
|
|
51
|
+
|
|
52
|
+
callPreBody();
|
|
53
|
+
|
|
54
|
+
ON_FIRST_INVOCATION_END();
|
|
55
|
+
|
|
56
|
+
suiteFailed[CURRENT_SITE_NUMBER()] = 0;
|
|
57
|
+
|
|
58
|
+
body();
|
|
59
|
+
|
|
60
|
+
callPostBody(this);
|
|
61
|
+
|
|
62
|
+
if (suiteFailed[CURRENT_SITE_NUMBER()]) {
|
|
63
|
+
if (_onFailFlag != "") {
|
|
64
|
+
SET_USER_DOUBLE(_onFailFlag, 1);
|
|
65
|
+
}
|
|
66
|
+
} else {
|
|
67
|
+
if (_onPassFlag != "") {
|
|
68
|
+
SET_USER_DOUBLE(_onPassFlag, 1);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
bFirstRun = false;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
void Base::datalog(double value) {
|
|
76
|
+
TESTSET()
|
|
77
|
+
.testnumber(testNumber())
|
|
78
|
+
.cont(true)
|
|
79
|
+
.TEST("", testName(), noLimits(), value);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
void Base::datalog(string testName, double value) {
|
|
83
|
+
TESTSET()
|
|
84
|
+
.testnumber(testNumber(testName))
|
|
85
|
+
.cont(true)
|
|
86
|
+
.TEST("", testName, noLimits(), value);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
void Base::judgeAndDatalog(double value) {
|
|
90
|
+
bool alreadyFailed = suiteFailed[CURRENT_SITE_NUMBER()];
|
|
91
|
+
|
|
92
|
+
if (!alreadyFailed) {
|
|
93
|
+
suiteFailed[CURRENT_SITE_NUMBER()] = !preJudge(value);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
TESTSET()
|
|
97
|
+
.testnumber(testNumber())
|
|
98
|
+
.cont(true)
|
|
99
|
+
.judgeAndLog_ParametricTest(
|
|
100
|
+
"", testName(), _forcePass ? toNALimit(testLimits().TEST_API_LIMIT)
|
|
101
|
+
: testLimits().TEST_API_LIMIT,
|
|
102
|
+
value);
|
|
103
|
+
|
|
104
|
+
// Preserve the first bin assigned within this test suite as the final one
|
|
105
|
+
if ((!alreadyFailed) && (!_forcePass) &&
|
|
106
|
+
(suiteFailed[CURRENT_SITE_NUMBER()])) {
|
|
107
|
+
SET_MULTIBIN(testLimits().BinsNumString, testLimits().BinhNum);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
void Base::judgeAndDatalog(string testName, double value) {
|
|
112
|
+
bool alreadyFailed = suiteFailed[CURRENT_SITE_NUMBER()];
|
|
113
|
+
|
|
114
|
+
if (!alreadyFailed) {
|
|
115
|
+
suiteFailed[CURRENT_SITE_NUMBER()] = !preJudge(testName, value);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
TESTSET()
|
|
119
|
+
.testnumber(testNumber(testName))
|
|
120
|
+
.cont(true)
|
|
121
|
+
.judgeAndLog_ParametricTest(
|
|
122
|
+
"", testName,
|
|
123
|
+
_forcePass ? toNALimit(testLimits(testName).TEST_API_LIMIT)
|
|
124
|
+
: testLimits(testName).TEST_API_LIMIT,
|
|
125
|
+
value);
|
|
126
|
+
|
|
127
|
+
// Preserve the first bin assigned within this test suite as the final one
|
|
128
|
+
if ((!alreadyFailed) && (!_forcePass) &&
|
|
129
|
+
(suiteFailed[CURRENT_SITE_NUMBER()])) {
|
|
130
|
+
SET_MULTIBIN(testLimits().BinsNumString, testLimits().BinhNum);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/// Returns true if the given value will pass the current test, but does not
|
|
135
|
+
/// affect the site status if it fails
|
|
136
|
+
bool Base::preJudge(double value) {
|
|
137
|
+
return isWithinLimits(value, testLimits().TEST_API_LIMIT);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/// Returns true if the given value will pass the given test, but does not
|
|
141
|
+
/// affect the site status if it fails
|
|
142
|
+
bool Base::preJudge(string testName, double value) {
|
|
143
|
+
return isWithinLimits(value, testLimits(testName).TEST_API_LIMIT);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/// Returns true if the given value is within the given limits
|
|
147
|
+
bool Base::isWithinLimits(double value, LIMIT limits) {
|
|
148
|
+
bool passed = true;
|
|
149
|
+
double dHigh(0), dLow(0);
|
|
150
|
+
TM::COMPARE cHigh, cLow;
|
|
151
|
+
|
|
152
|
+
limits.get(cLow, dLow, cHigh, dHigh);
|
|
153
|
+
|
|
154
|
+
if (cLow == TM::GT && value <= dLow) {
|
|
155
|
+
passed = false;
|
|
156
|
+
} else if (cLow == TM::GE && value < dLow) {
|
|
157
|
+
passed = false;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (cHigh == TM::LT && value >= dHigh) {
|
|
161
|
+
passed = false;
|
|
162
|
+
} else if (cHigh == TM::LE && value > dHigh) {
|
|
163
|
+
passed = false;
|
|
164
|
+
}
|
|
165
|
+
return passed;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/// Converts the given limits object to an equivalent version with the limit
|
|
169
|
+
/// types set to N/A
|
|
170
|
+
LIMIT Base::toNALimit(LIMIT limits) {
|
|
171
|
+
LIMIT naLimit(limits);
|
|
172
|
+
double dHigh(0), dLow(0);
|
|
173
|
+
limits.getHigh(&dHigh);
|
|
174
|
+
limits.getLow(&dLow);
|
|
175
|
+
naLimit.high(TM::NA, dHigh);
|
|
176
|
+
naLimit.low(TM::NA, dLow);
|
|
177
|
+
return naLimit;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/// Returns the base test number
|
|
181
|
+
int Base::testNumber() { return testLimits().TestNumber; }
|
|
182
|
+
|
|
183
|
+
/// Returns the test test number for the given test name
|
|
184
|
+
int Base::testNumber(string testName) {
|
|
185
|
+
return testLimits(testName).TestNumber;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/// Returns the base test limits
|
|
189
|
+
TMLimits::LimitInfo Base::testLimits() {
|
|
190
|
+
// Doesn't seem like this should be required from the documentation, but had
|
|
191
|
+
// some
|
|
192
|
+
// problems with getLimitRef not working properly without it when other code
|
|
193
|
+
// has set
|
|
194
|
+
// a specific key.
|
|
195
|
+
tmLimits.setDefaultLookupKeys();
|
|
196
|
+
return tmLimits.getLimitRef(suiteName, testName());
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/// Returns the test limits for the given test name
|
|
200
|
+
TMLimits::LimitInfo Base::testLimits(string testName) {
|
|
201
|
+
// Doesn't seem like this should be required from the documentation, but had
|
|
202
|
+
// some
|
|
203
|
+
// problems with getLimitRef not working properly without it when other code
|
|
204
|
+
// has set
|
|
205
|
+
// a specific key.
|
|
206
|
+
tmLimits.setDefaultLookupKeys();
|
|
207
|
+
return tmLimits.getLimitRef(suiteName, testName);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/// Returns the value of the testName parameter supplied from the test suite, or
|
|
211
|
+
/// if not supplied falls back
|
|
212
|
+
/// to the test suite name
|
|
213
|
+
string Base::testName() {
|
|
214
|
+
if (_testName == "") {
|
|
215
|
+
return suiteName;
|
|
216
|
+
} else {
|
|
217
|
+
return _testName;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/// Changes a 0 -> 1 and 1 -> 0 if Origen::invertFunctionalResults has been set
|
|
222
|
+
/// to true
|
|
223
|
+
int Base::invertFunctionalResultIfRequired(int v) {
|
|
224
|
+
if (Origen::invertFunctionalResults) {
|
|
225
|
+
return v == 1 ? 0 : 1;
|
|
226
|
+
} else {
|
|
227
|
+
return v;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|