如何使用 DPI-C 嵌入 Systemverilog 解释器? [英] How to Embed Systemverilog Interpreter using DPI-C?

查看:59
本文介绍了如何使用 DPI-C 嵌入 Systemverilog 解释器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题描述:

我在 SystemVerilog 中进行设计并使用相同的语言编写测试平台.我希望能够在模拟过程中编译我的设计并测试不同的功能,就像您使用带有 e 的解释器一样.理想情况下,当模拟器碰到某条线路时,我会在模拟时弹出一个终端.

I design in SystemVerilog and write the testbenches in the same language. I want to be able to compile my design and test different functions during simulation in the way you would using an interpreter with e. Ideally, I would have a terminal pop-up upon simulation when the simulator hit some line.

潜在想法:

我查看了 DPI-C,似乎我必须导出"项目中的所有任务才能从解释器中运行它们.但是,我不确定如何自动执行此操作或是否有更好的方法.此外,我不知道如何让 C 为我打开第二个 shell 来输入 SystemVerilog 任务(我想运行).

I've looked at the DPI-C and it seems like I would have to "export" all tasks in my project in order to run them from the interpreter. However, I'm not sure how to do this automatically or if there's a better way. Furthermore, I have no idea how I would get C to open up a second shell for me to type the SystemVerilog tasks in (that I would want to run).

这是我的同事回应的一个问题,如果在编译一个测试平台之间不必等待 10 分钟,这会让生活少很多痛苦.

This is a problem echoes by my colleagues and it would make life a lot less painful to not have to wait 10 minutes between compiling just a testbench.

推荐答案

我提供了另一个例子.

示例SV-CODE

 ////////////////////////////////////////////////////////////////////////
 //IMPORT FUNCTION DPI DECLARATION FROM C
 ////////////////////////////////////////////////////////////////////////            
import "DPI-C" function void python_sign_msg(string key_file_name, string msg_file_name, string signed_file_name );
import "DPI-C" function string return_string_in_c(string text, inout string output_txt);    
    

typedef class keycontrol_seq_handles;
//-----------------------
class keycontrol_predictor#(int PARAM_PLACEHOLDER = 1) extends pve_predictor#(keycontrol_seq_handles);//extends uvm_component;
………..
//////////////////////
//USE OF DPI
//////////////////////
string output_c,output2_c;
output_c = return_string_in_c("This text",output2_c); 
python_sign_msg("file.txt","bla","blo");

endclass 

C 代码

//include DPI
#include "svdpi.h"
//include the IO files
#include <stdio.h>
//include string functions
#include <string.h>
//include use of malloc
#include <stdlib.h>
//include Phyton embed lib
#include <Python.h>
 
 
//to add the ability to use printf
// same inputs as defined in SV with python path which is the defined surrounded by double quotes ""

#ifndef PYTHON_PATH
#error You must define the path to the python file in gcc compiler with -D 'PYTHON_PATH="'$PYTHON_DIR'"' or vlog with -ccflags "-I/usr/include/python2.6/ -D 'PYTHON_PATH=\"$PYTHON_DIR\"'"
#endif
 
 /* function declaration */
void python_sign_msg( char *key_file_name, char *msg_file_name, char *signed_file_name ) {
 
         
          char *append_path = malloc(sizeof(char) * 1000);
          append_path = PYTHON_PATH":.";
          printf("Append to path is:\n%s\n", append_path);           
          setenv("PYTHONPATH",append_path,1);//Set PYTHONPATH TO working directory https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.1.0/com.ibm.zos.v2r1.bpxbd00/setenv.htm
          char *path = Py_GetPath();
          printf("Python search path is:\n%s\n", path);
          
          int argc;
          char * argv[2];
          char *phyton_script_name = malloc(sizeof(char) * 100);
          phyton_script_name = "test";//don't use the .py extension here
          
          
          argc = 3;//argument count is 3 arguments
          argv[0] = phyton_script_name;//key_file_name;//"mymod";//the argument value vector is
          argv[1] = "4";
          argv[2] = "3";
          
           Py_Initialize();// Initialize the Python Interpreter
           
           //First import python script module name
           
           PySys_SetArgv(argc, argv);//set the previous arguments as calling arguments of the import module
           //PyObject* myPmodule = PyImport_ImportModule("sign_hmac-sha256");//don't put the .py extension here
           PyObject* myPmodule = PyImport_ImportModule(phyton_script_name);//IMPORTANT THE MAIN MODULE IS EXECUTED here with the PySys_SetArgv arguments
           if(myPmodule==NULL)
           {
               printf("Not able to load&execute main phyton script:\n%s\n", phyton_script_name);
               PyErr_Print();
           }
           ///////////////////////////////
           //Extract variables through dict
           //////////////////////////////
           //retrieve all variables and functions of the module in a namespace or dict
           PyObject *module_dict   = PyModule_GetDict(myPmodule);
          
           char *function_name = malloc(sizeof(char) * 100);
           function_name = "suma";//don't use the .py extension here
           //getting the reference to the specific python function you want from the python script
           PyObject* myPfunction = PyObject_GetAttrString(myPmodule, function_name);

           if (PyCallable_Check(myPfunction))
           {
               //EXAMPLE CREATE arguments in Python 
               //PyObject* myPargs=Py_BuildValue("(z)",(char*)"something");
               //PyObject* myPargs = PyTuple_Pack(1,PyFloat_FromDouble(2.0));
               //ok = PyArg_ParseTuple(args, "lls", &k, &l, &s); /* Two longs and a string */
               //PyObject* myPargs = Py_BuildValue("sss",key_file_name,msg_file_name,signed_file_name); /* Three strings */
               //Execute the function with arguments directly
               //PyObject* result = PyObject_CallObject(myPfunction, (char*)"something", (char*)"something", (char*)"something");/* Three strings */               
               //PyObject* myPargs = Py_BuildValue("zz","4" ,"3");
               PyObject* myPargs = Py_BuildValue("ii",4 ,3);
               PyObject* item=PyTuple_GetItem(myPargs,0);//get the item of the tuple position 0 
               printf("Python tuple: %d\n", (int)PyInt_AsSsize_t(item)); /*incase an integer*/
               //printf("Python tuple: %s\n", PyString_AsString(item));
               PyErr_Print();               
               PyObject* result = PyObject_CallObject(myPfunction, myPargs);//the myPargs must be always be a Pyobject               
               
               PyErr_Print();
               Py_DECREF(myPargs);
               Py_DECREF(item);
               Py_DECREF(result);
           } else 
           {
               printf("The function:\n%s\n", function_name);
               //Pring errors comming from Python
               PyErr_Print();
           }
           
           
           ////////////////////////////////////////
           // Clean up phase
           ////////////////////////////////////////
           Py_DECREF(myPmodule);
           Py_DECREF(myPfunction);
           
           
           
           Py_Finalize();// Finish the Python Interpreter
}
 
 /* function declaration text char stream passed as pointer value and text2 passed as pointer reference */
  char * return_string_in_c( char *text,  char **text2) {
    char *fix="This variable cannot be changed although it is a pointer, just as example";/*fix allocation and constant*/
    char dest[50]="Variable array created in a function:";/* String array max 50 chars allocated*/
    char *out = malloc(sizeof(char) * 100);/* Dynamic string max 100 chars allocated*/
    /* Concatenate input text and put in out of strcat*/
    //strcat(out, text);/* initialize out using text string*/
    snprintf(out, sizeof(char) * 100, "%s%s", out,text);
    printf("fix : |%s|,dest : |%s|,text : |%s|,out : |%s|\n", fix,dest,text,out);
    *text2=dest;/* allocate pointer value with dest*/
    *text2=out;/* allocate pointer value with out*/
    return out;
}
 
 /* main */
 void main() {
    char text[100]="from_main_text_variable";/*max 100 chars allocated*/
    char *text2;/* pointer not allocated*/
    char *point = return_string_in_c(text, &text2);/* &text2 passing by reference*/
    printf("Final destination string : |%s|\n", text2);
    printf("point output : |%s|\n", point);       
    
    printf("DEFINED PYTHON_PATH: |%s|\n", PYTHON_PATH);
    python_sign_msg("","","");
    printf("Finished python\n");
    
 }

Python 脚本 - TEST.py,删除 TABS 非常重要!!!!!!

PYTHON SCRIPT - TEST.py, very important to remove TABS!!!!!!

#!/usr/bin/python
# This program adds two numbers
import sys
 
if( len( sys.argv ) < 3 ) :
    raise( Exception( "Usage: test.py number1 number2" ) )
 
num1 = int(sys.argv[ 1 ])
print "sys.argv[ 1 ] : ",int(sys.argv[ 1 ])
num2 = int(sys.argv[ 2 ])
print "sys.argv[ 2 ] : ", int(sys.argv[ 2 ])
 
#the suma function definition
def suma( arg1, arg2 ):
    # Add both the parameters and return them."
    total = arg1 + arg2; # Here total is local variable.
    print "Inside the function local total : ", total
    return total;
 
# Display the suma
print('The sum using suma function of {0} and {1} is {2}'.format(num1, num2, suma(num1,num2)))
 
#num1 = 1.5
#num2 = 6.3
# Add two numbers
sum = float(num1) + float(num2)
# Display the sum
print('The sum of {0} and {1} is {2}'.format(num1, num2, sum))
 
 
#a dummy function definition
def multiply():
   c = 12345*6789
   print 'The result of 12345 x 6789 :', c
   return c

最后,您必须使用供应商流程编译文件.例如,Questa1) 您使用 ccflags 编译 C 代码并引入要添加的定义.在我们的例子中,我们的 C 代码需要定义 PYTHON_PATH

Lastly, you have to compile the files using your vendor flow. For example, Questa 1) You compile the C code using ccflags and introducing the defines you want to add. In our case our C code need the define PYTHON_PATH

vlog $DUT_VLOG_ARGS ${TB_DIR}/your_C_code.c -ccflags "-I/usr/include/python2.6/  -D 'PYTHON_PATH=\"$PYTHON_DIR\"'"

2) 在 Questa 中,如果您有 python,则必须调用 vsim 包括 -ldflags '-lpython2.6'类似的东西:

2) In Questa if you have python you have to call vsim including -ldflags '-lpython2.6' Something like:

vsim -ldflags '-lpython2.6'  -voptargs="+acc" -solvefaildebug -assertdebug -onfinish stop +UVM_TESTNAME=${TESTCASE_STRING}  yourtop_tb_top \

Synopsys VCS1) 您使用 ccflags 编译 C 代码并引入要添加的定义.在我们的例子中,我们的 C 代码需要定义 PYTHON_PATH

Synopsys VCS 1) You compile the C code using ccflags and introducing the defines you want to add. In our case our C code need the define PYTHON_PATH

#GCC in two steps for shared object
gcc -g -D 'PYTHON_PATH="'$PYTHON_DIR'"'  -fPIC -Wall -I${VCS_HOME}/include -I/usr/include/python2.6/ -lpython2.6 -c ${PROJECTDIR}/verification/PVE/keycontrol/tb/keycontrol_C_code_wrapper.c 
gcc -fPIC -shared -o keycontrol_C_code_wrapper.so  keycontrol_C_code_wrapper.o 

2) 您进行 VCS 详细说明,将 python 库与 -LDFLAGS '-lpython2.6'

2) You do the VCS elaboration linking the python lybrary with -LDFLAGS '-lpython2.6'

vcs -timescale=1ps/1ps -ntb_opts uvm -lca -kdb -full64 keycontrol_tb_top -debug_access+all+reverse  -LDFLAGS '-lpython2.6'

3) 您运行创建的模拟文件.您调用 simv 包括 -sv_lib keycontrol_C_code_wrapper 以导入 C 共享对象.

3) You run the created simulation file. You call simv including -sv_lib keycontrol_C_code_wrapper to import the C shared object.

#RUN C CODE
./simv -gui -ucli +DVE +UVM_NO_RELNOTES  -l simv.log  +UVM_TESTNAME=keycontrol_basic_test -do ../../verification/PVE/keycontrol/tools/keycontrol_ucli_init.synopsys -sv_lib keycontrol_C_code_wrapper

其他工具会有另一个流程.

Another tools would have another flow.

在你的 Python 脚本中嵌入 python 是一种比 FILE IO [b]更高效[/b] 的解决方案.

Embedding python is a solution that is [b]more efficient[/b] than FILE IO in your python script.

如果您的 python 脚本从文件读取输入和输出,那么从 Systemverilog 调用 python 的最简单方法就是执行系统调用.

If your python script reads inputs and outputs from files, then the easiest way to call python from Systemverilog is just by doing a system call.

$system("python yourscript.py filenamein filenameout ")

您当然必须在 systemverilog 中写入您的输入文件并在 systemverilog 中读取输出文件以进行比较.

You have of course to write in systemverilog your input file and read in systemverilog the output file for comparison.

这篇关于如何使用 DPI-C 嵌入 Systemverilog 解释器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆