Module: OrigenTesters::SmartestBasedTester::SMT8

Defined in:
lib/origen_testers/smartest_based_tester/smt8.rb

Instance Method Summary collapse

Instance Method Details

#format_vector(vec) ⇒ Object

This is an internal method use by Origen which returns a fully formatted vector You can override this if you wish to change the output formatting at vector level



146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/origen_testers/smartest_based_tester/smt8.rb', line 146

def format_vector(vec)
  has_microcode = vec.microcode && !vec.microcode.empty?
  has_repeat = vec.repeat && vec.repeat > 1
  if has_microcode || has_repeat
    # Close out current gen_vec group
    write_gen_vec
    if has_repeat
      @program_lines << "    <Instruction id=\"genVec\" value=\"1\">"
      @program_lines << "      <Assignment id=\"repeat\" value=\"#{vec.repeat}\"/>"
      @program_lines << '    </Instruction>'
      @gen_vec -= 1
    end
    if has_microcode
      puts vec.microcode
    end
  end

  unless Origen.mode.simulation? || !inline_comments || $_testers_no_inline_comments
    header_comments = []
    repeat_comment = ''
    vec.comments.each_with_index do |comment, i|
      if comment =~ /^#/
        if comment =~ /^#(R\d+)$/
          repeat_comment = Regexp.last_match(1) + ' '
        # Throw away the ############# headers and footers
        elsif comment !~ /^# ####################/
          comment = comment.strip.sub(/^# (## )?/, '')
          if comment == ''
            # Throw away empty lines at the start/end, but preserve them in the middle
            unless header_comments.empty? || i == vec.comments.size - 1
              header_comments << comment
            end
          else
            header_comments << comment
          end
        end
      end
    end

    if vec.pin_vals && ($_testers_enable_vector_comments || vector_comments)
      comment = "#{vec.number}:#{vec.cycle}"
      comment += ': ' if !header_comments.empty? || !vec.inline_comment.empty?
    else
      comment = ''
    end
    # comment += header_comments.join("\cm") unless header_comments.empty?
    # Seems that SMT8 does not support the above newline char, so identify split lines with something else
    comment += header_comments.join('----') unless header_comments.empty?
    unless vec.inline_comment.empty?
      comment += "\cm" unless header_comments.empty?
      comment += "(#{vec.inline_comment})"
    end
    c = "#{repeat_comment}#{comment}"
    @comment_lines << "#{@vector_number} #{c}"[0, 3000] unless c.empty?
  end

  if vec.pin_vals
    @vector_lines << vec.pin_vals.gsub(' ', '')
    @vector_number += 1
    @gen_vec += 1
  end
end

#open_and_write_pattern(filename) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/origen_testers/smartest_based_tester/smt8.rb', line 54

def open_and_write_pattern(filename)
  pat_name = Pathname.new(filename).basename.to_s

  @gen_vec = 0
  @vector_number = 0
  @vector_lines = []
  @comment_lines = []
  # @program_lines was already created with the pattern_header

  yield

  write_gen_vec
  @program_lines << '  </Instrument>'

  if zip_patterns
    tmp_dir = filename.gsub('.', '_')
    FileUtils.mkdir_p(tmp_dir)
    program_file = File.join(tmp_dir, 'Program.sprg')
    vector_file = File.join(tmp_dir, 'Vectors.vec')
    comments_file = File.join(tmp_dir, 'Comments.cmt')

    File.open(program_file, 'w') do |f|
      (@program_lines + @program_action_lines + @program_footer_lines).each do |line|
        f.puts line
      end
    end

    File.open(vector_file, 'w') { |f| @vector_lines.each { |l| f.puts l } }
    File.open(comments_file, 'w') { |f| @comment_lines.each { |l| f.puts l } }

    Dir.chdir tmp_dir do
      `zip #{pat_name} Program.sprg Vectors.vec Comments.cmt`
      FileUtils.mv pat_name, filename
    end
  else
    File.open filename, 'w' do |f|
      f.puts '<Pattern>'
      f.puts '  <Program>'
      (@program_lines + @program_action_lines + @program_footer_lines).each do |line|
        f.puts '  ' + line
      end
      f.puts '  </Program>'
      f.puts '  <Vector>'
      @vector_lines.each { |l| f.puts '    ' + l }
      f.puts '  </Vector>'
      f.puts '  <Comment>'
      @comment_lines.each { |l| f.puts '    ' + l }
      f.puts '  </Comment>'
      f.puts '</Pattern>'
    end
  end
ensure
  FileUtils.rm_rf(tmp_dir) if zip_patterns && File.exist?(tmp_dir)
end

An internal method called by Origen to generate the pattern footer



41
42
43
44
45
46
47
48
49
50
51
# File 'lib/origen_testers/smartest_based_tester/smt8.rb', line 41

def pattern_footer(options = {})
  options = {
    end_in_ka:      false
  }.merge(options)
  if options[:end_in_ka]
    Origen.log.warning '93K keep alive not yet implemented!'
    ss 'WARNING: 93K keep alive not yet implemented!'
  end
  @program_footer_lines = []
  @program_footer_lines << '</Program>' if zip_patterns
end

#pattern_header(options = {}) ⇒ Object

An internal method called by Origen to create the pattern header



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/origen_testers/smartest_based_tester/smt8.rb', line 11

def pattern_header(options = {})
  options = {
  }.merge(options)
  @program_lines = []
  @program_action_lines = []
  if zip_patterns
    @program_lines << '<?xml version="1.0" encoding="UTF-8"?>'
    @program_lines << '<Program xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Program.xsd">'
  end
  @program_lines << '  <Assignment id="memory" value="SM"/>'
  pin_list = ordered_pins.map do |p|
    if Origen.app.pin_pattern_order.include?(p.id)
      # specified name overrides pin name
      if (p.is_a?(Origen::Pins::PinCollection)) || p.id != p.name
        p.id.to_s # groups or aliases can be lower case
      else
        p.id.to_s.upcase # pins must be uppercase
      end
    else
      if (p.is_a?(Origen::Pins::PinCollection)) || p.id != p.name
        p.name.to_s # groups or aliases can be lower case
      else
        p.name.to_s.upcase # pins must be uppercase
      end
    end
  end.join(',')
  @program_lines << "  <Instrument id=\"#{pin_list}\">"
end

#subdirectoryObject

This currently defines what subdirectory of the pattern output directory that patterns will be output to



6
7
8
# File 'lib/origen_testers/smartest_based_tester/smt8.rb', line 6

def subdirectory
  File.join(package_namespace, 'patterns')
end

#track_and_format_comment(comment) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

The SMT8 microcode is implemented as a post conversion of the SMT7 microcode, rather than generating SMT8 microcode originally. This is generally an easier implementation and since they both run on the same h/ware there should always be a 1:1 feature mapping between the 2 systems.



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/origen_testers/smartest_based_tester/smt8.rb', line 115

def track_and_format_comment(comment)
  if comment =~ /^SQPG/
    if comment =~ /^SQPG PADDING/
      # A gen vec should not be used for MRPT vectors, the padding instruction marks the end of them
      @gen_vec = 0
    else
      write_gen_vec
      if comment =~ /^SQPG JSUB ([^;]+);/
        @program_lines << "    <Instruction id=\"patternCall\" value=\"#{tester.package_namespace}.patterns.#{Regexp.last_match(1)}\"/>"
      elsif comment =~ /^SQPG MACT (\d+);/
        @program_lines << "    <Instruction id=\"match\" value=\"#{Regexp.last_match(1)}\"/>"
      elsif comment =~ /^SQPG MRPT (\d+);/
        @program_lines << "    <Instruction id=\"matchRepeat\" value=\"#{Regexp.last_match(1)}\"/>"
      elsif comment =~ /^SQPG LBGN (\d+);/
        @program_lines << "    <Instruction id=\"loop\" value=\"#{Regexp.last_match(1)}\"/>"
      elsif comment =~ /^SQPG LEND;/
        @program_lines << "    <Instruction id=\"loopEnd\"/>"
      elsif comment =~ /^SQPG RETC (\d) (\d);/
        @program_lines << "    <Instruction id=\"returnConditional\">"
        @program_lines << "      <Assignment id=\"onFail\" value=\"#{Regexp.last_match(1) == '0' ? 'false' : 'true'}\"/>"
        @program_lines << "      <Assignment id=\"resetFail\" value=\"#{Regexp.last_match(2) == '0' ? 'false' : 'true'}\"/>"
        @program_lines << '    </Instruction>'
      else
        Origen.log.warning "This SMT7 microcode was not converted to SMT8: #{comment}"
      end
    end
  end
end

#write_gen_vecObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



210
211
212
213
214
215
# File 'lib/origen_testers/smartest_based_tester/smt8.rb', line 210

def write_gen_vec
  if @gen_vec > 0
    @program_lines << "    <Instruction id=\"genVec\" value=\"#{@gen_vec}\"/>"
    @gen_vec = 0
  end
end