接上篇博客
systemverilog 的svlib的用法1-CSDN博客
已经介绍了关于解析固定格式文件到class里面,但是如果数据比较复杂,不规范,就需要用到一些特殊处理方法。
forexample 1:
获取如下txt的数据
2
#0;0 #2;1 #29;0
#1;0 #3;1 #40;0 #51;1
可以使用如下code去解析:
int file_handle; // 文件句柄
int ret_val; // 返回值,用于存储$fgets的结果
string read_str; // 存储从文件中读取的一行字符串
int num_vca_types; // 存储vca类型数量
int counter = 0; // 用于计数
int signal_values_array[][]; // 存储每个信号的值
int signal_times_array[][]; // 存储每个信号的时间
string split_line[$]; // 存储按#号分割后的字符串
string signal_data[$]; // 存储按逗号分割后的信号数据
Regex split_hash; // 用于按#号分割字符串的正则表达式
Regex split_comma; // 用于按逗号分割信号数据的正则表达式
// 打开文件
file_handle = $fopen("test.txt", "r");
if (!file_handle)
$display("Unable to open test file");
// 读取文件并解析
while (! $feof(file_handle)) begin
if (counter == 0) begin
ret_val = $fgets(read_str, file_handle);
// 将读取的字符串转换为整数,获取vca类型的数量
num_vca_types = read_str.atoi();
// 动态分配数组大小
signal_values_array = new[num_vca_types];
signal_times_array = new[num_vca_types];
end
else if (counter <= num_vca_types) begin
// 初始化数组和正则表达式
split_line = new[string]();
signal_data = new[string]();
// 读取文件中的一行
ret_val = $fgets(read_str, file_handle);
// 根据#号分割字符串
split_hash = Regex::create("#");
split_hash.setStrContents(read_str);
split_line = split_hash.split();
// 遍历split_line数组,处理信号和时间
foreach (split_line[j]) begin
if (j >= 1) begin
// 按分号分割每个信号
split_comma = Regex::create(";");
split_comma.setStrContents(split_line[j]);
signal_data = split_comma.split();
// 将信号的时间和值存储到对应的数组中
signal_times_array[counter-1][j] = signal_data[0].atoi();
signal_values_array[counter-1][j] = signal_data[1].atoi();
end
end
end
else begin
// 读取下一行
ret_val = $fgets(read_str, file_handle);
end
// 增加计数器
counter++;
end
// 关闭文件
$fclose(file_handle);