#!/usr/local/bin/perl
# 
# modedit - automaticly make the edits we need to HP-BSIM2 mosfet models
#
# $Log: modedit,v $
# Revision 1.1  1994/11/23 18:30:12  tell
# Initial revision
#
#
#

$RSDWdiv=1.0e-6;  # what to divide RSDW by to get RS and RD
$LD=0.0;

$no_resistors = 0;	# set to 1 to defeat parasitic resistors
$no_overlapcap = 0;	# set to 1 to zero-out overlap capacitances
$no_diodecap = 0;	# set to 1 to zero out parasitic diode capacitance
$no_dlac = 0;		# set to 1 to delete D[LW]AC (hspice compatibility)
$no_namemap = 0;	# default: change model names to nfet/pfet. 1 leaves.

$process = 'hpcmos14';

# these parameters will not be passed through unchanged, but will
# still be parsed in and may modified and written out at the end of the
# model

@param_omit=('TCR', 'RSDW', 'CGDO', 'CGSO', 'CGBO', 'CJ', 'CJSW');

while($ARGV[0] =~ /^-/) {
	$option = shift(@ARGV);
	
	if($option eq '-nores') {
		$no_resistors = 1;
	} elsif($option eq '-novcap') {
		$no_overlapcap = 1;
	} elsif($option eq '-nodiodecap') {
		$no_diodecap = 1;
	} elsif($option eq '-noacdelta') {
		$no_dlwac = 1;
	} elsif($option eq '-nonamemap') {
		$no_namemap = 1;
	} elsif($option eq '-process') {
		$process = shift(@ARGV);
	} else {
		print STDERR "Unknown option: $option\n";
	}
}

if($#ARGV != 1) {
	print STDERR "usage: modedit slow|nom|fast file\n";
	exit 1;
}

if($process ne 'hpcmos14' && $process ne 'hpcmos26') {
	print STDERR "-process: must be either hpcmos14 or hpcmos26\n";
	exit 1;
}

$case = $ARGV[0];
if($case ne 'slow' && $case ne 'fast' && $case ne 'nom') {
	print STDERR "case must be one of slow, nom, or fast\n";
	exit 1;
}

$infile = $ARGV[1];

#
# These parameters have to do with the resistance of diffusion interconnect
# when contacts are not placed right next to transistors.
# They are not found in the model files, but in the HP fab documents.
# XW is width correction factor, listed as Wc in some of the documents.
#
#
# For HPCMOS14, they come from the "CMOS14TA Design Reference Manual,"
# chapter 3, "Interconnect characteristics,", page 57-59.
# RSH, N/P-island sheet resistance, comes from table 3-1 and 3-3
# XW, N/P-island width correction factor, comes from table 3-2 and 3-4
# TCR, temperature coeficient of resistance for RSH, comes from the text of
# sections 3.1.1.1 and 3.1.1.2.    The parameters are the same for N and P
# transistors; this code will have to be changed if that is not true for some
# process.

if($process eq 'hpcmos14') {
	$TCR=0.0042;
	if($case eq "slow") {
		$XW=-0.15e-6;
		$RSH=5.0;
	} elsif($case eq "nom") {
		$XW=0.07e-6;
		$RSH=2.5;
	} elsif($case eq "fast") {
		$XW=0.15e-6;
		$RSH=1.0;
	} else {
		print STDERR "no case $case\n";
		exit(1);
	}
#
# For HPCMOS26, these come from "CMOS26 Design Rules, Rev C, Page 75"
#
} elsif($process eq 'hpcmos26') {
	$TCR=0.0042;
	if($case eq "slow") {
		$XW=-0.34e-6;
		$RSH=5.0;
	} elsif($case eq "nom") {
		$XW=-0.20e-6;
		$RSH=3.0;
	} elsif($case eq "fast") {
		$XW=-0.06e-6;
		$RSH=2.0;
	} else {
		print STDERR "no case $case\n";
		exit(1);
	}
} else {
	print STDERR "no process\n";
	exit(1);
}

open($infile, $infile) || die "can't open $infile\n";

print "* processed by modedit $case\n";
if($no_resistors == 1) {
	printf STDERR "Models will have source and drain resistors forced to 0\n";
	print "*** Devices have source and drain resistors forced to 0\n";
	$LDIF=0;
	$HDIF=0;
} else {
	$LDIF=1.0e-6;
	$HDIF=1.0e-6;
}
if($no_overlapcap == 1) {
	print STDERR "Models will have overlap capacitances forced to 0\n";
	print "*** Devices have overlap capacitances forced to 0\n";
}
if($no_diodecap == 1) {
	print STDERR "Models will have parasitic diode capacitances forced to 0\n";
	print "*** Devices have parasitic diode capacitances forced to 0\n";
}
if($no_dlwac) {
	print STDERR "Models will have AC geometry correction omitted\n";
	print "*** Devices have DLAC/DWAC omitted\n";
	push(@param_omit, 'DLAC', 'DWAC');
}


foreach $par (@param_omit) {
	$param_omit{$par} = 1;
}

$lineno = 0;
$nmod = 0;
line: while($_ = <$infile> ) {
	$lineno++;
	if($_ =~ /^\*/) {
		print $_;
	} elsif($_ =~ /^\s*$/) {
		print $_;
	} elsif($_ =~ /^.model/) {
		($dotmod, $modname, $type) = split(/[ \t\n]+/, $_);
		$nmod++;
		$nparline=0;
		if($no_namemap == 0) {
			$modname =~ s/^N\.(\S)/nfet.$1/;
			$modname =~ s/^P\.(\S)/pfet.$1/;
			$modname =~ s/^NENH\.(\S)/nfet.$1/;
			$modname =~ s/^PENH\.(\S)/pfet.$1/;
		}

		print ".model $modname $type\n";
		print "+ ACM=2\n";

		cont: while($_ = <$infile> ) {
			# this counts on the fact that the line after
			# the last continuation line is a comment-line in
			# the model files
			if($_ !~ /^\+/) {
				last cont;
			}
			#print $_;
			$nparline++;

			$_ =~ s/^\+\s*//;
			@params = split(/[ \t\n]+/, $_);
			@outpars=();
			foreach $par (@params) {
				($parname, $parval) = split(/[=]/, $par);
				if($parname eq 'WMAX' && $parval > 10e-3) {
					$parval = 1e3;
				}
				if($parname eq 'LMAX' && $parval > 10e-3) {
					$parval = 1e3;
				}
				$params{$parname} = $parval;
				if($param_omit{$parname} != 1) {
					push(@outpars, "$parname=$parval");
				}
			}
			if($#outpars >= 0) {
				print "+ ", join("\t", @outpars), "\n";
			}
		}
		# we now have all of the parameters for this model.
		# they've already been printed out, but we can insert
		# new ones here, and add on constant ones
		if($no_diodecap) {
			print "+ CJ=0.0\n";
			print "+ CJSW=0.0\n";
		} else {
			printf "+ CJ=%g\n", $params{'CJ'};
			printf "+ CJSW=%g\n", $params{'CJSW'};
		}
		if($no_overlapcap) {
			print "+ CGSO=0.0\n";
			print "+ CGDO=0.0\n";
			print "+ CGBO=0.0\n";
		} else {
			printf "+ CGSO=%g\n", $params{'CGSO'};
			printf "+ CGDO=%g\n", $params{'CGDO'};
			if(defined($params{'CGBO'})) {
				printf "+ CGBO=%g\n", $params{'CGBO'};
			}
		}
		printf "+ LDIF=%g\tLD=%g\n", $LDIF, $LD;
		printf "+ TCR=%g\tXW=%g\tRSH=%g\n", $TCR, $XW, $RSH;
		$rs = $params{'RSDW'}/$RSDWdiv;
		printf "+ RS=%g\tRD=%g\n", $rs, $rs;

		print "*\n";
	} else {
		print STDERR "Unknown line at $lineno: $_";
		exit 1;
	}
}

print STDERR "$nmod models processed\n";
exit 0;
######################################################################
