2.4. Digital tutorial

As presented in section 2.2, several file formats are supported. In the current section, all supported languages are presented for each example.

Note

For the json and jsonml file formats, the Wavedrom tutorial can be followed at the exception of steps 7 and 9.

The seventh step deals with skin, header, and footer. While the skin property is under development, the header and footer properties can advantageously be replaced with annotations.

The ninth step concerns the use of programming language to generate signals. As one could notice, the javascript language is messy and not intended for string manipulation. Undulate being a python module, one can leverage the true power of python to generate the desired signals.

2.4.1. digital signal

Let’s see how to generate your first digital waveform. First create a text file in which we will add the textual representation of the waveform with all possibilities of a digital signal. Each character in the wave string represents a single time step (clock period).

jsonml yaml toml

set the content of the file to

{signal: [
    {name: "digital", wave: "01.zx=ud.2.3.45XziIzmzM"}
]}

then generate an image with undulate

undulate -f svg -i step_1_dig.json -o step_1_dig.svg
_images/step_1_dig.json.svg

set the content of the file to

digital:
    wave: "01.zx=ud.2.3.45XziIzmzM"

then generate an image with undulate

undulate -f svg -i step_1_dig.yaml -o step_1_dig.svg
_images/step_1_dig.yaml.svg

set the content of the file to

digital.wave = "01.zx=ud.2.3.45XziIzmzM"

then generate an image with undulate

undulate -f svg -i step_1_dig.toml -o step_1_dig.svg
_images/step_1_dig.toml.svg

Note

  • “.” extends the previous symbol by one more period.

  • “i” is an impulse 1 -> 0 -> 1

  • “I” is an impulse 0 -> 1 -> 0

  • “m” is a metastability resolved to 0

  • “M” is a metastability resolved to 1

2.4.2. clocks

However, most digital design are synchronous. The reference being a clock let’s see how to define a clock.

At first a clock is normal digital signal with specific bricks for rising edge clocks or falling edge clocks.

jsonml yaml toml

set the content of the file to

{signal: [
    {name: "pclk", wave: "p........"},
    {name: "Pclk", wave: "P........"},
    {name: "nclk", wave: "n........"},
    {name: "Nclk", wave: "N........"},
    {},
    {name: 'clk0', wave: 'phnlPHNL' },
    {name: 'clk1', wave: 'xhlhLHl.' },
    {name: 'clk2', wave: 'hpHplnLn' },
    {name: 'clk3', wave: 'nhNhplPl' },
    {name: 'clk4', wave: 'xlh.L.Hx' },
]}

then generate an image with undulate

undulate -f svg -i step_2_dig.json -o step_2_dig.svg
_images/step_2_dig.json.svg

set the content of the file to

pclk:
    wave: "p......."
Pclk:
    wave: "P......."
nclk:
    wave: "n......."
Nclk:
    wave: "N......."
spacer:
    wave: ""
clk0:
    wave: "phnlPHNL"
clk1:
    wave: "xhlhLHl."
clk2:
    wave: "hpHplnLn"
clk3:
    wave: "nhNhplPl"
clk4:
    wave: "xlh.L.Hx"

then generate an image with undulate

undulate -f svg -i step_2_dig.yaml -o step_2_dig.svg
_images/step_2_dig.yaml.svg

set the content of the file to

pclk.wave   = "p......."
Pclk.wave   = "P......."
nclk.wave   = "n......."
Nclk.wave   = "N......."
spacer.wave = ""
clk0.wave   = "phnlPHNL"
clk1.wave   = "xhlhLHl."
clk2.wave   = "hpHplnLn"
clk3.wave   = "nhNhplPl"
clk4.wave   = "xlh.L.Hx"

then generate an image with undulate

undulate -f svg -i step_2_dig.toml -o step_2_dig.svg
_images/step_2_dig.toml.svg

Note

  • Upper case characters has an arrow on the edge of reference

  • notice the spacing with {}, spacer:, or spacer.wave = ""

    In yaml spacer can be an empty string or a string starting with spacer.
    For toml any string starting with spacer is considered as a spacer.
  • slewing is considered even for clock signals

Tip

try to modify the slew of signal by adding slewing: 18 attribute or slewing: 0

2.4.3. bus

It is common for busses to represent only a transition with the new value. The list of possible characters is the following: xX=23456789

x or X define any unknown value.
=23456789 are the same symbol with different background color
jsonml yaml toml

set the content of the file to

{signal: [
    {name: "clk", wave: "p.....|..."},
    {name: "data", wave: "x.345x|=.x", data: ["head", "body", "tail", "data"]}
    {},
    {name: 'request', wave: '0.1..0|1.0' },
    {name: 'acknowledge', wave: '1.....|01.' }
]}

then generate an image with undulate

undulate -f svg -i step_3_dig.json -o step_3_dig.svg
_images/step_3_dig.json.svg

set the content of the file to

clk:
    wave: "p.....|..."
data:
    wave: "x.345x|=.x"
    data: "head body tail data"
"":
    wave: ""
request:
    wave: "0.1..0|1.0"
acknowledge:
    wave: "1.....|01."

then generate an image with undulate

undulate -f svg -i step_3_dig.yaml -o step_3_dig.svg
_images/step_3_dig.yaml.svg

set the content of the file to

clk.wave         = "p.....|..."
data.wave        = "x.345x|=.x"
spacer.wave      = ""
request.wave     = "0.1..0|1.0"
acknowledge.wave = "1.....|01."

data.data   = "head body tail data"

then generate an image with undulate

undulate -f svg -i step_3_dig.toml -o step_3_dig.svg
_images/step_3_dig.toml.svg

Note

  • values of bus is defined in data attribute

    data could be either an array or a string where items
    are delimited by a space character

2.4.4. groups

In order to gather signals in a given context, or of a same protocol, groups can be nested.

jsonml yaml toml

set the content of the file to

{signal: [
    {name: "clk", wave: "p..Pp..P", slewing: 0},
    ["Master",
        {name: "io_address", wave: "x3.x4..x", data: "A1 A2"},
        {name: "io_wdata", wave: "x3.x....", data: "D1"},
        ["control",
            {name: "io_write", wave: "01.0...."},
            {name: "io_read", wave: "0...1..0"}
        ]
    ],
    {},
    ["Slave",
        {name: "io_rdata", wave: "x.....4x", data: "Q2"},
        ["control",
            {name: "io_valid", wave: "x01x0.1x"}
        ]
    ]
]}

then generate an image with undulate

undulate -f svg -i step_4_dig.json -o step_4_dig.svg
_images/step_4_dig.json.svg

set the content of the file to

clk:
    wave: "p..Pp..P"
    slewing: 0
Master:
    io_address:
        wave: "x3.x4..x"
        data:
            - "A1"
            - "A2"
    io_wdata:
        wave: "x3.x...."
        data: "D1"
    control:
        io_write:
            wave: "01.0...."
        io_read:
            wave: "0...1..0"
spacer:
    wave: ""
Slave:
    io_rdata:
        wave: "x.....4x"
        data: "Q2"
    control:
        io_valid:
        wave: "x01x0.1x"

then generate an image with undulate

undulate -f svg -i step_4_dig.yaml -o step_4_dig.svg
_images/step_4_dig.yaml.svg

set the content of the file to

clk.wave = "p..Pp..P"
clk.slewing = 0

[Master]
io_address.wave       = "x3.x4..x"
io_wdata.wave         = "x3.x...."
control.io_write.wave = "01.0...."
control.io_read.wave  = "0...1..0"

io_address.data = "A1 A2"
io_wdata.data   = "D1"

spacer.wave = ""

[Slave]
io_rdata.wave         = "x.....4x"
control.io_valid.wave = "x01x0.1x"

io_rdata.data = "Q2"

then generate an image with undulate

undulate -f svg -i step_4_dig.toml -o step_4_dig.svg
_images/step_4_dig.toml.svg

Note

Notice the conciseness of new languages such as toml or yaml. These languages have been designed to be less verbose than json and natively support comments.

Also notice the difference of implementation in jsonml compare to yaml/toml of groups: while in jsonml the name of the group is the first item of an array, in yaml and toml, a group is a key:value pair of an HashMap. The key is the name of the group, and the value is the content of the group.

Warning

With nested group, the name of the group take one extra row in height instead of adding a name beside an accolade delimiting signals of a same group (wavedrom). Thus the image grows vertically rather than horizontally.

Growing horizontally make the image look smaller when integrated inside a document. However, signals not being in a group being placed after a group will look as if they belong to it.

2.4.5. periods, duty cycle, and phase

Let’s suppose you have a frequency divider in your circuits. The description of its signals can tremendously expand as the frequency ratio grows. The only variation is the period.

For a pwm signal, the duty cycle will change from one cycle to another. It is somehow convenient to tell the list of duty_cycles.

And for inter-chip communication it is interesting to delay the clock with respect to the data sent. In other term, it is the phase of the signal which need to be changed.

jsonml yaml toml

set the content of the file to

{signal: [
    {name: "clk", wave: "P", repeat: 8, period: 2},
    {name: "data", wave: "x.3x=x4x5x=x5x=x", data: "RST NOP CAS INC NOP NOP NOP", phase: 0.5},
    {name: "Q", wave: "p", repeat: 8, period: 2, duty_cycles: [0.5, 0.5, 0.5, 0.25, 0.35, 0.35, 0.35, 0.35]}
]}

then generate an image with undulate

undulate -f svg -i step_5_dig.json -o step_5_dig.svg
_images/step_5_dig.json.svg

set the content of the file to

clk:
    wave: "P"
    repeat: 8
    period: 2
data:
    wave: "x.3x=x4x=x=x=x=x"
    data: "RST NOP CAS INC NOP NOP NOP"
    phase: 0.5
Q:
    wave: "p"
    repeat: 8
    period: 2
    duty_cycles: [0.5, 0.5, 0.25, 0.35, 0.35, 0.35, 0.35]

then generate an image with undulate

undulate -f svg -i step_5_dig.yaml -o step_5_dig.svg
_images/step_5_dig.yaml.svg

set the content of the file to

clk.wave   = "P"
clk.repeat = 8
clk.period = 2

data.wave  = "x.3x=x4x=x=x=x=x"
data.data  = "RST NOP CAS INC NOP NOP NOP"
data.phase = 0.5

Q.wave     = "p"
Q.repeat   = 8
Q.period   = 2
Q.duty_cycles = [0.5, 0.5, 0.25, 0.35, 0.35, 0.35, 0.35]

then generate an image with undulate

undulate -f svg -i step_5_dig.toml -o step_5_dig.svg
_images/step_5_dig.toml.svg

Tip

For repetitive patterns, use repeat with the number of repetition you desire.

Tip

If you desire to change the period from one cycle to another, use periods with a list of scaling factor as done for duty_cycles.

my_signal:
    periods: [0.25, 0.5, 0.75, 1, 1.25, 1.5, 2]

Tip

If you need to advance a signal rather than delaying it, use a negative value for phase.

my_signal:
    phase: -0.2