diff --git a/common/soc_floorplanner.py b/common/soc_floorplanner.py
new file mode 100755
index 0000000..959a623
--- /dev/null
+++ b/common/soc_floorplanner.py
@@ -0,0 +1,2619 @@
+#!/usr/bin/env python3
+#
+#--------------------------------------------------------
+# Padframe Editor and Core Floorplanner
+#
+#--------------------------------------------------------
+# Written by Tim Edwards
+# efabless, inc.
+# April 24, 2019
+# Version 0.5
+# Based on https://github.com/YosysHQ/padring (requirement)
+# Update: May 9, 2019 to add console message window
+# Update: May 10, 2019 to incorporate core floorplanning
+# Update: Jan 31, 2020 to allow batch operation
+#--------------------------------------------------------
+
+import os
+import re
+import sys
+import glob
+import json
+import math
+import shutil
+import signal
+import select
+import subprocess
+import faulthandler
+
+import tkinter
+from tkinter import ttk
+from tkinter import filedialog
+import tksimpledialog
+from consoletext import ConsoleText
+
+# User preferences file (if it exists)
+prefsfile = '~/design/.profile/prefs.json'
+
+#------------------------------------------------------
+# Dialog for entering a pad
+#------------------------------------------------------
+
+class PadNameDialog(tksimpledialog.Dialog):
+    def body(self, master, warning=None, seed=None):
+        if warning:
+            ttk.Label(master, text=warning).grid(row = 0, columnspan = 2, sticky = 'wns')
+        ttk.Label(master, text="Enter new group name:").grid(row = 1, column = 0, sticky = 'wns')
+        self.nentry = ttk.Entry(master)
+        self.nentry.grid(row = 1, column = 1, sticky = 'ewns')
+        if seed:
+            self.nentry.insert(0, seed)
+        return self.nentry # initial focus
+
+    def apply(self):
+        return self.nentry.get()
+
+#------------------------------------------------------
+# Dialog for entering core dimensions
+#------------------------------------------------------
+
+class CoreSizeDialog(tksimpledialog.Dialog):
+    def body(self, master, warning="Chip core dimensions", seed=None):
+        if warning:
+            ttk.Label(master, text=warning).grid(row = 0, columnspan = 2, sticky = 'wns')
+        ttk.Label(master, text="Enter core width x height (microns):").grid(row = 1, column = 0, sticky = 'wns')
+        self.nentry = ttk.Entry(master)
+        self.nentry.grid(row = 1, column = 1, sticky = 'ewns')
+
+
+        if seed:
+            self.nentry.insert(0, seed)
+        return self.nentry # initial focus
+
+    def apply(self):
+        return self.nentry.get()
+
+#------------------------------------------------
+# SoC Floorplanner and Padframe Generator GUI
+#------------------------------------------------
+
+class SoCFloorplanner(ttk.Frame):
+    """Open Galaxy Pad Frame Generator."""
+
+    def __init__(self, parent = None, *args, **kwargs):
+        '''See the __init__ for Tkinter.Toplevel.'''
+        ttk.Frame.__init__(self, parent, *args[1:], **kwargs)
+        self.root = parent
+        self.init_data()
+        if args[0] == True:
+            self.do_gui = True
+            self.init_gui()
+        else:
+            self.do_gui = False
+            self.use_console = False
+
+    def on_quit(self):
+        """Exits program."""
+        quit()
+
+    def init_gui(self):
+        """Builds GUI."""
+        global prefsfile
+
+        message = []
+        fontsize = 11
+
+        # Read user preferences file, get default font size from it.
+        prefspath = os.path.expanduser(prefsfile)
+        if os.path.exists(prefspath):
+            with open(prefspath, 'r') as f:
+                self.prefs = json.load(f)
+            if 'fontsize' in self.prefs:
+                fontsize = self.prefs['fontsize']
+        else:
+            self.prefs = {}
+
+        s = ttk.Style()
+
+        available_themes = s.theme_names()
+        s.theme_use(available_themes[0])
+
+        s.configure('normal.TButton', font=('Helvetica', fontsize), border = 3, relief = 'raised')
+        s.configure('title.TLabel', font=('Helvetica', fontsize, 'bold italic'),
+                        foreground = 'brown', anchor = 'center')
+        s.configure('blue.TLabel', font=('Helvetica', fontsize), foreground = 'blue')
+        s.configure('normal.TLabel', font=('Helvetica', fontsize))
+        s.configure('normal.TCheckbutton', font=('Helvetica', fontsize))
+        s.configure('normal.TMenubutton', font=('Helvetica', fontsize))
+        s.configure('normal.TEntry', font=('Helvetica', fontsize), background='white')
+        s.configure('pad.TLabel', font=('Helvetica', fontsize), foreground = 'blue', relief = 'flat')
+        s.configure('select.TLabel', font=('Helvetica', fontsize, 'bold'), foreground = 'white',
+			background = 'blue', relief = 'flat')
+ 
+        # parent.withdraw()
+        self.root.title('Padframe Generator and Core Floorplanner')
+        self.root.option_add('*tearOff', 'FALSE')
+        self.pack(side = 'top', fill = 'both', expand = 'true')
+        self.root.protocol("WM_DELETE_WINDOW", self.on_quit)
+
+        pane = tkinter.PanedWindow(self, orient = 'vertical', sashrelief = 'groove',
+			sashwidth = 6)
+        pane.pack(side = 'top', fill = 'both', expand = 'true')
+
+        self.toppane = ttk.Frame(pane)
+        self.botpane = ttk.Frame(pane)
+
+        self.toppane.columnconfigure(0, weight = 1)
+        self.toppane.rowconfigure(0, weight = 1)
+        self.botpane.columnconfigure(0, weight = 1)
+        self.botpane.rowconfigure(0, weight = 1)
+
+        # Scrolled frame using canvas widget
+        self.pframe = tkinter.Frame(self.toppane)
+        self.pframe.grid(row = 0, column = 0, sticky = 'news')
+        self.pframe.rowconfigure(0, weight = 1)
+        self.pframe.columnconfigure(0, weight = 1)
+
+        # Add column on the left, listing all groups and the pads they belong to.
+        # This starts as just a frame to be filled.  Use a canvas to create a
+        # scrolled frame.
+
+        # The primary frame holds the canvas
+        self.canvas = tkinter.Canvas(self.pframe, background = "white")
+        self.canvas.grid(row = 0, column = 0, sticky = 'news')
+
+        # Add Y scrollbar to pad list window
+        xscrollbar = ttk.Scrollbar(self.pframe, orient = 'horizontal')
+        xscrollbar.grid(row = 1, column = 0, sticky = 'news')
+        yscrollbar = ttk.Scrollbar(self.pframe, orient = 'vertical')
+        yscrollbar.grid(row = 0, column = 1, sticky = 'news')
+
+        self.canvas.config(xscrollcommand = xscrollbar.set)
+        xscrollbar.config(command = self.canvas.xview)
+        self.canvas.config(yscrollcommand = yscrollbar.set)
+        yscrollbar.config(command = self.canvas.yview)
+
+        self.canvas.bind("<Button-4>", self.on_scrollwheel)
+        self.canvas.bind("<Button-5>", self.on_scrollwheel)
+
+        # Configure callback
+        self.canvas.bind("<Configure>", self.frame_configure)
+
+        # Add a text window to capture output.  Redirect print statements to it.
+        self.console = ttk.Frame(self.botpane)
+        self.console.grid(column = 0, row = 0, sticky = "news")
+        self.text_box = ConsoleText(self.console, wrap='word', height = 4)
+        self.text_box.pack(side='left', fill='both', expand='true')
+        console_scrollbar = ttk.Scrollbar(self.console)
+        console_scrollbar.pack(side='right', fill='y')
+        # Attach console to scrollbar
+        self.text_box.config(yscrollcommand = console_scrollbar.set)
+        console_scrollbar.config(command = self.text_box.yview)
+
+        # Add the bottom bar with buttons
+        self.bbar = ttk.Frame(self.botpane)
+        self.bbar.grid(column = 0, row = 1, sticky = "news")
+
+        self.bbar.import_button = ttk.Button(self.bbar, text='Import',
+		command=self.vlogimport, style='normal.TButton')
+        self.bbar.import_button.grid(column=0, row=0, padx = 5)
+
+        self.bbar.generate_button = ttk.Button(self.bbar, text='Generate',
+		command=self.generate, style='normal.TButton')
+        self.bbar.generate_button.grid(column=1, row=0, padx = 5)
+
+        self.bbar.save_button = ttk.Button(self.bbar, text='Save',
+		command=self.save, style='normal.TButton')
+        self.bbar.save_button.grid(column=2, row=0, padx = 5)
+
+        self.bbar.cancel_button = ttk.Button(self.bbar, text='Quit',
+		command=self.on_quit, style='normal.TButton')
+        self.bbar.cancel_button.grid(column=3, row=0, padx = 5)
+
+        pane.add(self.toppane)
+        pane.add(self.botpane)
+        pane.paneconfig(self.toppane, stretch='first')
+
+    def init_data(self):
+
+        self.vlogpads = []
+        self.corecells = []
+        self.Npads = []
+        self.Spads = []
+        self.Epads = []
+        self.Wpads = []
+        self.NEpad = []
+        self.NWpad = []
+        self.SEpad = []
+        self.SWpad = []
+        self.coregroup = []
+
+        self.celldefs = []
+        self.coredefs = []
+        self.selected = []
+        self.ioleflibs = []
+        self.llx = 0
+        self.lly = 0
+        self.urx = 0
+        self.ury = 0
+
+        self.event_data = {}
+        self.event_data['x0'] = 0
+        self.event_data['y0'] = 0
+        self.event_data['x'] = 0
+        self.event_data['y'] = 0
+        self.event_data['tag'] = None
+        self.scale = 1.0
+        self.margin = 10
+        self.pad_rotation = 0
+
+        self.init_messages = []
+        self.stdout = None
+        self.stderr = None
+
+        self.keep_cfg = False
+        self.ef_format = False
+        self.use_console = False
+
+    def init_padframe(self):
+        self.set_project()
+        self.vlogimport()
+        self.readplacement(precheck=True)
+        self.resolve()
+        self.generate(0)
+
+    # Local routines for handling printing to the text console
+
+    def print(self, message, file=None, end='\n', flush=True):
+        if not file:
+            if not self.use_console:
+                file = sys.stdout
+            else:
+                file = ConsoleText.StdoutRedirector(self.text_box)
+        if self.stdout:
+            print(message, file=file, end=end)
+            if flush:
+                self.stdout.flush()
+                self.update_idletasks()
+        else:
+            self.init_messages.append(message)
+
+    def text_to_console(self):
+        # Redirect stdout and stderr to the console as the last thing to do. . .
+        # Otherwise errors in the GUI get sucked into the void.
+
+        self.stdout = sys.stdout
+        self.stderr = sys.stderr
+        if self.use_console:
+            sys.stdout = ConsoleText.StdoutRedirector(self.text_box)
+            sys.stderr = ConsoleText.StderrRedirector(self.text_box)
+
+        if len(self.init_messages) > 0:
+            for message in self.init_messages:
+                self.print(message)
+            self.init_messages = []
+
+    # Set the project name(s).  This is the name of the top-level verilog.
+    # The standard protocol is that the project directory contains a file
+    # project.json that defines a name 'ip-name' that is the same as the
+    # layout name, the verilog module name, etc.  
+
+    def set_project(self):
+        # Check pwd
+        pwdname = self.projectpath if self.projectpath else os.getcwd()
+        
+        subdir = os.path.split(pwdname)[1]
+        if subdir == 'mag' or subdir == 'verilog':
+            projectpath = os.path.split(pwdname)[0]
+        else:
+            projectpath = pwdname
+
+        projectroot = os.path.split(projectpath)[0]
+        projectdirname = os.path.split(projectpath)[1]
+
+        # Check for efabless format.  This is probably more complicated than
+        # it deserves to be.  Option -ef_format is the best way to specify
+        # efabless format.  However, if it is not specified, then check the
+        # technology PDK directory and the project directory for the tell-tale
+        # ".ef-config" (efabless format) directory vs. ".config" (not efabless
+        # format).
+
+        if not self.ef_format:
+            if os.path.exists(projectpath + '/.ef-config'):
+                self.ef_format = True
+            elif self.techpath:
+                if os.path.exists(self.techpath + '/.ef-config'):
+                    self.ef_format = True
+        else:
+            # Do a quick consistency check.  Honor the -ef_format option but warn if
+            # there is an apparent inconsistency.
+            if os.path.exists(projectpath + '/.config'):
+                self.print('Warning:  -ef_format used in apparently non-efabless setup.')
+            elif self.techpath:
+                if os.path.exists(self.techpath + '/.config'):
+                    self.print('Warning:  -ef_format used in apparently non-efabless setup.')
+
+        # Check for project.json
+
+        jsonname = None
+        if os.path.isfile(projectpath + '/project.json'):
+            jsonname = projectpath + '/project.json'
+        elif os.path.isfile(projectroot + '/' + projectdirname + '.json'):
+            jsonname = projectroot + '/' + projectdirname + '.json'
+        if os.path.isfile(projectroot + '/project.json'):
+            # Just in case this was started from some other subdirectory
+            projectpath = projectroot
+            jsonname = projectroot + '/project.json'
+
+        if jsonname:
+            self.print('Reading project JSON file ' + jsonname)
+            with open(jsonname, 'r') as ifile:
+                topdata = json.load(ifile)
+                if 'data-sheet' in topdata:
+                    dsheet = topdata['data-sheet']
+                    if 'ip-name' in dsheet:
+                        self.project = dsheet['ip-name']
+                        self.projectpath = projectpath
+        else:
+            self.print('No project JSON file; using directory name as the project name.')
+            self.project = os.path.split(projectpath)[1]
+            self.projectpath = projectpath
+
+        self.print('Project name is ' + self.project + ' (' + self.projectpath + ')')
+
+    # Functions for drag-and-drop capability
+    def add_draggable(self, tag):
+        self.canvas.tag_bind(tag, '<ButtonPress-1>', self.on_button_press)
+        self.canvas.tag_bind(tag, '<ButtonRelease-1>', self.on_button_release)
+        self.canvas.tag_bind(tag, '<B1-Motion>', self.on_button_motion)
+        self.canvas.tag_bind(tag, '<ButtonPress-2>', self.on_button2_press)
+        self.canvas.tag_bind(tag, '<ButtonPress-3>', self.on_button3_press)
+
+    def on_button_press(self, event):
+        '''Begining drag of an object'''
+        # Find the closest item, then record its tag.
+        locx = event.x + self.canvas.canvasx(0)
+        locy = event.y + self.canvas.canvasy(0)
+        item = self.canvas.find_closest(locx, locy)[0]
+        self.event_data['tag'] = self.canvas.gettags(item)[0]
+        self.event_data['x0'] = event.x
+        self.event_data['y0'] = event.y
+        self.event_data['x'] = event.x
+        self.event_data['y'] = event.y
+
+    def on_button2_press(self, event):
+        '''Flip an object (excluding corners)'''
+        locx = event.x + self.canvas.canvasx(0)
+        locy = event.y + self.canvas.canvasy(0)
+        item = self.canvas.find_closest(locx, locy)[0]
+        tag = self.canvas.gettags(item)[0]
+
+        try:
+            corecell = next(item for item in self.coregroup if item['name'] == tag)
+        except:
+            try:
+                pad = next(item for item in self.Npads if item['name'] == tag)
+            except:
+                pad = None
+            if not pad:
+                try:
+                    pad = next(item for item in self.Epads if item['name'] == tag)
+                except:
+                    pad = None
+            if not pad:
+                try:
+                    pad = next(item for item in self.Spads if item['name'] == tag)
+                except:
+                    pad = None
+            if not pad:
+                try:
+                    pad = next(item for item in self.Wpads if item['name'] == tag)
+                except:
+                    pad = None
+            if not pad:
+                self.print('Error: Object cannot be flipped.')
+            else:
+                # Flip the pad (in the only way meaningful for the pad).
+                orient = pad['o']
+                if orient == 'N':
+                    pad['o'] = 'FN'
+                elif orient == 'E':
+                    pad['o'] = 'FW'
+                elif orient == 'S':
+                    pad['o'] = 'FS'
+                elif orient == 'W':
+                    pad['o'] = 'FE'
+                elif orient == 'FN':
+                    pad['o'] = 'N'
+                elif orient == 'FE':
+                    pad['o'] = 'W'
+                elif orient == 'FS':
+                    pad['o'] = 'S'
+                elif orient == 'FW':
+                    pad['o'] = 'E'
+        else:
+            # Flip the cell.  Use the DEF meaning of flip, which is to
+            # add or subtract 'F' from the orientation.
+            orient = corecell['o']
+            if not 'F' in orient:
+                corecell['o'] = 'F' + orient
+            else:
+                corecell['o'] = orient[1:]
+
+        # Redraw
+        self.populate(0)
+
+    def on_button3_press(self, event):
+        '''Rotate a core object (no pads) '''
+        locx = event.x + self.canvas.canvasx(0)
+        locy = event.y + self.canvas.canvasy(0)
+        item = self.canvas.find_closest(locx, locy)[0]
+        tag = self.canvas.gettags(item)[0]
+
+        try:
+            corecell = next(item for item in self.coregroup if item['name'] == tag)
+        except:
+            self.print('Error: Object cannot be rotated.')
+        else:
+            # Modify its orientation
+            orient = corecell['o']
+            if orient == 'N':
+                corecell['o'] = 'E'
+            elif orient == 'E':
+                corecell['o'] = 'S'
+            elif orient == 'S':
+                corecell['o'] = 'W'
+            elif orient == 'W':
+                corecell['o'] = 'N'
+            elif orient == 'FN':
+                corecell['o'] = 'FW'
+            elif orient == 'FW':
+                corecell['o'] = 'FS'
+            elif orient == 'FS':
+                corecell['o'] = 'FE'
+            elif orient == 'FE':
+                corecell['o'] = 'FN'
+
+            # rewrite the core DEF file
+            self.write_core_def()
+
+        # Redraw
+        self.populate(0)
+
+    def on_button_motion(self, event):
+        '''Handle dragging of an object'''
+        # compute how much the mouse has moved
+        delta_x = event.x - self.event_data['x']
+        delta_y = event.y - self.event_data['y']
+        # move the object the appropriate amount
+        self.canvas.move(self.event_data['tag'], delta_x, delta_y)
+        # record the new position
+        self.event_data['x'] = event.x
+        self.event_data['y'] = event.y
+
+    def on_button_release(self, event):
+        '''End drag of an object'''
+
+        # Find the pad associated with the tag and update its position information
+        tag = self.event_data['tag']
+
+        # Collect pads in clockwise order.  Note that E and S rows are not clockwise
+        allpads = []
+        allpads.extend(self.Npads)
+        allpads.extend(self.NEpad)
+        allpads.extend(reversed(self.Epads))
+        allpads.extend(self.SEpad)
+        allpads.extend(reversed(self.Spads))
+        allpads.extend(self.SWpad)
+        allpads.extend(self.Wpads)
+        allpads.extend(self.NWpad)
+
+        # Create a list of row references (also in clockwise order, but no reversing)
+        padrows = [self.Npads, self.NEpad, self.Epads, self.SEpad, self.Spads, self.SWpad, self.Wpads, self.NWpad]
+
+        # Record the row or corner where this pad was located before the move
+        for row in padrows:
+            try:
+                pad = next(item for item in row if item['name'] == tag)
+            except:
+                pass
+            else:
+                padrow = row
+                break
+
+        # Currently there is no procedure to move a pad out of the corner
+        # position;  corners are fixed by definition.
+        if padrow == self.NEpad or padrow == self.SEpad or padrow == self.SWpad or padrow == self.NWpad:
+            # Easier to run generate() than to put the pad back. . .
+            self.generate(0)
+            return
+
+        # Find the original center point of the pad being moved
+
+        padllx = pad['x']
+        padlly = pad['y']
+        if pad['o'] == 'N' or pad['o'] == 'S':
+            padurx = padllx + pad['width']
+            padury = padlly + pad['height']
+        else:
+            padurx = padllx + pad['height']
+            padury = padlly + pad['width']
+        padcx = (padllx + padurx) / 2
+        padcy = (padlly + padury) / 2
+
+        # Add distance from drag information (note that drag position in y
+        # is negative relative to the chip dimensions)
+        padcx += (self.event_data['x'] - self.event_data['x0']) / self.scale
+        padcy -= (self.event_data['y'] - self.event_data['y0']) / self.scale
+
+        # reset the drag information
+        self.event_data['tag'] = None
+        self.event_data['x'] = 0
+        self.event_data['y'] = 0
+        self.event_data['x0'] = 0
+        self.event_data['y0'] = 0
+
+        # Find the distance from the pad to all other pads, and get the two
+        # closest entries.
+
+        wwidth = self.urx - self.llx
+        dist0 = wwidth
+        dist1 = wwidth
+        pad0 = None
+        pad1 = None
+          
+        for npad in allpads:
+            if npad == pad:
+                continue
+
+            npadllx = npad['x']
+            npadlly = npad['y']
+            if npad['o'] == 'N' or npad['o'] == 'S':
+                npadurx = npadllx + npad['width']
+                npadury = npadlly + npad['height']
+            else:
+                npadurx = npadllx + npad['height']
+                npadury = npadlly + npad['width']
+            npadcx = (npadllx + npadurx) / 2
+            npadcy = (npadlly + npadury) / 2
+
+            deltx = npadcx - padcx
+            delty = npadcy - padcy
+            pdist = math.sqrt(deltx * deltx + delty * delty)
+            if pdist < dist0:
+                dist1 = dist0
+                pad1 = pad0
+                dist0 = pdist
+                pad0 = npad
+
+            elif pdist < dist1:
+                dist1 = pdist
+                pad1 = npad
+
+        # Diagnostic
+        # self.print('Two closest pads to pad ' + pad['name'] + ' (' + pad['cell'] + '): ')
+        # self.print(pad0['name'] + ' (' + pad0['cell'] + ') dist = ' + str(dist0))
+        # self.print(pad1['name'] + ' (' + pad1['cell'] + ') dist = ' + str(dist1))
+
+        # Record the row or corner where these pads are
+        for row in padrows:
+            try:
+                testpad = next(item for item in row if item['name'] == pad0['name'])
+            except:
+                pass
+            else:
+                padrow0 = row
+                break
+
+        for row in padrows:
+            try:
+                testpad = next(item for item in row if item['name'] == pad1['name'])
+            except:
+                pass
+            else:
+                padrow1 = row
+                break
+
+        # Remove pad from its own row
+        padrow.remove(pad)
+
+        # Insert pad into new row.  Watch for wraparound from the last entry to the first
+        padidx0 = allpads.index(pad0)
+        padidx1 = allpads.index(pad1)
+        if padidx0 == 0 and padidx1 > 2:
+            padidx1 = -1
+
+        if padidx1 > padidx0:
+            padafter = pad1
+            rowafter = padrow1
+            padbefore = pad0
+            rowbefore = padrow0
+        else:
+            padafter = pad0
+            rowafter = padrow0
+            padbefore = pad1
+            rowbefore = padrow1
+
+        # Do not replace corner positions (? may be necessary ?)
+        if rowafter == self.NWpad:
+            self.Wpads.append(pad)
+        elif rowafter == self.NWpad:
+            self.Npads.append(pad)
+        elif rowafter == self.SEpad:
+            self.Epads.insert(0, pad)
+        elif rowafter == self.SWpad:
+            self.Spads.insert(0, pad)
+        elif rowafter == self.Wpads or rowafter == self.Npads:
+            idx = rowafter.index(padafter)
+            rowafter.insert(idx, pad)
+        elif rowbefore == self.NEpad:
+            self.Epads.append(pad)
+        elif rowbefore == self.SEpad:
+            self.Spads.append(pad)
+        else:
+            # rows E and S are ordered counterclockwise
+            idx = rowbefore.index(padbefore)
+            rowbefore.insert(idx, pad)
+
+        # Re-run padring
+        self.generate(0)
+
+    def on_scrollwheel(self, event):
+        if event.num == 4:
+            zoomval = 1.1;
+        elif event.num == 5:
+            zoomval = 0.9;
+        else:
+            zoomval = 1.0;
+
+        self.scale *= zoomval
+        self.canvas.scale('all', -15 * zoomval, -15 * zoomval, zoomval, zoomval)
+        self.event_data['x'] *= zoomval
+        self.event_data['y'] *= zoomval
+        self.event_data['x0'] *= zoomval
+        self.event_data['y0'] *= zoomval
+        self.frame_configure(event)
+
+    # Callback functions similar to the pad event callbacks above, but for
+    # core cells.  Unlike pad cells, core cells can be rotated and flipped
+    # arbitrarily, and they do not force a recomputation of the padframe
+    # unless their position forces the padframe to expand
+
+    def add_core_draggable(self, tag):
+        self.canvas.tag_bind(tag, '<ButtonPress-1>', self.on_button_press)
+        self.canvas.tag_bind(tag, '<ButtonRelease-1>', self.core_on_button_release)
+        self.canvas.tag_bind(tag, '<B1-Motion>', self.on_button_motion)
+        self.canvas.tag_bind(tag, '<ButtonPress-2>', self.on_button2_press)
+        self.canvas.tag_bind(tag, '<ButtonPress-3>', self.on_button3_press)
+
+    def core_on_button_release(self, event):
+        '''End drag of a core cell'''
+
+        # Find the pad associated with the tag and update its position information
+        tag = self.event_data['tag']
+
+        try:
+            corecell = next(item for item in self.coregroup if item['name'] == tag)
+        except:
+            self.print('Error: cell ' + item['name'] + ' is not in coregroup!')
+        else:  
+            # Modify its position values
+            corex = corecell['x']
+            corey = corecell['y']
+
+            # Add distance from drag information (note that drag position in y
+            # is negative relative to the chip dimensions)
+            deltax = (self.event_data['x'] - self.event_data['x0']) / self.scale
+            deltay = (self.event_data['y'] - self.event_data['y0']) / self.scale
+
+            corecell['x'] = corex + deltax
+            corecell['y'] = corey - deltay
+
+            # rewrite the core DEF file
+            self.write_core_def()
+
+        # reset the drag information
+        self.event_data['tag'] = None
+        self.event_data['x'] = 0
+        self.event_data['y'] = 0
+        self.event_data['x0'] = 0
+        self.event_data['y0'] = 0
+
+    # Critically needed or else frame does not resize to scrollbars!
+    def grid_configure(self, padx, pady):
+        pass
+
+    # Redraw the chip frame view in response to changes in the pad list
+    def redraw_frame(self):
+        self.canvas.coords('boundary', self.llx, self.urx, self.lly, self.ury)
+   
+    # Update the canvas scrollregion to incorporate all the interior windows
+    def frame_configure(self, event):
+        if self.do_gui == False:
+            return
+        self.update_idletasks()
+        bbox = self.canvas.bbox("all")
+        try:
+            newbbox = (-15, -15, bbox[2] + 15, bbox[3] + 15)
+        except:
+            pass
+        else:
+            self.canvas.configure(scrollregion = newbbox)
+
+    # Fill the GUI entries with resident data
+    def populate(self, level):
+        if self.do_gui == False:
+            return
+
+        if level > 1:
+            self.print('Recursion error:  Returning now.')
+            return
+
+        self.print('Populating floorplan view.')
+
+        # Remove all entries from the canvas
+        self.canvas.delete('all')
+
+        allpads = self.Npads + self.NEpad + self.Epads + self.SEpad + self.Spads + self.SWpad + self.Wpads + self.NWpad
+
+        notfoundlist = []
+
+        for pad in allpads:
+            if 'x' not in pad:
+                self.print('Error:  Pad ' + pad['name'] + ' has no placement information.')
+                continue
+            llx = int(pad['x'])
+            lly = int(pad['y'])
+            pado = pad['o']
+            try:
+                padcell = next(item for item in self.celldefs if item['name'] == pad['cell'])
+            except:
+                # This should not happen (failsafe)
+                if pad['cell'] not in notfoundlist:
+                    self.print('Warning:  there is no cell named ' + pad['cell'] + ' in the libraries.')
+                notfoundlist.append(pad['cell'])
+                continue
+            padw = padcell['width']
+            padh = padcell['height']
+            if 'N' in pado or 'S' in pado:
+                urx = int(llx + padw)
+                ury = int(lly + padh)
+            else:
+                urx = int(llx + padh)
+                ury = int(lly + padw)
+            
+            pad['llx'] = llx
+            pad['lly'] = lly
+            pad['urx'] = urx
+            pad['ury'] = ury
+
+        # Note that the DEF coordinate system is reversed in Y from the canvas. . .
+
+        height = self.ury - self.lly
+        for pad in allpads:
+
+            llx = pad['llx']
+            lly = height - pad['lly']
+            urx = pad['urx']
+            ury = height - pad['ury']
+
+            tag_id = pad['name']
+            if 'subclass' in pad:
+                if pad['subclass'] == 'POWER':
+                    pad_color = 'orange2'
+                elif pad['subclass'] == 'INOUT':
+                    pad_color = 'yellow'
+                elif pad['subclass'] == 'OUTPUT':
+                    pad_color = 'powder blue'
+                elif pad['subclass'] == 'INPUT':
+                    pad_color = 'goldenrod1'
+                elif pad['subclass'] == 'SPACER':
+                    pad_color = 'green yellow'
+                elif pad['class'] == 'ENDCAP':
+                    pad_color = 'green yellow'
+                elif pad['subclass'] == '' or pad['class'] == ';':
+                    pad_color = 'khaki1'
+                else:
+                    self.print('Unhandled pad class ' + pad['class'])
+                    pad_color = 'gray'
+            else:
+                 pad_color = 'gray'
+
+            sllx = self.scale * llx
+            slly = self.scale * lly
+            surx = self.scale * urx
+            sury = self.scale * ury
+
+            self.canvas.create_rectangle((sllx, slly), (surx, sury), fill=pad_color, tags=[tag_id])
+            cx = (sllx + surx) / 2
+            cy = (slly + sury) / 2
+
+            s = 10 if pad['width'] >= 10 else pad['width']
+            if pad['height'] < s:
+                s = pad['height']
+
+            # Create an indicator line at the bottom left corner of the cell
+            if pad['o'] == 'N':
+                allx = sllx
+                ally = slly - s
+                aurx = sllx + s
+                aury = slly
+            elif pad['o'] == 'E':
+                allx = sllx
+                ally = sury + s
+                aurx = sllx + s
+                aury = sury
+            elif pad['o'] == 'S':
+                allx = surx
+                ally = sury + s
+                aurx = surx - s
+                aury = sury
+            elif pad['o'] == 'W':
+                allx = surx
+                ally = slly - s
+                aurx = surx - s
+                aury = slly
+            elif pad['o'] == 'FN':
+                allx = surx
+                ally = slly - s
+                aurx = surx - s
+                aury = slly
+            elif pad['o'] == 'FE':
+                allx = surx
+                ally = sury + s
+                aurx = surx - s
+                aury = sury
+            elif pad['o'] == 'FS':
+                allx = sllx
+                ally = sury + s
+                aurx = sllx + s
+                aury = sury
+            elif pad['o'] == 'FW':
+                allx = sllx
+                ally = slly - s
+                aurx = sllx + s
+                aury = slly
+            self.canvas.create_line((allx, ally), (aurx, aury), tags=[tag_id])
+ 
+            # Rotate text on top and bottom rows if the tkinter version allows it.
+            if tkinter.TclVersion >= 8.6:
+                if pad['o'] == 'N' or pad['o'] == 'S':
+                    angle = 90
+                else:
+                    angle = 0
+                self.canvas.create_text((cx, cy), text=pad['name'], angle=angle, tags=[tag_id])
+            else:
+                self.canvas.create_text((cx, cy), text=pad['name'], tags=[tag_id])
+
+            # Make the pad draggable
+            self.add_draggable(tag_id)
+
+        # Now add the core cells
+        for cell in self.coregroup:
+            if 'x' not in cell:
+                self.print('Error:  Core cell ' + cell['name'] + ' has no placement information.')
+                continue
+            # else:
+            #     self.print('Diagnostic:  Creating object for core cell ' + cell['name'])
+            llx = int(cell['x'])
+            lly = int(cell['y'])
+            cello = cell['o']
+            try:
+                corecell = next(item for item in self.coredefs if item['name'] == cell['cell'])
+            except:
+                # This should not happen (failsafe)
+                if cell['cell'] not in notfoundlist:
+                    self.print('Warning:  there is no cell named ' + cell['cell'] + ' in the libraries.')
+                notfoundlist.append(cell['cell'])
+                continue
+            cellw = corecell['width']
+            cellh = corecell['height']
+            if 'N' in cello or 'S' in cello:
+                urx = int(llx + cellw)
+                ury = int(lly + cellh)
+            else:
+                urx = int(llx + cellh)
+                ury = int(lly + cellw)
+                print('NOTE: cell ' + corecell['name'] + ' is rotated, w = ' + str(urx - llx) + '; h = ' + str(ury - lly))
+
+            cell['llx'] = llx
+            cell['lly'] = lly
+            cell['urx'] = urx
+            cell['ury'] = ury
+
+        # Watch for out-of-window position in core cells.
+        corellx = self.llx
+        corelly = self.lly
+        coreurx = self.urx
+        coreury = self.ury
+
+        for cell in self.coregroup:
+
+            if 'llx' not in cell:
+                # Error message for this was handled above
+                continue
+
+            llx = cell['llx']
+            lly = height - cell['lly']
+            urx = cell['urx']
+            ury = height - cell['ury']
+
+            # Check for out-of-window cell
+            if llx < corellx:
+                corellx = llx
+            if lly < corelly:
+                corelly = lly
+            if urx > coreurx:
+                coreurx = urx
+            if ury > coreury:
+                coreury = ury
+
+            tag_id = cell['name']
+            cell_color = 'gray40'
+
+            sllx = self.scale * llx
+            slly = self.scale * lly
+            surx = self.scale * urx
+            sury = self.scale * ury
+
+            self.canvas.create_rectangle((sllx, slly), (surx, sury), fill=cell_color, tags=[tag_id])
+            cx = (sllx + surx) / 2
+            cy = (slly + sury) / 2
+
+            s = 10 if cell['width'] >= 10 else cell['width']
+            if cell['height'] < s:
+                s = cell['height']
+
+            # Create an indicator line at the bottom left corner of the cell
+            if cell['o'] == 'N':
+                allx = sllx
+                ally = slly - s
+                aurx = sllx + s
+                aury = slly
+            elif cell['o'] == 'E':
+                allx = sllx
+                ally = sury + s
+                aurx = sllx + s
+                aury = sury
+            elif cell['o'] == 'S':
+                allx = surx
+                ally = sury + s
+                aurx = surx - s
+                aury = sury
+            elif cell['o'] == 'W':
+                allx = surx
+                ally = slly - s
+                aurx = surx - s
+                aury = slly
+            elif cell['o'] == 'FN':
+                allx = surx
+                ally = slly - s
+                aurx = surx - s
+                aury = slly
+            elif cell['o'] == 'FE':
+                allx = surx
+                ally = sury + s
+                aurx = surx - s
+                aury = sury
+            elif cell['o'] == 'FS':
+                allx = sllx
+                ally = sury + s
+                aurx = sllx + s
+                aury = sury
+            elif cell['o'] == 'FW':
+                allx = sllx
+                ally = slly - s
+                aurx = sllx + s
+                aury = slly
+            self.canvas.create_line((allx, ally), (aurx, aury), tags=[tag_id])
+ 
+            # self.print('Created entry for cell ' + cell['name'] + ' at {0:g}, {1:g}'.format(cx, cy))
+ 
+            # Rotate text on top and bottom rows if the tkinter version allows it.
+            if tkinter.TclVersion >= 8.6:
+                if 'N' in cell['o'] or 'S' in cell['o']:
+                    angle = 90
+                else:
+                    angle = 0
+                self.canvas.create_text((cx, cy), text=cell['name'], angle=angle, tags=[tag_id])
+            else:
+                self.canvas.create_text((cx, cy), text=cell['name'], tags=[tag_id])
+
+            # Make the core cell draggable
+            self.add_core_draggable(tag_id)
+
+        # Is there a boundary size defined?
+        if self.urx > self.llx and self.ury > self.lly:
+            self.create_boundary()
+
+        # Did the core extend into negative X or Y?  If so, adjust all canvas
+        # coordinates to fit in the window, or else objects cannot be reached
+        # even by zooming out (since zooming is pinned on the top corner).
+
+        offsetx = 0
+        offsety = 0
+
+        # NOTE:  Probably want to check if the core exceeds the inner
+        # dimension of the pad ring, not the outer (to check and to do).
+
+        if corellx < self.llx:
+            offsetx = self.llx - corellx 
+        if corelly < self.lly:
+            offsety = self.lly - corelly
+        if offsetx > 0 or offsety > 0:
+            self.canvas.move("all", offsetx, offsety)
+            # An offset implies that the chip is core limited, and the
+            # padframe requires additional space.  This can be accomplished
+            # simply by running "Generate".  NOTE:  Since generate() calls
+            # populate(), be VERY SURE that this does not infinitely recurse!
+            self.generate(level)
+
+    # Generate a DEF file of the core area
+
+    def write_core_def(self):
+        self.print('Writing core placementment information in DEF file "core.def".')
+
+        mag_path = self.projectpath + '/mag'
+
+        # The core cells must always clear the I/O pads on the left and
+        # bottom (with the ad-hoc margin of self.margin).  If core cells have
+        # been moved to the left or down past the padframe edge, then the
+        # entire core needs to be repositioned.
+
+        # To be done:  draw a boundary around the core, let the edges of that
+        # boundary be draggable, and let the difference between the boundary
+        # and the core area define the margin.
+
+        if self.SWpad != []:
+            corellx = self.SWpad[0]['x'] + self.SWpad[0]['width'] + self.margin
+            corelly = self.SWpad[0]['y'] + self.SWpad[0]['height'] + self.margin
+        else:
+            corellx = self.Wpads[0]['x'] + self.Wpads[0]['height'] + self.margin
+            corelly = self.Spads[0]['x'] + self.Spads[0]['height'] + self.margin
+
+        offsetx = 0
+        offsety = 0
+        for corecell in self.coregroup:
+            if corecell['x'] < corellx:
+                if corellx - corecell['x'] > offsetx:
+                    offsetx = corellx - corecell['x']
+            if corecell['y'] < corelly:
+                if corelly - corecell['y'] > offsety:
+                    offsety = corelly - corecell['y']
+        if offsetx > 0 or offsety > 0:
+            for corecell in self.coregroup:
+                corecell['x'] += offsetx
+                corecell['y'] += offsety
+
+        # Now write the core DEF file
+
+        with open(mag_path + '/core.def', 'w') as ofile:
+            print('DESIGN CORE ;', file=ofile)
+            print('UNITS DISTANCE MICRONS 1000 ;', file=ofile)
+            print('COMPONENTS {0:d} ;'.format(len(self.coregroup)), file=ofile)
+            for corecell in self.coregroup:
+                print('  - ' + corecell['name'] + ' ' + corecell['cell'], file=ofile)
+                print('    + PLACED ( {0:d} {1:d} ) {2:s} ;'.format(int(corecell['x'] * 1000), int(corecell['y'] * 1000), corecell['o']), file=ofile)
+            print ('END COMPONENTS', file=ofile)
+            print ('END DESIGN', file=ofile)
+
+    # Create the chip boundary area
+
+    def create_boundary(self):
+        scale = self.scale
+        llx = (self.llx - 10) * scale
+        lly = (self.lly - 10) * scale
+        urx = (self.urx + 10) * scale
+        ury = (self.ury + 10) * scale
+
+        pad_color = 'plum1'
+        tag_id = 'boundary'
+        self.canvas.create_rectangle((llx, lly), (urx, ury), outline=pad_color, width=2, tags=[tag_id])
+        # Add text to the middle representing the chip and core areas
+        cx = ((self.llx + self.urx) / 2) * scale
+        cy = ((self.lly + self.ury) / 2) * scale
+        width = self.urx - self.llx
+        height = self.ury - self.lly
+        areatext = 'Chip dimensions (um): {0:g} x {1:g}'.format(width, height)
+        tag_id = 'chiparea' 
+        self.canvas.create_text((cx, cy), text=areatext, tags=[tag_id])
+
+    # Rotate orientation according to self.pad_rotation. 
+
+    def rotate_orientation(self, orient_in):
+        orient_v = ['N', 'E', 'S', 'W', 'N', 'E', 'S', 'W']
+        idxadd = int(self.pad_rotation / 90)
+        idx = orient_v.index(orient_in)
+        return orient_v[idx + idxadd]
+
+    # Read a list of cell macros (name, size, class) from a LEF library
+
+    def read_lef_macros(self, libpath, libname = None, libtype = 'iolib'):
+        if libtype == 'iolib':
+            libtext = 'I/O '
+        elif libtype == 'celllib':
+            libtext = 'core '
+        else:
+            libtext = ''
+
+        macros = []
+
+        if libname:
+            if os.path.splitext(libname)[1] == '':
+                libname += '.lef'
+            leffiles = glob.glob(libpath + '/' + libname)
+        else:
+            leffiles = glob.glob(libpath + '/*.lef')
+        if leffiles == []:
+            if libname:
+                self.print('WARNING:  No file ' + libpath + '/' + libname + '.lef')
+            else:
+                self.print('WARNING:  No files ' + libpath + '/*.lef')
+        for leffile in leffiles:
+            libpath = os.path.split(leffile)[0]
+            libname = os.path.split(libpath)[1]
+            self.print('Reading LEF ' + libtext + 'library ' + leffile)
+            with open(leffile, 'r') as ifile:
+                ilines = ifile.read().splitlines()
+                in_macro = False
+                for iline in ilines:
+                    iparse = iline.split()
+                    if iparse == []:
+                        continue
+                    elif iparse[0] == 'MACRO':
+                        in_macro = True
+                        newmacro = {}
+                        newmacro['name'] = iparse[1]
+                        newmacro[libtype] = leffile
+                        macros.append(newmacro)
+                    elif in_macro:
+                        if iparse[0] == 'END':
+                            if len(iparse) > 1 and iparse[1] == newmacro['name']:
+                                in_macro = False
+                        elif iparse[0] == 'CLASS':
+                            newmacro['class'] = iparse[1]
+                            if len(iparse) > 2:
+                                newmacro['subclass'] = iparse[2]
+
+                                # Use the 'ENDCAP' class to identify pad rotations
+                                # other than BOTTOMLEFT.  This is somewhat ad-hoc
+                                # depending on the foundry;  may not be generally
+                                # applicable.
+
+                                if newmacro['class'] == 'ENDCAP':
+                                    if newmacro['subclass'] == 'TOPLEFT':
+                                        self.pad_rotation = 90
+                                    elif newmacro['subclass'] == 'TOPRIGHT':
+                                        self.pad_rotation = 180
+                                    elif newmacro['subclass'] == 'BOTTOMRIGHT':
+                                        self.pad_rotation = 270
+                            else:
+                                newmacro['subclass'] = None
+                        elif iparse[0] == 'SIZE':
+                            newmacro['width'] = float(iparse[1])
+                            newmacro['height'] = float(iparse[3])
+                        elif iparse[0] == 'ORIGIN':
+                            newmacro['x'] = float(iparse[1])
+                            newmacro['y'] = float(iparse[2])
+        return macros
+          
+    # Read a list of cell names from a verilog file
+    # If filename is relative, then check in the same directory as the verilog
+    # top-level netlist (vlogpath) and in the subdirectory 'source/' of the top-
+    # level directory.  Also check in the ~/design/ip/ directory.  These are
+    # common include paths for the simulation.
+
+    def read_verilog_lib(self, incpath, vlogpath):
+        iocells = []
+        if not os.path.isfile(incpath) and incpath[0] != '/':
+            locincpath = vlogpath + '/' + incpath
+            if not os.path.isfile(locincpath):
+                locincpath = vlogpath + '/source/' + incpath
+            if not os.path.isfile(locincpath):
+                projectpath = os.path.split(vlogpath)[0]
+                designpath = os.path.split(projectpath)[0]
+                locincpath = designpath + '/ip/' + incpath
+        else:
+            locincpath = incpath
+
+        if not os.path.isfile(locincpath):
+            self.print('File ' + incpath + ' not found (at ' + locincpath + ')!')
+        else:
+            self.print('Reading verilog library ' + locincpath)
+            with open(locincpath, 'r') as ifile:
+                ilines = ifile.read().splitlines()
+                for iline in ilines:
+                    iparse = re.split('[\t ()]', iline)
+                    while '' in iparse:
+                        iparse.remove('')
+                    if iparse == []:
+                        continue
+                    elif iparse[0] == 'module':
+                        iocells.append(iparse[1])
+        return iocells
+
+    # Generate a LEF abstract view from a magic layout.  If "outpath" is not
+    # "None", then write output to outputpath (this is required if the input
+    # file is in a read-only directory).
+
+    def write_lef_file(self, magfile, outpath=None):
+        mag_path = os.path.split(magfile)[0]
+        magfullname = os.path.split(magfile)[1]
+        module = os.path.splitext(magfullname)[0]
+
+        if outpath:
+            write_path = outpath
+        else:
+            write_path = mag_path
+
+        self.print('Generating LEF view from layout for module ' + module)
+
+        with open(write_path + '/pfg_write_lef.tcl', 'w') as ofile:
+            print('drc off', file=ofile)
+            print('box 0 0 0 0', file=ofile)
+            # NOTE:  Using "-force" option in case an IP with a different but
+            # compatible tech is used (e.g., EFHX035A IP inside EFXH035C).  This
+            # is not checked for legality!
+            if outpath:
+                print('load ' + magfile + ' -force', file=ofile)
+            else:
+                print('load ' + module + ' -force', file=ofile)
+            print('lef write -hide', file=ofile)
+            print('quit', file=ofile)
+
+        magicexec = self.magic_path if self.magic_path else 'magic'
+        mproc = subprocess.Popen([magicexec, '-dnull', '-noconsole',
+			'pfg_write_lef.tcl'],
+			stdin = subprocess.PIPE, stdout = subprocess.PIPE,
+			stderr = subprocess.PIPE, cwd = write_path, universal_newlines = True)
+
+        self.watch(mproc)
+        os.remove(write_path + '/pfg_write_lef.tcl')
+
+    # Watch a running process, polling for output and updating the GUI message
+    # window as output arrives.  Return only when the process has exited.
+    # Note that this process cannot handle stdin(), so any input to the process
+    # must be passed from a file.
+
+    def watch(self, process):
+        if process == None:
+            return
+
+        while True:
+            status = process.poll()
+            if status != None:
+                try:
+                    outputpair = process.communicate(timeout=1)
+                except ValueError:
+                    self.print("Process forced stop, status " + str(status))
+                else:
+                    for line in outputpair[0].splitlines():
+                        self.print(line)
+                    for line in outputpair[1].splitlines():
+                        self.print(line, file=sys.stderr)
+                break
+            else:
+                sresult = select.select([process.stdout, process.stderr], [], [], 0)[0]
+                if process.stdout in sresult:
+                    outputline = process.stdout.readline().strip()
+                    self.print(outputline)
+                elif process.stderr in sresult:
+                    outputline = process.stderr.readline().strip()
+                    self.print(outputline, file=sys.stderr)
+                else:
+                    self.update_idletasks()
+
+    # Reimport the pad list by reading the top-level verilog netlist.  Determine
+    # what pads are listed in the file, and check against the existing pad list.
+
+    # The verilog/ directory should have a .v file containing a module of the
+    # same name as self.project (ip-name).  The .v filename should have the
+    # same name as well (but not necessarily).  To do:  Handle import of
+    # projects having a top-level schematic instead of a verilog netlist.
+
+    def vlogimport(self):
+
+        if self.ef_format:
+            config_dir = '/.ef-config'
+        else:
+            config_dir = '/.config'
+
+        # First find the process PDK name for this project.  Read the nodeinfo.json
+        # file and find the list of I/O cell libraries.  
+
+        if self.techpath:
+            pdkpath = self.techpath
+        elif os.path.islink(self.projectpath + config_dir + '/techdir'):
+            pdkpath = os.path.realpath(self.projectpath + config_dir + '/techdir')
+        else:
+            self.print('Error:  Cannot determine path to PDK.  Try using option -tech-path=')
+            return
+
+        self.print('Importing verilog sources.')
+
+        nodeinfopath = pdkpath + config_dir + '/nodeinfo.json'
+        ioleflist = []
+        if os.path.exists(nodeinfopath):
+            self.print('Reading known I/O cell libraries from ' + nodeinfopath)
+            with open(nodeinfopath, 'r') as ifile:
+                itop = json.load(ifile)
+                if 'iocells' in itop:
+                    ioleflist = []
+                    for iolib in itop['iocells']:
+                        if '/' in iolib:
+                            # Entries <lib>/<cell> refer to specific files
+                            if self.ef_format:
+                                iolibpath = pdkpath + '/libs.ref/lef/' + iolib
+                            else:
+                                iolibpath = pdkpath + '/libs.ref/' + iolib
+                            if os.path.splitext(iolib)[1] == '':
+                                if not os.path.exists(iolibpath):
+                                    iolibpath = iolibpath + '.lib'
+                            if not os.path.exists(iolibpath):
+                                self.print('Warning: nodeinfo.json bad I/O library path ' + iolibpath)
+                            ioleflist.append(iolibpath)
+                        else:
+                            # All other entries refer to everything in the directory.
+                            if self.ef_format:
+                                iolibpath = pdkpath + '/libs.ref/lef/' + iolib
+                            else:
+                                iolibpath = pdkpath + '/libs.ref/' + iolib + '/lef/'
+                            iolibfiles = glob.glob(iolibpath + '/*.lef')
+                            if len(iolibfiles) == 0:
+                                self.print('Warning: nodeinfo.json bad I/O library path ' + iolibpath)
+                            ioleflist.extend(iolibfiles)
+        else:
+            # Diagnostic
+            self.print('Cannot read PDK information file ' + nodeinfopath)
+
+        # Fallback behavior:  List everything in libs.ref/lef/ beginning with "IO"
+        if len(ioleflist) == 0:
+            if self.ef_format:
+                ioleflist = glob.glob(pdkpath + '/libs.ref/lef/IO*/*.lef')
+            else:
+                ioleflist = glob.glob(pdkpath + '/libs.ref/IO*/lef/*.lef')
+
+        if len(ioleflist) == 0:
+            self.print('Cannot find any I/O cell libraries for this technology')
+            return
+
+        # Read the LEF libraries to get a list of all available cells.  Keep
+        # this list of cells in "celldefs".
+
+        celldefs = []
+        ioliblist = []
+        ioleflibs = []
+        for iolib in ioleflist:
+            iolibpath = os.path.split(iolib)[0]
+            iolibfile = os.path.split(iolib)[1]
+            ioliblist.append(os.path.split(iolibpath)[1])
+            celldefs.extend(self.read_lef_macros(iolibpath, iolibfile, 'iolib'))
+
+        verilogcells = []
+        newpadlist = []
+        coredefs = []
+        corecells = []
+        corecelllist = []
+        lefprocessed = []
+
+        busrex = re.compile('.*\[[ \t]*([0-9]+)[ \t]*:[ \t]*([0-9]+)[ \t]*\]')
+
+        vlogpath = self.projectpath + '/verilog'
+        vlogfile = vlogpath + '/' + self.project + '.v'
+
+        # Verilog netlists are too difficult to parse from a simple script.
+        # Use qflow tools to convert to SPICE, if they are available.  Parse
+        # the verilog only for "include" statements to find the origin of
+        # the various IP blocks, and then parse the SPICE file to get the
+        # full list of instances.
+        #
+        # (to be done)
+
+        if os.path.isfile(vlogfile):
+            with open(vlogfile, 'r') as ifile:
+                vloglines = ifile.read().splitlines()
+                for vlogline in vloglines:
+                    vlogparse = re.split('[\t ()]', vlogline)
+                    while '' in vlogparse:
+                        vlogparse.remove('')
+                    if vlogparse == []:
+                        continue
+                    elif vlogparse[0] == '//':
+                        continue
+                    elif vlogparse[0] == '`include':
+                        incpath = vlogparse[1].strip('"')
+                        libpath = os.path.split(incpath)[0]
+                        libname = os.path.split(libpath)[1]
+                        libfile = os.path.split(incpath)[1]
+
+                        # Read the verilog library for module names to match
+                        # against macro names in celldefs.
+                        modulelist = self.read_verilog_lib(incpath, vlogpath)
+                        matching = list(item for item in celldefs if item['name'] in modulelist)
+                        for imatch in matching:
+                            verilogcells.append(imatch['name'])
+                            leffile = imatch['iolib']
+                            if leffile not in ioleflibs:
+                                ioleflibs.append(leffile)
+
+                        # Read a corresponding LEF file entry for non-I/O macros, if one
+                        # can be found (this handles files in the PDK).
+                        if len(matching) == 0:
+                            if libname != '':
+                                # (NOTE:  Assumes full path starting with '/')
+                                lefpath = libpath.replace('verilog', 'lef')
+                                lefname = libfile.replace('.v', '.lef')
+                                if not os.path.exists(lefpath + '/' + lefname):
+                                    leffiles = glob.glob(lefpath + '/*.lef')
+                                else:
+                                    leffiles = [lefpath + '/' + lefname]
+
+                                for leffile in leffiles:
+                                    if leffile in ioleflibs:
+                                        continue
+                                    elif leffile in lefprocessed:
+                                        continue
+                                    else:
+                                        lefprocessed.append(leffile)
+
+                                    lefname = os.path.split(leffile)[1]
+
+                                    newcoredefs = self.read_lef_macros(lefpath, lefname, 'celllib')
+                                    coredefs.extend(newcoredefs)
+                                    corecells.extend(list(item['name'] for item in newcoredefs))
+
+                                if leffiles == []:
+                                    maglefname = libfile.replace('.v', '.mag')
+
+                                    # Handle PDK files with a maglef/ view but no LEF file.
+                                    maglefpath = libpath.replace('verilog', 'maglef')
+                                    if not os.path.exists(maglefpath + '/' + maglefname):
+                                        magleffiles = glob.glob(maglefpath + '/*.mag')
+                                    else:
+                                        magleffiles = [maglefpath + '/' + maglefname]
+
+                                    if magleffiles == []:
+                                        # Handle user ip/ files with a maglef/ view but
+                                        # no LEF file.
+                                        maglefpath = libpath.replace('verilog', 'maglef')
+                                        designpath = os.path.split(self.projectpath)[0]
+                                        maglefpath = designpath + '/ip/' + maglefpath
+
+                                        if not os.path.exists(maglefpath + '/' + maglefname):
+                                            magleffiles = glob.glob(maglefpath + '/*.mag')
+                                        else:
+                                            magleffiles = [maglefpath + '/' + maglefname]
+
+                                    for magleffile in magleffiles:
+                                        # Generate LEF file.  Since PDK and ip/ entries
+                                        # are not writeable, write into the project mag/
+                                        # directory.
+                                        magpath = self.projectpath + '/mag'
+                                        magname = os.path.split(magleffile)[1]
+                                        magroot = os.path.splitext(magname)[0]
+                                        leffile = magpath + '/' + magroot + '.lef'
+                                        if not os.path.isfile(leffile):
+                                            self.write_lef_file(magleffile, magpath)
+
+                                        if leffile in ioleflibs:
+                                            continue
+                                        elif leffile in lefprocessed:
+                                            continue
+                                        else:
+                                            lefprocessed.append(leffile)
+
+                                        lefname = os.path.split(leffile)[1]
+
+                                        newcoredefs = self.read_lef_macros(magpath, lefname, 'celllib')
+                                        coredefs.extend(newcoredefs)
+                                        corecells.extend(list(item['name'] for item in newcoredefs))
+                                        # LEF files generated on-the-fly are not needed
+                                        # after they have been parsed.
+                                        # os.remove(leffile)
+
+                            # Check if all modules in modulelist are represented by
+                            # corresponding LEF macros.  If not, then go looking for a LEF
+                            # file in the mag/ or maglef/ directory.  Then, go looking for
+                            # a .mag file in the mag/ or maglef/ directory, and build a
+                            # LEF macro from it.
+
+                            matching = list(item['name'] for item in coredefs if item['name'] in modulelist)
+                            for module in modulelist:
+                                if module not in matching:
+                                    lefpath = self.projectpath + '/lef'
+                                    magpath = self.projectpath + '/mag'
+                                    maglefpath = self.projectpath + '/mag'
+                                    lefname = libfile.replace('.v', '.lef')
+
+                                    # If the verilog file root name is not the same as
+                                    # the module name, then make a quick check for a
+                                    # LEF file with the same root name as the verilog.
+                                    # That indicates that the module does not exist in
+                                    # the LEF file, probably because it is a primary
+                                    # module that does not correspond to any layout.
+
+                                    leffile = lefpath + '/' + lefname
+                                    if os.path.exists(leffile):
+                                        self.print('Diagnostic: module ' + module + ' is not in ' + leffile + ' (probably a primary module)')
+                                        continue
+
+                                    leffile = magpath + '/' + lefname
+                                    istemp = False
+                                    if not os.path.exists(leffile):
+                                        magname = libfile.replace('.v', '.mag')
+                                        magfile = magpath + '/' + magname
+                                        if os.path.exists(magfile):
+                                            self.print('Diagnostic: Found a .mag file for ' + module + ' in ' + magfile)
+                                            self.write_lef_file(magfile)
+                                            istemp = True
+                                        else:
+                                            magleffile = maglefpath + '/' + lefname
+                                            if not os.path.exists(magleffile):
+                                                self.print('Diagnostic: (module ' + module + ') has no LEF file ' + leffile + ' or ' + magleffile)
+                                                magleffile = maglefpath + '/' + magname
+                                                if os.path.exists(magleffile):
+                                                    self.print('Diagnostic: Found a .mag file for ' + module + ' in ' + magleffile)
+                                                    if os.access(maglefpath, os.W_OK):
+                                                        self.write_lef_file(magleffile)
+                                                        leffile = magleffile
+                                                        istemp = True
+                                                    else:
+                                                        self.write_lef_file(magleffile, magpath)
+                                                else:
+                                                    self.print('Did not find a file ' + magfile)
+                                                    # self.print('Warning: module ' + module + ' has no LEF or .mag views')
+                                                    pass
+                                            else:
+                                                self.print('Diagnostic: Found a LEF file for ' + module + ' in ' + magleffile)
+                                                leffile = magleffile
+                                    else:
+                                        self.print('Diagnostic: Found a LEF file for ' + module + ' in ' + leffile)
+
+                                    if os.path.exists(leffile):
+                                        if leffile in lefprocessed:
+                                            continue
+                                        else:
+                                            lefprocessed.append(leffile)
+
+                                        newcoredefs = self.read_lef_macros(magpath, lefname, 'celllib')
+                                        # The LEF file generated on-the-fly is not needed
+                                        # any more after parsing the macro(s).
+                                        # if istemp:
+                                        #     os.remove(leffile)
+                                        coredefs.extend(newcoredefs)
+                                        corecells.extend(list(item['name'] for item in newcoredefs))
+                                    else:
+                                        # self.print('Failed to find a LEF view for module ' + module)
+                                        pass
+
+                    elif vlogparse[0] in verilogcells:
+                        # Check for array of pads
+                        bushigh = buslow = -1
+                        if len(vlogparse) >= 3:
+                            bmatch = busrex.match(vlogline)
+                            if bmatch:
+                                bushigh = int(bmatch.group(1))
+                                buslow = int(bmatch.group(2))
+                                
+                        for i in range(buslow, bushigh + 1):
+                            newpad = {}
+                            if i >= 0:
+                                newpad['name'] = vlogparse[1] + '[' + str(i) + ']'
+                            else:
+                                newpad['name'] = vlogparse[1]
+                            newpad['cell'] = vlogparse[0]
+                            padcell = next(item for item in celldefs if item['name'] == vlogparse[0])
+                            newpad['iolib'] = padcell['iolib']
+                            newpad['class'] = padcell['class']
+                            newpad['subclass'] = padcell['subclass']
+                            newpad['width'] = padcell['width']
+                            newpad['height'] = padcell['height']
+                            newpadlist.append(newpad)
+
+                    elif vlogparse[0] in corecells:
+                        # Check for array of cells
+                        bushigh = buslow = -1
+                        if len(vlogparse) >= 3:
+                            bmatch = busrex.match(vlogline)
+                            if bmatch:
+                                bushigh = int(bmatch.group(1))
+                                buslow = int(bmatch.group(2))
+                                
+                        for i in range(buslow, bushigh + 1):
+                            newcorecell = {}
+                            if i >= 0:
+                                newcorecell['name'] = vlogparse[1] + '[' + str(i) + ']'
+                            else:
+                                newcorecell['name'] = vlogparse[1]
+                            newcorecell['cell'] = vlogparse[0]
+                            corecell = next(item for item in coredefs if item['name'] == vlogparse[0])
+                            newcorecell['celllib'] = corecell['celllib']
+                            newcorecell['class'] = corecell['class']
+                            newcorecell['subclass'] = corecell['subclass']
+                            newcorecell['width'] = corecell['width']
+                            newcorecell['height'] = corecell['height']
+                            corecelllist.append(newcorecell)
+
+        self.print('')
+        self.print('Source file information:')
+        self.print('Source filename: ' + vlogfile)
+        self.print('Number of I/O libraries is ' + str(len(ioleflibs)))
+        self.print('Number of library cells in I/O libraries used: ' + str(len(verilogcells)))
+        self.print('Number of core celldefs is ' + str(len(coredefs)))
+        self.print('')
+        self.print('Number of I/O cells in design: ' + str(len(newpadlist)))
+        self.print('Number of core cells in design: ' + str(len(corecelllist)))
+        self.print('')
+
+        # Save the results
+        self.celldefs = celldefs
+        self.coredefs = coredefs
+        self.vlogpads = newpadlist
+        self.corecells = corecelllist
+        self.ioleflibs = ioleflibs
+
+    # Check self.vlogpads, which was created during import (above) against
+    # self.(N,S,W,E)pads, which was read from the DEF file (if there was one)
+    # Also check self.corecells, which was created during import against
+    # self.coregroup, which was read from the DEF file.
+
+    def resolve(self):
+        self.print('Resolve differences in verilog and LEF views.')
+
+        samepads = []
+        addedpads = []
+        removedpads = []
+
+        # (1) Create list of entries that are in both self.vlogpads and self.()pads
+        # (2) Create list of entries that are in self.vlogpads but not in self.()pads
+
+        allpads = self.Npads + self.NEpad + self.Epads + self.SEpad + self.Spads + self.SWpad + self.Wpads + self.NWpad
+
+        for pad in self.vlogpads:
+            newpadname = pad['name']
+            try:
+                lpad = next(item for item in allpads if item['name'] == newpadname) 
+            except:
+                addedpads.append(pad)
+            else:
+                samepads.append(lpad)
+
+        # (3) Create list of entries that are in allpads but not in self.vlogpads
+        for pad in allpads:
+            newpadname = pad['name']
+            try:
+                lpad = next(item for item in self.vlogpads if item['name'] == newpadname) 
+            except:
+                removedpads.append(pad)
+
+        # Print results
+        if len(addedpads) > 0:
+            self.print('Added pads:')
+            for pad in addedpads:
+                self.print(pad['name'] + ' (' + pad['cell'] + ')')
+
+        if len(removedpads) > 0:
+            plist = []
+            nspacers = 0
+            for pad in removedpads:
+                if 'subclass' in pad:
+                    if pad['subclass'] != 'SPACER':
+                        plist.append(pad)
+                    else:
+                        nspacers += 1
+
+            if nspacers > 0:
+                self.print(str(nspacers) + ' spacer cells ignored.')
+            if len(plist) > 0:
+                self.print('Removed pads:')
+                for pad in removedpads:
+                    self.print(pad['name'] + ' (' + pad['cell'] + ')')
+
+        if len(addedpads) + len(removedpads) == 0:
+            self.print('Pad list has not changed.')
+
+        # Remove all cells from the "removed" list, with comment
+
+        allpads = [self.Npads, self.NEpad, self.Epads, self.SEpad, self.Spads, self.SWpad, self.Wpads, self.NWpad]
+
+        for pad in removedpads:
+            rname = pad['name']
+            for row in allpads:
+                try:
+                    rpad = next(item for item in row if item['name'] == rname)
+                except:
+                    rpad = None
+                else:
+                    row.remove(rpad)
+
+        # Now the verilog file has no placement information, so the old padlist
+        # entries (if they exist) are preferred.  Add to these the new padlist
+        # entries
+
+        # First pass for unassigned pads:  Use of "CLASS ENDCAP" is preferred
+        # for identifying corner pads.  Otherwise, if 'CORNER' or 'corner' is
+        # in the pad name, then make sure there is one per row in the first
+        # position.  This is not foolproof and depends on the cell library
+        # using the text 'corner' in the name of the corner cell.  However,
+        # if the ad hoc methods fail, the user can still manually move the
+        # corner cells to the right place (to be done:  Identify if library
+        # uses ENDCAP designation for corner cells up front;  don't go
+        # looking for 'corner' text if the cells are easily identifiable by
+        # LEF class).
+
+        for pad in addedpads[:]:
+            iscorner = False
+            if 'class' in pad and pad['class'] == 'ENDCAP':
+                iscorner = True
+            elif 'CORNER' in pad['cell'].upper():
+                iscorner = True
+           
+            if iscorner:
+                if self.NWpad == []:
+                    self.NWpad.append(pad)
+                    pad['o'] = 'E'
+                    addedpads.remove(pad)
+                elif self.NEpad == []:
+                    self.NEpad.append(pad)
+                    pad['o'] = 'S'
+                    addedpads.remove(pad)
+                elif self.SEpad == []:
+                    self.SEpad.append(pad)
+                    pad['o'] = 'W'
+                    addedpads.remove(pad)
+                elif self.SWpad == []:
+                    self.SWpad.append(pad)
+                    pad['o'] = 'N'
+                    addedpads.remove(pad)
+
+        numN = len(self.Npads)
+        numS = len(self.Spads)
+        numE = len(self.Epads)
+        numW = len(self.Wpads)
+
+        minnum = min(numN, numS, numE, numW)
+        minnum = max(minnum, int(len(addedpads) / 4))
+
+        # Add pads in clockwise order.  Note that S and E pads are defined counterclockwise
+        for pad in addedpads:
+            if numN < minnum:
+                self.Npads.append(pad)
+                numN += 1
+                pad['o'] = 'S'
+                self.print("Adding pad " + pad['name'] + " to Npads")
+            elif numE < minnum:
+                self.Epads.insert(0, pad)
+                numE += 1
+                pad['o'] = 'W'
+                self.print("Adding pad " + pad['name'] + " to Epads")
+            elif numS < minnum:
+                self.Spads.insert(0, pad)
+                numS += 1
+                pad['o'] = 'N'
+                self.print("Adding pad " + pad['name'] + " to Spads")
+            # elif numW < minnum:
+            else:
+                self.Wpads.append(pad)
+                numW += 1
+                pad['o'] = 'E'
+                self.print("Adding pad " + pad['name'] + " to Wpads")
+
+            minnum = min(numN, numS, numE, numW)
+            minnum = max(minnum, int(len(addedpads) / 4))
+
+        # Make sure all pads have included information from the cell definition
+
+        allpads = self.Npads + self.NEpad + self.Epads + self.SEpad + self.Spads + self.SWpad + self.Wpads + self.NWpad
+
+        for pad in allpads:
+            if 'width' not in pad:
+                try:
+                    celldef = next(item for item in celldefs if item['name'] == pad['cell'])
+                except:
+                    self.print('Cell ' + pad['cell'] + ' not found!')
+                else:
+                    pad['width'] = celldef['width']
+                    pad['height'] = celldef['height']
+                    pad['class'] = celldef['class']
+                    pad['subclass'] = celldef['subclass']
+
+        # Now treat the core cells in the same way (resolve list parsed from verilog
+        # against the list parsed from DEF)	
+
+        # self.print('Diagnostic: ')
+        # self.print('self.corecells = ' + str(self.corecells))
+        # self.print('self.coregroup = ' + str(self.coregroup))
+
+        samecore = []
+        addedcore = []
+        removedcore = []
+
+        # (1) Create list of entries that are in both self.corecells and self.coregroup
+        # (2) Create list of entries that are in self.corecells but not in self.coregroup
+
+        for cell in self.corecells:
+            newcellname = cell['name']
+            try:
+                lcore = next(item for item in self.coregroup if item['name'] == newcellname) 
+            except:
+                addedcore.append(cell)
+            else:
+                samecore.append(lcore)
+
+        # (3) Create list of entries that are in self.coregroup but not in self.corecells
+        for cell in self.coregroup:
+            newcellname = cell['name']
+            try:
+                lcore = next(item for item in self.corecells if item['name'] == newcellname) 
+            except:
+                removedcore.append(cell)
+
+        # Print results
+        if len(addedcore) > 0:
+            self.print('Added core cells:')
+            for cell in addedcore:
+                self.print(cell['name'] + ' (' + cell['cell'] + ')')
+
+        if len(removedcore) > 0:
+            clist = []
+            for cell in removedcore:
+                clist.append(cell)
+
+            if len(clist) > 0:
+                self.print('Removed core cells:')
+                for cell in removedcore:
+                    self.print(cell['name'] + ' (' + cell['cell'] + ')')
+
+        if len(addedcore) + len(removedcore) == 0:
+            self.print('Core cell list has not changed.')
+
+        # Remove all cells from the "removed" list
+
+        coregroup = self.coregroup
+        for cell in removedcore:
+            rname = cell['name']
+            try:
+                rcell = next(item for item in coregroup if item['name'] == rname)
+            except:
+                rcell = None
+            else:
+                coregroup.remove(rcell)
+
+        # Add all cells from the "added" list to coregroup
+
+        for cell in addedcore:
+            rname = cell['name']
+            try:
+                rcell = next(item for item in coregroup if item['name'] == rname)
+            except:
+                coregroup.append(cell)
+                if not 'o' in cell:
+                    cell['o'] = 'N'
+                if not 'x' in cell:
+                    if len(self.Wpads) > 0:
+                        pad = self.Wpads[0]
+                        padx = pad['x'] if 'x' in pad else 0
+                        cell['x'] = padx + pad['height'] + self.margin
+                    else:
+                        cell['x'] = self.margin
+                if not 'y' in cell:
+                    if len(self.Spads) > 0:
+                        pad = self.Spads[0]
+                        pady = pad['y'] if 'y' in pad else 0
+                        cell['y'] = pady + pad['height'] + self.margin
+                    else:
+                        cell['y'] = self.margin
+            else:
+                rcell = None
+
+        # Make sure all core cells have included information from the cell definition
+
+        for cell in coregroup:
+            if 'width' not in cell:
+                try:
+                    coredef = next(item for item in coredefs if item['name'] == cell['cell'])
+                except:
+                    self.print('Cell ' + cell['cell'] + ' not found!')
+                else:
+                    cell['width'] = coredef['width']
+                    cell['height'] = coredef['height']
+                    cell['class'] = coredef['class']
+                    cell['subclass'] = coredef['subclass']
+
+    # Generate a new padframe by writing the configuration file, running
+    # padring, reading back the DEF file, and (re)poplulating the workspace
+
+    def generate(self, level):
+        self.print('Generate legal padframe using padring')
+
+        # Write out the configuration file
+        self.writeconfig()
+        # Run the padring app
+        self.runpadring()
+        # Rotate pads in the output if pad orientations are different from
+        # padring's expectations
+        self.rotate_pads_in_def()
+        # Read the placement information back from the generated DEF file
+        self.readplacement()
+        # Resolve differences (e.g., remove spacers)
+        self.resolve()
+        # Recreate and draw the padframe view on the canvas
+        self.populate(level + 1)
+        self.frame_configure(None)
+
+    # Write a new configuration file
+
+    def writeconfig(self):
+        mag_path = self.projectpath + '/mag'
+        if not os.path.exists(mag_path):
+            self.print('Error:  No project path /mag directory exists.  Cannot write config file.')
+            return
+
+        self.print('Writing padring configuration file.')
+
+        # Determine cell width and height from pad sizes.
+        # NOTE:  This compresses the chip to the minimum dimensions
+        # allowed by the arrangement of pads.  Use a "core" block to
+        # force the area larger than minimum (not yet implemented)
+        
+        topwidth = 0
+        for pad in self.Npads:
+            if 'width' not in pad:
+                self.print('No width: pad = ' + str(pad))
+            topwidth += pad['width']
+
+        # Add in the corner cells
+        if self.NWpad != []:
+            topwidth += self.NWpad[0]['height']
+        if self.NEpad != []:
+            topwidth += self.NEpad[0]['width']
+
+        botwidth = 0
+        for pad in self.Spads:
+            botwidth += pad['width']
+
+        # Add in the corner cells
+        if self.SWpad != []:
+            botwidth += self.SWpad[0]['width']
+        if self.SEpad != []:
+            botwidth += self.SEpad[0]['height']
+
+        width = max(botwidth, topwidth)
+
+        # if width < self.urx - self.llx:
+        #     width = self.urx - self.llx
+
+        leftheight = 0
+        for pad in self.Wpads:
+            leftheight += pad['width']
+
+        # Add in the corner cells
+        if self.NWpad != []:
+            leftheight += self.NWpad[0]['height']
+        if self.SWpad != []:
+            leftheight += self.SWpad[0]['width']
+
+        rightheight = 0
+        for pad in self.Epads:
+            rightheight += pad['width']
+
+        # Add in the corner cells
+        if self.NEpad != []:
+            rightheight += self.NEpad[0]['width']
+        if self.SEpad != []:
+            rightheight += self.SEpad[0]['height']
+
+        height = max(leftheight, rightheight)
+
+        # Check the dimensions of the core cells.  If they exceed the available
+        # padframe area, then expand the padframe to accomodate the core.
+
+        corellx = coreurx = (self.llx + self.urx) / 2
+        corelly = coreury = (self.lly + self.ury) / 2
+
+        for corecell in self.coregroup:
+            corient = corecell['o']
+            if 'S' in corient or 'N' in corient:
+                cwidth = corecell['width']
+                cheight = corecell['height']
+            else:
+                cwidth = corecell['height']
+                cheight = corecell['width']
+
+            if corecell['x'] < corellx:
+                corellx = corecell['x']
+            if corecell['x'] + cwidth > coreurx:
+                coreurx = corecell['x'] + cwidth
+            if corecell['y'] < corelly:
+                corelly = corecell['y']
+            if corecell['y'] + cheight > coreury:
+                coreury = corecell['y'] + cheight
+
+        coreheight = coreury - corelly
+        corewidth = coreurx - corellx
+
+        # Ignoring the possibility of overlaps with nonstandard-sized pads,
+        # assuming that the user has visually separated them.  Only check
+        # the core bounds against the standard padframe inside edge.
+
+        if self.SWpad != [] and self.SEpad != []:
+            if corewidth > width - self.SWpad[0]['width'] - self.SEpad[0]['width']:
+                width = corewidth + self.SWpad[0]['width'] + self.SEpad[0]['width']
+        if self.NWpad != [] and self.SWpad != []:
+            if coreheight > height - self.NWpad[0]['height'] - self.SWpad[0]['height']:
+                height = coreheight + self.NWpad[0]['height'] + self.SWpad[0]['height']
+
+        # Core cells are given a margin of self.margin from the pad inside edge, so the
+        # core area passed to the padring app is 2 * self.margin larger than the
+        # measured size of the core area.
+        width += 2 * self.margin
+        height += 2 * self.margin
+
+        if self.keep_cfg == False or not os.path.exists(mag_path + '/padframe.cfg'):
+
+            if os.path.exists(mag_path + '/padframe.cfg'):
+                # Copy the previous padframe.cfg file to a backup.  In case something
+                # goes badly wrong, this should be the only file overwritten, and can
+                # be recovered from the backup.
+                shutil.copy(mag_path + '/padframe.cfg', mag_path + '/padframe.cfg.bak')
+
+            with open(mag_path + '/padframe.cfg', 'w') as ofile:
+                print('AREA ' + str(int(width)) + ' ' + str(int(height)) + ' ;',
+			file=ofile)
+                print('', file=ofile)
+                for pad in self.NEpad:
+                    print('CORNER ' + pad['name'] + ' SW ' + pad['cell'] + ' ;',
+			    file=ofile)
+                for pad in self.SEpad:
+                    print('CORNER ' + pad['name'] + ' NW ' + pad['cell'] + ' ;',
+			    file=ofile)
+                for pad in self.SWpad:
+                    print('CORNER ' + pad['name'] + ' NE ' + pad['cell'] + ' ;',
+			    file=ofile)
+                for pad in self.NWpad:
+                    print('CORNER ' + pad['name'] + ' SE ' + pad['cell'] + ' ;',
+			    file=ofile)
+                for pad in self.Npads:
+                    flip = 'F ' if 'F' in pad['o'] else ''
+                    print('PAD ' + pad['name'] + ' N ' + flip + pad['cell'] + ' ;',
+			    file=ofile)
+                for pad in self.Epads:
+                    flip = 'F ' if 'F' in pad['o'] else ''
+                    print('PAD ' + pad['name'] + ' E ' + flip + pad['cell'] + ' ;',
+			    file=ofile)
+                for pad in self.Spads:
+                    flip = 'F ' if 'F' in pad['o'] else ''
+                    print('PAD ' + pad['name'] + ' S ' + flip + pad['cell'] + ' ;',
+			    file=ofile)
+                for pad in self.Wpads:
+                    flip = 'F ' if 'F' in pad['o'] else ''
+                    print('PAD ' + pad['name'] + ' W ' + flip + pad['cell'] + ' ;',
+			    file=ofile)
+
+    # Run the padring app.
+
+    def runpadring(self):
+        mag_path = self.projectpath + '/mag'
+        if not os.path.exists(mag_path):
+            self.print('No path /mag exists in project space;  cannot run padring.')
+            return
+
+        self.print('Running padring')
+
+        if self.padring_path:
+            padringopts = [self.padring_path]
+        else:
+            padringopts = ['padring']
+
+        # Diagnostic
+        # self.print('Used libraries (self.ioleflibs) = ' + str(self.ioleflibs))
+
+        for iolib in self.ioleflibs:
+            padringopts.append('-L')
+            padringopts.append(iolib)
+        padringopts.append('--def')
+        padringopts.append('padframe.def')
+        padringopts.append('padframe.cfg')
+
+        self.print('Running ' + str(padringopts))
+   
+        p = subprocess.Popen(padringopts, stdout = subprocess.PIPE,
+		    stderr = subprocess.PIPE, cwd = mag_path)
+        self.watch(p)
+
+    # Read placement information from the DEF file generated by padring.
+
+    def readplacement(self, precheck=False):
+        self.print('Reading placement information from DEF file')
+
+        mag_path = self.projectpath + '/mag'
+        if not os.path.isfile(mag_path + '/padframe.def'):
+            if not precheck:
+                self.print('No file padframe.def:  pad frame was not generated.')
+            return False 
+
+        # Very simple DEF file parsing.  The placement DEF only contains a
+        # COMPONENTS section.  Certain assumptions are made about the syntax
+        # that depends on the way 'padring' writes its output.  This is not
+        # a rigorous DEF parser!
+
+        units = 1000
+        in_components = False
+        Npadlist = []
+        Spadlist = []
+        Epadlist = []
+        Wpadlist = []
+        NEpad = []
+        NWpad = []
+        SEpad = []
+        SWpad = []
+        coregroup = []
+
+        # Reset bounds
+        self.llx = self.lly = self.urx = self.ury = 0
+        corners = 0
+
+        with open(mag_path + '/padframe.def', 'r') as ifile:
+            deflines = ifile.read().splitlines()
+            for line in deflines:
+                if 'UNITS DISTANCE MICRONS' in line:
+                    units = line.split()[3]
+                elif in_components:
+                    lparse = line.split()
+                    if lparse[0] == '-':
+                        instname = lparse[1]
+                        cellname = lparse[2]
+                        
+                    elif lparse[0] == '+':
+                        if lparse[1] == 'PLACED':
+                            placex = lparse[3]
+                            placey = lparse[4]
+                            placeo = lparse[6]
+
+                            newpad = {}
+                            newpad['name'] = instname
+                            newpad['cell'] = cellname
+
+                            try:
+                                celldef = next(item for item in self.celldefs if item['name'] == cellname)
+                            except:
+                                celldef = None
+                            else:
+                                newpad['iolib'] = celldef['iolib']
+                                newpad['width'] = celldef['width']
+                                newpad['height'] = celldef['height']
+                                newpad['class'] = celldef['class']
+                                newpad['subclass'] = celldef['subclass']
+ 
+                            newpad['x'] = float(placex) / float(units)
+                            newpad['y'] = float(placey) / float(units)
+                            newpad['o'] = placeo
+
+                            # Adjust bounds
+                            if celldef:
+                                if newpad['x'] < self.llx:
+                                    self.llx = newpad['x']
+                                if newpad['y'] < self.lly:
+                                    self.lly = newpad['y']
+
+                                if newpad['o'] == 'N' or newpad['o'] == 'S':
+                                    padurx = newpad['x'] + celldef['width']
+                                    padury = newpad['y'] + celldef['height']
+                                else:
+                                    padurx = newpad['x'] + celldef['height']
+                                    padury = newpad['y'] + celldef['width']
+
+                                if padurx > self.urx:
+                                    self.urx = padurx
+                                if padury > self.ury:
+                                    self.ury = padury
+
+                            # First four entries in the DEF file are corners
+                            # padring puts the lower left corner at zero, so
+                            # use the zero coordinates to determine which pads
+                            # are which.  Note that padring assumes the corner
+                            # pad is drawn in the SW corner position!
+
+                            if corners < 4:
+                                if newpad['x'] == 0 and newpad['y'] == 0:
+                                    SWpad.append(newpad)
+                                elif newpad['x'] == 0:
+                                    NWpad.append(newpad)
+                                elif newpad['y'] == 0:
+                                    SEpad.append(newpad)
+                                else:
+                                    NEpad.append(newpad)
+                                corners += 1       
+                            else:
+                                # Place according to orientation.  If orientation
+                                # is not standard, be sure to make it standard!
+                                placeo = self.rotate_orientation(placeo)
+                                if placeo == 'N':
+                                    Spadlist.append(newpad)
+                                elif placeo == 'E':
+                                    Wpadlist.append(newpad)
+                                elif placeo == 'S':
+                                    Npadlist.append(newpad)
+                                else:
+                                    Epadlist.append(newpad)
+
+                    elif 'END COMPONENTS' in line:
+                        in_components = False
+                elif 'COMPONENTS' in line:
+                    in_components = True
+
+            self.Npads = Npadlist
+            self.Wpads = Wpadlist
+            self.Spads = Spadlist
+            self.Epads = Epadlist
+
+            self.NWpad = NWpad
+            self.NEpad = NEpad
+            self.SWpad = SWpad
+            self.SEpad = SEpad
+
+        # The padframe has its own DEF file from the padring app, but the core
+        # does not.  The core needs to be floorplanned in a very similar manner.
+        # This will be done by searching for a DEF file of the project top-level
+        # layout.  If none exists, it is created by generating it from the layout.
+        # If the top-level layout does not exist, then all core cells are placed
+        # at the origin, and the origin placed at the padframe inside corner.
+
+        mag_path = self.projectpath + '/mag'
+        if not os.path.isfile(mag_path + '/' + self.project + '.def'):
+            if os.path.isfile(mag_path + '/' + self.project + '.mag'):
+
+                # Create a DEF file from the layout
+                with open(mag_path + '/pfg_write_def.tcl', 'w') as ofile:
+                    print('drc off', file=ofile)
+                    print('box 0 0 0 0', file=ofile)
+                    print('load ' + self.project, file=ofile)
+                    print('def write', file=ofile)
+                    print('quit', file=ofile)
+
+                magicexec = self.magic_path if self.magic_path else 'magic'
+                mproc = subprocess.Popen([magicexec, '-dnull', '-noconsole',
+			'pfg_write_def.tcl'],
+			stdin = subprocess.PIPE, stdout = subprocess.PIPE,
+			stderr = subprocess.PIPE, cwd = mag_path, universal_newlines = True)
+
+                self.watch(mproc)
+                os.remove(mag_path + '/pfg_write_def.tcl')
+
+            elif not os.path.isfile(mag_path + '/core.def'):
+
+                # With no other information available, copy the corecells
+                # (from the verilog file) into the coregroup list.
+                # Position all core cells starting at the padframe top left
+                # inside corner, and arranging in rows without overlapping.
+                # Note that no attempt is made to organize the cells or
+                # otherwise produce an efficient layout.  Any dimension larger
+                # than the current padframe overruns to the right or bottom.
+
+                if self.SWpad != []:
+                    corellx = SWpad[0]['x'] + SWpad[0]['width'] + self.margin
+                    corelly = SWpad[0]['y'] + SWpad[0]['height'] + self.margin
+                else:
+                    corellx = Wpadlist[0]['x'] + Wpadlist[0]['height'] + self.margin
+                    corelly = Spadlist[0]['x'] + Spadlist[0]['height'] + self.margin
+                if self.NEpad != []:
+                    coreurx = NEpad[0]['x'] - self.margin
+                    coreury = NEpad[0]['y'] - self.margin
+                else:
+                    coreurx = Epadlist[0]['x'] - self.margin
+                    coreury = Npadlist[0]['x'] - self.margin
+                locllx = corellx
+                testllx = corellx
+                loclly = corelly
+                testlly = corelly
+                nextlly = corelly
+              
+                for cell in self.corecells:
+
+                    testllx = locllx + cell['width']
+                    if testllx > coreurx:
+                        locllx = corellx
+                        corelly = nextlly
+                        loclly = nextlly
+
+                    newcore = cell
+                    newcore['x'] = locllx
+                    newcore['y'] = loclly
+                    newcore['o'] = 'N'
+
+                    locllx += cell['width'] + self.margin
+
+                    testlly = corelly + cell['height'] + self.margin
+                    if testlly > nextlly:
+                        nextlly = testlly
+
+                    coregroup.append(newcore)
+
+                self.coregroup = coregroup
+
+        if os.path.isfile(mag_path + '/' + self.project + '.def'):
+            # Read the top-level DEF, and use it to position the core cells.
+            self.print('Reading the top-level cell DEF for core cell placement.')
+
+            units = 1000
+            in_components = False
+            with open(mag_path + '/' + self.project + '.def', 'r') as ifile:
+                deflines = ifile.read().splitlines()
+                for line in deflines:
+                    if 'UNITS DISTANCE MICRONS' in line:
+                        units = line.split()[3]
+                    elif in_components:
+                        lparse = line.split()
+                        if lparse[0] == '-':
+                            instname = lparse[1]
+                            # NOTE: Magic should not drop the entire path to the
+                            # cell for the cellname;  this needs to be fixed!  To
+                            # work around it, remove any path components.
+                            cellpath = lparse[2]
+                            cellname = os.path.split(cellpath)[1]
+                        
+                        elif lparse[0] == '+':
+                            if lparse[1] == 'PLACED':
+                                placex = lparse[3]
+                                placey = lparse[4]
+                                placeo = lparse[6]
+
+                                newcore = {}
+                                newcore['name'] = instname
+                                newcore['cell'] = cellname
+
+                                try:
+                                    celldef = next(item for item in self.coredefs if item['name'] == cellname)
+                                except:
+                                    celldef = None
+                                else:
+                                    newcore['celllib'] = celldef['celllib']
+                                    newcore['width'] = celldef['width']
+                                    newcore['height'] = celldef['height']
+                                    newcore['class'] = celldef['class']
+                                    newcore['subclass'] = celldef['subclass']
+ 
+                                newcore['x'] = float(placex) / float(units)
+                                newcore['y'] = float(placey) / float(units)
+                                newcore['o'] = placeo
+                                coregroup.append(newcore)
+
+                        elif 'END COMPONENTS' in line:
+                            in_components = False
+                    elif 'COMPONENTS' in line:
+                        in_components = True
+
+            self.coregroup = coregroup
+
+        elif os.path.isfile(mag_path + '/core.def'):
+            # No DEF or .mag file, so fallback position is the last core.def
+            # file generated by this script.
+            self.read_core_def(precheck=precheck)
+
+        return True
+
+    # Read placement information from the "padframe.def" file and rotate
+    # all cells according to self.pad_rotation.  This accounts for the
+    # problem that the default orientation of pads is arbitrarily defined
+    # by the foundry, while padring assumes that the corner pad is drawn
+    # in the lower-left position and other pads are drawn with the pad at
+    # the bottom and the buses at the top.
+
+    def rotate_pads_in_def(self):
+        if self.pad_rotation == 0:
+            return
+
+        self.print('Rotating pads in padframe DEF file.')
+        mag_path = self.projectpath + '/mag'
+
+        if not os.path.isfile(mag_path + '/padframe.def'):
+            self.print('No file padframe.def:  Cannot modify pad rotations.')
+            return
+
+        deflines = []
+        with open(mag_path + '/padframe.def', 'r') as ifile:
+            deflines = ifile.read().splitlines()
+
+        outlines = []
+        in_components = False
+        for line in deflines:
+            if in_components:
+                lparse = line.split()
+                if lparse[0] == '+':
+                    if lparse[1] == 'PLACED':
+                        neworient = self.rotate_orientation(lparse[6])
+                        lparse[6] = neworient
+                        line = ' '.join(lparse)
+
+                elif 'END COMPONENTS' in line:
+                    in_components = False
+            elif 'COMPONENTS' in line:
+                in_components = True
+            outlines.append(line)
+
+        with open(mag_path + '/padframe.def', 'w') as ofile:
+            for line in outlines:
+                print(line, file=ofile)
+
+    # Read placement information from the DEF file for the core (created by
+    # a previous run of this script)
+
+    def read_core_def(self, precheck=False):
+        self.print('Reading placement information from core DEF file.')
+
+        mag_path = self.projectpath + '/mag'
+
+        if not os.path.isfile(mag_path + '/core.def'):
+            if not precheck:
+                self.print('No file core.def:  core placement was not generated.')
+            return False 
+
+        # Very simple DEF file parsing, similar to the padframe.def reading
+        # routine above.
+
+        units = 1000
+        in_components = False
+
+        coregroup = []
+
+        with open(mag_path + '/core.def', 'r') as ifile:
+            deflines = ifile.read().splitlines()
+            for line in deflines:
+                if 'UNITS DISTANCE MICRONS' in line:
+                    units = line.split()[3]
+                elif in_components:
+                    lparse = line.split()
+                    if lparse[0] == '-':
+                        instname = lparse[1]
+                        cellname = lparse[2]
+                        
+                    elif lparse[0] == '+':
+                        if lparse[1] == 'PLACED':
+                            placex = lparse[3]
+                            placey = lparse[4]
+                            placeo = lparse[6]
+
+                            newcore = {}
+                            newcore['name'] = instname
+                            newcore['cell'] = cellname
+
+                            try:
+                                celldef = next(item for item in self.coredefs if item['name'] == cellname)
+                            except:
+                                celldef = None
+                            else:
+                                newcore['celllib'] = celldef['celllib']
+                                newcore['width'] = celldef['width']
+                                newcore['height'] = celldef['height']
+                                newcore['class'] = celldef['class']
+                                newcore['subclass'] = celldef['subclass']
+ 
+                            newcore['x'] = float(placex) / float(units)
+                            newcore['y'] = float(placey) / float(units)
+                            newcore['o'] = placeo
+                            coregroup.append(newcore)
+
+                    elif 'END COMPONENTS' in line:
+                        in_components = False
+                elif 'COMPONENTS' in line:
+                    in_components = True
+
+            self.coregroup = coregroup
+
+        return True
+
+    # Save the layout to a Magic database file (to be completed)
+
+    def save(self):
+        self.print('Saving results in a magic layout database.')
+
+        # Generate a list of (unique) LEF libraries for all padframe and core cells
+        leflist = []
+        for pad in self.celldefs:
+            if pad['iolib'] not in leflist:
+                leflist.append(pad['iolib'])
+
+        for core in self.coredefs:
+            if core['celllib'] not in leflist:
+                leflist.append(core['celllib'])
+
+        # Run magic, and generate the padframe with a series of commands
+        mag_path = self.projectpath + '/mag'
+
+        with open(mag_path + '/pfg_write_mag.tcl', 'w') as ofile:
+            print('drc off', file=ofile)
+            print('box 0 0 0 0', file=ofile)
+            for leffile in leflist:
+                print('lef read ' + leffile, file=ofile)
+            print('def read padframe', file=ofile)
+            print('select top cell', file=ofile)
+            print('select area', file=ofile)
+            print('select save padframe', file=ofile)
+            print('delete', file=ofile)
+            print('def read core', file=ofile)
+            print('getcell padframe', file=ofile)
+            print('save ' + self.project, file=ofile)
+            print('writeall force ' + self.project, file=ofile)
+            print('quit', file=ofile)
+
+        magicexec = self.magic_path if self.magic_path else 'magic'
+        mproc = subprocess.Popen([magicexec, '-dnull', '-noconsole',
+			'pfg_write_mag.tcl'],
+			stdin = subprocess.PIPE, stdout = subprocess.PIPE,
+			stderr = subprocess.PIPE, cwd = mag_path, universal_newlines = True)
+        self.watch(mproc)
+        os.remove(mag_path + '/pfg_write_mag.tcl')
+        self.print('Done writing layout ' + self.project + '.mag')
+
+        # Write the core DEF file if it does not exist yet.
+        if not os.path.isfile(mag_path + '/core.def'):
+            self.write_core_def()
+
+if __name__ == '__main__':
+    faulthandler.register(signal.SIGUSR2)
+    options = []
+    arguments = []
+    for item in sys.argv[1:]:
+        if item.find('-', 0) == 0:
+            options.append(item)
+        else:
+            arguments.append(item)
+
+    if '-help' in options:
+        print(sys.argv[0] + ' [options]')
+        print('')
+        print('options:')
+        print('   -noc    Print output to terminal, not the gui window')
+        print('   -nog    No graphics, run in batch mode')
+        print('   -cfg    Use existing padframe.cfg, do not regenerate')
+        print('   -padring-path=<path>	path to padring executable')
+        print('   -magic-path=<path>	path to magic executable')
+        print('   -tech-path=<path>	path to tech root folder')
+        print('   -project-path=<path>	path to project root folder')
+        print('   -help   Print this usage information')
+        print('')
+        sys.exit(0)
+
+    root = tkinter.Tk()
+    do_gui = False if ('-nog' in options or '-nogui' in options) else True
+    app = SoCFloorplanner(root, do_gui)
+
+    # Allow option -noc to bypass the text-to-console redirection, so crash
+    # information doesn't disappear with the app.
+
+    app.use_console = False if ('-noc' in options or '-noconsole' in options) else True
+    if do_gui == False:
+        app.use_console = False
+
+    # efabless format can be specified on the command line, but note that it
+    # is otherwise auto-detected by checking for .config vs. .ef-config in
+    # the project space.
+
+    app.ef_format = True if '-ef_format' in options else False
+    app.keep_cfg = True if '-cfg' in options else False
+
+    app.padring_path = None
+    app.magic_path = None
+    app.techpath = None
+    app.projectpath = None
+
+    for option in options:
+        if option.split('=')[0] == '-padring-path':
+            app.padring_path = option.split('=')[1]
+        elif option.split('=')[0] == '-magic-path':
+            app.magic_path = option.split('=')[1]
+        elif option.split('=')[0] == '-tech-path':
+            app.techpath = option.split('=')[1]
+        elif option.split('=')[0] == '-project-path':
+            app.projectpath = option.split('=')[1]
+            app.projectpath = app.projectpath[:-1] if app.projectpath[-1] == '/' else app.projectpath
+
+    app.text_to_console()
+    app.init_padframe()
+    if app.do_gui:
+        root.mainloop()
+    else:
+        # Run 'save' in non-GUI mode
+        app.save()
+        sys.exit(0)
+
