origen_testers 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/config/application.rb +140 -0
- data/config/commands.rb +73 -0
- data/config/development.rb +12 -0
- data/config/environment.rb +1 -0
- data/config/shared_commands.rb +47 -0
- data/config/users.rb +18 -0
- data/config/version.rb +8 -0
- data/lib/commands/build.rb +69 -0
- data/lib/origen_testers.rb +23 -0
- data/lib/origen_testers/api.rb +258 -0
- data/lib/origen_testers/basic_test_setups.rb +105 -0
- data/lib/origen_testers/callback_handlers.rb +58 -0
- data/lib/origen_testers/generator.rb +279 -0
- data/lib/origen_testers/generator/flow_control_api.rb +611 -0
- data/lib/origen_testers/generator/identity_map.rb +23 -0
- data/lib/origen_testers/generator/placeholder.rb +11 -0
- data/lib/origen_testers/generator/test_numberer.rb +23 -0
- data/lib/origen_testers/igxl_based_tester.rb +12 -0
- data/lib/origen_testers/igxl_based_tester/base.rb +641 -0
- data/lib/origen_testers/igxl_based_tester/base/flow.rb +171 -0
- data/lib/origen_testers/igxl_based_tester/base/flow_line.rb +322 -0
- data/lib/origen_testers/igxl_based_tester/base/generator.rb +217 -0
- data/lib/origen_testers/igxl_based_tester/base/patgroup.rb +109 -0
- data/lib/origen_testers/igxl_based_tester/base/patgroups.rb +38 -0
- data/lib/origen_testers/igxl_based_tester/base/patset.rb +68 -0
- data/lib/origen_testers/igxl_based_tester/base/patset_pattern.rb +56 -0
- data/lib/origen_testers/igxl_based_tester/base/patsets.rb +38 -0
- data/lib/origen_testers/igxl_based_tester/base/patsubr.rb +68 -0
- data/lib/origen_testers/igxl_based_tester/base/patsubr_pattern.rb +56 -0
- data/lib/origen_testers/igxl_based_tester/base/patsubrs.rb +38 -0
- data/lib/origen_testers/igxl_based_tester/base/test_instance.rb +326 -0
- data/lib/origen_testers/igxl_based_tester/base/test_instance_group.rb +58 -0
- data/lib/origen_testers/igxl_based_tester/base/test_instances.rb +179 -0
- data/lib/origen_testers/igxl_based_tester/files.rb +43 -0
- data/lib/origen_testers/igxl_based_tester/j750.rb +248 -0
- data/lib/origen_testers/igxl_based_tester/j750/flow.rb +10 -0
- data/lib/origen_testers/igxl_based_tester/j750/flow_line.rb +19 -0
- data/lib/origen_testers/igxl_based_tester/j750/generator.rb +19 -0
- data/lib/origen_testers/igxl_based_tester/j750/patgroup.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750/patgroups.rb +10 -0
- data/lib/origen_testers/igxl_based_tester/j750/patset.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750/patset_pattern.rb +18 -0
- data/lib/origen_testers/igxl_based_tester/j750/patsets.rb +10 -0
- data/lib/origen_testers/igxl_based_tester/j750/patsubr.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750/patsubr_pattern.rb +18 -0
- data/lib/origen_testers/igxl_based_tester/j750/patsubrs.rb +10 -0
- data/lib/origen_testers/igxl_based_tester/j750/templates/flow.txt.erb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750/templates/instances.txt.erb +16 -0
- data/lib/origen_testers/igxl_based_tester/j750/templates/patgroups.txt.erb +8 -0
- data/lib/origen_testers/igxl_based_tester/j750/templates/patsets.txt.erb +10 -0
- data/lib/origen_testers/igxl_based_tester/j750/templates/patsubrs.txt.erb +10 -0
- data/lib/origen_testers/igxl_based_tester/j750/test_instance.rb +547 -0
- data/lib/origen_testers/igxl_based_tester/j750/test_instance_group.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750/test_instances.rb +10 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt.rb +34 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt/flow.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt/flow_line.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt/generator.rb +19 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt/patgroup.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt/patgroups.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt/patset.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt/patset_pattern.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt/patsets.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt/patsubr.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt/patsubr_pattern.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt/patsubrs.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt/test_instance.rb +515 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt/test_instance_group.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/j750_hpt/test_instances.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/parser.rb +102 -0
- data/lib/origen_testers/igxl_based_tester/parser/ac_spec.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/parser/ac_specs.rb +0 -0
- data/lib/origen_testers/igxl_based_tester/parser/dc_spec.rb +33 -0
- data/lib/origen_testers/igxl_based_tester/parser/dc_specs.rb +48 -0
- data/lib/origen_testers/igxl_based_tester/parser/descriptions.rb +339 -0
- data/lib/origen_testers/igxl_based_tester/parser/flow.rb +109 -0
- data/lib/origen_testers/igxl_based_tester/parser/flow_line.rb +203 -0
- data/lib/origen_testers/igxl_based_tester/parser/flows.rb +21 -0
- data/lib/origen_testers/igxl_based_tester/parser/pattern_set.rb +92 -0
- data/lib/origen_testers/igxl_based_tester/parser/pattern_sets.rb +31 -0
- data/lib/origen_testers/igxl_based_tester/parser/test_instance.rb +341 -0
- data/lib/origen_testers/igxl_based_tester/parser/test_instances.rb +24 -0
- data/lib/origen_testers/igxl_based_tester/parser/timeset.rb +13 -0
- data/lib/origen_testers/igxl_based_tester/parser/timesets.rb +0 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex.rb +477 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/flow.rb +10 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/flow_line.rb +19 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/generator.rb +19 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/patgroup.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/patgroups.rb +10 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/patset.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/patset_pattern.rb +18 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/patsets.rb +10 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/patsubr.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/patsubr_pattern.rb +18 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/patsubrs.rb +10 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/templates/flow.txt.erb +9 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/templates/instances.txt.erb +16 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/templates/patgroups.txt.erb +9 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/templates/patsets.txt.erb +10 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/templates/patsubrs.txt.erb +10 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/test_instance.rb +270 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/test_instance_group.rb +9 -0
- data/lib/origen_testers/igxl_based_tester/ultraflex/test_instances.rb +10 -0
- data/lib/origen_testers/interface.rb +183 -0
- data/lib/origen_testers/parser.rb +22 -0
- data/lib/origen_testers/parser/description_lookup.rb +62 -0
- data/lib/origen_testers/parser/searchable_array.rb +30 -0
- data/lib/origen_testers/parser/searchable_hash.rb +30 -0
- data/lib/origen_testers/pattern_compilers.rb +116 -0
- data/lib/origen_testers/pattern_compilers/assembler.rb +88 -0
- data/lib/origen_testers/pattern_compilers/job.rb +96 -0
- data/lib/origen_testers/pattern_compilers/ultraflex_pattern_compiler.rb +599 -0
- data/lib/origen_testers/program_generators.rb +55 -0
- data/lib/origen_testers/smartest_based_tester.rb +8 -0
- data/lib/origen_testers/smartest_based_tester/base.rb +411 -0
- data/lib/origen_testers/smartest_based_tester/base/flow.rb +188 -0
- data/lib/origen_testers/smartest_based_tester/base/flow_node.rb +476 -0
- data/lib/origen_testers/smartest_based_tester/base/generator.rb +123 -0
- data/lib/origen_testers/smartest_based_tester/base/pattern_compiler.rb +23 -0
- data/lib/origen_testers/smartest_based_tester/base/pattern_master.rb +47 -0
- data/lib/origen_testers/smartest_based_tester/base/test_method.rb +143 -0
- data/lib/origen_testers/smartest_based_tester/base/test_methods.rb +73 -0
- data/lib/origen_testers/smartest_based_tester/base/test_methods/ac_tml.rb +33 -0
- data/lib/origen_testers/smartest_based_tester/base/test_methods/base_tml.rb +38 -0
- data/lib/origen_testers/smartest_based_tester/base/test_methods/custom_tml.rb +19 -0
- data/lib/origen_testers/smartest_based_tester/base/test_methods/dc_tml.rb +147 -0
- data/lib/origen_testers/smartest_based_tester/base/test_methods/limits.rb +43 -0
- data/lib/origen_testers/smartest_based_tester/base/test_suite.rb +166 -0
- data/lib/origen_testers/smartest_based_tester/base/test_suites.rb +58 -0
- data/lib/origen_testers/smartest_based_tester/v93k.rb +8 -0
- data/lib/origen_testers/smartest_based_tester/v93k/builder.rb +89 -0
- data/lib/origen_testers/smartest_based_tester/v93k/builder/flow.rb +169 -0
- data/lib/origen_testers/smartest_based_tester/v93k/builder/pattern_master.rb +54 -0
- data/lib/origen_testers/smartest_based_tester/v93k/flow.rb +10 -0
- data/lib/origen_testers/smartest_based_tester/v93k/flow_node.rb +9 -0
- data/lib/origen_testers/smartest_based_tester/v93k/generator.rb +19 -0
- data/lib/origen_testers/smartest_based_tester/v93k/pattern_compiler.rb +10 -0
- data/lib/origen_testers/smartest_based_tester/v93k/pattern_master.rb +10 -0
- data/lib/origen_testers/smartest_based_tester/v93k/templates/template.aiv.erb +17 -0
- data/lib/origen_testers/smartest_based_tester/v93k/templates/template.flow.erb +201 -0
- data/lib/origen_testers/smartest_based_tester/v93k/templates/template.pmfl.erb +13 -0
- data/lib/origen_testers/smartest_based_tester/v93k/test_method.rb +9 -0
- data/lib/origen_testers/smartest_based_tester/v93k/test_methods.rb +9 -0
- data/lib/origen_testers/smartest_based_tester/v93k/test_suite.rb +9 -0
- data/lib/origen_testers/smartest_based_tester/v93k/test_suites.rb +9 -0
- data/lib/origen_testers/test/basic_interface.rb +17 -0
- data/lib/origen_testers/test/block.rb +21 -0
- data/lib/origen_testers/test/dut.rb +184 -0
- data/lib/origen_testers/test/dut2.rb +76 -0
- data/lib/origen_testers/test/j750_base_interface.rb +119 -0
- data/lib/origen_testers/test/j750_hpt_interface.rb +8 -0
- data/lib/origen_testers/test/j750_interface.rb +8 -0
- data/lib/origen_testers/test/nvm.rb +94 -0
- data/lib/origen_testers/test/ultraflex_interface.rb +110 -0
- data/lib/origen_testers/test/v93k_interface.rb +115 -0
- data/lib/origen_testers/timing.rb +362 -0
- data/lib/origen_testers/vector.rb +203 -0
- data/lib/origen_testers/vector_based_tester.rb +42 -0
- data/lib/origen_testers/vector_generator.rb +623 -0
- data/lib/origen_testers/vector_pipeline.rb +288 -0
- data/pattern/dc_instr.rb +7 -0
- data/pattern/delay.rb +7 -0
- data/pattern/mem_test.rb +8 -0
- data/pattern/multi_vector.rb +117 -0
- data/pattern/multi_vector_plus1.rb +125 -0
- data/pattern/nvm/j750/add_late_pins.rb +3 -0
- data/pattern/nvm/j750/iterator_postfix_test_x_bx.rb +8 -0
- data/pattern/nvm/j750/iterator_test_x_bx.rb +8 -0
- data/pattern/nvm/j750/j750_halt.rb +159 -0
- data/pattern/nvm/j750/j750_workout.rb +202 -0
- data/pattern/nvm/j750/timing.rb +73 -0
- data/pattern/nvm/v93k/v93k_workout.rb +136 -0
- data/pattern/read_write_reg.rb +58 -0
- data/pattern/reset.rb +4 -0
- data/pattern/subroutines.rb +38 -0
- data/program/_additional_erase.rb +7 -0
- data/program/_efa_resources.rb +7 -0
- data/program/_erase.rb +25 -0
- data/program/_erase_vfy.rb +5 -0
- data/program/_iv_resources.rb +10 -0
- data/program/basic_interface.rb +5 -0
- data/program/components/_prb2_main.rb +6 -0
- data/program/flow_control.rb +164 -0
- data/program/prb1.rb +226 -0
- data/program/prb1_resources.rb +28 -0
- data/program/prb2.rb +40 -0
- data/program/test.rb +20 -0
- data/templates/example.txt.erb +53 -0
- data/templates/j750/_vt_flow.txt.erb +8 -0
- data/templates/j750/_vt_instances.txt.erb +4 -0
- data/templates/j750/program_sheet.txt.erb +9 -0
- data/templates/manifest/v93k.yaml.erb +22 -0
- data/templates/web/index.md.erb +51 -0
- data/templates/web/layouts/_basic.html.erb +15 -0
- data/templates/web/partials/_navbar.html.erb +22 -0
- data/templates/web/release_notes.md.erb +5 -0
- metadata +332 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module OrigenTesters
|
|
2
|
+
module Generator
|
|
3
|
+
class IdentityMap
|
|
4
|
+
def initialize
|
|
5
|
+
@store = {}
|
|
6
|
+
@versions = {}
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def current_version_of(obj)
|
|
10
|
+
map = map_for(obj)
|
|
11
|
+
if map
|
|
12
|
+
map[:replaced_by] || map[:instance]
|
|
13
|
+
else
|
|
14
|
+
obj
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def map_for(obj)
|
|
19
|
+
@store[obj.object_id]
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module OrigenTesters
|
|
2
|
+
module Generator
|
|
3
|
+
class TestNumberer
|
|
4
|
+
# Will return a test number for the given test.
|
|
5
|
+
#
|
|
6
|
+
# @param [Hash] options Options to customize the number generation
|
|
7
|
+
# @option options [Integer] :bits (6) The number of bits in the DAC code
|
|
8
|
+
# @option options [Float] :range (1.26) The range parameter, see code formula
|
|
9
|
+
# @option options [Integer] :offset (0) The o
|
|
10
|
+
def test_number_for(test_name, options = {})
|
|
11
|
+
options = {
|
|
12
|
+
|
|
13
|
+
}.merge(options)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
def store_file
|
|
19
|
+
@store_file ||= Pathname.new "#{Origen.root}/.test_program/test_numbers"
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module OrigenTesters
|
|
2
|
+
module IGXLBasedTester
|
|
3
|
+
autoload :Base, 'origen_testers/igxl_based_tester/base.rb'
|
|
4
|
+
autoload :J750, 'origen_testers/igxl_based_tester/j750.rb'
|
|
5
|
+
autoload :J750_HPT, 'origen_testers/igxl_based_tester/j750_hpt.rb'
|
|
6
|
+
autoload :UltraFLEX, 'origen_testers/igxl_based_tester/ultraflex.rb'
|
|
7
|
+
end
|
|
8
|
+
# Convenience/Legacy names without the IGXLBasedTester namespace
|
|
9
|
+
autoload :J750, 'origen_testers/igxl_based_tester/j750.rb'
|
|
10
|
+
autoload :J750_HPT, 'origen_testers/igxl_based_tester/j750_hpt.rb'
|
|
11
|
+
autoload :UltraFLEX, 'origen_testers/igxl_based_tester/ultraflex.rb'
|
|
12
|
+
end
|
|
@@ -0,0 +1,641 @@
|
|
|
1
|
+
module OrigenTesters
|
|
2
|
+
module IGXLBasedTester
|
|
3
|
+
# This is the base class of all IGXL-based testers
|
|
4
|
+
class Base
|
|
5
|
+
include VectorBasedTester
|
|
6
|
+
|
|
7
|
+
attr_accessor :software_version
|
|
8
|
+
attr_accessor :pattern_compiler_pinmap
|
|
9
|
+
attr_accessor :memory_test_en
|
|
10
|
+
|
|
11
|
+
# NOTE: DO NOT USE THIS CLASS DIRECTLY ONLY USED AS PARENT FOR
|
|
12
|
+
# DESIRED TESTER CLASS
|
|
13
|
+
|
|
14
|
+
# Returns a new IGXLBasedTester instance, normally there would only ever be one of these
|
|
15
|
+
# assigned to the global variable such as $tester by your target.
|
|
16
|
+
def initialize
|
|
17
|
+
@unique_counter = 0
|
|
18
|
+
@counter_lsb_bits = 0
|
|
19
|
+
@counter_msb_bits = 0
|
|
20
|
+
@max_repeat_loop = 65_535 # 16 bits
|
|
21
|
+
@min_repeat_loop = 2
|
|
22
|
+
@pat_extension = 'atp'
|
|
23
|
+
@active_loads = true
|
|
24
|
+
@pipeline_depth = 34
|
|
25
|
+
@software_version = ''
|
|
26
|
+
@compress = true
|
|
27
|
+
@support_repeat_previous = true
|
|
28
|
+
@match_entries = 10
|
|
29
|
+
@name = ''
|
|
30
|
+
@program_comment_char = ['logprint', "'"]
|
|
31
|
+
@opcode_mode = :extended
|
|
32
|
+
@flags = %w(cpuA cpuB cpuC cpuD)
|
|
33
|
+
@microcode = {}
|
|
34
|
+
@microcode[:enable] = 'enable'
|
|
35
|
+
@microcode[:set_flag] = 'set_cpu'
|
|
36
|
+
@microcode[:mask_vector] = 'ign ifc icc'
|
|
37
|
+
|
|
38
|
+
@mask_vector = false # sticky option to mask all subsequent vectors
|
|
39
|
+
|
|
40
|
+
@min_pattern_vectors = 0 # no minimum
|
|
41
|
+
|
|
42
|
+
@memory_test_en = false # memory test enabled (for all patterns?)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def assign_dc_instr_pins(dc_pins)
|
|
46
|
+
@dc_pins = dc_pins
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def get_dc_instr_pins
|
|
50
|
+
@dc_pins
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def flows
|
|
54
|
+
parser.flows
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Main accessor to all content parsed from existing test program sheets found in the
|
|
58
|
+
# supplied directory or in Origen.config.test_program_output_directory
|
|
59
|
+
def parser(prog_dir = Origen.config.test_program_output_directory)
|
|
60
|
+
unless prog_dir
|
|
61
|
+
fail 'You must supply the directory containing the test program sheets, or define it via Origen.config.test_program_output_directory'
|
|
62
|
+
end
|
|
63
|
+
@parser ||= IGXLBasedTester::Parser.new
|
|
64
|
+
@parsed_dir ||= false
|
|
65
|
+
if @parsed_dir != prog_dir
|
|
66
|
+
@parser.parse(prog_dir)
|
|
67
|
+
@parsed_dir = prog_dir
|
|
68
|
+
end
|
|
69
|
+
@parser
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Capture a vector to the tester HRAM.
|
|
73
|
+
#
|
|
74
|
+
# This method applies a store vector (stv) opcode to the previous vector, note that is does
|
|
75
|
+
# not actually generate a new vector.
|
|
76
|
+
#
|
|
77
|
+
# Sometimes when generating vectors within a loop you may want to apply a stv opcode
|
|
78
|
+
# retrospectively to a previous vector, passing in an offset option will allow you
|
|
79
|
+
# to do this.
|
|
80
|
+
#
|
|
81
|
+
# On J750 the pins argument is ignored since the tester only supports whole vector capture.
|
|
82
|
+
#
|
|
83
|
+
# @example
|
|
84
|
+
# $tester.cycle # This is the vector you want to capture
|
|
85
|
+
# $tester.store # This applies the STV opcode
|
|
86
|
+
#
|
|
87
|
+
# $tester.cycle # This one gets stored
|
|
88
|
+
# $tester.cycle
|
|
89
|
+
# $tester.cycle
|
|
90
|
+
# $tester.store(:offset => -2) # Just realized I need to capture that earlier vector
|
|
91
|
+
def store(*pins)
|
|
92
|
+
options = pins.last.is_a?(Hash) ? pins.pop : {}
|
|
93
|
+
options = { offset: 0
|
|
94
|
+
}.merge(options)
|
|
95
|
+
update_vector microcode: 'stv', offset: options[:offset]
|
|
96
|
+
end
|
|
97
|
+
alias_method :to_hram, :store
|
|
98
|
+
alias_method :capture, :store
|
|
99
|
+
|
|
100
|
+
# Capture the next vector generated to HRAM
|
|
101
|
+
#
|
|
102
|
+
# This method applies a store vector (stv) opcode to the next vector to be generated,
|
|
103
|
+
# note that is does not actually generate a new vector.
|
|
104
|
+
#
|
|
105
|
+
# On J750 the pins argument is ignored since the tester only supports whole vector capture.
|
|
106
|
+
#
|
|
107
|
+
# @example
|
|
108
|
+
# $tester.store_next_cycle
|
|
109
|
+
# $tester.cycle # This is the vector that will be captured
|
|
110
|
+
def store_next_cycle(*pins)
|
|
111
|
+
options = pins.last.is_a?(Hash) ? pins.pop : {}
|
|
112
|
+
options = {
|
|
113
|
+
}.merge(options)
|
|
114
|
+
preset_next_vector microcode: 'stv'
|
|
115
|
+
end
|
|
116
|
+
alias_method :store!, :store_next_cycle
|
|
117
|
+
|
|
118
|
+
# Call a subroutine.
|
|
119
|
+
#
|
|
120
|
+
# This method applies a call subroutine opcode to the previous vector, it does not
|
|
121
|
+
# generate a new vector.
|
|
122
|
+
#
|
|
123
|
+
# Subroutines should always be called through this method as it ensures a running
|
|
124
|
+
# log of called subroutines is maintained and which then gets output in the pattern
|
|
125
|
+
# header to import the right dependencies.
|
|
126
|
+
#
|
|
127
|
+
# An offset option is available to make the call on earlier vectors.
|
|
128
|
+
#
|
|
129
|
+
# ==== Examples
|
|
130
|
+
# $tester.call_subroutine("mysub")
|
|
131
|
+
# $tester.call_subroutine("my_other_sub", :offset => -1)
|
|
132
|
+
def call_subroutine(name, options = {})
|
|
133
|
+
options = {
|
|
134
|
+
offset: 0
|
|
135
|
+
}.merge(options)
|
|
136
|
+
called_subroutines << name.to_s.chomp unless called_subroutines.include?(name.to_s.chomp) || @inhibit_vectors
|
|
137
|
+
update_vector microcode: "call #{name}", offset: options[:offset]
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# Start a subroutine.
|
|
141
|
+
#
|
|
142
|
+
# Generates a global subroutine label. Global is used to adhere to the best practice of
|
|
143
|
+
# containing all subroutines in dedicated patterns, e.g. global_subs.atp
|
|
144
|
+
#
|
|
145
|
+
# ==== Examples
|
|
146
|
+
# $tester.start_subroutine("wait_for_done")
|
|
147
|
+
# < generate your subroutine vectors here >
|
|
148
|
+
# $tester.end_subroutine
|
|
149
|
+
def start_subroutine(name)
|
|
150
|
+
local_subroutines << name.to_s.chomp unless local_subroutines.include?(name.to_s.chomp) || @inhibit_vectors
|
|
151
|
+
microcode "global subr #{name}:"
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# End a subroutine.
|
|
155
|
+
#
|
|
156
|
+
# Generates a return opcode on the last vector.
|
|
157
|
+
#
|
|
158
|
+
# ==== Examples
|
|
159
|
+
# $tester.start_subroutine("wait_for_done")
|
|
160
|
+
# < generate your subroutine vectors here >
|
|
161
|
+
# $tester.end_subroutine
|
|
162
|
+
# cond: whether return is conditional on a flag (to permit to mix subrs together)
|
|
163
|
+
def end_subroutine(cond = false)
|
|
164
|
+
if cond
|
|
165
|
+
update_vector microcode: 'if (flag) return'
|
|
166
|
+
else
|
|
167
|
+
update_vector microcode: 'return'
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# Do a frequency measure.
|
|
172
|
+
#
|
|
173
|
+
# Write the necessary micro code to do a frequency measure on the given pin,
|
|
174
|
+
# optionally supply a read code to pass information to the tester.
|
|
175
|
+
#
|
|
176
|
+
# ==== Examples
|
|
177
|
+
# $tester.freq_count($top.pin(:d_out)) # Freq measure on pin "d_out"
|
|
178
|
+
# $tester.freq_count($top.pin(:d_out):readcode => 10)
|
|
179
|
+
def freq_count(pin, options = {})
|
|
180
|
+
options = { readcode: false
|
|
181
|
+
}.merge(options)
|
|
182
|
+
|
|
183
|
+
set_code(options[:readcode]) if options[:readcode]
|
|
184
|
+
cycle(microcode: "#{@microcode[:set_flag]} (cpuA)")
|
|
185
|
+
cycle(microcode: "#{@microcode[:set_flag]} (cpuA)")
|
|
186
|
+
cycle(microcode: "#{@microcode[:set_flag]} (cpuB)")
|
|
187
|
+
cycle(microcode: "#{@microcode[:set_flag]} (cpuC)")
|
|
188
|
+
cycle(microcode: 'freq_loop_1:')
|
|
189
|
+
cycle(microcode: 'if (cpuA) jump freq_loop_1')
|
|
190
|
+
pin.drive_lo
|
|
191
|
+
delay(2000)
|
|
192
|
+
pin.dont_care
|
|
193
|
+
cycle(microcode: "freq_loop_2: #{@microcode[:enable]} (#{@flags[1]})")
|
|
194
|
+
cycle(microcode: 'if (flag) jump freq_loop_2')
|
|
195
|
+
cycle(microcode: "#{@microcode[:enable]} (#{@flags[2]})")
|
|
196
|
+
cycle(microcode: 'if (flag) jump freq_loop_1')
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
# * J750 Specific *
|
|
200
|
+
#
|
|
201
|
+
# Generates a single MTO opcode line for J750
|
|
202
|
+
#
|
|
203
|
+
# Codes implemented: xa load_preset, xa inc, ya load_preset, ya inc, stv_m0, stv_m1, stv_c<br>
|
|
204
|
+
def memory_test(options = {})
|
|
205
|
+
options = {
|
|
206
|
+
gen_vector: true, # Default generate vector not just MTO opcode
|
|
207
|
+
init_counter_x: false, # initialize counter X
|
|
208
|
+
inc_counter_x: false, # increment counter X
|
|
209
|
+
init_counter_y: false, # initialize counter X
|
|
210
|
+
inc_counter_y: false, # increment counter X
|
|
211
|
+
capture_vector: false, # capture vector to memory using all mem types
|
|
212
|
+
capture_vector_mem0: false, # capture vector to memory type 0, here for J750 will be stv_m0
|
|
213
|
+
capture_vector_mem1: false, # capture vector to memory type 1, here for J750 will be stv_m1
|
|
214
|
+
capture_vector_mem2: false, # capture vector to memory type 2, here for J750 will be stv_c
|
|
215
|
+
pin: false, # pin on which to drive or expect data, pass pin object here!
|
|
216
|
+
pin_data: false, # pin data (:none, :drive, :expect)
|
|
217
|
+
}.merge(options)
|
|
218
|
+
|
|
219
|
+
mto_opcode = ''
|
|
220
|
+
|
|
221
|
+
if options[:init_counter_x]
|
|
222
|
+
mto_opcode += ' xa load_preset'
|
|
223
|
+
end
|
|
224
|
+
if options[:inc_counter_x]
|
|
225
|
+
mto_opcode += ' xa inc'
|
|
226
|
+
end
|
|
227
|
+
if options[:init_counter_y]
|
|
228
|
+
mto_opcode += ' ya load_preset'
|
|
229
|
+
end
|
|
230
|
+
if options[:inc_counter_y]
|
|
231
|
+
mto_opcode += ' ya inc'
|
|
232
|
+
end
|
|
233
|
+
if options[:capture_vector]
|
|
234
|
+
mto_opcode += ' stv_m0 stv_m1 stv_c'
|
|
235
|
+
end
|
|
236
|
+
if options[:capture_vector_mem0]
|
|
237
|
+
mto_opcode += ' stv_m0'
|
|
238
|
+
end
|
|
239
|
+
if options[:capture_vector_mem1]
|
|
240
|
+
mto_opcode += ' stv_m1'
|
|
241
|
+
end
|
|
242
|
+
if options[:capture_vector_mem2]
|
|
243
|
+
mto_opcode += ' stv_c'
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
unless mto_opcode.eql?('')
|
|
247
|
+
mto_opcode = '(mto:' + mto_opcode + ')'
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
if options[:gen_vector]
|
|
251
|
+
if options[:pin]
|
|
252
|
+
case options[:pin_data]
|
|
253
|
+
when :drive
|
|
254
|
+
# store current pin state
|
|
255
|
+
cur_pin_state = options[:pin].state.to_sym
|
|
256
|
+
options[:pin].drive_mem
|
|
257
|
+
when :expect
|
|
258
|
+
# store current pin state
|
|
259
|
+
cur_pin_state = options[:pin].state.to_sym
|
|
260
|
+
options[:pin].expect_mem
|
|
261
|
+
end
|
|
262
|
+
end
|
|
263
|
+
cycle(microcode: "#{mto_opcode}")
|
|
264
|
+
if options[:pin]
|
|
265
|
+
# restore previous pin state
|
|
266
|
+
case options[:pin_data]
|
|
267
|
+
when :drive
|
|
268
|
+
options[:pin].state = cur_pin_state
|
|
269
|
+
when :expect
|
|
270
|
+
options[:pin].state = cur_pin_state
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
else
|
|
274
|
+
microcode "#{mto_opcode}"
|
|
275
|
+
end
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
# Generates a match loop on up to two pins.
|
|
279
|
+
#
|
|
280
|
+
# This method is not really intended to be called directly, rather you should call
|
|
281
|
+
# via Tester#wait e.g. $tester.wait(:match => true).
|
|
282
|
+
#
|
|
283
|
+
# The timeout should be provided in cycles, however when called via the wait method the
|
|
284
|
+
# time-based helpers (time_in_us, etc) will be converted to cycles for you.
|
|
285
|
+
# The following options are available to tailor the match loop behavior, defaults in
|
|
286
|
+
# parenthesis:
|
|
287
|
+
# * :pin - The pin object to match on (*required*)
|
|
288
|
+
# * :state - The pin state to match on, :low or :high (*required*)
|
|
289
|
+
# * :pin2 (nil) - Optionally supply a second pin to match on
|
|
290
|
+
# * :state2 (nil) - State for the second pin (required if :pin2 is supplied)
|
|
291
|
+
# * :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)
|
|
292
|
+
# * :force_fail_on_timeout (true) - Force a vector mis-compare if the match loop times out
|
|
293
|
+
# * :on_timeout_goto ("") - Optionally supply a label to branch to on timeout, by default will continue from the end of the match loop
|
|
294
|
+
# * :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
|
|
295
|
+
# * :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
|
|
296
|
+
# * :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
|
|
297
|
+
# * :force_fail_on_timeout (true) - force pattern to fail if timeout occurs
|
|
298
|
+
# * :global_loops (false) - whether match loop loops should use global labels
|
|
299
|
+
# * :manual_stop (false) - whether to use extra cpuB flag to resolve IG-XL v.3.50.xx bug where VBT clears cpuA immediately
|
|
300
|
+
# at start of PatFlagFunc instead of at end. Use will have to manually clear cpuB to resume this pattern.
|
|
301
|
+
# ==== Examples
|
|
302
|
+
# $tester.wait(:match => true, :time_in_us => 5000, :pin => $top.pin(:done), :state => :high)
|
|
303
|
+
def match(pin, state, timeout, options = {})
|
|
304
|
+
options = {
|
|
305
|
+
check_for_fails: false,
|
|
306
|
+
on_timeout_goto: false,
|
|
307
|
+
pin2: false,
|
|
308
|
+
state2: false,
|
|
309
|
+
on_pin_match_goto: false,
|
|
310
|
+
multiple_entries: false,
|
|
311
|
+
force_fail_on_timeout: true,
|
|
312
|
+
global_loops: false,
|
|
313
|
+
manual_stop: false,
|
|
314
|
+
clr_fail_post_match: false
|
|
315
|
+
}.merge(options)
|
|
316
|
+
|
|
317
|
+
match_block(timeout, options) do |match_conditions, fail_conditions|
|
|
318
|
+
# Define match conditions
|
|
319
|
+
match_conditions.add do
|
|
320
|
+
state == :low ? pin.expect_lo : pin.expect_hi
|
|
321
|
+
cc "Check if #{pin.name} is #{state == :low ? 'low' : 'high'}"
|
|
322
|
+
cycle
|
|
323
|
+
pin.dont_care
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
if options[:pin2]
|
|
327
|
+
match_conditions.add do
|
|
328
|
+
state == :low ? pin.expect_hi : pin.expect_lo
|
|
329
|
+
options[:state2] == :low ? options[:pin2].expect_lo : options[:pin2].expect_hi
|
|
330
|
+
cc "Check if #{options[:pin2].name} is #{options[:state2] == :low ? 'low' : 'high'}"
|
|
331
|
+
cycle
|
|
332
|
+
options[:pin2].dont_care
|
|
333
|
+
pin.dont_care
|
|
334
|
+
end
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
# Define fail conditions
|
|
338
|
+
fail_conditions.add do
|
|
339
|
+
state == :low ? pin.expect_lo : pin.expect_hi
|
|
340
|
+
cc "Check if #{pin.name} is #{state == :low ? 'low' : 'high'}"
|
|
341
|
+
if options[:pin2]
|
|
342
|
+
options[:state2] == :low ? options[:pin2].expect_lo : options[:pin2].expect_hi
|
|
343
|
+
cc "Check if #{options[:pin2].name} is #{options[:state2] == :low ? 'low' : 'high'}"
|
|
344
|
+
end
|
|
345
|
+
cycle
|
|
346
|
+
pin.dont_care
|
|
347
|
+
options[:pin2].dont_care if options[:pin2]
|
|
348
|
+
end
|
|
349
|
+
end
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
# Call a match loop.
|
|
353
|
+
#
|
|
354
|
+
# Normally you would put your match loop in a global subs pattern, then you can
|
|
355
|
+
# call it via this method. This method automatically syncs match loop naming with
|
|
356
|
+
# the match generation flow, no arguments required.
|
|
357
|
+
#
|
|
358
|
+
# This is an IGXLBasedTester specific API.
|
|
359
|
+
#
|
|
360
|
+
# ==== Examples
|
|
361
|
+
# $tester.cycle
|
|
362
|
+
# $tester.call_match # Calls the match loop, or the first entry point if you have multiple
|
|
363
|
+
# $tester.cycle
|
|
364
|
+
# $tester.call_match # Calls the match loop, or the second entry point if you have multiple
|
|
365
|
+
def call_match
|
|
366
|
+
@match_counter = @match_counter || 0
|
|
367
|
+
call_subroutine("match_done_#{@match_counter}")
|
|
368
|
+
@match_counter += 1 unless @match_counter == (@match_entries || 1) - 1
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
# Apply a label to the pattern.
|
|
372
|
+
#
|
|
373
|
+
# No additional vector is generated.
|
|
374
|
+
# Arguments:
|
|
375
|
+
# name : label name
|
|
376
|
+
# global : (optional) whether to apply global label, default=false
|
|
377
|
+
#
|
|
378
|
+
# ==== Examples
|
|
379
|
+
# $tester.label("something_significant")
|
|
380
|
+
# $tester.label("something_significant",true) # apply global label
|
|
381
|
+
def label(name, global = false)
|
|
382
|
+
global_opt = (global) ? 'global ' : ''
|
|
383
|
+
microcode global_opt + name + ':'
|
|
384
|
+
end
|
|
385
|
+
|
|
386
|
+
# * J750 Specific *
|
|
387
|
+
#
|
|
388
|
+
# Set a readcode.
|
|
389
|
+
#
|
|
390
|
+
# Use the set an explicit readcode for communicating with the tester. This method
|
|
391
|
+
# will generate an additional vector.
|
|
392
|
+
#
|
|
393
|
+
# ==== Examples
|
|
394
|
+
# $tester.set_code(55)
|
|
395
|
+
def set_code(code)
|
|
396
|
+
cycle(microcode: "set_code #{code}")
|
|
397
|
+
end
|
|
398
|
+
|
|
399
|
+
# Branch execution to the given point.
|
|
400
|
+
#
|
|
401
|
+
# This generates a new vector with a jump instruction to a given label. This method
|
|
402
|
+
# will generate an additional vector.
|
|
403
|
+
#
|
|
404
|
+
# ==== Examples
|
|
405
|
+
# $tester.branch_to("something_significant")
|
|
406
|
+
def branch_to(label)
|
|
407
|
+
cycle(microcode: "jump #{label}")
|
|
408
|
+
end
|
|
409
|
+
alias_method :branch, :branch_to
|
|
410
|
+
|
|
411
|
+
# Add loop to the pattern.
|
|
412
|
+
#
|
|
413
|
+
# Pass in a name for the loop and the number of times to execute it, all vectors
|
|
414
|
+
# generated by the given block will be captured in the loop.
|
|
415
|
+
#
|
|
416
|
+
# Optional arguments: global - whether to apply global label (default=false)
|
|
417
|
+
# label_first - whether to apply loop label before loop vector or not
|
|
418
|
+
#
|
|
419
|
+
# ==== Examples
|
|
420
|
+
# $tester.loop_vectors("pulse_loop", 3) do # Do this 3 times...
|
|
421
|
+
# $tester.cycle
|
|
422
|
+
# some_other_method_to_generate_vectors
|
|
423
|
+
# end
|
|
424
|
+
def loop_vectors(name, number_of_loops, global = false, label_first = false)
|
|
425
|
+
if number_of_loops > 1
|
|
426
|
+
@loop_counters ||= {}
|
|
427
|
+
if @loop_counters[name]
|
|
428
|
+
@loop_counters[name] += 1
|
|
429
|
+
else
|
|
430
|
+
@loop_counters[name] = 0
|
|
431
|
+
end
|
|
432
|
+
loop_name = @loop_counters[name] == 0 ? name : "#{name}_#{@loop_counters[name]}"
|
|
433
|
+
if label_first
|
|
434
|
+
global_opt = (global) ? 'global ' : ''
|
|
435
|
+
microcode "#{global_opt}#{loop_name}: "
|
|
436
|
+
end
|
|
437
|
+
cycle(microcode: "loopA #{number_of_loops}")
|
|
438
|
+
unless label_first
|
|
439
|
+
global_opt = (global) ? 'global ' : ''
|
|
440
|
+
cycle(microcode: "#{global_opt}#{loop_name}: ")
|
|
441
|
+
end
|
|
442
|
+
yield
|
|
443
|
+
cycle(microcode: "end_loopA #{loop_name}")
|
|
444
|
+
else
|
|
445
|
+
yield
|
|
446
|
+
end
|
|
447
|
+
end
|
|
448
|
+
alias_method :loop_vector, :loop_vectors
|
|
449
|
+
|
|
450
|
+
# An internal method called by Origen Pattern Create to create the pattern header
|
|
451
|
+
def pattern_header(options = {})
|
|
452
|
+
options = {
|
|
453
|
+
instruments: {}, # Provide instruments here if desired as a hash (e.g. "mto" => "dgen_2bit")
|
|
454
|
+
subroutine_pat: false,
|
|
455
|
+
svm_only: true, # Whether 'svm_only' can be specified
|
|
456
|
+
group: false, # If true the end pattern is intended to run within a pattern group
|
|
457
|
+
high_voltage: false, # Supply a pin name here to declare it as an HV instrument (not yet defined)
|
|
458
|
+
freq_counter: false, # Supply a pin name here to declare it as a frequency counter
|
|
459
|
+
memory_test: false, # If true, define 2-bit MTO DGEN as instrument
|
|
460
|
+
}.merge(options)
|
|
461
|
+
|
|
462
|
+
if level_period?
|
|
463
|
+
microcode "import tset #{min_period_timeset.name};"
|
|
464
|
+
else
|
|
465
|
+
called_timesets.each do |timeset|
|
|
466
|
+
microcode "import tset #{timeset.name};"
|
|
467
|
+
end
|
|
468
|
+
end
|
|
469
|
+
unless options[:group] # Withhold imports for pattern groups, is this correct?
|
|
470
|
+
called_subroutines.each do |sub_name|
|
|
471
|
+
# Don't import any called subroutines that are declared in the current pattern
|
|
472
|
+
microcode "import svm_subr #{sub_name};" unless local_subroutines.include?(sub_name)
|
|
473
|
+
end
|
|
474
|
+
end
|
|
475
|
+
|
|
476
|
+
# If memory test, then add to instruments hash
|
|
477
|
+
if options[:memory_test]
|
|
478
|
+
options[:instruments].merge!('mto' => 'dgen_2bit')
|
|
479
|
+
end
|
|
480
|
+
|
|
481
|
+
if options[:svm_only]
|
|
482
|
+
microcode "svm_only_file = #{options[:subroutine_pat] ? 'yes' : 'no'};"
|
|
483
|
+
end
|
|
484
|
+
|
|
485
|
+
microcode "opcode_mode = #{@opcode_mode};"
|
|
486
|
+
microcode "digital_inst = #{options[:digital_inst]};" if options[:digital_inst]
|
|
487
|
+
microcode 'compressed = yes;' # if $dut.gzip_patterns
|
|
488
|
+
|
|
489
|
+
# Take care of any instruments
|
|
490
|
+
if options[:instruments].length > 0
|
|
491
|
+
microcode 'instruments = {'
|
|
492
|
+
options[:instruments].each do |instrument, setting|
|
|
493
|
+
if "#{setting}" == 'nil'
|
|
494
|
+
microcode " #{instrument};"
|
|
495
|
+
else
|
|
496
|
+
microcode " #{instrument}:#{setting};"
|
|
497
|
+
end
|
|
498
|
+
end
|
|
499
|
+
microcode '}'
|
|
500
|
+
end
|
|
501
|
+
|
|
502
|
+
options[:high_voltage] = @use_hv_pin
|
|
503
|
+
microcode "pin_setup = {#{options[:high_voltage]} high_voltage;}" if options[:high_voltage]
|
|
504
|
+
microcode "pin_setup = {#{options[:freq_counter]} freq_count;}" if options[:freq_counter]
|
|
505
|
+
microcode ''
|
|
506
|
+
|
|
507
|
+
pin_list = ordered_pins.map(&:name).join(', ')
|
|
508
|
+
|
|
509
|
+
# here indicate pattern header specific stuff
|
|
510
|
+
yield pin_list
|
|
511
|
+
max_pin_name_length = ordered_pins.map(&:name).max { |a, b| a.length <=> b.length }.length
|
|
512
|
+
pin_widths = ordered_pins.map { |p| p.size - 1 }
|
|
513
|
+
|
|
514
|
+
max_pin_name_length.times do |i|
|
|
515
|
+
cc((' ' * 93) + ordered_pins.map.with_index { |p, x| ((p.name[i] || ' ') + ' ' * pin_widths[x]).gsub('_', '-') }.join(' '))
|
|
516
|
+
end
|
|
517
|
+
end
|
|
518
|
+
|
|
519
|
+
# An internal method called by Origen to generate the pattern footer
|
|
520
|
+
def pattern_footer(options = {})
|
|
521
|
+
options = {
|
|
522
|
+
subroutine_pat: false,
|
|
523
|
+
end_in_ka: false,
|
|
524
|
+
end_with_halt: false,
|
|
525
|
+
end_module: true
|
|
526
|
+
}.merge(options)
|
|
527
|
+
$tester.align_to_last
|
|
528
|
+
# cycle(:microcode => "#{$dut.end_of_pattern_label}:") if $dut.end_of_pattern_label
|
|
529
|
+
if options[:end_in_ka]
|
|
530
|
+
$tester.cycle microcode: 'keep_alive'
|
|
531
|
+
else
|
|
532
|
+
if options[:end_with_halt]
|
|
533
|
+
$tester.cycle microcode: 'halt'
|
|
534
|
+
else
|
|
535
|
+
if options[:end_module]
|
|
536
|
+
$tester.cycle microcode: 'end_module' unless options[:subroutine_pat]
|
|
537
|
+
else
|
|
538
|
+
$tester.cycle
|
|
539
|
+
end
|
|
540
|
+
end
|
|
541
|
+
end
|
|
542
|
+
microcode '}'
|
|
543
|
+
end
|
|
544
|
+
|
|
545
|
+
# Returns an array of subroutines called while generating the current pattern
|
|
546
|
+
def called_subroutines
|
|
547
|
+
@called_subroutines ||= []
|
|
548
|
+
end
|
|
549
|
+
|
|
550
|
+
# Returns an array of subroutines created by the current pattern
|
|
551
|
+
def local_subroutines # :nodoc:
|
|
552
|
+
@local_subroutines ||= []
|
|
553
|
+
end
|
|
554
|
+
|
|
555
|
+
# This is an internal method use by Origen which returns a fully formatted vector
|
|
556
|
+
# You can override this if you wish to change the output formatting at vector level
|
|
557
|
+
def format_vector(vec)
|
|
558
|
+
timeset = vec.timeset ? "> #{vec.timeset.name}" : ''
|
|
559
|
+
pin_vals = vec.pin_vals ? "#{vec.pin_vals} ;" : ''
|
|
560
|
+
if vec.repeat > 1
|
|
561
|
+
microcode = "repeat #{vec.repeat}"
|
|
562
|
+
else
|
|
563
|
+
microcode = vec.microcode ? vec.microcode : ''
|
|
564
|
+
end
|
|
565
|
+
if vec.pin_vals && ($_testers_enable_vector_comments || vector_comments)
|
|
566
|
+
comment = " // #{vec.number}:#{vec.cycle} #{vec.inline_comment}"
|
|
567
|
+
else
|
|
568
|
+
comment = vec.inline_comment.empty? ? '' : " // #{vec.inline_comment}"
|
|
569
|
+
end
|
|
570
|
+
|
|
571
|
+
"#{microcode.ljust(65)}#{timeset.ljust(31)}#{pin_vals}#{comment}"
|
|
572
|
+
end
|
|
573
|
+
|
|
574
|
+
# Override this to force the formatting to match the v1 J750 model (easier diffs)
|
|
575
|
+
def push_microcode(code) # :nodoc:
|
|
576
|
+
stage.store(code.ljust(65) + ''.ljust(31))
|
|
577
|
+
end
|
|
578
|
+
alias_method :microcode, :push_microcode
|
|
579
|
+
|
|
580
|
+
# All vectors generated with the supplied block will have all pins set
|
|
581
|
+
# to the repeat previous state. Any pins that are changed state within
|
|
582
|
+
# the block will still update to the supplied value.
|
|
583
|
+
# ==== Example
|
|
584
|
+
# # All pins except invoke will be assigned the repeat previous code
|
|
585
|
+
# # in the generated vector. On completion of the block they will
|
|
586
|
+
# # return to their previous state, except for invoke which will
|
|
587
|
+
# # retain the value assigned within the block.
|
|
588
|
+
# $tester.repeat_previous do
|
|
589
|
+
# $top.pin(:invoke).drive(1)
|
|
590
|
+
# $tester.cycle
|
|
591
|
+
# end
|
|
592
|
+
def repeat_previous
|
|
593
|
+
pinmap = Origen.pin_bank.pins
|
|
594
|
+
pinmap.each { |id, pin| pin.repeat_previous = true }
|
|
595
|
+
yield
|
|
596
|
+
pinmap.each { |id, pin| pin.repeat_previous = false }
|
|
597
|
+
end
|
|
598
|
+
|
|
599
|
+
def ignore_fails(*pins)
|
|
600
|
+
pins.each(&:suspend)
|
|
601
|
+
yield
|
|
602
|
+
pins.each(&:resume)
|
|
603
|
+
end
|
|
604
|
+
|
|
605
|
+
def enable_flag(options = {})
|
|
606
|
+
options = { flagnum: 4, # default flag to use
|
|
607
|
+
}.merge(options)
|
|
608
|
+
|
|
609
|
+
if options[:flagnum] > @flags.length
|
|
610
|
+
abort "ERROR! Invalid flag value passed to 'enable_flag' method!\n"
|
|
611
|
+
end
|
|
612
|
+
flagname = @flags[options[:flagnum] - 1]
|
|
613
|
+
update_vector(microcode: "#{@microcode[:enable]}(#{flagname})")
|
|
614
|
+
end
|
|
615
|
+
|
|
616
|
+
def set_flag(options = {})
|
|
617
|
+
options = { flagnum: 4, # default flag to use
|
|
618
|
+
}.merge(options)
|
|
619
|
+
|
|
620
|
+
if options[:flagnum] > @flags.length
|
|
621
|
+
abort "ERROR! Invalid flag value passed to 'set_flag' method!\n"
|
|
622
|
+
end
|
|
623
|
+
flagname = @flags[options[:flagnum] - 1]
|
|
624
|
+
update_vector(microcode: "#{@microcode[:set_flag]}(#{flagname})")
|
|
625
|
+
end
|
|
626
|
+
|
|
627
|
+
def cycle(options = {})
|
|
628
|
+
if @mask_vector
|
|
629
|
+
# tack on masking opcodes
|
|
630
|
+
super(options.merge(microcode: "#{options[:microcode]} #{@microcode[:mask_vector]}"))
|
|
631
|
+
else
|
|
632
|
+
super(options)
|
|
633
|
+
end
|
|
634
|
+
end
|
|
635
|
+
|
|
636
|
+
def mask_fails(setclr)
|
|
637
|
+
@mask_vector = setclr
|
|
638
|
+
end
|
|
639
|
+
end
|
|
640
|
+
end
|
|
641
|
+
end
|