#include "vpi_user.h"
#include "veriuser.h"
#include "svdpi.h"
#include
#include
#include
static int uvm_hdl_max_width()
{
vpiHandle ms;
s_vpi_value value_s = { vpiIntVal, { 0 } };
ms = vpi_handle_by_name(
(PLI_BYTE8*) "uvm_pkg::UVM_HDL_MAX_WIDTH", 0);
if(ms == 0)
return 1024;
vpi_get_value(ms, &value_s);
return value_s.value.integer;
}
#ifdef QUESTA
static int uvm_hdl_set_vlog(char *path, p_vpi_vecval value, PLI_INT32 flag);
static int uvm_hdl_get_vlog(char *path, p_vpi_vecval value, PLI_INT32 flag);
static int partsel = 0;
static int uvm_hdl_set_vlog_partsel(char *path, p_vpi_vecval value, PLI_INT32 flag)
{
char *path_ptr = path;
int path_len, idx;
svLogicVecVal bit_value;
path_len = strlen(path);
path_ptr = (char*)(path+path_len-1);
if (*path_ptr != ']')
return 0;
while(path_ptr != path && *path_ptr != ':' && *path_ptr != '[')
path_ptr--;
if (path_ptr == path || *path_ptr != ':')
return 0;
while(path_ptr != path && *path_ptr != '[')
path_ptr--;
if (path_ptr == path || *path_ptr != '[')
return 0;
int lhs, rhs, width, incr;
if (sscanf(path_ptr,"[%u:%u]",&lhs, &rhs)) {
char index_str[20];
int i;
path_ptr++;
path_len = (path_len - (path_ptr - path));
incr = (lhs>rhs) ? 1 : -1;
width = (lhs>rhs) ? lhs-rhs+1 : rhs-lhs+1;
for (i=0; i < width; i++) {
sprintf(index_str,"%u]",rhs);
strncpy(path_ptr,index_str,path_len);
svGetPartselLogic(&bit_value,value,i,1);
rhs += incr;
if (!uvm_hdl_set_vlog(path,&bit_value,flag))
return 0;
}
return 1;
}
}
static int uvm_hdl_get_vlog_partsel(char *path, p_vpi_vecval value, PLI_INT32 flag)
{
char *path_ptr = path;
int path_len, idx;
svLogicVecVal bit_value;
path_len = strlen(path);
path_ptr = (char*)(path+path_len-1);
if (*path_ptr != ']')
return 0;
while(path_ptr != path && *path_ptr != ':' && *path_ptr != '[')
path_ptr--;
if (path_ptr == path || *path_ptr != ':')
return 0;
while(path_ptr != path && *path_ptr != '[')
path_ptr--;
if (path_ptr == path || *path_ptr != '[')
return 0;
int lhs, rhs, width, incr;
if (sscanf(path_ptr,"[%u:%u]",&lhs, &rhs)) {
char index_str[20];
int i;
path_ptr++;
path_len = (path_len - (path_ptr - path));
incr = (lhs>rhs) ? 1 : -1;
width = (lhs>rhs) ? lhs-rhs+1 : rhs-lhs+1;
bit_value.aval = 0;
bit_value.bval = 0;
partsel = 1;
for (i=0; i < width; i++) {
int result;
svLogic logic_bit;
sprintf(index_str,"%u]",rhs);
strncpy(path_ptr,index_str,path_len);
result = uvm_hdl_get_vlog(path,&bit_value,flag);
logic_bit = svGetBitselLogic(&bit_value,0);
svPutPartselLogic(value,bit_value,i,1);
rhs += incr;
if (!result)
return 0;
}
partsel = 0;
return 1;
}
}
#endif
static int uvm_hdl_set_vlog(char *path, p_vpi_vecval value, PLI_INT32 flag)
{
static int maxsize = -1;
vpiHandle r;
s_vpi_value value_s = { vpiIntVal, { 0 } };
s_vpi_time time_s = { vpiSimTime, 0, 0, 0.0 };
#ifdef QUESTA
int result = 0;
result = uvm_hdl_set_vlog_partsel(path,value,flag);
if (result < 0)
return 0;
if (result == 1)
return 1;
if (!strncmp(path,"$root.",6))
r = vpi_handle_by_name(path+6, 0);
else
#endif
r = vpi_handle_by_name(path, 0);
if(r == 0)
{
vpi_printf((PLI_BYTE8*) "UVM_ERROR: set: unable to locate hdl path (%s)\n",path);
vpi_printf((PLI_BYTE8*) " Either the name is incorrect, or you may not have PLI/ACC visibility to that name\n");
return 0;
}
else
{
if(maxsize == -1)
maxsize = uvm_hdl_max_width();
if (flag == vpiReleaseFlag) {
}
value_s.format = vpiVectorVal;
value_s.value.vector = value;
vpi_put_value(r, &value_s, &time_s, flag);
if (value == NULL) {
value = value_s.value.vector;
}
}
#ifndef VCS
vpi_release_handle(r);
#endif
return 1;
}
static int uvm_hdl_get_vlog(char *path, p_vpi_vecval value, PLI_INT32 flag)
{
static int maxsize = -1;
int i, size, chunks;
vpiHandle r;
s_vpi_value value_s;
#ifdef QUESTA
if (!partsel) {
maxsize = uvm_hdl_max_width();
chunks = (maxsize-1)/32 + 1;
for(i=0;i<chunks-1; ++i) {
value[i].aval = 0;
value[i].bval = 0;
}
}
int result = 0;
result = uvm_hdl_get_vlog_partsel(path,value,flag);
if (result < 0)
return 0;
if (result == 1)
return 1;
if (!strncmp(path,"$root.",6))
r = vpi_handle_by_name(path+6, 0);
else
#endif
r = vpi_handle_by_name(path, 0);
if(r == 0)
{
vpi_printf((PLI_BYTE8*) "UVM_ERROR: get: unable to locate hdl path %s\n", path);
vpi_printf((PLI_BYTE8*) " Either the name is incorrect, or you may not have PLI/ACC visibility to that name\n");
return 0;
}
else
{
if(maxsize == -1)
maxsize = uvm_hdl_max_width();
size = vpi_get(vpiSize, r);
if(size > maxsize)
{
vpi_printf((PLI_BYTE8*) "UVM_ERROR: uvm_reg : hdl path '%s' is %0d bits,\n",path,size);
vpi_printf((PLI_BYTE8*) " but the maximum size is %0d. You can increase the maximum\n",maxsize);
vpi_printf((PLI_BYTE8*) " via a compile-time flag: +define+UVM_HDL_MAX_WIDTH=\n");
#ifndef VCS
vpi_release_handle(r);
#endif
return 0;
}
chunks = (size-1)/32 + 1;
value_s.format = vpiVectorVal;
vpi_get_value(r, &value_s);
for(i=0;i<chunks; ++i)
{
value[i].aval = value_s.value.vector[i].aval;
value[i].bval = value_s.value.vector[i].bval;
}
}
#ifndef VCS
vpi_release_handle(r);
#endif
return 1;
}
int uvm_hdl_check_path(char *path)
{
vpiHandle r;
#ifdef QUESTA
if (!strncmp(path,"$root.",6)) {
r = vpi_handle_by_name(path+6, 0);
}
else
#endif
r = vpi_handle_by_name(path, 0);
if(r == 0)
return 0;
else
return 1;
}
int uvm_hdl_read(char *path, p_vpi_vecval value)
{
return uvm_hdl_get_vlog(path, value, vpiNoDelay);
}
int uvm_hdl_deposit(char *path, p_vpi_vecval value)
{
return uvm_hdl_set_vlog(path, value, vpiNoDelay);
}
int uvm_hdl_force(char *path, p_vpi_vecval value)
{
return uvm_hdl_set_vlog(path, value, vpiForceFlag);
}
int uvm_hdl_release_and_read(char *path, p_vpi_vecval value)
{
return uvm_hdl_set_vlog(path, value, vpiReleaseFlag);
}
int uvm_hdl_release(char *path)
{
s_vpi_vecval value;
p_vpi_vecval valuep = &value;
return uvm_hdl_set_vlog(path, valuep, vpiReleaseFlag);
}