- 註冊時間
- 2006-10-8
- 最後登錄
- 2019-6-20
- 主題
- 查看
- 積分
- 1306
- 閱讀權限
- 110
- 文章
- 1393
- 相冊
- 0
- 日誌
- 1
![Rank: 11](static/image/common/star_level3.gif) ![Rank: 11](static/image/common/star_level3.gif) ![Rank: 11](static/image/common/star_level2.gif) ![Rank: 11](static/image/common/star_level1.gif)
狀態︰
離線
|
# include <vpi_user.h>
static int hello_compiletf(char*user_data)
{
return 0;
}
static int hello_calltf(char*user_data)
{
vpi_printf("Hello, World!\n");
return 0;
}
void hello_register()
{
s_vpi_systf_data tf_data;
tf_data.type = vpiSysTask;
tf_data.tfname = "$hello";
tf_data.calltf = hello_calltf;
tf_data.compiletf = hello_compiletf;
tf_data.sizetf = 0;
tf_data.user_data = 0;
vpi_register_systf(&tf_data);
}
static int linkc_compiletf(char*user_data)
{
return 0;
}
static int linkc_calltf(char*user_data)
{
vpi_printf("Link C success!\n");
return 0;
}
void linkc_register()
{
s_vpi_systf_data tf_data;
tf_data.type = vpiSysTask;
tf_data.tfname = "$linkc";
tf_data.calltf = linkc_calltf;
tf_data.compiletf = linkc_compiletf;
tf_data.sizetf = 0;
tf_data.user_data = 0;
vpi_register_systf(&tf_data);
}
void (*vlog_startup_routines[])() = {
hello_register,
linkc_register,
0
};
檔案:hello2.v
module main;
initial $hello;
initial #100 $linkc;
initial #200 $linkc;
endmodule
編譯執行過程
D:\ccc101\Verilog\c>iverilog-vpi hello2.c
Compiling hello2.c...
Making hello2.vpi from hello2.o...
D:\ccc101\Verilog\c>iverilog hello2.v -o hello2.vvp
D:\ccc101\Verilog\c>vvp -M. -mhello2 hello2.vvp
Hello, World!
Hello, World!
Hello, World!
D:\ccc101\Verilog\c>iverilog-vpi hello2.c
Compiling hello2.c...
Making hello2.vpi from hello2.o...
D:\ccc101\Verilog\c>iverilog hello2.v -o hello2.vvp
D:\ccc101\Verilog\c>vvp -M. -mhello2 hello2.vvp
Hello, World!
Link C success!
Link C success!
原理解說
在 Using VPI — http://iverilog.wikia.com/wiki/Using_VPI 這篇文章中,記載了這個機製的運作原理,以下是我認為最重要的一段話:
The simulator run time (The "vvp" program) gets a handle on a freshly loaded module by looking for the symbol "vlog_startup_routines" in the loaded module. This table, provided by the module author and compiled into the module, is a null terminated table of function pointers. The simulator calls each of the functions in the table in order. The following simple C definition defines a sample table:
void (*vlog_startup_routines[])() = {
hello_register,
0
};
Note that the "vlog_startup_routines" table is an array of function pointers, with the last pointer a 0 to mark the end. The programmer can organize the module to include many startup functions in this table, if desired.
透過這種方式,我們就能讓 Icarus Verilog 的 vvp 虛擬機呼叫 C 語言的函數了。
參考文獻
1.用 Iverilog-vpi 連結 C 語言與 Verilog
2.Using VPI — http://iverilog.wikia.com/wiki/Using_VPI
|
|