#!/usr/bin/env python3
#-----------------------------------------------------------------------
# netlist_to_layout.py
#-----------------------------------------------------------------------
#
# Generate a magic layout from a SPICE netlist, running magic in batch
# mode and calling up the PDK selections non-interactively for each
# component in the netlist.
#
#---------------------------------------------------------------------
# Written by Tim Edwards
# efabless, inc.
# November 17, 2016
# Updated December 17, 2016
# Version 1.0
# Imported December 22, 2020 to open_pdks
# Updated February 10, 2021 for use running on netlist alone
#---------------------------------------------------------------------

import os
import re
import sys
import subprocess

def generate_layout_start(library, ofile=sys.stdout):
    # Write a couple of simplifying procedures
    print('#!/usr/bin/env wish', file=ofile)
    print('#-------------------------------------', file=ofile)
    print('# Script to create layout from netlist', file=ofile)
    print('# Source this in magic.', file=ofile)
    print('#-----------------------------------------', file=ofile)
    print('proc move_forward {instname} {', file=ofile)
    print('    select cell $instname', file=ofile)
    print('    set anum [lindex [array -list count] 1]', file=ofile)
    print('    set xpitch [lindex [array -list pitch] 0]', file=ofile)
    print('    set bbox [box values]', file=ofile)
    print('    set posx [lindex $bbox 0]', file=ofile)
    print('    set posy [lindex $bbox 1]', file=ofile)
    print('    set width [expr [lindex $bbox 2] - $posx]', file=ofile)
    print('    set posx [expr $posx + $width + $xpitch * $anum]', file=ofile)
    print('    box position ${posx}i ${posy}i', file=ofile)
    print('    return [lindex $bbox 3]', file=ofile)
    print('}', file=ofile)
    print('', file=ofile)
    print('proc get_and_move_inst {cellname instname anum} {', file=ofile)
    print('    set newinst [getcell $cellname]', file=ofile)
    print('    select cell $newinst', file=ofile)
    print('    if {$newinst == ""} {return}', file=ofile)
    print('    identify $instname', file=ofile)
    print('    if {$anum > 1} {array 1 $anum}', file=ofile)
    print('    set bbox [box values]', file=ofile)
    print('    set posx [lindex $bbox 2]', file=ofile)
    print('    set posy [lindex $bbox 1]', file=ofile)
    print('    box position ${posx}i ${posy}i', file=ofile)
    print('    return [lindex $bbox 3]', file=ofile)
    print('}', file=ofile)
    print('', file=ofile)
    print('proc add_pin {pinname portnum} {', file=ofile)
    print('    box size 1um 1um', file=ofile)
    print('    paint m1', file=ofile)
    print('    label $pinname FreeSans 16 0 0 0 c m1', file=ofile)
    print('    port make $portnum', file=ofile)
    print('    box move s 2um', file=ofile)
    print('}', file=ofile)
    print('', file=ofile)
    if not library:
        print('namespace import ${PDKNAMESPACE}::*', file=ofile)
    print('suspendall', file=ofile)
    return ofile
 
def generate_layout_add(subname, subpins, complist, library, ofile=sys.stdout):
    parmrex = re.compile('([^=]+)=([^=]+)', re.IGNORECASE)
    exprrex = re.compile('\'([^\']+)\'', re.IGNORECASE)
    librex  = re.compile('(.*)__(.*)', re.IGNORECASE)

    print('load ' + subname, file=ofile)

    print('box 0um 0um 0um 0um', file=ofile)
    print('', file=ofile)

    # Generate all of the pins as labels
    pinlist = subpins.split()
    i = 0
    for pin in pinlist:
        # Escape [ and ] in pin name
        pin_esc = pin.replace('[', '\[').replace(']', '\]')
        # To be done:  watch for key=value parameters
        print('add_pin ' + pin_esc + ' ' + str(i), file=ofile)
        i += 1

    # Set initial position for importing cells
    print('box size 0 0', file=ofile)
    print('set posx 0', file=ofile)
    print('set posy [expr {round(3 / [cif scale out])}]', file=ofile)
    print('box position ${posx}i ${posy}i', file=ofile)

    for comp in complist:
        params = {}
        tokens = comp.split()
        # Diagnostic
        # print("Adding component " + tokens[0])
        instname = tokens[0]
        mult = 1
        for token in tokens[1:]:
            rmatch = parmrex.match(token)
            if rmatch:
                parmname = rmatch.group(1).upper()
                parmval = rmatch.group(2)
                params[parmname] = parmval
                if parmname.upper() == 'M':
                    try:
                        mult = int(parmval)
                    except ValueError:
                        # This takes care of multiplier expressions, as long
                        # as they don't reference parameter names themselves.
                        mult = eval(eval(parmval))
            else:
                # Last one that isn't a parameter will be kept
                devtype = token

        # If devtype is a cellname in the form "<lib>__<cell>" then check if <cell> is
        # in the user's /ip/ directory.  If so, recast devtype to just <cell>.
        ematch = librex.match(devtype)
        if ematch:
            cellname = ematch.group(2)
            if os.path.exists(os.path.expanduser('~/design/ip/' + cellname)):
                devtype = cellname

        # devtype is assumed to be in library.  If not, it will throw an error and
        # attempt to use 'getcell' on devtype.  NOTE:  Current usage is to not pass
        # a library to netlist_to_layout.py but to rely on the PDK Tcl script to
        # define variable PDKNAMESPACE, which is the namespace to use for low-level
        # components, and may not be the same name as the technology node.
        if library:
            libdev = library + '::' + devtype
        else:
            libdev = '${PDKNAMESPACE}::' + devtype
        outparts = []
        outparts.append('magic::gencell ' + libdev + ' ' + instname)

        #  Output all parameters.  Parameters not used by the toolkit are ignored
        # by the toolkit.
        outparts.append('-spice')
        for item in params:
            outparts.append(str(item).lower())
            outparts.append(params[item])

        outstring = ' '.join(outparts)
        print('if {[catch {' + outstring + '}]} {', file=ofile)
        print('   get_and_move_inst ' + devtype + ' ' + instname
			+ ' ' + str(mult), file=ofile)
        print('} else {', file=ofile)
        print('   move_forward ' + instname, file=ofile)
        print('}', file=ofile)
        print('', file=ofile)
    print('save ' + subname, file=ofile)
                
def generate_layout_end(ofile=sys.stdout):
    print('resumeall', file=ofile)
    print('refresh', file=ofile)
    print('writeall force', file=ofile)
    print('quit', file=ofile)

def usage():
    print('Usage:')
    print('	netlist_to_layout.py <filename> [<namespace>] [-options]')
    print('')
    print('Arguments:')
    print('	<filename> is the path to the SPICE netlist to import to magic')
    print('	<namespace> is the namespace of the PDK')
    print('')
    print('Options:')
    print('	-keep	Keep the working script after completion.')
    print('	-help	Print this help text.')

# Main procedure

if __name__ == '__main__':

    # Parse command line for options and arguments
    optionlist = []
    arguments = []
    for item in sys.argv[1:]:
        if item.find('-', 0) == 0:
            optionlist.append(item)
        else:
            arguments.append(item)

    if len(arguments) > 0:
        inputfile = arguments[0]
        if len(arguments) > 1:
            library = arguments[1]
        else:
            library = None
    else:
        usage()
        sys.exit(0)

    debugmode = False
    keepmode = False

    for item in optionlist:
        result = item.split('=')
        if result[0] == '-help':
            usage()
            sys.exit(0)
        elif result[0] == '-debug':
            debugmode = True
        elif result[0] == '-keep':
            keepmode = True
        else:
            usage()
            sys.exit(1)

    netpath = os.path.split(inputfile)[0]
    if netpath == '':
        netpath = os.getcwd()

    if os.path.splitext(inputfile)[1] == '.sch':
        print('Sorry, automatic conversion of schematic to netlist not yet supported.')
        sys.exit(1)

    netroot = os.path.split(netpath)[0]
    magpath = os.path.join(netroot, 'mag')
    if not os.path.isdir(magpath):
        print('Error:  Layout path "' + magpath + '" does not exist or is not readable.')
        sys.exit(1)

    # NOTE:  There should be some attempt to find the installed PDK magicrc file
    # if there is no mag/ directory.
    rcfile = '.magicrc'
    rcfilepath = os.path.join(magpath, rcfile)
    if not os.path.isfile(rcfilepath):
        print('Error:  No startup script file "' + rcfilepath + '"')
        sys.exit(1)

    # Read SPICE netlist
    with open(inputfile, 'r') as ifile:
        spicetext = ifile.read()
        
    subrex = re.compile('.subckt[ \t]+(.*)$', re.IGNORECASE)
    devrex = re.compile('[xmcrbdi]([^ \t]+)[ \t](.*)$', re.IGNORECASE)
    namerex = re.compile('([^= \t]+)[ \t]+(.*)$', re.IGNORECASE)
    endsrex = re.compile('^[ \t]*\.ends', re.IGNORECASE)

    # Contatenate continuation lines
    spicelines = spicetext.replace('\n+', ' ').splitlines()

    insub = False
    subname = ''
    subpins = ''
    complist = []
    scriptfile = 'generate_layout.tcl'
    scriptpath = os.path.join(magpath, scriptfile)

    with open(scriptpath, 'w') as ofile:
        generate_layout_start(library, ofile)
        for line in spicelines:
            if not insub:
                lmatch = subrex.match(line)
                if lmatch:
                    rest = lmatch.group(1)
                    smatch = namerex.match(rest)
                    if smatch:
                        subname = smatch.group(1)
                        subpins = smatch.group(2)
                        insub = True
                    else:
                        print('File ' + inputfile + ':  Failure to parse line ' + line)
            else:
                lmatch = endsrex.match(line)
                if lmatch:
                    insub = False
                    generate_layout_add(subname, subpins, complist, library, ofile)
                    subname = None
                    subpins = None
                    complist = []
                else:
                    dmatch = devrex.match(line)
                    if dmatch:
                        complist.append(line)

        generate_layout_end(ofile)

    myenv = os.environ.copy()
    myenv['MAGTYPE'] = 'mag'

    # Run the layout generator
    mproc = subprocess.run(['magic', '-dnull', '-noconsole', '-rcfile',
		rcfile, scriptfile],
		stdin = subprocess.DEVNULL, stdout = subprocess.PIPE,
		stderr = subprocess.PIPE, cwd = magpath,
		env = myenv, universal_newlines = True)
    if mproc.stdout:
        for line in mproc.stdout.splitlines():
            print(line)
    if mproc.stderr:
        print('Error message output from magic:')
        for line in mproc.stderr.splitlines():
            print(line)
    if mproc.returncode != 0:
        print('ERROR:  Magic exited with status ' + str(mproc.returncode))

    # Clean up
    if not keepmode:
        os.remove(scriptpath)

    sys.exit(0)
