使用Perl提取Excel中的IO_MUX

使用Perl提取Excel中的IO_MUX

关键问题


  • 提取数据
  • 格式化输出
  • 循环嵌套
  • 数据结构构建
  • 坐标映射,逆向提取关键字

描述


在IC集成中,我们使用Excel表格规划设计的IC引脚功能映射需要转化到Verilog层次,这个过程耗时耗力,但其中有一些规律,可以通过Perl将其格式化提取出部分可用的信息,应用得当可以减小出错的概率。

编程思路


输入映射

数据特点


同类引脚有多个通道,同一个引脚可能在不同的行列出现,即出现多次,唯一的是引脚的坐标(行列位置),所以我们可以构建哈希数组结构,哈希的键值为引同类引脚名,数组值为键值的坐标。

流程图


思路 将引脚使用坐标表示,在将坐标映射到P[A-Z]和AF[0-15],使用正则表达式处理映射字符。

映射部分代码


#################################################
#  统计出现次数
#################################################
    foreach $item (@ip_name) {
      $ip_channal{$item} += 1;
    }
    #foreach $item (keys %ip_channal) {  #遍历输出出现次数,debug显示使用
    #  print "$item was seen $ip_channal{$item} times.\n";
    #}
    foreach $item (keys %ip_channal) {   #清空次数值values
      $ip_channal{$item} = "";
    }
    
    #print "\n\n";
#################################################
#  遍历得到哈希键值的值:哈希数组
#################################################
    foreach $key (keys %ip_channal)
    {
       my (@array);
       for my $row ( $row_min .. $row_max ) {
           for my $col ( $col_min .. $col_max ) {
               my $cell = $worksheet->get_cell( $row, $col );
       	        next unless $cell;
       	        if(($cell->value() eq ""))
       	        {
       	           next;
       	        }
       	        if(($cell->value() eq "-"))
       	        {
       	           next;
       	        }

       	        $_ =  $cell->value();
       	        if(/\b$key\b/i)
       	        {
		   #格式化行列位置为4位数字(行列的位数格式化,便于后续处理)
	           my $rowtmpfmt=(sprintf "%03d", $row);
	           my $coltmpfmt=(sprintf "%03d", $col);
                   push(@array,$rowtmpfmt.$coltmpfmt);
                }
           }
       }
       $ip_channal{$key} = \@array;
    }
    #哈希数组,显示行列坐标位置,debug显示使用
    foreach $item (keys %ip_channal) {
      print "$item = @{$ip_channal{$item}}\n";
    }
    print "\n\n";
#################################################
# 解析数据(%ip_channal/%px/%afx/),格式化输出   映射
#################################################
    foreach my $ip_key (sort keys %ip_channal) {
       my (@fmtouts);
       foreach my $ip_position (@{$ip_channal{$ip_key}}){
          my ($out);
          foreach my $ip_px (sort keys %px){
             my $pretmp = substr($ip_position,0,3); 	#使用substr得到前三位字符串	  
             if($pretmp eq $px{$ip_px})
             {
                $out = $ip_px;
             }
          }
          foreach my $ip_afx (sort keys %afx){
             my $posttmp = substr($ip_position,3,3);    #使用substr得到后三位字符串		  
             if($posttmp eq $afx{$ip_afx})
             {
                $out = $out.$ip_afx;
             }
          }
          push(@fmtouts,$out);
       }
       #print "@fmtouts\n";

输出映射

数据特点


输出是处理P[A-Z]一行的数据,数据结构相对输入较为简单,只需构建一行中的引脚的哈希结构进行映射即可。

流程图


思路 将引脚使用坐标表示,在将坐标映射到P[A-Z]和AF[0-15],使用正则表达式处理映射字符。

数据映射部分代码


#################################################
# 解析数据(%px/%afx/),格式化输出
#################################################
    foreach my $px_key (sort keys %px) {
       my %ip_channal;	    
       my $row = $px{$px_key};  #定义PX所在行,循环得到IP名称。注意,计数从0开始

       #注意手动设置AFx的范围
       for my $searchcol ( $af0_namecol .. ($af0_namecol+$afx_rang) ) {
           my $cell = $worksheet->get_cell( $row, $searchcol );
	   next unless $cell;
	   if(!defined $cell->value())
       	   {
       	      next;
       	   }
	   $_ = $cell->value();
	   #if(/Y\+|Y\-|X\+|BKIN|\_IN|\_RX|\_ETR/)    #排除Y+/X+/BKIN/_IN/_RX
	   if(/BKIN|\_IN|\_RX|\_ETR/)    #排除Y+/X+/BKIN/_IN/_RX
       	   {
       	      next;
       	   }
	   if(/\w+/)
	   {
              #格式化行列位置为3位数字(行列的位数格式化,便于后续处理)
	      my $coltmpfmt=(sprintf "%03d", $searchcol);
              $ip_channal{$cell->value()} = $coltmpfmt;
           }
       }

       print "row = $row\n";
       foreach my $ip_name (sort keys %ip_channal) {
          print "$ip_name = $ip_channal{$ip_name}\n";
       }
       
       my (@fmtouts);
       foreach my $ip_key (sort keys %ip_channal) {
          foreach my $ip_afx (sort keys %afx){
             my $out;
             if($ip_channal{$ip_key} eq $afx{$ip_afx})
             {
                $out = $ip_key.$ip_afx.$px_key;   #组合映射出单元的行列位置
		#print "$out\t";
             }
	     else
	     {
                next;   #值为空则执行下一次循环
	     }
	     push(@fmtouts,$out);
            }
       }

       print "fmtouts = @fmtouts\n\n";
posted @ 2017-04-26 08:42  乔_木  阅读(807)  评论(0编辑  收藏  举报