diff --git a/.gitignore b/.gitignore index 2b7b337..fd123ee 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,9 @@ me241102_vpi/*.o me241102_vpi/*.so me241103_cRe/main + +me250300_pli/00_func_return/vcsworks/ +me250300_pli/00_func_return/verdiLog/ +me250300_pli/00_func_return/novas.conf +me250300_pli/00_func_return/novas.rc +me250300_pli/00_func_return/*.swp diff --git a/me250300_pli/00_func_return/Makefile b/me250300_pli/00_func_return/Makefile new file mode 100644 index 0000000..e3cdb64 --- /dev/null +++ b/me250300_pli/00_func_return/Makefile @@ -0,0 +1,33 @@ +LSB_RELEASE = $(shell lsb_release -is) +LSB_VERSION = $(shell lsb_release -rs) +ifeq (${LSB_RELEASE}, Ubuntu) + ifeq ($(shell echo "${LSB_VERSION}>18.04" | bc), 1) + CC = gcc-4.8 + CPP = g++-4.8 + else + CC = gcc + CPP = g++ + endif +else + CC = gcc + CPP = g++ +endif + +comp_c: + - gcc -fPIC -shared -o ./vcsworks/libfunc.so func.c -I ${VCS_HOME}/include +comp: comp_c + - pushd ./vcsworks && vcs -full64 +v2k -sverilog -LDFLAGS -Wl,--no-as-needed -cc $(CC) -cpp $(CPP)\ + -P ${VERDI_HOME}/share/PLI/VCS/LINUX64/novas.tab ${VERDI_HOME}/share/PLI/VCS/LINUX64/pli.a \ + -P ../func.tab \ + +vcs+fsdbon -debug_access+all -kdb\ + -top testbench -l compile.log -timescale=1ns/1ps\ + ../testbench.sv && popd + +sim: + - pushd vcsworks && ./simv -l sim.log +fsdbfile+wave.fsdb -load ./libfunc.so -ucli -do ../func.tcl && popd + +verdi: + - verdi -ssf wave.fsdb -sswr signal.rc & + +clean: + - \rm -rf vcsworks/* diff --git a/me250300_pli/00_func_return/ReadMe.md b/me250300_pli/00_func_return/ReadMe.md new file mode 100644 index 0000000..a151377 --- /dev/null +++ b/me250300_pli/00_func_return/ReadMe.md @@ -0,0 +1,27 @@ +# 获取call的返回值 + +## 概述 + +使用call调用pli编写的function, 尝试获取function的返回值。 + +## 快速开始 + +### 一、编译 + +```bash +make comp +``` + +### 二、运行 + +```bash +make sim +``` +### 三、结果 + +在sv中可以正常获取函数的返回值,但是在tcl中使用call命令只能获取INT整数值。 +按16进制转10进制,然后查ASCII表可以转换成字符串。 + +*在公司服务器,使用vcs2020.03无法复现。call命令获得的INT整数值全是0* + + diff --git a/me250300_pli/00_func_return/func.c b/me250300_pli/00_func_return/func.c new file mode 100644 index 0000000..dff6b0e --- /dev/null +++ b/me250300_pli/00_func_return/func.c @@ -0,0 +1,36 @@ +#include +#include + +void get_arg(PLI_BYTE8 *user_data) +{ + // 变量定义 + s_vpi_value value_s; + vpiHandle systf_handle, arg_iter, arg_handle; + + // 获取函数调用的句柄 + systf_handle = vpi_handle(vpiSysTfCall, NULL); + // 从句柄中获取参数迭代器 + arg_iter = vpi_iterate(vpiArgument, systf_handle); + if(arg_iter == NULL){ + vpi_printf("ERROR: failed to obtain systf arg handles\n"); + vpi_control(vpiFinish, 1); /* abort simulation */ + return; + } + + // 迭代获取第一个参数 + arg_handle = vpi_scan(arg_iter); + value_s.format = vpiStringVal; + vpi_get_value(arg_handle, &value_s); + PLI_BYTE8 *arg1 = value_s.value.str; + + // 释放迭代器 + vpi_free_object(arg_iter); /* because not scanning until null */ + + vpi_printf("arg[1] = %s", arg1); + + /* write result to simulation as return value $pow */ + value_s.format = vpiStringVal; + value_s.value.str = arg1; + vpi_put_value(systf_handle, &value_s, NULL, vpiNoDelay); + return; +} \ No newline at end of file diff --git a/me250300_pli/00_func_return/func.tab b/me250300_pli/00_func_return/func.tab new file mode 100644 index 0000000..17e9423 --- /dev/null +++ b/me250300_pli/00_func_return/func.tab @@ -0,0 +1 @@ +$get_arg call=get_arg size=88 \ No newline at end of file diff --git a/me250300_pli/00_func_return/func.tcl b/me250300_pli/00_func_return/func.tcl new file mode 100644 index 0000000..3af5f60 --- /dev/null +++ b/me250300_pli/00_func_return/func.tcl @@ -0,0 +1,18 @@ +config cmdecho off + +proc hex_to_ascii {hex_str} { + set result "" + foreach hex_pair [regexp -all -inline {..} $hex_str] { + set decimal [expr 0x$hex_pair] + set char [format %c $decimal] + append result $char + } + return $result +} + +set str [call {$get_arg("Hello world")}] +puts "\ntcl str = $str" + +set str_t [hex_to_ascii $str] + +puts "\ntcl str_t = $str_t" diff --git a/me250300_pli/00_func_return/testbench.sv b/me250300_pli/00_func_return/testbench.sv new file mode 100644 index 0000000..868da13 --- /dev/null +++ b/me250300_pli/00_func_return/testbench.sv @@ -0,0 +1,7 @@ +module testbench; + string str; + initial begin + str = $get_arg("Hello world"); + $display("\nstr = %s", str); + end +endmodule \ No newline at end of file diff --git a/me250300_pli/ReadMe.md b/me250300_pli/ReadMe.md new file mode 100644 index 0000000..c086578 --- /dev/null +++ b/me250300_pli/ReadMe.md @@ -0,0 +1,9 @@ +# pli + +pli是一系列学习pli的项目合集。 + +## 项目列表 + +| 项目 | 描述 | 状态 | 博客 | 备注 | +| ---------------------------------------------- | ----------------------------------------------------- | ---- | ------------------------------------------------------------ | ---- | +| [00_func_return](./00_func_return) | 在ucli中使用call获取PLI函数的返回值 | 100% | | |