使用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.
";
#}
foreach $item (keys %ip_channal) { #清空次数值values
$ip_channal{$item} = "";
}
#print "
";
#################################################
# 遍历得到哈希键值的值:哈希数组
#################################################
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(/$key/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}}
";
}
print "
";
#################################################
# 解析数据(%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
";
输出映射
数据特点
输出是处理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
";
foreach my $ip_name (sort keys %ip_channal) {
print "$ip_name = $ip_channal{$ip_name}
";
}
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 ";
}
else
{
next; #值为空则执行下一次循环
}
push(@fmtouts,$out);
}
}
print "fmtouts = @fmtouts
";