URL
https://opencores.org/ocsvn/uart2bus_testbench/uart2bus_testbench/trunk
Subversion Repositories uart2bus_testbench
[/] [uart2bus_testbench/] [trunk/] [tb/] [uvm_src/] [dpi/] [uvm_hdl_vcs.c] - Rev 16
Compare with Previous | Blame | View Log
//---------------------------------------------------------------------- // Copyright 2007-2011 Cadence Design Systems, Inc. // Copyright 2009-2010 Mentor Graphics Corporation // Copyright 2010-2011 Synopsys, Inc. // All Rights Reserved Worldwide // // Licensed under the Apache License, Version 2.0 (the // "License"); you may not use this file except in // compliance with the License. You may obtain a copy of // the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in // writing, software distributed under the License is // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR // CONDITIONS OF ANY KIND, either express or implied. See // the License for the specific language governing // permissions and limitations under the License. //---------------------------------------------------------------------- #include "uvm_dpi.h" #include <math.h> #include "svdpi.h" #include "vcsuser.h" #ifdef VCSMX #include "mhpi_user.h" #include "vhpi_user.h" #endif /* * UVM HDL access C code. * */ /* * This C code checks to see if there is PLI handle * with a value set to define the maximum bit width. * * If no such variable is found, then the default * width of 1024 is used. * * This function should only get called once or twice, * its return value is cached in the caller. * */ 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; /* If nothing else is defined, this is the DEFAULT */ vpi_get_value(ms, &value_s); return value_s.value.integer; } /* * Given a path, look the path name up using the PLI, * and set it to 'value'. */ 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 }; //vpi_printf("uvm_hdl_set_vlog(%s,%0x)\n",path,value[0].aval); r = vpi_handle_by_name(path, 0); if(r == 0) { const char * err_str = "set: unable to locate hdl path (%s)\n Either the name is incorrect, or you may not have PLI/ACC visibility to that name"; char buffer[strlen(err_str) + strlen(path)]; sprintf(buffer, err_str, path); m_uvm_report_dpi(M_UVM_ERROR, (char*) "UVM/DPI/HDL_SET", &buffer[0], M_UVM_NONE, (char*)__FILE__, __LINE__); return 0; } else { if(maxsize == -1) maxsize = uvm_hdl_max_width(); if (flag == vpiReleaseFlag) { //size = vpi_get(vpiSize, r); //value_p = (p_vpi_vecval)(malloc(((size-1)/32+1)*8*sizeof(s_vpi_vecval))); //value = &value_p; } value_s.format = vpiVectorVal; value_s.value.vector = value; vpi_put_value(r, &value_s, &time_s, flag); //if (value_p != NULL) // free(value_p); if (value == NULL) { value = value_s.value.vector; } } return 1; } /* * Given a path, look the path name up using the PLI * and return its 'value'. */ 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; r = vpi_handle_by_name(path, 0); if(r == 0) { const char * err_str = "get: unable to locate hdl path (%s)\n Either the name is incorrect, or you may not have PLI/ACC visibility to that name"; char buffer[strlen(err_str) + strlen(path)]; sprintf(buffer, err_str, path); m_uvm_report_dpi(M_UVM_ERROR, (char*)"UVM/DPI/HDL_GET", &buffer[0], M_UVM_NONE, (char*)__FILE__, __LINE__); // Exiting is too harsh. Just return instead. // tf_dofinish(); return 0; } else { if(maxsize == -1) maxsize = uvm_hdl_max_width(); size = vpi_get(vpiSize, r); if(size > maxsize) { const char * err_str = "uvm_reg : hdl path '%s' is %0d bits, but the maximum size is %0d. You can increase the maximum via a compile-time flag: +define+UVM_HDL_MAX_WIDTH=<value>"; char buffer[strlen(err_str) + strlen(path) + (2*int_str_max(10))]; sprintf(buffer, err_str, path, size, maxsize); m_uvm_report_dpi(M_UVM_ERROR, (char*)"UVM/DPI/HDL_SET", &buffer[0], M_UVM_NONE, (char*)__FILE__, __LINE__); return 0; } chunks = (size-1)/32 + 1; value_s.format = vpiVectorVal; vpi_get_value(r, &value_s); /*dpi and vpi are reversed*/ for(i=0;i<chunks; ++i) { value[i].aval = value_s.value.vector[i].aval; value[i].bval = value_s.value.vector[i].bval; } } //vpi_printf("uvm_hdl_get_vlog(%s,%0x)\n",path,value[0].aval); return 1; } /* * Given a path, look the path name up using the PLI, * but don't set or get. Just check. * * Return 0 if NOT found. * Return 1 if found. */ int uvm_hdl_check_path(char *path) { vpiHandle r; r = vpi_handle_by_name(path, 0); if(r == 0) return 0; else return 1; } /* * convert binary to integer */ long int uvm_hdl_btoi(char *binVal) { long int remainder, dec=0, j = 0; unsigned long long int bin; int i; char tmp[2]; tmp[1] = '\0'; for(i= strlen(binVal) -1 ; i >= 0 ; i--) { tmp[0] = binVal[i]; bin = atoi(tmp); dec = dec+(bin*(pow(2,j))); j++; } return(dec); } /* *decimal to hex conversion */ char *uvm_hdl_dtob(long int decimalNumber) { int remainder, quotient; int i=0,j, length; int binN[65]; static char binaryNumber[65]; char *str = (char*) malloc(sizeof(char)); quotient = decimalNumber; do { binN[i++] = quotient%2; quotient = quotient/2; } while (quotient!=0); length = i; for (i=length-1, j = 0; i>=0; i--) { binaryNumber[j++] = binN[i]?'1':'0'; } binaryNumber[j] = '\0'; return(binaryNumber); } /* * Mixed lanaguage API Get calls */ #ifdef VCSMX int uvm_hdl_get_mhdl(char *path, p_vpi_vecval value) { long int value_int; char *binVal; int i = 0; vhpiValueT value1; p_vpi_vecval vecval; mhpi_initialize('/'); mhpiHandleT mhpiH = mhpi_handle_by_name(path, 0); vhpiHandleT vhpiH = (long unsigned int *)mhpi_get_vhpi_handle(mhpiH); value1.format=vhpiStrVal; value1.bufSize = vhpi_get(vhpiSizeP, vhpiH); value1.value.str = (char*)malloc(value1.bufSize*sizeof(char)+1); if (vhpi_get_value(vhpiH, &value1) == 0) { binVal = value1.value.str; value_int = uvm_hdl_btoi(binVal); value->aval = (PLI_UINT32) value_int; value->bval = 0; mhpi_release_parent_handle(mhpiH); free(value1.value.str); return(1); } else { mhpi_release_parent_handle(mhpiH); free(value1.value.str); return (0); } } #endif /* * Given a path, look the path name up using the PLI * or the VHPI, and return its 'value'. */ int uvm_hdl_read(char *path, p_vpi_vecval value) { #ifndef VCSMX return uvm_hdl_get_vlog(path, value, vpiNoDelay); #else mhpi_initialize('/'); mhpiHandleT h = mhpi_handle_by_name(path, 0); if (mhpi_get(mhpiPliP, h) == mhpiVpiPli) { mhpi_release_parent_handle(h); return uvm_hdl_get_vlog(path, value, vpiNoDelay); } else if (mhpi_get(mhpiPliP, h) == mhpiVhpiPli) { mhpi_release_parent_handle(h); return uvm_hdl_get_mhdl(path,value); } #endif } /* * Mixed Language API Set calls */ #ifdef VCSMX int uvm_hdl_set_mhdl(char *path, p_vpi_vecval value, mhpiPutValueFlagsT flags) { mhpi_initialize('/'); mhpiRealT forceDelay = 0; mhpiRealT cancelDelay = -1; mhpiReturnT ret; mhpiHandleT h = mhpi_handle_by_name(path, 0); mhpiHandleT mhpi_mhRegion = mhpi_handle(mhpiScope, h); int val = value->aval; char *force_value = uvm_hdl_dtob(val); ret = mhpi_force_value(path, mhpi_mhRegion, force_value, flags, forceDelay, cancelDelay); mhpi_release_parent_handle(h); if (ret == mhpiRetOk) { return(1); } else return(0); } #endif /* * Given a path, look the path name up using the PLI * or the VHPI, and set it to 'value'. */ int uvm_hdl_deposit(char *path, p_vpi_vecval value) { #ifndef VCSMX return uvm_hdl_set_vlog(path, value, vpiNoDelay); #else mhpi_initialize('/'); mhpiHandleT h = mhpi_handle_by_name(path, 0); if (mhpi_get(mhpiPliP, h) == mhpiVpiPli) { mhpi_release_parent_handle(h); return uvm_hdl_set_vlog(path, value, vpiNoDelay); } else if (mhpi_get(mhpiPliP, h) == mhpiVhpiPli) { mhpi_release_parent_handle(h); return uvm_hdl_set_mhdl(path, value, mhpiNoDelay); } else return (0); #endif } /* * Given a path, look the path name up using the PLI * or the VHPI, and set it to 'value'. */ int uvm_hdl_force(char *path, p_vpi_vecval value) { #ifndef VCSMX return uvm_hdl_set_vlog(path, value, vpiForceFlag); #else mhpi_initialize('/'); mhpiHandleT h = mhpi_handle_by_name(path, 0); if (mhpi_get(mhpiPliP, h) == mhpiVpiPli) { mhpi_release_parent_handle(h); return uvm_hdl_set_vlog(path, value, vpiForceFlag); } else if (mhpi_get(mhpiPliP, h) == mhpiVhpiPli) { mhpi_release_parent_handle(h); return uvm_hdl_set_mhdl(path, value, mhpiForce); } else return (0); #endif } /* * Given a path, look the path name up using the PLI * or the VHPI, and release it. */ int uvm_hdl_release_and_read(char *path, p_vpi_vecval value) { return uvm_hdl_set_vlog(path, value, vpiReleaseFlag); } /* * Given a path, look the path name up using the PLI * or the VHPI, and release it. */ int uvm_hdl_release(char *path) { s_vpi_vecval value; p_vpi_vecval valuep = &value; #ifndef VCSMX return uvm_hdl_set_vlog(path, valuep, vpiReleaseFlag); #else mhpi_initialize('/'); mhpiHandleT h = mhpi_handle_by_name(path, 0); mhpiReturnT ret; if (mhpi_get(mhpiPliP, h) == mhpiVpiPli) { return uvm_hdl_set_vlog(path, valuep, vpiReleaseFlag); } else if (mhpi_get(mhpiPliP, h) == mhpiVhpiPli) { mhpiHandleT mhpi_mhRegion = mhpi_handle(mhpiScope, h); ret = mhpi_release_force(path, mhpi_mhRegion); if (ret == mhpiRetOk) { return(1); } else return(0); } else return (0); #endif }