处理电路的cdl文件时,有时候想输出指定cell的cdl,下面将用不同的Perl脚本实现该功能在不同场景下的应用:
该脚本主要是通过$line_control这个flag来实现两个匹配行之间的内容输出。
1、输出DFF的子电路(以SUBCKT.*CDL开始,以ENDS结尾)
#!/usr/bin/perl
open CDL, "simple.cdl" or die $!;
open OUT, ">output.cdl" or die $!;
while ($lines=<CDL>){
if($lines=~/SUBCKT.*DFF/){
$line_control=1;
}
elsif($lines=~/ENDS/ and $line_control==1){
$line_control=0;
print OUT $lines;
}
if($line_control==1){
print OUT $lines;
}
}
close CDL;
close OUT;
2、如果有一个list,那么如何输出该list对应的子电路呢?(该list的顺序和.cdl文件中list对应的子电路的排列顺序一致)
#!/usr/bin/perl
open CDL, "all.cdl" or die $!;
open OUT, ">output.cdl" or die $!;
open LIST, "list" or die $!;
@list = <LIST>;
$count = 0;
foreach my $cell(@list){
chomp $cell;
while ($lines=<CDL>){
if($lines=~/SUBCKT.*$cell/){
$line_control=1;
}
elsif($lines=~/ENDS/ and $line_control==1){
$line_control=0;
print OUT $lines;
$count++;
print "$cell completed $count\n";
}
if($line_control==1){
print OUT $lines;
}
}
}
close CDL;
close OUT;
close LIST;
3、如果有一个list,那么如何输出该list对应的子电路呢?(该list的顺序和.cdl文件中list对应的子电路的排列顺序不一致)
#!/usr/bin/perl
if(-e "output.cdl"){
unlink "output.cdl";
}
open LIST, "list" or die $!;
@list = <LIST>;
$count = 0;
foreach my $cell(@list){
open CDL, "all.cdl" or die $!;
open OUT, ">>output.cdl" or die $!;
chomp $cell;
while ($lines=<CDL>){
if($lines=~/SUBCKT.*$cell/){
$line_control=1;
}
elsif($lines=~/ENDS/ and $line_control==1){
$line_control=0;
print OUT $lines;
$count++;
print "$cell completed $count\n";
close CDL;
close OUT;
last;
}
if($line_control==1){
print OUT $lines;
}
}
}
close LIST;
由于while是一行一行处理的,处理完一行后,就不会再回来了,只会继续处理后面的新行。如果list和cdl的顺序不一致,就会发生下面的情况,比如:
list:
ADD
DFF
LATCH
MUX
SDFF
cdl:
ADD
MUX
LATCH
DFF
SDFF
output:
ADD
DFF
这是因为找到DFF之后,cdl中的ADD/MUX/LATCH/DFF这些行都已经被处理过了,所以接下来找LATCH是找不到的。
为了解决这个问题,采用了open句柄的操作放在了foreach循环中,每次读取下一个list时,重新打开CDL句柄,让while循环从第一行开始处理,一旦抓到匹配行就追加进output文件,接着用last语句立刻结束while循环,并关闭句柄,以便跳到外层的foreach循环重新打开CDL句柄。