origen_testers 0.5.7 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|