用户工具

站点工具


vlsi:scripts:create-lib-from-verilog

Create .lib File From Verilog

从网表产生.lib,再生成.db文件,是后端经常做的工作。

通常我们用PrimeTime产生.db和.lib文件。

其实我们可以直接根据网表写一个空的.lib文件,再用DC生成.db。应该比较快一些。

下面的脚本可以根据网表直接写出一个.lib文件,和大家一起分享。

用法:

create_lib <verilog_netlist> <module_name> [transition_value] [capacitance_value]

脚本代码

#!/usr/bin/perl
 
use strict;
 
if ($#ARGV < 1 ) {
	print "usage: create_lib <verilog_netlist> <module_name> \n";
	exit;
}
 
my $netlist = $ARGV[0] ;
my $module  = $ARGV[1] ;
my $tran = 2.5 ;
my $cap = 0.001;
my $signal_level = "VDD" ;
 
if(defined $ARGV[2]) {$tran = $ARGV[2];}
if(defined $ARGV[3]) {$cap = $ARGV[3];}
if(defined $ARGV[4]) {$signal_level = $ARGV[4];}
 
my $FF;
my $FO;
open $FF, "< $ARGV[0]" or die "Can't open $ARGV[0] : $!";
open $FO, ">$module.lib" or die "Can't open $module.lib for write : $!";
 
my $db = createTopLevelDB(); 
createDotLib($db,$FO);
 
sub createDotLib
{
	my $topLevelDBRef = shift;
	my $FO = shift ;	
	### Header 
	print $FO "library\($topLevelDBRef->{'design'}->{'cell'}\) {\n";
	print $FO "\n /* unit attributes */\n";
	print $FO "  time_unit : \"1ns\"\;\n";
	print $FO "  voltage_unit : \"1V\"\;\n";
	print $FO "  current_unit : \"1uA\"\;\n";
	print $FO "  pulling_resistance_unit : \"1kohm\"\;\n";
	print $FO "  leakage_power_unit : \"1nW\"\;\n";
	print $FO "  capacitive_load_unit\(1,pf\)\;\n\n";
	foreach my $direction (keys(%{$topLevelDBRef->{'bus'}})) {
		foreach my $bus_type (keys %{$topLevelDBRef->{'bus'}->{$direction}}) {
			my @bus_width =  split(/_/, $bus_type); 
			my $bus_hi = $bus_width[1] ;
			my $bus_lo = $bus_width[2] ;
			my $bus_width = $bus_hi+1-$bus_lo;
			print $FO " type \($bus_type\) { \n";
			print $FO "   base_type : array ; \n" ;
    			print $FO "   data_type : bit  \n" ;;
    			print $FO "   bit_width : $bus_width   \n" ;;
    			print $FO "   bit_from : $bus_hi  \n" ;;
    			print $FO "   bit_to : $bus_lo ; \n" ;
    			print $FO "   downto : true ; \n" ;
    			print $FO " } \n" ;
		}
	}
	print $FO "\n  cell\($topLevelDBRef->{'design'}->{'cell'}\) {\n";
	foreach my $direction (keys(%{$topLevelDBRef->{'pins'}})) {
		foreach my $pin_name (@{$topLevelDBRef->{'pins'}->{$direction}}) {
			print $FO ("    pin\($pin_name\) { \n");
			print $FO ("\tdirection : $direction ;\n");
			if($direction eq "input") {
				print $FO ("\tmax_transition : $tran;\n");
			}
			print $FO ("\tcapacitance : $cap; \n");  	
			print $FO ("    } \n") ;
		}
	}
	foreach my $direction (keys(%{$topLevelDBRef->{'bus'}})) {
		foreach my $bus_type (keys %{$topLevelDBRef->{'bus'}->{$direction}}) {
			my @bus_width =  split(/_/, $bus_type); 
			my $bus_hi = $bus_width[1] ;
			my $bus_lo = $bus_width[2] ;
			foreach my $bus_name (@{$topLevelDBRef->{'bus'}->{$direction}{$bus_type}}) {
                                        chomp($bus_name);
				print "BUS $bus_name : $bus_type : $direction \n" ;
				print $FO ("    bus\($bus_name\) { \n");
				print $FO ("\tbus_type : $bus_type ;\n");
				print $FO ("\tdirection : $direction ;\n");
				if($direction eq "input") {
					print $FO ("\tmax_transition : $tran;\n");
				}	
				for(my $i=$bus_lo; $i<=$bus_hi; $i++) {
					print $FO ("\tpin\($bus_name\[$i\]\) { \n");
					print $FO ("\t\tcapacitance : $cap; \n");  
					print $FO ("\t} \n") ;
				}
				print $FO ("    } \n") ;
			}
		}
	}
	print $FO ("  } \n") ;
	print $FO ("} \n") ;
}
 
sub createTopLevelDB 
{
	my $find_top_module = 0; 
	my %topLevelDB = () ;
	my %pins = () ;
	my %bus = () ;
	my @input_pins ;
	my @output_pins ;
	my @inout_pins ;
	my @bus_types ; 
	my %input_bus = () ;
	my %output_bus = () ;
	my %inout_bus = () ;
	my %design = ();
	$design{'cell'} = $module; 
	$design{'tran'} = $tran; 
	$design{'cap'} = $cap; 
	$design{'signal_level'} = $signal_level; 
	while(my $line = <$FF>) {
		last if($find_top_module == 1);
		if($line=~/module\s+$module/) {
			$find_top_module = 1 ;
			while(my $line = <$FF>) {
				next if($line =~ "\s*//" );
				chomp($line);
				if ($line =~/input\s+/ ) {
					$line=~s/\s*input\s+//;
					$line=~s/;//;
					if($line =~/\[(\d+):(\d+)\]/) { 
						my $bus_type = "bus_$1_$2";
						$line=~s/\[(\d+):(\d+)\]//;
						my @line =  split(/,/, $line); 
						unless(grep {$_ eq $bus_type} @bus_types) {  
							push(@bus_types,$bus_type);
						}
						foreach my $pin (@line) {
							$pin=~s/\s+//;
							push(@{$input_bus{$bus_type}}, $pin );
						}
					}
					else {
						my @line =  split(/,/, $line); 
						foreach my $pin (@line) {
							$pin=~s/\s+//;
							push(@input_pins, $pin); 
						}
					}
				}
				if ($line =~/output\s+/ ) {
					$line=~s/\s*output\s+//;
					$line=~s/;//;
					if($line =~/\[(\d+):(\d+)\]/) { 
						my $bus_type = "bus_$1_$2";
						$line=~s/\[(\d+):(\d+)\]//;
						my @line =  split(/,/, $line); 
						unless(grep {$_ eq $bus_type} @bus_types) {  
							push(@bus_types,$bus_type);
						}
						foreach my $pin (@line) {
							$pin=~s/\s+//;
							push(@{$output_bus{$bus_type}}, $pin );
						}
					}
					else {
						my @line =  split(/,/, $line); 
						foreach my $pin (@line) {
							$pin=~s/\s+//;
							push(@output_pins, $pin); 
						}
					}
 
				}
				if ($line =~/inout\s+/ ) {
					$line=~s/\s*inout\s+//;
					$line=~s/;//;
					if($line =~/\[(\d+):(\d+)\]/) { 
						my $bus_type = "bus_$1_$2";
						$line=~s/\[(\d+):(\d+)\]//;
						my @line =  split(/,/, $line); 
						unless(grep {$_ eq $bus_type} @bus_types) {  
							push(@bus_types,$bus_type);
						}
						foreach my $pin (@line) {
							$pin=~s/\s+//;
							push(@{$inout_bus{$bus_type}}, $pin );
						}
					}
					else {
						my @line =  split(/,/, $line); 
						foreach my $pin (@line) {
							$pin=~s/\s+//;
							push(@inout_pins, $pin); 
						}
					}
 
				}
 
				last if($line=~/endmodule/);
			}
 
		}
	}
	$pins{'input'} = \@input_pins;
	$pins{'output'} = \@output_pins;
	$pins{'inout'} = \@inout_pins;
	$bus{'input'} = \%input_bus;
	$bus{'output'} = \%output_bus;
	$bus{'inout'} = \%inout_bus;
	$topLevelDB{'pins'} = \%pins;
	$topLevelDB{'bus'} = \%bus;
	$topLevelDB{'design'} = \%design;
	return \%topLevelDB;
}

参考

vlsi/scripts/create-lib-from-verilog.txt · 最后更改: 2013/02/25 07:57 (外部编辑)