基于VCS使用VPI在verilog中调用c调用python进行仿真
生活随笔
收集整理的這篇文章主要介紹了
基于VCS使用VPI在verilog中调用c调用python进行仿真
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
遇到了這樣一個需求,許多驗證人員用python用的很熟練,但是只能通過vpi調用c代碼,要用c代碼實現相同功能的python代碼過于繁瑣,所以想著能不能在c中調用python中的方法,將其包一層變為c函數,然后用vpi調用這個c函數來實現:
首先解決c調用python
main.c代碼如下(引入頭文件 Python.h ):
代碼中展示了調用有參python方法和無參python方法兩種用法
#include <stdio.h> #include <Python.h>/* function callPythonFun();pyName ----> python文件名funcName---> python文件中要調用的函數名pArg ------> 通過Py_BuildValue()格式化好的參數 */ 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); //從字典屬性中獲取函數// 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); //調用函數,并得到python類型的返回值return result; }int main() {// 直接調用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); //參數類型轉換,傳遞兩個整型參數PyObject* result = callPythonFun("mypy","add",pArg);// 使用接口調用python腳本中函數add(a,b)int sum = 0;PyArg_Parse(result, "i", &sum); //將python類型的返回值轉換為c/c++類型, "i" ->>> intprintf("result = %d\n", sum);// example 2callPythonFun("mypy","printcharint",NULL);//無參數的情況//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這里重點是鏈接上Python To C的庫,具體的頭文件和庫文件位置需要對應自己的環境
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后運行run結果如下:
[lee@ubuntu runpyinc]$ ./run in python function add result = 3 charinfo 1解決基于VCS使用vpi調用包含了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); //參數類型轉換,傳遞兩個整型參數PyObject* result = callPythonFun("mypy","add",pArg);// 使用接口調用python腳本中函數add(a,b)int sum = 0;PyArg_Parse(result, "i", &sum); //將python類型的返回值轉換為c/c++類型, "i" ->>> intprintf("result = %d\n", sum);// example 2callPythonFun("mypy","printcharint",NULL);//無參數的情況//close python environmentPy_Finalize(); }hello_world()即為包了一層的c調用python的方法,就是上面的main函數,因為只是被vpi調用,c中不需要有主函數的概念了
然后編譯生成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,具體的路徑還是要對應自己的環境,我這里是在VCS的目錄下找到的
然后構建VCS仿真環境
已一個簡單的案例為例:
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; //調用c中的調用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中有參數和無參數的方法都已被正確調用,實際使用時還會向c中傳參,還要交互等等,就看具體需求具體修改了,本文只是拼湊出了一種基于VCS使用VPI調用c再調用python的方法,具體效果不再詳述。
總結
以上是生活随笔為你收集整理的基于VCS使用VPI在verilog中调用c调用python进行仿真的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 转岗大数据了,先用数据看看行情
- 下一篇: msys2编译php,MSYS2初体验