origen_testers 0.5.7 → 0.6.0
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 +4 -4
- data/config/shared_commands.rb +6 -0
- data/config/version.rb +2 -2
- data/lib/commands/run.rb +44 -0
- data/lib/origen_testers.rb +19 -1
- data/lib/origen_testers/flow.rb +382 -0
- data/lib/origen_testers/generator.rb +32 -29
- data/lib/origen_testers/igxl_based_tester/base/ac_specsets.rb +79 -0
- data/lib/origen_testers/igxl_based_tester/base/dc_specsets.rb +98 -0
- data/lib/origen_testers/igxl_based_tester/base/edge.rb +60 -0
- data/lib/origen_testers/igxl_based_tester/base/edges.rb +24 -0
- data/lib/origen_testers/igxl_based_tester/base/edgeset.rb +39 -0
- data/lib/origen_testers/igxl_based_tester/base/edgesets.rb +97 -0
- data/lib/origen_testers/igxl_based_tester/base/flow.rb +390 -115
- data/lib/origen_testers/igxl_based_tester/base/flow_line.rb +4 -54
- data/lib/origen_testers/igxl_based_tester/base/generator.rb +257 -11
- data/lib/origen_testers/igxl_based_tester/base/level_io_se.rb +59 -0
- data/lib/origen_testers/igxl_based_tester/base/level_supply.rb +39 -0
- data/lib/origen_testers/igxl_based_tester/base/levels.rb +31 -0
- data/lib/origen_testers/igxl_based_tester/base/levelset.rb +109 -0
- data/lib/origen_testers/igxl_based_tester/base/pinmap.rb +93 -0
- data/lib/origen_testers/igxl_based_tester/base/test_instance.rb +33 -1
- data/lib/origen_testers/igxl_based_tester/base/timeset.rb +37 -0
- data/lib/origen_testers/igxl_based_tester/base/timesets.rb +47 -0
- data/lib/origen_testers/igxl_based_tester/j750/templates/flow.txt.erb +2 -2
- data/lib/origen_testers/igxl_based_tester/ultraflex/ac_specsets.rb +10 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/custom_test_instance.rb +4 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/dc_specsets.rb +10 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/edge.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/edges.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/edgeset.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/edgesets.rb +10 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/flow.rb +137 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/level_io_se.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/level_supply.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/levels.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/levelset.rb +10 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/pinmap.rb +10 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/templates/ac_specsets.txt.erb +58 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/templates/dc_specsets.txt.erb +58 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/templates/edgesets.txt.erb +95 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/templates/flow.txt.erb +2 -2
- data/lib/origen_testers/igxl_based_tester/ultraflex/templates/levelset.txt.erb +121 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/templates/pinmap.txt.erb +24 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/templates/timesets.txt.erb +137 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/test_instance.rb +4 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/timeset.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/timesets.rb +10 -0
- data/lib/origen_testers/interface.rb +41 -6
- data/lib/origen_testers/no_interface.rb +7 -0
- data/lib/origen_testers/origen_ext/application/runner.rb +25 -0
- data/lib/origen_testers/origen_ext/generator.rb +37 -0
- data/lib/origen_testers/origen_ext/generator/flow.rb +70 -0
- data/lib/origen_testers/origen_ext/generator/resources.rb +21 -0
- data/lib/origen_testers/program_generators.rb +0 -1
- data/lib/origen_testers/smartest_based_tester/base/flow.rb +158 -134
- data/lib/origen_testers/smartest_based_tester/base/generator.rb +2 -3
- data/lib/origen_testers/smartest_based_tester/base/test_suite.rb +4 -0
- data/lib/origen_testers/smartest_based_tester/v93k/templates/template.flow.erb +5 -6
- data/lib/origen_testers/test/dut.rb +5 -0
- data/lib/origen_testers/test/j750_base_interface.rb +0 -3
- data/lib/origen_testers/test/ultraflex_interface.rb +230 -4
- data/lib/origen_testers/test/v93k_interface.rb +5 -23
- data/program/components/_temp.rb +6 -0
- data/program/flow_control.rb +190 -62
- data/program/prb1.rb +13 -50
- data/program/prb2.rb +0 -16
- data/program/test.rb +12 -3
- data/program/uflex_resources.rb +159 -0
- metadata +66 -16
- data/lib/origen_testers/doc.rb +0 -224
- data/lib/origen_testers/doc/generator.rb +0 -124
- data/lib/origen_testers/doc/generator/flow.rb +0 -69
- data/lib/origen_testers/doc/generator/flow_line.rb +0 -201
- data/lib/origen_testers/doc/generator/test.rb +0 -66
- data/lib/origen_testers/doc/generator/test_group.rb +0 -64
- data/lib/origen_testers/doc/generator/tests.rb +0 -45
- data/lib/origen_testers/doc/model.rb +0 -160
- data/lib/origen_testers/generator/flow_control_api.rb +0 -611
- data/lib/origen_testers/smartest_based_tester/base/flow_node.rb +0 -476
- data/lib/origen_testers/smartest_based_tester/v93k/flow_node.rb +0 -9
|
@@ -8,7 +8,6 @@ module OrigenTesters
|
|
|
8
8
|
module Generator
|
|
9
9
|
autoload :Placeholder, 'origen_testers/generator/placeholder'
|
|
10
10
|
autoload :IdentityMap, 'origen_testers/generator/identity_map'
|
|
11
|
-
autoload :FlowControlAPI, 'origen_testers/generator/flow_control_api'
|
|
12
11
|
|
|
13
12
|
extend ActiveSupport::Concern
|
|
14
13
|
|
|
@@ -16,19 +15,8 @@ module OrigenTesters
|
|
|
16
15
|
include Origen::Generator::Comparator
|
|
17
16
|
end
|
|
18
17
|
|
|
19
|
-
# The program source files are executed by eval to allow the tester to filter the
|
|
20
|
-
# source contents before executing. For examples the doc tester replaces all comments
|
|
21
|
-
# with a method call containing each comment so that they can be captured.
|
|
22
18
|
def self.execute_source(file)
|
|
23
|
-
|
|
24
|
-
File.open(file) do |f|
|
|
25
|
-
src = f.read
|
|
26
|
-
src = Origen.interface.filter_source(src)
|
|
27
|
-
eval(src, global_binding)
|
|
28
|
-
end
|
|
29
|
-
else
|
|
30
|
-
load file
|
|
31
|
-
end
|
|
19
|
+
load file
|
|
32
20
|
end
|
|
33
21
|
|
|
34
22
|
# When called on a generator no output files will be created from it
|
|
@@ -97,6 +85,11 @@ module OrigenTesters
|
|
|
97
85
|
@filename = name
|
|
98
86
|
end
|
|
99
87
|
|
|
88
|
+
def name
|
|
89
|
+
@filename.to_sym
|
|
90
|
+
end
|
|
91
|
+
alias_method :id, :name
|
|
92
|
+
|
|
100
93
|
def filename(options = {})
|
|
101
94
|
options = {
|
|
102
95
|
include_extension: true
|
|
@@ -111,6 +104,12 @@ module OrigenTesters
|
|
|
111
104
|
ext = f.extname.empty? ? file_extension : f.extname
|
|
112
105
|
body = f.basename(".#{ext}").to_s
|
|
113
106
|
body.gsub!('_resources', '')
|
|
107
|
+
if defined? self.class::OUTPUT_PREFIX
|
|
108
|
+
# Unless the fixfix is already in the name
|
|
109
|
+
unless body =~ /#{self.class::OUTPUT_PREFIX}$/i
|
|
110
|
+
body = "#{self.class::OUTPUT_PREFIX}_#{body}"
|
|
111
|
+
end
|
|
112
|
+
end
|
|
114
113
|
if defined? self.class::OUTPUT_POSTFIX
|
|
115
114
|
# Unless the postfix is already in the name
|
|
116
115
|
unless body =~ /#{self.class::OUTPUT_POSTFIX}$/i
|
|
@@ -157,13 +156,14 @@ module OrigenTesters
|
|
|
157
156
|
if defined? self.class::TEMPLATE || Origen.tester.is_a?(OrigenTesters::Doc)
|
|
158
157
|
write_from_template(options)
|
|
159
158
|
else
|
|
160
|
-
fail "Don't know
|
|
159
|
+
fail "Don't know how to write without a template!"
|
|
161
160
|
end
|
|
162
161
|
stats.completed_files += 1
|
|
163
162
|
end
|
|
164
163
|
end
|
|
165
164
|
|
|
166
165
|
def write_from_template(options = {})
|
|
166
|
+
return unless Origen.interface.write?
|
|
167
167
|
options = {
|
|
168
168
|
quiet: false,
|
|
169
169
|
skip_diff: false
|
|
@@ -186,18 +186,8 @@ module OrigenTesters
|
|
|
186
186
|
else
|
|
187
187
|
@append = false
|
|
188
188
|
Origen.file_handler.preserve_state do
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
OrigenTesters::Doc.model.add_flow(filename(include_extension: false), to_yaml)
|
|
192
|
-
else
|
|
193
|
-
Origen.file_handler.open_for_write(output_file) do |f|
|
|
194
|
-
f.puts YAML.dump(to_yaml(include_descriptions: false))
|
|
195
|
-
end
|
|
196
|
-
end
|
|
197
|
-
else
|
|
198
|
-
File.open(output_file, 'w') do |out|
|
|
199
|
-
out.puts compiler.insert(ERB.new(File.read(self.class::TEMPLATE), 0, Origen.config.erb_trim_mode).result(binding))
|
|
200
|
-
end
|
|
189
|
+
File.open(output_file, 'w') do |out|
|
|
190
|
+
out.puts compiler.insert(ERB.new(File.read(self.class::TEMPLATE), 0, Origen.config.erb_trim_mode).result(binding))
|
|
201
191
|
end
|
|
202
192
|
end
|
|
203
193
|
@@opened_files << output_file
|
|
@@ -239,10 +229,23 @@ module OrigenTesters
|
|
|
239
229
|
end
|
|
240
230
|
|
|
241
231
|
def render(file, options = {})
|
|
242
|
-
|
|
243
|
-
|
|
232
|
+
# Since the flow is now handled via ATP, render the string immediately
|
|
233
|
+
# for insertion into the AST
|
|
234
|
+
if try(:is_the_flow?)
|
|
235
|
+
val = nil
|
|
236
|
+
Origen.file_handler.preserve_current_file do
|
|
237
|
+
Origen.file_handler.default_extension = file_extension
|
|
238
|
+
file = Origen.file_handler.clean_path_to_sub_template(file)
|
|
239
|
+
placeholder = compiler.render(file, options)
|
|
240
|
+
val = compiler.insert(placeholder).chomp
|
|
241
|
+
end
|
|
242
|
+
val
|
|
244
243
|
else
|
|
245
|
-
|
|
244
|
+
if options.delete(:_inline)
|
|
245
|
+
super Origen.file_handler.clean_path_to_sub_template(file), options
|
|
246
|
+
else
|
|
247
|
+
collection << Placeholder.new(:render, file, options)
|
|
248
|
+
end
|
|
246
249
|
end
|
|
247
250
|
end
|
|
248
251
|
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
module OrigenTesters
|
|
2
|
+
module IGXLBasedTester
|
|
3
|
+
class Base
|
|
4
|
+
class ACSpecsets
|
|
5
|
+
include ::OrigenTesters::Generator
|
|
6
|
+
|
|
7
|
+
attr_accessor :ac_specs
|
|
8
|
+
attr_accessor :ac_specsets
|
|
9
|
+
|
|
10
|
+
OUTPUT_PREFIX = 'SpecsAC'
|
|
11
|
+
# OUTPUT_POSTFIX = 'SpecsAC'
|
|
12
|
+
|
|
13
|
+
def initialize # :nodoc:
|
|
14
|
+
## Hash Autovivification
|
|
15
|
+
l = ->(h, k) { h[k] = Hash.new(&l) }
|
|
16
|
+
|
|
17
|
+
@ac_specs = []
|
|
18
|
+
@ac_specsets = Hash.new(&l)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Assigns an AC spec value object to the given variable for this specset
|
|
22
|
+
# The attrs hash is expected to defined as follows:
|
|
23
|
+
# attrs = {
|
|
24
|
+
# specset: :specset_name, # if not defined, specset = :default
|
|
25
|
+
# # Spec selectors that contain both the scope and value of the spec
|
|
26
|
+
# nom: { typ: 1.8 }, # typ is an example of the UFlex scope, nom is the spec selector
|
|
27
|
+
# min: { min: 1.7 }, # Users can defined any number of selectors in this fashion
|
|
28
|
+
# max: { max: 1.9 }
|
|
29
|
+
# }
|
|
30
|
+
def add(spec, attrs = {})
|
|
31
|
+
attrs = {
|
|
32
|
+
specset: :default
|
|
33
|
+
}.merge(attrs)
|
|
34
|
+
|
|
35
|
+
specset = attrs.delete(:specset)
|
|
36
|
+
|
|
37
|
+
@ac_specs << spec unless @ac_specs.include?(spec)
|
|
38
|
+
|
|
39
|
+
attrs.each do |selector, value|
|
|
40
|
+
@ac_specsets[specset][spec][selector] = value
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Prepare the spec information for file output
|
|
45
|
+
def format_uflex_ac_spec(data, options = {})
|
|
46
|
+
case data
|
|
47
|
+
when NilClass
|
|
48
|
+
data_new = 0
|
|
49
|
+
when Fixnum, Float
|
|
50
|
+
case
|
|
51
|
+
when data == 0
|
|
52
|
+
data_new = data.to_s
|
|
53
|
+
when data.abs < 1e-9
|
|
54
|
+
data_new = (data * 1_000_000_000_000).round(4).to_s + '*ps'
|
|
55
|
+
when data.abs < 1e-6
|
|
56
|
+
data_new = (data * 1_000_000_000).round(4).to_s + '*ns'
|
|
57
|
+
when data.abs < 1e-3
|
|
58
|
+
data_new = (data * 1_000_000).round(4).to_s + '*us'
|
|
59
|
+
when data.abs < 1
|
|
60
|
+
data_new = (data * 1_000).round(4).to_s + '*ms'
|
|
61
|
+
else
|
|
62
|
+
data_new = data.to_s
|
|
63
|
+
end
|
|
64
|
+
data_new = data_new.gsub(/^/, '=')
|
|
65
|
+
when String
|
|
66
|
+
data_new = data.gsub(/^/, '=').gsub(/(\W)([a-zA-Z])/, '\1_\2')
|
|
67
|
+
# Remove underscores from unit designations
|
|
68
|
+
data_new.gsub!(/(\W)_(nS|uS|mS|S)(\W)/i, '\1\2\3')
|
|
69
|
+
data_new.gsub!(/(\W)_(nS|uS|mS|S)$/i, '\1\2')
|
|
70
|
+
else
|
|
71
|
+
Origen.log.error "Unknown class type (#{data.class}) for spec value: #{data}"
|
|
72
|
+
fail
|
|
73
|
+
end
|
|
74
|
+
data_new
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
module OrigenTesters
|
|
2
|
+
module IGXLBasedTester
|
|
3
|
+
class Base
|
|
4
|
+
class DCSpecsets
|
|
5
|
+
include ::OrigenTesters::Generator
|
|
6
|
+
|
|
7
|
+
attr_accessor :dc_specs
|
|
8
|
+
attr_accessor :dc_specsets
|
|
9
|
+
|
|
10
|
+
OUTPUT_PREFIX = 'SpecsDC'
|
|
11
|
+
# OUTPUT_POSTFIX = 'SpecsDC'
|
|
12
|
+
|
|
13
|
+
def initialize # :nodoc:
|
|
14
|
+
## Hash Autovivification
|
|
15
|
+
l = ->(h, k) { h[k] = Hash.new(&l) }
|
|
16
|
+
|
|
17
|
+
@dc_specs = []
|
|
18
|
+
@dc_specsets = Hash.new(&l)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Assigns a DC spec value object to the given variable for this specset
|
|
22
|
+
# The attrs hash is expected to defined as follows:
|
|
23
|
+
# attrs = {
|
|
24
|
+
# specset: :specset_name, # if not defined, specset = :default
|
|
25
|
+
# # Spec selectors that contain both the scope and value of the spec
|
|
26
|
+
# nom: { typ: 1.8 }, # typ is an example of the UFlex scope, nom is the spec selector
|
|
27
|
+
# min: { min: 1.7 }, # Users can defined any number of selectors in this fashion
|
|
28
|
+
# max: { max: 1.9 }
|
|
29
|
+
# }
|
|
30
|
+
def add(spec, attrs = {})
|
|
31
|
+
attrs = {
|
|
32
|
+
specset: :default
|
|
33
|
+
}.merge(attrs)
|
|
34
|
+
|
|
35
|
+
specset = attrs.delete(:specset)
|
|
36
|
+
|
|
37
|
+
@dc_specs << spec unless @dc_specs.include?(spec)
|
|
38
|
+
|
|
39
|
+
attrs.each do |selector, value|
|
|
40
|
+
@dc_specsets[specset][spec][selector] = value
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Prepare the spec information for file output
|
|
45
|
+
def format_uflex_dc_spec(data, options = {})
|
|
46
|
+
options = {
|
|
47
|
+
spec: nil
|
|
48
|
+
}.update(options)
|
|
49
|
+
|
|
50
|
+
case options[:spec]
|
|
51
|
+
when /(voh|vol|vt|vcl|vch|vdd)/i
|
|
52
|
+
spec_type = 'volt'
|
|
53
|
+
when /(ioh|iol)/i
|
|
54
|
+
spec_type = 'curr'
|
|
55
|
+
else
|
|
56
|
+
spec_type = nil
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
case data
|
|
60
|
+
when NilClass
|
|
61
|
+
data_new = 0
|
|
62
|
+
when Fixnum, Float
|
|
63
|
+
case
|
|
64
|
+
when data == 0
|
|
65
|
+
data_new = data.to_s
|
|
66
|
+
when data.abs < 1e-6
|
|
67
|
+
data_new = (data * 1_000_000_000).round(4).to_s + '*nV' if spec_type == 'volt'
|
|
68
|
+
data_new = (data * 1_000_000_000).round(4).to_s + '*nA' if spec_type == 'curr'
|
|
69
|
+
data_new = data.to_s if spec_type.nil?
|
|
70
|
+
when data.abs < 1e-3
|
|
71
|
+
data_new = (data * 1_000_000).round(4).to_s + '*uV' if spec_type == 'volt'
|
|
72
|
+
data_new = (data * 1_000_000).round(4).to_s + '*uA' if spec_type == 'curr'
|
|
73
|
+
data_new = data.to_s if spec_type.nil?
|
|
74
|
+
when data.abs < 1
|
|
75
|
+
data_new = data.to_s + '*V' if spec_type == 'volt'
|
|
76
|
+
data_new = (data * 1_000).round(4).to_s + '*mA' if spec_type == 'curr'
|
|
77
|
+
data_new = data.to_s if spec_type.nil?
|
|
78
|
+
else
|
|
79
|
+
data_new = data.to_s + '*V' if spec_type == 'volt'
|
|
80
|
+
data_new = data.to_s + '*A' if spec_type == 'curr'
|
|
81
|
+
data_new = data.to_s if spec_type.nil?
|
|
82
|
+
end
|
|
83
|
+
data_new = data_new.gsub(/^/, '=')
|
|
84
|
+
when String
|
|
85
|
+
data_new = data.gsub(/^/, '=').gsub(/(\W)([a-zA-Z])/, '\1_\2')
|
|
86
|
+
# Remove underscores from unit designations
|
|
87
|
+
data_new.gsub!(/(\W)_(nV|uV|mV|V|nA|uA|mA|A)(\W)/i, '\1\2\3')
|
|
88
|
+
data_new.gsub!(/(\W)_(nV|uV|mV|V|nA|uA|mA|A)$/i, '\1\2')
|
|
89
|
+
else
|
|
90
|
+
Origen.log.error "Unknown class type (#{data.class}) for spec value: #{data}"
|
|
91
|
+
fail
|
|
92
|
+
end
|
|
93
|
+
data_new
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
module OrigenTesters
|
|
2
|
+
module IGXLBasedTester
|
|
3
|
+
class Base
|
|
4
|
+
class Edge
|
|
5
|
+
attr_accessor :d_src, :d_fmt, :d0_edge, :d1_edge, :d2_edge, :d3_edge # Input pin timing information
|
|
6
|
+
attr_accessor :c_mode, :c1_edge, :c2_edge # Output pin timing information
|
|
7
|
+
attr_accessor :t_res, :clk_per
|
|
8
|
+
|
|
9
|
+
def initialize(options = {}) # :nodoc:
|
|
10
|
+
options = {
|
|
11
|
+
d_src: 'PAT', # source of the channel drive data (e.g. pattern, drive_hi, drive_lo, etc.)
|
|
12
|
+
d_fmt: 'NR', # drive data format (NR, RL, RH, etc.)
|
|
13
|
+
d0_edge: '', # time at which the input drive is turned on
|
|
14
|
+
d1_edge: '', # time of the initial data drive edge
|
|
15
|
+
d2_edge: '', # time of the return format data drive edge
|
|
16
|
+
d3_edge: '', # time at which the input drive is turned off
|
|
17
|
+
c_mode: 'Edge', # output compare mode
|
|
18
|
+
c1_edge: '', # time of the initial output compare edge
|
|
19
|
+
c2_edge: '', # time of the final output compare edge (window compare)
|
|
20
|
+
t_res: 'Machine', # timing resolution (possibly ATE-specific)
|
|
21
|
+
clk_per: '' # clock period equation - for use with MCG
|
|
22
|
+
}.merge(options)
|
|
23
|
+
@d_src = options[:d_src]
|
|
24
|
+
@d_fmt = options[:d_fmt]
|
|
25
|
+
@d0_edge = options[:d0_edge]
|
|
26
|
+
@d1_edge = options[:d1_edge]
|
|
27
|
+
@d2_edge = options[:d2_edge]
|
|
28
|
+
@d3_edge = options[:d3_edge]
|
|
29
|
+
@c_mode = options[:c_mode]
|
|
30
|
+
@c1_edge = options[:c1_edge]
|
|
31
|
+
@c2_edge = options[:c2_edge]
|
|
32
|
+
@t_res = options[:t_res]
|
|
33
|
+
@clk_per = options[:clk_per]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def ==(edge)
|
|
37
|
+
if edge.is_a? Edge
|
|
38
|
+
d_src == edge.d_src &&
|
|
39
|
+
d_fmt == edge.d_fmt &&
|
|
40
|
+
d0_edge == edge.d0_edge &&
|
|
41
|
+
d1_edge == edge.d1_edge &&
|
|
42
|
+
d2_edge == edge.d2_edge &&
|
|
43
|
+
d3_edge == edge.d3_edge &&
|
|
44
|
+
c_mode == edge.c_mode &&
|
|
45
|
+
c1_edge == edge.c1_edge &&
|
|
46
|
+
c2_edge == edge.c2_edge &&
|
|
47
|
+
t_res == edge.t_res &&
|
|
48
|
+
clk_per == edge.clk_per
|
|
49
|
+
else
|
|
50
|
+
super
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def platform
|
|
55
|
+
Origen.interface.platform
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module OrigenTesters
|
|
2
|
+
module IGXLBasedTester
|
|
3
|
+
class Base
|
|
4
|
+
class Edges
|
|
5
|
+
include ::OrigenTesters::Generator
|
|
6
|
+
|
|
7
|
+
attr_accessor :edges
|
|
8
|
+
|
|
9
|
+
def initialize(options = {}) # :nodoc:
|
|
10
|
+
@edges = Hash.new do |h, k|
|
|
11
|
+
h[k] = {}
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Defines a new Edge object for the category and pin name
|
|
16
|
+
def add(grp, pin, options = {})
|
|
17
|
+
grp = grp.to_sym unless grp.is_a? Symbol
|
|
18
|
+
pin = pin.to_sym unless pin.is_a? Symbol
|
|
19
|
+
edges[grp][pin] = platform::Edge.new(options)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
module OrigenTesters
|
|
2
|
+
module IGXLBasedTester
|
|
3
|
+
class Base
|
|
4
|
+
class Edgeset
|
|
5
|
+
attr_accessor :period, :t_mode # Edgeset information
|
|
6
|
+
attr_accessor :pins
|
|
7
|
+
attr_accessor :spec_sheet
|
|
8
|
+
attr_accessor :name
|
|
9
|
+
|
|
10
|
+
def initialize(name, pin, edge, attrs = {}) # :nodoc:
|
|
11
|
+
attrs = {
|
|
12
|
+
period: '', # tester cycle duration
|
|
13
|
+
t_mode: '', # timing mode (possibly ATE-specific)
|
|
14
|
+
spec_sheet: 'default' # defines which specset sheet to put variables in (e.g. func, scan) when generating specset files
|
|
15
|
+
}.merge(attrs)
|
|
16
|
+
@period = attrs[:period]
|
|
17
|
+
@t_mode = attrs[:t_mode]
|
|
18
|
+
@spec_sheet = attrs[:spec_sheet]
|
|
19
|
+
@pins = { pin => edge }
|
|
20
|
+
self.name = name
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Assigns a timing edge object to the given pin for this edgeset
|
|
24
|
+
def add_edge(pin, edge)
|
|
25
|
+
if @pins.key?(pin)
|
|
26
|
+
Origen.log.error "Pin #{pin} already exists in edgeset"
|
|
27
|
+
fail
|
|
28
|
+
else
|
|
29
|
+
@pins[pin] = edge
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def platform
|
|
34
|
+
Origen.interface.platform
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
module OrigenTesters
|
|
2
|
+
module IGXLBasedTester
|
|
3
|
+
class Base
|
|
4
|
+
class Edgesets
|
|
5
|
+
include ::OrigenTesters::Generator
|
|
6
|
+
|
|
7
|
+
attr_accessor :es
|
|
8
|
+
attr_accessor :es_sheet_pins
|
|
9
|
+
|
|
10
|
+
OUTPUT_PREFIX = 'ES'
|
|
11
|
+
# OUTPUT_POSTFIX = 'ES'
|
|
12
|
+
|
|
13
|
+
def initialize # :nodoc:
|
|
14
|
+
@es = {}
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def add(esname, pin, edge, options = {})
|
|
18
|
+
esname = esname.to_sym unless esname.is_a? Symbol
|
|
19
|
+
pin = pin.to_sym unless pin.is_a? Symbol
|
|
20
|
+
@es.key?(esname) ? @es[esname].add_edge(pin, edge) : @es[esname] = platform::Edgeset.new(esname, pin, edge, options)
|
|
21
|
+
@es_sheet_pins = options[:es_sheet_pins] unless @es_sheet_pins
|
|
22
|
+
@es
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def finalize(options = {})
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Populate an array of pins based on the pin or pingroup
|
|
29
|
+
def get_pin_objects(grp)
|
|
30
|
+
pins = []
|
|
31
|
+
if Origen.top_level.pin(grp).is_a?(Origen::Pins::Pin) ||
|
|
32
|
+
Origen.top_level.pin(grp).is_a?(Origen::Pins::FunctionProxy)
|
|
33
|
+
pins << Origen.top_level.pin(grp)
|
|
34
|
+
elsif Origen.top_level.pin(grp).is_a?(Origen::Pins::PinCollection)
|
|
35
|
+
Origen.top_level.pin(grp).each do |pin|
|
|
36
|
+
pins << pin
|
|
37
|
+
end
|
|
38
|
+
else
|
|
39
|
+
Origen.log.error "Could not find pin class: #{grp} #{Origen.top_level.pin(grp).class}"
|
|
40
|
+
end
|
|
41
|
+
pins
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Equality check to compare full contents of edge object
|
|
45
|
+
def edges_eql?(edge1, edge2)
|
|
46
|
+
edge1 == edge2
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Globally modify text within the edge object
|
|
50
|
+
def gsub_edges!(edge, old_val, new_val)
|
|
51
|
+
edge.d_src = edge.d_src.gsub(/#{Regexp.escape(old_val)}/, new_val)
|
|
52
|
+
edge.d_fmt = edge.d_fmt.gsub(/#{Regexp.escape(old_val)}/, new_val)
|
|
53
|
+
edge.d0_edge = edge.d0_edge.gsub(/#{Regexp.escape(old_val)}/, new_val)
|
|
54
|
+
edge.d1_edge = edge.d1_edge.gsub(/#{Regexp.escape(old_val)}/, new_val)
|
|
55
|
+
edge.d2_edge = edge.d2_edge.gsub(/#{Regexp.escape(old_val)}/, new_val)
|
|
56
|
+
edge.d3_edge = edge.d3_edge.gsub(/#{Regexp.escape(old_val)}/, new_val)
|
|
57
|
+
edge.c_mode = edge.c_mode.gsub(/#{Regexp.escape(old_val)}/, new_val)
|
|
58
|
+
edge.c1_edge = edge.c1_edge.gsub(/#{Regexp.escape(old_val)}/, new_val)
|
|
59
|
+
edge.c2_edge = edge.c2_edge.gsub(/#{Regexp.escape(old_val)}/, new_val)
|
|
60
|
+
edge.t_res = edge.t_res.gsub(/#{Regexp.escape(old_val)}/, new_val)
|
|
61
|
+
edge.clk_per = edge.clk_per.gsub(/#{Regexp.escape(old_val)}/, new_val)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Prepare the edge information for ES/TS file output
|
|
65
|
+
def format_uflex_edge(data, line_cnt, options = {})
|
|
66
|
+
options = {
|
|
67
|
+
no_disable: false
|
|
68
|
+
}.merge(options)
|
|
69
|
+
|
|
70
|
+
if data !~ /^\s*$/
|
|
71
|
+
data = data.gsub(/^/, '=')
|
|
72
|
+
end
|
|
73
|
+
data = data.gsub(/(\W)([a-zA-Z])/, '\1_\2')
|
|
74
|
+
|
|
75
|
+
case data
|
|
76
|
+
when /_d0_edge|_d_on/
|
|
77
|
+
data = data.gsub(/_d0_edge|_d_on/, "F#{line_cnt}")
|
|
78
|
+
when /_d1_edge|_d_data/
|
|
79
|
+
data = data.gsub(/_d1_edge|_d_data/, "G#{line_cnt}")
|
|
80
|
+
when /_d2_edge|_dret/
|
|
81
|
+
data = data.gsub(/_d2_edge|_dret/, "H#{line_cnt}")
|
|
82
|
+
when /_d3_edge|_d_off/
|
|
83
|
+
data = data.gsub(/_d3_edge|_d_off/, "I#{line_cnt}")
|
|
84
|
+
when /_c1_edge|_c_open/
|
|
85
|
+
data = data.gsub(/_c1_edge|_c_open/, "K#{line_cnt}")
|
|
86
|
+
when /_c2_edge|_c_close/
|
|
87
|
+
data = data.gsub(/_c2_edge|_c_close/, "L#{line_cnt}")
|
|
88
|
+
when /^\s*$/
|
|
89
|
+
options[:no_disable] ? data = '' : data = 'disable'
|
|
90
|
+
else
|
|
91
|
+
data
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|