#!/usr/bin/env python

import argparse
import sys
from collections import OrderedDict

from lxml import etree as ET

class SequentialPort:
    def __init__(self, port, clock):
        self.port = port
        self.clock = clock

class CombEdge:
    def __init__(self, src_port, sink_port):
        self.src_port = src_port
        self.sink_ports = sink_port

class ModelTiming:
    def __init__(self):
        self.sequential_ports = set()
        self.comb_edges = {}

INDENT = "    "

#To add support for new upgrades/features add the identifier string here
#and added a guarded call in main()
supported_upgrades = [
    "add_model_timing",
    "upgrade_fc_overrides",
    "upgrade_device_layout",
    "remove_io_chan_distr",
    "upgrade_pinlocations",
    "uniqify_interconnect_names",
    "upgrade_connection_block_input_switch",
    "upgrade_switch_types",
    "rename_fc_attributes",
    "longline_no_sb_cb",
    "upgrade_port_equivalence",
    "upgrade_complex_sb_num_conns",
    "add_missing_comb_model_internal_timing_edges",
]

def parse_args():
    parser = argparse.ArgumentParser(description="Upgrade Legacy VTR architecture files")

    parser.add_argument("xml_file", help="xml_file to update (modified in place)")
    parser.add_argument("--features",
                        nargs="*",
                        help="List of features/upgrades to apply (default: %(default)s)",
                        choices=supported_upgrades,
                        default=supported_upgrades)
    parser.add_argument("--debug", default=False, action="store_true", help="Print to stdout instead of modifying file inplace")
    parser.add_argument("--pretty", default=False, action="store_true", help="Pretty print the output?")

    return parser.parse_args()

def main():
    args = parse_args()

    print args.xml_file
    parser = ET.XMLParser()
    root = ET.parse(args.xml_file, parser)

    root_tags = root.findall(".")
    assert len(root_tags) == 1
    arch = root_tags[0]

    if arch.tag != "architecture":
        print "Not an architecture file, exiting..."
        sys.exit(1)

    modified = False
    if "add_model_timing" in args.features:
        result = add_model_timing(arch)
        if result:
            modified = True

    if "upgrade_fc_overrides" in args.features:
        result = upgrade_fc_overrides(arch)
        if result:
            modified = True

    if "upgrade_device_layout" in args.features:
        result = upgrade_device_layout(arch)
        if result:
            modified = True

    if "remove_io_chan_distr" in args.features:
        result = remove_io_chan_distr(arch)
        if result:
            modified = True

    if "upgrade_pinlocations" in args.features:
        result = upgrade_pinlocations(arch)
        if result:
            modified = True

    if "uniqify_interconnect_names" in args.features:
        result = uniqify_interconnect_names(arch)
        if result:
            modified = True

    if "upgrade_connection_block_input_switch" in args.features:
        result = upgrade_connection_block_input_switch(arch)
        if result:
            modified = True

    if "upgrade_switch_types" in args.features:
        result = upgrade_switch_types(arch)
        if result:
            modified = True

    if "rename_fc_attributes" in args.features:
        result = rename_fc_attributes(arch)
        if result:
            modified = True

    if "longline_no_sb_cb" in args.features:
        result = remove_longline_sb_cb(arch)
        if result:
            modified = True

    if "upgrade_port_equivalence" in args.features:
        result = upgrade_port_equivalence(arch)
        if result:
            modified = True

    if "upgrade_complex_sb_num_conns" in args.features:
        result = upgrade_complex_sb_num_conns(arch)
        if result:
            modified = True


    if "add_missing_comb_model_internal_timing_edges" in args.features:
        result = add_missing_comb_model_internal_timing_edges(arch)
        if result:
            modified = True

    if modified:
        if args.debug:
            root.write(sys.stdout, pretty_print=args.pretty)
        else:
            with open(args.xml_file, "w") as f:
                root.write(f, pretty_print=args.pretty)

def add_model_timing(arch):
    """
    Records the timing edges specified via timing annotationson primitive PB types,
    and adds the appropriate timing edges to the primitive descriptions in the models
    section.
    """
    models = arch.findall("./models/model")

    #Find all primitive pb types
    prim_pbs = arch.findall(".//pb_type[@blif_model]")

    #Build up the timing specifications from 
    default_models = frozenset([".input", ".output", ".latch", ".names"])
    primitive_timing_specs = {}
    for prim_pb in prim_pbs:

        blif_model = prim_pb.attrib['blif_model']

        if blif_model in default_models:
            continue

        assert blif_model.startswith(".subckt ")
        blif_model = blif_model[len(".subckt "):]

        if blif_model not in primitive_timing_specs:
            primitive_timing_specs[blif_model] = ModelTiming()

        #Find combinational edges
        for xpath_pattern in ["./delay_constant", "./delay_matrix"]:
            for delay_const in prim_pb.findall(xpath_pattern):
                iports = get_port_names(delay_const.attrib['in_port'])
                oports = get_port_names(delay_const.attrib['out_port'])

                for iport in iports:
                    if iport not in primitive_timing_specs[blif_model].comb_edges:
                        primitive_timing_specs[blif_model].comb_edges[iport] = set()

                    for oport in oports:
                        primitive_timing_specs[blif_model].comb_edges[iport].add(oport)

        #Find sequential ports
        for xpath_pattern in ["./T_setup", "./T_clock_to_Q", "./T_hold"]:
            for seq_tag in prim_pb.findall(xpath_pattern):
                ports = get_port_names(seq_tag.attrib['port'])
                for port in ports:
                    clk = seq_tag.attrib['clock']

                    primitive_timing_specs[blif_model].sequential_ports.add((port, clk))

    changed = False
    for model in models:
        if model.attrib['name'] not in primitive_timing_specs:
            print "Warning: no timing specifications found for {}".format(mode.attrib['name'])
            continue

        model_timing = primitive_timing_specs[model.attrib['name']]

        #Mark model ports as sequential
        for port_name, clock_name in model_timing.sequential_ports:
            port = model.find(".//port[@name='{}']".format(port_name))
            port.attrib['clock'] = clock_name
            changed = True

        #Mark combinational edges from sources to sink ports
        for src_port, sink_ports in model_timing.comb_edges.iteritems():
            xpath_pattern = "./input_ports/port[@name='{}']".format(src_port)
            port = model.find(xpath_pattern)
            port.attrib['combinational_sink_ports'] = ' '.join(sink_ports)
            changed = True

    return changed

def upgrade_fc_overrides(arch):
    """
    Convets the legacy block <fc> pin and segment override specifications,
    to the new unified format.
    """
    fc_tags = arch.findall(".//fc")

    changed = False
    for fc_tag in fc_tags:
        assert fc_tag.tag == "fc"

        old_fc_pin_overrides = fc_tag.findall("./pin")
        old_fc_seg_overrides = fc_tag.findall("./segment")

        assert len(old_fc_pin_overrides) == 0 or len(old_fc_seg_overrides) == 0, "Can only have pin or seg overrides (not both)"

        for old_pin_override in old_fc_pin_overrides:

            port = old_pin_override.attrib['name']
            fc_type = old_pin_override.attrib['fc_type']
            fc_val = old_pin_override.attrib['fc_val']
            
            fc_tag.remove(old_pin_override)

            new_attrib = OrderedDict()
            new_attrib["port_name"] = port
            new_attrib["fc_type"] = fc_type
            new_attrib["fc_val"] = fc_val

            new_pin_override = ET.SubElement(fc_tag, "fc_override", attrib=new_attrib)
            changed = True

        for old_seg_override in old_fc_seg_overrides:

            seg_name = old_seg_override.attrib['name']
            in_val = old_seg_override.attrib['in_val']
            out_val = old_seg_override.attrib['out_val']

            fc_tag.remove(old_seg_override)

            fc_in_type = fc_tag.attrib['default_in_type']
            fc_out_type = fc_tag.attrib['default_out_type']

            pb_type = fc_tag.find("..")
            assert pb_type.tag == "pb_type"

            inputs = pb_type.findall("./input")
            outputs = pb_type.findall("./output")
            clocks = pb_type.findall("./clock")

            for input in inputs + clocks:

                new_attrib = OrderedDict()
                new_attrib["port_name"] = input.attrib['name']
                new_attrib["segment_name"] = seg_name
                new_attrib["fc_type"] = fc_in_type
                new_attrib["fc_val"] = in_val

                fc_override = ET.SubElement(fc_tag, "fc_override", attrib=new_attrib)

            for output in outputs:

                new_attrib = OrderedDict()
                new_attrib["port_name"] = output.attrib['name']
                new_attrib["segment_name"] = seg_name
                new_attrib["fc_type"] = fc_out_type
                new_attrib["fc_val"] = out_val

                fc_override = ET.SubElement(fc_tag, "fc_override", attrib=new_attrib)
        
            changed = True
    return changed

def upgrade_device_layout(arch):
    """
    Upgrades the legacy <gridlocation> specifications (on each pb_type) to the new format
    placed under the <layout> tag.
    """
    changed = False

    #Get the layout tag
    layout = arch.find("./layout")

    #Find all the top level pb_types
    top_pb_types = arch.findall("./complexblocklist/pb_type")

    type_to_grid_specs = OrderedDict()
    for top_pb_type in top_pb_types:
        type_name = top_pb_type.attrib['name']

        assert type_name not in type_to_grid_specs
        type_to_grid_specs[type_name] = []

        gridlocations = top_pb_type.find("gridlocations")
        if gridlocations == None:
            continue

        for child in gridlocations:
            if child.tag is ET.Comment:
                continue
            assert child.tag == "loc"
            type_to_grid_specs[type_name].append(child)

        #Remove the legacy gridlocations from the <pb_type>
        top_pb_type.remove(gridlocations)
        changed = True

    if not changed:
        #No legacy specs to upgrade
        return changed

    device_auto = None
    if 'auto' in layout.attrib:
        aspect_ratio = layout.attrib['auto']

        del layout.attrib['auto']
        change = True

        device_auto = ET.SubElement(layout, 'auto_layout')
        device_auto.attrib['aspect_ratio'] = str(aspect_ratio)
    elif 'width' in layout.attrib and 'height' in layout.attrib:
        width = layout.attrib['width']
        height = layout.attrib['height']

        del layout.attrib['width']
        del layout.attrib['height']
        changed = True

        device_auto = ET.SubElement(layout, 'fixed_layout')
        device_auto.attrib['name'] = "unnamed_device"
        device_auto.attrib['width'] = width
        device_auto.attrib['height'] = height
    else:
        assert False, "Unrecognized <layout> specification"
    
    if 0:
        for type, locs in type_to_grid_specs.iteritems():
            print "Type:", type
            for loc in locs:
                print "\t", loc.tag, loc.attrib

    have_perimeter = False

    for type_name, locs in type_to_grid_specs.iteritems():
        for loc in locs:
            if loc.attrib['type'] == "perimeter":
                have_perimeter = True


    if changed:
        layout.text = "\n" + INDENT
        device_auto.text = "\n" + 2*INDENT
        device_auto.tail = "\n"

    
    for type_name, locs in type_to_grid_specs.iteritems():
        for loc in locs:
            assert loc.tag == "loc"

            loc_type = loc.attrib['type']

            #Note that we scale the priority by a factor of 10 to allow us to 'tweak'
            #the priorities without causing conflicts with user defined priorities
            priority = 10*int(loc.attrib['priority'])

            if loc_type == "col":
                start = loc.attrib['start']

                repeat = None
                if 'repeat' in loc.attrib:
                    repeat = loc.attrib['repeat']

                comment_str = "Column of '{}' with 'EMPTY' blocks wherever a '{}' does not fit.".format(type_name, type_name)

                if have_perimeter:
                    comment_str += " Vertical offset by 1 for perimeter."

                comment = ET.Comment(comment_str)
                device_auto.append(comment)
                comment.tail = "\n" + 2*INDENT

                col_spec = ET.SubElement(device_auto, 'col')

                col_spec.attrib['type'] = type_name
                col_spec.attrib['startx'] = start
                if have_perimeter:
                    col_spec.attrib['starty'] = "1"
                if repeat:
                    col_spec.attrib['repeatx'] = repeat
                col_spec.attrib['priority'] = str(priority)
                col_spec.tail = "\n" + 2*INDENT

                #Classic VPR fills blank spaces (e.g. where a height > 1 block won't fit) with "EMPTY" 
                #instead of with the underlying type. To replicate that we create a col spec with the same 
                #location information, but of type 'EMPTY' and with slightly lower priority than the real type.

                col_empty_spec = ET.SubElement(device_auto, 'col')
                col_empty_spec.attrib['type'] = "EMPTY"
                col_empty_spec.attrib['startx'] = start
                if repeat:
                    col_empty_spec.attrib['repeatx'] = repeat
                if have_perimeter:
                    col_empty_spec.attrib['starty'] = "1"
                col_empty_spec.attrib['priority'] = str(priority - 1) #-1 so it won't override the 'real' col
                col_empty_spec.tail = "\n" + 2*INDENT

            elif loc_type == "rel":
                pos = loc.attrib['pos']

                div_factor = 1. / float(pos)

                int_div_factor = int(div_factor)

                startx = "(W - 1) / {}".format(div_factor)

                if float(int_div_factor) != div_factor:
                    print "Warning: Relative position factor conversion is not exact. Original pos factor: {}. New startx expression: {}".format(pos, startx)

                comment_str = "Column of '{}' with 'EMPTY' blocks wherever a '{}' does not fit.".format(type_name, type_name)

                if have_perimeter:
                    comment_str += " Vertical offset by 1 for perimeter."

                comment = ET.Comment(comment_str)
                device_auto.append(comment)
                comment.tail = "\n" + 2*INDENT

                col_spec = ET.SubElement(device_auto, 'col')
                col_spec.attrib['type'] = type_name
                col_spec.attrib['startx'] = startx
                if have_perimeter:
                    col_spec.attrib['starty'] = "1"
                col_spec.attrib['priority'] = str(priority)
                col_spec.tail = "\n" + 2*INDENT

                #Classic VPR fills blank spaces (e.g. where a height > 1 block won't fit) with "EMPTY" 
                #instead of with the underlying type. To replicate that we create a col spec with the same 
                #location information, but of type 'EMPTY' and with slightly lower priority than the real type.
                col_empty_spec = ET.SubElement(device_auto, 'col')
                col_empty_spec.attrib['type'] = "EMPTY"
                col_empty_spec.attrib['startx'] = startx
                if have_perimeter:
                    col_empty_spec.attrib['starty'] = "1"
                col_empty_spec.attrib['priority'] = str(priority - 1) #-1 so it won't override the 'real' col
                col_empty_spec.tail = "\n" + 2*INDENT

            elif loc_type == "fill":

                comment = ET.Comment("Fill with '{}'".format(type_name))
                device_auto.append(comment)
                comment.tail = "\n" + 2*INDENT

                fill_spec = ET.SubElement(device_auto, 'fill')
                fill_spec.attrib['type'] = type_name
                fill_spec.attrib['priority'] = str(priority)
                fill_spec.tail = "\n" + 2*INDENT

            elif loc_type == "perimeter":
                #The classic VPR perimeter specification did not include the corners (while the new version does)
                # As a result we specify a full perimeter (including corners), and then apply an EMPTY type override
                # at the corners

                comment = ET.Comment("Perimeter of '{}' blocks with 'EMPTY' blocks at corners".format(type_name))
                device_auto.append(comment)
                comment.tail = "\n" + 2*INDENT

                perim_spec = ET.SubElement(device_auto, 'perimeter')
                perim_spec.attrib['type'] = type_name
                perim_spec.attrib['priority'] = str(priority)
                perim_spec.tail = "\n" + 2*INDENT

                corners_spec = ET.SubElement(device_auto, 'corners')
                corners_spec.attrib['type'] = "EMPTY"
                corners_spec.attrib['priority'] = str(priority + 1) #+1 to ensure overrides
                corners_spec.tail = "\n" + 2*INDENT

            else:
                assert False, "Unrecognzied <loc> type tag {}".format(loc_type)

    return changed
        
def remove_io_chan_distr(arch):
    """
    Removes the legacy '<io>' channel width distribution tags
    """
    device = arch.find("./device")
    chan_width_distr = device.find("./chan_width_distr")

    io = chan_width_distr.find("./io")
    if io != None:
        width = float(io.attrib['width'])

        if width != 1.:
            print "Found non-unity io width {}. This is no longer supported by VPR and must be manually correct. Exiting...".format(width)
            sys.exit(1)
        else:
            assert width == 1.
            chan_width_distr.remove(io)
            return True #Modified

def upgrade_pinlocations(arch):
    """
    Upgrades custom pin locations from the 'offset' to 'yoffset' attribute.
    Since previously only width==1 blocks were supported, we only need to consider
    the yoffset case
    """
    modified = False
    pinlocations_list = arch.findall(".//pinlocations")

    for pinlocations in pinlocations_list:
        pb_type = pinlocations.find("..")

        assert pb_type.tag == "pb_type"

        width = 1
        height = 1
        if 'width' in pb_type.attrib:
            width = int(pb_type.attrib['width'])
        if 'height' in pb_type.attrib:
            height = int(pb_type.attrib['height'])

        if width == 1:

            if pinlocations.attrib['pattern'] == "custom":

                for loc in pinlocations:
                    if loc.tag is ET.Comment:
                        continue

                    assert loc.tag == "loc"

                    if 'offset' in loc.attrib:
                        offset = int(loc.attrib['offset'])

                        assert offset < height

                        #Remove the old attribute
                        del loc.attrib['offset']

                        #Add the new attribute
                        loc.attrib['yoffset'] = str(offset)

                        modified = True

            else:
                assert pinlocations.attrib['pattern'] == "spread"

    return modified

def uniqify_interconnect_names(arch):
    """
    Ensure all interconnect tags have unique names
    """
    modified = False

    for interconnect_tag in arch.findall(".//interconnect"):
        seen_names = set()
        cnt = 0
        for child_tag in interconnect_tag:
            if child_tag.tag is ET.Comment:
                continue

            name = orig_name = child_tag.attrib['name']

            if orig_name in seen_names:
                #Generate a unique name
                while name in seen_names:
                    name = orig_name + "_{}".format(cnt)
                    cnt += 1

                assert name not in seen_names
                child_tag.attrib['name'] = name
                modified = True

            seen_names.add(name)

    return modified

def upgrade_connection_block_input_switch(arch):
    """
    Convert connection block input switch specification to use a switch named
    in <switchlist>
    """
    modified = False

    device_tag = arch.find("./device")
    timing_tag = device_tag.find("./timing")
    sizing_tag = device_tag.find("./sizing")
    switchlist_tag = arch.find("./switchlist")
    connection_block_tag = arch.find("./connection_block")

    assert sizing_tag is not None

    if timing_tag is not None:
        assert sizing_tag is not None
        assert 'ipin_mux_trans_size' in sizing_tag.attrib
        assert 'C_ipin_cblock' in timing_tag.attrib
        assert 'T_ipin_cblock' in timing_tag.attrib
        assert not device_tag.find("./connection_block") is not None
        assert switchlist_tag is not None

        R_minW_nmos = sizing_tag.attrib['R_minW_nmos']
        ipin_switch_mux_trans_size = sizing_tag.attrib['ipin_mux_trans_size']
        ipin_switch_cin = timing_tag.attrib['C_ipin_cblock']
        ipin_switch_tdel = timing_tag.attrib['T_ipin_cblock']

        modified = True

        #Remove the old attributes
        del sizing_tag.attrib['ipin_mux_trans_size']
        device_tag.remove(timing_tag)

        #
        #Create the switch
        #
        
        switch_name = "ipin_cblock"

        #Make sure the switch name doesn't already exist
        for switch_tag in switchlist_tag.findall("./switch"):
            assert switch_tag.attrib['name'] != switch_name

        #Comment the switch
        comment = ET.Comment("switch {} resistance set to yeild for 4x minimum drive strength buffer".format(switch_name))
        comment.tail = "\n" + 2*INDENT
        switchlist_tag.append(comment)
        #Create the switch
        switch_tag = ET.SubElement(switchlist_tag, "switch")
        switch_tag.attrib['type'] = 'mux'
        switch_tag.attrib['name'] = switch_name
        switch_tag.attrib['R'] = str(float(R_minW_nmos) / 4.)
        switch_tag.attrib['Cout'] = "0."
        switch_tag.attrib['Cin'] = ipin_switch_cin
        switch_tag.attrib['Tdel'] = ipin_switch_tdel
        switch_tag.attrib['mux_trans_size'] = ipin_switch_mux_trans_size
        switch_tag.attrib['buf_size'] = "auto"
        switch_tag.tail = "\n" + 2*INDENT

        #Create the connection_block tag
        connection_block_tag = ET.SubElement(device_tag, "connection_block")
        connection_block_tag.attrib['input_switch_name'] = switch_name
        connection_block_tag.tail = "\n" + 2*INDENT

    else:
        assert 'ipin_switch_mux_trans_size' not in sizing_tag.attrib

    return modified

def upgrade_switch_types(arch):
    """
    Rename 'buffered' and 'pass_trans' <switch type=""/> to 'tristate' and 'pass_gate'
    """
    modified = False
    switchlist_tag = arch.find("./switchlist")
    assert switchlist_tag is not None

    for switch_tag in switchlist_tag.findall("./switch"):
        
        switch_type = switch_tag.attrib['type']

        if switch_type in ['buffered', 'pass_trans']:
            if switch_type == 'buffered':
                switch_type = "tristate"
            else:
                assert switch_type == 'pass_trans'
                switch_type = "pass_gate"

            switch_tag.attrib['type'] = switch_type
            modified = True

    return modified

def rename_fc_attributes(arch):
    """
    Converts <fc> attributes of the form default_% to %
    """
    fc_tags = arch.findall(".//fc")

    changed = False
    for fc_tag in fc_tags:
        assert fc_tag.tag == "fc"
        attr_to_replace = ["default_in_type", "default_in_val", "default_out_type", "default_out_val"]
        attr_list = list(fc_tag.attrib.keys())
        for attr in attr_list:
            if attr in attr_to_replace:
                val = fc_tag.attrib[attr]
                del fc_tag.attrib[attr]
                fc_tag.attrib[attr.replace("default_", "")] = val
                changed = True
    return changed

def remove_longline_sb_cb(arch):
    """
    Drops <sb> and <cb> of any <segment> types with length="longline",
    since we now assume longlines have full switch block/connection block 
    populations
    """

    longline_segment_tags = arch.findall(".//segment[@length='longline']")

    changed = False
    for longline_segment_tag in longline_segment_tags:
        assert longline_segment_tag.tag == 'segment'
        assert longline_segment_tag.attrib['length'] == 'longline'

        child_sb_tags = longline_segment_tag.findall("./sb")
        child_cb_tags = longline_segment_tag.findall("./cb")

        for cb_sb_tag in child_sb_tags + child_cb_tags:
            assert cb_sb_tag.tag == 'cb' or cb_sb_tag.tag == 'sb'
            print >>sys.stderr, "Warning: Removing invalid {} tag for longline segment".format(cb_sb_tag.tag)
            longline_segment_tag.remove(cb_sb_tag)
            changed = True

    return changed

def upgrade_port_equivalence(arch):
    """
    Upgrades port equivalence from "true|false" to "none|full|instance"

    Note that to be safely conservative we upgrade <output equivalent="true">
    to <output equivalent="instance">. Users should check whether their architecture
    should actually be using <output equivalent="full">.
    """

    input_equivalent_tags = arch.findall(".//input[@equivalent]")
    output_equivalent_tags = arch.findall(".//output[@equivalent]")

    changed = False

    for input_equivalent_tag in input_equivalent_tags:
        assert input_equivalent_tag.tag == "input"
        assert 'equivalent' in input_equivalent_tag.attrib

        #For inputs, 'true' is upgraded to full, and 'false' to 'none'
        if input_equivalent_tag.attrib['equivalent'] == "true":
            input_equivalent_tag.attrib['equivalent'] = "full"
            changed = True
        elif input_equivalent_tag.attrib['equivalent'] == "false":
            input_equivalent_tag.attrib['equivalent'] = "none"
            changed = True
        else:
            assert input_equivalent_tag.attrib['equivalent'] in ['none', 'full', 'instance'], "equivalence already upgraded"

    for output_equivalent_tag in output_equivalent_tags:
        assert output_equivalent_tag.tag == "output"
        assert 'equivalent' in output_equivalent_tag.attrib

        #For outputs, 'true' is upgraded to full, and 'false' to 'none'
        if output_equivalent_tag.attrib['equivalent'] == "true":
            parent_tag = output_equivalent_tag.find("..[@name]")
            print >>sys.stderr, "Warning: Conservatively upgrading output port equivalence from 'true' to 'instance' on {}. The user should manually check whether this can be upgraded to 'full'".format(parent_tag.attrib['name'])
            output_equivalent_tag.attrib['equivalent'] = "instance" #Conservative
            changed = True
        elif output_equivalent_tag.attrib['equivalent'] == "false":
            output_equivalent_tag.attrib['equivalent'] = "none"
            changed = True
        else:
            assert output_equivalent_tag.attrib['equivalent'] in ['none', 'full', 'instance'], "equivalence already upgraded"

    return changed

def get_port_names(string):
    ports = []

    for elem in string.split():
        #Split off the prefix
        port = elem.split('.')[-1]
        if '[' in port:
            port = port[:port.find('[')]

        ports.append(port)

    return ports

def upgrade_complex_sb_num_conns(arch):
    """
    Upgrades <wireconn> 'num_conns_type' attribute to 'num_conns"
    """

    wireconn_tags = arch.findall(".//wireconn[@num_conns_type]")

    changed = False

    for wireconn_tag in wireconn_tags:
        assert wireconn_tag.tag == "wireconn"
        assert 'num_conns_type' in wireconn_tag.attrib

        #For inputs, 'true' is upgraded to full, and 'false' to 'none'
        num_conns_value = wireconn_tag.attrib['num_conns_type']

        del wireconn_tag.attrib['num_conns_type']

        if num_conns_value == 'min':
            num_conns_value = 'min(from,to)'
        elif num_conns_value == 'max':
            num_conns_value = 'max(from,to)'

        wireconn_tag.attrib['num_conns'] = num_conns_value

        changed = True

    return changed

def add_missing_comb_model_internal_timing_edges(arch):
    """
    For the purposes of constant generator detection every model needs to include
    a set of primtiive internal timing edges.

    If we find a combinational model definition which has no internal timing edges,
    we add timing edges between all input and output ports. This is a pessimistic,
    but safe assumption.

    Note that if we find any internal timing edges specified we assume the user has
    specified them correctly and do not make any changes to that model
    """
    changed = False

    model_tags = arch.findall("./models/model")

    for model_tag in model_tags:

        input_clock_tags = model_tag.findall("./input_ports/port[@is_clock='1']")
        if len(input_clock_tags) > 0:
            continue #Sequential primitive -- no change

        input_tags_with_timing_edges = model_tag.findall("./input_ports/port[@combinational_sink_ports]")
        if len(input_tags_with_timing_edges) > 0:
            continue #Already has internal edges specified -- no change

        #Collect the model port definitions
        input_port_tags = model_tag.findall("./input_ports/port")
        output_port_tags = model_tag.findall("./output_ports/port")

        #Collect output port names
        output_port_names = []
        for output_port_tag in output_port_tags:
            output_port_names.append(output_port_tag.attrib['name'])

        for input_port_tag in input_port_tags:

            assert 'combinational_sink_ports' not in input_port_tag

            input_port_tag.attrib['combinational_sink_ports'] = " ".join(output_port_names)

            print >>sys.stderr, "Warning: Conservatively upgrading combinational sink dependencies for input port '{}' of model '{}' to '{}'. The user should manually check whether a reduced set of sink dependencies can be safely specified.".format(input_port_tag.attrib['name'], model_tag.attrib['name'], input_port_tag.attrib['combinational_sink_ports'])

            changed = True

    return changed

if __name__ == "__main__":
    main()
