tidy sv code port declarations

#!/bin/perl
use strict;

use Data::Dumper;
use Tie::File;
use Getopt::Long;

my $opt_infile;
my $opt_nochk;

GetOptions(
    "i=s"     => \$opt_infile,
    "nochk:s" => \$opt_nochk,
) or die "Error in command line arguments\n";

my $tidy_regex = qr/
    \s*\/\/
    \s*Tidy:
    \s*\(
        \s*([1-9][0-9]*)
        \s*,
        \s*([1-9][0-9]*)
    \s*\)
/x;

my $identifier_regex = qr/[a-zA-Z][a-zA-Z0-9_]*/;
my $number_regex     = qr/[1-9][0-9]*/;
my $range_regex      = qr/\[$number_regex:0\]/;
my $port_regex       = qr/
    (?<dir>       input|output)?
    (?<type>      wire|reg|bit|logic)?
    (?<pdim_str>  $range_regex*)
    (?<id>        $identifier_regex)
    (?<updim_str> $range_regex*)
    ;
/x;
my $suffix_regex     = qr/;(?<suffix>.*)/;

my @contents;
tie @contents, 'Tie::File', $opt_infile or die "Fail to tie to [$opt_infile]\n";
#------------------------------------------------------------------------------#
my $interval = &traverse;
for (@$interval) {
    my $records = &make_records($_);
    my $printer = &make_printer($records);
    &tidy($printer, $records);
}
#------------------------------------------------------------------------------#
sub traverse {
    my $intervals = [];
    for (@contents) {
        if (/$tidy_regex/) {
            push @$intervals, [$1, $2];
        }
    }
    return $intervals;
}

sub make_records {
    my $interval = shift;
    my @records;
    for (my $i = $interval->[0]-1; $i < $interval->[1]; $i++) {
        my $record = {};
        my $line = $contents[$i];

        $record->{lineno} = $i+1;

        $line =~ $suffix_regex;
        my $suffix = $+{suffix};
        $suffix =~ s/^\s*//;
        $suffix =~ s/\s*$//;
        $record->{suffix} = $suffix;

        $line =~ s/\s//g;
        my %line_record_tmp;
        if ($line =~ $port_regex) {
            %line_record_tmp = %+; # copy %+
            $record = \%line_record_tmp;
            push @records, $record;
        }
        ($record->{pdim},  $record->{pdims},  $record->{pdims_len})
            = &proc_dim_str($record->{pdim_str});
        ($record->{updim}, $record->{updims}, $record->{updims_len})
            = &proc_dim_str($record->{updim_str});
    }
    # print Dumper(\@records);
    return \@records;

}

sub make_printer {
    my $records = shift;
    my %printer = (
        dir_w        => 0,
        type_w       => 0,
        m_pdim       => 0,
        m_pdims_len  => [],
        id_w         => 0,
        m_updim      => 0,
        m_updims_len => [],
    );
    for (@$records) {
        my $cur_dir_w  = length($_->{dir});
        my $cur_type_w = length($_->{type});
        my $cur_id_w   = length($_->{id});
        $printer{dir_w}  = $cur_dir_w  if ($cur_dir_w  > $printer{dir_w});
        $printer{type_w} = $cur_type_w if ($cur_type_w > $printer{type_w});
        $printer{id_w}   = $cur_id_w   if ($cur_id_w   > $printer{id_w});

        $printer{m_pdim}  = $_->{pdim}  if ($_->{pdim}  > $printer{m_pdim});
        for (my $i = 0; $i < $_->{pdim}; $i++) {
            $printer{m_pdims_len}->[$i] = $_->{pdims_len}->[$i]
                if (not defined $printer{m_pdims_len}->[$i] or $_->{pdims_len}->[$i] > $printer{m_pdims_len}->[$i]);
        }

        $printer{m_updim} = $_->{updim} if ($_->{updim} > $printer{m_updim});
        for (my $i = 0; $i < $_->{updim}; $i++) {
            $printer{m_updims_len}->[$i] = $_->{updims_len}->[$i]
                if (not defined $printer{m_updims_len}->[$i] or $_->{updims_len}->[$i] > $printer{m_updims_len}->[$i]);
        }
    }
    # print Dumper(\%printer);
    return \%printer;
}
sub proc_dim_str {
    my $dim_str = shift;
    $dim_str =~ s/\[//g;
    $dim_str =~ s/0\]//g;
    my @dims = split ":", $dim_str;
    my @dims_len;
    for (@dims) {
        push @dims_len, length($_);
    }
    return scalar(@dims), \@dims, \@dims_len; 
}


sub tidy {
    my ($printer, $records) = (shift, shift);
    for (@$records) {
        my $fmt = "";
        $fmt .= "%-$printer->{dir_w}s";
        $fmt .= " " if ($printer->{dir_w} > 0);

        $fmt .= "%-$printer->{type_w}s";
        $fmt .= " " if ($printer->{type_w} > 0);

        for (my $i = 0; $i < $printer->{m_pdim}; $i++) {
            if ($i < $_->{pdim}) {
                $fmt .= "[%-$printer->{m_pdims_len}->[$i]s:0]";
            } else {
                my $dummy_len = $printer->{m_pdims_len}->[$i]+4;
                $fmt .= " "x$dummy_len;
            }
        }

        $fmt .= " %-$printer->{id_w}s";
        for (my $i = 0; $i < $printer->{m_updim}; $i++) {
            if ($i < $_->{updim}) {
                $fmt .= "[%-$printer->{m_updims_len}->[$i]s:0]";
            } else {
                my $dummy_len = $printer->{m_updims_len}->[$i]+4;
                $fmt .= " "x$dummy_len;
            }
        }
        $fmt .= "; %-s\n";
        my $str = sprintf $fmt, $_->{dir}, $_->{type}, @{$_->{pdims}}, $_->{id}, @{$_->{updims}}, $_->{suffix};
        print $str;
        if (defined $opt_nochk) {
            $contents[$_->{lineno}-1] = $str;
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值