origen_link 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d1466528f6de1eb1b70731626991a685065ad6e0
4
- data.tar.gz: 06d3028a38164e75078b9865ec5a2ff63fb0b422
3
+ metadata.gz: 14d0facfcb04447ab5238b62f38ee31b4332e212
4
+ data.tar.gz: f68f21592acc3eb1dd48301cac3e220a742b789a
5
5
  SHA512:
6
- metadata.gz: 30db744c9d97bd49fe11988415c69b39ef9a71f14d54fb485209df8ca89247b7a2f52b1a917c93d74da167426d11dcb7a2a1d2da419e544e9bf1b40c94d6bcc2
7
- data.tar.gz: cb73f596dc2fdfd691b31722a232e67c9969b0346520e142aaf511cf289eabad94a65e3e029324d5cfad6ac510bdd8ce7c86ca09e1ff4013e7c09799583b5023
6
+ metadata.gz: e162fafd6a68753e03afb20a20cd6f779b7a25a5d50473711f83a9769955453c3e1259adfedd02a9b3c36f8077fc4d9823c68ed5f802b9a8ae8c049265070010
7
+ data.tar.gz: 8fd17ea6f4eb541a880e9c526d36d265ba3fdfc075e276bfd65b6f535f785a854b615b576df5f2467df791a23d57c27535eb912758bfec2c4e48ecf3930071ee
@@ -1,15 +1,18 @@
1
1
  #!/usr/bin/env ruby
2
2
  $LOAD_PATH.unshift(File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib'))
3
+ $LOAD_PATH.unshift(File.join(File.expand_path(File.dirname(__FILE__)), '..', 'config'))
3
4
  require 'socket'
4
5
  require 'origen_link/server/sequencer'
6
+ require 'version'
5
7
 
6
8
  server = TCPServer.open('', 12_777)
7
- puts 'server started'
8
9
  pinsequencer = OrigenLink::Server::Sequencer.new
10
+ pinsequencer.version = OrigenLink::VERSION
9
11
  remoteuser = ''
10
12
  remotehost = ''
11
13
  sessionactivity = Time.now
12
14
  sessionactive = false
15
+ puts "server version #{pinsequencer.version} started"
13
16
 
14
17
  loop do
15
18
  client = server.accept
data/config/version.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module OrigenLink
2
2
  MAJOR = 0
3
- MINOR = 2
3
+ MINOR = 3
4
4
  BUGFIX = 0
5
5
  DEV = nil
6
6
 
@@ -11,6 +11,10 @@ module OrigenLink
11
11
  @pinmap = pinmap.gsub(/\s+/, '')
12
12
  response = send_cmd('pin_assign', @pinmap)
13
13
  setup_cmd_response_logger('pin_assign', response)
14
+ # store pins to the pinmap hash, this is used to remove non-link pins
15
+ # from the pattern in cases where the app includes too many pins
16
+ pinmap_arr = @pinmap.split(',')
17
+ 0.step(pinmap_arr.size - 1, 2) { |p| @pinmap_hash[pinmap_arr[p]] = true }
14
18
  end
15
19
 
16
20
  # pinorder=
@@ -24,9 +28,40 @@ module OrigenLink
24
28
  # example:
25
29
  # tester.pinorder = 'tclk,tms,tdi,tdo'
26
30
  def pinorder=(pinorder)
27
- @pinorder = pinorder.gsub(/\s+/, '')
28
- response = send_cmd('pin_patternorder', @pinorder)
29
- setup_cmd_response_logger('pin_patternorder', response)
31
+ cmd = []
32
+ cmd << 'pin_patternorder'
33
+ cmd << pinorder.gsub(/\s+/, '')
34
+ @pinorder = cmd[1]
35
+ if @pinmap.nil?
36
+ @batched_setup_cmds << cmd
37
+ else
38
+ response = send_cmd(cmd[0], @pinorder)
39
+ setup_cmd_response_logger(cmd[0], response)
40
+ end
41
+ end
42
+
43
+ # set_pinorder
44
+ # This method is called if the app has not explicitly set the pin order
45
+ # for the Link server using pinorder= (above)
46
+ #
47
+ # Origen.app.pin_pattern_order is read to get the pin pattern order
48
+ # and pass it to pinorder=
49
+ def set_pinorder
50
+ pinlist = ''
51
+ ordered_pins_cache.each do |pin|
52
+ unless pin.is_a?(Hash)
53
+ if pin.size == 1
54
+ pinlist = pinlist + ',' unless pinlist.length == 0
55
+ pinlist = pinlist + pin.name.to_s
56
+ else
57
+ dut.pins(pin.id).map.each do |sub_pin|
58
+ pinlist = pinlist + ',' unless pinlist.length == 0
59
+ pinlist = pinlist + sub_pin.name.to_s
60
+ end
61
+ end
62
+ end
63
+ end
64
+ self.pinorder = pinlist
30
65
  end
31
66
 
32
67
  # pinformat=
@@ -36,9 +71,16 @@ module OrigenLink
36
71
  # example:
37
72
  # tester.pinformat = 'func_25mhz,tclk,rl'
38
73
  def pinformat=(pinformat)
39
- @pinformat = replace_tset_name_w_number(pinformat.gsub(/\s+/, ''))
40
- response = send_cmd('pin_format', @pinformat)
41
- setup_cmd_response_logger('pin_format', response)
74
+ cmd = []
75
+ cmd << 'pin_format'
76
+ cmd << replace_tset_name_w_number(pinformat.gsub(/\s+/, ''))
77
+ @pinformat = cmd[1]
78
+ if @pinmap.nil?
79
+ @batched_setup_cmds << cmd
80
+ else
81
+ response = send_cmd(cmd[0], @pinformat)
82
+ setup_cmd_response_logger(cmd[0], response)
83
+ end
42
84
  end
43
85
 
44
86
  # pintiming=
@@ -51,9 +93,119 @@ module OrigenLink
51
93
  # example:
52
94
  # tester.pintiming = 'func_25mhz,tms,0,tdi,0,tdo,1'
53
95
  def pintiming=(pintiming)
54
- @pintiming = replace_tset_name_w_number(pintiming.gsub(/\s+/, ''))
55
- response = send_cmd('pin_timing', @pintiming)
56
- setup_cmd_response_logger('pin_timing', response)
96
+ cmd = []
97
+ cmd << 'pin_timing'
98
+ cmd << replace_tset_name_w_number(pintiming.gsub(/\s+/, ''))
99
+ @pintiming = cmd[1]
100
+ if @pinmap.nil?
101
+ @batched_setup_cmds << cmd
102
+ else
103
+ response = send_cmd(cmd[0], @pintiming)
104
+ setup_cmd_response_logger(cmd[0], response)
105
+ end
106
+ end
107
+
108
+ # process_timeset(tset)
109
+ # This method will check the pin timing api for the current timeset.
110
+ # If the timset is programmed, it will be processed into the Link
111
+ # timing format, registered, and sent to the server.
112
+ # Else, a warning message will be displayed
113
+ #
114
+ # example generated command:
115
+ # send_cmd('pin_timingv2', '2,drive,5,data,tck;10,data,tdi|compare,35,data,tck,tdo;5,data,tdi')
116
+ def process_timeset(tset)
117
+ # Check to see if this timeset has been programmed
118
+ if dut.timesets(tset.to_sym).nil?
119
+ # Timset has not been programmed through the pin timing api
120
+ tset_warning(tset)
121
+ '' # return empty string on failure
122
+ else
123
+ # Timeset has been programmed
124
+ # accumulate and sort drive events
125
+ drive_str = tset_argstr_from_events(dut.timesets(tset.to_sym).drive_waves)
126
+
127
+ # accumulate and sort compare events
128
+ compare_str = tset_argstr_from_events(dut.timesets(tset.to_sym).compare_waves)
129
+
130
+ # construct the command argument string
131
+ argstr = get_tset_number(tset).to_s
132
+ if drive_str.length > 0
133
+ argstr = argstr + ',drive,' + drive_str
134
+ argstr = argstr + '|compare,' + compare_str if compare_str.length > 0
135
+ elsif compare_str.length > 0
136
+ argstr = argstr + ',compare,' + compare_str
137
+ else
138
+ fail "#{tset} timeset is programmed with no drive or compare edges"
139
+ end
140
+
141
+ # send the timeset information to the server
142
+ cmd = []
143
+ cmd << 'pin_timingv2'
144
+ cmd << argstr
145
+ if @pinmap.nil?
146
+ @batched_setup_cmds << cmd
147
+ else
148
+ response = send_cmd('pin_timingv2', argstr)
149
+ setup_cmd_response_logger('pin_timingv2', response)
150
+ end
151
+
152
+ # return the tset number from the tset hash
153
+ "tset#{@tsets_programmed[tset]},"
154
+ end
155
+ end
156
+
157
+ # tset_argstr_from_events(timing_waves)
158
+ # consume timing wave info and return command argstr format
159
+ # output: 10,data,tdi,tms;15,data,tck;25,0,tck;35,data,tms
160
+ def tset_argstr_from_events(waves)
161
+ event_time = []
162
+ event_setting = {}
163
+ event_pins = {}
164
+ waves.each do |w|
165
+ # skip any events wave that does not have any associated pins
166
+ unless w.pins.size == 0
167
+ w.evaluated_events.each do |e|
168
+ event_key = e[0].to_f # time stamp for the event
169
+ event_time << event_key
170
+ event_setting[event_key] = [] unless event_setting.key?(event_key)
171
+ event_setting[event_key] << e[1].to_s
172
+
173
+ event_pins[event_key] = [] unless event_pins.key?(event_key)
174
+ event_pins[event_key] << []
175
+ w.pins.each do |p|
176
+ event_pins[event_key].last << p.id.to_s if @pinmap_hash[p.id.to_s]
177
+ end
178
+ end
179
+ end
180
+ end
181
+ # now sort the events into time order and build the tset argstr
182
+ event_time.uniq!
183
+ event_time.sort!
184
+ rtnstr = ''
185
+ event_time.each do |event_key|
186
+ rtnstr = rtnstr + ';' unless rtnstr.length == 0
187
+ event_setting[event_key].each_index do |i|
188
+ pins = event_pins[event_key][i].uniq.join(',')
189
+ rtnstr = rtnstr + ';' if i > 0
190
+ rtnstr = rtnstr + event_key.to_s + ',' + event_setting[event_key][i] + ',' + pins if pins.length > 0
191
+ end
192
+ end
193
+ rtnstr.gsub(/;+/, ';')
194
+ end
195
+
196
+ # tset_warning(tset)
197
+ # This method is used to display a no timing info warning.
198
+ # The warning is displayed only once per tset that is
199
+ # encountered
200
+ def tset_warning(tset)
201
+ unless @tsets_warned.key?(tset)
202
+ Origen.log.warn("No timing information provided for timeset :#{tset}")
203
+ Origen.log.warn('Default timing will be used (pin operations are in pattern order)')
204
+ Origen.log.warn('Specify timing through the timing api or by using:')
205
+ Origen.log.warn(" tester.pinformat = 'func_25mhz,tclk,rl'")
206
+ Origen.log.warn(" tester.pintiming = 'func_25mhz,tms,0,tdi,0,tdo,1'")
207
+ @tsets_warned[tset] = true
208
+ end
57
209
  end
58
210
 
59
211
  # replace_tset_name_w_number(csl)
@@ -2,11 +2,17 @@ require 'origen_link/server/pin'
2
2
 
3
3
  module OrigenLink
4
4
  module Server
5
+ # The Jtag class is not part of the OrigenLink plug-in/server ecosystem.
6
+ # It implements standard jtag protocol. It can be used to implement a
7
+ # Jtag protocol server (not included in this repository presently).
5
8
  class Jtag
9
+ # The value read from TDO during the shift
6
10
  attr_reader :tdoval
11
+ # Enable extra output
7
12
  attr_accessor :verbose_enable
8
13
  attr_accessor :anytdofail
9
14
 
15
+ # Create the jtag pin objects
10
16
  def initialize(tdiio = 16, tdoio = 23, tmsio = 19, tckio = 26, tck_period = 0.000001)
11
17
  @tdipin = Pin.new(tdiio, :out)
12
18
  @tdopin = Pin.new(tdoio, :in)
@@ -19,10 +25,12 @@ module OrigenLink
19
25
  @anytdofail = false
20
26
  end
21
27
 
28
+ # not needed, no need for wait states between operations
22
29
  def tck_period=(value)
23
30
  @tck_half_period = value / 2
24
31
  end
25
32
 
33
+ # close out file IO objects for the pins
26
34
  def destroy
27
35
  @tdipin.destroy
28
36
  @tdopin.destroy
@@ -34,6 +42,7 @@ module OrigenLink
34
42
  @tckpin = nil
35
43
  end
36
44
 
45
+ # perform 1 jtag cycle
37
46
  def do_cycle(tdival, tmsval, capturetdo = false)
38
47
  @tdipin.out(tdival)
39
48
  @tmspin.out(tmsval)
@@ -47,11 +56,13 @@ module OrigenLink
47
56
  @tckpin.out(0)
48
57
  end
49
58
 
59
+ # advance state machine to test logic reset, then return to run/test idle
50
60
  def do_tlr
51
61
  8.times { do_cycle(0, 1) }
52
62
  do_cycle(0, 0)
53
63
  end
54
64
 
65
+ # shift a value in on tdi, optionall capture tdo
55
66
  def do_shift(numbits, value, capturetdo = false, suppresscomments = false, tdocompare = '')
56
67
  @tdoval = 0
57
68
  @tdostr = ''
@@ -98,6 +109,7 @@ module OrigenLink
98
109
  end
99
110
  end
100
111
 
112
+ # perform an ir-update
101
113
  def do_ir(numbits, value, options = {})
102
114
  defaults = {
103
115
  capturetdo: false,
@@ -130,6 +142,7 @@ module OrigenLink
130
142
  do_cycle(0, 0)
131
143
  end
132
144
 
145
+ # perform a dr update
133
146
  def do_dr(numbits, value, options = {})
134
147
  defaults = {
135
148
  capturetdo: true,
@@ -160,6 +173,7 @@ module OrigenLink
160
173
  do_cycle(0, 0)
161
174
  end
162
175
 
176
+ # traverse the pause dr state
163
177
  def pause_dr
164
178
  do_cycle(0, 1)
165
179
  do_cycle(0, 0)
@@ -171,6 +185,7 @@ module OrigenLink
171
185
  do_cycle(0, 0)
172
186
  end
173
187
 
188
+ # traverse the pause ir state
174
189
  def pause_ir
175
190
  do_cycle(0, 1)
176
191
  pause_dr
@@ -5,20 +5,31 @@
5
5
 
6
6
  module OrigenLink
7
7
  module Server
8
+ # The server pin class is used to perform IO using the UDOO pins
8
9
  class Pin
9
10
  @@pin_setup = {
10
11
  in: 'in',
11
12
  out: 'out'
12
13
  }
13
14
 
15
+ # True if this pin exists in /sys/class/gpio after export. False otherwise.
14
16
  attr_reader :gpio_valid
17
+ # This pin's vector data for the pattern cycle being executed
18
+ attr_accessor :pattern_data
19
+ # This pin's index in the vector data received from the plug-in app
20
+ attr_accessor :pattern_index
21
+ # This pin's response for the executing vector
22
+ attr_accessor :response
15
23
 
16
- # initialize:
17
- # description - This method will execute system command
18
- # "sudo echo ionumber > /sys/class/gpio/export"
19
- # to create the IO file interface. It will
20
- # set the direction, initial pin state and initialize
21
- # instance variables
24
+ # Export the pin io files through the system and take control of the IO
25
+ #
26
+ # This method will execute system command
27
+ # "echo #{ionumber} > /sys/class/gpio/export"
28
+ # to create the IO file interface. It will
29
+ # set the direction, initial pin state and initialize
30
+ # instance variables
31
+ #
32
+ # Receives
22
33
  # ionumber - required, value indicating the pin number (BCM IO number,
23
34
  # not the header pin number)
24
35
  # direction - optional, specifies the pin direction. A pin is
@@ -49,8 +60,94 @@ module OrigenLink
49
60
  end
50
61
  @pin_val_obj = File.open(@pin_val_name, 'r+') if @gpio_valid
51
62
  end
63
+ @pattern_data = ''
64
+ @pattern_index = -1
65
+ @response = 'W'
66
+ @cycle_failure = false
67
+ @data_is_drive = false
68
+ end
69
+
70
+ # data_is_drive?
71
+ # returns whether the current pattern data is drive
72
+ def data_is_drive?
73
+ @data_is_drive
74
+ end
75
+
76
+ # data_is_compare?
77
+ # returns whether the current pattern data is compare
78
+ def data_is_compare?
79
+ !@data_is_drive
52
80
  end
53
81
 
82
+ # cycle_failure
83
+ # returns a boolean indicating pass/fail status of this pin
84
+ def cycle_failure
85
+ if @response == 'W'
86
+ true # force failure if no operation performed
87
+ else
88
+ @cycle_failure
89
+ end
90
+ end
91
+
92
+ # load_pattern_data
93
+ # Grab this pin's data character from the pattern data
94
+ def load_pattern_data(cycle)
95
+ if @pattern_index > -1
96
+ @pattern_data = cycle[@pattern_index]
97
+ @response = 'W'
98
+ @cycle_failure = false
99
+ if @pattern_data == '1' || @pattern_data == '0'
100
+ @data_is_drive = true
101
+ else
102
+ @data_is_drive = false
103
+ end
104
+ else
105
+ @gpio_valid = false
106
+ end
107
+ end
108
+
109
+ # process_event(event)
110
+ # perform the requested pin operation and update the response (if required)
111
+ def process_event(operation, requested_action)
112
+ if operation == :drive
113
+ if data_is_drive?
114
+ if requested_action == 'data'
115
+ out(@pattern_data)
116
+ @response = @pattern_data
117
+ else
118
+ out(requested_action)
119
+ end # requested_action == 'data'
120
+ end # data_is_drive?
121
+ end # operation == :drive
122
+ if operation == :compare
123
+ if data_is_compare?
124
+ if requested_action == 'data'
125
+ case self.in
126
+ when '0'
127
+ @cycle_failure = true if @pattern_data == 'H'
128
+ if @pattern_data == 'X'
129
+ @response = '.'
130
+ else
131
+ @response = 'L'
132
+ end
133
+ # end of when '0'
134
+ when '1'
135
+ @cycle_failure = true if @pattern_data == 'L'
136
+ if @pattern_data == 'X'
137
+ @response = '`'
138
+ else
139
+ @response = 'H'
140
+ end
141
+ # end of when '1'
142
+ else
143
+ @response = 'W'
144
+ end # case
145
+ end # requested_action == 'data'
146
+ end # data_is_compare?
147
+ end # operation == :compare
148
+ end
149
+
150
+ # Close the file IO objects associated with this pin
54
151
  def destroy
55
152
  if @gpio_valid
56
153
  @pin_dir_obj.close
@@ -60,10 +157,10 @@ module OrigenLink
60
157
  end
61
158
  end
62
159
 
63
- # out:
64
- # description - Sets the output state of the pin. If the pin
65
- # is setup as an input, the direction will first
66
- # be changed to output.
160
+ # Sets the output state of the pin.
161
+ #
162
+ # If the pin is setup as an input,
163
+ # the direction will first be changed to output.
67
164
  #
68
165
  def out(value)
69
166
  if @gpio_valid
@@ -75,10 +172,10 @@ module OrigenLink
75
172
  end
76
173
  end
77
174
 
78
- # in:
79
- # description - Reads and returns state of the pin. If the pin
80
- # is setup as an output, the direction will first
81
- # be changed to input.
175
+ # Reads and returns state of the pin.
176
+ #
177
+ # If the pin is setup as an output, the direction will first
178
+ # be changed to input.
82
179
  #
83
180
  def in
84
181
  if @gpio_valid
@@ -95,11 +192,10 @@ module OrigenLink
95
192
  end
96
193
  end
97
194
 
98
- # update_direction:
99
- # description - Sets the pin direction
195
+ # Sets the pin direction
100
196
  #
101
- # direction - specifies the pin direction. A pin is
102
- # initialized as an input if a direction isn't specified.
197
+ # Receives:
198
+ # direction - specifies the pin direction. Input is default.
103
199
  #
104
200
  # Valid direction values:
105
201
  # :in - input
@@ -113,6 +209,7 @@ module OrigenLink
113
209
  end
114
210
  end
115
211
 
212
+ # Returns 'OrigenLinPin' + io number
116
213
  def to_s
117
214
  'OrigenLinkPin' + @ionumber.to_s
118
215
  end