Initial commit of public repository open_pdks.
diff --git a/common/pdk.tcl b/common/pdk.tcl
new file mode 100644
index 0000000..04f32a6
--- /dev/null
+++ b/common/pdk.tcl
@@ -0,0 +1,274 @@
+#-------------------------------------------------------------------
+# General-purpose routines for the PDK script in all technologies
+#-------------------------------------------------------------------
+# 
+#----------------------------------------
+# Number Conversion Functions
+#----------------------------------------
+
+#---------------------
+# Microns to Lambda
+#---------------------
+proc magic::u2l {micron} {
+    set techlambda [magic::tech lambda]
+    set tech1 [lindex $techlambda 1]
+    set tech0 [lindex $techlambda 0]
+    set tscale [expr {$tech1 / $tech0}]
+    set lambdaout [expr {((int([magic::cif scale output] * 10000)) / 10000.0)}]
+    return [expr $micron / ($lambdaout*$tscale) ]
+}
+
+#---------------------
+# Lambda to Microns
+#---------------------
+proc magic::l2u {lambda} {
+    set techlambda [magic::tech lambda]
+    set tech1 [lindex $techlambda 1] ; set tech0 [lindex $techlambda 0]
+    set tscale [expr {$tech1 / $tech0}]
+    set lambdaout [expr {((int([magic::cif scale output] * 10000)) / 10000.0)}]
+    return [expr $lambda * $lambdaout * $tscale ]
+}
+
+#---------------------
+# Internal to Microns
+#---------------------
+proc magic::i2u { value } {
+    return [expr {((int([magic::cif scale output] * 10000)) / 10000.0) * $value}]
+}
+
+#---------------------
+# Microns to Internal
+#---------------------
+proc magic::u2i {value} {
+    return [expr {$value / ((int([magic::cif scale output] * 10000)) / 10000.0)}]
+}
+
+#---------------------
+# Float to Spice 
+#---------------------
+proc magic::float2spice {value} { 
+    if {$value >= 1.0e+6} { 
+	set exponent 1e+6
+	set unit "meg"
+    } elseif {$value >= 1.0e+3} { 
+	set exponent 1e+3
+	set unit "k"
+    } elseif { $value >= 1} { 
+	set exponent 1
+	set unit ""
+    } elseif {$value >= 1.0e-3} { 
+	set exponent 1e-3
+	set unit "m"
+    } elseif {$value >= 1.0e-6} { 
+	set exponent 1e-6
+	set unit "u"
+    } elseif {$value >= 1.0e-9} { 
+	set exponent 1e-9
+	set unit "n"
+    } elseif {$value >= 1.0e-12} { 
+	set exponent 1e-12
+	set unit "p"
+    } elseif {$value >= 1.0e-15} { 
+	set exponent 1e-15
+	set unit "f"
+    } else {
+	set exponent 1e-18
+	set unit "a"
+    }
+    set val [expr $value / $exponent]
+    set val [expr int($val * 1000) / 1000.0]
+    if {$val == 0} {set unit ""}
+    return $val$unit
+}
+
+#---------------------
+# Spice to Float
+#---------------------
+proc magic::spice2float {value {faultval 0.0}} { 
+    # Remove trailing units, at least for some common combinations
+    set value [string tolower $value]
+    set value [string map {um u nm n uF n nF n pF p aF a} $value]
+    set value [string map {meg "* 1.0e6" k "* 1.0e3" m "* 1.0e-3" u "* 1.0e-6" \
+		 n "* 1.0 e-9" p "* 1.0e-12" f "* 1.0e-15" a "* 1.0e-15"} $value]
+    if {[catch {set rval [expr $value]}]} {
+	puts stderr "Value is not numeric!"
+	set rval $faultval
+    }
+    return $rval
+}
+
+#---------------------
+# Numeric Precision
+#---------------------
+proc magic::3digitpastdecimal {value} {
+    set new [expr int([expr $value * 1000 + 0.5 ]) / 1000.0]
+    return $new
+}
+
+#-------------------------------------------------------------------
+# File Access Functions
+#-------------------------------------------------------------------
+
+#-------------------------------------------------------------------
+# Ensures that a cell name does not already exist, either in
+# memory or on disk. Modifies the name until it does.
+#-------------------------------------------------------------------
+proc magic:cellnameunique {cellname} {
+    set i 0
+    set newname $cellname
+    while {[cellname list exists $newname] != 0 || [magic::searchcellondisk $newname] != 0} {
+	incr i
+	set newname ${cellname}_$i
+    }
+    return $newname
+}
+
+#-------------------------------------------------------------------
+# Looks to see if a cell exists on disk
+#-------------------------------------------------------------------
+proc magic::searchcellondisk {name} {
+    set rlist {}
+    foreach dir [path search] {
+	set ftry [file join $dir ${name}.mag]
+	if [file exists $ftry] {
+	    return 1
+	}
+    }
+    return 0
+} 
+
+#-------------------------------------------------------------------
+# Checks to see if a cell already exists on disk or in memory
+#-------------------------------------------------------------------
+proc magic::iscellnameunique {cellname} {
+    if {[cellname list exists $cellname] == 0 && [magic::searchcellondisk $cellname] == 0} { 
+	return 1
+    } else {
+	return 0
+    }
+}
+
+#--------------------------------------------------------------
+# Procedure that checks the user's "ip" subdirectory on startup
+# and adds each one's maglef subdirectory to the path.
+#--------------------------------------------------------------
+
+proc magic::query_mylib_ip {} {
+    global TECHPATH
+    global env
+    if [catch {set home $env(SUDO_USER)}] {
+        set home $env(USER)
+    }
+    set homedir /home/${home}
+    set ip_dirs [glob -directory ${homedir}/design/ip *]
+    set proj_dir [pwd]
+    set config_dir .config
+    set info_dir ${proj_dir}/${config_dir}
+    if {![file exists ${info_dir}]} {
+	set config_dir .ef-config
+	set info_dir ${proj_dir}/${config_dir}
+    }
+
+    set info_file ${info_dir}/info
+    set depends [dict create]
+    if {![catch {open $info_file r} ifd]} {
+        set depsec false
+        while {[gets $ifd line] >= 0} {
+	    if {[string first dependencies: $line] >= 0} {
+	        set depsec true
+	    }
+	    if {$depsec} {
+		if {[string first version: $line] >= 0} {
+		    if {$ipname != ""} {
+			set ipvers [string trim [lindex [split $line] 1] ']
+			dict set depends $ipname $ipvers
+			set ipname ""
+		    } else {
+			puts stderr "Badly formatted info file in ${config_dir}!"
+		    }
+		} else {
+		    set ipname [string trim $line :]
+		}
+	    }
+	}
+    }
+
+    foreach dir $ip_dirs {
+	# Version handling:  version dependencies are found in
+	# ${config_dir}/info.  For all other IP, use the most recent
+	# version number.
+	set ipname [lindex [file split $dir] end]
+	if {![catch {set version [dict get $depends $ipname]}]} {
+	    if {[file isdirectory ${dir}/${version}/maglef]} {
+		addpath ${dir}/${version}/maglef
+		continue
+	    } else {
+		puts stderr "ERROR:  Dependency ${ipname} version ${version} does not exist"
+	    }
+	}
+
+	# Secondary directory is the version number.  Use the highest
+	# version available.
+
+	set sub_dirs {}
+        catch {set sub_dirs [glob -directory $dir *]}
+	set maxver 0.0
+	foreach subdir $sub_dirs {
+	    set vidx [string last / $subdir]
+	    incr vidx
+	    set version [string range $subdir $vidx end]
+	    if {$version > $maxver} {
+		set maxver $version
+	    }
+	}
+	if {[file exists ${dir}/${maxver}/maglef]} {
+	    # Compatibility rule:  foundry name must match.
+	    # Get foundry name from ${config_dir}/techdir symbolic link reference
+	    if {[file exists ${dir}/${maxver}/${config_dir}/techdir]} {
+		set technodedir [file link ${dir}/${maxver}/${config_dir}/techdir]
+		set nidx [string last / $technodedir]
+		set techdir [string range $technodedir 0 $nidx-1]
+		if {$techdir == $TECHPATH} {
+		    addpath ${dir}/${maxver}/maglef
+		}
+	    }
+	}
+    }
+}
+
+#--------------------------------------------------------------
+# Procedure that checks the user's design directory on startup
+# and adds each one's mag subdirectory to the path.
+#--------------------------------------------------------------
+
+proc magic::query_my_projects {} {
+    global TECHPATH
+    global env
+    if [catch {set home $env(SUDO_USER)}] {
+        set home $env(USER)
+    }
+    set homedir /home/${home}
+    set proj_dirs [glob -directory ${homedir}/design *]
+    foreach dir $proj_dirs {
+	# Compatibility rule:  foundry name must match.
+	# Get foundry name from ${config_dir}/techdir symbolic link reference
+	if {[file exists ${dir}/mag]} {
+	    set config_dir .config
+	    set tech_dir ${dir}/${config_dir}
+	    if {![file exists ${tech_dir}]} {
+		set config_dir .ef-config
+		set tech_dir ${dir}/${config_dir}
+	    }
+	    if {[file exists ${dir}/${config_dir}/techdir]} {
+		set technodedir [file link ${dir}/${config_dir}/techdir]
+		set nidx [string last / $technodedir]
+		set techdir [string range $technodedir 0 $nidx-1]
+		if {$techdir == $TECHPATH} {
+		    addpath ${dir}/mag
+		}
+	    }
+	}
+    }
+}
+
+#----------------------------------------------------------------