Skip to main content

wavedrom

https://mp.weixin.qq.com/s/3HTPEVBf3r-rub5RXiDwjQ

一. 前言​

驱动开发,尤其是接口驱动等, 很多时候都是围绕着器件的波形图和时序图来进行,很多时候写设计文档,或者问题分析文档时,需要添加波形时序图进行描述和示例, 比如希望把关键点标志出来,尤其是需要注意的时序点, 比如复位等待时间,上电时序, setup,hold时间等。如何优雅的生成波形图时序图呢?

平常我们的做法是datasheet中截图,然后编辑标注,虽然也可以,但是显得不是那么优雅美丽!

那么是否有有优雅的方式,直接画出需要的波形时序图呢?这里推荐一个工具wavedrom
官网
直接网页就可以使用

二.使用介绍​

参考官方文档

1 信号​

基本的语法是

{ signal: [{ name: "Alfa", wave: "01.zx=ud.23.456789" }] }

1

  • "signal" 数组,包含多个WaveLanes,一个wave就是一行,一个波形.
  • 每个WaveLane 至少需要 "name" 和"wave"两个字段.
  • Signal下有一行标题为Alfa波形根据wave后面的内容画出
  • 一个字符对应一个bit周期,用不同的字符代表不同的含义,其中 1表示高电平,0表示低电平, .表示保持前一个状态
  • 空行用一个占用一行即可

2 时钟​

时钟也是上述的一个信号,一个bit周期改变两次,有正负极性,可以边沿加箭头

主要字符含义如下

  • p 高在前的时钟
  • P 带上升沿箭头的p
  • n 低在前的时钟
  • N 带下降沿箭头的n

上述n和p对应negative和positive,大写就表示带箭头 h 表示全高 H 表示带上升沿箭头的h l 表示全低 L 表示带下降沿箭头的l 上述h对应high,l对应low,大写表示带箭头

  • x表示x态
  • z表示高阻态

{ 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' },
]}

2

3 标签​

wave中用=表示需要加标签, 后面按顺序找对应的data中对应的标签

{ "signal" : [
{ "name": "clk", "wave": "P......" },
{ "name": "bus", "wave": "x.==.=x", "data": ["head", "body", "tail", "data"] },
{ "name": "wire", "wave": "0.1..0." }
]}

3

  • 第一个=找到head
  • 第二个=找到body
  • 由于后面还有一个.表示还是body
  • 第三个=找到tail
  • 所以最后data中的data不显示,因为只有三个=

4 间断省略​

用|表示

{ "signal" : [
{ "name": "clk", "wave": "p.....|..." },
{ "name": "Data", "wave": "x.346x|=.x", "data": ["head", "body", "tail", "data"] },
{ "name": "Request", "wave": "0.1..0|1.0" },
{},
{ "name": "Acknowldge", "wave": "1.....|01." }
]}

4

5 带颜色标签​

2-9表示, 其中2是没有颜色和=等价

6 分组​

用[]括起来一组信号: ['group name', {...}, {...}, ...]

{signal: [
{ name: 'clk', wave: 'p..Pp..P'},
['Master',
['ctrl',
{name: 'write', wave: '01.0....'},
{name: 'read', wave: '0...1..0'}
],
{ name: 'addr', wave: 'x3.x4..x', data: 'A1 A2'},
{ name: 'wdata', wave: 'x3.x....', data: 'D1' },
],
{},
['Slave',
['ctrl',
{name: 'ack', wave: 'x01x0.1x'},
],
{ name: 'rdata', wave: 'x.....4x', data: 'Q2'},
]
]}

5

7 周期和相位​

增加字段

  • period: 表示周期
  • phase: 0.5表示相位; 负数表示信号后移动,正数前移

{ "signal" : [
{ "name": "CK", "wave": "P.......", "period":2 },
{ "name": "CMD", "wave": "x.3x=x4x=x=x=x=x", "data" : "RAS NOP CAS NOP NOP NOP NOP", "phase" :-0.5 },
{ "name": "ADDR","wave": "x.=x..=x........", "data" : "ROW COL", "phase" :0.5 },
{ "name": "DQS", "wave": "z.......0.1010z." },
{ "name": "DQ", "wave": "z.........5555z.", "data" : "D0 D1 D2 D3" }
]}

6

8 配置属性​

缩放​

放在signal数组后

config: { hscale: x }

x为大于0的整数表示水平放大多少倍

主题​

config:{skin:'...'} ...可以为'default' 和 'narrow'

上下标题​

head:{...} 和 foot:{...}

可以加如下属性

  • tick: 增加时间标签,边沿对齐
  • tock: 增加时间标签,中间对齐
  • text: 标签内容,格式支持 tspan 属性,详见文档
  • every: ticks 和 tocks 递增单位, 不写则为1
{signal: [
{name:'clk', wave: 'p....' },
{name:'Data', wave: 'x345x', data: 'a b c' },
{name:'Request', wave: '01..0' }
],
head:{
text:'WaveDrom example',
tick:0,
every:2
},
foot:{
text:'Figure 100',
tock:9
},
}

7

9 箭头​

支持以下箭头,定义node来标志位置,箭头连接不同node位置

格式为:Node 箭头 node 文字

~ -~
<~> <-~>
~> -~> ~->
{ 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'
]
}

8

10 连线​

和箭头类似

支持以下

- -| -|-
<-> <-|> <-|->
-> -|> -|-> |->
+
{ signal: [
{ name: 'A', wave: '01..0..', node: '.a..e..' },
{ name: 'B', wave: '0.1..0.', node: '..b..d.', phase:0.5 },
{ name: 'C', wave: '0..1..0', node: '...c..f' },
{ node: '...g..h' },
{ node: '...I..J', phase:0.5 },
{ name: 'D', wave: '0..1..0', phase:0.5 }
],
edge: [
'b-|a t1', 'a-|c t2', 'b-|-c t3', 'c-|->e t4', 'e-|>f more text',
'e|->d t6', 'c-g', 'f-h', 'g<->h 3 ms', 'I+J 5 ms'
]
}

9

11 使用代码​

还有高阶用法,直接使用代码生成

(function (bits, ticks) {
var i, t, gray, state, data = [], arr = [];
for (i = 0; i < bits; i++) {
arr.push({name: i + '', wave: ''});
state = 1;
for (t = 0; t < ticks; t++) {
data.push(t + '');
gray = (((t >> 1) ^ t) >> i) & 1;
arr[i].wave += (gray === state) ? '.' : gray + '';
state = gray;
}
}
arr.unshift('gray');
return {signal: [
{name: 'bin', wave: '='.repeat(ticks), data: data}, arr
]};
})(5, 16)

10

12 逻辑图​

还可以画逻辑电路原理图, 使用assign

见 逻辑图tutorial

{ assign: [
["out",
["|",
["&", ["~", "a"], "b"],
["&", ["~", "b"], "a"]
]
]
]
}

11

三. 总结​

可以看到wavedrom功能强大,可以非常优雅快速地画各种波形时序图,

语法也比较好理解,基本从英文单词就可以理解符号的作用,网页可以可视化编辑,非常方便。