Skip to content

Commit b76b238

Browse files
committed
comm_analyzer: analyze generic Wishbone PHYs
Add generic handler for Wishbone PHY devices, that will save the bus transactions to a VCD file. Signed-off-by: Drew Risinger <[email protected]>
1 parent 6d26def commit b76b238

File tree

1 file changed

+77
-0
lines changed

1 file changed

+77
-0
lines changed

artiq/coredevice/comm_analyzer.py

+77
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,83 @@ def process_read(self, address, data, read_slack):
307307
raise NotImplementedError
308308

309309

310+
class GenericWishboneHandler(WishboneHandler):
311+
"""Generic Wishbone Bus Data Handler.
312+
313+
Useful for testing out-of-tree PHY devices and viewing their bus transactions
314+
in a VCD file.
315+
"""
316+
317+
comm_buses_and_width = {
318+
"out_address": 8,
319+
"out_data": 32,
320+
"out_stb": 1,
321+
"in_data": 14,
322+
"in_stb": 1
323+
}
324+
def __init__(self, vcd_manager, name, channel):
325+
"""Create the Wishbone Data Handler.
326+
327+
Args:
328+
vcd_manager (VCDManager): VCD Manager to add this device's channels to.
329+
name (str): Name of the coredevice that communicates on this channel.
330+
"""
331+
self.channels = {}
332+
with vcd_manager.scope("bus_device/{}(chan{})".format(name, channel)):
333+
for bus_name, bus_width in self.comm_buses_and_width.items():
334+
self.channels[bus_name] = vcd_manager.get_channel(
335+
"{}/{}".format(name, bus_name),
336+
bus_width
337+
)
338+
339+
def set_channel(self, channel_name, value):
340+
"""Set channel to a specific value.
341+
342+
Formats the data properly for interpretation by VCD viewer
343+
(on a per-channel basis).
344+
345+
Args:
346+
channel_name (str): Name of the channel to write
347+
value (int): Value to be stored to VCD. Should be some sort of integer.
348+
"""
349+
# format all outputs as binary of proper length
350+
chan_fmt_string = "{{:0{}b}}".format(self.comm_buses_and_width[channel_name])
351+
self.channels[channel_name].set_value(chan_fmt_string.format(value))
352+
353+
def process_message(self, message):
354+
"""Process a Wishbone message into VCD events.
355+
356+
Args:
357+
message (typing.Union[InputMessage, OutputMessage]):
358+
A message from the coredevice, either an InputMessage
359+
(signal from PHY to coredevice) or an OutputMessage
360+
(signal from coredevice to PHY).
361+
"""
362+
# TODO: doesn't reset bus (addr/data) to 0 after bus transaction is done
363+
# TODO: stb doesn't display width, but edges register when jumping through waveform
364+
if isinstance(message, OutputMessage):
365+
logger.debug(
366+
"Wishbone out @%d adr=0x%02x data=0x%08x",
367+
message.timestamp,
368+
message.address,
369+
message.data
370+
)
371+
self.set_channel("out_stb", 1)
372+
self.set_channel("out_stb", 0)
373+
self.set_channel("out_address", message.address)
374+
self.set_channel("out_data", message.data)
375+
elif isinstance(message, InputMessage):
376+
logger.debug(
377+
"Wishbone in @%d(ts=%d) data=0x%08x",
378+
message.rtio_counter,
379+
message.timestamp,
380+
message.data
381+
)
382+
self.set_channel("in_data", message.data)
383+
self.set_channel("in_stb", 1)
384+
self.set_channel("in_stb", 0)
385+
386+
310387
class SPIMasterHandler(WishboneHandler):
311388
def __init__(self, vcd_manager, name):
312389
self.channels = {}

0 commit comments

Comments
 (0)