[verilog]如何在modelsim中使用PLI功能

代码如下:

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








你可能感兴趣的:([verilog]如何在modelsim中使用PLI功能)