wavedrom
https://mp.weixin.qq.com/s/3HTPEVBf3r-rub5RXiDwjQ
一. 前言
驱动开发,尤其是接口驱动等, 很多时候都是围绕着器件的波形图和时序图来进行,很多时候写设计文档,或者问题分析文档时,需要添加波形时序图进行描述和示例, 比如希望把关键点标志出来,尤其是需要注意的时序点, 比如复位等待时间,上电时序, setup,hold时间等。如何优雅的生成波形图时序图呢?
平常我们的做法是datasheet中截图,然后编辑标注,虽然也可以,但是显得不是那么优雅美丽!
那么是否有有优雅的方式,直接画出需要的波形时序图呢?这里推荐一个工具wavedrom
官网
直接网页就可以使用
二.使用介绍
1 信号
基本的语法是
{ signal: [{ name: "Alfa", wave: "01.zx=ud.23.456789" }] }
- "signal" 数组,包含多个WaveLanes,一个wave就是一行,一个波形.
- 每个WaveLane 至少需要 "name" 和"wave"两个字段.
- Signal下有一行标题为Alfa波形根据wave后面的内容画出
- 一个字符对应一个bit周期,用不同的字符代表不同的含义,其中
1表示高电平,0表示低电平,.表示保持前一个状态 - 空行用一个占用一行即可
2 时钟
时钟也是上述的一个信号,一个bit周期改变两次,有正负极性,可以边沿加箭头
主要字符含义如下
p高在前的时钟P带上升沿箭头的pn低在前的时钟N带下降沿箭头的n
上述n和p对应negative和positive,大写就表示带箭头
h表示全高H表示带上升沿箭头的hl表示全低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' },
]}

3 标签
wave中用=表示需要加标签, 后面按顺序找对应的data中对应的标签
{ "signal" : [
{ "name": "clk", "wave": "P......" },
{ "name": "bus", "wave": "x.==.=x", "data": ["head", "body", "tail", "data"] },
{ "name": "wire", "wave": "0.1..0." }
]}
- 第一个=找到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." }
]}

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

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" }
]}

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
},
}

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

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

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)

12 逻辑图
还可以画逻辑电路原理图, 使用assign
{ assign: [
["out",
["|",
["&", ["~", "a"], "b"],
["&", ["~", "b"], "a"]
]
]
]
}
三. 总结
可以看到wavedrom功能强大,可以非常优雅快速地画各种波形时序图,
语法也比较好理解,基本从英文单词就可以理解符号的作用,网页可以可视化编辑,非常方便。