← Back to Guides
DiagramsWaveDrom Timing Diagrams
Published on 2026-02-22

WaveDrom Timing Diagrams

How to use WaveDrom to draw digital timing diagrams, waveforms, and CPU architectures in Markdown.

WaveDrom is a specialized engine designed specifically for electronic engineers, hardware designers, and embedded software developers. It draws digital timing diagrams, logic waveforms, and register architectures using a simple JSON syntax.

To use it, wrap valid WaveDrom JSON in a wavedrom language block.

Digital Waveforms

WaveDrom uses single-character text strings to indicate the state of a digital signal over time (clock cycles).

  • 0 or L: Low Level
  • 1 or H: High Level
  • p or P: Positive clock edge (pulse)
  • n or N: Negative clock edge (pulse)
  • x: Unknown / Don’t Care state
  • z: High Impedance state
  • =: Data / Valid bus value

Basic Example

syntax
{ "signal": [
  {"name": "clk", "wave": "p....."},
  {"name": "data", "wave": "x345x.", "data": "head body tail"},
  {"name": "req", "wave": "01..0."},
  {"name": "ack", "wave": "1..01."}
]}
WaveDromWaveDrom diagram

The "wave" string tells WaveDrom what the signal does at each time step. The "data" array provides labels when bus states (like 3, 4, 5, or =) are used.

Adding Spacers and Grouping

You can group related signals together using an array inside the "signal" array. The first element of the sub-array becomes the group’s label. To add empty space between groups or signals, insert {}.

syntax
{ "signal": [
    {"name": "clk", "wave": "p......" },
    {},
    ["Master",
      {"name": "ctrl", "wave": "x1.0..x" },
      {"name": "addr", "wave": "x=.x..x", "data": "A1"}
    ],
    {},
    ["Slave",
      {"name": "ctrl", "wave": "x0.1..x" },
      {"name": "data", "wave": "x..=.0x", "data": "D1"}
    ]
]}
WaveDromWaveDrom diagram

Adding Arrows and Phase Edges

WaveDrom allows you to draw arrows between specific clock cycles to indicate causality (e.g., Signal B goes high because Signal A went high).

You tag specific nodes in the wave string with letters (like a or b), and then define edges connecting them in an "edge" array.

syntax
{ "signal": [
  {"name": "A", "wave": "01........0....",  "node": ".a........j" },
  {"name": "B", "wave": "0.1.......0.1..",  "node": "..b.......i" },
  {"name": "C", "wave": "0..1....0...1..",  "node": "...c....h.." },
  {"name": "D", "wave": "0...1..0.....1.",  "node": "....d..g..." },
  {"name": "E", "wave": "0....10.......1",  "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"
  ]
}
WaveDromWaveDrom diagram

WaveDrom entirely eliminates the need to fiddle with vector drawing tools like Visio or Illustrator for complex timing diagrams. Whenever the protocol gets updated, simply change the JSON string and your PDF documentation updates automatically.