origen_testers 0.52.5 → 0.52.7

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 68bd4c35fef793a404ccab7d41d8212fccbdc69e2b92f7cbcbf1c711cca27b64
4
- data.tar.gz: d641609bc1bccd7476dbbdce14b01745726bfdc66062709d2991f3cdf8dd6d8c
3
+ metadata.gz: ccd63605d6a24fffaea0ef6fa10e4f3d9078f58c36e98857bcfb7a82a7564c44
4
+ data.tar.gz: 9964c66bbe4042f62acf9bf56d0b579e85c8e12d6d656c79846294fb6d2289b0
5
5
  SHA512:
6
- metadata.gz: df597ce4879df80783faa634975b7c5531594d60a6f230fc6495927a384ea56e2608f004d3ae5ad4ddbe9cc31609324e4c2f0b410aaf9a003e148082e50f2431
7
- data.tar.gz: f3f6c2d67eabb103d31f375262729cceb99170adaba9f38d2f567fbff6ad6b6c92cdf1708aebfe77dfdb761642304a96a642f8f244cc7f0709683a0a06acf1c4
6
+ metadata.gz: 23694bb90289fb1381f4987b31ef47f5adf57d15551f60ad6fd0cfa335e0f12e783716c0b8d375541375082a7186e59fe4a0aaaab28189c7b668caf48aa54544
7
+ data.tar.gz: b32fb971c9693bd113f928e70e1d52e2c9c3052d0f44d8a8e95692752145e6946a815ec77bb11c257fd4c2a2a0080a9fc481ac525cc4cff6d5cb812df08c0722
data/config/version.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  module OrigenTesters
2
2
  MAJOR = 0
3
3
  MINOR = 52
4
- BUGFIX = 5
4
+ BUGFIX = 7
5
5
  DEV = nil
6
6
  VERSION = [MAJOR, MINOR, BUGFIX].join(".") + (DEV ? ".pre#{DEV}" : '')
7
7
  end
@@ -103,6 +103,8 @@ module OrigenTesters
103
103
  alias_method :pinlist, :pins
104
104
 
105
105
  def initialize(pins:, context:)
106
+ # remove trailing formatting characters
107
+ pins = pins.map { |p| p.split(':').first }
106
108
  @pins = pins.map(&:strip).map(&:to_sym)
107
109
  super(context: context, type: :pinlist)
108
110
  end
@@ -110,6 +110,10 @@ module OrigenTesters
110
110
  new(name, :powersupply, attrs)
111
111
  end
112
112
 
113
+ def self.new_dcvi_powersupply(name, attrs = {})
114
+ new(name, :dcvi_powersupply, attrs)
115
+ end
116
+
113
117
  def self.new_mto_memory(name, attrs = {})
114
118
  new(name, :mto_memory, attrs)
115
119
  end
@@ -163,6 +163,10 @@ module OrigenTesters
163
163
  end
164
164
  alias_method :power_supply, :powersupply
165
165
 
166
+ def dcvi_powersupply(name, options = {})
167
+ add(name, :dcvi_powersupply, options)
168
+ end
169
+
166
170
  def ppmu(name, options = {})
167
171
  add(name, :pin_pmu, options)
168
172
  end
@@ -59,6 +59,8 @@ module OrigenTesters
59
59
  nodes_namespace::CommentBlock.new(context: self,
60
60
  comments: raw_vector.split("\n")
61
61
  )
62
+ elsif raw_vector.strip.size == 0
63
+ nodes_namespace::CommentBlock.new(context: self, comments: ['// blank line replaced with comment by origen convert'])
62
64
  elsif raw_vector =~ Regexp.new('^\s*start_label')
63
65
  nodes_namespace::StartLabel.new(context: self,
64
66
  start_label: raw_vector[raw_vector.index('start_label') + 11..-1].strip[0..-2]
@@ -69,7 +71,9 @@ module OrigenTesters
69
71
  label_type: contents[0],
70
72
  label_name: contents[1]
71
73
  )
72
- elsif raw_vector =~ Regexp.new(':(?!(.*>))')
74
+ # original elsif for label was updated to avoid confusing origen's eol comments for a label
75
+ # elsif raw_vector =~ Regexp.new(':(?!(.*>))')
76
+ elsif raw_vector.split(';').first =~ Regexp.new(':(?!(.*>))')
73
77
  nodes_namespace::Label.new(context: self,
74
78
  # Strip any whitespace from the vector and grab contents up to
75
79
  # the ':' symbol.
@@ -18,15 +18,15 @@ module OrigenTesters
18
18
  TEST_INSTANCE_EXTRA_ARGS = 130
19
19
 
20
20
  TEST_INSTANCE_ALIASES = {
21
- name: :test_name,
22
- time_set: :time_sets,
23
- timeset: :time_sets,
24
- timesets: :time_sets,
21
+ name: :test_name,
22
+ time_set: :time_sets,
23
+ timeset: :time_sets,
24
+ timesets: :time_sets,
25
25
 
26
- other: {
26
+ other: {
27
27
  },
28
28
 
29
- empty: {
29
+ empty: {
30
30
  arg_list: :arg0,
31
31
  start_func: :arg1,
32
32
  start_of_body_f: :arg1,
@@ -65,7 +65,7 @@ module OrigenTesters
65
65
  },
66
66
 
67
67
  # Functional test instances
68
- functional: {
68
+ functional: {
69
69
  arg_list: :arg0,
70
70
  pattern: :arg1,
71
71
  patterns: :arg1,
@@ -125,7 +125,7 @@ module OrigenTesters
125
125
  concurrent_mode: :arg35
126
126
  },
127
127
 
128
- pin_pmu: {
128
+ pin_pmu: {
129
129
  arg_list: :arg0,
130
130
  hsp_start: :arg1,
131
131
  start_func: :arg2,
@@ -206,22 +206,88 @@ module OrigenTesters
206
206
  force_cond_alt: :arg56,
207
207
  force_irange_alt: :arg57,
208
208
  meas_irange_alt: :arg58
209
+ },
210
+
211
+ dcvi_powersupply: {
212
+ arg_list: :arg0,
213
+ precond_pat: :arg1,
214
+ start_func: :arg2,
215
+ pre_pat_func: :arg3,
216
+ pre_test_func: :arg4,
217
+ post_test_func: :arg5,
218
+ post_pat_func: :arg6,
219
+ end_of_body_f: :arg7,
220
+ hold_state_pat: :arg8,
221
+ pattern: :arg8,
222
+ drive_lo_pins: :arg9,
223
+ drive_hi_pins: :arg10,
224
+ drive_z_pins: :arg11,
225
+ float_pins: :arg12,
226
+ sampling_time: :arg13,
227
+ sample: :arg14,
228
+ sample_size: :arg14,
229
+ settling_time: :arg15,
230
+ main_voltage: :arg16,
231
+ alt_voltage: :arg17,
232
+ power_pins: :arg18,
233
+ disable_pins: :arg19,
234
+ voltage_output: :arg20,
235
+ pcp_start_label: :arg21,
236
+ pcp_start: :arg21,
237
+ pcp_stop_label: :arg22,
238
+ pcp_stop: :arg22,
239
+ start_func_args: :arg23,
240
+ start_of_body_f_args: :arg23,
241
+ pre_pat_func_args: :arg24,
242
+ pre_pat_f_args: :arg24,
243
+ pre_test_func_args: :arg25,
244
+ pre_test_f_args: :arg25,
245
+ post_test_func_args: :arg26,
246
+ post_test_f_args: :arg26,
247
+ post_pat_func_args: :arg27,
248
+ post_pat_f_args: :arg27,
249
+ end_func_args: :arg28,
250
+ end_of_body_f_args: :arg28,
251
+ hsp_start_label: :arg29,
252
+ hsp_start: :arg29,
253
+ hsp_stop_label: :arg30,
254
+ hsp_stop: :arg30,
255
+ pcp_check_patGen: :arg31,
256
+ current_clamp: :arg32,
257
+ hsp_checkpat_gen: :arg33,
258
+ hsp_resume_pat: :arg34,
259
+ relay_mode: :arg35,
260
+ utility_pins_1: :arg36,
261
+ utility_pins_0: :arg37,
262
+ test_control: :arg38,
263
+ serialize_meas: :arg39,
264
+ meas_f: :arg40,
265
+ meas_f_args: :arg41,
266
+ wait_flag1: :arg42,
267
+ wait_flag2: :arg43,
268
+ wait_flag3: :arg44,
269
+ wait_flag4: :arg45,
270
+ validating: :arg46,
271
+ i_range: :arg47,
272
+ pattern_timeout: :arg48,
273
+ pcp_disable_alarm: :arg49,
274
+ hcp_disable_alarm: :arg50
209
275
  }
210
276
 
211
277
  }
212
278
 
213
279
  TEST_INSTANCE_DEFAULTS = {
214
- empty: {
280
+ empty: {
215
281
  arg_list: 'StartOfBodyF,PrePatF,PreTestF,PostTestF,PostPatF,EndOfBodyF,StartOfBodyFArgs,PrePatFArgs,PreTestFArgs,PostTestFArgs,PostPatFArgs,EndOfBodyFArgs,Util1Pins,Util0Pins,DriveLoPins,DriveHiPins,DriveZPins,FloatPins,DisablePins',
216
282
  proc_type: 'VBT',
217
283
  proc_name: 'Empty_T',
218
284
  proc_called_as: 'Excel Macro'
219
285
  },
220
- other: {
286
+ other: {
221
287
  proc_type: 'Other',
222
288
  proc_called_as: 'Excel Macro'
223
289
  },
224
- functional: {
290
+ functional: {
225
291
  arg_list: 'Patterns,StartOfBodyF,PrePatF,PreTestF,PostTestF,PostPatF,EndOfBodyF,ReportResult,ResultMode,DriveLoPins,DriveHiPins,DriveZPins,DisablePins,FloatPins,StartOfBodyFArgs,PrePatFArgs,PreTestFArgs,PostTestFArgs,PostPatFArgs,EndOfBodyFArgs,Util1Pins,Util0Pins,PatFlagF,PatFlagFArgs,RelayMode,PatThreading,MatchAllSites,WaitFlagA,WaitFlagB,WaitFlagC,WaitFlagD,Validating_,PatternTimeout,WaitTimeDomain,ConcurrentMode',
226
292
  proc_type: 'VBT',
227
293
  proc_name: 'Functional_T',
@@ -236,7 +302,7 @@ module OrigenTesters
236
302
  wait_flag4: -2, # waitoff
237
303
  wait_time: 30
238
304
  },
239
- pin_pmu: {
305
+ pin_pmu: {
240
306
  arg_list: 'HspStartLabel,StartOfBodyF,PrePatF,PreTestF,PostTestF,PostPatF,EndOfBodyF,PreconditionPat,HoldStatePat,PcpStopLabel,DriveLoPins,DriveHiPins,DriveZPins,DisablePins,FloatPins,Pins,MeasureMode,SettlingTime,ForceCond1,ForceCond2,RelayMode,StartOfBodyFArgs,PrePatFArgs,PreTestFArgs,PostTestFArgs,PostPatFArgs,EndOfBodyFArgs,PcpStartLabel,PcpCheckPatGen,HspStopLabel,HspCheckPatGen,SamplingTime,SampleCount,HspResumePat,VClampLo,VClampHi,Util1Pins,Util0Pins,WaitFlagA,WaitFlagB,WaitFlagC,WaitFlagD,Validating_,ForceIRange,MeasIRange,PatternTimeout,PcpDisableAlarmCheck,HspDisableAlarmCheck,TestingInSeries,BackgroundMeasureMode,BackgroundForceIRange,BackgroundMeasIRange,BackgroundForceCond,PinsAlt,MeasureModeAlt,ForceCondAlt,ForceIRangeAlt,MeasIRangeAlt',
241
307
  proc_type: 'VBT',
242
308
  proc_name: 'PinPmu_T',
@@ -245,7 +311,18 @@ module OrigenTesters
245
311
  wait_flag2: -2, # waitoff
246
312
  wait_flag3: -2, # waitoff
247
313
  wait_flag4: -2, # waitoff
314
+ },
315
+ dcvi_powersupply: {
316
+ arg_list: 'PreconditionPat,StartOfBodyF,PrePatF,PreTestF,PostTestF,PostPatF,EndOfBodyF,HoldStatePat,DriveLoPins,DriveHiPins,DriveZPins,FloatPins,SamplingTime,SampleSize,SettlingTime,MainVoltage,AltVoltage,PowerPins,DisablePins,VoltageOutput,PcpStartLabel,PcpStopLabel,StartOfBodyFArgs,PrePatFArgs,PreTestFArgs,PostTestFArgs,PostPatFArgs,EndOfBodyFArgs,HspStartLabel,HspStopLabel,PcpCheckPatGen,CurrentClamp,HspCheckPatGen,HspResumePat,RelayMode,Util1Pins,Util0Pins,TestControl,SerializeMeas,MeasF,MeasFArgs,WaitFlagA,WaitFlagB,WaitFlagC,WaitFlagD,Validating_,Irange,PatternTimeout,PcpDisableAlarm,HspDisableAlarm',
317
+ proc_type: 'VBT',
318
+ proc_name: 'DCVIPowerSupply_T',
319
+ proc_called_as: 'Excel Macro',
320
+ wait_flag1: -2, # waitoff
321
+ wait_flag2: -2, # waitoff
322
+ wait_flag3: -2, # waitoff
323
+ wait_flag4: -2, # waitoff
248
324
  }
325
+
249
326
  }
250
327
 
251
328
  # Generate the instance method definitions based on the above
@@ -241,6 +241,9 @@ module OrigenTesters
241
241
  end
242
242
  test_suites.finalize
243
243
  test_methods.finalize
244
+ if smt8?
245
+ shmoo_tests.finalize
246
+ end
244
247
  if tester.create_limits_file && top_level?
245
248
  render_limits_file
246
249
  end
@@ -10,6 +10,8 @@ module OrigenTesters
10
10
  test_suite = node.find(:object).to_a[0]
11
11
  if test_suite.is_a?(String)
12
12
  name = test_suite
13
+ elsif test_suite.is_a?(ShmooTest)
14
+ name = test_suite.name
13
15
  else
14
16
  name = test_suite.name
15
17
  test_method = test_suite.test_method
@@ -185,6 +187,10 @@ module OrigenTesters
185
187
  @sub_flows || {}
186
188
  end
187
189
 
190
+ def shmoo_tests
191
+ @shmoo_tests ||= platform::ShmooTests.new(self)
192
+ end
193
+
188
194
  def auxiliary_flows
189
195
  @auxiliary_flows || {}
190
196
  end
@@ -42,6 +42,10 @@ module OrigenTesters
42
42
  def limits_workbook
43
43
  @@limits_workbook ||= LimitsWorkbook.new(manually_register: true)
44
44
  end
45
+
46
+ def shmoo_tests
47
+ flow.shmoo_tests
48
+ end
45
49
  end
46
50
  end
47
51
  end
@@ -0,0 +1,426 @@
1
+ module OrigenTesters
2
+ module SmartestBasedTester
3
+ class V93K_SMT8
4
+ class ShmooTest
5
+ ATTRS =
6
+ %w(
7
+ name
8
+
9
+ bypass
10
+ target
11
+ result_title
12
+ result_type
13
+ result_signal
14
+ execution_order
15
+ ffc_error_count
16
+ axis
17
+ )
18
+
19
+ ALIASES = {
20
+ targets: :target,
21
+ title: :result_title,
22
+ type: :result_type,
23
+ signal: :result_signal
24
+ }
25
+
26
+ DEFAULTS = {
27
+ }
28
+
29
+ NO_STRING_TYPES = [:list_strings, :list_classes, :class]
30
+ # Generate accessors for all attributes and their aliases
31
+ ATTRS.each do |attr|
32
+ if attr == 'name'
33
+ attr_reader attr.to_sym
34
+ else
35
+ attr_accessor attr.to_sym
36
+ end
37
+ end
38
+
39
+ # Define the aliases
40
+ ALIASES.each do |_alias, val|
41
+ define_method("#{_alias}=") do |v|
42
+ send("#{val}=", v)
43
+ end
44
+ define_method("#{_alias}") do
45
+ send(val)
46
+ end
47
+ end
48
+ attr_accessor :meta
49
+
50
+ def initialize(name, attrs = {})
51
+ @name = name
52
+ if interface.unique_test_names == :signature
53
+ if interface.flow.sig
54
+ @name = "#{name}_#{interface.flow.sig}"
55
+ end
56
+ elsif interface.unique_test_names == :flowname || interface.unique_test_names == :flow_name
57
+ @name = "#{name}_#{interface.flow.name.to_s.symbolize}"
58
+ elsif interface.unique_test_names == :preflowname || interface.unique_test_names == :pre_flow_name
59
+ @name = "#{interface.flow.name.to_s.symbolize}_#{name}"
60
+ elsif interface.unique_test_names
61
+ utn_string = interface.unique_test_names.to_s
62
+ if utn_string =~ /^prepend_/
63
+ utn_string = utn_string.gsub(/^prepend_/, '')
64
+ @name = "#{utn_string}_#{name}"
65
+ else
66
+ utn_string = utn_string.gsub(/^append_/, '')
67
+ @name = "#{name}_#{utn_string}"
68
+ end
69
+ end
70
+
71
+ # handle axis
72
+ if axis = attrs.delete(:axis)
73
+ axis = [axis] unless axis.is_a?(Array)
74
+ axis.each_with_index do |a, i|
75
+ aname = a.delete(:name) || "axis#{i + 1}"
76
+ if axes_names.include?(aname.to_sym)
77
+ fail "Axis name #{aname} is already used in shmoo test '#{@name}'"
78
+ end
79
+ axes << ShmooTestAxis.new(aname.to_sym, a)
80
+ end
81
+ else
82
+ fail 'ShmooTest must have at least one axis'
83
+ end
84
+
85
+ # Set the defaults
86
+ self.class::DEFAULTS.each do |k, v|
87
+ send("#{k}=", v)
88
+ end
89
+ # Then the values that have been supplied
90
+ attrs.each do |k, v|
91
+ send("#{k}=", v) if respond_to?("#{k}=") && k.to_sym != :name
92
+ end
93
+ end
94
+
95
+ def smt8?
96
+ tester.smt8?
97
+ end
98
+
99
+ def inspect
100
+ "<ShmooTest: #{name}>"
101
+ end
102
+
103
+ # The name is immutable once the shmoo test is created, this will raise an error when called
104
+ def name=(val, options = {})
105
+ fail 'Once assigned the name of a shmoo test cannot be changed!'
106
+ end
107
+
108
+ def interface
109
+ Origen.interface
110
+ end
111
+
112
+ def axes
113
+ @axes ||= []
114
+ end
115
+
116
+ def axes_names
117
+ axes.map(&:name)
118
+ end
119
+
120
+ def lines
121
+ l = []
122
+ l << "shmoo #{name} {"
123
+ if target.length > 1
124
+ l << " target = \#[#{target.map(&:to_s).join(',')}];"
125
+ else
126
+ l << " target = #{target[0]};"
127
+ end
128
+ l << " resultTitle = \"#{result_title}\";" if result_title
129
+ l << " resultType = \"#{result_type}\";" if result_type
130
+ l << " resultSignal = \"#{result_signal}\";" if result_signal
131
+ l << " executionOrder = #{execution_order};" if execution_order
132
+ l << " bypass = \"#{bypass}\";" if bypass
133
+ l << " ffcErrorCount = #{ffc_error_count};" if ffc_error_count
134
+ l << ''
135
+
136
+ axes.each do |a|
137
+ a.lines.each do |al|
138
+ l << al
139
+ end
140
+ end
141
+
142
+ l << '}'
143
+ l
144
+ end
145
+ end
146
+
147
+ class ShmooTestAxis
148
+ ATTRS =
149
+ %w(
150
+ name
151
+
152
+ resource_type
153
+ resource_name
154
+ setup_signal
155
+
156
+ range_resolution
157
+ range_steps
158
+ range_fast_steps
159
+ range_scale
160
+ range_list
161
+ range_start
162
+ range_stop
163
+ range_relative_percentage_start
164
+ range_relative_percentage_stop
165
+ range_relative_value_start
166
+ range_relative_value_stop
167
+ tracking
168
+ )
169
+
170
+ ALIASES = {
171
+ resolution: :range_resolution,
172
+ steps: :range_steps,
173
+ fast_steps: :range_fast_steps
174
+ }
175
+
176
+ # Generate accessors for all attributes and their aliases
177
+ ATTRS.each do |attr|
178
+ if attr == 'name'
179
+ attr_reader attr.to_sym
180
+ else
181
+ attr_accessor attr.to_sym
182
+ end
183
+ end
184
+
185
+ def initialize(name, attrs = {})
186
+ @name = name
187
+
188
+ @resource_type = attrs.delete(:resource_type)
189
+ @resource_name = attrs.delete(:resource_name)
190
+ @setup_signal = attrs.delete(:setup_signal)
191
+
192
+ if range_list = attrs.delete(:range_list)
193
+ @range_list = range_list
194
+ elsif attrs[:range] && attrs[:range].is_a?(Array)
195
+ @range_list = attrs.delete(:range)
196
+ else
197
+ if range = attrs.delete(:range)
198
+ if range.is_a?(Range)
199
+ @range_start = range.begin
200
+ @range_stop = range.end
201
+ @range_steps = attrs.delete(:range_steps) || attrs.delete(:steps)
202
+ @range_resolution = attrs.delete(:range_resolution) || attrs.delete(:resolution)
203
+ @range_fast_steps = attrs.delete(:range_fast_steps) || attrs.delete(:fast_steps)
204
+ elsif range.is_a?(Hash)
205
+ @range_start = range[:start]
206
+ @range_stop = range[:stop]
207
+ @range_steps = range[:steps]
208
+ @range_resolution = range[:resolution]
209
+ @range_fast_steps = range[:fast_steps]
210
+ end
211
+ elsif range_relative_percentage = attrs.delete(:range_relative_percentage)
212
+ if range_relative_percentage.is_a?(Range)
213
+ @range_relative_percentage_start = range_relative_percentage.begin
214
+ @range_relative_percentage_stop = range_relative_percentage.end
215
+ @range_steps = attrs.delete(:range_steps) || attrs.delete(:steps)
216
+ @range_resolution = attrs.delete(:range_resolution) || attrs.delete(:resolution)
217
+ @range_fast_steps = attrs.delete(:range_fast_steps) || attrs.delete(:fast_steps)
218
+ elsif range_relative_percentage.is_a?(Hash)
219
+ @range_relative_percentage_start = range_relative_percentage[:start]
220
+ @range_relative_percentage_stop = range_relative_percentage[:stop]
221
+ @range_steps = range_relative_percentage[:steps]
222
+ @range_resolution = range_relative_percentage[:resolution]
223
+ @range_fast_steps = range_relative_percentage[:fast_steps]
224
+ end
225
+ elsif range_relative_value = attrs.delete(:range_relative_value)
226
+ if range_relative_value.is_a?(Range)
227
+ @range_relative_value_start = range_relative_value.begin
228
+ @range_relative_value_stop = range_relative_value.end
229
+ @range_steps = attrs.delete(:range_steps) || attrs.delete(:steps)
230
+ @range_resolution = attrs.delete(:range_resolution) || attrs.delete(:resolution)
231
+ @range_fast_steps = attrs.delete(:range_fast_steps) || attrs.delete(:fast_steps)
232
+ elsif range_relative_value.is_a?(Hash)
233
+ @range_relative_value_start = range_relative_value[:start]
234
+ @range_relative_value_stop = range_relative_value[:stop]
235
+ @range_steps = range_relative_value[:steps]
236
+ @range_resolution = range_relative_value[:resolution]
237
+ @range_fast_steps = range_relative_value[:fast_steps]
238
+ end
239
+ else
240
+ attrs.each do |k, v|
241
+ send("#{k}=", v) if respond_to?("#{k}=") && k.to_sym != :name
242
+ end
243
+ end
244
+ end
245
+
246
+ if tracking = attrs.delete(:tracking)
247
+ tracking = [tracking] unless tracking.is_a?(Array)
248
+ tracking.each_with_index do |t, i|
249
+ tname = t.delete(:name) || "tracking#{i + 1}"
250
+ if trackings_names.include?(tname.to_sym)
251
+ fail "Tracking name #{tname} is already used in shmoo test axis '#{@name}'"
252
+ end
253
+ trackings << ShmooTestTracking.new(tname.to_sym, t)
254
+ end
255
+ end
256
+
257
+ attrs.each do |k, v|
258
+ send("#{k}=", v) if respond_to?("#{k}=") && k.to_sym != :name
259
+ end
260
+ end
261
+
262
+ def lines
263
+ l = []
264
+ l << " axis [#{name}] = {"
265
+ if resource_type
266
+ l << " resourceType = #{resource_type};"
267
+ else
268
+ fail 'Shmoo Axis must have a resource type'
269
+ end
270
+ if resource_name
271
+ l << " resourceName = \"#{resource_name}\";"
272
+ else
273
+ fail 'Shmoo Axis must have a resource name'
274
+ end
275
+ l << " setup_signal = \"#{setup_signal}\";" if setup_signal
276
+ if range_list
277
+ l << " range.list = \#[#{range_list.map(&:to_s).join(',')}];"
278
+ elsif range_start && range_stop
279
+ l << " range.start = #{range_start};"
280
+ l << " range.stop = #{range_stop};"
281
+ elsif range_relative_percentage_start && range_relative_percentage_stop
282
+ l << " range.relativePercentage.start = #{range_relative_percentage_start};"
283
+ l << " range.relativePercentage.stop = #{range_relative_percentage_stop};"
284
+ elsif range_relative_value_start && range_relative_value_stop
285
+ l << " range.relativeValue.start = #{range_relative_value_start};"
286
+ l << " range.relativeValue.stop = #{range_relative_value_stop};"
287
+ else
288
+ fail 'Shmoo Axis must have a range (start & stop) or range list'
289
+ end
290
+ if range_resolution && range_steps.nil?
291
+ l << " range.resolution = #{range_resolution};"
292
+ if range_fast_steps
293
+ fail 'Shmoo Axis cannot have range fast steps with range resolution'
294
+ end
295
+ elsif range_steps && range_resolution.nil?
296
+ l << " range.steps = #{range_steps};"
297
+ if range_fast_steps
298
+ l << " range.fastSteps = #{range_fast_steps};"
299
+ end
300
+ elsif range_resolution.nil? && range_steps.nil?
301
+ fail 'Shmoo Axis must define either range resolution or range steps'
302
+ else
303
+ fail 'Shmoo Axis must define either range resolution or range steps, but not both'
304
+ end
305
+ l << '' if trackings.length > 0
306
+ trackings.each do |t|
307
+ t.lines.each do |tl|
308
+ l << tl
309
+ end
310
+ end
311
+
312
+ l << ' };'
313
+ l
314
+ end
315
+
316
+ def trackings
317
+ @trackings ||= []
318
+ end
319
+
320
+ def trackings_names
321
+ trackings.map(&:name)
322
+ end
323
+ end
324
+
325
+ class ShmooTestTracking
326
+ ATTRS =
327
+ %w(
328
+ name
329
+
330
+ resource_type
331
+ resource_name
332
+ setup_signal
333
+
334
+ range_list
335
+ range_start
336
+ range_stop
337
+ range_relative_percentage_start
338
+ range_relative_percentage_stop
339
+ range_relative_value_start
340
+ range_relative_value_stop
341
+ )
342
+
343
+ # Generate accessors for all attributes and their aliases
344
+ ATTRS.each do |attr|
345
+ if attr == 'name'
346
+ attr_reader attr.to_sym
347
+ else
348
+ attr_accessor attr.to_sym
349
+ end
350
+ end
351
+
352
+ def initialize(name, attrs = {})
353
+ @name = name
354
+
355
+ @resource_type = attrs.delete(:resource_type)
356
+ @resource_name = attrs.delete(:resource_name)
357
+ @setup_signal = attrs.delete(:setup_signal)
358
+
359
+ if range = attrs.delete(:range)
360
+ if range.is_a?(Range)
361
+ @range_start = range.begin
362
+ @range_stop = range.end
363
+ elsif range.is_a?(Hash)
364
+ @range_start = range[:start]
365
+ @range_stop = range[:stop]
366
+ elsif range.is_a?(Array)
367
+ @range_list = range
368
+ end
369
+ elsif range_relative_percentage = attrs.delete(:range_relative_percentage)
370
+ if range_relative_percentage.is_a?(Range)
371
+ @range_relative_percentage_start = range_relative_percentage.begin
372
+ @range_relative_percentage_stop = range_relative_percentage.end
373
+ elsif range_relative_percentage.is_a?(Hash)
374
+ @range_relative_percentage_start = range_relative_percentage[:start]
375
+ @range_relative_percentage_stop = range_relative_percentage[:stop]
376
+ end
377
+ elsif range_relative_value = attrs.delete(:range_relative_value)
378
+ if range_relative_value.is_a?(Range)
379
+ @range_relative_value_start = range_relative_value.begin
380
+ @range_relative_value_stop = range_relative_value.end
381
+ elsif range_relative_value.is_a?(Hash)
382
+ @range_relative_value_start = range_relative_value[:start]
383
+ @range_relative_value_stop = range_relative_value[:stop]
384
+ end
385
+ else
386
+ attrs.each do |k, v|
387
+ send("#{k}=", v) if respond_to?("#{k}=") && k.to_sym != :name
388
+ end
389
+ end
390
+ end
391
+
392
+ def lines
393
+ l = []
394
+ l << " tracking [#{name}] = {"
395
+ if resource_type
396
+ l << " resourceType = #{resource_type};"
397
+ else
398
+ fail 'Shmoo Tracking must have a resource type'
399
+ end
400
+ if resource_name
401
+ l << " resourceName = \"#{resource_name}\";"
402
+ else
403
+ fail 'Shmoo Tracking must have a resource name'
404
+ end
405
+ l << " setup_signal = \"#{setup_signal}\";" if setup_signal
406
+ if range_list
407
+ l << " range.list = \#[#{range_list.map(&:to_s).join(',')}];"
408
+ elsif range_start && range_stop
409
+ l << " range.start = #{range_start};"
410
+ l << " range.stop = #{range_stop};"
411
+ elsif range_relative_percentage_start && range_relative_percentage_stop
412
+ l << " range.relativePercentage.start = #{range_relative_percentage_start};"
413
+ l << " range.relativePercentage.stop = #{range_relative_percentage_stop};"
414
+ elsif range_relative_value_start && range_relative_value_stop
415
+ l << " range.relativeValue.start = #{range_relative_value_start};"
416
+ l << " range.relativeValue.stop = #{range_relative_value_stop};"
417
+ else
418
+ fail 'Shmoo Tracking must have a range (start & stop) or range list'
419
+ end
420
+ l << ' };'
421
+ l
422
+ end
423
+ end
424
+ end
425
+ end
426
+ end
@@ -0,0 +1,92 @@
1
+ module OrigenTesters
2
+ module SmartestBasedTester
3
+ class Base
4
+ class ShmooTests
5
+ # Origen::Tester::Generator not included since test suites do not have their
6
+ # own top-level sheet, they will be incorporated within the flow sheet
7
+
8
+ attr_accessor :flow, :collection
9
+
10
+ def initialize(flow)
11
+ @flow = flow
12
+ @collection = []
13
+ @existing_names = {}
14
+ # Test names also have to be unique vs. the current flow name
15
+ if tester.smt8?
16
+ @existing_names[flow.filename.sub('.flow', '').to_s] = true
17
+ end
18
+ end
19
+
20
+ def filename
21
+ flow.filename
22
+ end
23
+
24
+ def add(name, options = {})
25
+ symbol = name.is_a?(Symbol)
26
+ name = make_unique(name)
27
+ # Ensure names given as a symbol stay as a symbol, this is more for
28
+ # alignment to existing test cases than anything else
29
+ name = name.to_sym if symbol
30
+ shmoo = platform::ShmooTest.new(name, options)
31
+ @collection << shmoo
32
+ shmoo
33
+ end
34
+ alias_method :run, :add
35
+ alias_method :run_and_branch, :add
36
+
37
+ def platform
38
+ Origen.interface.platform
39
+ end
40
+
41
+ def finalize
42
+ # match any formatting difference between test suite shmoo and test flow shmoo
43
+ @collection.each do |shmoo_test|
44
+ shmoo_test.targets.each_with_index do |target, i|
45
+ target_is_a_test_suite = false
46
+ flow.test_suites.sorted_collection.each do |suite|
47
+ if suite.name.to_s == target.to_s
48
+ target_is_a_test_suite = true
49
+ break
50
+ end
51
+ end
52
+
53
+ unless target_is_a_test_suite
54
+ target_is_a_test_flow = false
55
+ flow.sub_flows.each do |name, path|
56
+ target_name = target.to_s.gsub(' ', '_')
57
+ if name.to_s.downcase == target_name.to_s.downcase
58
+ target_is_a_test_flow = true
59
+ shmoo_test.targets[i] = name
60
+ break
61
+ end
62
+ end
63
+
64
+ unless target_is_a_test_flow
65
+ fail "Shmoo test target '#{target}' for shmoo test '#{shmoo_test.name}' not found in test suites or sub_flows"
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+ def sorted_collection
73
+ @collection.sort_by { |st| st.name.to_s }
74
+ end
75
+
76
+ private
77
+
78
+ def make_unique(name)
79
+ name = name.to_s
80
+ tempname = name
81
+ i = 0
82
+ while @existing_names[tempname]
83
+ i += 1
84
+ tempname = "#{name}_#{i}"
85
+ end
86
+ @existing_names[tempname] = true
87
+ tempname
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
@@ -21,6 +21,12 @@ flow <%= flow_name %> {
21
21
  <%= line %>
22
22
  % end
23
23
 
24
+ % end
25
+ % shmoo_tests.sorted_collection.each do |shmoo_test|
26
+ % shmoo_test.lines.each do |line|
27
+ <%= line %>
28
+ % end
29
+
24
30
  % end
25
31
  % auxiliary_flows.each do |name, path|
26
32
  flow <%= name %> calls <%= path %> {}
@@ -398,6 +398,14 @@ module OrigenTesters
398
398
  end
399
399
  end
400
400
 
401
+ def shmoo(name, targets, options = {})
402
+ if tester.v93k? && tester.smt8?
403
+ targets = [targets] unless targets.is_a?(Array)
404
+ st = shmoo_tests.run(name, { targets: targets }.merge(options))
405
+ flow.test st, options
406
+ end
407
+ end
408
+
401
409
  def por(options = {})
402
410
  options = {
403
411
  instance_not_available: true
@@ -500,13 +508,19 @@ module OrigenTesters
500
508
 
501
509
  if tester.j750? || tester.uflex?
502
510
  if tester.uflex?
503
- ins = test_instances.functional(name)
504
- ins.set_wait_flags(:a) if options[:duration] == :dynamic
511
+ if options[:pins] == :dcvi
512
+ ins = test_instances.dcvi_powersupply(name)
513
+ ins.set_wait_flags(:a) # set wait flag for tester handshake with patterns
514
+ ins.relay_mode = 1 # tlPowered - keep power on
515
+ else
516
+ ins = test_instances.functional(name)
517
+ ins.set_wait_flags(:a) if options[:duration] == :dynamic
518
+ ins.scale = options[:scale]
519
+ ins.units = options[:units]
520
+ end
505
521
  ins.pin_levels = options.delete(:pin_levels) if options[:pin_levels]
506
522
  ins.lo_limit = options[:lo_limit]
507
523
  ins.hi_limit = options[:hi_limit]
508
- ins.scale = options[:scale]
509
- ins.units = options[:units]
510
524
  ins.defer_limits = options[:defer_limits]
511
525
  else
512
526
  if options[:pins] == :hi_v
@@ -194,6 +194,7 @@ Flow.create do |options|
194
194
 
195
195
  meas :bgap_voltage_meas, tnum: 1050, bin: 119, soft_bin: 2, hi_limit: 45, number: 5910
196
196
  meas :bgap_voltage_meas1, number: 5920
197
+ meas :standby_current, pins: :dcvi, power_pins: :vdd, number: 5930
197
198
  end
198
199
 
199
200
  if tester.j750?
@@ -259,4 +260,33 @@ Flow.create do |options|
259
260
 
260
261
  double_int_type_check :type_check, number: 6035
261
262
 
263
+ if tester.smt8?
264
+ log 'shmoo test insertion works as expected, shmoo over test suite 1D'
265
+ range = { start: 3.0, stop: 5.0, steps: 10 }
266
+ axis = { name: :axis1, resource_type: 'specVariable', resource_name: 'vcc', range: range }
267
+ shmoo :shmoo_over_ts_1D, :cc_test_0, title: 'shmooOverTest', execution_order: :horizontal, axis: axis
268
+
269
+ log 'shmoo test insertion works as expected, shmoo over test suite 3D'
270
+ axis = [
271
+ { resource_type: :instrumentProperty, resource_name: 'vih', range_relative_percentage: -0.01..0.01, steps: 10 },
272
+ { resource_type: :specVariable, resource_name: 'vcc', range: 3..5, steps: 10 },
273
+ { resource_type: :suiteParameter, resource_name: 'forceVoltage', range: 4.8..5.2, steps: 10 }
274
+ ]
275
+ shmoo :shmoo_over_ts_3D, :erase_all, axis: axis, if_enable: 'do_erase'
276
+
277
+ log 'shmoo test insertion works as expected, shmoo over multiple test suites'
278
+ axis = { name: :vih, resource_type: :instrumentProperty, resource_name: 'vih', range_relative_percentage: -0.01..0.01, steps: 10 }
279
+ shmoo :shmoo_over_ts_multiple_ts, [:margin_read0_ckbd, :margin_read1_ckbd], title: 'shmooOverMultiTS', axis: axis
280
+
281
+ log 'shmoo test insertion works as expected, shmoo over test flow'
282
+ axis = { name: :vcc, resource_type: :specVariable, resource_name: 'vcc', range: 3..5, steps: 10 }
283
+ shmoo :shmoo_over_tf, "200Mhz Tests", title: 'shmooOverTF', axis: axis, if_failed: :g200
284
+
285
+ log 'shmoo test insertion works as expected, shmoo with tracking parameters'
286
+ range = { start: 0.5, stop: 3.5, steps: 10 }
287
+ tracking = { name: :voh, resource_type: 'instrumentProperty', resource_name: 'voh', range_relative_value: 1..2 }
288
+ axis = { name: :vcc, resource_type: 'specVariable', resource_name: 'vcc', range: range, tracking: tracking }
289
+ shmoo :shmoo_with_tracking_para, :erase, title: 'shmooOverTF', axis: axis
290
+ end
291
+
262
292
  end
@@ -134,4 +134,69 @@ If you wish to have a collapse-able block for the variables, you need to set the
134
134
  flow_variable_grouping: true
135
135
  ~~~
136
136
 
137
+ #### Built-In Shmoo Element
138
+
139
+ SMT8 provides a built in shmoo element that can be used to shmoo a test suite or test flow.
140
+ In order to add setup and execute code to the flow, create the shmoo_test object using `shmoo_tests.run(name, options)` and add it to the flow with `flow.test` method.
141
+
142
+
143
+ Example of integrating the shmoo api in an interface:
144
+
145
+ ~~~ruby
146
+ def shmoo(name, targets, options = {})
147
+ if tester.v93k? && tester.smt8?
148
+ targets = [targets] unless targets.is_a?(Array)
149
+ st = shmoo_tests.run(name, { targets: targets }.merge(options))
150
+ flow.test st, options
151
+ end
152
+ end
153
+ ~~~
154
+
155
+
156
+ Then in the flow, you can add the shmoo element to the flow with the following code:
157
+
158
+ ~~~ruby
159
+ Flow.create
160
+ ...
161
+ range = { start: 3.0, stop: 5.0, steps: 10 }
162
+ axis = { name: :axis1, resource_type: 'specVariable', resource_name: 'vcc', range: range }
163
+ shmoo :shmoo_over_ts_1D, :cc_test_0, title: 'shmooOverTest', execution_order: :horizontal, axis: axis
164
+ ...
165
+ end
166
+ ~~~
167
+
168
+ Please see Advantest TDC Topic 253309 for details ahbout Shmoo parameters.
169
+
170
+
171
+ The above code will generate the following flow code:
172
+
173
+ ~~~java
174
+ flow <FLOW> {
175
+ setup {
176
+ ...
177
+ shmoo shmoo_over_ts_1D {
178
+ target = cc_test_0;
179
+ resultTitle = "shmooOverTest";
180
+ executionOrder = horizontal;
181
+
182
+ axis [axis1] = {
183
+ resourceType = specVariable;
184
+ resourceName = "vcc";
185
+ range.start = 3.0;
186
+ range.stop = 5.0;
187
+ range.steps = 10;
188
+ };
189
+ }
190
+ ...
191
+ }
192
+
193
+ execute {
194
+ ...
195
+ shmoo_over_ts_1D.execute();
196
+ ...
197
+ }
198
+ }
199
+ ~~~
200
+
201
+
137
202
  % end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: origen_testers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.52.5
4
+ version: 0.52.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen McGinty
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-07-18 00:00:00.000000000 Z
11
+ date: 2024-11-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: origen
@@ -479,6 +479,8 @@ files:
479
479
  - lib/origen_testers/smartest_based_tester/v93k_smt8/generator.rb
480
480
  - lib/origen_testers/smartest_based_tester/v93k_smt8/limits_file.rb
481
481
  - lib/origen_testers/smartest_based_tester/v93k_smt8/limits_workbook.rb
482
+ - lib/origen_testers/smartest_based_tester/v93k_smt8/shmoo_test.rb
483
+ - lib/origen_testers/smartest_based_tester/v93k_smt8/shmoo_tests.rb
482
484
  - lib/origen_testers/smartest_based_tester/v93k_smt8/templates/limits.csv.erb
483
485
  - lib/origen_testers/smartest_based_tester/v93k_smt8/templates/template.flow.erb
484
486
  - lib/origen_testers/smartest_based_tester/v93k_smt8/test_suite.rb
@@ -615,7 +617,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
615
617
  - !ruby/object:Gem::Version
616
618
  version: '0'
617
619
  requirements: []
618
- rubygems_version: 3.4.10
620
+ rubygems_version: 3.1.6
619
621
  signing_key:
620
622
  specification_version: 4
621
623
  summary: This plugin provides Origen tester models to drive ATE type testers like