Hitchhiker’s的WaveDrom使用指导(第一部分)
WaveDrom
是一个Javascript应用程序。WaveJSON
是一种描述数字信号时序图的格式。WaveDrom
直接在浏览器中渲染图表。元素signal
是WaveLanes
的组。每一个WaveLanes
都有两个必不可少的域,name
和wave
。
第一步 信号
首先,我们用一个简单便捷的案例来开始。下面的代码将会生成一个名为Alfa
的1bit的信号,并且展示了该信号的状态随时间的变化。
{signal: [{name: "Alfa", wave: "01.zx=ud.23.456789"}]}
每一个在wave
字符串中的字符都代表了一个单独的时钟周期。
符号.
代表了将上一个时钟周期的状态多保持一个时钟周期。
下面是这段代码渲染完之后的样子
第二步 添加时钟
数字时钟信号是一种特殊的信号。它在一个时钟周期内变化两次,拥有正、负两个极性。它可以选择是否显示触发边缘。时钟信号可以同其他信号状态混合来达到时钟门的效果。以下是它的代码:
{ 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' },
]}
渲染出来的图表是这样的
第三步 把所有的合在一起
典型的信号时序图拥有时钟和信号。多位的信号可以从data
数组中提取标签。
{ signal: [
{ name: "clk", wave: "P......" },
{ name: "bus", wave: "x.==.=x", data: ["head", "body", "tail", "data"] },
{ name: "wire", wave: "0.1..0." }
]}
第四步 空格和间隙
{ 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." }
]}
第五步 组
WaveLanes
可以被规统一划到一个被命名的组当中。属于同一组的WaveLanes
和组的名字一起放在一个数组中,["GroupName", {}, {},...]
。这个数组的第一个元素必须是组的名字。组是可以嵌套使用的。
{ 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'},
]
]}
第六步 周期和相位
参数period
和phase
用来调整每一条WaveLane
。
{ 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" }
]}
第七步 属性设置
config{...}
是用来设置渲染效果的。
hecale
config{hscale:#}
是用来控制图标的水平尺寸的。用户可以输入任意大于0的整数。
{ signal: [
{ name: "clk", wave: "p...." },
{ name: "Data", wave: "x345x", data: ["head", "body", "tail"] },
{ name: "Request", wave: "01..0" }
],
config: { hscale: 1 }
}
hecale=1(默认值)
hecale=2
hecale=3
skin
config{skin:'...'}
是用来选择渲染风格的。这个选项只能存在于一个界面上的第一处时序图中。WaveDrom
内提供了两种标准皮肤,default
和narrow
。
head/foot
head:{...}
和foot:{...}
是用来设置时序图上方和下方区域的文字内容用的。
- tick
- 在与垂直标记线对齐的位置添加时间线
- tock
- 在垂直标记线之间添加时间线
- text
- 添加标题文本
- every
- 每N个时间周期才显示一次
tick
或tock
- 每N个时间周期才显示一次
{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
},
}
head
/foot
具有SVG文本的所有属性。通过设置标准SVG属性tspan
来修改文本的全部默认属性。可以使用JsonML标记语言来表示SVG文本的内容。同时,wavedrom
提供了几种预设的格式,可以直接使用以及任意搭配:
h1
h2
h3
h4
h5
h6
是预设的字体大小muted
warning
error
info
success
是预设的字体颜色
可以自由的搭配使用SVG属性tspan
,如下所示:
{signal: [
{name:'clk', wave: 'p.....PPPPp....' },
{name:'dat', wave: 'x....2345x.....', data: 'a b c d' },
{name:'req', wave: '0....1...0.....' }
],
head: {text:
['tspan',
['tspan', {class:'error h1'}, 'error '],
['tspan', {class:'warning h2'}, 'warning '],
['tspan', {class:'info h3'}, 'info '],
['tspan', {class:'success h4'}, 'success '],
['tspan', {class:'muted h5'}, 'muted '],
['tspan', {class:'h6'}, 'h6 '],
'default ',
['tspan', {fill:'pink', 'font-weight':'bold', 'font-style':'italic'}, 'pink-bold-italic']
]
},
foot: {text:
['tspan', 'E=mc',
['tspan', {dy:'-5'}, '2'],
['tspan', {dy: '5'}, '. '],
['tspan', {'font-size':'25'}, 'B '],
['tspan', {'text-decoration':'overline'},'over '],
['tspan', {'text-decoration':'underline'},'under '],
['tspan', {'baseline-shift':'sub'}, 'sub '],
['tspan', {'baseline-shift':'super'}, 'super ']
],tock:-5
}
}
第八步 箭头
曲线
~ -~
<~> <-~>
~> -~> ~->
{ 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'
]
}
折线
- -| -|-
<-> <-|> <-|->
-> -|> -|-> |->
+
{ 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'
]
}
第九步 一些代码
(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)