logictools
WaveDrom TutorialWaveDrom is a tool for rendering digital timing waveforms. The waveforms are defined in a simple textual format.
This notebook will show how to render digital waveforms using the pynq library.
The logictools
overlay uses the same format as WaveDrom to specify and generate real signals on the board.
A full tutorial of WaveDrom can be found here
In [1]:
from pynq.lib.logictools.waveform import draw_wavedrom
A simple function to add wavedrom diagrams into an jupyter notebook. It utilises the wavedrom java script library.
**Example usage:**
from pynq.lib.logictools.waveform import draw_wavedrom
clock = {'signal': [{'name': 'clk', 'wave': 'h....l...'}]}
draw_wavedrom(clock)
**Method:**
def draw_wavedrom(data, width=None):
# Note the optional argument width forces the width in pixels
In [2]:
clock = {'signal': [{'name': 'clock_0', 'wave': 'hlhlhlhlhlhlhlhl'}],
'foot': {'tock': 1},
'head': {'text': 'Clock Signal'}}
draw_wavedrom(clock)
Notes on waveform specification
In [3]:
pattern = {'signal': [{'name': 'clk', 'wave': 'hl' * 8},
{'name': 'clkn', 'wave': 'lh' * 8},
{'name': 'data0', 'wave': 'l.......h.......'},
{'name': 'data1', 'wave': 'h.l...h...l.....'}],
'foot': {'tock': 1},
'head': {'text': 'Pattern'}}
draw_wavedrom(pattern)
Notes on waveform specification
Adding multiple wave groups and spaces
In [4]:
pattern_group = {'signal': [['Group1',
{'name': 'clk', 'wave': 'hl' * 8},
{'name': 'clkn', 'wave': 'lh' * 8},
{'name': 'data0', 'wave': 'l.......h.......'},
{'name': 'data1', 'wave': 'h.l...h...l.....'}],
{},
['Group2',
{'name': 'data2', 'wave': 'l...h..l.h......'},
{'name': 'data3', 'wave': 'l.h.' * 4}]],
'foot': {'tock': 1},
'head': {'text': 'Pattern'}}
draw_wavedrom(pattern_group)
Notes on waveform specification
draw_waveform()
method on the dictionary populated by the Trace Analyzer to extend and modify the dictionary with annotations.In the example below, we are going to generate 3 signals on the Arduino interface pins D0, D1 and D2 using the Pattern Generator. Since all IOs are accessible to the Trace analyzer, we will capture the data on the pins as well. This operation will serve as an internal loopback.
In [5]:
from pynq.lib.logictools import Waveform
from pynq.overlays.logictools import LogicToolsOverlay
logictools_olay = LogicToolsOverlay('logictools.bit')
loopback_test = {'signal': [
['stimulus',
{'name': 'output0', 'pin': 'D0', 'wave': 'lh' * 8},
{'name': 'output1', 'pin': 'D1', 'wave': 'l.h.' * 4},
{'name': 'output2', 'pin': 'D2', 'wave': 'l...h...' * 2}],
{},
['analysis',
{'name': 'input0', 'pin': 'D0'},
{'name': 'input1', 'pin': 'D1'},
{'name': 'input2', 'pin': 'D2'}]],
'foot': {'tock': 1},
'head': {'text': 'loopback_test'}}
waveform = Waveform(loopback_test)
waveform.display()
Note: Since there are no captured samples at this moment, the analysis group will be empty.
Notes on the enhanced WaveJSON specification format
In [6]:
pattern_generator = logictools_olay.pattern_generator
pattern_generator.trace(num_analyzer_samples=16)
pattern_generator.setup(loopback_test,
stimulus_group_name='stimulus',
analysis_group_name='analysis')
pattern_generator.run()
pattern_generator.show_waveform()
In [7]:
import pprint
output_wavejson = pattern_generator.waveform.waveform_dict
pprint.pprint(output_wavejson)
In [8]:
state_list = ['S0', 'S1', 'S2', 'S3', 'S4', 'S5', 'S6', 'S7',
'S0', 'S1', 'S2', 'S3', 'S4', 'S5', 'S6', 'S7']
color_dict = {'white': '2', 'yellow': '3', 'orange': '4', 'blue': '5'}
output_wavejson['signal'].extend([{}, ['Annotation',
{'name': 'state',
'wave': color_dict['yellow'] * 8 +
color_dict['blue'] * 8,
'data': state_list}]])
Note: The color_dict is a color code map as defined by WaveDrom
In [9]:
draw_wavedrom(output_wavejson)