基于VCS使用VPI在verilog中调用c调用python进行仿真
遇到了這樣一個需求,許多驗(yàn)證人員用python用的很熟練,但是只能通過vpi調(diào)用c代碼,要用c代碼實(shí)現(xiàn)相同功能的python代碼過于繁瑣,所以想著能不能在c中調(diào)用python中的方法,將其包一層變?yōu)閏函數(shù),然后用vpi調(diào)用這個c函數(shù)來實(shí)現(xiàn):
首先解決c調(diào)用python
main.c代碼如下(引入頭文件 Python.h ):
代碼中展示了調(diào)用有參python方法和無參python方法兩種用法
#include <stdio.h> #include <Python.h>/* function callPythonFun();pyName ----> python文件名funcName---> python文件中要調(diào)用的函數(shù)名pArg ------> 通過Py_BuildValue()格式化好的參數(shù) */ PyObject* callPythonFun(char* pyName,char* funcName,PyObject* pArg){PyObject* pModule = NULL;// PyObject* pDict = NULL;PyObject* pFunc = NULL;PyObject* result = NULL;// PyRun_SimpleString("import os");PyRun_SimpleString("import sys");// PyRun_SimpleString("print(os.listdir(\"./\"))");// PyRun_SimpleString("sys.path.append(\"/netapp/home/wenqi/tools/runpyinc\")");PyRun_SimpleString("sys.path.append(\"./\")");// change path to current filepModule = PyImport_ImportModule(pyName); //引入py fileif (!pModule){printf("[ERROR]can't import python file\n");return ;}pFunc = PyObject_GetAttrString(pModule, funcName); //從字典屬性中獲取函數(shù)// printf("[NOTE]loading......\n");// pFunc = PyObject_GetAttrString(pModule, "add");if (!pFunc || !PyCallable_Check(pFunc)){printf("[ERROR]can't find function in python file\n");return ;}result = PyEval_CallObject(pFunc, pArg); //調(diào)用函數(shù),并得到python類型的返回值return result; }int main() {// 直接調(diào)用python腳本的方法// FILE * fp;// char buffer[80];// fp=popen("python test.py","r");// fgets(buffer,sizeof(buffer),fp);// printf("%s",buffer);// pclose(fp);//init python environmentPy_Initialize();if (Py_IsInitialized()){// printf("init\n");}else{printf("[ERROR]py init fail\n");return ;}// example 1PyObject* pArg = Py_BuildValue("(i, i)", 1, 2); //參數(shù)類型轉(zhuǎn)換,傳遞兩個整型參數(shù)PyObject* result = callPythonFun("mypy","add",pArg);// 使用接口調(diào)用python腳本中函數(shù)add(a,b)int sum = 0;PyArg_Parse(result, "i", &sum); //將python類型的返回值轉(zhuǎn)換為c/c++類型, "i" ->>> intprintf("result = %d\n", sum);// example 2callPythonFun("mypy","printcharint",NULL);//無參數(shù)的情況//close python environmentPy_Finalize();return 0; }makefile文件:
all: run run: main.o@gcc -L/usr/lib64/python3.4/ -lpython3 main.o -o run main.o: main.c@gcc -c -w main.c -I/usr/include/python3.4/ clean:@rm -rf *.pyc run這里重點(diǎn)是鏈接上Python To C的庫,具體的頭文件和庫文件位置需要對應(yīng)自己的環(huán)境
mypy.py:
#!/tools/bin/python3 import os import re import sysdef add(a,b):print("in python function add")return a + bdef testout():print ("in python function testout")def printcharint():charf = "charinfo"intf = 1print(charf + " " + str(intf))if __name__=="__main__":print("in python")make后運(yùn)行run結(jié)果如下:
[lee@ubuntu runpyinc]$ ./run in python function add result = 3 charinfo 1解決基于VCS使用vpi調(diào)用包含了python的c
首先c文件要引入vpi_user.h
mod_info.c:
#include <stdio.h> #include "vpi_user.h" #include <Python.h> void module_info() {vpiHandle moditH, topmodH;moditH = vpi_iterate(vpiModule, NULL);if(!moditH) {vpi_printf(" Error: no modules in the design\n");}while (topmodH = vpi_scan(moditH)) {vpi_printf("Top module Full Name: %s\n",vpi_get_str(vpiFullName, topmodH));vpi_printf(" Top module Name: %s\n", vpi_get_str(vpiName, topmodH));} } void register_my_systfs() {s_vpi_systf_data task_data_s;p_vpi_systf_data task_data_p = &task_data_s;task_data_p->type = vpiSysTask;task_data_p->tfname = "$module_info";task_data_p->calltf = (int(*)()) module_info;task_data_p->compiletf = 0;vpi_register_systf(task_data_p); }PyObject* callPythonFun(char* pyName,char* funcName,PyObject* pArg){ //………………………………略 }void hello_world(){vpi_printf("*********this is print by vpi************\n");Py_Initialize();if (Py_IsInitialized()){// printf("init\n");}else{printf("[ERROR]py init fail\n");return ;}// example 1PyObject* pArg = Py_BuildValue("(i, i)", 1, 2); //參數(shù)類型轉(zhuǎn)換,傳遞兩個整型參數(shù)PyObject* result = callPythonFun("mypy","add",pArg);// 使用接口調(diào)用python腳本中函數(shù)add(a,b)int sum = 0;PyArg_Parse(result, "i", &sum); //將python類型的返回值轉(zhuǎn)換為c/c++類型, "i" ->>> intprintf("result = %d\n", sum);// example 2callPythonFun("mypy","printcharint",NULL);//無參數(shù)的情況//close python environmentPy_Finalize(); }hello_world()即為包了一層的c調(diào)用python的方法,就是上面的main函數(shù),因?yàn)橹皇潜籿pi調(diào)用,c中不需要有主函數(shù)的概念了
然后編譯生成mod_info.o
makefile如下:
mod_info.o: mod_info.c@gcc -c -w -fPIC mod_info.c -I/usr/include/python3.4/ -I/tools/install/synopsys/vcs_mx/vO-2018.09-SP2/include clean:@rm -rf *.o這里與上面的不同是要添加上vpi_user.h頭文件所在的目錄,并且只需要生成.o,具體的路徑還是要對應(yīng)自己的環(huán)境,我這里是在VCS的目錄下找到的
然后構(gòu)建VCS仿真環(huán)境
已一個簡單的案例為例:
pipe.v:
module pipe ( out, in, clk );output out; reg out;input in, clk;always @ (in)@ (posedge clk)out <= repeat (2) @ (posedge clk) in; endmoduletest.v:
module hello;wire a, b, c;initialbegin$hello_world; //調(diào)用c中的調(diào)用python的方法$module_info;endpipe p1 (a, b, c);//stimuli//monitor response endmodulevpi.tab:
$module_info call=module_info $hello_world call=hello_world啟動腳本runvcs.sh:
vcs -R -full64 -fsdb -sverilog +vpi \ -v pipe.v \ test.v \ -lpython3 \ -P vpi.tab mod_info.o最終的VCS仿真報告
../simv up to date Chronologic VCS simulator copyright 1991-2018 Contains Synopsys proprietary information. Compiler version O-2018.09-SP2-11_Full64; Runtime version O-2018.09-SP2-11_Full64; May 17 16:15 2022 *********this is print by vpi************ in python function add result = 3 charinfo 1 Top module Full Name: helloTop module Name: helloV C S S i m u l a t i o n R e p o r t Time: 0 CPU Time: 0.290 seconds; Data structure size: 0.0Mb可以看到python中有參數(shù)和無參數(shù)的方法都已被正確調(diào)用,實(shí)際使用時還會向c中傳參,還要交互等等,就看具體需求具體修改了,本文只是拼湊出了一種基于VCS使用VPI調(diào)用c再調(diào)用python的方法,具體效果不再詳述。
總結(jié)
以上是生活随笔為你收集整理的基于VCS使用VPI在verilog中调用c调用python进行仿真的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 转岗大数据了,先用数据看看行情
- 下一篇: qpython kivy_Kivy和PY