我们使用vivado的ila抓取波形后,常常希望用该波形作为激励参与仿真。稍微复杂的项目中手动输入的工作量巨大,几乎是不可能采取的方式。我的方法是保存ila波形为vcd格式文件,用python解析vcd文件,转换成仿真激励的代码。
python代码如下所示:
# -*- coding: utf-8 -*-
"""
Created on Wed Jan 29 10:04:59 2025
@author: weiyi
"""
import os
import sys
signal = {}
file = r'iladata2.vcd'
with open(file,"r") as f:
lines = f.readlines()
for line in lines:
if "$var" in line:
var = line.split(" ")
signal[var[3]] = [var[2],var[4]] #width + name
last_time = 0
with open(file+".txt","w+") as f:
for line in lines:
line = line.strip()
if line.startswith("#"):
time = int(line.strip("#"))
incr_time = time - last_time
last_time = time
f.write("repeat("+str(incr_time)+")@(posedge vcd_clk)" + ';\n')
if line[-2:] in signal:
if 'b' in line:
f.write("force " + signal[line[-2:]][1] + " = " + signal[line[-2:]][0] + '\'' + line[:-2] + ";\n")
else:
f.write("force " + signal[line[-2:]][1] + " = " + signal[line[-2:]][0] + '\'b' + line[:-2] + ";\n")
elif line[-1:] in signal:
if 'b' in line:
f.write("force " + signal[line[-1:]][1] + " = " + signal[line[-1:]][0] + '\'' + line[:-1] + ";\n")
else:
f.write("force " + signal[line[-1:]][1] + " = " + signal[line[-1:]][0] + '\'b' + line[:-1] + ";\n")
f.write("repeat(1)@(posedge vcd_clk)" + ';\n')
for s in signal:
f.write("release " + signal[s][1] + ";\n")
vcd文件是文本文件,用$var reg 8 #" inst%/top%/rx_data [7:0] $end
定义信号。
因此我们在代码里先找到$var
开头的内容,找到信号名字和位宽。信号名字就是位宽后面的#"
从$dumpvars
后就开始出现具体波形。例如
#510
b10001 #"
1%.
#511
b100010 #"
#512
b110011 #"
#513
b1000100 #"
表示510时刻, #"
这个信号的值是b10001,%.
这个信号的值是1。
那么我们从每遇到1个#就计算它相对于前一个#的偏移周期。用repeat(x)@(posedge vcd_clk)
的方式表达出来。
简单说,这个代码就是提取了信号名称,计算时间偏移。最终得到的效果如下
repeat(0)@(posedge vcd_clk);
force _GAP = 1'b#;
force inst_eth_top/inst_tri_mac/rx_axis_mac_tdata = 8'b0 ;
force locked = 1'b1;
force inst_eth_top/inst_tri_mac/rx_axis_mac_tlast = 1'b0;
force inst_eth_top/inst_tri_mac/rx_axis_mac_tuser = 1'b0;
force inst_eth_top/inst_tri_mac/rx_axis_mac_tvalid = 1'b0;
force _TRIGGER = 1'b0;
force _WINDOW = 1'b1;
force _GAP = 1'b0;
repeat(508)@(posedge vcd_clk);
force inst_eth_top/inst_tri_mac/rx_axis_mac_tvalid = 1'b1;
repeat(1)@(posedge vcd_clk);
force inst_eth_top/inst_tri_mac/rx_axis_mac_tdata = 8'b10001 ;
repeat(1)@(posedge vcd_clk);
force _GAP = 1'b#51;
force inst_eth_top/inst_tri_mac/rx_axis_mac_tdata = 8'b100010 ;
repeat(1)@(posedge vcd_clk);
force inst_eth_top/inst_tri_mac/rx_axis_mac_tdata = 8'b110011 ;
只需要手动替换inst_eth_top/inst_tri_mac/
为仿真目录需要的层级,把vcd_clk
替换成真实clk,把不需要的force语句删除(选择某个单词,全选,全选当前行,删除)。就能得到一个激励task。值得注意的是,信号名称有时候是1个字符,有时候是2个字符。
本方法我已应用许久,还是比较好用的,推荐给大家。
以下给出1个vcd文件内容
$date
2025-Mar-22 20:55:33
$end
$version
Vivado v2022.2 (64-bit)
$end
$timescale
1ps
$end
$scope module dut $end
$var reg 8 " inst_eth_top/inst_tri_mac/rx_axis_mac_tdata [7:0] $end
$var reg 1 * locked $end
$var reg 1 + inst_eth_top/inst_tri_mac/rx_axis_mac_tlast $end
$var reg 1 , inst_eth_top/inst_tri_mac/rx_axis_mac_tuser $end
$var reg 1 - inst_eth_top/inst_tri_mac/rx_axis_mac_tvalid $end
$var reg 1 . _TRIGGER $end
$var reg 1 / _WINDOW $end
$var reg 1 0 _GAP $end
$upscope $end
$enddefinitions $end
#0
$dumpvars
b0 "
1*
0+
0,
0-
0.
1/
00
$end
#508
1-
#509
b10001 "
#510
b100010 "
#511
b110011 "
#512
b1000100 "
1.
#513
b1010101 "
#514
b1011000 "
#515
b10001 "
#516
b100010 "
#517
b10110000 "
#552
b0 "
#567
0-
#571
1+
1-
#572
0+
0-