origen 0.2.6 → 0.3.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.
Files changed (158) hide show
  1. checksums.yaml +4 -4
  2. data/bin/origen +3 -1
  3. data/config/boot.rb +1 -7
  4. data/config/commands.rb +0 -1
  5. data/config/version.rb +2 -2
  6. data/lib/c99/{j750_interface.rb → ate_interface.rb} +3 -11
  7. data/lib/c99/doc_interface.rb +1 -1
  8. data/lib/origen.rb +9 -30
  9. data/lib/origen/application.rb +10 -8
  10. data/lib/origen/application/configuration.rb +13 -26
  11. data/lib/origen/application/plugins.rb +122 -0
  12. data/lib/origen/application/plugins_manager.rb +16 -254
  13. data/lib/origen/application/release.rb +2 -2
  14. data/lib/origen/application/runner.rb +2 -4
  15. data/lib/origen/chips.rb +0 -0
  16. data/lib/origen/chips/chip.rb +0 -0
  17. data/lib/origen/chips/design_entry.rb +0 -0
  18. data/lib/origen/chips/doc_entry.rb +0 -0
  19. data/lib/origen/chips/note.rb +0 -0
  20. data/lib/origen/commands.rb +4 -44
  21. data/lib/origen/commands/compile.rb +1 -2
  22. data/lib/origen/commands/generate.rb +1 -1
  23. data/lib/origen/commands/interactive.rb +1 -2
  24. data/lib/origen/commands/plugin.rb +49 -56
  25. data/lib/origen/commands/program.rb +1 -1
  26. data/lib/origen/commands/rc.rb +2 -2
  27. data/lib/origen/commands/version.rb +2 -17
  28. data/lib/origen/commands_global.rb +3 -0
  29. data/lib/origen/file_handler.rb +10 -10
  30. data/lib/origen/generator.rb +1 -1
  31. data/lib/origen/generator/job.rb +1 -1
  32. data/lib/origen/generator/pattern.rb +2 -2
  33. data/lib/origen/generator/pattern_finder.rb +10 -9
  34. data/lib/origen/pins/pin.rb +0 -0
  35. data/lib/origen/regression_manager.rb +0 -0
  36. data/lib/origen/remote_manager.rb +2 -8
  37. data/lib/origen/revision_control/design_sync.rb +0 -0
  38. data/lib/origen/revision_control/git.rb +0 -0
  39. data/lib/origen/specs.rb +0 -0
  40. data/lib/origen/specs/checkers.rb +0 -0
  41. data/lib/origen/specs/creation_info.rb +0 -0
  42. data/lib/origen/specs/exhibit.rb +0 -0
  43. data/lib/origen/specs/spec.rb +0 -0
  44. data/lib/origen/utility.rb +0 -1
  45. data/lib/origen/utility/diff.rb +0 -0
  46. metadata +42 -119
  47. data/lib/origen/import_manager.rb +0 -596
  48. data/lib/origen/nvm.rb +0 -6
  49. data/lib/origen/nvm/block_array.rb +0 -72
  50. data/lib/origen/tester.rb +0 -56
  51. data/lib/origen/tester/api.rb +0 -277
  52. data/lib/origen/tester/bdm/bdm.rb +0 -25
  53. data/lib/origen/tester/doc/doc.rb +0 -226
  54. data/lib/origen/tester/doc/generator.rb +0 -126
  55. data/lib/origen/tester/doc/generator/flow.rb +0 -71
  56. data/lib/origen/tester/doc/generator/flow_line.rb +0 -203
  57. data/lib/origen/tester/doc/generator/test.rb +0 -68
  58. data/lib/origen/tester/doc/generator/test_group.rb +0 -66
  59. data/lib/origen/tester/doc/generator/tests.rb +0 -47
  60. data/lib/origen/tester/doc/model.rb +0 -162
  61. data/lib/origen/tester/generator.rb +0 -271
  62. data/lib/origen/tester/generator/flow_control_api.rb +0 -606
  63. data/lib/origen/tester/generator/identity_map.rb +0 -25
  64. data/lib/origen/tester/generator/placeholder.rb +0 -13
  65. data/lib/origen/tester/generator/test_numberer.rb +0 -25
  66. data/lib/origen/tester/interface.rb +0 -154
  67. data/lib/origen/tester/j750/files.rb +0 -45
  68. data/lib/origen/tester/j750/generator.rb +0 -203
  69. data/lib/origen/tester/j750/generator/flow.rb +0 -123
  70. data/lib/origen/tester/j750/generator/flow_line.rb +0 -288
  71. data/lib/origen/tester/j750/generator/patgroup.rb +0 -111
  72. data/lib/origen/tester/j750/generator/patgroups.rb +0 -41
  73. data/lib/origen/tester/j750/generator/patset.rb +0 -111
  74. data/lib/origen/tester/j750/generator/patsets.rb +0 -41
  75. data/lib/origen/tester/j750/generator/templates/flow.txt.erb +0 -9
  76. data/lib/origen/tester/j750/generator/templates/instances.txt.erb +0 -16
  77. data/lib/origen/tester/j750/generator/templates/patgroups.txt.erb +0 -8
  78. data/lib/origen/tester/j750/generator/templates/patsets.txt.erb +0 -10
  79. data/lib/origen/tester/j750/generator/test_instance.rb +0 -846
  80. data/lib/origen/tester/j750/generator/test_instance_group.rb +0 -60
  81. data/lib/origen/tester/j750/generator/test_instances.rb +0 -182
  82. data/lib/origen/tester/j750/j750.rb +0 -845
  83. data/lib/origen/tester/j750/j750_hpt.rb +0 -35
  84. data/lib/origen/tester/j750/parser.rb +0 -104
  85. data/lib/origen/tester/j750/parser/ac_spec.rb +0 -11
  86. data/lib/origen/tester/j750/parser/ac_specs.rb +0 -0
  87. data/lib/origen/tester/j750/parser/dc_spec.rb +0 -36
  88. data/lib/origen/tester/j750/parser/dc_specs.rb +0 -50
  89. data/lib/origen/tester/j750/parser/descriptions.rb +0 -340
  90. data/lib/origen/tester/j750/parser/flow.rb +0 -111
  91. data/lib/origen/tester/j750/parser/flow_line.rb +0 -207
  92. data/lib/origen/tester/j750/parser/flows.rb +0 -23
  93. data/lib/origen/tester/j750/parser/pattern_set.rb +0 -94
  94. data/lib/origen/tester/j750/parser/pattern_sets.rb +0 -33
  95. data/lib/origen/tester/j750/parser/test_instance.rb +0 -322
  96. data/lib/origen/tester/j750/parser/test_instances.rb +0 -26
  97. data/lib/origen/tester/j750/parser/timeset.rb +0 -15
  98. data/lib/origen/tester/j750/parser/timesets.rb +0 -0
  99. data/lib/origen/tester/jlink/jlink.rb +0 -33
  100. data/lib/origen/tester/parser.rb +0 -24
  101. data/lib/origen/tester/parser/description_lookup.rb +0 -64
  102. data/lib/origen/tester/parser/searchable_array.rb +0 -32
  103. data/lib/origen/tester/parser/searchable_hash.rb +0 -32
  104. data/lib/origen/tester/time.rb +0 -338
  105. data/lib/origen/tester/timing.rb +0 -253
  106. data/lib/origen/tester/ultraflex/files.rb +0 -45
  107. data/lib/origen/tester/ultraflex/generator.rb +0 -200
  108. data/lib/origen/tester/ultraflex/generator/flow.rb +0 -119
  109. data/lib/origen/tester/ultraflex/generator/flow_line.rb +0 -269
  110. data/lib/origen/tester/ultraflex/generator/patgroup.rb +0 -111
  111. data/lib/origen/tester/ultraflex/generator/patgroups.rb +0 -41
  112. data/lib/origen/tester/ultraflex/generator/patset.rb +0 -111
  113. data/lib/origen/tester/ultraflex/generator/patsets.rb +0 -41
  114. data/lib/origen/tester/ultraflex/generator/templates/flow.txt.erb +0 -9
  115. data/lib/origen/tester/ultraflex/generator/templates/instances.txt.erb +0 -16
  116. data/lib/origen/tester/ultraflex/generator/templates/patgroups.txt.erb +0 -8
  117. data/lib/origen/tester/ultraflex/generator/templates/patsets.txt.erb +0 -10
  118. data/lib/origen/tester/ultraflex/generator/test_instance.rb +0 -622
  119. data/lib/origen/tester/ultraflex/generator/test_instance_group.rb +0 -60
  120. data/lib/origen/tester/ultraflex/generator/test_instances.rb +0 -174
  121. data/lib/origen/tester/ultraflex/parser.rb +0 -104
  122. data/lib/origen/tester/ultraflex/parser/ac_spec.rb +0 -11
  123. data/lib/origen/tester/ultraflex/parser/ac_specs.rb +0 -0
  124. data/lib/origen/tester/ultraflex/parser/dc_spec.rb +0 -36
  125. data/lib/origen/tester/ultraflex/parser/dc_specs.rb +0 -50
  126. data/lib/origen/tester/ultraflex/parser/descriptions.rb +0 -342
  127. data/lib/origen/tester/ultraflex/parser/flow.rb +0 -111
  128. data/lib/origen/tester/ultraflex/parser/flow_line.rb +0 -207
  129. data/lib/origen/tester/ultraflex/parser/flows.rb +0 -23
  130. data/lib/origen/tester/ultraflex/parser/pattern_set.rb +0 -94
  131. data/lib/origen/tester/ultraflex/parser/pattern_sets.rb +0 -33
  132. data/lib/origen/tester/ultraflex/parser/test_instance.rb +0 -262
  133. data/lib/origen/tester/ultraflex/parser/test_instances.rb +0 -26
  134. data/lib/origen/tester/ultraflex/parser/timeset.rb +0 -15
  135. data/lib/origen/tester/ultraflex/parser/timesets.rb +0 -0
  136. data/lib/origen/tester/ultraflex/ultraflex.rb +0 -759
  137. data/lib/origen/tester/v93k/generator.rb +0 -80
  138. data/lib/origen/tester/v93k/generator/flow.rb +0 -63
  139. data/lib/origen/tester/v93k/generator/flow_node.rb +0 -17
  140. data/lib/origen/tester/v93k/generator/flow_node/print.rb +0 -10
  141. data/lib/origen/tester/v93k/generator/pattern.rb +0 -16
  142. data/lib/origen/tester/v93k/generator/pattern_master.rb +0 -54
  143. data/lib/origen/tester/v93k/generator/templates/_test_method.txt.erb +0 -6
  144. data/lib/origen/tester/v93k/generator/templates/_test_suite.txt.erb +0 -11
  145. data/lib/origen/tester/v93k/generator/templates/template.flow.erb +0 -121
  146. data/lib/origen/tester/v93k/generator/templates/template.pmfl.erb +0 -9
  147. data/lib/origen/tester/v93k/generator/test_function.rb +0 -103
  148. data/lib/origen/tester/v93k/generator/test_functions.rb +0 -79
  149. data/lib/origen/tester/v93k/generator/test_method.rb +0 -46
  150. data/lib/origen/tester/v93k/generator/test_methods.rb +0 -75
  151. data/lib/origen/tester/v93k/generator/test_suite.rb +0 -54
  152. data/lib/origen/tester/v93k/generator/test_suites.rb +0 -65
  153. data/lib/origen/tester/v93k/v93k.rb +0 -420
  154. data/lib/origen/tester/vector.rb +0 -86
  155. data/lib/origen/tester/vector_generator.rb +0 -637
  156. data/lib/origen/tester/vector_pipeline.rb +0 -150
  157. data/lib/origen/utility/design_sync.rb +0 -494
  158. data/lib/origen/version_checker.rb +0 -117
@@ -1,60 +0,0 @@
1
- module Origen
2
- module Tester
3
- class J750
4
- module Generator
5
- class TestInstanceGroup
6
- attr_accessor :name, :version, :append_version
7
-
8
- include Enumerable
9
-
10
- def initialize(name, _options = {})
11
- @name = name
12
- @store = []
13
- @append_version = true
14
- end
15
-
16
- def name
17
- if unversioned_name
18
- if version && @append_version
19
- "#{unversioned_name}_v#{version}"
20
- else
21
- unversioned_name.to_s
22
- end
23
- end
24
- end
25
-
26
- def unversioned_name
27
- if @name
28
- if @name =~ /grp$/
29
- @name
30
- else
31
- "#{@name}_grp"
32
- end
33
- end
34
- end
35
-
36
- def <<(instance)
37
- @store << instance
38
- end
39
-
40
- def size
41
- @store.size
42
- end
43
-
44
- def each
45
- @store.each { |ins| yield ins }
46
- end
47
-
48
- def ==(other_instance_group)
49
- self.class == other_instance_group.class &&
50
- unversioned_name.to_s == other_instance_group.unversioned_name.to_s &&
51
- size == other_instance_group.size &&
52
- self.all? do |ins|
53
- other_instance_group.any? { |other_ins| ins == other_ins }
54
- end
55
- end
56
- end
57
- end
58
- end
59
- end
60
- end
@@ -1,182 +0,0 @@
1
- module Origen
2
- module Tester
3
- class J750
4
- module Generator
5
- class TestInstances
6
- include Origen::Tester::Generator
7
-
8
- TEMPLATE = "#{Origen.top}/lib/origen/tester/j750/generator/templates/instances.txt.erb"
9
- OUTPUT_POSTFIX = 'instances'
10
-
11
- class IndexedString < ::String
12
- attr_accessor :index
13
-
14
- def name
15
- self
16
- end
17
- end
18
-
19
- def add(name, type, options = {})
20
- options = {
21
- test_instance_class: TestInstance
22
- }.merge(options)
23
- ins = options.delete(:test_instance_class).new(name, type, options)
24
- if @current_group
25
- @current_group << ins
26
- else
27
- collection << ins
28
- end
29
- c = Origen.interface.consume_comments
30
- Origen.interface.descriptions.add_for_test_definition(name, c)
31
- ins
32
- end
33
-
34
- # IG-XL doesn't have a formal instance group type and instead declares them anonymously
35
- # whenever test instances of the same name appear consecutively in the test instance sheet.
36
- # However when it comes to generating a test program life becomes much easier if we have
37
- # a way to explicitly declare instances as part of a group - this makes duplicate tracking
38
- # and sorting of the test instance sheet much easier.
39
- #
40
- # Use this method to generate instance groups via a block. Within the the block you should
41
- # generate instances as normal and they will automatically be assigned to the current group.
42
- # Note that the name of the instances generated within the group is discarded and replaced
43
- # with the name of the group. Origen automatically appends "grp" to this name to highlight
44
- # instances that were generated as part of the group.
45
- #
46
- # test_instances.group("erase_all_blocks") do |group|
47
- # # Generate instances here as normal
48
- # test_instances.functional("erase_blk0")
49
- # test_instances.functional("erase_blk1")
50
- # end
51
- #
52
- # The group object is passed into the block but usually you should not need to interact
53
- # with this directly except maybe to set the name if it is not yet established at the point
54
- # where the group is initiated:
55
- #
56
- # test_instances.group do |group|
57
- # # Generate instances here as normal
58
- # group.name = "group_blah"
59
- # end
60
- #
61
- # A common way to generate groups is to create a helper method in your application which
62
- # is responsible for creating groups as required:
63
- #
64
- # def group_wrapper(name, options)
65
- # if options[:by_block]
66
- # test_instances.group(name) do |group|
67
- # yield group
68
- # end
69
- # else
70
- # yield
71
- # end
72
- # end
73
- #
74
- # In that case the group argument becomes quite useful for branching based on whether you
75
- # are generating a group or standalone instances:
76
- #
77
- # group_wrapper(name, options) do |group|
78
- # if group
79
- # # Generate group instances
80
- # else
81
- # # Generate standalone instances
82
- # end
83
- # end
84
- def group(name = nil, options = {})
85
- name, options = nil, name if name.is_a?(Hash)
86
- @current_group = TestInstanceGroup.new(name, options)
87
- collection << @current_group
88
- yield @current_group
89
- @current_group = nil
90
- end
91
- alias_method :add_group, :group
92
-
93
- def finalize(_options = {}) # :nodoc:
94
- uniq!
95
- sort!
96
- end
97
-
98
- def uniq! # :nodoc:
99
- uniques = []
100
- versions = {}
101
- multi_version_tests = {}
102
- collection.each do |instance|
103
- # If a uniquely named instance is found add it, otherwise update the version
104
- # of the current instance to match that of the existing instance that it duplicates
105
- unless uniques.any? do |i|
106
- if i == instance
107
- instance.version = i.version
108
- true
109
- else
110
- false
111
- end
112
- end
113
- if instance.respond_to?(:version=)
114
- versions[instance.unversioned_name] ||= 0
115
- versions[instance.unversioned_name] += 1
116
- if versions[instance.unversioned_name] > 1
117
- multi_version_tests[instance.unversioned_name] = true
118
- end
119
- instance.version = versions[instance.unversioned_name]
120
- end
121
- uniques << instance
122
- end
123
- end
124
- # This final loop disables the version identifier for tests that have only a single version,
125
- # this makes it clearer when multiple versions exist - whenever you see a v1 you know there
126
- # is at least a v2 also.
127
- collection.map! do |instance|
128
- if instance.respond_to?(:version=)
129
- unless multi_version_tests[instance.unversioned_name]
130
- instance.append_version = false
131
- end
132
- end
133
- instance
134
- end
135
- self.collection = uniques
136
- end
137
-
138
- def sort! # :nodoc:
139
- # Present the instances in the final sheet in alphabetical order
140
- collection.map!.with_index do |ins, _i|
141
- if ins.is_a?(String) # Can happen if content has been rendered in from a template
142
- ins = IndexedString.new(ins)
143
- end
144
- ins
145
- end
146
- collection.sort! { |a, b| [a.name.to_s] <=> [b.name.to_s] }
147
- end
148
-
149
- def bpmu(name, options = {})
150
- add(name, :board_pmu, options)
151
- end
152
- alias_method :board_pmu, :bpmu
153
-
154
- def ppmu(name, options = {})
155
- add(name, :pin_pmu, options)
156
- end
157
- alias_method :pin_pmu, :ppmu
158
-
159
- def functional(name, options = {})
160
- add(name, :functional, options)
161
- end
162
-
163
- def empty(name, options = {})
164
- add(name, :empty, options)
165
- end
166
-
167
- def other(name, options = {})
168
- add(name, :other, options)
169
- end
170
-
171
- def apmu_powersupply(name, options = {})
172
- add(name, :apmu_powersupply, options)
173
- end
174
-
175
- def mto_memory(name, options = {})
176
- add(name, :mto_memory, options)
177
- end
178
- end
179
- end
180
- end
181
- end
182
- end
@@ -1,845 +0,0 @@
1
- module Origen
2
- module Tester
3
- # This class is soon to be deprecated
4
- # Origen.deprecate <<-END
5
- # J750 Tester in Origen core is currently being moved to a dedicated plugin,
6
- # use Testers::J750 from this plugin instead of Origen::Tester::J750
7
- # http://origen.freescale.net/testers
8
- # END
9
-
10
- # Tester model to generate .atp patterns for the Teradyne J750
11
- #
12
- # == Basic Usage
13
- # $tester = Origen::Tester::J750.new
14
- # $tester.cycle # Generate a vector
15
- #
16
- # Many more methods exist to generate J750 specific micro-code, see below for
17
- # details.
18
- #
19
- # Also note that this class inherits from the base Tester class and so all methods
20
- # described there are also available.
21
- class J750
22
- include Tester
23
- include Parser
24
- require 'origen/tester/j750/files'
25
- include Files
26
-
27
- autoload :Parser, 'origen/tester/j750/parser'
28
- autoload :Generator, 'origen/tester/j750/generator'
29
-
30
- attr_accessor :use_hv_pin
31
- attr_accessor :software_version
32
-
33
- def self.hpt_mode
34
- @@hpt_mode
35
- end
36
- def self.hpt_mode?
37
- @@hpt_mode
38
- end
39
-
40
- # Returns a new J750 instance, normally there would only ever be one of these
41
- # assigned to the global variable such as $tester by your target:
42
- # $tester = J750.new
43
- def initialize
44
- @unique_counter = 0
45
- @max_repeat_loop = 65_535
46
- @min_repeat_loop = 2
47
- @pat_extension = 'atp'
48
- @active_loads = true
49
- @pipeline_depth = 34 # for extended mode is vectors, for normal mode is vector pairs (54 for J750Ex)
50
- @use_hv_pin = false # allows to use high voltage for a pin for all patterns
51
- @software_version = '3.50.40'
52
- @compress = true
53
- @support_repeat_previous = true
54
- @match_entries = 10
55
- @name = 'j750'
56
- @program_comment_char = ['logprint', "'"]
57
- @@hpt_mode = false
58
- end
59
-
60
- def flows
61
- parser.flows
62
- end
63
-
64
- # Main accessor to all content parsed from existing test program sheets found in the
65
- # supplied directory or in Origen.config.test_program_output_directory
66
- def parser(prog_dir = Origen.config.test_program_output_directory)
67
- unless prog_dir
68
- fail 'You must supply the directory containing the test program sheets, or define it via Origen.config.test_program_output_directory'
69
- end
70
- @parser ||= J750::Parser.new
71
- @parsed_dir ||= false
72
- if @parsed_dir != prog_dir
73
- @parser.parse(prog_dir)
74
- @parsed_dir = prog_dir
75
- end
76
- @parser
77
- end
78
-
79
- # Capture a vector to the tester HRAM.
80
- #
81
- # This method applys a store vector (stv) opcode to the previous vector, note that is does
82
- # not actually generate a new vector.
83
- #
84
- # Sometimes when generating vectors within a loop you may want to apply a stv opcode
85
- # retrospectively to a previous vector, passing in an offset option will allow you
86
- # to do this.
87
- #
88
- # On J750 the pins argument is ignored since the tester only supports whole vector capture.
89
- #
90
- # @example
91
- # $tester.cycle # This is the vector you want to capture
92
- # $tester.store # This applys the STV opcode
93
- #
94
- # $tester.cycle # This one gets stored
95
- # $tester.cycle
96
- # $tester.cycle
97
- # $tester.store(:offset => -2) # Just realized I need to capture that earlier vector
98
- def store(*pins)
99
- options = pins.last.is_a?(Hash) ? pins.pop : {}
100
- options = { offset: 0
101
- }.merge(options)
102
- update_vector microcode: 'stv', offset: options[:offset]
103
- end
104
- alias_method :to_hram, :store
105
- alias_method :capture, :store
106
-
107
- # Capture the next vector generated to HRAM
108
- #
109
- # This method applys a store vector (stv) opcode to the next vector to be generated,
110
- # note that is does not actually generate a new vector.
111
- #
112
- # On J750 the pins argument is ignored since the tester only supports whole vector capture.
113
- #
114
- # @example
115
- # $tester.store_next_cycle
116
- # $tester.cycle # This is the vector that will be captured
117
- def store_next_cycle(*pins)
118
- options = pins.last.is_a?(Hash) ? pins.pop : {}
119
- options = {
120
- }.merge(options)
121
- preset_next_vector microcode: 'stv'
122
- end
123
-
124
- # Call a subroutine.
125
- #
126
- # This method applies a call subroutine opcode to the previous vector, it does not
127
- # generate a new vector.
128
- #
129
- # Subroutines should always be called through this method as it ensures a running
130
- # log of called subroutines is maintained and which then gets output in the pattern
131
- # header to import the right dependencies.
132
- #
133
- # An offset option is available to make the call on earlier vectors.
134
- #
135
- # ==== Examples
136
- # $tester.call_subroutine("mysub")
137
- # $tester.call_subroutine("my_other_sub", :offset => -1)
138
- def call_subroutine(name, options = {})
139
- options = {
140
- offset: 0
141
- }.merge(options)
142
- called_subroutines << name.to_s.chomp unless called_subroutines.include?(name.to_s.chomp) || @inhibit_vectors
143
- update_vector microcode: "call #{name}", offset: options[:offset]
144
- end
145
-
146
- # Start a subroutine.
147
- #
148
- # Generates a global subroutine label. Global is used to adhere to the best practice of
149
- # containing all subroutines in dedicated patterns, e.g. global_subs.atp
150
- #
151
- # ==== Examples
152
- # $tester.start_subroutine("wait_for_done")
153
- # < generate your subroutine vectors here >
154
- # $tester.end_subroutine
155
- def start_subroutine(name)
156
- local_subroutines << name.to_s.chomp unless local_subroutines.include?(name.to_s.chomp) || @inhibit_vectors
157
- microcode "global subr #{name}:"
158
- end
159
-
160
- # * J750 Specific *
161
- #
162
- #
163
- def enable_flag(options = {})
164
- options = { flagnum: 4, # which flag to enable for later checking
165
- }.merge(options)
166
-
167
- case options[:flagnum]
168
- when 1
169
- flagname = 'cpuA'
170
- when 2
171
- flagname = 'cpuB'
172
- when 3
173
- flagname = 'cpuC'
174
- when 4
175
- flagname = 'cpuD'
176
- else
177
- abort "ERROR! Invalid flag name passed to 'enable_flag' method!\n"
178
- end
179
- update_vector(microcode: "enable(#{flagname})")
180
- end
181
-
182
- # * J750 Specific *
183
- #
184
- #
185
- def set_flag(options = {})
186
- options = { flagnum: 4, # which flag to set
187
- }.merge(options)
188
-
189
- case options[:flagnum]
190
- when 1
191
- flagname = 'cpuA'
192
- when 2
193
- flagname = 'cpuB'
194
- when 3
195
- flagname = 'cpuC'
196
- when 4
197
- flagname = 'cpuD'
198
- else
199
- abort "ERROR! Invalid flag name passed to 'set_flag' method!\n"
200
- end
201
- update_vector(microcode: "set_cpu(#{flagname})")
202
- end
203
-
204
- # End a subroutine.
205
- #
206
- # Generates a return opcode on the last vector.
207
- #
208
- # ==== Examples
209
- # $tester.start_subroutine("wait_for_done")
210
- # < generate your subroutine vectors here >
211
- # $tester.end_subroutine
212
- # cond: whether return is conditional on a flag (to permit to mix subrs together)
213
- def end_subroutine(cond = false)
214
- if cond
215
- update_vector microcode: 'if (flag) return'
216
- else
217
- update_vector microcode: 'return'
218
- end
219
- end
220
-
221
- # Handshake with the tester.
222
- #
223
- # Will set a cpu flag (A) and wait for it to be cleared by the tester, optionally
224
- # pass in a read code to pass information to the tester.
225
- #
226
- # ==== Examples
227
- # $tester.handshake # Pass control to the tester for a measurement
228
- # $tester.handshake(:readcode => 10) # Trigger a specific action by the tester
229
- def handshake(options = {})
230
- options = {
231
- readcode: false,
232
- manual_stop: false, # set a 2nd CPU flag in case 1st flag is automatically cleared
233
- }.merge(options)
234
- if options[:readcode]
235
- cycle(microcode: "set_code #{options[:readcode]}")
236
- end
237
- if options[:manual_stop]
238
- cycle(microcode: 'enable (cpuB)')
239
- cycle(microcode: 'set_cpu (cpuA cpuB)')
240
- cycle(microcode: "loop_here_#{@unique_counter}: if (flag) jump loop_here_#{@unique_counter}")
241
- else
242
- cycle(microcode: 'set_cpu (cpuA)')
243
- cycle(microcode: "loop_here_#{@unique_counter}: if (cpuA) jump loop_here_#{@unique_counter}")
244
- end
245
- @unique_counter += 1 # Increment so a different label will be applied if another
246
- # handshake is called in the same pattern
247
- end
248
-
249
- # Do a frequency measure.
250
- #
251
- # Write the necessary micro code to do a frequency measure on the given pin,
252
- # optionally supply a read code to pass information to the tester.
253
- #
254
- # ==== Examples
255
- # $tester.freq_count($top.pin(:d_out)) # Freq measure on pin "d_out"
256
- # $tester.freq_count($top.pin(:d_out):readcode => 10)
257
- def freq_count(pin, options = {})
258
- options = { readcode: false
259
- }.merge(options)
260
-
261
- cycle(microcode: "set_code #{options[:readcode]}") if options[:readcode]
262
- cycle(microcode: 'set_cpu (cpuA)')
263
- cycle(microcode: 'set_cpu (cpuA)')
264
- cycle(microcode: 'set_cpu (cpuB)')
265
- cycle(microcode: 'set_cpu (cpuC)')
266
- cycle(microcode: 'freq_loop_1:')
267
- cycle(microcode: 'if (cpuA) jump freq_loop_1')
268
- pin.drive_lo
269
- delay(2000)
270
- pin.dont_care
271
- cycle(microcode: 'freq_loop_2: enable (cpuB)')
272
- cycle(microcode: 'if (flag) jump freq_loop_2')
273
- cycle(microcode: 'enable (cpuC)')
274
- cycle(microcode: 'if (flag) jump freq_loop_1')
275
- end
276
-
277
- # * J750 Specific *
278
- #
279
- # Generates a single MTO opcode line for J750
280
- #
281
- # Codes implemented: xa load_preset, xa inc, ya load_preset, ya inc, stv_m0, stv_m1, stv_c<br>
282
- def memory_test(options = {})
283
- options = {
284
- gen_vector: true, # Default generate vector not just MTO opcode
285
- init_counter_x: false, # initialize counter X
286
- inc_counter_x: false, # increment counter X
287
- init_counter_y: false, # initialize counter X
288
- inc_counter_y: false, # increment counter X
289
- capture_vector: false, # capture vector to memory using all mem types
290
- capture_vector_mem0: false, # capture vector to memory type 0, here for J750 will be stv_m0
291
- capture_vector_mem1: false, # capture vector to memory type 1, here for J750 will be stv_m1
292
- capture_vector_mem2: false, # capture vector to memory type 2, here for J750 will be stv_c
293
- pin: false, # pin on which to drive or expect data, pass pin object here!
294
- pin_data: false, # pin data (:none, :drive, :expect)
295
- }.merge(options)
296
-
297
- mto_opcode = ''
298
-
299
- if options[:init_counter_x]
300
- mto_opcode += ' xa load_preset'
301
- end
302
- if options[:inc_counter_x]
303
- mto_opcode += ' xa inc'
304
- end
305
- if options[:init_counter_y]
306
- mto_opcode += ' ya load_preset'
307
- end
308
- if options[:inc_counter_y]
309
- mto_opcode += ' ya inc'
310
- end
311
- if options[:capture_vector]
312
- mto_opcode += ' stv_m0 stv_m1 stv_c'
313
- end
314
- if options[:capture_vector_mem0]
315
- mto_opcode += ' stv_m0'
316
- end
317
- if options[:capture_vector_mem1]
318
- mto_opcode += ' stv_m1'
319
- end
320
- if options[:capture_vector_mem2]
321
- mto_opcode += ' stv_c'
322
- end
323
-
324
- unless mto_opcode.eql?('')
325
- mto_opcode = '(mto:' + mto_opcode + ')'
326
- end
327
-
328
- if options[:gen_vector]
329
- if options[:pin]
330
- case options[:pin_data]
331
- when :drive
332
- # store current pin state
333
- cur_pin_state = options[:pin].state.to_sym
334
- options[:pin].drive_mem
335
- when :expect
336
- # store current pin state
337
- cur_pin_state = options[:pin].state.to_sym
338
- options[:pin].expect_mem
339
- end
340
- end
341
- cycle(microcode: "#{mto_opcode}")
342
- if options[:pin]
343
- # restore previous pin state
344
- case options[:pin_data]
345
- when :drive
346
- options[:pin].state = cur_pin_state
347
- when :expect
348
- options[:pin].state = cur_pin_state
349
- end
350
- end
351
- else
352
- microcode "#{mto_opcode}"
353
- end
354
- end
355
-
356
- # Generates a match loop on up to two pins.
357
- #
358
- # This method is not really intended to be called directly, rather you should call
359
- # via Tester#wait e.g. $tester.wait(:match => true).
360
- #
361
- # The timeout should be provided in cycles, however when called via the wait method the
362
- # time-based helpers (time_in_us, etc) will be converted to cycles for you.
363
- # The following options are available to tailor the match loop behavior, defaults in
364
- # parenthesis:
365
- # * :pin - The pin object to match on (*required*)
366
- # * :state - The pin state to match on, :low or :high (*required*)
367
- # * :pin2 (nil) - Optionally supply a second pin to match on
368
- # * :state2 (nil) - State for the second pin (required if :pin2 is supplied)
369
- # * :check_for_fails (false) - Flushes the pipeline and handshakes with the tester (passing readcode 100) prior to the match (to allow binout of fails encountered before the match)
370
- # * :force_fail_on_timeout (true) - Force a vector mis-compare if the match loop times out
371
- # * :on_timeout_goto ("") - Optionally supply a label to branch to on timeout, by default will continue from the end of the match loop
372
- # * :on_pin_match_goto ("") - Optionally supply a label to branch to when pin 1 matches, by default will continue from the end of the match loop
373
- # * :on_pin2_match_goto ("") - Optionally supply a label to branch to when pin 2 matches, by default will continue from the end of the match loop
374
- # * :multiple_entries (false) - Supply an integer to generate multiple entries into the match (each with a unique readcode), this can be useful when debugging patterns with multiple matches
375
- # * :force_fail_on_timeout (true) - force pattern to fail if timeout occurs
376
- # * :global_loops (false) - whether match loop loops should use global labels
377
- # * :manual_stop (false) - whether to use extra cpuB flag to resolve IG-XL v.3.50.xx bug where VBT clears cpuA immediately
378
- # at start of PatFlagFunc instead of at end. Use will have to manually clear cpuB to resume this pattern.
379
- # ==== Examples
380
- # $tester.wait(:match => true, :time_in_us => 5000, :pin => $top.pin(:done), :state => :high)
381
- def match(pin, state, timeout, options = {})
382
- options = {
383
- check_for_fails: false,
384
- on_timeout_goto: false,
385
- pin2: false,
386
- state2: false,
387
- on_pin_match_goto: false,
388
- on_pin2_match_goto: false,
389
- multiple_entries: false,
390
- force_fail_on_timeout: true,
391
- global_loops: false,
392
- manual_stop: false,
393
- clr_fail_post_match: false
394
- }.merge(options)
395
-
396
- # Flush the pipeline first and then pass control to the program to bin out any failures
397
- # prior to entering the match loop
398
- if options[:check_for_fails]
399
- if options[:multiple_entries]
400
- @match_entries.times do |i|
401
- microcode "global subr match_done_#{i}:"
402
- cycle(microcode: "set_code #{i + 100}")
403
- cycle(microcode: 'jump call_tester') unless i == @match_entries - 1
404
- end
405
- microcode 'call_tester:'
406
- else
407
- cycle(microcode: 'set_code 100')
408
- end
409
- cc 'Wait for any prior failures to propagate through the pipeline'
410
- cycle(microcode: 'pipe_minus 1')
411
- cc 'Now handshake with the tester to bin out and parts that have failed before they got here'
412
- handshake(manual_stop: options[:manual_stop])
413
- end
414
-
415
- # Now do the main match loop
416
- cc 'Start the match loop'
417
-
418
- # Calculate the loop counts for the 2 loops to appropriately hit the timeout requested
419
- inner_loop_vectors = (@pipeline_depth - 1) + 4 # num vectors in inner loop
420
- if timeout.to_f < @max_repeat_loop * inner_loop_vectors * @min_repeat_loop
421
- # Handle case for smaller timeouts (that would force small outer loop count)
422
- inner_loop_count = (timeout.to_f / (inner_loop_vectors * @min_repeat_loop)).ceil
423
- outer_loop_count = @min_repeat_loop
424
- else
425
- # Handle longer delays
426
- inner_loop_count = @max_repeat_loop
427
- outer_loop_count = (timeout.to_f / (@max_repeat_loop * inner_loop_vectors)).ceil # Will do a minimum of 1 * max_repeat_loop * (pipeline_depth-1)
428
- end
429
-
430
- global_opt = (options[:global_loops]) ? 'global ' : ''
431
- microcode "#{global_opt}match_outer_loop_#{@unique_counter}:"
432
- cycle(microcode: "loopB #{outer_loop_count} ign ifc icc")
433
- microcode "#{global_opt}match_inner_loop_#{@unique_counter}:"
434
- state == :low ? pin.expect_lo : pin.expect_hi
435
- cc "Check if #{pin.name} is #{state == :low ? 'low' : 'high'} yet"
436
- cycle(microcode: "loopA #{inner_loop_count} ign ifc icc")
437
- pin.dont_care
438
- cc ' Wait for the result to propagate through the pipeline'
439
- cycle(microcode: 'pipe_minus 1 ign ifc icc')
440
- cc "Branch if #{pin.name} was #{state == :low ? 'low' : 'high'}"
441
- cycle(microcode: "if (pass) jump #{pin.name}_matched_#{@unique_counter} icc ifc")
442
- cycle(microcode: 'clr_flag (fail) icc')
443
- if options[:pin2]
444
- cc "Check if #{options[:pin2].name} is #{options[:state2] == :low ? 'low' : 'high'} yet"
445
- options[:state2] == :low ? options[:pin2].expect_lo : options[:pin2].expect_hi
446
- state == :low ? pin.expect_hi : pin.expect_lo # Give priority to pin 1, don't match pin 2 on this cycle
447
- # if it is really a pin 1 match
448
- cycle # Read for pin 2 and !pin 1
449
- options[:pin2].dont_care
450
- pin.dont_care
451
- cc 'Again wait for the result to propagate through the pipeline'
452
- cycle(microcode: 'pipe_minus 1 ign ifc icc')
453
- cc "Branch if #{options[:pin2].name} was #{options[:state2] == :low ? 'low' : 'high'}"
454
- cycle(microcode: "if (pass) jump #{options[:pin2].name}_matched_#{@unique_counter} icc ifc")
455
- cycle(microcode: 'clr_flag (fail) icc')
456
- end
457
- cc 'Loop back around if time remaining'
458
- cycle(microcode: "end_loopA match_inner_loop_#{@unique_counter} icc")
459
- cycle(microcode: "end_loopB match_outer_loop_#{@unique_counter} icc")
460
- if options[:force_fail_on_timeout]
461
- cc 'To get here something has gone wrong, strobe again to force a pattern failure'
462
- state == :low ? pin.expect_lo : pin.expect_hi
463
- options[:state2] == :low ? options[:pin2].expect_lo : options[:pin2].expect_hi if options[:pin2]
464
- cycle
465
- pin.dont_care
466
- options[:pin2].dont_care if options[:pin2]
467
- end
468
- if options[:on_timeout_goto]
469
- cycle(microcode: "jump #{options[:on_timeout_goto]} icc")
470
- else
471
- cycle(microcode: "jump match_loop_end_#{@unique_counter} icc")
472
- # cycle(:microcode => 'halt')
473
- end
474
- microcode "#{pin.name}_matched_#{@unique_counter}:"
475
- cycle(microcode: 'pop_loop icc')
476
- unless options[:clr_fail_post_match]
477
- cycle(microcode: 'clr_fail')
478
- end
479
- if options[:on_pin_match_goto]
480
- cycle(microcode: "jump #{options[:on_pin_match_goto]}")
481
- end
482
- if options[:pin2]
483
- microcode "#{options[:pin2].name}_matched_#{@unique_counter}:"
484
- cycle(microcode: 'pop_loop icc')
485
- cycle(microcode: 'clr_fail')
486
- if options[:on_pin2_match_goto]
487
- cycle(microcode: "jump #{options[:on_pin2_match_goto]}")
488
- end
489
- end
490
- microcode "match_loop_end_#{@unique_counter}:"
491
- if options[:clr_fail_post_match]
492
- cycle(microcode: 'clr_fail')
493
- end
494
-
495
- @unique_counter += 1 # Increment so a different label will be applied if another
496
- # handshake is called in the same pattern
497
- end
498
-
499
- # Generates a match loop based on vector condition passed in via block
500
- #
501
- # This method is not really intended to be called directly, rather you should call
502
- # via Tester#wait:
503
- # e.g. $tester.wait(:match => true) do
504
- # reg(:status_reg).bit(:done).read(1)! # vector condition that you want to match
505
- # end
506
- #
507
- # The timeout should be provided in cycles, however when called via the wait method the
508
- # time-based helpers (time_in_us, etc) will be converted to cycles for you.
509
- #
510
- # The following options are available to tailor the match loop behavior, defaults in
511
- # parenthesis:
512
- # * :check_for_fails (false) - Flushes the pipeline and handshakes with the tester (passing readcode 100) prior to the match (to allow binout of fails encountered before the match)
513
- # * :force_fail_on_timeout (true) - Force a vector mis-compare if the match loop times out
514
- # * :on_timeout_goto ("") - Optionally supply a label to branch to on timeout, by default will continue from the end of the match loop
515
- # * :on_block_match_goto ("") - Optionally supply a label to branch to when block condition is met, by default will continue from the end of the match loop
516
- # * :multiple_entries (false) - Supply an integer to generate multiple entries into the match (each with a unique readcode), this can be useful when debugging patterns with multiple matches
517
- # * :force_fail_on_timeout (true) - force pattern to fail if timeout occurs
518
- # * :global_loops (false) - whether match loop loops should use global labels
519
- # * :manual_stop (false) - whether to use extra cpuB flag to resolve IG-XL v.3.50.xx bug where VBT clears cpuA immediately
520
- # at start of PatFlagFunc instead of at end. Use will have to manually clear cpuB to resume this pattern.
521
- # ==== Examples
522
- # $tester.wait(:match => true, :time_in_us => 5000, :pin => $top.pin(:done), :state => :high)
523
- def match_block(timeout, options = {})
524
- options = {
525
- check_for_fails: false,
526
- on_timeout_goto: false,
527
- on_block_match_goto: false,
528
- multiple_entries: false,
529
- force_fail_on_timeout: true,
530
- global_loops: false,
531
- manual_stop: false,
532
- clr_fail_post_match: false
533
- }.merge(options)
534
-
535
- unless block_given?
536
- fail 'ERROR: block not passed to match_block!'
537
- end
538
-
539
- # Flush the pipeline first and then pass control to the program to bin out any failures
540
- # prior to entering the match loop
541
- if options[:check_for_fails]
542
- if options[:multiple_entries]
543
- @match_entries.times do |i|
544
- microcode "global subr match_done_#{i}:"
545
- cycle(microcode: "set_code #{i + 100}")
546
- cycle(microcode: 'jump call_tester') unless i == @match_entries - 1
547
- end
548
- microcode 'call_tester:'
549
- else
550
- cycle(microcode: 'set_code 100')
551
- end
552
- cc 'Wait for any prior failures to propagate through the pipeline'
553
- cycle(microcode: 'pipe_minus 1')
554
- cc 'Now handshake with the tester to bin out and parts that have failed before they got here'
555
- handshake(manual_stop: options[:manual_stop])
556
- end
557
-
558
- # Now do the main match loop
559
- cc 'Start the match loop'
560
-
561
- # Calculate the loop counts for the 2 loops to appropriately hit the timeout requested
562
- inner_loop_vectors = (@pipeline_depth - 1) + 4 # num vectors in inner loop
563
- if timeout.to_f < @max_repeat_loop * inner_loop_vectors * @min_repeat_loop
564
- # Handle case for smaller timeouts (that would force small outer loop count)
565
- inner_loop_count = (timeout.to_f / (inner_loop_vectors * @min_repeat_loop)).ceil
566
- outer_loop_count = @min_repeat_loop
567
- else
568
- # Handle longer delays
569
- inner_loop_count = @max_repeat_loop
570
- outer_loop_count = (timeout.to_f / (@max_repeat_loop * inner_loop_vectors)).ceil # Will do a minimum of 1 * max_repeat_loop * (pipeline_depth-1)
571
- end
572
-
573
- global_opt = (options[:global_loops]) ? 'global ' : ''
574
- microcode "#{global_opt}match_outer_loop_#{@unique_counter}:"
575
- cycle(microcode: "loopB #{outer_loop_count} ign ifc icc")
576
- microcode "#{global_opt}match_inner_loop_#{@unique_counter}:"
577
- cycle(microcode: "loopA #{inner_loop_count} ign ifc icc")
578
- cc 'Check if block condition met'
579
- yield
580
- cc ' Wait for the result to propagate through the pipeline'
581
- cycle(microcode: 'pipe_minus 1 ign ifc icc')
582
- cc 'Branch if block condition met'
583
- cycle(microcode: "if (pass) jump block_matched_#{@unique_counter} icc ifc")
584
- cycle(microcode: 'clr_flag (fail) icc')
585
- cc 'Loop back around if time remaining'
586
- cycle(microcode: "end_loopA match_inner_loop_#{@unique_counter} icc")
587
- cycle(microcode: "end_loopB match_outer_loop_#{@unique_counter} icc")
588
- if options[:force_fail_on_timeout]
589
- cc 'To get here something has gone wrong, check block again to force a pattern failure'
590
- yield
591
- end
592
- if options[:on_timeout_goto]
593
- cycle(microcode: "jump #{options[:on_timeout_goto]} icc")
594
- else
595
- cycle(microcode: "jump match_loop_end_#{@unique_counter} icc")
596
- # cycle(:microcode => 'halt')
597
- end
598
- microcode "block_matched_#{@unique_counter}:"
599
- cycle(microcode: 'pop_loop icc')
600
- unless options[:clr_fail_post_match]
601
- cycle(microcode: 'clr_fail')
602
- end
603
- if options[:on_block_match_goto]
604
- cycle(microcode: "jump #{options[:on_block_match_goto]}")
605
- end
606
- microcode "match_loop_end_#{@unique_counter}:"
607
- if options[:clr_fail_post_match]
608
- cycle(microcode: 'clr_fail')
609
- end
610
-
611
- @unique_counter += 1 # Increment so a different label will be applied if another
612
- # handshake is called in the same pattern
613
- end
614
-
615
- # Call a match loop.
616
- #
617
- # Normally you would put your match loop in a global subs pattern, then you can
618
- # call it via this method. This method automatically syncs match loop naming with
619
- # the match generation flow, no arguments required.
620
- #
621
- # This is a J750 specific API.
622
- #
623
- # ==== Examples
624
- # $tester.cycle
625
- # $tester.call_match # Calls the match loop, or the first entry point if you have multiple
626
- # $tester.cycle
627
- # $tester.call_match # Calls the match loop, or the second entry point if you have multiple
628
- def call_match
629
- @match_counter = @match_counter || 0
630
- call_subroutine("match_done_#{@match_counter}")
631
- @match_counter += 1 unless @match_counter == (@match_entries || 1) - 1
632
- end
633
-
634
- # Apply a label to the pattern.
635
- #
636
- # No additional vector is generated.
637
- # Arguments:
638
- # name : label name
639
- # global : (optional) whether to apply global label, default=false
640
- #
641
- # ==== Examples
642
- # $tester.label("something_significant")
643
- # $tester.label("something_significant",true) # apply global label
644
- def label(name, global = false)
645
- global_opt = (global) ? 'global ' : ''
646
- microcode global_opt + name + ':'
647
- end
648
-
649
- # * J750 Specific *
650
- #
651
- # Set a readcode.
652
- #
653
- # Use the set an explicit readcode for communicating with the tester. This method
654
- # will generate an additional vector.
655
- #
656
- # ==== Examples
657
- # $tester.set_code(55)
658
- def set_code(code)
659
- cycle(microcode: "set_code #{code}")
660
- end
661
-
662
- # Branch execution to the given point.
663
- #
664
- # This generates a new vector with a jump instruction to a given label. This method
665
- # will generate an additional vector.
666
- #
667
- # ==== Examples
668
- # $tester.branch_to("something_significant")
669
- def branch_to(label)
670
- cycle(microcode: "jump #{label}")
671
- end
672
- alias_method :branch, :branch_to
673
-
674
- # Add loop to the pattern.
675
- #
676
- # Pass in a name for the loop and the number of times to execute it, all vectors
677
- # generated by the given block will be captured in the loop.
678
- #
679
- # Optional arguments: global - whether to apply global label (default=false)
680
- # label_first - whether to apply loop label before loop vector or not
681
- #
682
- # ==== Examples
683
- # $tester.loop_vectors("pulse_loop", 3) do # Do this 3 times...
684
- # $tester.cycle
685
- # some_other_method_to_generate_vectors
686
- # end
687
- def loop_vectors(name, number_of_loops, global = false, label_first = false)
688
- if number_of_loops > 1
689
- @loop_counters ||= {}
690
- if @loop_counters[name]
691
- @loop_counters[name] += 1
692
- else
693
- @loop_counters[name] = 0
694
- end
695
- loop_name = @loop_counters[name] == 0 ? name : "#{name}_#{@loop_counters[name]}"
696
- if label_first
697
- global_opt = (global) ? 'global ' : ''
698
- microcode "#{global_opt}#{loop_name}: "
699
- end
700
- cycle(microcode: "loopA #{number_of_loops}")
701
- unless label_first
702
- global_opt = (global) ? 'global ' : ''
703
- cycle(microcode: "#{global_opt}#{loop_name}: ")
704
- end
705
- yield
706
- cycle(microcode: "end_loopA #{loop_name}")
707
- else
708
- yield
709
- end
710
- end
711
- alias_method :loop_vector, :loop_vectors
712
-
713
- # An internal method called by Origen to create the pattern header
714
- def pattern_header(options = {})
715
- options = {
716
- subroutine_pat: false,
717
- group: false, # If true the end pattern is intended to run within a pattern group
718
- high_voltage: false, # Supply a pin name here to declare it as an HV instrument
719
- freq_counter: false, # Supply a pin name here to declare it as a frequency counter
720
- memory_test: false, # If true, define 2-bit MTO DGEN as instrument
721
- }.merge(options)
722
-
723
- called_timesets.each do |timeset|
724
- microcode "import tset #{timeset.name};"
725
- end
726
- unless options[:group] # Withhold imports for pattern groups, is this correct?
727
- called_subroutines.each do |sub_name|
728
- # Don't import any called subroutines that are declared in the current pattern
729
- microcode "import svm_subr #{sub_name};" unless local_subroutines.include?(sub_name)
730
- end
731
- end
732
- # Should implement this more like @instruments.each...
733
- if options[:memory_test]
734
- microcode 'instruments = {'
735
- microcode ' mto:dgen_2bit;'
736
- microcode '}'
737
- end
738
- microcode "svm_only_file = #{options[:subroutine_pat] ? 'yes' : 'no'};"
739
- microcode 'opcode_mode = extended;'
740
- microcode 'compressed = yes;' # if $soc.gzip_patterns
741
- options[:high_voltage] = @use_hv_pin
742
- microcode "pin_setup = {#{options[:high_voltage]} high_voltage;}" if options[:high_voltage]
743
- microcode "pin_setup = {#{options[:freq_counter]} freq_count;}" if options[:freq_counter]
744
- microcode ''
745
-
746
- pin_list = ordered_pins.map do |p|
747
- if Origen.app.pin_pattern_order.include?(p.id)
748
- p.id # specified name overrides pin name
749
- else
750
- p.name
751
- end
752
- end.join(', ')
753
-
754
- microcode "vector ($tset, #{pin_list})"
755
- microcode '{'
756
- unless options[:subroutine_pat]
757
- microcode 'start_label pattern_st:'
758
- end
759
- end
760
-
761
- # An internal method called by Origen to generate the pattern footer
762
- def pattern_footer(options = {})
763
- options = {
764
- subroutine_pat: false,
765
- end_in_ka: false,
766
- end_with_halt: false
767
- }.merge(options)
768
- # cycle(:microcode => "#{$soc.end_of_pattern_label}:") if $soc.end_of_pattern_label
769
- if options[:end_in_ka]
770
- $tester.cycle microcode: 'keep_alive'
771
- else
772
- if options[:end_with_halt]
773
- $tester.cycle microcode: 'halt'
774
- else
775
- $tester.cycle microcode: 'end_module' unless options[:subroutine_pat]
776
- end
777
- end
778
- microcode '}'
779
- end
780
-
781
- # Returns an array of subroutines called while generating the current pattern
782
- def called_subroutines
783
- @called_subroutines ||= []
784
- end
785
-
786
- # Returns an array of subroutines created by the current pattern
787
- def local_subroutines # :nodoc:
788
- @local_subroutines ||= []
789
- end
790
-
791
- # This is an internal method use by Origen which returns a fully formatted vector
792
- # You can override this if you wish to change the output formatting at vector level
793
- def format_vector(vec)
794
- timeset = vec.timeset ? "> #{vec.timeset.name}" : ''
795
- pin_vals = vec.pin_vals ? "#{vec.pin_vals} ;" : ''
796
- if vec.repeat > 1
797
- microcode = "repeat #{vec.repeat}"
798
- else
799
- microcode = vec.microcode ? vec.microcode : ''
800
- end
801
- # if vec.pin_vals && vec.number && vec.cycle_number
802
- # comment = " // Vector #{@pattern_vectors}, Cycle #{@pattern_cycles}"
803
- # else
804
- comment = ''
805
- # end
806
- "#{microcode.ljust(65)}#{timeset.ljust(31)}#{pin_vals}#{comment}"
807
- end
808
-
809
- # Override this to force the formatting to match the v1 J750 model (easier diffs)
810
- def push_microcode(code) # :nodoc:
811
- stage.store(code.ljust(65) + ''.ljust(31))
812
- end
813
- alias_method :microcode, :push_microcode
814
-
815
- # All vectors generated with the supplied block will have all pins set
816
- # to the repeat previous state. Any pins that are changed state within
817
- # the block will still update to the supplied value.
818
- # ==== Example
819
- # # All pins except invoke will be assigned the repeat previous code
820
- # # in the generated vector. On completion of the block they will
821
- # # return to their previous state, except for invoke which will
822
- # # retain the value assigned within the block.
823
- # $tester.repeat_previous do
824
- # $top.pin(:invoke).drive(1)
825
- # $tester.cycle
826
- # end
827
- def repeat_previous
828
- pinmap = Origen.pin_bank.pins
829
- pinmap.each { |_id, pin| pin.repeat_previous = true }
830
- yield
831
- pinmap.each { |_id, pin| pin.repeat_previous = false }
832
- end
833
-
834
- def ignore_fails(*pins)
835
- pins.each(&:suspend)
836
- yield
837
- pins.each(&:resume)
838
- end
839
-
840
- def j750?
841
- true
842
- end
843
- end
844
- end
845
- end