WaveDrom-rs
This is the book for wavedrom-rs
. It provides a reference on the
features of wavedrom-rs
and aims to be an extension of the original
Hitcherhiker's Guide to WaveDrom.
This book teaches you how to generate beautiful Digital Timing Diagrams such as the one illustrated below. These diagrams are easy to edit and extend.
{
signal: [
{ name: "clk", wave: "p........." },
{ name: "req", wave: "010......." },
{ name: "done", wave: "0......10." },
{
name: "state",
wave: "==.=.=.==.",
data: [ 'Idle', 'Fetch', 'Calculate', 'Process', 'Return', 'Idle' ]
}
]
}
This book has sections.
- Installation of
wavedrom-rs
for different environments - Capabilities of
wavedrom-rs
Note on WaveDrom-js
Wavedrom-rs is a port of a JavaScript implementation with the same name. This project is not officially associated with that project, but does try to be an complete replacement for the Digital Timing Diagram part of this project.
This project currently supports all features of the JavaScript project with exception of:
- JavaScript skins
- Custom tspans through JsonML in headers and footers
There is currently no plan to implement these features.
In turn, wavedrom-rs improves on its JavaScript counterpart in several areas.
- Proper handling of UTF-8 character widths
- Minimization of SVG in several areas
- More customization editor
- More correct rendering of edges
- JSON skins
Rust Crate
Wavedrom-rs can be used as a Rust crate to programmatically generate diagrams. The documentation for this can be found at docs.rs.
Command-Line Interface
There is an official Command-Line Interface for wavedrom that can easily be incorporated into scripts or workflows. This binary is available from the GitHub releases.
A binary can be downloaded from here and be put into a location corresponding to a operating system.
For Mac and Linux, /usr/bin/local
is a good place to store the binary.
Compilation from source
It is possible to compile from the GitHub directory. This generates the most
up-to-date binary, but may be less stable. This requires git
and the Rust
toolchain cargo
to be installed.
git clone https://github.com/coastalwhite/wavedrom-rs
cargo install --path=./wavedrom
Editor Website
The editor website uses WebAssembly to run a only instance of wavedrom. It also allows easy customization, importation and exportation of skins. The official instance can be found here.
MdBook Preprocessor
This offers an integration for wavedrom-rs with mdbook.
Getting started
First, install the preprocessor utilizing the Rust Toolchain.
cargo install mdbook-wavedrom-rs
Then, add the preprocessor to the list of preprocessors in your mdbook
configuration file book.toml
.
# book.toml
[preprocessor.wavedrom-rs]
Afterwards, you should be able to add a wavedrom
codeblock, which should
automatically get replaced by a wavedrom-rs diagram when building the
mdbook.
# Chapter 1
```wavedrom
{
signal: [
{ name: "clk", wave: "p......." },
{ name: "pulses", wave: "0..10.10" },
]
}
```
Add a skin
A WaveDrom skin can be added by adding a path to a skin file in the skin
property.
# book.toml
[preprocessor.wavedrom-rs]
skin = "path/to/skin.json5"
GitHub CI
To incorporate wavedrom-rs into your CI/CD workflow you can download and run
the Command-Line Interface. This is done with the following code.
Remember to replace the file.svg
and diagram.svg
with your desired input
and output file.
- name: WaveDrom-rs render
run: |
curl -sLO https://github.com/coastalwhite/wavedrom-rs/releases/download/v0.1.0/wavedrom-x86_64-unknown-linux-gnu.tar.xz
tar xvf wavedrom-x86_64-unknown-linux-gnu.tar.xz
chmod +x wavedrom-x86_64-unknown-linux-gnu/wavedrom
mv wavedrom-x86_64-unknown-linux-gnu/wavedrom /usr/local/bin/wavedrom
wavedrom -i file.json -o diagram.svg
The same can be done for the MdBook Preprocessor. Afterwards, it can be used by mdbook as a preprocessor.
- name: WaveDrom-rs MdBook
run: |
curl -sLO https://github.com/coastalwhite/wavedrom-rs/releases/download/v0.1.0/mdbook-wavedrom-rs-x86_64-unknown-linux-gnu.tar.xz
tar xvf mdbook-wavedrom-rs-x86_64-unknown-linux-gnu.tar.xz
chmod +x mdbook-wavedrom-rs-x86_64-unknown-linux-gnu/mdbook-wavedrom-rs
mv mdbook-wavedrom-rs-x86_64-unknown-linux-gnu/mdbook-wavedrom-rs /usr/local/bin/mdbook-wavedrom-rs
Signal Types
This section lists all the different signal types.
Top & Bottom
The Top and Bottom signals correspond to the logical on and off states. They
are represented by a 1
and 0
. Transitions to and from these states takes a
certain amount of time.
{
signal: [
{ wave: "101010101" },
{ wave: "000111110" },
// You can create a vertical gap with an empty signal
{},
// You can continue a signal with '.'
{ wave: "1.0.1.0.1" },
]
}
Clock
Clock Signals are periodic signals. There are several ways to manage a close signal.
- Positive edge clock with
p
andP
- Negative edge clock with
n
andN
- Manual positive edge or High with
h
orH
- Manual negitive edge or Low with
l
orL
The state's case determines whether to place a edge marker.
- Lowercase does NOT contain a edge marker
- Uppercase does contain a edge marker
The period of a clock signal can be controlled with the period
option. Any
fractional period will get rounded up to an integer.
{
signal: [
{ name: "posedge clk", wave: "p......." },
{ name: "posedge clk marked", wave: "P......." },
{ name: "posedge clk period=2", wave: "p.", period: 4 },
{},
{ name: "negedge clk", wave: "n......." },
{ name: "negedge clk marked", wave: "N......." },
{ name: "negedge clk period=2", wave: "n...", period: 2 },
{},
{ name: "manual", wave: "hlh.l..." },
{ name: "manual marked", wave: "HLH.L..." },
]
}
High Impedance & Undefined
The High Impedance is given by a z
and is represented by a straight
centered line. The Undefined is given by a x
and is represented by hatch
pattern.
A Undefined line needs to be extended with a .
to avoid a transition.
{
signal: [
{ name: "data", wave: "0z..1z.x.." },
{ name: "response", wave: "0x..1x.z.." },
]
}
Data Types
To display general data in signal, we have the data
property and several
states that can contain data. The data states corresponding to the numbers 2
to 9
with different background colors. Similarly, the =
state can also be
used as a data state. The data
property defines the data that goes into the
data states. If the data
property is given a string, the string is split
over whitespace and filled into states. The data
property can also be defined
with an array.
Data states need to be extended using the .
state, otherwise it is transited
to a new data state.
{
signal: [
{ name: "data states", wave: "023456789=0" },
{ name: "with text", wave: "023456789=0", data: "a b c d e f g h i" },
{},
{ name: "continued", wave: "2..2..2....", data: [
"First State",
"Second State",
"Third State",
]}
]
}
Gaps
Gaps in the signal can be added with the |
state. This extends the previous
signal by one and placed a gap indicator over extension cycle.
{
signal: [
{ name: "clk", wave: "p..|.." },
{ name: "req", wave: "010|.." },
{ name: "done", wave: "0..|10" },
]
}
Up & Down
The Up and Down states are used to gradually transition to a logical 1
and
0
. Up and Down are represented with a u
and d
.
{
signal: [
{ name: "up", wave: "0..u..0..u" },
{ name: "down", wave: "1.d.1.d..1" },
]
}
Signal Groups
A sequence of signals can be grouped by putting them into an array. A name / label for the group can also be added by starting the array with a string.
{
signal: [
[
"group",
{ name: "A", wave: "p...." },
[
"embed",
{ name: "B", wave: "2...." },
{ name: "C", wave: "3...." },
],
],
[
{ name: "D", wave: "4...." },
{ name: "E", wave: "5...." },
]
]
}
Header & Footer
Both the head
and the foot
properties can be used to add header and footer
text.
{
signal: [
{ name: "A", wave: "2....." },
{ name: "B", wave: "3....." },
{ name: "C", wave: "4....." },
{ name: "D", wave: "5....." },
{ name: "E", wave: "6....." },
],
head: {
text: "Hello World!",
},
foot: {
text: "Bye World!",
}
}
Cycle Enumeration Marker
The head.tick
and the foot.tock
properties can be set to add cycle
enumeration markers. The every
property defines every how many cycles a
marker should be put.
{
signal: [
{ name: "A", wave: "2....." },
{ name: "B", wave: "3....." },
{ name: "C", wave: "4....." },
{ name: "D", wave: "5....." },
{ name: "E", wave: "6....." },
],
head: {
tick: 42,
},
foot: {
tock: 1,
every: 2,
}
}
Edges
Edges or arrows can be used to better highlight certain properties of the
diagram. An edge is defined as between two nodes. Nodes are defined on signals
and then edges are defined as <start><type><end> [label]
in the edge
property.
{ signal: [
{ name: 'A', wave: '01........0.', node: '.a........j' },
{ name: 'B', wave: '0.1.......0.', node: '..b.......i' },
{ name: 'C', wave: '0..1....0...', node: '...c....h..' },
{ name: 'D', wave: '0...1..0....', node: '....d..g...' },
{ name: 'E', wave: '0....10.....', node: '.....ef....' }
],
edge: [
'a~b t1', 'c-~a t2', 'c-~>d time 3', 'd~-e',
'e~>f', 'f->g', 'g-~>h', 'h~>i some text', 'h~->j'
]
}
There are several types of arrows.
Identifier | Type | Property |
---|---|---|
~ | Spline | Start and ending horizontal |
-~ | Spline | Start horizontal |
~- | Spline | Ending horizontal |
- | Sharp | Shortest path |
+ | Sharp | Shortest path with bars |
`- | -` | Sharp |
`- | ` | Sharp |
` | -` | Sharp |
For all except the +
the <
and >
can be appended to add arrows at the
beginning and the end.
Skins
Skins allow customization of font sizes, colors, dimensions, paddings and spacings. Skins are created with a JSON that can contain any subset of the assemble and render options.
A template skin
file
can be found in the repository. Skins can also be previewed, edited and exported
from the editor by opening the Render Settings
.