origen 0.2.6 → 0.3.0

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