@@ -307,6 +307,83 @@ def process_read(self, address, data, read_slack):
307
307
raise NotImplementedError
308
308
309
309
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
+
310
387
class SPIMasterHandler (WishboneHandler ):
311
388
def __init__ (self , vcd_manager , name ):
312
389
self .channels = {}
0 commit comments