使用触发器在Verilog网表上解析块和正则表达式

时间:2018-08-30 17:24:13

标签: verilog

我正在尝试修改如下所示的Verilog网表:

module la_bla ( a b c d);
input a; 
output; 
inout c d;

uHBMN_1  X20 (.Z(en), .A(gg), .Q(qq), .EN(rr));
nch_mac  M20 (.G(en), .D(gg), .B(qq), .S(rr));
pch_mac_svt  M20 (.G(en), .D(gg), .B(qq), .S(rr));
endmodule 

module la_bla2 ( aw b2 c1 dt);
input aw;
output b2;
inout c1 dt;

HBMN_2  X21 (.Z(en), .A(gg), .Q(qq), .EN(rr));
HBMN_3  X21 (.Z(env), .A(ggg7), .Q(qq), .EN(rr));
HBMN_4  X21 (.Z(en5), .A(gg), .Q(qq8), .EN(rr));
HBMN_5  X21 (.Z(en1), .A(gg), .Q(qq), .EN(rr));

endmodule 
.
.
.
.
.

每次我找到以“ nch_mac”或pct_mac_svt设备开头的行时,我都想在所有模块内容中添加注释,但要保留模块语句和终端语句(输入,输出inout)和endmodule声明保持不变。我尝试使用perl触发器命令:

首先,我尝试捕获以模块开头并以endmodule结尾的块。然后,我尝试使用正则表达式捕获设备名称。

我的问题是所需的设备名称可以位于模块语句内的任何位置-那么我如何注释其前面的模块内的行? 我尝试过类似的事情:

while<FILE>{
if(/module/i.../endmodule/i){
   if($_ =~/nch_mac|pch_mac_svt){ $newline=~ s/$_/\/\/$_/} 

但这没用。
我想得到:

 module la_bla ( a b c d);
 input a; 
 output; 
 inout c d;

 //uHBMN_1  X20 (.Z(en), .A(gg), .Q(qq), .EN(rr));
 //nch_mac  M20 (.G(en), .D(gg), .B(qq), .S(rr));
 //pch_mac_svt  M20 (.G(en), .D(gg), .B(qq), .S(rr));
 endmodule 

 module la_bla2 ( aw b2 c1 dt);
 input aw;
 output b2;
 inout c1 dt;

 HBMN_2  X21 (.Z(en), .A(gg), .Q(qq), .EN(rr));
 HBMN_3  X21 (.Z(env), .A(ggg7), .Q(qq), .EN(rr));
 HBMN_4  X21 (.Z(en5), .A(gg), .Q(qq8), .EN(rr));
 HBMN_5  X21 (.Z(en1), .A(gg), .Q(qq), .EN(rr));

 endmodule 
 .
 .
 .

有什么建议吗?

2 个答案:

答案 0 :(得分:0)

将行存储在数组中,然后再决定如何打印它们:

use warnings;
use strict;

my $flag = 1;
my @lines;
while (<DATA>) {
    if (/(input|output|inout|\bmodule)/) {
        print;
        $flag = 1;
    }
    elsif (/endmodule/) {
        for my $line (@lines) {
            $line = "//$line" unless $flag;
            print $line
        }
        print;
        @lines = ();
    }
    else {
        push @lines, $_;
        if (/nch_mac|pch_mac_svt/) {
            $flag = 0;
        }
    }
}

__DATA__
module la_bla ( a b c d);
input a; 
output; 
inout c d;

uHBMN_1  X20 (.Z(en), .A(gg), .Q(qq), .EN(rr));
nch_mac  M20 (.G(en), .D(gg), .B(qq), .S(rr));
pch_mac_svt  M20 (.G(en), .D(gg), .B(qq), .S(rr));
endmodule 

module la_bla2 ( aw b2 c1 dt);
input aw;
output b2;
inout c1 dt;

HBMN_2  X21 (.Z(en), .A(gg), .Q(qq), .EN(rr));
HBMN_3  X21 (.Z(env), .A(ggg7), .Q(qq), .EN(rr));
HBMN_4  X21 (.Z(en5), .A(gg), .Q(qq8), .EN(rr));
HBMN_5  X21 (.Z(en1), .A(gg), .Q(qq), .EN(rr));

endmodule 

这是我的确切输出:

module la_bla ( a b c d);
input a; 
output; 
inout c d;
//
//uHBMN_1  X20 (.Z(en), .A(gg), .Q(qq), .EN(rr));
//nch_mac  M20 (.G(en), .D(gg), .B(qq), .S(rr));
//pch_mac_svt  M20 (.G(en), .D(gg), .B(qq), .S(rr));
endmodule 
module la_bla2 ( aw b2 c1 dt);
input aw;
output b2;
inout c1 dt;


HBMN_2  X21 (.Z(en), .A(gg), .Q(qq), .EN(rr));
HBMN_3  X21 (.Z(env), .A(ggg7), .Q(qq), .EN(rr));
HBMN_4  X21 (.Z(en5), .A(gg), .Q(qq8), .EN(rr));
HBMN_5  X21 (.Z(en1), .A(gg), .Q(qq), .EN(rr));

endmodule 

如果您输入的Verilog代码复杂得多,请使用适当的解析器,例如Verilog-Perl

答案 1 :(得分:0)

这是我编写的完整代码。 它有效,但可以改进。例如以“ module”开头的行 可以扩展到几行(可以是2行,可以是100行),但始终以char“;”

结尾
#!/usr/intel/bin/perl -w
 use strict;
 use Data::Dumper;
 use Getopt::Long;


   my $verilog1=      "/p/ccd/wa/mlea/roodbridgetc/analog/roodbridgetc_9m1z1u/User_libs/libFlow/meny_lo   cal/noam_tc_phy_ana_top/verilog/netlist";
   my $verilog2=  "/p/ccd/wa/mlea/roodbridgetc/analog/roodbridgetc_9m1z1u/User_libs/libFlow/meny_local/noam_tc_phy_ana_top/verilog/netlist2" ;


   open(VERILOGA,"$verilog1") or die "Can't open original verilog file $verilog1 - $!\n"; 
   open(VERILOGAA,">$verilog2") or die "Can't open destination verilog file $verilog2 - $!\n"; 


    my $flag = 1;
    my @lines =();

    while (<VERILOGA>) {

    if ($_ =~ /^input|^output|^inout|^module/) {
    print VERILOGAA $_;
    $flag = 1;
    }
   elsif($_ =~ /^\/\/|timescale|^`include|^\s*$/){print VERILOGAA $_ }  ## this is for general information lines in verilog netlist 
   elsif($_ =~ /\s+{?\w+?(\[\d+\])?}?,?\s?\)?;?$/){print VERILOGAA $_ } ## this is for supporting the case that the "module line contain \n  char or {} for bus or [*]
   elsif($_ =~ /^\s+\)+?;$/){print VERILOGAA $_ }
   elsif(/^endmodule/) {
        for my $line (@lines) {
         $line = "//$line" unless $flag;
         print VERILOGAA $line;
     }
      print VERILOGAA $_;
       @lines = ();
  }
  else{
    push @lines, $_; 

if(/^nch_mac
   |^nch_18_mac
   |^nch_svt_mac
   |^nch_ulvt_dnw_mac
   |^nch_lvt_mac
   |^pch_lvt_mac
   |^pch_18_mac
   |^pch_svt_mac
   |^nch_18_mac
   |^pch_ulvt_mac
   |^nch_ulvt_mac
   |^crtmom_wo_rf
   |^cfmom_2t_p80
   |^nch_gate_sw
   |^rhim_m
   |^rhim_rf
   |^nch_svt_dnw_mac
   |^pwdnw
   |^nch_lvt_dnw_mac
   |^pch_18ud12_mac
   |^pch_18ud15_mac
   |^nch_ulvt_dnw_mac
    /gx){

        $flag = 0;
       }#if
    }#else
}#while



  close VERILOGA;
   close ;