#! /opt/perl/5.6.1/bin/perl # # Paul Fernando NCSU, IBIS-MACRO 01/17/2006 # prfernan@ncsu.edu # # IBIS-to-AMS converter script v0.1 (GUI capabilities added) - 1/30/06 # IBIS-to-AMS converter script v0.2 (VHDL-A(MS) parsing added) - 2/1/06 # IBIS-to-AMS converter script v0.3 (windows "pwd" bug fixed) - 2/2/06 # IBIS-to-AMS converter script v0.4 (more bug fixes) - 2/3/06 # IBIS-to-AMS converter script v0.5 (Updated 'convert' to handle ALL models & corners) - 2/6/06 # IBIS-to-AMS converter script v0.6 (references/v_range, Rise/Fall waveform ordering) - 2/8/06 # IBIS-to-AMS converter script v0.7 (Verilog-A "/" in input model, table name) - 3/2/06 # # This program is used to convert ibis file to verilog/vhdl A(MS) files. # This program requires Perl/Tk. http://www.perl.com/download.csp # Note: only the "convert" menu works so far # ################################################################################################# use Tk 800.000; use subs qw/file_menuitems convert_menuitems template_menuitems lib_menuitems help_menuitems/; require Tk::BrowseEntry; require Tk::LabEntry; use Tk::DialogBox; use Tk::Dialog; use Tk::ErrorDialog; $Help_file="help.txt"; $default_IBIS_file="lab_1.ibs"; ########## Create scroller_bar my $mw = MainWindow->new(-title => "IBIS-to-AMS converter"); my $t = $mw->Scrolled("Text", -width => 50, -height => 20, -scrollbars => 'se', -wrap => 'none')->pack(-expand => 1, -fill => 'both'); # scrollbars on south & east $t->configure(-state => 'disabled'); # disallows user typing in canvas ########## Create the menubar $mw->configure(-menu => my $menubar = $mw->Menu); map {$menubar->cascade( -label => '~' . $_->[0], -menuitems => $_->[1] )} ['File', file_menuitems], # Each of these functions is defined below, in the next section ['Convert', convert_menuitems], # Each of these functions is defined below, in the next section ['Template', template_menuitems], # Each of these functions is defined below, in the next section ['Macro Library', lib_menuitems], # Each of these functions is defined below, in the next section ['Help', help_menuitems]; if ($^O eq 'MSWin32') { $current_dir=`cd`; chomp($current_dir); $current_dir=$current_dir."\\"; my $syst = $menubar->cascade(-label => '~System'); my $dir = 'dir | sort | more'; $syst->command( -label => $dir, -command => sub {system $dir}, ); } else{ $current_dir=`pwd`; chomp($current_dir); $current_dir=$current_dir."/"; } print "Running on $^O"."\n"; print "Current directory is $current_dir\n"; MainLoop; ########################################################################################### ########################################################################################### ########################################################################################### ########################################################################################### # File Menu ################################################################################################# sub file_menuitems { # Create the menu items for the File menu. my($motif, $bisque) = (1, 0); my $new_image_format = 'png'; [ [qw/command ~Quit -accelerator Ctrl-q -command/ => sub { if($mw->Dialog(-title=>'Exit?', -text=>'Confirm exit', -buttons=>['Exit', 'Return'], -default_button=>'Return', -bitmap=>'warning') ->Show eq "Exit") { &exit }}], ]; } # end file_menuitems ########################################################################################### # This function converts a model in a normal ibis file to AMS format ################################################################################################# sub convert_menuitems { # Create the menu items for the File menu. my($motif, $bisque) = (1, 0); my $new_image_format = 'png'; [ ['command', '~Convert IBIS file to Verilog-A', qw/-accelerator Ctrl-c/, -command => sub{ &ibs_to_AMS("verilog");}], ['command', '~Convert IBIS file to VHDL-A', qw/-accelerator Ctrl-c/, -command => sub{ &ibs_to_AMS("vhdl");}], ]; } # end convert_menuitems ################################################################################################# # opens an AMS template file and links its data ################################################################################################# sub template_menuitems { # Create the menu items for the template menu my($motif, $bisque) = (1, 0); my $new_image_format = 'png'; [ ['command', 'Open ~template file', qw/-accelerator Ctrl-t/, -command => sub{ }], ]; } # end template_menuitems ################################################################################################# # Read AMS macro library and list its contents ################################################################################################# sub lib_menuitems { [ ['command', '~List macro library modules', qw/-accelerator Ctrl-l/, -command => sub{ if ($in_va_file=$mw->getOpenFile(-initialfile=>"$current_dir"."IBIS_macro_library.va")) { #$t->configure(-state => 'normal'); # disallows user typing #my $f1 = $t->Frame->pack(-side => 'top', -expand => 1, -fill =>'y'); # Read modules in Verilog-A macro library file open( INFILEP, "< $in_va_file" ) or die "Can't open $in_va_file"; $temp_modules=""; while( $line= ) { if($line=~m/^(\s*)module\s+/i) { @words = split(/\s+/, $line); #push(@macro_lib_modules, $words[1]); print "$words[1]\n"; $temp_modules=$temp_modules."\n$words[1]"; } } close INFILEP; #my $be = $f1->Label(-text => "$temp_modules", -relief => 'groove', -width => 50) # ->pack(-ipady => 5, -side => 'left'); } }], ]; } # end lib_menuitems ################################################################################################# # help ################################################################################################# sub help_menuitems { [ ['command', '~Help', qw/-accelerator Ctrl-h/, -command => sub{&Editor_module($Help_file)}],'', ['command', '~About', qw/-accelerator Ctrl-a/, -command => sub { my $db2=$mw->Dialog(-title=> "About", -text=>"IBIS to AMS Converter\nNCSU, IBIS-Macro 2006\nRunning on $^O\n\nContact:\nprfernan\@ncsu.edu"."\n", -buttons=>['Ok'], -default_button=> 'Ok', -bitmap=>'info')->Show();}], ]; } ################################################################################################# # ibs_to_AMS - Oversees the ibis to AMS conversion ################################################################################################# sub ibs_to_AMS{ # Prompt for input ibis file if ($in_ibs_file=$mw->getOpenFile(-initialfile=>"$current_dir"."$default_IBIS_file")) { # Reinitialize data stucts &Reset_data_structs; $in_model_name_temp=""; @choices=""; # Read models(@choices) in ibis file open( INFILEP, "< $in_ibs_file" ) or die "Can't open $in_ibs_file"; while( $line= ) { if($line=~m/^(\s*)\[Model\]\s+/i) { @words = split(/\s+/, $line); push(@choices, $words[1]); } } close INFILEP; push(@choices, "ALL"); # Create dialog for model selection my $db1=$mw->Dialog(-title=> "Select model", -text=>"Select model", -buttons=>['Ok', 'Cancel'], -default_button=> 'Ok'); $db1->BrowseEntry(-label => "Select model", -choices => \@choices, -variable => \$in_model_name_temp, -justify=>'right') ->pack(-ipady => 2, -side => 'bottom', -fill => 'both'); #$db->insert('end', "\n"); my $ans=$db1->Show(); if($ans eq "Ok" && $in_model_name_temp ne "" && $in_model_name_temp ne "ALL") { $in_model_name=$in_model_name_temp; # Parse input file name $in_ibs_file1=$in_ibs_file; $in_ibs_file1=~s/.ibs//g; ($temp, $in_ibs_file1)=$in_ibs_file1=~m/(.*\/)(.*)$/; # Dialog to get process corner, default: typical my $db2=$mw->Dialog(-title=> "Select Process corner", -text=>"Select Process corner", -buttons=>['Typical', 'Minimum', 'Maximum', 'ALL'], -default_button=> 'Typical'); my $ans2=$db2->Show(); if($ans2 eq 'Typical') { $corner="t"; $corner1="Typical"; &ibs_to_AMS_conversion($_[0]); &Reset_data_structs;} elsif($ans2 eq 'Minimum') { $corner="n"; $corner1="Minimum"; &ibs_to_AMS_conversion($_[0]); &Reset_data_structs;} elsif($ans2 eq 'Maximum') { $corner="x"; $corner1="Maximum"; &ibs_to_AMS_conversion($_[0]); &Reset_data_structs;} elsif($ans2 eq 'ALL') { $corner="t"; $corner1="Typical"; &ibs_to_AMS_conversion($_[0]); &Reset_data_structs; $corner="n"; $corner1="Minimum"; &ibs_to_AMS_conversion($_[0]); &Reset_data_structs; $corner="x"; $corner1="Maximum"; &ibs_to_AMS_conversion($_[0]); &Reset_data_structs; } } elsif($ans eq "Ok" && $in_model_name_temp eq "ALL") { foreach $in_model_name (@choices) { if($in_model_name ne "ALL" && $in_model_name ne "") { # Parse input file name $in_ibs_file1=$in_ibs_file; $in_ibs_file1=~s/.ibs//g; ($temp, $in_ibs_file1)=$in_ibs_file1=~m/(.*\/)(.*)$/; $corner="t"; $corner1="Typical"; &ibs_to_AMS_conversion($_[0], "FORCE"); &Reset_data_structs; $corner="n"; $corner1="Minimum"; &ibs_to_AMS_conversion($_[0], "FORCE"); &Reset_data_structs; $corner="x"; $corner1="Maximum"; &ibs_to_AMS_conversion($_[0], "FORCE"); &Reset_data_structs; } } } } } sub Reset_data_structs{ $input_state=""; $ibs_model_type=""; %ibs_V_pu_ref=(); %ibs_V_pd_ref=(); %ibs_V_pc_ref=(); %ibs_V_gc_ref=(); %ibs_V_tf=(); %ibs_T_tf=(); %ibs_V_tr=(); %ibs_T_tr=(); %ibs_vrange=(); %ibs_I_pc=(); %ibs_I_gc=(); %ibs_I_pu=(); %ibs_I_pd=(); %Vfx_r=(); %Vfx_f=(); $ibs_Vinh=""; $ibs_Vinl=""; $ibs_V_pc=""; $ibs_V_gc=""; $ibs_V_pu=""; $ibs_V_pd=""; } sub ibs_to_AMS_conversion{ # Read ibis file and create data structs &create_datastructs($in_ibs_file); &sort_rising_falling_entries; # depending on selection create Verilog or VHDL output file. if($_[0] eq "verilog") { if($_[1] eq "FORCE") { &create_verilog_output_file("$current_dir"."$in_ibs_file1"."_$in_model_name"."_$corner".".dat"); } elsif($out_file=$mw->getSaveFile(-initialfile=>"$current_dir"."$in_ibs_file1"."_$in_model_name"."_$corner".".dat")) { &create_verilog_output_file($out_file); } } elsif($_[0] eq "vhdl") { if($_[1] eq "FORCE") { &create_vhdl_output_file("$current_dir"."$in_ibs_file1"."_$in_model_name"."_$corner".".txt"); } elsif($out_file=$mw->getSaveFile(-initialfile=>"$current_dir"."$in_ibs_file1"."_$in_model_name"."_$corner".".txt")) { &create_vhdl_output_file($out_file); } } #&Editor_module($out_file); # Open output file in text viewer #&print_all_structs; # Prints all datastructures to screen } sub sort_rising_falling_entries{ my $temp_Vfx_r; my $temp_Rfx_r; my $temp_TR_counter; my $temp_ibs_T_tr; my $temp_ibs_V_tr; # If V_fixture min & max don't exist copy V_fixture to them if($Vfx_r{"1n"} eq "") {$Vfx_r{"1n"}=$Vfx_r{"1t"};} if($Vfx_r{"2n"} eq "") {$Vfx_r{"2n"}=$Vfx_r{"2t"};} if($Vfx_f{"1n"} eq "") {$Vfx_f{"1n"}=$Vfx_f{"1t"};} if($Vfx_f{"2n"} eq "") {$Vfx_f{"2n"}=$Vfx_f{"2t"};} if($Vfx_r{"1x"} eq "") {$Vfx_r{"1x"}=$Vfx_r{"1t"};} if($Vfx_r{"2x"} eq "") {$Vfx_r{"2x"}=$Vfx_r{"2t"};} if($Vfx_f{"1x"} eq "") {$Vfx_f{"1x"}=$Vfx_f{"1t"};} if($Vfx_f{"2x"} eq "") {$Vfx_f{"2x"}=$Vfx_f{"2t"};} # R1 must have the lower Vfx (of R1 and R2) # F1 must have the higher Vfx (of F1 and F2) if($ibs_model_type1 ne "IBIS_OPENSINK" && $ibs_model_type1 ne "IBIS_IO_OPENSINK" && $ibs_model_type1 ne "IBIS_OPENSOURCE" && $ibs_model_type1 ne "IBIS_IO_OPENSOURCE") { if($Vfx_r{"1".$corner}>$Vfx_r{"2".$corner}) { # swap the two #print "Swapped Rising WFs for model:$in_model_name type:$ibs_model_type1 corner:$corner\n"; $temp_Vfx_r =$Vfx_r{"1".$corner}; $temp_Rfx_r =$Rfx_r{"1"}; $temp_TR_counter=$TR_counter{"1"}; $temp_ibs_T_tr =$ibs_T_tr{"1"}; $temp_ibs_V_tr =$ibs_V_tr{$corner."1"}; $Vfx_r{"1".$corner} =$Vfx_r{"2".$corner}; $Rfx_r{"1"} =$Rfx_r{"2"}; $TR_counter{"1"} =$TR_counter{"2"}; $ibs_T_tr{"1"} =$ibs_T_tr{"2"}; $ibs_V_tr{$corner."1"}=$ibs_V_tr{$corner."2"}; $Vfx_r{"2".$corner} =$temp_Vfx_r; $Rfx_r{"2"} =$temp_Rfx_r; $TR_counter{"2"} =$temp_TR_counter; $ibs_T_tr{"2"} =$temp_ibs_T_tr; $ibs_V_tr{$corner."2"}=$temp_ibs_V_tr; } if($Vfx_f{"1".$corner}<$Vfx_f{"2".$corner}) { # swap the two #print "Swapped Falling WFs for model:$in_model_name type:$ibs_model_type1 corner:$corner\n"; $temp_Vfx_f =$Vfx_f{"1".$corner}; $temp_Rfx_f =$Rfx_f{"1"}; $temp_TF_counter=$TF_counter{"1"}; $temp_ibs_T_tf =$ibs_T_tf{"1"}; $temp_ibs_V_tf =$ibs_V_tf{$corner."1"}; $Vfx_f{"1".$corner} =$Vfx_f{"2".$corner}; $Rfx_f{"1"} =$Rfx_f{"2"}; $TF_counter{"1"} =$TF_counter{"2"}; $ibs_T_tf{"1"} =$ibs_T_tf{"2"}; $ibs_V_tf{$corner."1"}=$ibs_V_tf{$corner."2"}; $Vfx_f{"2".$corner} =$temp_Vfx_f; $Rfx_f{"2"} =$temp_Rfx_f; $TF_counter{"2"} =$temp_TF_counter; $ibs_T_tf{"2"} =$temp_ibs_T_tf; $ibs_V_tf{$corner."2"}=$temp_ibs_V_tf; } } # If [... reference]s are not provided use [voltage range] instead. if($ibs_V_pu_ref{$corner} eq "") { $ibs_V_pu_ref{$corner}=$ibs_vrange{$corner}; } if($ibs_V_pd_ref{$corner} eq "") { $ibs_V_pd_ref{$corner}="0"; } if($ibs_V_pc_ref{$corner} eq "") { $ibs_V_pc_ref{$corner}=$ibs_vrange{$corner}; } if($ibs_V_gc_ref{$corner} eq "") { $ibs_V_gc_ref{$corner}="0"; } } ################################################################################################# # functional subroutines: ################################################################################################# ################################################################################################# # If valid args are provided, parse the model and create internal data structs ################################################################################################# sub create_datastructs{ $file_flag1="0"; %ibs_C_comp=""; $input_state=""; $PC_counter=0; $GC_counter=0; $PU_counter=0; $PD_counter=0; $TR_counter{"1"}=0; $TR_counter{"2"}=0; $TF_counter{"1"}=0; $TF_counter{"2"}=0; $current_TR=0; $current_TF=0; if($in_model_name ne "") { open( INFILEP, "< $_[0]" ) or die "Can't open $_[0]"; while( $line= ) { if($line=~m/^(\s*)\[Model\]\s+$in_model_name\s+/i) { $file_flag1="1"; #@words = split(/\s+/, $line); #print "$words[1]\n"; }elsif($file_flag1 eq "1" && $line=~m/^(\s*)\[Model\]\s+/i) { $file_flag1="0"; } if($file_flag1 eq "1") { #print $line; if($line=~m/^(\s*)\[/i) { $input_state=""; } if($line=~m/^(\s*)\|/i) { # Comment line }elsif($line=~m/^(\s*)Model_type\s+/i) { @words = split(/\s+/, $line); $ibs_model_type=$words[1]; if(lc($ibs_model_type) eq "input") { $ibs_model_type1="IBIS_INPUT"} elsif(lc($ibs_model_type) eq "output") { $ibs_model_type1="IBIS_OUTPUT"} elsif(lc($ibs_model_type) eq "i/o") { $ibs_model_type1="IBIS_IO"} elsif(lc($ibs_model_type) eq "3-state") { $ibs_model_type1="IBIS_3STATE"} elsif(lc($ibs_model_type) eq "open_sink") { $ibs_model_type1="IBIS_OPENSINK"} elsif(lc($ibs_model_type) eq "i/o_open_sink") { $ibs_model_type1="IBIS_IO_OPENSINK"} elsif(lc($ibs_model_type) eq "open_source") { $ibs_model_type1="IBIS_OPENSOURCE"} elsif(lc($ibs_model_type) eq "i/o_open_source") { $ibs_model_type1="IBIS_IO_OPENSOURCE"} else { print "Model type $ibs_model_type in model $in_model_name in file $in_ibs_file is not valid\n"; exit;} }elsif($line=~m/^(\s*)Vinl\s*=/i) { $line=~s/(\s+)//g; chomp($line); $line=&parse_val($line); @words = split(/=/, $line); $ibs_Vinl=$words[1]; }elsif($line=~m/^(\s*)Vinh\s*=/i) { $line=~s/(\s+)//g; chomp($line); $line=&parse_val($line); @words = split(/=/, $line); $ibs_Vinh=$words[1]; }elsif($line=~m/^(\s*)Vmeas\s*=/i) { $line=~s/(\s+)//g; chomp($line); $line=&parse_val($line); @words = split(/=/, $line); $ibs_Vmeas=$words[1]; }elsif($line=~m/^(\s*)Cref\s*=/i) { $line=~s/(\s+)//g; chomp($line); $line=&parse_val($line); @words = split(/=/, $line); $ibs_Cref=$words[1]; }elsif($line=~m/^(\s*)C_comp\s*/i) { $line=&parse_val($line); @words = split(/\s+/, $line); $ibs_C_comp{"t"}=$words[1]; $ibs_C_comp{"n"}=$words[2]; $ibs_C_comp{"x"}=$words[3]; }elsif($line=~m/^(\s*)\[Voltage Range\]\s*/i) { @words = split(/\s+/, $line); $ibs_vrange{"t"}=$words[2]; $ibs_vrange{"t"}=&parse_val($ibs_vrange{"t"}); $ibs_vrange{"n"}=$words[3]; $ibs_vrange{"n"}=&parse_val($ibs_vrange{"n"}); $ibs_vrange{"x"}=$words[4]; $ibs_vrange{"x"}=&parse_val($ibs_vrange{"x"}); }elsif($line=~m/^(\s*)\[Pullup Reference\]\s*/i) { @words = split(/\s+/, $line); $ibs_V_pu_ref{"t"}=$words[2]; $ibs_V_pu_ref{"t"}=&parse_val($ibs_V_pu_ref{"t"}); $ibs_V_pu_ref{"n"}=$words[3]; $ibs_V_pu_ref{"n"}=&parse_val($ibs_V_pu_ref{"n"}); $ibs_V_pu_ref{"x"}=$words[4]; $ibs_V_pu_ref{"x"}=&parse_val($ibs_V_pu_ref{"x"}); }elsif($line=~m/^(\s*)\[Pulldown Reference\]\s*/i) { @words = split(/\s+/, $line); $ibs_V_pd_ref{"t"}=$words[2]; $ibs_V_pd_ref{"t"}=&parse_val($ibs_V_pd_ref{"t"}); $ibs_V_pd_ref{"n"}=$words[3]; $ibs_V_pd_ref{"n"}=&parse_val($ibs_V_pd_ref{"n"}); $ibs_V_pd_ref{"x"}=$words[4]; $ibs_V_pd_ref{"x"}=&parse_val($ibs_V_pd_ref{"x"}); }elsif($line=~m/^(\s*)\[POWER Clamp Reference\]\s*/i) { @words = split(/\s+/, $line); $ibs_V_pc_ref{"t"}=$words[3]; $ibs_V_pc_ref{"t"}=&parse_val($ibs_V_pc_ref{"t"}); $ibs_V_pc_ref{"n"}=$words[4]; $ibs_V_pc_ref{"n"}=&parse_val($ibs_V_pc_ref{"n"}); $ibs_V_pc_ref{"x"}=$words[5]; $ibs_V_pc_ref{"x"}=&parse_val($ibs_V_pc_ref{"x"}); }elsif($line=~m/^(\s*)\[GND Clamp Reference\]\s*/i) { @words = split(/\s+/, $line); $ibs_V_gc_ref{"t"}=$words[3]; $ibs_V_gc_ref{"t"}=&parse_val($ibs_V_gc_ref{"t"}); $ibs_V_gc_ref{"n"}=$words[4]; $ibs_V_gc_ref{"n"}=&parse_val($ibs_V_gc_ref{"n"}); $ibs_V_gc_ref{"x"}=$words[5]; $ibs_V_gc_ref{"x"}=&parse_val($ibs_V_gc_ref{"x"}); }elsif($line=~m/^(\s*)\[Temperature Range\]\s*/i) { @words = split(/\s+/, $line); $ibs_trange{"t"}=$words[2]; $ibs_trange{"t"}=&parse_val($ibs_trange{"t"}); $ibs_trange{"n"}=$words[3]; $ibs_trange{"n"}=&parse_val($ibs_trange{"n"}); $ibs_trange{"x"}=$words[4]; $ibs_trange{"x"}=&parse_val($ibs_trange{"x"}); }elsif(($line=~m/^(\s*)\[POWER Clamp\]/i) or ($line=~m/^(\s*)\[POWER_Clamp\]/i)) { $input_state="PC"; }elsif(($line=~m/^(\s*)\[GND Clamp\]/i) or ($line=~m/^(\s*)\[GND_Clamp\]/i)) { $input_state="GC"; }elsif($line=~m/^(\s*)\[Pullup\]/i) { $input_state="PU"; }elsif($line=~m/^(\s*)\[Pulldown\]/i) { $input_state="PD"; }elsif($line=~m/^(\s*)\[Falling Waveform\]/i) { $input_state="TF"; $current_TF++; }elsif($line=~m/^(\s*)\[Rising Waveform\]/i) { $input_state="TR"; $current_TR++; }elsif($input_state ne "") { if(($input_state eq "TR" || $input_state eq "TF") && $line=~m/_fixture/i) { if($line=~m/^V_fixture(\s*)=/i) { $line=~s/(\s+)//g; chomp($line); @words = split(/=/, $line); $words[1]=~s/v//ig; if($input_state eq "TR") { $Vfx_r{$current_TR."t"}=&parse_val($words[1]); } elsif($input_state eq "TF") { $Vfx_f{$current_TF."t"}=&parse_val($words[1]); } }elsif($line=~m/^V_fixture_min(\s*)=/i) { $line=~s/(\s+)//g; chomp($line); @words = split(/=/, $line); $words[1]=~s/v//ig; if($input_state eq "TR") { $Vfx_r{$current_TR."n"}=&parse_val($words[1]); } elsif($input_state eq "TF") { $Vfx_f{$current_TF."n"}=&parse_val($words[1]); } }elsif($line=~m/^V_fixture_max(\s*)=/i) { $line=~s/(\s+)//g; chomp($line); @words = split(/=/, $line); $words[1]=~s/v//ig; if($input_state eq "TR") { $Vfx_r{$current_TR."x"}=&parse_val($words[1]); } elsif($input_state eq "TF") { $Vfx_f{$current_TF."x"}=&parse_val($words[1]); } }elsif($line=~m/^R_fixture/i) { $line=~s/(\s+)//g; chomp($line); @words = split(/=/, $line); $words[1]=~s/ohm//ig; if($input_state eq "TR") { $Rfx_r{$current_TR}=&parse_val($words[1]); } elsif($input_state eq "TF") { $Rfx_f{$current_TF}=&parse_val($words[1]); } } } else { # Values section chomp($line); $line=~s/^(\s*)//g; $line=&parse_val($line); @words = split(/\s+/, $line); if($input_state eq "PC") { $PC_counter++; if($ibs_V_pc ne "") { $ibs_V_pc=$ibs_V_pc.", "; $ibs_I_pc{"t"}=$ibs_I_pc{"t"}.", "; $ibs_I_pc{"n"}=$ibs_I_pc{"n"}.", "; $ibs_I_pc{"x"}=$ibs_I_pc{"x"}.", "; } $ibs_V_pc=$ibs_V_pc.$words[0]; $ibs_I_pc{"t"}=$ibs_I_pc{"t"}.$words[1]; $ibs_I_pc{"n"}=$ibs_I_pc{"n"}.$words[2]; $ibs_I_pc{"x"}=$ibs_I_pc{"x"}.$words[3]; }elsif($input_state eq "GC") { $GC_counter++; if($ibs_V_gc ne "") { $ibs_V_gc=$ibs_V_gc.", "; $ibs_I_gc{"t"}=$ibs_I_gc{"t"}.", "; $ibs_I_gc{"n"}=$ibs_I_gc{"n"}.", "; $ibs_I_gc{"x"}=$ibs_I_gc{"x"}.", "; } $ibs_V_gc=$ibs_V_gc.$words[0]; $ibs_I_gc{"t"}=$ibs_I_gc{"t"}.$words[1]; $ibs_I_gc{"n"}=$ibs_I_gc{"n"}.$words[2]; $ibs_I_gc{"x"}=$ibs_I_gc{"x"}.$words[3]; }elsif($input_state eq "PU") { $PU_counter++; if($ibs_V_pu ne "") { $ibs_V_pu=$ibs_V_pu.", "; $ibs_I_pu{"t"}=$ibs_I_pu{"t"}.", "; $ibs_I_pu{"n"}=$ibs_I_pu{"n"}.", "; $ibs_I_pu{"x"}=$ibs_I_pu{"x"}.", "; } $ibs_V_pu=$ibs_V_pu.$words[0]; $ibs_I_pu{"t"}=$ibs_I_pu{"t"}.$words[1]; $ibs_I_pu{"n"}=$ibs_I_pu{"n"}.$words[2]; $ibs_I_pu{"x"}=$ibs_I_pu{"x"}.$words[3]; }elsif($input_state eq "PD") { $PD_counter++; if($ibs_V_pd ne "") { $ibs_V_pd=$ibs_V_pd.", "; $ibs_I_pd{"t"}=$ibs_I_pd{"t"}.", "; $ibs_I_pd{"n"}=$ibs_I_pd{"n"}.", "; $ibs_I_pd{"x"}=$ibs_I_pd{"x"}.", "; } $ibs_V_pd=$ibs_V_pd.$words[0]; $ibs_I_pd{"t"}=$ibs_I_pd{"t"}.$words[1]; $ibs_I_pd{"n"}=$ibs_I_pd{"n"}.$words[2]; $ibs_I_pd{"x"}=$ibs_I_pd{"x"}.$words[3]; }elsif($input_state eq "TR") { $TR_counter{$current_TR}++; if($ibs_T_tr{$current_TR} ne "") { $ibs_T_tr{$current_TR}=$ibs_T_tr{$current_TR}.", "; $ibs_V_tr{"t".$current_TR}=$ibs_V_tr{"t".$current_TR}.", "; $ibs_V_tr{"n".$current_TR}=$ibs_V_tr{"n".$current_TR}.", "; $ibs_V_tr{"x".$current_TR}=$ibs_V_tr{"x".$current_TR}.", "; } $ibs_T_tr{$current_TR}=$ibs_T_tr{$current_TR}.$words[0]; $ibs_V_tr{"t".$current_TR}=$ibs_V_tr{"t".$current_TR}.$words[1]; $ibs_V_tr{"n".$current_TR}=$ibs_V_tr{"n".$current_TR}.$words[2]; $ibs_V_tr{"x".$current_TR}=$ibs_V_tr{"x".$current_TR}.$words[3]; }elsif($input_state eq "TF") { $TF_counter{$current_TF}++; if($ibs_T_tf{$current_TF} ne "") { $ibs_T_tf{$current_TF}=$ibs_T_tf{$current_TF}.", "; $ibs_V_tf{"t".$current_TF}=$ibs_V_tf{"t".$current_TF}.", "; $ibs_V_tf{"n".$current_TF}=$ibs_V_tf{"n".$current_TF}.", "; $ibs_V_tf{"x".$current_TF}=$ibs_V_tf{"x".$current_TF}.", "; } $ibs_T_tf{$current_TF}=$ibs_T_tf{$current_TF}.$words[0]; $ibs_V_tf{"t".$current_TF}=$ibs_V_tf{"t".$current_TF}.$words[1]; $ibs_V_tf{"n".$current_TF}=$ibs_V_tf{"n".$current_TF}.$words[2]; $ibs_V_tf{"x".$current_TF}=$ibs_V_tf{"x".$current_TF}.$words[3]; } } } } } } } ################################################################################################# # Create output .dat file in verilog-A(MS) format ################################################################################################# sub create_verilog_output_file{ open( OUTFILEP, "> $_[0]" ) or die "Can't open $_[0]"; print OUTFILEP "// Generated on: ".&Return_time."\n// Input file: $in_ibs_file\n"; print OUTFILEP "// Verilog-A primitive type: $ibs_model_type1 corner=$corner1\n\n"; #print OUTFILEP "`define $in_ibs_file1"."_$in_model_name"." \\"."\n\\"."\n"; print OUTFILEP "`define Data"." \\"."\n\\"."\n"; if($ibs_C_comp{$corner} ne "") { print OUTFILEP ".C_comp($ibs_C_comp{$corner}), \\"."\n"; } if($ibs_model_type1 ne "IBIS_OUTPUT" &&$ibs_model_type1 ne "IBIS_OPENSINK" && $ibs_model_type1 ne "IBIS_OPENSOURCE") { if($ibs_Vinh ne "") { print OUTFILEP ".Vinh($ibs_Vinh), \\"."\n"; } if($ibs_Vinl ne "") { print OUTFILEP ".Vinl($ibs_Vinl), \\"."\n"; } } if($ibs_model_type1 ne "IBIS_INPUT") { print OUTFILEP ".V_pc_ref($ibs_V_pc_ref{$corner}), \\"."\n"; print OUTFILEP ".V_gc_ref($ibs_V_gc_ref{$corner}), \\"."\n"; if($ibs_model_type1 ne "IBIS_OPENSINK" && $ibs_model_type1 ne "IBIS_IO_OPENSINK") { print OUTFILEP ".V_pu_ref($ibs_V_pu_ref{$corner}), \\"."\n"; print OUTFILEP ".V_pd_ref($ibs_V_pd_ref{$corner}), \\"."\n\\"."\n"; } } print OUTFILEP ".IVpc_length($PC_counter), \\"."\n"; print OUTFILEP ".I_pc({$ibs_I_pc{$corner}}), \\"."\n"; print OUTFILEP ".V_pc({$ibs_V_pc}), \\"."\n"; print OUTFILEP ".IVgc_length($GC_counter), \\"."\n"; print OUTFILEP ".I_gc({$ibs_I_gc{$corner}}), \\"."\n"; print OUTFILEP ".V_gc({$ibs_V_gc})"; if($ibs_model_type1 ne "IBIS_INPUT") { print OUTFILEP ", \\"."\n\\"."\n"; if($ibs_model_type1 ne "IBIS_OPENSINK" && $ibs_model_type1 ne "IBIS_IO_OPENSINK" ) { print OUTFILEP ".IVpu_length($PU_counter), \\"."\n"; print OUTFILEP ".I_pu({$ibs_I_pu{$corner}}), \\"."\n"; print OUTFILEP ".V_pu({$ibs_V_pu}), \\"."\n"; } if($ibs_model_type1 ne "IBIS_OPENSOURCE" && $ibs_model_type1 ne "IBIS_IO_OPENSOURCE" ) { print OUTFILEP ".IVpd_length($PD_counter), \\"."\n"; print OUTFILEP ".I_pd({$ibs_I_pd{$corner}}), \\"."\n"; print OUTFILEP ".V_pd({$ibs_V_pd}), \\"."\n\\"."\n"; } } if($ibs_model_type1 ne "IBIS_INPUT") { print OUTFILEP ".Vfx_r1($Vfx_r{\"1\".$corner}), \\"."\n"; print OUTFILEP ".Rfx_r1($Rfx_r{\"1\"}), \\"."\n"; print OUTFILEP ".VTr1_length($TR_counter{\"1\"}), \\"."\n"; print OUTFILEP ".Tr1({$ibs_T_tr{\"1\"}}), \\"."\n"; print OUTFILEP ".Vr1({$ibs_V_tr{$corner.\"1\"}}), \\"."\n\\"."\n"; print OUTFILEP ".Vfx_f1($Vfx_f{\"1\".$corner}), \\"."\n"; print OUTFILEP ".Rfx_f1($Rfx_f{\"1\"}), \\"."\n"; print OUTFILEP ".VTf1_length($TF_counter{\"1\"}), \\"."\n"; print OUTFILEP ".Tf1({$ibs_T_tf{\"1\"}}), \\"."\n"; print OUTFILEP ".Vf1({$ibs_V_tf{$corner.\"1\"}})"; if($ibs_model_type1 ne "IBIS_OPENSINK" && $ibs_model_type1 ne "IBIS_IO_OPENSINK" && $ibs_model_type1 ne "IBIS_OPENSOURCE" && $ibs_model_type1 ne "IBIS_IO_OPENSOURCE") { print OUTFILEP ", \\"."\n\\"."\n"; print OUTFILEP ".Vfx_r2($Vfx_r{\"2\".$corner}), \\"."\n"; print OUTFILEP ".Rfx_r2($Rfx_r{\"2\"}), \\"."\n"; print OUTFILEP ".VTr2_length($TR_counter{\"2\"}), \\"."\n"; print OUTFILEP ".Tr2({$ibs_T_tr{\"2\"}}), \\"."\n"; print OUTFILEP ".Vr2({$ibs_V_tr{$corner.\"2\"}}), \\"."\n\\"."\n"; print OUTFILEP ".Vfx_f2($Vfx_f{\"2\".$corner}), \\"."\n"; print OUTFILEP ".Rfx_f2($Rfx_f{\"2\"}), \\"."\n"; print OUTFILEP ".VTf2_length($TF_counter{\"2\"}), \\"."\n"; print OUTFILEP ".Tf2({$ibs_T_tf{\"2\"}}), \\"."\n"; print OUTFILEP ".Vf2({$ibs_V_tf{$corner.\"2\"}})"."\n"; } } print OUTFILEP "\n"; close OUTFILEP; } ################################################################################################# # Create output .dat file in VHDL-A(MS) format ################################################################################################# sub create_vhdl_output_file{ open( OUTFILEP, "> $_[0]" ) or die "Can't open $_[0]"; print OUTFILEP "-- Generated on: ".&Return_time."\n-- Input file: $in_ibs_file\n"; print OUTFILEP "-- VHDL-A primitive type: $ibs_model_type1 corner=$corner1\n\n"; if($ibs_C_comp{$corner} ne "") { print OUTFILEP "-----------------------"."\n"; print OUTFILEP "-- C_comp Parameters --"."\n"; print OUTFILEP "-----------------------"."\n"; print OUTFILEP "C_comp"."\n$ibs_C_comp{$corner}"."\n"; print OUTFILEP "kC_comp_pc\n0.25\n"; print OUTFILEP "kC_comp_pu\n0.25\n"; print OUTFILEP "kC_comp_pd\n0.25\n"; print OUTFILEP "kC_comp_gc\n0.25\n"; } if($ibs_model_type1 ne "IBIS_OUTPUT" &&$ibs_model_type1 ne "IBIS_OPENSINK" && $ibs_model_type1 ne "IBIS_OPENSOURCE") { if($ibs_Vinh ne "") { print OUTFILEP "-------------------------"."\n"; print OUTFILEP "-- Receiver Thresholds --"."\n"; print OUTFILEP "-------------------------"."\n"; print OUTFILEP "Vinh\n$ibs_Vinh"."\n"; } if($ibs_Vinl ne "") { print OUTFILEP "Vinl\n$ibs_Vinl"."\n"; } } if($ibs_model_type1 ne "IBIS_INPUT") { print OUTFILEP "-------------------------------------------------"."\n"; print OUTFILEP "-- [Pullup Reference] and [Pulldown Reference] --"."\n"; print OUTFILEP "-------------------------------------------------"."\n"; print OUTFILEP "V_pc_ref\n$ibs_V_pc_ref{$corner}"."\n"; print OUTFILEP "V_gc_ref\n$ibs_V_gc_ref{$corner}"."\n"; if($ibs_model_type1 ne "IBIS_OPENSINK" && $ibs_model_type1 ne "IBIS_IO_OPENSINK") { print OUTFILEP "V_pu_ref\n$ibs_V_pu_ref{$corner}"."\n"; print OUTFILEP "V_pd_ref\n$ibs_V_pd_ref{$corner}"."\n"; } } print OUTFILEP "\n"; #print OUTFILEP ".IVpc_length($PC_counter), \\"."\n"; $ibs_I_pc{$corner}=~s/, /\n/g; print OUTFILEP "---------------------"."\n"; print OUTFILEP "-- IV curve tables --"."\n"; print OUTFILEP "---------------------"."\n"; print OUTFILEP "I_pc\n$ibs_I_pc{$corner}"."\n\n"; $ibs_V_pc=~s/, /\n/g; print OUTFILEP "V_pc\n$ibs_V_pc"."\n\n"; #print OUTFILEP ".IVgc_length($GC_counter), \\"."\n"; $ibs_I_gc{$corner}=~s/, /\n/g; print OUTFILEP "I_gc\n$ibs_I_gc{$corner}"."\n\n"; $ibs_V_gc=~s/, /\n/g; print OUTFILEP "V_gc\n$ibs_V_gc"."\n\n"; if($ibs_model_type1 ne "IBIS_INPUT") { if($ibs_model_type1 ne "IBIS_OPENSINK" && $ibs_model_type1 ne "IBIS_IO_OPENSINK" ) { #print OUTFILEP "IVpu_length($PU_counter), \\"."\n"; $ibs_I_pu{$corner}=~s/, /\n/g; print OUTFILEP "\nI_pu\n$ibs_I_pu{$corner}"."\n"; $ibs_V_pu=~s/, /\n/g; print OUTFILEP "\nV_pu\n$ibs_V_pu"."\n"; } if($ibs_model_type1 ne "IBIS_OPENSOURCE" && $ibs_model_type1 ne "IBIS_IO_OPENSOURCE" ) { #print OUTFILEP ".IVpd_length($PD_counter), \\"."\n"; $ibs_I_pd{$corner}=~s/, /\n/g; print OUTFILEP "\nI_pd\n$ibs_I_pd{$corner}"."\n"; $ibs_V_pd=~s/, /\n/g; print OUTFILEP "\nV_pd\n$ibs_V_pd"."\n"; } } print OUTFILEP "\n"; if($ibs_model_type1 ne "IBIS_INPUT") { #print OUTFILEP "`define $in_ibs_file1"."_$in_model_name"."_VT_data \\"."\n"; print OUTFILEP "---------------------"."\n"; print OUTFILEP "-- Vt curve tables --"."\n"; print OUTFILEP "---------------------"."\n"; print OUTFILEP "\nVfx_r1\n$Vfx_r{\"1\".$corner}"."\n"; print OUTFILEP "\nRfx_r1\n$Rfx_r{\"1\"}"."\n"; #print OUTFILEP "\nVTr1_length\n$TR_counter{\"1\"}"."\n"; $ibs_T_tr{"1"}=~s/, /\n/g; print OUTFILEP "\nTr1\n$ibs_T_tr{\"1\"}"."\n"; $ibs_V_tr{$corner."1"}=~s/, /\n/g; print OUTFILEP "\nVr1\n$ibs_V_tr{$corner.\"1\"}"."\n"; print OUTFILEP "\nVfx_f1\n$Vfx_f{\"1\".$corner}"."\n"; print OUTFILEP "\nRfx_f1\n$Rfx_f{\"1\"}"."\n"; #print OUTFILEP "\nVTf1_length\n$TF_counter{\"1\"}"."\n"; $ibs_T_tf{"1"}=~s/, /\n/g; print OUTFILEP "\nTf1\n$ibs_T_tf{\"1\"}"."\n"; $ibs_V_tf{$corner."1"}=~s/, /\n/g; print OUTFILEP "\nVf1\n$ibs_V_tf{$corner.\"1\"}"."\n"; if($ibs_model_type1 ne "IBIS_OPENSINK" && $ibs_model_type1 ne "IBIS_IO_OPENSINK" && $ibs_model_type1 ne "IBIS_OPENSOURCE" && $ibs_model_type1 ne "IBIS_IO_OPENSOURCE") { print OUTFILEP "\nVfx_r2\n$Vfx_r{\"2\".$corner}"."\n"; print OUTFILEP "\nRfx_r2\n$Rfx_r{\"2\"}"."\n"; #print OUTFILEP "\nVTr2_length\n$TR_counter{\"2\"}"."\n"; $ibs_T_tr{"2"}=~s/, /\n/g; print OUTFILEP "\nTr2\n$ibs_T_tr{\"2\"}"."\n"; $ibs_V_tr{$corner."2"}=~s/, /\n/g; print OUTFILEP "\nVr2\n$ibs_V_tr{$corner.\"2\"}"."\n"; print OUTFILEP "\nVfx_f2\n$Vfx_f{\"2\".$corner}"."\n"; print OUTFILEP "\nRfx_f2\n$Rfx_f{\"2\"}"."\n"; #print OUTFILEP "\nVTf2_length\n$TF_counter{\"2\"}"."\n"; $ibs_T_tf{"2"}=~s/, /\n/g; print OUTFILEP "\nTf2\n$ibs_T_tf{\"2\"}"."\n"; $ibs_V_tf{$corner."2"}=~s/, /\n/g; print OUTFILEP "\nVf2\n$ibs_V_tf{$corner.\"2\"}"."\n"; } } close OUTFILEP; } ################################################################################################# # Formats numerical values to exponential notation ################################################################################################# sub parse_val{ my $line; $line=$_[0]; $line=~s/V//g; $line=~s/A//g; $line=~s/F//g; $line=~s/ohm(\s*)$//g; $line=~s/f/E-15/g; $line=~s/p/E-12/g; $line=~s/n/E-9/g; $line=~s/u/E-6/g; $line=~s/m/E-3/g; $line=~s/k/E+3/g; $line=~s/M/E+6/g; $line=~s/G/E+9/g; $line=~s/T/E+12/g; return $line; } ################################################################################################# # Prints all datastructures ################################################################################################# sub print_all_structs{ print "// Generated on: ".&Return_time."\n\n"; print "ibs_model_type=$ibs_model_type\n"; print "ibs_Vinl=$ibs_Vinl\n"; print "ibs_Vinh=$ibs_Vinh\n"; print "ibs_Vmeas=$ibs_Vmeas\n"; print "ibs_Cref=$ibs_Cref\n"; foreach $line (%ibs_C_comp) { # prints ibs_C_comp t,n,x if($ibs_C_comp{$line} ne "") { print "ibs_C_comp_$line = $ibs_C_comp{$line}\t"; } } print "\n"; foreach $line (%ibs_vrange) { # prints ibs_vrange t,n,x if($ibs_vrange{$line} ne "") { print "ibs_vrange_$line = $ibs_vrange{$line}\t"; } } print "\n"; foreach $line (%ibs_trange) { # prints ibs_trange t,n,x if($ibs_trange{$line} ne "") { print "ibs_trange_$line = $ibs_trange{$line}\t"; } } print "\n"; print "\n"; ##################################### print "ibs_V_pc=$ibs_V_pc\n"; # prints PC voltages print "PC_counter=$PC_counter\n"; # prints PC number of datapoints foreach $line (%ibs_I_pc) { # prints PC currents t,n,x if($ibs_I_pc{$line} ne "") { print "ibs_I_pc_$line = $ibs_I_pc{$line}"; } print "\n"; } print "\n"; print "\n"; print "ibs_V_gc=$ibs_V_gc\n"; # GC print "GC_counter=$GC_counter\n"; foreach $line (%ibs_I_gc) { if($ibs_I_gc{$line} ne "") { print "ibs_I_gc_$line = $ibs_I_gc{$line}"; } print "\n"; } print "\n"; print "\n"; print "ibs_V_pu=$ibs_V_pu\n"; # PU print "PU_counter=$PU_counter\n"; foreach $line (%ibs_I_pu) { if($ibs_I_pu{$line} ne "") { print "ibs_I_pu_$line = $ibs_I_pu{$line}"; } print "\n"; } print "\n"; print "\n"; print "ibs_V_pd=$ibs_V_pd\n"; # PD print "PD_counter=$PD_counter\n"; foreach $line (%ibs_I_pd) { if($ibs_I_pd{$line} ne "") { print "ibs_I_pd_$line = $ibs_I_pd{$line}"; } print "\n"; } print "\n"; print "\n"; print "ibs_T_tr{\"1\"}=$ibs_T_tr{\"1\"}\n"; # prints rising waweforms(1) time range print "PD_counter=$TR_counter{\"1\"}\n"; # prints rising waweforms(1) number of datapoints foreach $line (%ibs_V_tr) { # prints rising waweforms(1) voltages t,n,x if($ibs_V_tr{$line} ne "") { print "ibs_V_tr_$line = $ibs_V_tr{$line}"; } print "\n"; } print "\n"; print "\n"; } ################################################################################################# # Return_time - formats the time for time stamping the output files ################################################################################################# sub Return_time { my $sec; my $min; my $hour; my $mday; my $mon; my $year; my $wday; my $yday; ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday) = localtime(time); $year=$year+1900; $mon=$mon+1; return "Time: $hour:$min:$sec\tDate: $mon/$mday, $year"; } ################################################################################################# # Editor_module - Opens a file for viewing purposes ################################################################################################# sub Editor_module { my $line1; my $file_to_open; if($_[0]) { $file_to_open=$_[0];} else {$file_to_open=$mw->getOpenFile(-initialfile=>"$current_dir")} if($file_to_open) { my $text_mw = MainWindow->new(-title => "File Viewer. NCSU 2006"); my $t = $text_mw->Scrolled('Text', -scrollbars=>'se')->pack(-fill => 'both', -expand => 1); $t->insert('end', ""); $t->markSet('one', '1.3'); if(open( INIBSFILEP, "< $file_to_open" )) { while( $line1= ) { $t->insert('end', $line1); } } close INIBSFILEP; } } # EOF