origen_testers 0.31.0 → 0.40.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/config/application.rb +3 -1
  3. data/config/shared_commands.rb +4 -0
  4. data/config/version.rb +1 -1
  5. data/lib/origen_testers/api.rb +8 -0
  6. data/lib/origen_testers/atp/flow.rb +30 -9
  7. data/lib/origen_testers/flow.rb +36 -2
  8. data/lib/origen_testers/generator.rb +44 -5
  9. data/lib/origen_testers/interface.rb +22 -2
  10. data/lib/origen_testers/origen_ext/generator.rb +4 -3
  11. data/lib/origen_testers/origen_ext/generator/flow.rb +99 -5
  12. data/lib/origen_testers/program_generators.rb +5 -1
  13. data/lib/origen_testers/smartest_based_tester.rb +1 -0
  14. data/lib/origen_testers/smartest_based_tester/base.rb +177 -114
  15. data/lib/origen_testers/smartest_based_tester/base/flow.rb +329 -127
  16. data/lib/origen_testers/smartest_based_tester/base/generator.rb +25 -7
  17. data/lib/origen_testers/smartest_based_tester/base/limits_file.rb +186 -60
  18. data/lib/origen_testers/smartest_based_tester/base/pattern_compiler.rb +4 -0
  19. data/lib/origen_testers/smartest_based_tester/base/pattern_master.rb +4 -0
  20. data/lib/origen_testers/smartest_based_tester/base/processors/extract_bin_names.rb +5 -1
  21. data/lib/origen_testers/smartest_based_tester/base/processors/extract_flow_vars.rb +108 -0
  22. data/lib/origen_testers/smartest_based_tester/base/test_method.rb +8 -3
  23. data/lib/origen_testers/smartest_based_tester/base/test_suite.rb +9 -108
  24. data/lib/origen_testers/smartest_based_tester/base/test_suites.rb +17 -7
  25. data/lib/origen_testers/smartest_based_tester/base/variables_file.rb +29 -7
  26. data/lib/origen_testers/smartest_based_tester/smt7.rb +59 -0
  27. data/lib/origen_testers/smartest_based_tester/smt8.rb +218 -0
  28. data/lib/origen_testers/smartest_based_tester/v93k/flow.rb +32 -0
  29. data/lib/origen_testers/smartest_based_tester/v93k/templates/vars.tf.erb +2 -2
  30. data/lib/origen_testers/smartest_based_tester/v93k/test_suite.rb +109 -0
  31. data/lib/origen_testers/smartest_based_tester/v93k_smt8.rb +8 -0
  32. data/lib/origen_testers/smartest_based_tester/v93k_smt8/flow.rb +234 -0
  33. data/lib/origen_testers/smartest_based_tester/v93k_smt8/generator.rb +48 -0
  34. data/lib/origen_testers/smartest_based_tester/v93k_smt8/limits_file.rb +14 -0
  35. data/lib/origen_testers/smartest_based_tester/v93k_smt8/limits_workbook.rb +148 -0
  36. data/lib/origen_testers/smartest_based_tester/v93k_smt8/templates/limits.csv.erb +3 -0
  37. data/lib/origen_testers/smartest_based_tester/v93k_smt8/templates/template.flow.erb +41 -0
  38. data/lib/origen_testers/smartest_based_tester/v93k_smt8/test_suite.rb +66 -0
  39. data/lib/origen_testers/stil_based_tester/base.rb +4 -0
  40. data/lib/origen_testers/test/interface.rb +16 -2
  41. data/lib/origen_testers/vector_generator.rb +9 -4
  42. data/lib/origen_testers/vector_pipeline.rb +1 -1
  43. data/pattern/nvm/v93k/v93k_workout.rb +7 -0
  44. data/program/_erase_vfy.rb +2 -1
  45. data/program/components/_deep_nested.rb +3 -0
  46. data/program/components/_prb1_main.rb +1 -1
  47. data/program/components/_prb2_main.rb +6 -2
  48. data/program/flow_control.rb +3 -3
  49. data/program/prb1.rb +4 -0
  50. data/program/prb2.rb +7 -3
  51. data/templates/origen_guides/pattern/v93k.md.erb +24 -0
  52. data/templates/origen_guides/program/v93k.md.erb +6 -148
  53. data/templates/origen_guides/program/v93ksmt7.md.erb +165 -0
  54. data/templates/origen_guides/program/v93ksmt8.md.erb +112 -0
  55. metadata +30 -3
  56. data/lib/origen_testers/smartest_based_tester/base/test_methods/smart_calc_tml.rb +0 -23
@@ -17,13 +17,17 @@ module OrigenTesters
17
17
  attr_accessor :abs_class_name
18
18
  attr_reader :limits
19
19
  attr_accessor :limits_id
20
+ alias_method :limit_id, :limits_id
21
+ alias_method :limit_id=, :limits_id=
22
+ # Used to store the name of the primary test logged in SMT8
23
+ attr_accessor :sub_test_name
20
24
 
21
25
  def initialize(options)
22
26
  @type = options[:type]
23
27
  @library = options[:library]
24
28
  @class_name = options[:methods].delete(:class_name)
25
29
  @parameters = {}
26
- @limits_id = options[:methods].delete(:limits_id)
30
+ @limits_id = options[:methods].delete(:limits_id) || options[:methods].delete(:limit_id)
27
31
  @limits = TestMethods::Limits.new(self)
28
32
  # Add any methods
29
33
  if options[:methods][:methods]
@@ -116,10 +120,11 @@ module OrigenTesters
116
120
  when :boolean
117
121
  # Check for valid values
118
122
  if [0, 1, true, false].include?(val)
123
+ # Use true/false for smt8 and 0/1 for smt7
119
124
  if [1, true].include?(val)
120
- 1
125
+ tester.smt8? ? true : 1
121
126
  else
122
- 0
127
+ tester.smt8? ? false : 0
123
128
  end
124
129
  else
125
130
  fail "Unknown boolean value for attribute #{attr}: #{val}"
@@ -4,87 +4,6 @@ module OrigenTesters
4
4
  class TestSuite
5
5
  attr_accessor :meta
6
6
 
7
- ATTRS =
8
- %w(name
9
- comment
10
-
11
- timing_equation timing_spec timing_set
12
- level_equation level_spec level_set
13
- analog_set
14
- pattern
15
- context
16
- test_type
17
- test_method
18
-
19
- test_number
20
- test_level
21
-
22
- bypass
23
- set_pass
24
- set_fail
25
- hold
26
- hold_on_fail
27
- output_on_pass
28
- output_on_fail
29
- pass_value
30
- fail_value
31
- per_pin_on_pass
32
- per_pin_on_fail
33
- log_mixed_signal_waveform
34
- fail_per_label
35
- ffc_enable
36
- log_first
37
- ffv_enable
38
- frg_enable
39
- hardware_dsp_disable
40
- )
41
-
42
- ALIASES = {
43
- tim_equ_set: :timing_equation,
44
- tim_spec_set: :timing_spec,
45
- timset: :timing_set,
46
- timeset: :timing_set,
47
- time_set: :timing_set,
48
- lev_equ_set: :level_equation,
49
- lev_spec_set: :level_spec,
50
- levset: :level_set,
51
- levels: :level_set,
52
- pin_levels: :level_set,
53
- anaset: :analog_set,
54
- test_num: :test_number,
55
- test_function: :test_method,
56
- value_on_pass: :pass_value,
57
- value_on_fail: :fail_value,
58
- seqlbl: :pattern,
59
- mx_waves_enable: :log_mixed_signal_waveform,
60
- hw_dsp_disable: :hardware_dsp_disable,
61
- ffc_on_fail: :log_first
62
- }
63
-
64
- DEFAULTS = {
65
- output_on_pass: true,
66
- output_on_fail: true,
67
- pass_value: true,
68
- fail_value: true,
69
- per_pin_on_pass: true,
70
- per_pin_on_fail: true
71
- }
72
-
73
- # Generate accessors for all attributes and their aliases
74
- ATTRS.each do |attr|
75
- attr_accessor attr.to_sym
76
- end
77
-
78
- # Define the aliases
79
- ALIASES.each do |_alias, val|
80
- define_method("#{_alias}=") do |v|
81
- send("#{val}=", v)
82
- end
83
- define_method("#{_alias}") do
84
- send(val)
85
- end
86
- end
87
-
88
7
  def initialize(name, attrs = {})
89
8
  @name = name
90
9
  if interface.unique_test_names == :signature
@@ -106,7 +25,7 @@ module OrigenTesters
106
25
  end
107
26
  end
108
27
  # Set the defaults
109
- DEFAULTS.each do |k, v|
28
+ self.class::DEFAULTS.each do |k, v|
110
29
  send("#{k}=", v)
111
30
  end
112
31
  # Then the values that have been supplied
@@ -115,6 +34,10 @@ module OrigenTesters
115
34
  end
116
35
  end
117
36
 
37
+ def smt8?
38
+ tester.smt8?
39
+ end
40
+
118
41
  def pattern=(name)
119
42
  Origen.interface.record_pattern_reference(name) if name
120
43
  @pattern = name
@@ -129,31 +52,6 @@ module OrigenTesters
129
52
  fail 'Once assigned the name of a test suite cannot be changed!'
130
53
  end
131
54
 
132
- def lines
133
- if pattern
134
- burst = $tester.multiport ? "#{$tester.multiport_name(pattern)}" : "#{pattern}"
135
- end
136
- l = []
137
- l << " comment = \"#{comment}\";" if comment
138
- l << " ffc_on_fail = #{wrap_if_string(log_first)};" if log_first
139
- l << " local_flags = #{flags};"
140
- l << ' override = 1;'
141
- l << " override_anaset = #{wrap_if_string(analog_set)};" if analog_set
142
- l << " override_lev_equ_set = #{wrap_if_string(level_equation)};" if level_equation
143
- l << " override_lev_spec_set = #{wrap_if_string(level_spec)};" if level_spec
144
- l << " override_levset = #{wrap_if_string(level_set)};" if level_set
145
- l << " override_seqlbl = #{wrap_if_string(burst)};" if pattern
146
- l << " override_test_number = #{test_number};" if test_number
147
- l << " override_testf = #{test_method.id};" if test_method
148
- l << " override_tim_equ_set = #{wrap_if_string(timing_equation)};" if timing_equation
149
- l << " override_tim_spec_set = #{wrap_if_string(timing_spec)};" if timing_spec
150
- l << " override_timset = #{wrap_if_string(timing_set)};" if timing_set
151
- l << ' site_control = "parallel:";'
152
- l << ' site_match = 2;'
153
- l << " test_level = #{test_level};" if test_level
154
- l
155
- end
156
-
157
55
  def method_missing(method, *args, &block)
158
56
  if test_method && test_method.respond_to?(method)
159
57
  test_method.send(method, *args, &block)
@@ -171,7 +69,10 @@ module OrigenTesters
171
69
  end
172
70
 
173
71
  def to_meta
174
- meta || {}
72
+ m = meta || {}
73
+ m['Test'] = name
74
+ m['Test Name'] ||= try(:test_name)
75
+ m
175
76
  end
176
77
 
177
78
  def extract_atp_attributes(options)
@@ -10,6 +10,11 @@ module OrigenTesters
10
10
  def initialize(flow)
11
11
  @flow = flow
12
12
  @collection = []
13
+ @existing_names = {}
14
+ # Test names also have to be unique vs. the current flow name
15
+ if tester.smt8?
16
+ @existing_names[flow.filename.sub('.flow', '').to_s] = true
17
+ end
13
18
  end
14
19
 
15
20
  def filename
@@ -17,7 +22,11 @@ module OrigenTesters
17
22
  end
18
23
 
19
24
  def add(name, options = {})
25
+ symbol = name.is_a?(Symbol)
20
26
  name = make_unique(name)
27
+ # Ensure names given as a symbol stay as a symbol, this is more for
28
+ # alignment to existing test cases than anything else
29
+ name = name.to_sym if symbol
21
30
  suite = platform::TestSuite.new(name, options)
22
31
  @collection << suite
23
32
  # c = Origen.interface.consume_comments
@@ -43,14 +52,15 @@ module OrigenTesters
43
52
  private
44
53
 
45
54
  def make_unique(name)
46
- @existing_names ||= {}
47
- if @existing_names[name.to_sym]
48
- @existing_names[name.to_sym] += 1
49
- "#{name}_#{@existing_names[name.to_sym]}"
50
- else
51
- @existing_names[name.to_sym] = 0
52
- name
55
+ name = name.to_s
56
+ tempname = name
57
+ i = 0
58
+ while @existing_names[tempname]
59
+ i += 1
60
+ tempname = "#{name}_#{i}"
53
61
  end
62
+ @existing_names[tempname] = true
63
+ tempname
54
64
  end
55
65
  end
56
66
  end
@@ -5,33 +5,55 @@ module OrigenTesters
5
5
  class VariablesFile
6
6
  include OrigenTesters::Generator
7
7
 
8
- attr_reader :flow_control_variables, :runtime_control_variables
8
+ attr_reader :variables
9
9
  attr_accessor :filename, :id
10
10
 
11
11
  def initialize(options = {})
12
- @flow_control_variables = []
13
- @runtime_control_variables = []
14
12
  end
15
13
 
16
14
  def subdirectory
17
15
  'testflow/mfh.testflow.setup'
18
16
  end
19
17
 
20
- def clean_flow_control_variables
21
- flow_control_variables.uniq.sort do |x, y|
18
+ def add_variables(vars)
19
+ if @variables
20
+ vars.each do |k, v|
21
+ if k == :empty?
22
+ @variables[:empty?] ||= v
23
+ else
24
+ v.each do |k2, v2|
25
+ unless v2.empty?
26
+ @variables[k][k2] |= v2
27
+ end
28
+ end
29
+ end
30
+ end
31
+ else
32
+ @variables = vars
33
+ end
34
+ end
35
+
36
+ # What SMT7 calls a flag
37
+ def flags
38
+ (variables[:all][:referenced_enables] + variables[:all][:set_enables]).uniq.sort do |x, y|
22
39
  x = x[0] if x.is_a?(Array)
23
40
  y = y[0] if y.is_a?(Array)
24
41
  x <=> y
25
42
  end
26
43
  end
27
44
 
28
- def clean_runtime_control_variables
29
- runtime_control_variables.uniq.sort do |x, y|
45
+ # What SMT7 calls a declaration
46
+ def declarations
47
+ (variables[:all][:jobs] + variables[:all][:referenced_flags] + variables[:all][:set_flags]).uniq.sort do |x, y|
30
48
  x = x[0] if x.is_a?(Array)
31
49
  y = y[0] if y.is_a?(Array)
32
50
  x <=> y
33
51
  end
34
52
  end
53
+
54
+ def to_be_written?
55
+ tester.smt7?
56
+ end
35
57
  end
36
58
  end
37
59
  end
@@ -0,0 +1,59 @@
1
+ module OrigenTesters
2
+ module SmartestBasedTester
3
+ module SMT7
4
+ # This is an internal method use by Origen which returns a fully formatted vector
5
+ # You can override this if you wish to change the output formatting at vector level
6
+ def format_vector(vec)
7
+ timeset = vec.timeset ? "#{vec.timeset.name}" : ''
8
+ pin_vals = vec.pin_vals ? "#{vec.pin_vals} " : ''
9
+ if vec.repeat # > 1
10
+ microcode = "R#{vec.repeat}"
11
+ else
12
+ microcode = vec.microcode ? vec.microcode : ''
13
+ end
14
+
15
+ if Origen.mode.simulation? || !inline_comments || $_testers_no_inline_comments
16
+ comment = ''
17
+ else
18
+
19
+ header_comments = []
20
+ repeat_comment = ''
21
+ vec.comments.each_with_index do |comment, i|
22
+ if comment =~ /^#/
23
+ if comment =~ /^#(R\d+)$/
24
+ repeat_comment = Regexp.last_match(1) + ' '
25
+ # Throw away the ############# headers and footers
26
+ elsif comment !~ /^# ####################/
27
+ comment = comment.strip.sub(/^# (## )?/, '')
28
+ if comment == ''
29
+ # Throw away empty lines at the start/end, but preserve them in the middle
30
+ unless header_comments.empty? || i == vec.comments.size - 1
31
+ header_comments << comment
32
+ end
33
+ else
34
+ header_comments << comment
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ if vec.pin_vals && ($_testers_enable_vector_comments || vector_comments)
41
+ comment = "#{vec.number}:#{vec.cycle}"
42
+ comment += ': ' if !header_comments.empty? || !vec.inline_comment.empty?
43
+ else
44
+ comment = ''
45
+ end
46
+ comment += header_comments.join("\cm") unless header_comments.empty?
47
+ unless vec.inline_comment.empty?
48
+ comment += "\cm" unless header_comments.empty?
49
+ comment += "(#{vec.inline_comment})"
50
+ end
51
+ comment = "#{repeat_comment}#{comment}"
52
+ end
53
+
54
+ # Max comment length 250 at the end
55
+ "#{microcode.ljust(25)}#{timeset.ljust(27)}#{pin_vals}# #{comment[0, 247]};"
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,218 @@
1
+ module OrigenTesters
2
+ module SmartestBasedTester
3
+ module SMT8
4
+ # This currently defines what subdirectory of the pattern output directory that
5
+ # patterns will be output to
6
+ def subdirectory
7
+ File.join(package_namespace, 'patterns')
8
+ end
9
+
10
+ # An internal method called by Origen to create the pattern header
11
+ def pattern_header(options = {})
12
+ options = {
13
+ }.merge(options)
14
+ @program_lines = []
15
+ @program_action_lines = []
16
+ if zip_patterns
17
+ @program_lines << '<?xml version="1.0" encoding="UTF-8"?>'
18
+ @program_lines << '<Program xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Program.xsd">'
19
+ end
20
+ @program_lines << ' <Assignment id="memory" value="SM"/>'
21
+ pin_list = ordered_pins.map do |p|
22
+ if Origen.app.pin_pattern_order.include?(p.id)
23
+ # specified name overrides pin name
24
+ if (p.is_a?(Origen::Pins::PinCollection)) || p.id != p.name
25
+ p.id.to_s # groups or aliases can be lower case
26
+ else
27
+ p.id.to_s.upcase # pins must be uppercase
28
+ end
29
+ else
30
+ if (p.is_a?(Origen::Pins::PinCollection)) || p.id != p.name
31
+ p.name.to_s # groups or aliases can be lower case
32
+ else
33
+ p.name.to_s.upcase # pins must be uppercase
34
+ end
35
+ end
36
+ end.join(',')
37
+ @program_lines << " <Instrument id=\"#{pin_list}\">"
38
+ end
39
+
40
+ # An internal method called by Origen to generate the pattern footer
41
+ def pattern_footer(options = {})
42
+ options = {
43
+ end_in_ka: false
44
+ }.merge(options)
45
+ if options[:end_in_ka]
46
+ Origen.log.warning '93K keep alive not yet implemented!'
47
+ ss 'WARNING: 93K keep alive not yet implemented!'
48
+ end
49
+ @program_footer_lines = []
50
+ @program_footer_lines << '</Program>' if zip_patterns
51
+ end
52
+
53
+ # @api private
54
+ def open_and_write_pattern(filename)
55
+ pat_name = Pathname.new(filename).basename.to_s
56
+
57
+ @gen_vec = 0
58
+ @vector_number = 0
59
+ @vector_lines = []
60
+ @comment_lines = []
61
+ # @program_lines was already created with the pattern_header
62
+
63
+ yield
64
+
65
+ write_gen_vec
66
+ @program_lines << ' </Instrument>'
67
+
68
+ if zip_patterns
69
+ tmp_dir = filename.gsub('.', '_')
70
+ FileUtils.mkdir_p(tmp_dir)
71
+ program_file = File.join(tmp_dir, 'Program.sprg')
72
+ vector_file = File.join(tmp_dir, 'Vectors.vec')
73
+ comments_file = File.join(tmp_dir, 'Comments.cmt')
74
+
75
+ File.open(program_file, 'w') do |f|
76
+ (@program_lines + @program_action_lines + @program_footer_lines).each do |line|
77
+ f.puts line
78
+ end
79
+ end
80
+
81
+ File.open(vector_file, 'w') { |f| @vector_lines.each { |l| f.puts l } }
82
+ File.open(comments_file, 'w') { |f| @comment_lines.each { |l| f.puts l } }
83
+
84
+ Dir.chdir tmp_dir do
85
+ `zip #{pat_name} Program.sprg Vectors.vec Comments.cmt`
86
+ FileUtils.mv pat_name, filename
87
+ end
88
+ else
89
+ File.open filename, 'w' do |f|
90
+ f.puts '<Pattern>'
91
+ f.puts ' <Program>'
92
+ (@program_lines + @program_action_lines + @program_footer_lines).each do |line|
93
+ f.puts ' ' + line
94
+ end
95
+ f.puts ' </Program>'
96
+ f.puts ' <Vector>'
97
+ @vector_lines.each { |l| f.puts ' ' + l }
98
+ f.puts ' </Vector>'
99
+ f.puts ' <Comment>'
100
+ @comment_lines.each { |l| f.puts ' ' + l }
101
+ f.puts ' </Comment>'
102
+ f.puts '</Pattern>'
103
+ end
104
+ end
105
+ ensure
106
+ FileUtils.rm_rf(tmp_dir) if zip_patterns && File.exist?(tmp_dir)
107
+ end
108
+
109
+ # @api private
110
+ #
111
+ # The SMT8 microcode is implemented as a post conversion of the SMT7 microcode, rather than
112
+ # generating SMT8 microcode originally.
113
+ # This is generally an easier implementation and since they both run on the same h/ware there
114
+ # should always be a 1:1 feature mapping between the 2 systems.
115
+ def track_and_format_comment(comment)
116
+ if comment =~ /^SQPG/
117
+ if comment =~ /^SQPG PADDING/
118
+ # A gen vec should not be used for MRPT vectors, the padding instruction marks the end of them
119
+ @gen_vec = 0
120
+ else
121
+ write_gen_vec
122
+ if comment =~ /^SQPG JSUB ([^;]+);/
123
+ @program_lines << " <Instruction id=\"patternCall\" value=\"#{tester.package_namespace}.patterns.#{Regexp.last_match(1)}\"/>"
124
+ elsif comment =~ /^SQPG MACT (\d+);/
125
+ @program_lines << " <Instruction id=\"match\" value=\"#{Regexp.last_match(1)}\"/>"
126
+ elsif comment =~ /^SQPG MRPT (\d+);/
127
+ @program_lines << " <Instruction id=\"matchRepeat\" value=\"#{Regexp.last_match(1)}\"/>"
128
+ elsif comment =~ /^SQPG LBGN (\d+);/
129
+ @program_lines << " <Instruction id=\"loop\" value=\"#{Regexp.last_match(1)}\"/>"
130
+ elsif comment =~ /^SQPG LEND;/
131
+ @program_lines << " <Instruction id=\"loopEnd\"/>"
132
+ elsif comment =~ /^SQPG RETC (\d) (\d);/
133
+ @program_lines << " <Instruction id=\"returnConditional\">"
134
+ @program_lines << " <Assignment id=\"onFail\" value=\"#{Regexp.last_match(1) == '0' ? 'false' : 'true'}\"/>"
135
+ @program_lines << " <Assignment id=\"resetFail\" value=\"#{Regexp.last_match(2) == '0' ? 'false' : 'true'}\"/>"
136
+ @program_lines << ' </Instruction>'
137
+ else
138
+ Origen.log.warning "This SMT7 microcode was not converted to SMT8: #{comment}"
139
+ end
140
+ end
141
+ end
142
+ end
143
+
144
+ # This is an internal method use by Origen which returns a fully formatted vector
145
+ # You can override this if you wish to change the output formatting at vector level
146
+ def format_vector(vec)
147
+ has_microcode = vec.microcode && !vec.microcode.empty?
148
+ has_repeat = vec.repeat && vec.repeat > 1
149
+ if has_microcode || has_repeat
150
+ # Close out current gen_vec group
151
+ write_gen_vec
152
+ if has_repeat
153
+ @program_lines << " <Instruction id=\"genVec\" value=\"1\">"
154
+ @program_lines << " <Assignment id=\"repeat\" value=\"#{vec.repeat}\"/>"
155
+ @program_lines << ' </Instruction>'
156
+ @gen_vec -= 1
157
+ end
158
+ if has_microcode
159
+ puts vec.microcode
160
+ end
161
+ end
162
+
163
+ unless Origen.mode.simulation? || !inline_comments || $_testers_no_inline_comments
164
+ header_comments = []
165
+ repeat_comment = ''
166
+ vec.comments.each_with_index do |comment, i|
167
+ if comment =~ /^#/
168
+ if comment =~ /^#(R\d+)$/
169
+ repeat_comment = Regexp.last_match(1) + ' '
170
+ # Throw away the ############# headers and footers
171
+ elsif comment !~ /^# ####################/
172
+ comment = comment.strip.sub(/^# (## )?/, '')
173
+ if comment == ''
174
+ # Throw away empty lines at the start/end, but preserve them in the middle
175
+ unless header_comments.empty? || i == vec.comments.size - 1
176
+ header_comments << comment
177
+ end
178
+ else
179
+ header_comments << comment
180
+ end
181
+ end
182
+ end
183
+ end
184
+
185
+ if vec.pin_vals && ($_testers_enable_vector_comments || vector_comments)
186
+ comment = "#{vec.number}:#{vec.cycle}"
187
+ comment += ': ' if !header_comments.empty? || !vec.inline_comment.empty?
188
+ else
189
+ comment = ''
190
+ end
191
+ # comment += header_comments.join("\cm") unless header_comments.empty?
192
+ # Seems that SMT8 does not support the above newline char, so identify split lines with something else
193
+ comment += header_comments.join('----') unless header_comments.empty?
194
+ unless vec.inline_comment.empty?
195
+ comment += "\cm" unless header_comments.empty?
196
+ comment += "(#{vec.inline_comment})"
197
+ end
198
+ c = "#{repeat_comment}#{comment}"
199
+ @comment_lines << "#{@vector_number} #{c}"[0, 3000] unless c.empty?
200
+ end
201
+
202
+ if vec.pin_vals
203
+ @vector_lines << vec.pin_vals.gsub(' ', '')
204
+ @vector_number += 1
205
+ @gen_vec += 1
206
+ end
207
+ end
208
+
209
+ # @api private
210
+ def write_gen_vec
211
+ if @gen_vec > 0
212
+ @program_lines << " <Instruction id=\"genVec\" value=\"#{@gen_vec}\"/>"
213
+ @gen_vec = 0
214
+ end
215
+ end
216
+ end
217
+ end
218
+ end