diff --git a/common/foundry_install.py b/common/foundry_install.py
index 149c21f..267342b 100755
--- a/common/foundry_install.py
+++ b/common/foundry_install.py
@@ -116,6 +116,13 @@
 import fnmatch
 import subprocess
 
+# Import local routines
+from create_gds_library import create_gds_library
+from create_spice_library import create_spice_library
+from create_lef_library import create_lef_library
+from create_lib_library import create_lib_library
+from create_verilog_library import create_verilog_library
+
 def usage():
     print("foundry_install.py [options...]")
     print("   -copy             Copy files from source to target (default)")
@@ -327,438 +334,6 @@
                         print(line)
 
 #----------------------------------------------------------------------------
-# Given a destination directory holding individual verilog files of a number
-# of modules, create a single verilog library file named <alllibname> and place
-# it in the same directory.  This is done for the option "compile" if specified
-# for the "-verilog" install.
-#----------------------------------------------------------------------------
-
-def create_verilog_library(destlibdir, destlib, do_compile_only, do_stub, excludelist):
-
-    alllibname = destlibdir + '/' + destlib + '.v'
-    if os.path.isfile(alllibname):
-        os.remove(alllibname)
-
-    print('Diagnostic:  Creating consolidated verilog library ' + destlib + '.v')
-    vlist = glob.glob(destlibdir + '/*.v')
-    if alllibname in vlist:
-        vlist.remove(alllibname)
-
-    # Create exclude list with glob-style matching using fnmatch
-    if len(vlist) > 0:
-        vlistnames = list(os.path.split(item)[1] for item in vlist)
-        notvlist = []
-        for exclude in excludelist:
-            notvlist.extend(fnmatch.filter(vlistnames, exclude))
-
-        # Apply exclude list
-        if len(notvlist) > 0:
-            for file in vlist[:]:
-                if os.path.split(file)[1] in notvlist:
-                    vlist.remove(file)
-
-    if len(vlist) > 1:
-        print('New file is:  ' + alllibname)
-        with open(alllibname, 'w') as ofile:
-            allmodules = []
-            for vfile in vlist:
-                with open(vfile, 'r') as ifile:
-                    # print('Adding ' + vfile + ' to library.')
-                    vtext = ifile.read()
-                    modules = re.findall(r'[ \t\n]module[ \t]+([^ \t\n\(]+)', vtext)
-                    mseen = list(item for item in modules if item in allmodules)
-                    allmodules.extend(list(item for item in modules if item not in allmodules))
-                    vfilter = remove_redundant_modules(vtext, allmodules, mseen)
-                    # NOTE:  The following workaround resolves an issue with iverilog,
-                    # which does not properly parse specify timing paths that are not in
-                    # parentheses.  Easy to work around
-                    vlines = re.sub(r'\)[ \t]*=[ \t]*([01]:[01]:[01])[ \t]*;', r') = ( \1 ) ;', vfilter)
-                    print(vlines, file=ofile)
-                print('\n//--------EOF---------\n', file=ofile)
-
-        if do_compile_only == True:
-            print('Compile-only:  Removing individual verilog files')
-            for vfile in vlist:
-                if os.path.isfile(vfile):
-                    os.remove(vfile)
-                elif os.path.islink(vfile):
-                    os.unlink(vfile)
-    else:
-        print('Only one file (' + str(vlist) + ');  ignoring "compile" option.')
-
-#----------------------------------------------------------------------------
-# Remove redundant module entries from a verilog file.  "m2list" is a list of
-# module names gleaned from all previously read files using re.findall().
-# "mlist" is a list of all module names including those in "ntext".
-# The reason for doing this is that some verilog files may includes modules used
-# by all the files, and if included more than once, then iverilog complains.
-#----------------------------------------------------------------------------
-
-def remove_redundant_modules(ntext, mlist, m2list):
-    updated = ntext
-    for module in mlist:
-        # Determine the number of times the module appears in the text
-        if module in m2list:
-            # This module seen before outside of ntext, so remove all occurrances in ntext
-            new = re.sub(r'[ \t\n]+module[ \t]+' + module + '[ \t\n\(]+.*[ \t\n]endmodule', '\n', updated, flags=re.DOTALL)
-            updated = new
-
-        else:
-            n = len(re.findall(r'[ \t\n]module[ \t]+' + module + '[ \t\n\(]+.*[ \t\n]endmodule', updated, flags=re.DOTALL))
-            # This module defined more than once inside ntext, so remove all but one
-            # Optimization:  Just keep original text if n < 2
-            if n < 2:
-                continue
-
-            # Remove all but one
-            updated = re.sub(r'[ \t\n]+module[ \t]+' + module + '[ \t\n]+.*[ \t\n]endmodule', '\n', n - 1, updated, flags=re.IGNORECASE | re.DOTALL)
-    return updated
-
-#----------------------------------------------------------------------------
-# Given a destination directory holding individual LEF files of a number
-# of cells, create a single LEF library file named <alllibname> and place
-# it in the same directory.  This is done for the option "compile" if specified
-# for the "-lef" install.
-#----------------------------------------------------------------------------
-
-def create_lef_library(destlibdir, destlib, do_compile_only, excludelist):
-
-    alllibname = destlibdir + '/' + destlib + '.lef'
-    if os.path.isfile(alllibname):
-        os.remove(alllibname)
-
-    print('Diagnostic:  Creating consolidated LEF library ' + destlib + '.lef')
-    llist = glob.glob(destlibdir + '/*.lef')
-    if alllibname in llist:
-        llist.remove(alllibname)
-
-    # Create exclude list with glob-style matching using fnmatch
-    if len(llist) > 0:
-        llistnames = list(os.path.split(item)[1] for item in llist)
-        notllist = []
-        for exclude in excludelist:
-            notllist.extend(fnmatch.filter(llistnames, exclude))
-
-        # Apply exclude list
-        if len(notllist) > 0:
-            for file in llist[:]:
-                if os.path.split(file)[1] in notllist:
-                    llist.remove(file)
-
-    if len(llist) > 1:
-        print('New file is:  ' + alllibname)
-        with open(alllibname, 'w') as ofile:
-            headerdone = False
-            for lfile in llist:
-                with open(lfile, 'r') as ifile:
-                    # print('Adding ' + lfile + ' to library.')
-                    ltext = ifile.read()
-                    llines = ltext.splitlines()
-                    headerseen = False
-                    for lline in llines:
-                        if headerdone:
-                            if not headerseen:
-                                if not lline.startswith('MACRO'):
-                                    continue
-                                else:
-                                    headerseen = True
-                        print(lline, file=ofile)
-                    headerdone = True
-                print('#--------EOF---------\n', file=ofile)
-
-        if do_compile_only == True:
-            print('Compile-only:  Removing individual LEF files')
-            for lfile in llist:
-                if os.path.isfile(lfile):
-                    os.remove(lfile)
-            if newname:
-                if os.path.isfile(newname):
-                    os.remove(newname)
-    else:
-        print('Only one file (' + str(llist) + ');  ignoring "compile" option.')
-
-#----------------------------------------------------------------------------
-# Given a destination directory holding individual liberty files of a number
-# of cells, create a single liberty library file named <alllibname> and place
-# it in the same directory.  This is done for the option "compile" if specified
-# for the "-lib" install.
-#----------------------------------------------------------------------------
-
-# Warning:  This script is unfinished.  Needs to parse the library header
-# in each cell and generate a new library header combining the contents of
-# all cell headers.  Also:  The library name in the header needs to be
-# changed to the full library name.  Also:  There is no mechanism for
-# collecting all files belonging to a single process corner/temperature/
-# voltage.
-
-def create_lib_library(destlibdir, destlib, do_compile_only, excludelist):
-
-    alllibname = destlibdir + '/' + destlib + '.lib'
-    if os.path.isfile(alllibname):
-        os.remove(alllibname)
-
-    print('Diagnostic:  Creating consolidated liberty library ' + destlib + '.lib')
-
-    # Create exclude list with glob-style matching using fnmatch
-    if len(llist) > 0:
-        llistnames = list(os.path.split(item)[1] for item in llist)
-        notllist = []
-        for exclude in excludelist:
-            notllist.extend(fnmatch.filter(llistnames, exclude))
-
-        # Apply exclude list
-        if len(notllist) > 0:
-            for file in llist[:]:
-                if os.path.split(file)[1] in notllist:
-                    llist.remove(file)
-
-    if len(llist) > 1:
-        print('New file is:  ' + alllibname)
-        with open(alllibname, 'w') as ofile:
-            headerdone = False
-            for lfile in llist:
-                with open(lfile, 'r') as ifile:
-                    # print('Adding ' + lfile + ' to library.')
-                    ltext = ifile.read()
-                    llines = ltext.splitlines()
-                    headerseen = False
-                    for lline in llines:
-                        if headerdone:
-                            if not headerseen:
-                                if not lline.split()[0] == 'cell':
-                                    continue
-                                else:
-                                    headerseen = True
-                        print(lline, file=ofile)
-                    headerdone = True
-                print('/*--------EOF---------*/\n', file=ofile)
-
-        if do_compile_only == True:
-            print('Compile-only:  Removing individual LEF files')
-            for lfile in llist:
-                if os.path.isfile(lfile):
-                    os.remove(lfile)
-            if newname:
-                if os.path.isfile(newname):
-                    os.remove(newname)
-    else:
-        print('Only one file (' + str(llist) + ');  ignoring "compile" option.')
-
-#----------------------------------------------------------------------------
-# Given a destination directory holding individual GDS files of a number
-# of cells, create a single GDL library file named <alllibname> and place
-# it in the same directory.  This is done for the option "compile" if specified
-# for the "-gds" install.
-#----------------------------------------------------------------------------
-
-def create_gds_library(destlibdir, destlib, startup_script, do_compile_only, excludelist):
-
-    alllibname = destlibdir + '/' + destlib + '.gds'
-    if os.path.isfile(alllibname):
-        os.remove(alllibname)
-
-    print('Diagnostic:  Creating consolidated GDS library ' + destlib + '.gds')
-    glist = glob.glob(destlibdir + '/*.gds')
-    glist.extend(glob.glob(destlibdir + '/*.gdsii'))
-    glist.extend(glob.glob(destlibdir + '/*.gds2'))
-    if alllibname in glist:
-        glist.remove(alllibname)
-
-    # Create exclude list with glob-style matching using fnmatch
-    if len(glist) > 0:
-        glistnames = list(os.path.split(item)[1] for item in glist)
-        notglist = []
-        for exclude in excludelist:
-            notglist.extend(fnmatch.filter(glistnames, exclude))
-
-        # Apply exclude list
-        if len(notglist) > 0:
-            for file in glist[:]:
-                if os.path.split(file)[1] in notglist:
-                    glist.remove(file)
-
-    if len(glist) > 1:
-        print('New file is:  ' + alllibname)
-
-        if os.path.isfile(startup_script):
-            # If the symbolic link exists, remove it.
-            if os.path.isfile(destlibdir + '/.magicrc'):
-                os.remove(destlibdir + '/.magicrc')
-            os.symlink(startup_script, destlibdir + '/.magicrc')
-
-        # A GDS library is binary and requires handling in Magic
-        print('Creating magic generation script to generate GDS library.') 
-        with open(destlibdir + '/generate_magic.tcl', 'w') as ofile:
-            print('#!/usr/bin/env wish', file=ofile)
-            print('#--------------------------------------------', file=ofile)
-            print('# Script to generate .gds library from files   ', file=ofile)
-            print('#--------------------------------------------', file=ofile)
-            print('drc off', file=ofile)
-            print('gds readonly true', file=ofile)
-            print('gds flatten true', file=ofile)
-            print('gds rescale false', file=ofile)
-            print('tech unlock *', file=ofile)
-
-            for gdsfile in glist:
-                print('gds read ' + gdsfile, file=ofile)
-
-            print('puts stdout "Creating cell ' + destlib + '"', file=ofile)
-            print('load ' + destlib, file=ofile)
-            print('puts stdout "Adding cells to library"', file=ofile)
-            print('box values 0 0 0 0', file=ofile)
-            for gdsfile in glist:
-                gdsroot = os.path.split(gdsfile)[1]
-                gdsname = os.path.splitext(gdsroot)[0]
-                print('getcell ' + gdsname, file=ofile)
-                # Could properly make space for the cell here. . . 
-                print('box move e 200', file=ofile)
-                                
-            print('puts stdout "Writing GDS library ' + destlib + '"', file=ofile)
-            print('gds library', file=ofile)
-            print('gds write ' + destlib, file=ofile)
-            print('puts stdout "Done."', file=ofile)
-            print('quit -noprompt', file=ofile)
-
-        # Run magic to read in the individual GDS files and
-        # write out the consolidated GDS library
-
-        print('Running magic to create GDS library.')
-        sys.stdout.flush()
-
-        mproc = subprocess.run(['magic', '-dnull', '-noconsole',
-			destlibdir + '/generate_magic.tcl'],
-			stdin = subprocess.DEVNULL,
-			stdout = subprocess.PIPE,
-			stderr = subprocess.PIPE, cwd = destlibdir,
-			universal_newlines = True)
-
-        if mproc.stdout:
-            for line in mproc.stdout.splitlines():
-                print(line)
-        if mproc.stderr:
-            print('Error message output from magic:')
-            for line in mproc.stderr.splitlines():
-                print(line)
-        if mproc.returncode != 0:
-            print('ERROR:  Magic exited with status ' + str(mproc.returncode))
-        if do_compile_only == True:
-            print('Compile-only:  Removing individual GDS files')
-            for gfile in glist:
-                if os.path.isfile(gfile):
-                    os.remove(gfile)
-            if newname:
-                if os.path.isfile(newname):
-                    os.remove(newname)
-    else:
-        print('Only one file (' + str(glist) + ');  ignoring "compile" option.')
-
-#----------------------------------------------------------------------------
-# Given a destination directory holding individual SPICE netlists of a number
-# of cells, create a single SPICE library file named <alllibname> and place
-# it in the same directory.  This is done for the option "compile" if specified
-# for the "-spice" install.
-#----------------------------------------------------------------------------
-
-def create_spice_library(destlibdir, destlib, spiext, do_compile_only, do_stub, excludelist):
-
-    fformat = 'CDL' if spiext == '.cdl' else 'SPICE'
-
-    allstubname = destlibdir + '/stub' + spiext
-    alllibname = destlibdir + '/' + destlib + spiext
-    if do_stub:
-        outputname = allstubname
-    else:
-        outputname = alllibname
-
-    print('Diagnostic:  Creating consolidated ' + fformat + ' library ' + outputname)
-
-    if os.path.isfile(outputname):
-        os.remove(outputname)
-
-    if fformat == 'CDL':
-        slist = glob.glob(destlibdir + '/*.cdl')
-    else:
-        # Sadly, there is no consensus on what a SPICE file extension should be.
-        slist = glob.glob(destlibdir + '/*.spc')
-        slist.extend(glob.glob(destlibdir + '/*.spice'))
-        slist.extend(glob.glob(destlibdir + '/*.spi'))
-        slist.extend(glob.glob(destlibdir + '/*.ckt'))
-
-    if alllibname in slist:
-        slist.remove(alllibname)
-
-    if allstubname in slist:
-        slist.remove(allstubname)
-
-    # Create exclude list with glob-style matching using fnmatch
-    if len(slist) > 0:
-        slistnames = list(os.path.split(item)[1] for item in slist)
-        notslist = []
-        for exclude in excludelist:
-            notslist.extend(fnmatch.filter(slistnames, exclude))
-
-        # Apply exclude list
-        if len(notslist) > 0:
-            for file in slist[:]:
-                if os.path.split(file)[1] in notslist:
-                    slist.remove(file)
-
-    if len(slist) > 1:
-        with open(outputname, 'w') as ofile:
-            allsubckts = []
-            for sfile in slist:
-                with open(sfile, 'r') as ifile:
-                    # print('Adding ' + sfile + ' to library.')
-                    stext = ifile.read()
-                    subckts = re.findall(r'\.subckt[ \t]+([^ \t\n]+)', stext, flags=re.IGNORECASE)
-                    sseen = list(item for item in subckts if item in allsubckts)
-                    allsubckts.extend(list(item for item in subckts if item not in allsubckts))
-                    sfilter = remove_redundant_subckts(stext, allsubckts, sseen)
-                    print(sfilter, file=ofile)
-                print('\n******* EOF\n', file=ofile)
-
-        if do_compile_only == True:
-            print('Compile-only:  Removing individual SPICE files')
-            for sfile in slist:
-                if os.path.isfile(sfile):
-                    os.remove(sfile)
-                elif os.path.islink(sfile):
-                    os.unlink(sfile)
-    else:
-        print('Only one file (' + str(slist) + ');  ignoring "compile" option.')
-
-#----------------------------------------------------------------------------
-# Remove redundant subcircuit entries from a SPICE or CDL netlist file.  "sseen"
-# is a list of subcircuit names gleaned from all previously read files using
-# re.findall(). "slist" is a list of subcircuits including those in "ntext".
-# If a subcircuit is defined outside of "ntext", then remove all occurrences in
-# "ntext".  Otherwise, if a subcircuit is defined more than once in "ntext",
-# remove all but one copy.  The reason for doing this is that some netlists will
-# include primitive device definitions used by all the standard cell subcircuits.
-#
-# It may be necessary to remove redundant .include statements and redundant .model
-# and/or .option statements as well.
-#----------------------------------------------------------------------------
-
-def remove_redundant_subckts(ntext, slist, sseen):
-    updated = ntext
-    for subckt in slist:
-        if subckt in sseen:
-            # Remove all occurrences of subckt
-            updated = re.sub(r'\n\.subckt[ \t]+' + subckt + '[ \t\n]+.*\n\.ends[ \t\n]+', '\n', updated, flags=re.IGNORECASE | re.DOTALL)
-
-        else:
-            # Determine the number of times the subcircuit appears in the text
-            n = len(re.findall(r'\n\.subckt[ \t]+' + subckt + '[ \t\n]+.*\n\.ends[ \t\n]+', updated, flags=re.IGNORECASE | re.DOTALL))
-            # Optimization:  Just keep original text if n < 2
-            if n < 2:
-                continue
-
-            # Remove all but one
-            updated = re.sub(r'\n\.subckt[ \t]+' + subckt + '[ \t\n]+.*\n\.ends[ \t\n]+', '\n', n - 1, updated, flags=re.IGNORECASE | re.DOTALL)
-    return updated
-
-#----------------------------------------------------------------------------
 # This is the main entry point for the foundry install script.
 #----------------------------------------------------------------------------
 
