uvm_svcmd_dpi——DPI在UVM中的实现(二)

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_DPI
import "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);
endfunction

function string uvm_dpi_get_tool_name();
  return uvm_dpi_get_tool_name_c();
endfunction

function string uvm_dpi_get_tool_version();
  return uvm_dpi_get_tool_version_c();
endfunction

import "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);

`else
function string uvm_dpi_get_next_arg(int init=0);
  return "";
endfunction

function string uvm_dpi_get_tool_name();
  return "?";
endfunction

function string uvm_dpi_get_tool_version();
  return "?";
endfunction


function chandle uvm_dpi_regcomp(string regex); return null; endfunction
function int uvm_dpi_regexec(chandle preg, string str); return 0; endfunction
function void uvm_dpi_regfree(chandle preg); endfunction

`endif

看完了uvm_svcmd_dpi.svh的源代码,让我们再看看uvm_svcmd_dpi.cc的源代码,这里面的函数是采用vpi方式实现的。

#include "uvm_dpi.h"
#include <assert.h>

#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 args
char** 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<argc) || ((lvl>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);
}
View Code
原文地址:https://www.cnblogs.com/dpc525/p/8066204.html