Verilator c++ wrapper兼容不同名称的verilog模块

Verilator c++ wrapper兼容不同名称的verilog模块

需求

例如编写的C++ wrapper是测试文件,需要测试比较若干具有相同功能但实现细节不同、具有不同名称的RTL。

对于verilog模块xxx,verilator在编译后生成的头文件为Vxxx.h,这就导致在测试不同模块时要频繁手动修改wrapper中的include文件名,以及模块实例化时的Vxxx类名再编译,十分麻烦,也对版本控制系统不友好。

解决方式

这一问题可以通过C++的宏定义功能解决。

首先在verilator编译时增加命令行参数-CFLAGS "-Dmodule_name=$module_name",向C++文件传入名称为module_name宏,其值为实际使用的模块名称(替换上述命令行中的$module_name)。例如,使用的模块名称为top,则应传入-CFLAGS "-Dmodule_name=top"

而后新建一个头文件,增加模块名称处理的相关宏。其原理是利用了C++宏强大的连接语法和字符串嵌入功能(详见文档)。注意其中头文件在include中需要的是字符串(平时用双引号包裹头文件名),因此V_HEADER套了一层STR宏,而V_TYPE直接作为类名,所以不需要。

另外注意这里默认头文件路径位于obj_dir,如果在其他路径需要自行修改。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
//extern define module_name $module_name
#define QUOTE(name) #name
#define STR(macro) QUOTE(macro)

#define V_HEADER_CONCAT(name) obj_dir/V##name.h
#define GET_V_HEADER(name) STR(V_HEADER_CONCAT(name))

#define V_TYPE_CONCAT(name) V##name
#define GET_V_TYPE(name) V_TYPE_CONCAT(name)

#define V_HEADER GET_V_HEADER(module_name)
#define V_TYPE GET_V_TYPE(module_name)

最后在wrapper中分别使用V_HEADER和V_TYPE即可。

1
2
3
4
5
6
7
8
9
#include <verilated.h>
#include V_HEADER
int main(int argc, char **argv) 
{
	V_TYPE *tb = new V_TYPE;
	//do something
	delete tb;
	return 0;
}
0%