UVM中有需要从cmmand line 输入参数的需求,所有uvm_svcmd_dpi.svh和uvm_svcmd_dpi.cc 文件就是实现功能。
uvm_svcmd_dpi.svh的源代码如下,我们可以看SV采用import的方式导入C代码函数,所有者写函数的实现在uvm_svcmd_dpi.cc 中。当定义了UVM_CMDLINE_NO_DPI的宏时,所有函数返回值要么是NULL,要么是“?”。
// Import DPI functions used by the interface to generate the// lists.`ifndef UVM_CMDLINE_NO_DPIimport "DPI-C" function string uvm_dpi_get_next_arg_c (int init);import "DPI-C" function string uvm_dpi_get_tool_name_c ();import "DPI-C" function string uvm_dpi_get_tool_version_c ();function string uvm_dpi_get_next_arg(int init=0); return uvm_dpi_get_next_arg_c(init);endfunctionfunction string uvm_dpi_get_tool_name(); return uvm_dpi_get_tool_name_c();endfunctionfunction string uvm_dpi_get_tool_version(); return uvm_dpi_get_tool_version_c();endfunctionimport "DPI-C" function chandle uvm_dpi_regcomp(string regex);import "DPI-C" function int uvm_dpi_regexec(chandle preg, string str);import "DPI-C" function void uvm_dpi_regfree(chandle preg);`elsefunction string uvm_dpi_get_next_arg(int init=0); return "";endfunctionfunction string uvm_dpi_get_tool_name(); return "?";endfunctionfunction string uvm_dpi_get_tool_version(); return "?";endfunctionfunction chandle uvm_dpi_regcomp(string regex); return null; endfunctionfunction int uvm_dpi_regexec(chandle preg, string str); return 0; endfunctionfunction void uvm_dpi_regfree(chandle preg); endfunction`endif
看完了uvm_svcmd_dpi.svh的源代码,让我们再看看uvm_svcmd_dpi.cc的源代码,这里面的函数是采用vpi方式实现的。
#include "uvm_dpi.h"#include#define ARGV_STACK_PTR_SIZE 32// the total number of arguments (minus the -f/-F minus associated filenames) int argc_total;// the ptr to the array of ptrs to the argschar** argv_stack=NULL;char ** argv_ptr=NULL;void push_data(int lvl,char *entry, int cmd) { if(cmd==0) argc_total++; else *argv_ptr++=entry;}// walk one level (potentially recursive)void walk_level(int lvl, int argc, char**argv,int cmd) { int idx; for(idx=0; ((lvl==0) && idx 0) && (*argv));idx++,argv++) { if(strcmp(*argv, "-f") && strcmp(*argv, "-F")) { push_data(lvl,*argv,cmd); } else { argv++; idx++; char **n=(char**) *argv; walk_level(lvl+1,argc,++n,cmd); } }}const char *uvm_dpi_get_next_arg_c (int init) { s_vpi_vlog_info info; static int idx=0; if(init==1) { // free if necessary free(argv_stack); argc_total=0; vpi_get_vlog_info(&info); walk_level(0,info.argc,info.argv,0); argv_stack = (char**) malloc (sizeof(char*)*argc_total); argv_ptr=argv_stack; walk_level(0,info.argc,info.argv,1); idx=0; argv_ptr=argv_stack; } if(idx++>=argc_total) return NULL; return *argv_ptr++;}extern char* uvm_dpi_get_tool_name_c (){ s_vpi_vlog_info info; vpi_get_vlog_info(&info); return info.product;}extern char* uvm_dpi_get_tool_version_c (){ s_vpi_vlog_info info; vpi_get_vlog_info(&info); return info.version;}extern regex_t* uvm_dpi_regcomp (char* pattern){ regex_t* re = (regex_t*) malloc (sizeof(regex_t)); int status = regcomp(re, pattern, REG_NOSUB|REG_EXTENDED); if(status) { const char * err_str = "uvm_dpi_regcomp : Unable to compile regex: |%s|, Element 0 is: %c"; char buffer[strlen(err_str) + strlen(pattern) + 1]; sprintf(buffer, err_str, pattern, pattern[0]); m_uvm_report_dpi(M_UVM_ERROR, (char*)"UVM/DPI/REGCOMP", &buffer[0], M_UVM_NONE, (char*) __FILE__, __LINE__); regfree(re); free (re); return NULL; } return re;}extern int uvm_dpi_regexec (regex_t* re, char* str){ if(!re ) { return 1; } return regexec(re, str, (size_t)0, NULL, 0);}extern void uvm_dpi_regfree (regex_t* re){ if(!re) return; regfree(re); free (re);}