Icarus iverilog中PLI使用范例

安装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,&current_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,&current_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.

猜你喜欢

转载自blog.csdn.net/qq_44801767/article/details/109275209
PLI