origen_arm_debug 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 +59 -0
- data/config/commands.rb +51 -0
- data/config/development.rb +17 -0
- data/config/environment.rb +3 -0
- data/config/users.rb +19 -0
- data/config/version.rb +8 -0
- data/lib/origen_arm_debug.rb +16 -0
- data/lib/origen_arm_debug/abs_if_jtag.rb +255 -0
- data/lib/origen_arm_debug/abs_if_swd.rb +269 -0
- data/lib/origen_arm_debug/core_access_M4.rb +0 -0
- data/lib/origen_arm_debug/driver.rb +67 -0
- data/lib/origen_arm_debug/dut.rb +51 -0
- data/lib/origen_arm_debug/dut_jtag.rb +17 -0
- data/lib/origen_arm_debug/dut_swd.rb +14 -0
- data/lib/origen_arm_debug/jtag_ap.rb +0 -0
- data/lib/origen_arm_debug/jtag_dp.rb +0 -0
- data/lib/origen_arm_debug/mem_ap.rb +387 -0
- data/lib/origen_arm_debug/sw_dp.rb +0 -0
- data/lib/origen_arm_debug/swj_dp.rb +437 -0
- data/pattern/read_write_reg.rb +20 -0
- data/templates/web/index.md.erb +89 -0
- data/templates/web/layouts/_basic.html.erb +16 -0
- data/templates/web/partials/_navbar.html.erb +22 -0
- data/templates/web/release_notes.md.erb +5 -0
- metadata +126 -0
File without changes
|
@@ -0,0 +1,437 @@
|
|
1
|
+
module OrigenARMDebug
|
2
|
+
class SWJ_DP
|
3
|
+
include Origen::Registers
|
4
|
+
|
5
|
+
# Returns the parent object that instantiated the driver, could be
|
6
|
+
# either a DUT object or a protocol abstraction
|
7
|
+
attr_reader :owner
|
8
|
+
attr_reader :imp
|
9
|
+
attr_accessor :write_ap_dly
|
10
|
+
attr_accessor :acc_access_dly
|
11
|
+
|
12
|
+
# Initialize class variables
|
13
|
+
#
|
14
|
+
# @param [Object] owner Parent object
|
15
|
+
# @param [Hash] options Options to customize the operation
|
16
|
+
#
|
17
|
+
# @example
|
18
|
+
# # Create new SWD::Driver object
|
19
|
+
# DUT.new.arm_debug.swj_dp
|
20
|
+
#
|
21
|
+
def initialize(owner, implementation, options = {})
|
22
|
+
@owner = owner
|
23
|
+
|
24
|
+
if implementation == :jtag || implementation == :swd
|
25
|
+
@imp = implementation
|
26
|
+
else
|
27
|
+
msg = "SWJ-DP: '#{implementation}' implementation not supported. JTAG and SWD only"
|
28
|
+
Origen.log.error msg
|
29
|
+
|
30
|
+
# Just default to jtag for now
|
31
|
+
@imp = :jtag
|
32
|
+
end
|
33
|
+
|
34
|
+
@write_ap_dly = 8
|
35
|
+
@acc_access_dly = 7
|
36
|
+
|
37
|
+
@current_apaddr = 0
|
38
|
+
@orundetect = 0
|
39
|
+
|
40
|
+
add_reg :dpacc, 0x00, 35, rnw: { pos: 0 },
|
41
|
+
a: { pos: 1, bits: 2 },
|
42
|
+
data: { pos: 3, bits: 32 }
|
43
|
+
|
44
|
+
add_reg :apacc, 0x00, 35, rnw: { pos: 0 },
|
45
|
+
a: { pos: 1, bits: 2 },
|
46
|
+
data: { pos: 0, bits: 35 }
|
47
|
+
|
48
|
+
add_reg :reserved, 0x00, 32, data: { pos: 0, bits: 32 }
|
49
|
+
add_reg :ctrl_stat, 0x04, 32, data: { pos: 0, bits: 32 }
|
50
|
+
add_reg :select, 0x08, 32, data: { pos: 0, bits: 32 }
|
51
|
+
add_reg :rebuff, 0x0C, 32, data: { pos: 0, bits: 32 }
|
52
|
+
|
53
|
+
# jtag-dp only
|
54
|
+
add_reg :idcode, 0x00, 32, data: { pos: 0, bits: 32 }
|
55
|
+
add_reg :abort, 0x00, 35, rnw: { pos: 0 },
|
56
|
+
a: { pos: 1, bits: 2 },
|
57
|
+
data: { pos: 0, bits: 32 }
|
58
|
+
end
|
59
|
+
|
60
|
+
# Method to add additional Memory Access Ports (MEM-AP) with specified base address
|
61
|
+
#
|
62
|
+
# @param [Integer] name Short name for mem_ap that is being created
|
63
|
+
# @param [Integer] base_address Base address
|
64
|
+
#
|
65
|
+
# @examples
|
66
|
+
# arm_debug.add_mem_ap('alt_ahbapi', 0x02000000)
|
67
|
+
#
|
68
|
+
def add_mem_ap(name, base_address)
|
69
|
+
instance_variable_set("@#{name}", MemAP.new(self, base_address: base_address))
|
70
|
+
self.class.send(:attr_accessor, name)
|
71
|
+
end
|
72
|
+
|
73
|
+
#-------------------------------------
|
74
|
+
# DPACC Access API
|
75
|
+
#-------------------------------------
|
76
|
+
|
77
|
+
# Method to read from a Debug Port register
|
78
|
+
#
|
79
|
+
# @param [String] name Name of register to be read from
|
80
|
+
# Supports: 'IDCODE','ABORT','CTRL/STAT','SELECT','RDBUFF','WCR','RESEND'
|
81
|
+
# @param [Hash] options Options to customize the operation
|
82
|
+
# @option options [Integer] edata Value to compare read data against
|
83
|
+
def read_dp(name, options = {})
|
84
|
+
options = { r_attempts: 1, mask: 0xffffffff }.merge(options)
|
85
|
+
if @imp == :swd
|
86
|
+
read_dp_swd(name, options)
|
87
|
+
else
|
88
|
+
read_dp_jtag(name, options)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# Method to read from a Debug Port register and compare for an expected value
|
93
|
+
#
|
94
|
+
# @param [String] name Name of register to be read from
|
95
|
+
# Supports: 'IDCODE','ABORT','CTRL/STAT','SELECT','RDBUFF','WCR','RESEND'
|
96
|
+
# @param [Integer] edata Value to compare read data against
|
97
|
+
# @param [Hash] options Options to customize the operation
|
98
|
+
def read_expect_dp(name, edata, options = {})
|
99
|
+
options[:edata] = edata
|
100
|
+
read_dp(name, options)
|
101
|
+
end
|
102
|
+
|
103
|
+
# Method to write to a Debug Port register
|
104
|
+
#
|
105
|
+
# @param [String] name Name of register to be written to
|
106
|
+
# Supports: 'IDCODE','ABORT','CTRL/STAT','SELECT','RDBUFF','WCR','RESEND'
|
107
|
+
# @param [Integer] wdata Value to written
|
108
|
+
# @param [Hash] options Options to customize the operation
|
109
|
+
def write_dp(name, wdata, options = {})
|
110
|
+
options = { w_attempts: 1 }.merge(options)
|
111
|
+
if @imp == :swd
|
112
|
+
write_dp_swd(name, wdata, options)
|
113
|
+
else
|
114
|
+
write_dp_jtag(name, wdata, options)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# Method to write to and then read from a Debug Port register
|
119
|
+
#
|
120
|
+
# @param [String] name Name of register to be written to and read from
|
121
|
+
# Supports: 'IDCODE','ABORT','CTRL/STAT','SELECT','RDBUFF','WCR','RESEND'
|
122
|
+
# @param [Integer] wdata Value to written
|
123
|
+
# @param [Hash] options Options to customize the operation
|
124
|
+
def write_read_dp(name, wdata, options = {})
|
125
|
+
write_dp(name, wdata, options)
|
126
|
+
read_dp(name, options)
|
127
|
+
if @imp == :swd
|
128
|
+
cc "SW-DP: WR-32: name='#{name}', "\
|
129
|
+
"data=0x#{wdata.to_s(16).rjust(8, '0')}"
|
130
|
+
else
|
131
|
+
cc "JTAG-DP: WR-32: name='#{name}', "\
|
132
|
+
"data=0x#{wdata.to_s(16).rjust(8, '0')}"
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
#-------------------------------------
|
137
|
+
# APACC Access API
|
138
|
+
#-------------------------------------
|
139
|
+
|
140
|
+
# Method to read from a Access Port register
|
141
|
+
#
|
142
|
+
# @param [Integer] addr Address of register to be read from
|
143
|
+
# @param [Hash] options Options to customize the operation
|
144
|
+
# @option options [Integer] edata Value to compare read data against
|
145
|
+
def read_ap(addr, options = {})
|
146
|
+
rwb = 1
|
147
|
+
options = { r_attempts: 1 }.merge(options)
|
148
|
+
|
149
|
+
# Create another copy of options with select keys removed.
|
150
|
+
# This first read is junk so we do not want to store it or compare it.
|
151
|
+
junk_options = options.clone.delete_if do |key, val|
|
152
|
+
(key.eql?(:r_mask) && val.eql?('store')) || key.eql?(:compare_data)
|
153
|
+
end
|
154
|
+
|
155
|
+
apacc_access(addr, rwb, random, 0, junk_options)
|
156
|
+
read_dp('RDBUFF', options) # This is the real data
|
157
|
+
|
158
|
+
if @imp == :swd
|
159
|
+
cc "SW-AP: R-32: addr=0x#{addr.to_s(16).rjust(8, '0')}"
|
160
|
+
else
|
161
|
+
cc "JTAG-AP: R-32: addr=0x#{addr.to_s(16).rjust(8, '0')}"
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
# Method to read from a Access Port register and compare against specific value
|
166
|
+
#
|
167
|
+
# @param [Integer] addr Address of register to be read from
|
168
|
+
# @param [Integer] edata Value to compare read data against
|
169
|
+
# @param [Hash] options Options to customize the operation
|
170
|
+
def read_expect_ap(addr, edata, options = {})
|
171
|
+
options[:edata] = edata
|
172
|
+
read_ap(name, options)
|
173
|
+
end
|
174
|
+
alias_method :wait_read_expect_ap, :read_expect_ap
|
175
|
+
|
176
|
+
# Method to write to a Access Port register
|
177
|
+
#
|
178
|
+
# @param [Integer] addr Address of register to be read from
|
179
|
+
# @param [Integer] wdata Value to written
|
180
|
+
# @param [Hash] options Options to customize the operation
|
181
|
+
def write_ap(addr, wdata, options = {})
|
182
|
+
rwb = 0
|
183
|
+
options = { w_attempts: 1 }.merge(options)
|
184
|
+
apacc_access(addr, rwb, wdata, 0, options)
|
185
|
+
$tester.cycle(repeat: @write_ap_dly) if @imp == :jtag
|
186
|
+
if @imp == :swd
|
187
|
+
cc 'SW-AP: W-32: '\
|
188
|
+
"addr=0x#{addr.to_s(16).rjust(8, '0')}, "\
|
189
|
+
"data=0x#{wdata.to_s(16).rjust(8, '0')}"
|
190
|
+
else
|
191
|
+
cc 'JTAG-AP: W-32: '\
|
192
|
+
"addr=0x#{addr.to_s(16).rjust(8, '0')}, "\
|
193
|
+
"data=0x#{wdata.to_s(16).rjust(8, '0')}"
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
# Method to write to and then read from a Debug Port register
|
198
|
+
#
|
199
|
+
# @param [Integer] addr Address of register to be read from
|
200
|
+
# @param [Integer] wdata Value to written
|
201
|
+
# @param [Hash] options Options to customize the operation
|
202
|
+
def write_read_ap(addr, wdata, options = {})
|
203
|
+
write_ap(addr, wdata, options)
|
204
|
+
read_ap(addr, options)
|
205
|
+
if @imp == :swd
|
206
|
+
cc 'SW-AP: WR-32: '\
|
207
|
+
"addr=0x#{addr.to_s(16).rjust(8, '0')}, "\
|
208
|
+
"data=0x#{wdata.to_s(16).rjust(8, '0')}"
|
209
|
+
else
|
210
|
+
cc 'JTAG-AP: WR-32: '\
|
211
|
+
"addr=0x#{addr.to_s(16).rjust(8, '0')}, "\
|
212
|
+
"data=0x#{wdata.to_s(16).rjust(8, '0')}"
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
private
|
217
|
+
|
218
|
+
#-----------------------------------------------
|
219
|
+
# DPACC Access Implementation-Specific methods
|
220
|
+
#-----------------------------------------------
|
221
|
+
|
222
|
+
# Method to read from a Debug Port register with SWD protocol
|
223
|
+
#
|
224
|
+
# @param [String] name Name of register to be read from
|
225
|
+
# Supports: 'IDCODE','ABORT','CTRL/STAT','SELECT','RDBUFF','WCR','RESEND'
|
226
|
+
# @param [Hash] options Options to customize the operation
|
227
|
+
def read_dp_swd(name, options = {})
|
228
|
+
rwb = 1
|
229
|
+
case name
|
230
|
+
when 'IDCODE' then dpacc_access(name, rwb, random, options)
|
231
|
+
when 'ABORT' then Origen.log.error "#{name} #{@imp.to_s.upcase}-DP register is write-only!"
|
232
|
+
when 'CTRL/STAT' then dpacc_access(name, rwb, random, options)
|
233
|
+
when 'SELECT' then Origen.log.error "#{name} #{@imp.to_s.upcase}-DP register is write-only!"
|
234
|
+
when 'RDBUFF' then dpacc_access(name, rwb, random, options)
|
235
|
+
when 'WCR' then dpacc_access(name, rwb, random, options)
|
236
|
+
when 'RESEND' then dpacc_access(name, rwb, random, options)
|
237
|
+
else Origen.log.error "Unknown #{@imp.to_s.upcase}-DP register name #{name}"
|
238
|
+
end
|
239
|
+
cc "SW-DP: R-32: name='#{name}'"
|
240
|
+
end
|
241
|
+
|
242
|
+
# Method to read from a Debug Port register with JTAG protocol
|
243
|
+
#
|
244
|
+
# @param [String] name Name of register to be read from
|
245
|
+
# Supports: 'IDCODE','ABORT','CTRL/STAT','SELECT','RDBUFF','WCR','RESEND'
|
246
|
+
# @param [Hash] options Options to customize the operation
|
247
|
+
def read_dp_jtag(name, options = {})
|
248
|
+
rwb = 1
|
249
|
+
set_ir(name) if name == 'IDCODE'
|
250
|
+
case name
|
251
|
+
when 'IDCODE' then jtag.write_dr(random, size: 32)
|
252
|
+
when 'ABORT' then Origen.log.error "#{name} #{@imp.to_s.upcase}-DP register is write-only!"
|
253
|
+
when 'CTRL/STAT' then dpacc_access(name, rwb, random, options)
|
254
|
+
when 'SELECT' then dpacc_access(name, rwb, random, options)
|
255
|
+
when 'RDBUFF' then dpacc_access(name, rwb, random, options)
|
256
|
+
else Origen.log.error "Unknown #{@imp.to_s.upcase}-DP register name #{name}"
|
257
|
+
end
|
258
|
+
read_dp_jtag('RDBUFF', options) if name != 'IDCODE' && name != 'RDBUFF'
|
259
|
+
cc "JTAG-DP: R-32: name='#{name}'"
|
260
|
+
end
|
261
|
+
|
262
|
+
# Method to write to a Debug Port register with SWD protocol
|
263
|
+
#
|
264
|
+
# @param [String] name Name of register to be read from
|
265
|
+
# Supports: 'IDCODE','ABORT','CTRL/STAT','SELECT','RDBUFF','WCR','RESEND'
|
266
|
+
# @param [Integer] wdata Data to be written
|
267
|
+
# @param [Hash] options Options to customize the operation
|
268
|
+
def write_dp_swd(name, wdata, options = {})
|
269
|
+
rwb = 0
|
270
|
+
case name
|
271
|
+
when 'IDCODE' then Origen.log.error "#{name} #{@imp.to_s.upcase}-DP register is read-only!"
|
272
|
+
when 'ABORT' then dpacc_access(name, rwb, wdata, options)
|
273
|
+
when 'CTRL/STAT' then dpacc_access(name, rwb, wdata, options)
|
274
|
+
when 'SELECT' then dpacc_access(name, rwb, wdata, options)
|
275
|
+
when 'RDBUFF' then Origen.log.error "#{name} #{@imp.to_s.upcase}-DP register is read-only!"
|
276
|
+
when 'WCR' then dpacc_access(name, rwb, wdata, options)
|
277
|
+
when 'RESEND' then Origen.log.error "#{name} #{@imp.to_s.upcase}-DP register is read-only!"
|
278
|
+
else Origen.log.error "Unknown #{@imp.to_s.upcase}-DP register name #{name}"
|
279
|
+
end
|
280
|
+
cc "SW-DP: W-32: name='#{name}', "\
|
281
|
+
"data=0x#{wdata.to_s(16).rjust(8, '0')}"
|
282
|
+
end
|
283
|
+
|
284
|
+
# Method to write to a Debug Port register with JTAG protocol
|
285
|
+
#
|
286
|
+
# @param [String] name Name of register to be read from
|
287
|
+
# Supports: 'IDCODE','ABORT','CTRL/STAT','SELECT','RDBUFF','WCR','RESEND'
|
288
|
+
# @param [Integer] wdata Data to be written
|
289
|
+
# @param [Hash] options Options to customize the operation
|
290
|
+
def write_dp_jtag(name, wdata, options = {})
|
291
|
+
rwb = 0
|
292
|
+
case name
|
293
|
+
when 'IDCODE' then Origen.log.error "#{name} #{@imp.to_s.upcase}-DP register is read-only!"
|
294
|
+
when 'ABORT' then dpacc_access(name, rwb, wdata, options)
|
295
|
+
when 'CTRL/STAT' then dpacc_access(name, rwb, wdata, options)
|
296
|
+
when 'SELECT' then dpacc_access(name, rwb, wdata, options)
|
297
|
+
when 'RDBUFF' then Origen.log.error "#{name} #{@imp.to_s.upcase}-DP register is read-only!"
|
298
|
+
else Origen.log.error "Unknown #{@imp.to_s.upcase}-DP register name #{name}"
|
299
|
+
end
|
300
|
+
cc "JTAG-DP: W-32: name='#{name}', "\
|
301
|
+
"data=0x#{wdata.to_s(16).rjust(8, '0')}"
|
302
|
+
end
|
303
|
+
|
304
|
+
def dpacc_access(name, rwb, wdata, options = {})
|
305
|
+
addr = get_dp_addr(name)
|
306
|
+
|
307
|
+
if name == 'CTRL/STAT' && @imp == :swd
|
308
|
+
set_apselect(@current_apaddr & 0xFFFFFFFE, options)
|
309
|
+
end
|
310
|
+
set_ir(name) if @imp == :jtag
|
311
|
+
acc_access(addr, rwb, 0, wdata, options)
|
312
|
+
end
|
313
|
+
|
314
|
+
def apacc_access(addr, rwb, wdata, rdata, options = {})
|
315
|
+
set_apselect((addr & 0xFFFFFFFE) | (@current_apaddr & 1), options)
|
316
|
+
if @imp == :swd
|
317
|
+
options.delete(:w_delay) if options.key?(:w_delay)
|
318
|
+
else
|
319
|
+
set_ir('APACC')
|
320
|
+
end
|
321
|
+
acc_access((addr & 0xC), rwb, 1, wdata, options)
|
322
|
+
end
|
323
|
+
|
324
|
+
def acc_access(addr, rwb, ap_dp, wdata, options = {})
|
325
|
+
if @imp == :swd
|
326
|
+
acc_access_swd(addr, rwb, ap_dp, wdata, options = {})
|
327
|
+
else
|
328
|
+
acc_access_jtag(addr, rwb, ap_dp, wdata, options = {})
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
332
|
+
def acc_access_swd(addr, rwb, ap_dp, wdata, options = {})
|
333
|
+
if (rwb == 1)
|
334
|
+
swd.read(ap_dp, addr, options)
|
335
|
+
else
|
336
|
+
swd.write(ap_dp, addr, wdata, options)
|
337
|
+
end
|
338
|
+
options = { w_delay: 10 }.merge(options)
|
339
|
+
swd.swd_dio_to_0(options[:w_delay])
|
340
|
+
end
|
341
|
+
|
342
|
+
def acc_access_jtag(addr, rwb, ap_dp, wdata, options = {})
|
343
|
+
if !options[:r_attempts].nil?
|
344
|
+
attempts = options[:r_attempts]
|
345
|
+
elsif !options[:r_attempts].nil?
|
346
|
+
attempts = options[:w_attempts]
|
347
|
+
else
|
348
|
+
attempts = 1
|
349
|
+
end
|
350
|
+
|
351
|
+
attempts.times do
|
352
|
+
if name == 'RDBUFF'
|
353
|
+
r = $dut.reg(:dap)
|
354
|
+
if options[:r_mask] == 'store'
|
355
|
+
r.bits(3..34).store
|
356
|
+
elsif options.key?(:compare_data)
|
357
|
+
r.bits(3..34).data = options[:compare_data]
|
358
|
+
end
|
359
|
+
|
360
|
+
options = options.merge(size: r.size)
|
361
|
+
jtag.read_dr(r, options)
|
362
|
+
else
|
363
|
+
options = options.merge(size: 35)
|
364
|
+
addr_3_2 = (addr & 0x0000000C) >> 2
|
365
|
+
wr_data = (wdata << 3) | (addr_3_2 << 1) | rwb
|
366
|
+
jtag.write_dr(wr_data, options)
|
367
|
+
end
|
368
|
+
end
|
369
|
+
$tester.cycle(repeat: @acc_access_dly)
|
370
|
+
end
|
371
|
+
|
372
|
+
def get_dp_addr(name)
|
373
|
+
case name
|
374
|
+
when 'IDCODE' then return 0x0
|
375
|
+
when 'ABORT' then return 0x0
|
376
|
+
when 'CTRL/STAT' then return 0x4
|
377
|
+
when 'SELECT' then return 0x8
|
378
|
+
when 'RDBUFF' then return 0xC
|
379
|
+
when 'WCR' then return 0x4
|
380
|
+
when 'RESEND' then return 0x8
|
381
|
+
else Origen.log.error "Unknown #{@imp.to_s.upcase}-DP register name #{name}"
|
382
|
+
end
|
383
|
+
end
|
384
|
+
|
385
|
+
def set_ir(name)
|
386
|
+
new_ir = get_ir_code(name)
|
387
|
+
jtag.write_ir(new_ir, size: 4)
|
388
|
+
end
|
389
|
+
|
390
|
+
def get_ir_code(name)
|
391
|
+
case name
|
392
|
+
when 'IDCODE' then return 0b1110 # JTAGC_ARM_IDCODE
|
393
|
+
when 'ABORT' then return 0b1000 # JTAGC_ARM_ABORT
|
394
|
+
when 'CTRL/STAT' then return 0b1010 # JTAGC_ARM_DPACC
|
395
|
+
when 'SELECT' then return 0b1010 # JTAGC_ARM_DPACC
|
396
|
+
when 'RDBUFF' then return 0b1010 # JTAGC_ARM_DPACC
|
397
|
+
when 'RESEND' then Origen.log.error "#{name} is a SW-DP only register"
|
398
|
+
when 'WCR' then Origen.log.error "#{name} is a SW-DP only register"
|
399
|
+
when 'APACC' then return 0b1011 # JTAGC_ARM_APACC
|
400
|
+
else Origen.log.error "Unknown JTAG-DP register name: #{name}"
|
401
|
+
end
|
402
|
+
0
|
403
|
+
end
|
404
|
+
|
405
|
+
def set_apselect(addr, options = {})
|
406
|
+
if @imp == :swd
|
407
|
+
addr &= 0xff0000f1
|
408
|
+
else
|
409
|
+
addr &= 0xff0000f0
|
410
|
+
end
|
411
|
+
|
412
|
+
if (addr != @current_apaddr)
|
413
|
+
write_dp('SELECT', addr & 0xff0000ff, options)
|
414
|
+
end
|
415
|
+
@current_apaddr = addr
|
416
|
+
end
|
417
|
+
|
418
|
+
# Generates 32-bit random number. Although, for pattern comparison
|
419
|
+
# it is better to used the same value so that is what is used here.
|
420
|
+
# To turn on random-ness, un-comment rand() line.
|
421
|
+
def random
|
422
|
+
# rand(4294967295) # random 32-bit integer
|
423
|
+
# 0x55555555 # completely unroll jtag data shift
|
424
|
+
0x00000000 # compress read out jtag shifts
|
425
|
+
end
|
426
|
+
|
427
|
+
# Provides shortname access to top-level jtag driver
|
428
|
+
def jtag
|
429
|
+
owner.owner.jtag
|
430
|
+
end
|
431
|
+
|
432
|
+
# Provides shortname access to top-level swd driver
|
433
|
+
def swd
|
434
|
+
owner.owner.swd
|
435
|
+
end
|
436
|
+
end
|
437
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Pattern.create do
|
2
|
+
|
3
|
+
ss "Test write register, should write value 0xFF01"
|
4
|
+
$dut.reg(:test).write!(0xFF01)
|
5
|
+
ss "Test read register, should read value 0xFF01"
|
6
|
+
$dut.reg(:test).read!
|
7
|
+
ss "Test bit level read, should read value 0xXXXxxx1"
|
8
|
+
$dut.reg(:test).bit(:bit).read!
|
9
|
+
|
10
|
+
|
11
|
+
$dut.read_register($dut.reg(:test))
|
12
|
+
$dut.write_register($dut.reg(:test), 0xFF02)
|
13
|
+
|
14
|
+
|
15
|
+
$dut_swd.arm_debug.swj_dp.read_dp("IDCODE");
|
16
|
+
$dut_swd.arm_debug.swj_dp.write_read_dp("CTRL/STAT", 0x50000000, edata: 0xf0000000);
|
17
|
+
$dut_swd.arm_debug.swj_dp.read_ap(0x010000FC);
|
18
|
+
$dut_swd.arm_debug.swj_dp.write_read_ap(0x01000004, 0x10101010);
|
19
|
+
|
20
|
+
end
|