如何使用Verilog::SigParser排除Verilog被包含文件的端口?
解决Verilog::SigParser读取顶层文件时混入被引用文件端口的问题
问题背景
我在Perl中使用Verilog::SigParser模块读取Verilog文件并提取端口,该模块会在信号声明、模块实例化或模块定义时触发回调。但当前遇到的问题是:顶层Verilog文件verilog.v通过include引用了happy.vp文件,SigParser会将happy.vp里的模块端口也存入%arr哈希表,导致后续生成测试平台时出错。
相关代码示例
Perl处理代码
#On top of the file package MyParser use Verilog::SigParser $filename = /user/home/verilog.v .... use base qw(Verilog::SigParser); my %arr = (); #In this array, all module inputs and outputs are being saved. #Process my verilog file my $vf Verilog::Preproc->new(keep_comments->0); $vf->open(filename=>$filename) or die $!; open(FH,'>',/users/home/port_file); print(FH, %arr()); #HERE IT IS INCLUDING NOT JUST THE PORTS FROM VERILOG.V BUT ALSO THE ONES FROM HAPPY.VP, I want only the ones from verilog.v close(FH);
顶层文件verilog.v
`include happy.vp module top(); . #lots of inputs and outputs . . endmodule
被包含文件happy.vp
module happy(); #some other inputs or outputs I don't want in my ports file. endmodule
解决方案
核心思路是仅跟踪目标顶层模块(top)的端口,忽略被包含文件中的其他模块。通过重写Verilog::SigParser的回调方法,实现模块级别的过滤:
修改后的Perl代码
package MyParser; use strict; use warnings; use base qw(Verilog::SigParser); my %arr; my $current_module; # 记录当前正在处理的模块名称 # 模块定义开始时的回调:记录当前模块名 sub module { my ($self, $keyword, $name) = @_; $current_module = $name; } # 端口声明时的回调:仅收集顶层模块的端口 sub port { my ($self, $direction, $name, $data_type) = @_; # 仅处理名为top的顶层模块的端口 if ($current_module eq 'top') { $arr{$name} = { direction => $direction, data_type => $data_type }; } } # 主处理逻辑 my $filename = '/user/home/verilog.v'; # 初始化预处理器 my $pp = Verilog::Preproc->new(keep_comments => 0); $pp->open(filename => $filename) or die "无法打开文件: $!"; # 使用自定义解析器解析 my $parser = MyParser->new(); $parser->parse_preproc($pp); # 将筛选后的端口写入文件 open(my $fh, '>', '/users/home/port_file') or die "无法创建端口文件: $!"; foreach my $port (keys %arr) { print $fh "$port\t$arr{$port}->{direction}\t$arr{$port}->{data_type}\n"; } close($fh);
关键说明
- 模块跟踪:重写
module回调方法,每次进入新模块时记录模块名称,明确当前处理的模块上下文。 - 端口过滤:在
port回调中判断当前模块是否为目标顶层模块(top),仅符合条件时才将端口存入哈希表。 - 修复原代码问题:
- 修正了变量声明语法错误(
my $vf = ...而非my $vf ...) - 添加
strict和warnings模式,避免潜在语法问题 - 正确遍历哈希表写入端口信息,替代原代码中直接打印哈希表的错误写法
- 修正了变量声明语法错误(
内容的提问来源于stack exchange,提问作者anasan
相关产品推荐
相关产品推荐

