use strict; use warnings; my @test = qw/1 5:10 18:14 21 24:25 31:28/; print get_reserved( \@test ), "\n"; sub get_reserved { my ( $bits_ref ) = @_; # should be an array ref return "bad call to get_reserved()" unless ( ref( $bits_ref ) eq 'ARRAY' and @$bits_ref ); my @reg32set; for my $spec ( @$bits_ref ) { if ( $spec =~ /(\d+):(\d+)/) { my ( $bgn, $end ) = sort {$a<=>$b} ( $1, $2 ); $reg32set[$_] = 1 for ( $bgn .. $end ); } else { $reg32set[$spec] = 1; } } my $verilog_string = ''; for my $seq ( 0 .. $#reg32set ) { if ( defined( $reg32set[$seq] )) { $verilog_string .= ", "; } else { $verilog_string .= "$seq:"; } } return "no intervals to report from get_reserved()" unless ( $verilog_string =~ /\d/ ); $verilog_string =~ s/(?<=\d):[\d:]+:(?=\d)/:/g; # e.g. "2:3:4:5:6 -> 2:6 $verilog_string =~ s/^(?:, )+//; $verilog_string =~ s/:(?:, )*$//; $verilog_string =~ s/:,(?: ,)*/,/g; return $verilog_string; }