Module: OrigenLink::ConfigurationCommands

Included in:
VectorBased
Defined in:
lib/origen_link/configuration_commands.rb

Instance Method Summary collapse

Instance Method Details

#get_tset_number(name) ⇒ Object

get_tset_number(name)

This method returns the test number associated with the
passed in tset name.  If the name is unknown a new lookup
number is returned.


228
229
230
231
232
233
234
# File 'lib/origen_link/configuration_commands.rb', line 228

def get_tset_number(name)
  unless @tsets_programmed.key?(name)
    @tsets_programmed[name] = @tset_count
    @tset_count += 1
  end
  @tsets_programmed[name]
end

#pinformat=(pinformat) ⇒ Object

pinformat=

This method is used to setup the pin clock format on the debugger device.
The supported formats are rl and rh

example:
  tester.pinformat = 'func_25mhz,tclk,rl'


73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/origen_link/configuration_commands.rb', line 73

def pinformat=(pinformat)
  cmd = []
  cmd << 'pin_format'
  cmd << replace_tset_name_w_number(pinformat.gsub(/\s+/, ''))
  @pinformat = cmd[1]
  if @pinmap.nil?
    @batched_setup_cmds << cmd
  else
    response = send_cmd(cmd[0], @pinformat)
    setup_cmd_response_logger(cmd[0], response)
  end
end

#pinmap=(pinmap) ⇒ Object

pinmap=

This method is used to setup the pin map on the debugger device.
The argument should be a string with <pin name>, <gpio #>, <pin name>
<gpio #>, etc

example:
  tester.pinmap = 'tclk,26,tms,19,tdi,16,tdo,23'


10
11
12
13
14
15
16
17
18
# File 'lib/origen_link/configuration_commands.rb', line 10

def pinmap=(pinmap)
  @pinmap = pinmap.gsub(/\s+/, '')
  response = send_cmd('pin_assign', @pinmap)
  setup_cmd_response_logger('pin_assign', response)
  # store pins to the pinmap hash, this is used to remove non-link pins
  # from the pattern in cases where the app includes too many pins
  pinmap_arr = @pinmap.split(',')
  0.step(pinmap_arr.size - 1, 2) { |p| @pinmap_hash[pinmap_arr[p]] = true }
end

#pinorder=(pinorder) ⇒ Object

pinorder=

This method is used to setup the pin order on the debugger device.
The pin order will indicate the order that pin data appears in vector
data.

This is a duplicate of pattern_pin_order and can be handled behind the
scenes in the future.

example:
  tester.pinorder = 'tclk,tms,tdi,tdo'


30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/origen_link/configuration_commands.rb', line 30

def pinorder=(pinorder)
  cmd = []
  cmd << 'pin_patternorder'
  cmd << pinorder.gsub(/\s+/, '')
  @pinorder = cmd[1]
  if @pinmap.nil?
    @batched_setup_cmds << cmd
  else
    response = send_cmd(cmd[0], @pinorder)
    setup_cmd_response_logger(cmd[0], response)
  end
end

#pintiming=(pintiming) ⇒ Object

pintiming=

This method is used to setup the pin timing on the debugger device.
Timing is relative to the rise and fall of a clock

timing value:         0   1   2
clock waveform:      ___/***\___

example:
  tester.pintiming = 'func_25mhz,tms,0,tdi,0,tdo,1'


95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/origen_link/configuration_commands.rb', line 95

def pintiming=(pintiming)
  cmd = []
  cmd << 'pin_timing'
  cmd << replace_tset_name_w_number(pintiming.gsub(/\s+/, ''))
  @pintiming = cmd[1]
  if @pinmap.nil?
    @batched_setup_cmds << cmd
  else
    response = send_cmd(cmd[0], @pintiming)
    setup_cmd_response_logger(cmd[0], response)
  end
end

#process_timeset(tset) ⇒ Object

process_timeset(tset)

This method will check the pin timing api for the current timeset.
If the timset is programmed, it will be processed into the Link
timing format, registered, and sent to the server.
Else, a warning message will be displayed

example generated command:
  send_cmd('pin_timingv2', '2,drive,5,data,tck;10,data,tdi|compare,35,data,tck,tdo;5,data,tdi')


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
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/origen_link/configuration_commands.rb', line 116

def process_timeset(tset)
  # Check to see if this timeset has been programmed
  if dut.timesets(tset.to_sym).nil?
    # Timset has not been programmed through the pin timing api
    tset_warning(tset)
    ''	# return empty string on failure
  else
    # Timeset has been programmed
    # accumulate and sort drive events
    drive_str = tset_argstr_from_events(dut.timesets(tset.to_sym).drive_waves)

    # accumulate and sort compare events
    compare_str = tset_argstr_from_events(dut.timesets(tset.to_sym).compare_waves)

    # construct the command argument string
    argstr = get_tset_number(tset).to_s
    if drive_str.length > 0
      argstr = argstr + ',drive,' + drive_str
      argstr = argstr + '|compare,' + compare_str if compare_str.length > 0
    elsif compare_str.length > 0
      argstr = argstr + ',compare,' + compare_str
    else
      fail "#{tset} timeset is programmed with no drive or compare edges"
    end

    # send the timeset information to the server
    cmd = []
    cmd << 'pin_timingv2'
    cmd << argstr
    if @pinmap.nil?
      @batched_setup_cmds << cmd
    else
      response = send_cmd('pin_timingv2', argstr)
      setup_cmd_response_logger('pin_timingv2', response)
    end

    # return the tset number from the tset hash
    "tset#{@tsets_programmed[tset]},"
  end
end

#replace_tset_name_w_number(csl) ⇒ Object

replace_tset_name_w_number(csl)

This method is used by pinformat= and pintiming=
This method receives a comma separated list of arguments
the first of which is a timeset name.  A comma
separated list is returned with the timeset name replaced
by it's lookup number.  If it is a new timset, a lookup
number is associated with the name.


218
219
220
221
222
# File 'lib/origen_link/configuration_commands.rb', line 218

def replace_tset_name_w_number(csl)
  args = csl.split(',')
  args[0] = get_tset_number(args[0])
  args.join(',')
end

#set_pinorderObject

set_pinorder

This method is called if the app has not explicitly set the pin order
for the Link server using pinorder= (above)

Origen.app.pin_pattern_order is read to get the pin pattern order
and pass it to pinorder=


49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/origen_link/configuration_commands.rb', line 49

def set_pinorder
  pinlist = ''
  ordered_pins_cache.each do |pin|
    unless pin.is_a?(Hash)
      if pin.size == 1
        pinlist = pinlist + ',' unless pinlist.length == 0
        pinlist = pinlist + pin.name.to_s
      else
        dut.pins(pin.id).map.each do |sub_pin|
          pinlist = pinlist + ',' unless pinlist.length == 0
          pinlist = pinlist + sub_pin.name.to_s
        end
      end
    end
  end
  self.pinorder = pinlist
end

#tset_argstr_from_events(waves) ⇒ Object

tset_argstr_from_events(timing_waves)

consume timing wave info and return command argstr format
output: 10,data,tdi,tms;15,data,tck;25,0,tck;35,data,tms


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
# File 'lib/origen_link/configuration_commands.rb', line 160

def tset_argstr_from_events(waves)
  event_time = []
  event_setting = {}
  event_pins = {}
  waves.each do |w|
    # skip any events wave that does not have any associated pins
    unless w.pins.size == 0
      w.evaluated_events.each do |e|
        event_key = e[0].to_f		# time stamp for the event
        event_time << event_key
        event_setting[event_key] = [] unless event_setting.key?(event_key)
        event_setting[event_key] << e[1].to_s

        event_pins[event_key] = [] unless event_pins.key?(event_key)
        event_pins[event_key] << []
        w.pins.each do |p|
          event_pins[event_key].last << p.id.to_s if @pinmap_hash[p.id.to_s]
        end
      end
    end
  end
  # now sort the events into time order and build the tset argstr
  event_time.uniq!
  event_time.sort!
  rtnstr = ''
  event_time.each do |event_key|
    rtnstr = rtnstr + ';' unless rtnstr.length == 0
    event_setting[event_key].each_index do |i|
      pins = event_pins[event_key][i].uniq.join(',')
      rtnstr = rtnstr + ';' if i > 0
      rtnstr = rtnstr + event_key.to_s + ',' + event_setting[event_key][i] + ',' + pins if pins.length > 0
    end
  end
  rtnstr.gsub(/;+/, ';')
end

#tset_warning(tset) ⇒ Object

tset_warning(tset)

This method is used to display a no timing info warning.
The warning is displayed only once per tset that is
encountered


200
201
202
203
204
205
206
207
208
209
# File 'lib/origen_link/configuration_commands.rb', line 200

def tset_warning(tset)
  unless @tsets_warned.key?(tset)
    Origen.log.warn("No timing information provided for timeset :#{tset}")
    Origen.log.warn('Default timing will be used (pin operations are in pattern order)')
    Origen.log.warn('Specify timing through the timing api or by using:')
    Origen.log.warn("  tester.pinformat = 'func_25mhz,tclk,rl'")
    Origen.log.warn("  tester.pintiming = 'func_25mhz,tms,0,tdi,0,tdo,1'")
    @tsets_warned[tset] = true
  end
end