origen_arm_debug 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|