代码如下:
https://github.com/adream307/PLITest.git
modelsim中的PLI功能,使得用于可以用C语言编写自己的函数,然后在modelsim中想调用系统函数一样调用用户定义的函数。
在这个例子中,用户自定义函数实现简单的8位有符号数相加的功能,代码如下:
//test_pli.c #include"veriuser.h" #include"acc_user.h" int test(int,int); int test_sizetf() { return 8; } int test_calltf() { int x,y,r; x=tf_getp(1); y=tf_getp(2); r=test(x,y); tf_putp(0,r); return 0; } int test_checktf() { bool err=FALSE; if(tf_nump()!=2){ tf_error("$test requires exactly 2 arguments.\n"); err=TRUE; } if(tf_typep(1) == tf_nullparam){ tf_error("$test's first argument can't be null"); err=TRUE; } if(tf_typep(2) == tf_nullparam){ tf_error("$test's second argument can't be null"); err=TRUE; } if(tf_sizep(1)>8){ tf_error("$test's first argument can't longer than 8 bits"); err=TRUE; } if(tf_sizep(2)>8){ tf_error("$test's second argument can't longer than 8 bits"); err=TRUE; } if (err) { tf_message(ERR_ERROR, "", "", ""); } return(0); } int test(int x,int y) { return x+y; } s_tfcell veriusertfs[] = { {userfunction, // type of PLI routine - usertask or userfunction 0, // user_data value test_checktf, // checktf() routine test_sizetf, // sizetf() routine test_calltf, // calltf() routine 0, // misctf() routine "$test" // "$tfname" system task/function name }, {0} // final entry must be 0 };
在verilog代码中通过调用$test调用这个用户自定义的系统函数,代码如下:
`timescale 1ps/1ps //test_pli.v module test_pli(); reg clk; initial begin clk=0; forever begin #10; clk=~clk; end end reg signed [7:0] x; reg signed [7:0] y; reg signed [7:0] z1; reg signed [7:0] z2; reg err; initial begin x=-100; y=-100; z1=0; z2=0; err=0; repeat(4)@(negedge clk); repeat(200) begin repeat(200) begin @(negedge clk); z1=$test(x,y); $display("%d + %d = %d",x,y,z1); z2=x+y; if(z1!=z2) begin $display("error at x=%d, y=%d",x,y); err=1; end y=y+1; end x=x+1; end if(err) $display("Something is wrong through the calculation."); else $display("success"); $display("Finish"); $finish; end endmodule
makefile文件及do文件如下:
#sim.do onbreak {resume} onerror {quit -f} run -all simstats quit -f
MTI_HOME=/opt/modelsim6.5/modeltech CC=gcc -c -I$(MTI_HOME)/include LD=ld -shared -E -o test_pli.dll : test_pli.c test_pli.v $(CC) test_pli.c $(LD) test_pli.dll test_pli.o vlib work vlog -sv test_pli.v vsim -c -vopt test_pli -pli ./test_pli.dll -do sim.do clean: rm -rf work rm -rf vsim.wlf rm -rf transcript rm -rf test_pli.o rm -rf test_pli.dll