南宁网站建设 南宁联达亿,时尚女装网站模版,专做教育网站拿站,wordpress虚拟资源作者#xff1a;西南交通大学研究生导师邸志雄博士。
VPI:
Verilog Prodecure Interface(VPI), 最开始也称作PLI 2.0, 一个主要面向C语言的接口. 可以让行为级别的Verilog代码调用C函数, 让C函数调用标准Verilog系统函数.
1 // adder.c2#include vpi_user.h34stat…作者西南交通大学研究生导师邸志雄博士。
VPI:
Verilog Prodecure Interface(VPI), 最开始也称作PLI 2.0, 一个主要面向C语言的接口. 可以让行为级别的Verilog代码调用C函数, 让C函数调用标准Verilog系统函数.
1 // adder.c2#include vpi_user.h34static int sum_compiletf(char *user_data)5{6 fprintf(stderr, Yes, youcompiled me\n);7 return 0;8}9
10static int sum (char *user_data)
11{
12 vpiHandle systfref, args_iter,argh;
13 // typedef struct t_vpi_values_vpi_value
14 struct t_vpi_value argval;
15 unsigned int value, value2;
16 char res[1024];
17
18 systfref vpi_handle(vpiSysTfCall,NULL);
19 args_iter vpi_iterate(vpiArgument, systfref); // 迭代所有参数.
20
21 argh vpi_scan(args_iter); // 获取下一个参数
22 argval.format vpiIntVal; // 设定格式为int
23 vpi_get_value(argh, argval); //获取参数值
24 value argval.value.integer; // 读取获取到的参数值
25
26 argh vpi_scan(args_iter); // 获取下一个参数
27 argval.format vpiHexStrVal; // 以hex格式读入
28 vpi_get_value(argh, argval);
29 sscanf(argval.value.str, %x,value2); // 将hex str格式读入的值转换为int
30
31 argh vpi_scan(args_iter); // 获取第三个参数
32 argval.format vpiHexStrVal; // 设置格式为hex str, verilog读取的时候会自动转换的.
33 sprintf(res, %x, value value2); // 在C里计算两个值的和, 并将其转换为hex格式的字符串
34
35 argval.value.str res;
36 vpi_put_value(argh, argval, 0,vpiNoDelay); // 设置第三个参数的值
37
38 vpi_put_value(systfref,argval, 0, vpiNoDelay);
39 vpi_free_object(args_iter);
40 return 0;
41}
42
43
44// 注册 $sum
45void sum_register() {
46 s_vpi_systf_data tf_data;
47
48 tf_data.type vpiSysTask; // 类型. 还有一个是SysFunc
49 tf_data.tfname $sum; // 在verilog中调用的名称
50 tf_data.calltf sum; // 被verilog调用时调用的函数
51 tf_data.compiletf sum_compiletf; //被编译时调用的函数
52 tf_data.sizetf 0; // 不知道
53 tf_data.user_data 0; // 不知道
54 vpi_register_systf(tf_data); //注册
55}
56
57
58
59// 在这个函数数组里的函数会自动被调用.
60void (*vlog_startup_routines[])() {
61 sum_register,
62 0
63};1 // adder_tb.v2timescale 1ns/1ns3module adder_tb();4 reg [3:0] a;5 reg [3:0] b;6 wire [7:0] c;78 reg clk,rst_n;9
10 integer i, n, nf;
11
12 adder DUT (
13 .clk(clk),
14 .rst_n(rst_n),
15 .a(a),
16 .b(b),
17 .c(c)
18 );
19
20 always begin
21 #10 clk 0;
22 #10 clk 1;
23 end
24
25 initial begin
26 $display();
27 $display(Tb start athere);
28 rst_n 1;
29 n 0;
30 nf 0;
31 // $test($random%4,2);
32 for (i 0; i 20; i)
33 test($urandom%5b10000,$urandom%5b10000);
34 $display(%d total, %dfail, n, nf);
35 $finish;
36 end
37 task test;
38 input [3:0] in;
39 input [3:0] in2;
40 begin: test
41 reg [7:0] e;
42 a in;
43 b in2;
44 $sum(a,b,e); // HERE
45 (posedge clk);
46 (negedge clk);
47 n n 1;
48 if (c e) begin
49 $display(Itworks, %d %d %d, in, in2, e);
50 end else begin
51 nf nf 1;
52 $display(opps%d %d ~ %d, expect %d, in, in2, c, e);
53 end
54 end
55 endtask
56
57 // initial begin
58 //$dumpfile(wave.vcd);
59 // $dumpvars;
60 // end
61endmodule