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,94 @@
|
|
|
1
|
+
module OrigenTesters
|
|
2
|
+
module Test
|
|
3
|
+
class NVM
|
|
4
|
+
attr_accessor :blocks
|
|
5
|
+
|
|
6
|
+
include Origen::Pins
|
|
7
|
+
include Origen::Registers
|
|
8
|
+
|
|
9
|
+
def initialize
|
|
10
|
+
add_reg :mclkdiv, 0x03, 16, osch: { pos: 15 },
|
|
11
|
+
asel: { pos: 14 },
|
|
12
|
+
failctl: { pos: 13 },
|
|
13
|
+
parsel: { pos: 12 },
|
|
14
|
+
eccen: { pos: 11 },
|
|
15
|
+
cmdloc: { pos: 8, bits: 3, res: 0b001 },
|
|
16
|
+
clkdiv: { pos: 0, bits: 8, res: 0x18 }
|
|
17
|
+
|
|
18
|
+
add_reg :data, 0x4, 16, d: { pos: 0, bits: 16 }
|
|
19
|
+
|
|
20
|
+
@blocks = [Block.new(0, self), Block.new(1, self), Block.new(2, self)]
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def find_block_by_id(id)
|
|
24
|
+
@blocks.find { |block| block.id == id }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def reg_owner_alias
|
|
28
|
+
%w(flash fmu)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def override_method
|
|
32
|
+
:overridden
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def added_method
|
|
36
|
+
:added
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def add_proth_reg
|
|
40
|
+
reg :proth, 0x0024, size: 32 do
|
|
41
|
+
bits 31..24, :fprot7, reset: 0xFF
|
|
42
|
+
bits 23..16, :fprot6, reset: 0xEE
|
|
43
|
+
bits 15..8, :fprot5, reset: 0xDD
|
|
44
|
+
bits 7..0, :fprot4, reset: 0x11
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
class NVMSub < NVM
|
|
50
|
+
def redefine_data_reg
|
|
51
|
+
add_reg :data, 0x40, 16, d: { pos: 0, bits: 16 }
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Tests that the block format for defining registers works
|
|
55
|
+
def add_reg_with_block_format
|
|
56
|
+
# ** Data Register 3 **
|
|
57
|
+
# This is dreg
|
|
58
|
+
add_reg :dreg, 0x1000, size: 16 do
|
|
59
|
+
# This is dreg bit 15
|
|
60
|
+
bit 15, :bit15, reset: 1
|
|
61
|
+
# **Bit 14** - This does something cool
|
|
62
|
+
#
|
|
63
|
+
# 0 | Coolness is disabled
|
|
64
|
+
# 1 | Coolness is enabled
|
|
65
|
+
bits 14, :bit14
|
|
66
|
+
# This is dreg bit upper
|
|
67
|
+
bits 13..8, :upper
|
|
68
|
+
# This is dreg bit lower
|
|
69
|
+
# This is dreg bit lower line 2
|
|
70
|
+
bit 7..0, :lower, writable: false, reset: 0x55
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# This is dreg2
|
|
74
|
+
reg :dreg2, 0x1000, size: 16 do
|
|
75
|
+
# This is dreg2 bit 15
|
|
76
|
+
bit 15, :bit15, reset: 1
|
|
77
|
+
# This is dreg2 bit upper
|
|
78
|
+
bits 14..8, :upper
|
|
79
|
+
# This is dreg2 bit lower
|
|
80
|
+
# This is dreg2 bit lower line 2
|
|
81
|
+
bit 7..0, :lower, writable: false, reset: 0x55
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Finally a test that descriptions can be supplied via the API
|
|
85
|
+
reg :dreg3, 0x1000, size: 16, description: "** Data Register 3 **\nThis is dreg3" do
|
|
86
|
+
bit 15, :bit15, reset: 1, description: 'This is dreg3 bit 15'
|
|
87
|
+
bit 14, :bit14, description: "**Bit 14** - This does something cool\n\n0 | Coolness is disabled\n1 | Coolness is enabled"
|
|
88
|
+
bits 13..8, :upper, description: 'This is dreg3 bit upper'
|
|
89
|
+
bit 7..0, :lower, writable: false, reset: 0x55, description: "This is dreg3 bit lower\nThis is dreg3 bit lower line 2"
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
module OrigenTesters
|
|
2
|
+
module Test
|
|
3
|
+
class UltraFLEXInterface
|
|
4
|
+
include OrigenTesters::UltraFLEX::Generator
|
|
5
|
+
|
|
6
|
+
# Options passed to Flow.create and Library.create will be passed in here, use as
|
|
7
|
+
# desired to configure your interface
|
|
8
|
+
def initialize(options = {})
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def log(msg)
|
|
12
|
+
flow.logprint(msg)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def func(name, options = {})
|
|
16
|
+
options = {
|
|
17
|
+
duration: :static
|
|
18
|
+
}.merge(options)
|
|
19
|
+
|
|
20
|
+
block_loop(name, options) do |block, i, group|
|
|
21
|
+
ins = test_instances.functional(name)
|
|
22
|
+
ins.set_wait_flags(:a) if options[:duration] == :dynamic
|
|
23
|
+
ins.pin_levels = options.delete(:pin_levels) if options[:pin_levels]
|
|
24
|
+
if group
|
|
25
|
+
pname = "#{name}_b#{i}_pset"
|
|
26
|
+
patsets.add(pname, [{ pattern: "#{name}_b#{i}.PAT" },
|
|
27
|
+
{ pattern: 'nvm_global_subs.PAT', start_label: 'subr' }])
|
|
28
|
+
ins.pattern = pname
|
|
29
|
+
flow.test(group, options) if i == 0
|
|
30
|
+
else
|
|
31
|
+
pname = "#{name}_pset"
|
|
32
|
+
patsets.add(pname, [{ pattern: "#{name}.PAT" },
|
|
33
|
+
{ pattern: 'nvm_global_subs.PAT', start_label: 'subr' }])
|
|
34
|
+
ins.pattern = pname
|
|
35
|
+
if options[:cz_setup]
|
|
36
|
+
flow.cz(ins, options[:cz_setup], options)
|
|
37
|
+
else
|
|
38
|
+
flow.test(ins, options)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def meas(name, options = {})
|
|
45
|
+
options = {
|
|
46
|
+
duration: :static
|
|
47
|
+
}.merge(options)
|
|
48
|
+
|
|
49
|
+
name = "meas_#{name}" unless name.to_s =~ /meas/
|
|
50
|
+
|
|
51
|
+
ins = test_instances.functional(name)
|
|
52
|
+
ins.set_wait_flags(:a) if options[:duration] == :dynamic
|
|
53
|
+
ins.pin_levels = options.delete(:pin_levels) if options[:pin_levels]
|
|
54
|
+
|
|
55
|
+
pname = "#{name}_pset"
|
|
56
|
+
patsets.add(pname, [{ pattern: "#{name}.PAT" },
|
|
57
|
+
{ pattern: 'nvm_global_subs.PAT', start_label: 'subr' }])
|
|
58
|
+
ins.pattern = pname
|
|
59
|
+
if options[:cz_setup]
|
|
60
|
+
flow.cz(ins, options[:cz_setup], options)
|
|
61
|
+
else
|
|
62
|
+
use_limit_params = [:lo_limit, :hi_limit, :scale, :units] # define options to strip for flow.test
|
|
63
|
+
options_use_limit = options.dup # duplicate, as modifying options directly, even an assigned copy modifies original
|
|
64
|
+
flow.test(ins, options.reject! { |k, _| use_limit_params.include? k }) # set up test skipping use-limit options
|
|
65
|
+
flow.use_limit(name, options_use_limit) if options_use_limit[:hi_limit] || options_use_limit[:lo_limit] # Only use use-limit if limits present in flow
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def block_loop(name, options)
|
|
70
|
+
if options[:by_block]
|
|
71
|
+
test_instances.group do |group|
|
|
72
|
+
group.name = name
|
|
73
|
+
$dut.blocks.each_with_index do |block, i|
|
|
74
|
+
yield block, i, group
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
else
|
|
78
|
+
yield
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def por(options = {})
|
|
83
|
+
options = {
|
|
84
|
+
instance_not_available: true
|
|
85
|
+
}.merge(options)
|
|
86
|
+
flow.test('por_ins', options)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def para(name, options = {})
|
|
90
|
+
print "UltraFLEX Parametric Test not yet supported for UltraFlex!\n"
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# OR 2 IDS together into 1 flag
|
|
94
|
+
def or_ids(options = {})
|
|
95
|
+
flow.or_flags(options[:id1], options[:id2], options)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def nop(options = {})
|
|
99
|
+
flow.nop options
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def mto_memory(args)
|
|
103
|
+
# DO NOTHING, NOT YET SUPPORTED IN ULTRAFLEX
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def bin(number, options = {})
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
module OrigenTesters
|
|
2
|
+
module Test
|
|
3
|
+
class V93KInterface
|
|
4
|
+
include OrigenTesters::V93K::Generator
|
|
5
|
+
|
|
6
|
+
# Options passed to Flow.create and Library.create will be passed in here, use as
|
|
7
|
+
# desired to configure your interface
|
|
8
|
+
def initialize(options = {})
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def log(msg)
|
|
12
|
+
flow.print_to_datalog(msg)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def func(name, options = {})
|
|
16
|
+
options = {
|
|
17
|
+
duration: :static
|
|
18
|
+
}.merge(options)
|
|
19
|
+
|
|
20
|
+
block_loop(name, options) do |block, i, group|
|
|
21
|
+
tm = test_methods.ac_tml.ac_test.functional_test
|
|
22
|
+
ts = test_suites.run(name, options)
|
|
23
|
+
ts.test_method = tm
|
|
24
|
+
ts.levels = options.delete(:pin_levels) if options[:pin_levels]
|
|
25
|
+
if group
|
|
26
|
+
ts.pattern = "#{name}_b#{i}"
|
|
27
|
+
else
|
|
28
|
+
ts.pattern = name.to_s
|
|
29
|
+
# if options[:cz_setup]
|
|
30
|
+
# flow.cz(ins, options[:cz_setup], options)
|
|
31
|
+
# else
|
|
32
|
+
# end
|
|
33
|
+
end
|
|
34
|
+
flow.test ts, options
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def meas(name, options = {})
|
|
39
|
+
options = {
|
|
40
|
+
duration: :static
|
|
41
|
+
}.merge(options)
|
|
42
|
+
|
|
43
|
+
name = "meas_#{name}" unless name.to_s =~ /meas/
|
|
44
|
+
|
|
45
|
+
tm = test_methods.dc_tml.dc_test.general_pmu
|
|
46
|
+
ts = test_suites.run(name, options)
|
|
47
|
+
ts.test_method = tm
|
|
48
|
+
ts.levels = options.delete(:pin_levels) if options[:pin_levels]
|
|
49
|
+
ts.lo_limit = options[:lo_limit] if options[:lo_limit]
|
|
50
|
+
ts.hi_limit = options[:hi_limit] if options[:hi_limit]
|
|
51
|
+
ts.pattern = name.to_s
|
|
52
|
+
# if options[:cz_setup]
|
|
53
|
+
# flow.cz(ins, options[:cz_setup], options)
|
|
54
|
+
# else
|
|
55
|
+
# use_limit_params = [:lo_limit, :hi_limit, :scale, :units] # define options to strip for flow.test
|
|
56
|
+
# options_use_limit = options.dup # duplicate, as modifying options directly, even an assigned copy modifies original
|
|
57
|
+
# flow.test(ins, options.reject! { |k, _| use_limit_params.include? k }) # set up test skipping use-limit options
|
|
58
|
+
# flow.use_limit(name, options_use_limit) if options_use_limit[:hi_limit] || options_use_limit[:lo_limit] # Only use use-limit if limits present in flow
|
|
59
|
+
# end
|
|
60
|
+
flow.test ts, options
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def group(name, options = {})
|
|
64
|
+
flow.group name, options do |group|
|
|
65
|
+
yield group
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def block_loop(name, options)
|
|
70
|
+
if options[:by_block]
|
|
71
|
+
flow.group name, options do |group|
|
|
72
|
+
$dut.blocks.each_with_index do |block, i|
|
|
73
|
+
yield block, i, group
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
else
|
|
77
|
+
yield
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def por(options = {})
|
|
82
|
+
options = {
|
|
83
|
+
instance_not_available: true
|
|
84
|
+
}.merge(options)
|
|
85
|
+
func('por_ins', options)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def para(name, options = {})
|
|
89
|
+
# print "UltraFLEX Parametric Test not yet supported for UltraFLEX!\n"
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# OR 2 IDS together into 1 flag
|
|
93
|
+
# def or_ids(options = {})
|
|
94
|
+
# flow.or_flags(options[:id1], options[:id2], options)
|
|
95
|
+
# end
|
|
96
|
+
|
|
97
|
+
def nop(options = {})
|
|
98
|
+
# flow.nop options
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def mto_memory(name, options = {})
|
|
102
|
+
# Seriously?!
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# OR 2 IDS together into 1 flag
|
|
106
|
+
def or_ids(options = {})
|
|
107
|
+
# Eh?
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def bin(number, options = {})
|
|
111
|
+
flow.good_bin(number, bin_desc: options[:description])
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
module OrigenTesters
|
|
2
|
+
module Timing
|
|
3
|
+
extend ActiveSupport::Concern
|
|
4
|
+
|
|
5
|
+
included do
|
|
6
|
+
# When set to true all pattern vectors will be converted to use the same period (the
|
|
7
|
+
# shortest period used in the pattern).
|
|
8
|
+
#
|
|
9
|
+
# @example
|
|
10
|
+
# $tester.set_timeset("fast", 40)
|
|
11
|
+
# 2.cycles # fast 1 0 0 1 0
|
|
12
|
+
# # fast 1 0 0 1 0
|
|
13
|
+
#
|
|
14
|
+
# $tester.level_period = false # Without levelling enabled
|
|
15
|
+
# $tester.set_timeset("slow", 80)
|
|
16
|
+
# 2.cycles # slow 1 0 0 1 0
|
|
17
|
+
# # slow 1 0 0 1 0
|
|
18
|
+
#
|
|
19
|
+
# $tester.level_period = true # With levelling enabled
|
|
20
|
+
# $tester.set_timeset("slow", 80)
|
|
21
|
+
# 2.cycles # fast 1 0 0 1 0
|
|
22
|
+
# # fast 1 0 0 1 0
|
|
23
|
+
# # fast 1 0 0 1 0
|
|
24
|
+
# # fast 1 0 0 1 0
|
|
25
|
+
#
|
|
26
|
+
# @see Timing#timing_toggled_pins
|
|
27
|
+
attr_accessor :level_period
|
|
28
|
+
alias_method :level_period?, :level_period
|
|
29
|
+
attr_writer :timing_toggled_pins
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
class Timeset
|
|
33
|
+
attr_accessor :name, :period_in_ns
|
|
34
|
+
|
|
35
|
+
def initialize(attrs = {})
|
|
36
|
+
attrs.each do |name, value|
|
|
37
|
+
send("#{name}=", value)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Returns true if the timeset has a shorter period than the supplied timeset
|
|
42
|
+
def shorter_period_than?(timeset)
|
|
43
|
+
period_in_ns < timeset.period_in_ns
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# @see Timing#level_period
|
|
48
|
+
#
|
|
49
|
+
# When period levelling is enabled, vectors will be expanded like this:
|
|
50
|
+
# $tester.set_timeset("fast", 40)
|
|
51
|
+
# 2.cycles # fast 1 0 0 1 0
|
|
52
|
+
# # fast 1 0 0 1 0
|
|
53
|
+
# # Without levelling enabled
|
|
54
|
+
# $tester.set_timeset("slow", 80)
|
|
55
|
+
# 2.cycles # slow 1 0 0 1 0
|
|
56
|
+
# # slow 1 0 0 1 0
|
|
57
|
+
# # With levelling enabled
|
|
58
|
+
# $tester.set_timeset("slow", 80)
|
|
59
|
+
# 2.cycles # fast 1 0 0 1 0
|
|
60
|
+
# # fast 1 0 0 1 0
|
|
61
|
+
# # fast 1 0 0 1 0
|
|
62
|
+
# # fast 1 0 0 1 0
|
|
63
|
+
#
|
|
64
|
+
# The overall time of the levelled/expanded vectors matches that of the unlevelled
|
|
65
|
+
# case. i.e. 4 cycles at fast speed (4 * 40ns = 160ns) is equivalent to 2 cycles
|
|
66
|
+
# at slow speed (2 * 80ns = 160ns).
|
|
67
|
+
#
|
|
68
|
+
# However, what if pin 1 in the example above was a clk pin where the 1 -> 0 transition
|
|
69
|
+
# was handled by the timing setup for that pin.
|
|
70
|
+
# In that case the levelled code is no longer functionally correct since it contains
|
|
71
|
+
# 4 clock pulses while the unlevelled code only has 2.
|
|
72
|
+
#
|
|
73
|
+
# Such pins can be specified via this attribute and the levelling logic will then
|
|
74
|
+
# automatically adjust the drive state to keep the number of pulses correct.
|
|
75
|
+
# It would automatically adjust to the alternative logic state where 0 means 'on'
|
|
76
|
+
# and 1 means 'off' if applicable.
|
|
77
|
+
#
|
|
78
|
+
# $tester.timing_toggled_pins << $dut.pin(:tclk) # This is pin 1
|
|
79
|
+
#
|
|
80
|
+
# $tester.set_timeset("fast", 40)
|
|
81
|
+
# 2.cycles # fast 1 0 0 1 0
|
|
82
|
+
# # fast 1 0 0 1 0
|
|
83
|
+
# # Without levelling enabled
|
|
84
|
+
# $tester.set_timeset("slow", 80)
|
|
85
|
+
# 2.cycles # slow 1 0 0 1 0
|
|
86
|
+
# # slow 1 0 0 1 0
|
|
87
|
+
# # With levelling enabled
|
|
88
|
+
# $tester.set_timeset("slow", 80)
|
|
89
|
+
# 2.cycles # fast 1 0 0 1 0
|
|
90
|
+
# # fast 0 0 0 1 0
|
|
91
|
+
# # fast 1 0 0 1 0
|
|
92
|
+
# # fast 0 0 0 1 0
|
|
93
|
+
#
|
|
94
|
+
# Multiple pins an be specified like this:
|
|
95
|
+
# $tester.timing_toggled_pins = [$dut.pin(:tclk), $dut.pin(:clk)] # Overrides any pins added elsewhere
|
|
96
|
+
# $tester.timing_toggled_pins << [$dut.pin(:tclk), $dut.pin(:clk)] # In addition to any pins added elsewhere
|
|
97
|
+
def timing_toggled_pins
|
|
98
|
+
@timing_toggled_pins ||= []
|
|
99
|
+
@timing_toggled_pins.flatten!
|
|
100
|
+
@timing_toggled_pins
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Set the timeset for the next vectors, this will remain in place until the next
|
|
104
|
+
# time this is called.
|
|
105
|
+
#
|
|
106
|
+
# $tester.set_timeset("bist_25mhz", 40)
|
|
107
|
+
#
|
|
108
|
+
# This method also accepts a block in which case the contained vectors will generate
|
|
109
|
+
# with the supplied timeset and subsequent vectors will return to the previous timeset
|
|
110
|
+
# automatically.
|
|
111
|
+
#
|
|
112
|
+
# $tester.set_timeset("bist_25mhz", 40) do
|
|
113
|
+
# $tester.cycle
|
|
114
|
+
# end
|
|
115
|
+
#
|
|
116
|
+
# The arguments can also be supplied as a single array, or not at all. In the latter case
|
|
117
|
+
# the existing timeset will simply be preserved. This is useful if you have timesets that
|
|
118
|
+
# can be conditionally set based on the target.
|
|
119
|
+
#
|
|
120
|
+
# # Target 1
|
|
121
|
+
# $soc.readout_timeset = ["readout", 120]
|
|
122
|
+
# # Target 2
|
|
123
|
+
# $soc.readout_timeset = false
|
|
124
|
+
#
|
|
125
|
+
# # This code is compatible with both targets, in the first case the timeset will switch
|
|
126
|
+
# # over, in the second case the existing timeset will be preserved.
|
|
127
|
+
# $tester.set_timeset($soc.readout_timeset) do
|
|
128
|
+
# $tester.cycle
|
|
129
|
+
# end
|
|
130
|
+
def set_timeset(timeset, period_in_ns = nil)
|
|
131
|
+
if timeset.is_a?(Array)
|
|
132
|
+
timeset, period_in_ns = timeset[0], timeset[1]
|
|
133
|
+
end
|
|
134
|
+
timeset ||= @timeset
|
|
135
|
+
unless timeset.is_a?(Timeset)
|
|
136
|
+
fail 'You must supply a period_in_ns argument to set_timeset' unless period_in_ns
|
|
137
|
+
timeset = Timeset.new(name: timeset.to_s.chomp, period_in_ns: period_in_ns)
|
|
138
|
+
end
|
|
139
|
+
called_timesets << timeset unless called_timesets.map(&:name).include?(timeset.name)
|
|
140
|
+
if @min_period_timeset
|
|
141
|
+
@min_period_timeset = timeset if timeset.shorter_period_than?(@min_period_timeset)
|
|
142
|
+
else
|
|
143
|
+
@min_period_timeset = timeset
|
|
144
|
+
end
|
|
145
|
+
if block_given?
|
|
146
|
+
original = @timeset
|
|
147
|
+
timeset_changed(timeset)
|
|
148
|
+
@timeset = timeset
|
|
149
|
+
yield
|
|
150
|
+
timeset_changed(original)
|
|
151
|
+
@timeset = original
|
|
152
|
+
else
|
|
153
|
+
timeset_changed(timeset)
|
|
154
|
+
@timeset = timeset
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# Returns the timeset (a Timeset object) with the shortest period that has been
|
|
159
|
+
# encountered so far in the course of generating the current pattern.
|
|
160
|
+
#
|
|
161
|
+
# A tester object is re-instantiated at the start of every pattern which will reset
|
|
162
|
+
# this variable.
|
|
163
|
+
def min_period_timeset
|
|
164
|
+
@min_period_timeset
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def timeset_changed(timeset)
|
|
168
|
+
if last_vector && last_vector.timeset != timeset
|
|
169
|
+
change = { old: last_vector.timeset, new: timeset }
|
|
170
|
+
# Suppress any duplicate calls
|
|
171
|
+
if !@_last_timeset_change ||
|
|
172
|
+
(@_last_timeset_change[:new] != change[:new] &&
|
|
173
|
+
@_last_timeset_change[:old] != change[:old])
|
|
174
|
+
before_timeset_change(change)
|
|
175
|
+
end
|
|
176
|
+
@_last_timeset_change = change
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def before_timeset_change(options = {})
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
# Cause the pattern to wait.
|
|
184
|
+
# The following options are available to help you specify the time to wait:
|
|
185
|
+
# * :cycles - delays specified in raw cycles, the test model is responsible for translating this into a sequence of valid repeat statements
|
|
186
|
+
# * :time_in_ns - time specified in nano-seconds
|
|
187
|
+
# * :time_in_us - time specified in micro-seconds
|
|
188
|
+
# * :time_in_ms - time specified in milli-seconds
|
|
189
|
+
# * :time_in_s - time specified in seconds
|
|
190
|
+
# If more than one option is supplied they will get added together to give a final
|
|
191
|
+
# delay time expressed in cycles.
|
|
192
|
+
# ==== Examples
|
|
193
|
+
# $tester.wait(cycles: 100, time_in_ns: 200) # Wait for 100 cycles + 200ns
|
|
194
|
+
# This method can also be used to trigger a match loop in which case the supplied time
|
|
195
|
+
# becomes the time out for the match. See the J750#match method for full details of the
|
|
196
|
+
# available options.
|
|
197
|
+
# $tester.wait(match: true, state: :high, pin: $dut.pin(:done), time_in_ms: 500)
|
|
198
|
+
def wait(options = {})
|
|
199
|
+
options = {
|
|
200
|
+
cycles: 0,
|
|
201
|
+
time_in_cycles: 0,
|
|
202
|
+
time_in_us: 0,
|
|
203
|
+
time_in_ns: 0,
|
|
204
|
+
time_in_ms: 0,
|
|
205
|
+
time_in_s: 0,
|
|
206
|
+
match: false, # Set to true to invoke a match loop where the supplied delay
|
|
207
|
+
# will become the timeout duration
|
|
208
|
+
}.merge(options)
|
|
209
|
+
|
|
210
|
+
cycles = 0
|
|
211
|
+
cycles += options[:cycles] + options[:time_in_cycles]
|
|
212
|
+
cycles += s_to_cycles(options[:time_in_s])
|
|
213
|
+
cycles += ms_to_cycles(options[:time_in_ms])
|
|
214
|
+
cycles += us_to_cycles(options[:time_in_us])
|
|
215
|
+
cycles += ns_to_cycles(options[:time_in_ns])
|
|
216
|
+
|
|
217
|
+
time = cycles * current_period_in_ns # Total delay in ns
|
|
218
|
+
case
|
|
219
|
+
when time < 1000 # When less than 1us
|
|
220
|
+
cc "Wait for #{'a maximum of ' if options[:match]}#{time}ns"
|
|
221
|
+
when time < 1_000_000 # When less than 1ms
|
|
222
|
+
cc "Wait for #{'a maximum of ' if options[:match]}#{(time.to_f / 1000).round(1)}us" # Display delay in us
|
|
223
|
+
when time < 1_000_000_000 # When less than 1s
|
|
224
|
+
cc "Wait for #{'a maximum of ' if options[:match]}#{(time.to_f / 1_000_000).round(1)}ms"
|
|
225
|
+
else
|
|
226
|
+
cc "Wait for #{'a maximum of ' if options[:match]}%.2fs" % (time.to_f / 1_000_000_000)
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
if cycles > 0 # Allow this function to be called with 0 in which case it will just return
|
|
230
|
+
if options[:match]
|
|
231
|
+
if block_given?
|
|
232
|
+
match_block(cycles, options) { yield }
|
|
233
|
+
else
|
|
234
|
+
match(options[:pin], options[:state], cycles, options)
|
|
235
|
+
end
|
|
236
|
+
else
|
|
237
|
+
delay(cycles)
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
# @see Timing#wait
|
|
243
|
+
# @api private
|
|
244
|
+
# This should not be called directly, call via tester#wait
|
|
245
|
+
def delay(cycles, options = {})
|
|
246
|
+
(cycles / max_repeat_loop).times do
|
|
247
|
+
if block_given?
|
|
248
|
+
yield options.merge(repeat: max_repeat_loop)
|
|
249
|
+
else
|
|
250
|
+
cycle(options.merge(repeat: max_repeat_loop))
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
if block_given?
|
|
254
|
+
yield options.merge(repeat: (cycles % max_repeat_loop))
|
|
255
|
+
else
|
|
256
|
+
cycle(options.merge(repeat: (cycles % max_repeat_loop)))
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
def max_repeat_loop
|
|
261
|
+
@max_repeat_loop || 65_535
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
def min_repeat_loop
|
|
265
|
+
@min_repeat_loop
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
def called_timesets
|
|
269
|
+
@called_timesets ||= []
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
def current_period_in_ns
|
|
273
|
+
if @timeset
|
|
274
|
+
@timeset.period_in_ns
|
|
275
|
+
else
|
|
276
|
+
fail 'No timeset has been specified yet!'
|
|
277
|
+
end
|
|
278
|
+
end
|
|
279
|
+
alias_method :current_period, :current_period_in_ns
|
|
280
|
+
alias_method :period, :current_period_in_ns
|
|
281
|
+
|
|
282
|
+
def current_timeset
|
|
283
|
+
@timeset
|
|
284
|
+
end
|
|
285
|
+
alias_method :timeset, :current_timeset
|
|
286
|
+
|
|
287
|
+
# Convert the supplied number of cycles to a time, based on the SoC defined cycle period
|
|
288
|
+
def cycles_to_time(cycles) # :nodoc:
|
|
289
|
+
(cycles * current_period_in_ns).to_f / 1_000_000_000
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
# This function can be used to generate a clock or some other repeating function
|
|
293
|
+
# that spans accross a range of vectors.
|
|
294
|
+
# The period of each cycle and the duration of the sequence are supplied via the following
|
|
295
|
+
# options:
|
|
296
|
+
# * :period_in_cycles
|
|
297
|
+
# * :period_in_ns
|
|
298
|
+
# * :period_in_us
|
|
299
|
+
# * :period_in_ms
|
|
300
|
+
# * :duration_in_cycles
|
|
301
|
+
# * :duration_in_ns
|
|
302
|
+
# * :duration_in_us
|
|
303
|
+
# * :duration_in_ms
|
|
304
|
+
# If multiple definitions for either option are supplied then they will be added
|
|
305
|
+
# together.
|
|
306
|
+
# ==== Example
|
|
307
|
+
# # Supply a clock pulse on :pinA for 100ms
|
|
308
|
+
# $tester.count(:period_in_cycles => 10, :duration_in_ms => 100) do
|
|
309
|
+
# $top.pin(:pinA).drive!(1)
|
|
310
|
+
# $top.pin(:pinA).drive!(0)
|
|
311
|
+
# end
|
|
312
|
+
def count(options = {})
|
|
313
|
+
options = { period_in_cycles: 0, period_in_ms: 0, period_in_us: 0, period_in_ns: 0,
|
|
314
|
+
duration_in_cycles: 0, duration_in_ms: 0, duration_in_us: 0, duration_in_ns: 0
|
|
315
|
+
}.merge(options)
|
|
316
|
+
|
|
317
|
+
period_cycles = options[:period_in_cycles] + ms_to_cycles(options[:period_in_ms]) +
|
|
318
|
+
us_to_cycles(options[:period_in_us]) + ns_to_cycles(options[:period_in_ns])
|
|
319
|
+
|
|
320
|
+
duration_cycles = options[:duration_in_cycles] + ms_to_cycles(options[:duration_in_ms]) +
|
|
321
|
+
us_to_cycles(options[:duration_in_us]) + ns_to_cycles(options[:duration_in_ns])
|
|
322
|
+
|
|
323
|
+
total = 0
|
|
324
|
+
while total < duration_cycles
|
|
325
|
+
wait(time_in_cycles: period_cycles)
|
|
326
|
+
yield # Return control back to caller
|
|
327
|
+
total += period_cycles
|
|
328
|
+
end
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
private
|
|
332
|
+
|
|
333
|
+
def s_to_cycles(time) # :nodoc:
|
|
334
|
+
((time.to_f) * 1000 * 1000 * 1000 / current_period_in_ns).to_int
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
def ms_to_cycles(time) # :nodoc:
|
|
338
|
+
((time.to_f) * 1000 * 1000 / current_period_in_ns).to_int
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
def us_to_cycles(time) # :nodoc:
|
|
342
|
+
((time.to_f * 1000) / current_period_in_ns).to_int
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
def ns_to_cycles(time) # :nodoc:
|
|
346
|
+
(time.to_f / current_period_in_ns).to_int
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
def cycles_to_us(cycles) # :nodoc:
|
|
350
|
+
((cycles.to_f * current_period_in_ns) / (1000)).ceil
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
def cycles_to_ms(cycles) # :nodoc:
|
|
354
|
+
((cycles.to_f * current_period_in_ns) / (1000 * 1000)).ceil
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
# Cycles to tenths of a second
|
|
358
|
+
def cycles_to_ts(cycles) # :nodoc:
|
|
359
|
+
((cycles.to_f * current_period_in_ns) / (1000 * 1000 * 100)).ceil
|
|
360
|
+
end
|
|
361
|
+
end
|
|
362
|
+
end
|