#!/usr/xpg4/bin/awk -f
#
# A better SPICE to sim netlist converter
#
# Use as e.g.
# sp2sim -v "l=0.3" "n=nmos" "p=pmos" "v=vdd!" file.sp
#
# Parameters: 
#    l: Value of lambda in micron
#    n: Name of nmos model
#    p: Name of pmos model
#    v: Vdd supply name
#
# Johannes Grad, IIT
#


BEGIN{
  firstline=1;
  collecting=0;
  scale=l*10^-6;
  printf("| units: %d tech: scmos format: MIT\n\n",l*100);
}

#
# Convert a string to floating point
# understands "1e6" as well as "1u" format
# Syntax: Everything that is allowed in HSPICE
#

function a2f(num){
	num=toupper(num);
	test=index(num,"E");
	if(test!=0){
		split(num,a,"E");
		mag=a[1];
		expo=a[2];
	}
	else
	{
		mag=substr(num,1,length(num)-1);
		expo=substr(num,length(num),1);
		if(expo=="T") expo=12;
		else if(expo=="G") expo=9;
		else if(expo=="MEG") expo=6;
		else if(expo=="X") expo=6;
		else if(expo=="K") expo=3;
		else if(expo=="M") expo=-3;
		else if(expo=="U") expo=-6;
		else if(expo=="N") expo=-9;
		else if(expo=="P") expo=-12;
		else if(expo=="F") expo=-15;
		else if(expo=="A") expo=-18;
		else{
			mag=num;
			expo=0;
		}
	}
	return mag*10^expo;
}

# 
# Substitutes supply names for certain nodenames
#

function doNode(node)
{
  if(toupper(node)=="0" || toupper(node)=="GND!" || toupper(node)=="GROUND") node="gnd";
  else if(node==v) node="vdd";
  return node;
}


END{
  if(collecting==1)	 
    {
      printf("%s %s %s %s %.3f %.3f\n", type, gate, source, drain, len/scale, wid*mul/scale);
    }
}


{ if(firstline==1) firstline=0;
 else if(length($0)>0)
   {
     linetype=toupper(substr($0,1,1));
     if(linetype!="+" && collecting==1)
       {
	 collecting=0;
	 printf("%s %s %s %s %.3f %.3f\n", type, gate, source, drain, len/scale, wid*mul/scale);
       }
     if(linetype=="M")
       {
	 collecting=1; mul=1;
	 drain=doNode($2);
	 gate=doNode($3);
	 source=doNode($4);
	 if($6==n) type="n";
	 else if($6==p) type="p";
	 else {printf("Unkown transistor model %s found!!!\n", $6); exit;}
	 for(i=7;i<NF+1;i++){
	   split($i,a,"=");
	   fieldtype=toupper(a[1]);
	   number=toupper(a[2]);
	   if (fieldtype=="L") len=a2f(number);
	   else if (fieldtype=="W") wid=a2f(number);
	   else if (fieldtype=="M") mul=a2f(number);

	 }
       }
     if(linetype=="+")
       {
	 $1=substr($1,2,length($1)-1);
	 for(i=1;i<NF+1;i++){
	   split($i,a,"=");
	   fieldtype=toupper(a[1]);
	   number=toupper(a[2]);
	   if (fieldtype=="L") len=a2f(number);
	   else if (fieldtype=="W") wid=a2f(number);
	   else if (fieldtype=="M") mul=a2f(number);
	 }
       }
   }
}

