SystemVerilog只能读文件,却不能读目录。传统的做法是先用脚本处理好,再用sv的fopen、fread。这种方式有点不太灵活,每次仿真前都需要用脚本再处理一次。(当然也可以把这个脚本写到Makefile里,自动化处理。)今天介绍用SystemVerilog的DPI-C接口,C语言来实现这个功能。
//
// file: get_file_list.c
//
#include <sys/types.h>
#include <stdio.h>
#include <dirent.h>
#include <unistd.h>
#include <string.h>
#include <svdpi.h> //include sv header file
// ARGS:
// dirname(input): directory to read
// tc_list(output): string array to store file names
// tc_num(output): file counter
//
void get_bmp_list(const char * dirname, char ** tc_list, int * tc_num)
{
DIR * dir;
struct dirent * ptr;
// open dir
dir = opendir(dirname);
// read files until the last one
while((ptr = readdir(dir)) != NULL){
// filter . and ..
if(strcmp(ptr->d_name, ".") && strcmp(ptr->d_name, "..")){
// save file name to external string array
tc_list[*tc_num] = ptr->d_name;
// file counter
(*tc_num)++;
}
}
// close dir
closedir(dir);
}
// import c function, outside of class
import "DPI-C" function void get_bmp_list(input string dirname,
output string tc_list[256],
output int tc_num);
class test extends uvm_test;
`uvm_component_utils(test_base)
string tc_list[256]; //store file names
int tc_num = 0; //file counter
int N;
string image_name;
string dirname;
function void build_phase(uvm_phase phase);
// ...
dirname = $sformatf("%s/sim/tc/pics", `DEPTH);
// call c function
get_bmp_list(dirname, tc_list, tc_num);
// get one bmp randomly
N = $urandom_range(0, tc_num-1);
image_name = tc_list[N];
$display("\nRandom image name is %s\n", image_name);
// ...
endfunction
endclass
不需要额外的命令行参数:
irun -64bit -access rwc get_file_list.c xxx.sv