Cannot pass a string from C program to SV

Hi All,

I’m trying to do something using the DPI-C in System Verilog for the first time and I currently see an issue which I cannot get past.

Here is my C code:


#include <stdio.h>
#include <iostream>
#include <svdpi.h>
#include <vpi_user.h>
#include <string>
using namespace std;
extern "C" char* reg_access(char core_id[2], int mp, char my_name[256], char reg_path[256]) {
  char reg_hier[1024];
  if(mp) {
    reg_hier[0]='\0';
    strcat(reg_hier, "m_regs.");
    strcat(reg_hier, my_name);
    strcat(reg_hier, "_");

    strcat(reg_hier, core_id);
    strcat(reg_hier, ".");
    strcat(reg_hier, reg_path);
    vpi_printf(reg_hier);
    return reg_hier;
  } else {
    return "not valid";
  }
}

And here is my System Verilog Code:


import "DPI-C" context function string reg_access(string core_id, bit mp, string name, string reg_path);

$display("%s",reg_access("0", 1, "dut", "reg_map1.Enable"));

I’m basically trying to concatenate few strings together to form a register path. I see that my C function is called and the reg_hier value printed just before returning holds the value that I need. But the same value is not being printed in the System Verilog (It prints nothing). Is there something that I’m missing which could fix this? Any help appreciated.
Thanks,

In reply to szy0014:

I’m surprised you did not see the message from the C++ compiler attempting to return the address of a local variable ‘reg_hier’. It needs to be a static or heap allocated (malloc) address.

Also, the prototype for the reg_access function does not match what the DPI requires for string arguments and return values. You should use a dpi header file generated by your tool to match the code you have written.

dpiheader.h:

/* MTI_DPI */
/*
 * Copyright 2002-2022 Mentor Graphics Corporation.
 * Note:
 *   This file is automatically generated.
 *   Please do not edit this file - you will lose your edits.
 * Settings when this file was generated:
 *   PLATFORM = 'linux_x86_64'
 */
#ifndef INCLUDED_DPIHEADER
#define INCLUDED_DPIHEADER
#ifdef __cplusplus
#define DPI_LINK_DECL  extern "C" 
#else
#define DPI_LINK_DECL 
#endif
#include "svdpi.h"
DPI_LINK_DECL DPI_DLLESPEC
const char*
reg_access(
    const char* core_id,
    svBit mp,
    const char* name,
    const char* reg_path);
#endif

strings.c

#include <iostream>
#include <stdio.h>
#include <svdpi.h>
#include <vpi_user.h>
#include <string>
#include "dpiheader.h"
using namespace std;
 extern "C"  const char* reg_access(const char* core_id, svBit mp, const char* my_name, const char* reg_path) {
static  char reg_hier[1024]; 
 if(mp) {
    reg_hier[0]='\0';
    strcat(reg_hier, "m_regs.");
    strcat(reg_hier, my_name);
    strcat(reg_hier, "_");
    strcat(reg_hier, core_id);
    strcat(reg_hier, ".");
    strcat(reg_hier, reg_path);
    strcat(reg_hier, "\n");
    vpi_printf(reg_hier);
    return reg_hier;
  } else {
    return "not valid";
  }
}