是否有无需显式定义文件名即可遍历多文件验证的Verilog实现方法?
Verilog testbench遍历目录下多文件的实现方案
Verilog标准未提供原生的目录遍历系统函数,要实现不显式定义文件名批量读取目录下的验证文件,可采用以下两种常用方案:
方案一:Shell预生成文件列表(无额外依赖,易用性高)
无需修改仿真编译配置,只需要增加一步前置的shell操作即可:
- 仿真运行前执行shell命令,生成包含所有待处理文件名的列表文件:
# 遍历当前目录下所有txt文件,逐行写入file_list.txt for f in ./*.txt; do echo "$f" >> file_list.txt; done
- 在testbench中先读取该列表文件,逐行获取文件名后再分别打开处理,示例代码如下:
integer fd_list, fd_data; integer status; reg [255:0] filename; // 长度根据实际文件名最大长度调整 initial begin // 打开文件列表 fd_list = $fopen("file_list.txt", "r"); if (fd_list == 0) begin $error("无法打开文件列表"); $finish; end // 逐行读取文件名 while (!$feof(fd_list)) begin status = $fgets(filename, fd_list); // 去掉文件名末尾的换行符 if (filename[$bits(filename)-8 -: 8] == "\n") begin filename = filename << 8; end // 跳过空行 if (filename == 0) continue; // 打开对应数据文件执行验证逻辑 fd_data = $fopen(filename, "r"); if (fd_data == 0) begin $warning("无法打开文件: %s", filename); continue; end /* 这里插入你的单文件验证逻辑 */ $display("正在处理文件: %s", filename); $fclose(fd_data); end $fclose(fd_list); end
方案二:DPI-C调用C语言目录遍历接口(无外部前置步骤)
如果不想依赖shell前置操作,可以通过DPI调用C标准库的目录遍历函数实现,主流仿真器(VCS、Modelsim、Xcelium等)均支持该特性:
- 先编写C语言实现的目录遍历函数,保存为
dir_scan.c:
#include <dirent.h> #include <string.h> #include <svdpi.h> // 遍历指定后缀的文件,返回下一个匹配的文件名 const char* get_next_file(const char* suffix) { static DIR* dir = NULL; static struct dirent* entry; static char matched_suffix[256]; strcpy(matched_suffix, suffix); if (dir == NULL) { dir = opendir("."); if (dir == NULL) return NULL; } while ((entry = readdir(dir)) != NULL) { if (entry->d_type == DT_REG) { // 只匹配普通文件 char* ext = strrchr(entry->d_name, '.'); if (ext != NULL && strcmp(ext, matched_suffix) == 0) { return entry->d_name; } } } closedir(dir); dir = NULL; return NULL; }
- 在Verilog testbench中导入并调用该函数:
import "DPI-C" function string get_next_file(string suffix); integer fd; string filename; initial begin filename = get_next_file(".txt"); while (filename != "") begin fd = $fopen(filename, "r"); if (fd == 0) begin $warning("无法打开文件: %s", filename); filename = get_next_file(".txt"); continue; end /* 这里插入你的单文件验证逻辑 */ $display("正在处理文件: %s", filename); $fclose(fd); filename = get_next_file(".txt"); end end
编译仿真时把dir_scan.c加入编译列表即可,不需要额外配置。
注意事项
- 所有路径均为相对于仿真运行工作目录的相对路径,调整路径时注意对应
- 每处理完一个文件要及时调用
$fclose关闭文件句柄,避免超出系统允许的最大打开文件数限制
内容的提问来源于stack exchange,提问作者HazzaOb
相关产品推荐
相关产品推荐

