编 者 按
对于那些喜欢先写代码再写文档的小伙吧,寄希望于直接把仿真的波形直接贴到文档上作为接口时序图,又嫌弃波形文件太丑的小伙伴,那么可以尝试下wavedraw的VCDParser,直接将VCD文件转换为可用于wavedrom生成波形的json文件,支持只选择某个时间窗范围内的波形提取。
VCDParser
《告别繁琐JSON,wavedraw用Python重新定义时序图绘制》一文中已介绍了wavedraw的用法,正常研发流程里,一般都是先撰写文档过完评审然后开始写代码,最后进行仿真,也许有的小伙伴是先进行的demo验证,有一些仿真波形,那么在写文档时将方针波形贴到文档中作为接口时序,然而波形文件一般都张的较丑(文档也显得极不专业)。对于各种波形文件,一般都能转换成标准的VCD文件,VCD文件也相对简单,故在wavedraw中添加一个对VCD文件的解析并通过wavedraw提供的能力自动转换生成复符合wavedrom要求的json文件。
VCD文件通过wavedraw转换输出json格式的文件用法很简单,下图即是一个demo:
VCDParser其初始化函数定义如下:
- fileName:用于指定VCD波形文件的位置
- halfClockPeriod:用于指定波形中半个时钟周期的大小。对于时钟信号,在VCD波形中会记录上升沿和下降沿,同时会真实记录对应的时间轴,为避免在转换后的波形被迫拉长,这里需指定时钟周期的一半值(对于时钟周期为奇数,可能存在一点点问题)用于缩放波形。如果在波形中没有时钟,那么该值填1即可。
通过执行VCDParser的generateWave函数可以直接生成符合wavedrom标准的json字符串输出。generateWave的函数定义如下:
- title:指定波形的名称
- startTime:可以用于指定截取VCD波形中开始的时间位置
- endTime:可以用于指定截取VCD波形中的结束时间位置,其与startTime配合使用用于截取指定时间窗口的波形,如果任意一个值为None,那么则会将整个波形的都进行转换。
- period:用于指定生成波形中的period参数,如果波形中带有时钟,则建议该值设置为0.5,否则设置为1
上面这段代码读取的VCD是不带时钟的,直接执行即可得到输出的json格式波形描述:
{"signal":[
{"name":"lru_state","wave":'2..3..4..5..6..7..8..9..2..3..4..5.',"data":["0x0","0xe","0xdc","0xb98","0x7310","0x3b10","0x7310","0x620e","0x40dc","0xb98","0xa8e","0x7206"],"node":'..................................',"period":1,"phase":0},
{"name":"lru_entry","wave":'2..3..4..5..6........7..8..9.....2.',"data":["0x0","0x1","0x2","0x3","0x0","0x1","0x2","0x3","0x1"],"node":'..................................',"period":1,"phase":0},
{"name":"lru_update_req_lru_state","wave":'2.3..4..5..6..7..8..9..2..3..4..5..',"data":["0x14c3","0x0","0xe","0xdc","0xb98","0x7310","0x3b10","0x7310","0x620e","0x40dc","0xb98","0xa8e"],"node":'..................................',"period":1,"phase":0},
{"name":"lru_update_req_lru_update_entry","wave":'2.3..4..5..6..7..8..9..2..3..4..5..',"data":["0x2","0x0","0x1","0x2","0x3","0x2","0x3","0x0","0x1","0x2","0x0","0x3"],"node":'..................................',"period":1,"phase":0},
{"name":"lru_update_result","wave":'2.3..4..5..6..7..8..9..2..3..4..5..',"data":["0x1b83","0xe","0xdc","0xb98","0x7310","0x3b10","0x7310","0x620e","0x40dc","0xb98","0xa8e","0x7206"],"node":'..................................',"period":1,"phase":0},
{"name":"clk","wave":'0..................................',"node":'...................................',"period":1,"phase":0},
{"name":"reset","wave":'1..................................',"node":'...................................',"period":1,"phase":0},
["LruControl",
{"name":"lru_state","wave":'2..3..4..5..6..7..8..9..2..3..4..5.',"data":["0x0","0xe","0xdc","0xb98","0x7310","0x3b10","0x7310","0x620e","0x40dc","0xb98","0xa8e","0x7206"],"node":'..................................',"period":1,"phase":0},
{"name":"lru_entry","wave":'2..3..4..5..6........7..8..9.....2.',"data":["0x0","0x1","0x2","0x3","0x0","0x1","0x2","0x3","0x1"],"node":'..................................',"period":1,"phase":0},
{"name":"lru_update_req_lru_state","wave":'2.3..4..5..6..7..8..9..2..3..4..5..',"data":["0x14c3","0x0","0xe","0xdc","0xb98","0x7310","0x3b10","0x7310","0x620e","0x40dc","0xb98","0xa8e"],"node":'..................................',"period":1,"phase":0},
{"name":"lru_update_req_lru_update_entry","wave":'2.3..4..5..6..7..8..9..2..3..4..5..',"data":["0x2","0x0","0x1","0x2","0x3","0x2","0x3","0x0","0x1","0x2","0x0","0x3"],"node":'..................................',"period":1,"phase":0},
{"name":"lru_update_result","wave":'2.3..4..5..6..7..8..9..2..3..4..5..',"data":["0x1b83","0xe","0xdc","0xb98","0x7310","0x3b10","0x7310","0x620e","0x40dc","0xb98","0xa8e","0x7206"],"node":'..................................',"period":1,"phase":0},
{"name":"clk","wave":'0..................................',"node":'...................................',"period":1,"phase":0},
{"name":"reset","wave":'1..................................',"node":'...................................',"period":1,"phase":0},
{"name":"lru_row_state","wave":'2..3..4..5..6........7..8..9.....2.',"data":["0xf","0xe","0xc","0x8","0x1","0x2","0x4","0x8","0x2"],"node":'..................................',"period":1,"phase":0},
{"name":"lru_row_state_ohFirst_input","wave":'2..3..4..5..6........7..8..9.....2.',"data":["0xf","0xe","0xc","0x8","0x1","0x2","0x4","0x8","0x2"],"node":'..................................',"period":1,"phase":0},
{"name":"lru_row_state_ohFirst_masked","wave":'2..3..4..5..6........7..8..9.....2.',"data":["0x1","0x2","0x4","0x8","0x1","0x2","0x4","0x8","0x2"],"node":'..................................',"period":1,"phase":0},
{"name":"lru_row_state_oh","wave":'2..3..4..5..6........7..8..9.....2.',"data":["0x1","0x2","0x4","0x8","0x1","0x2","0x4","0x8","0x2"],"node":'..................................',"period":1,"phase":0},
{"name":"lru_update_entry_oh","wave":'2.3..4..5..6..7..8..9..2..3..4..5..',"data":["0x4","0x1","0x2","0x4","0x8","0x4","0x8","0x1","0x2","0x4","0x1","0x8"],"node":'..................................',"period":1,"phase":0},
],
],
"head":{"text":"wave","tick":0},
"config":{"hscale":1}}
直接生成时序图:
写在最后
在github上已上传该功能,并附带的又对应的demo(vcdTest.py),感兴趣的小伙伴可以自行去安装尝试,“阅读原文”中附带github地址。
这里的测试都是基于SpinalHDL仿真生成的VCD文件进行测试,后续其他功能如只挑选指定信号波形生成、截取多个时间窗口生成等功能再进行完善。
END
作者:玉骐
文章来源:Spinal FPGA
推荐阅读
- protocol——命令行绘制协议图大杀器
- PCIe 调试:超级好用的 rescan 与 remove 命令
- 使用 scp 命令跨服务器传输文件
- PCIE , USB , SATA , Ethernet 都在用的 SerDes 到底是个啥?
更多 IC 设计干货请关注IC设计专栏。欢迎添加极术小姐姐微信(id:aijishu20)加入技术交流群,请备注研究方向。