安装Icarus verilog
本人是老师提供软件源码,linux环境为windows subsystem linux,ubuntu版本为18.04。据说,win环境有较多bug。。。下面的操作请在linux环境进行
给个ftp链接
ftp://ftp.icarus.com/pub/eda/verilog/
并没有尝试ftp服务,ftp不行的话,如果需要,联系[email protected] or [email protected]
首先tar解压:
然后进入解压目录
然后偷懒的方式,依次输入下面指令
最后需要提升权限,加sudo。过程十分流程,可以使用下图指令,检查安装成功与否
LPI基本使用
使用流程需要提供一个描述接口函数的c文件和描述仿真激励模型的.v文件。这里假设hello.c和hello.v,对于不同的应用,函数名可发生变化。
编译和执行过程如下:
需要注意的是,第二条指令 -o 后加空格,第三条指令-M.中.表示当前目录,-m与hello紧紧相连,不用空格,否则报错。
已经解决的bug
1、头文件包含
gcc在文件包含时,需要路径信息,因此头文件需要根据当前目录和需要包含的文件进行灵活更改。
在我的设计中,linux工作路径为workOfVPI
而必备头文件和实现文件都在verilog-10.3中,故文件包含应该写为:#include “./verilog-10.3/vpi_user.h”
注意使用双引号,尖括号也报错。。
2、最后的函数定义大括号后需要添加分号
上图中,该部分代码在末尾,不添加分号会报错:[Error] expected ‘,’ or ‘;’ at end of input
。加上分号就行了,这也太细节了吧。。。
3、The Verilog PLI Handbook 2.pdf在show_all_net.c代码缺少一部分注册。
也就是加上bug2中的代码,不知道光盘有没有漏,但文档中应该没有该代码
代码分享
show_all_nets.c
#include<stdlib.h>
#include<stdio.h>
#include<stdarg.h>
#include "./verilog-10.3/vpi_user.h"
PLI_INT32 PLIBOOK_ShowNets_compiletf(PLI_BYTE8 *user_data),
PLIBOOK_ShowNets_calltf(PLI_BYTE8 *user_data);
void PLIBOOK_ShowNets_regisger()
{
s_vpi_systf_data tf_data;
tf_data.type=vpiSysTask;
// tf_data.sysfunctype=0;
tf_data.tfname="$show_all_nets";
tf_data.compiletf=PLIBOOK_ShowNets_compiletf;
tf_data.calltf=PLIBOOK_ShowNets_calltf;
tf_data.sizetf=NULL;
tf_data.user_data=NULL;
vpi_register_systf(&tf_data);
return ;
}
PLI_INT32 PLIBOOK_ShowNets_compiletf(PLI_BYTE8 *user_data)
{
vpiHandle systf_handle,arg_iterator,arg_handle;
PLI_INT32 tfarg_type ;
int err_flag=0;
systf_handle=vpi_handle(vpiSysTfCall,NULL);
arg_iterator=vpi_iterate(vpiArgument,systf_handle);
if(arg_iterator==NULL) {
vpi_printf("Error :$show_all_nets requires 1 argument\n");
err_flag=1;
}
else {
arg_handle =vpi_scan(arg_iterator);
tfarg_type=vpi_get(vpiType,arg_handle);
if (tfarg_type!=vpiModule) {
vpi_printf("error :$show_all_nets arg must be module instance\n");
vpi_free_object(arg_iterator);
err_flag=1;
}
else {
arg_handle=vpi_scan(arg_iterator);
if(arg_handle!=NULL) {
vpi_printf("error:$show_all_nets can only have 1 argument\n");
vpi_free_object(arg_iterator);
err_flag=1;
}
}
}
if(err_flag)
vpi_control(vpiFinish,1);
return 0;
}
PLI_INT32 PLIBOOK_ShowNets_calltf(PLI_BYTE8 *user_data)
{
vpiHandle systf_handle,arg_iterator,module_handle,net_iterator,net_handle;
s_vpi_time current_time;
s_vpi_value current_value;
systf_handle=vpi_handle(vpiSysTfCall,NULL);
arg_iterator=vpi_iterate(vpiArgument,systf_handle);
module_handle =vpi_scan(arg_iterator);
vpi_free_object(arg_iterator);
current_time.type=vpiScaledRealTime;
vpi_get_time(systf_handle,¤t_time);
vpi_printf("\nAt time %2.2f, ",current_time.real);
vpi_printf("net in module %s ",vpi_get_str(vpiFullName,module_handle));
vpi_printf("(%s):\n",vpi_get_str(vpiDefName,module_handle));
net_iterator=vpi_iterate(vpiNet,module_handle);
if(net_iterator==NULL)
vpi_printf(" no nets found in this module\n");
else {
current_value.format=vpiBinStrVal;
while ( (net_handle=vpi_scan(net_iterator))!=NULL) {
vpi_get_value(net_handle,¤t_value);
vpi_printf(" net %-10s value is %s (binary) \n",
vpi_get_str(vpiName,net_handle),
current_value.value.str);
}
}
return 0;
}
void (*vlog_startup_routines[]) () ={
PLIBOOK_ShowNets_regisger,
0
};
show_all_nets.v
`timescale 1ns /1ns
module top;
reg [2:0]test;
tri [1:0]results;
addbit i1 (test[0],test[1],test[2],results[0],results[1]);
initial
begin
test=3'b000;
#10 test=3'b011;
#10 $show_all_nets(top);
#10 $show_all_nets(i1);
#10 $stop;
#10 $finish;
end
endmodule
`timescale 1ns / 1ns
module addbit(a,b,ci,sum,co);
input a,b,ci;
output sum,co;
wire a,b,ci,sum,co,n1,n2,n3;
xor (n1,a,b);
xor #2 (sum,n1,ci);
and (n2,a,b);
and (n3,n1,ci);
or #2 (co,n2,n3);
endmodule
运行效果
最后输入finish可以结束仿真,回到shell.