Example #1
0
def check_feature(feature):
    """ Check if enabling this feature requires other features to be enabled.

    Some pips imply other features.  Example:

    .HCLK_LEAF_CLK_B_BOTL0.HCLK_CK_BUFHCLK10
    implies:
    .ENABLE_BUFFER.HCLK_CK_BUFHCLK10
    """

    feature_path = feature.split('.')

    if HCLK_CK_BUFHCLK_REGEX.fullmatch(feature_path[-1]):
        enable_buffer_feature = '{}.ENABLE_BUFFER.{}'.format(
            feature_path[0], feature_path[-1])

        return ' '.join((feature, enable_buffer_feature))

    m = CASCOUT_REGEX.fullmatch(feature_path[-2])
    if m:
        enable_cascout = '{}.CASCOUT_{}_ACTIVE'.format(feature_path[0],
                                                       m.group(1))

        return ' '.join((feature, enable_cascout))

    parts = feature.split('.')

    wire_feature = feature_when_routed(parts[1])
    if wire_feature is not None:
        return '{} {}.{}'.format(feature, parts[0], wire_feature)

    return feature
def check_feature(feature):
    """ Check if enabling this feature requires other features to be enabled.

    Some pips imply other features.  Example:

    .HCLK_LEAF_CLK_B_BOTL0.HCLK_CK_BUFHCLK10
    implies:
    .ENABLE_BUFFER.HCLK_CK_BUFHCLK10
    """

    # IOI_SING tiles have bits in common with the IOI tiles.
    #
    # The difference is that the TOP IOI_SING tile shares bits with
    # the bottom half of a normal IOI tile, while the BOTTOM IOI_SING
    # shares bits with the top half of a normal IOI TILE.
    #
    # The following, is to change the edge feature to accomodate this
    # need, as the IOI_SING tiles have the same wire, and pip names
    # despite they are found on the TOP or BOTTOM of an IOI column
    m = IOI_SING_REGEX.fullmatch(feature)
    if m:
        # Each clock region spans a total of 50 IOBs.
        # The IOI_SING are found on top or bottom of the whole
        # IOI/IOB column. The Y coordinate identified with the
        # second capture group is dived by 50 to get the relative
        # position of the IOI_SING within the clock region column
        is_bottom_sing = int(m.group(2)) % 50 == 0

        # This is the value to attach to the source pip name that
        # changes based on which IOI_SING is selected (top or bottom)
        #
        # Example: IOI_OLOGIC0_D1.IOI_IMUX34_0 -> IOI_OLOGIC0_D1.IOI_IMUX34_1
        src_value = '1' if is_bottom_sing else '0'

        # This is the value to attach to the IOI_SITE_PIPS names
        # in the destination wire of the pip
        #
        # Example: IOI_OLOGIC0 -> IOI_OLOGIC1
        dst_value = '0' if is_bottom_sing else '1'

        unchanged_feature = "{}{}{}{}".format(m.group(1), m.group(2),
                                              m.group(3), m.group(4))

        src_wire = m.group(6).replace('_SING', '')

        for pip in ['IMUX', 'LOGIC_OUTS', 'CTRL', 'FAN', 'BYP']:
            if pip in src_wire:
                src_wire = src_wire.replace('_0', '_{}'.format(src_value))

        if 'IOI_OCLK' in src_wire:
            src_wire = src_wire.replace('_0', '_{}'.format(dst_value))

        changed_feature = "{}{}".format(dst_value, src_wire)
        feature = "{}{}".format(unchanged_feature, changed_feature)

    feature_path = feature.split('.')

    # IOB_DIFFO_OUT0->IOB_DIFFO_IN1
    #
    # When this PIP is active the IOB operates in the differential output mode.
    # There is no feature assosciated with that PIP in the prjxray db but there
    # is a tile-wide feature named "DIFF_OUT".
    #
    # The "DIFF_OUT" cannot be set in the architecture as it is defined one
    # level up in the hierarchy (its tile-wide, not site-wide). So here we
    # map the PIP's feature to "DIFF_OUT"
    if feature_path[2] == "IOB_DIFFO_OUT0" and \
       feature_path[1] == "IOB_DIFFO_IN1":
        return '{}.OUT_DIFF'.format(feature_path[0])

    # IOB_PADOUT0->IOB_DIFFI_IN1
    # IOB_PADOUT1->IOB_DIFFI_IN0
    #
    # These connections are hard wires that connect IOB33M and IOB33S sites.
    # They are used in differential input mode.
    #
    # Vivado does not report this connection as a PIP but in the prjxray db it
    # is a pip. Instead of making it a pseudo-pip we simply reject fasm
    # features here.
    if feature_path[2] == "IOB_PADOUT0" and feature_path[1] == "IOB_DIFFI_IN1":
        return ''
    if feature_path[2] == "IOB_PADOUT1" and feature_path[1] == "IOB_DIFFI_IN0":
        return ''

    # REBUF stuff
    rebuf_key = (feature_path[0], feature_path[1])
    if rebuf_key in REBUF_SOURCES:
        return ' '.join([feature] + REBUF_NODES[REBUF_SOURCES[rebuf_key]])

    m = IOI_OCLK.fullmatch(feature_path[1])
    if m:
        enable_oclkm_feature = '{}.IOI_OCLKM_{}.{}'.format(
            feature_path[0], m.group(1), feature_path[-1])

        return ' '.join((feature, enable_oclkm_feature))

    if HCLK_CK_BUFHCLK_REGEX.fullmatch(feature_path[-1]):
        enable_buffer_feature = '{}.ENABLE_BUFFER.{}'.format(
            feature_path[0], feature_path[-1])

        return ' '.join((feature, enable_buffer_feature))

    # BUFHCE sites are now routed through, without the need of placing them, therefore,
    # when the relative pip is traversed, the correct fasm feature needs to be added.
    # The relevant features are:
    #    - IN_USE: to enable the BUFHCE site
    #    - ZINV_CE: to disable the inverter on CE input which is connected to VCC.
    #               This sets the CE signal to constant 1
    m = CLK_HROW_CK_MUX_REGEX.fullmatch(feature_path[-1])
    if m:
        x_loc_str = m.group(1)
        if 'L' in x_loc_str:
            x_loc = 0
        elif 'R' in x_loc_str:
            x_loc = 1
        else:
            assert False, "Impossible to determine X location of BUFHCE"

        y_loc = m.group(2)
        bufhce_loc = 'BUFHCE_X{}Y{}'.format(x_loc, y_loc)

        enable_bufhce_in_use = '{}.BUFHCE.{}.IN_USE'.format(
            feature_path[0], bufhce_loc)
        enable_bufhce_zinv_ce = '{}.BUFHCE.{}.ZINV_CE=1\'b1'.format(
            feature_path[0], bufhce_loc)

        return ' '.join((feature, enable_bufhce_in_use, enable_bufhce_zinv_ce))

    if BUFG_CLK_IN_REGEX.fullmatch(feature_path[-1]):
        enable_feature = '{}.{}_ACTIVE'.format(feature_path[0],
                                               feature_path[-1])

        return ' '.join((feature, enable_feature))

    if BUFG_CLK_OUT_REGEX.fullmatch(feature_path[-1]):
        enable_feature = '{}.{}_ACTIVE'.format(feature_path[0],
                                               feature_path[-1])

        return ' '.join((feature, enable_feature))

    if CCIO_ACTIVE_REGEX.fullmatch(feature_path[-1]):
        features = [feature]
        features.append('{}.{}_ACTIVE'.format(feature_path[0],
                                              feature_path[-1]))

        # Whenever a PIP connecting a CCIOn input of a HCLK_CMT tile is used
        # the additional feature CCIOn_USED has to be emitted. There is however
        # one exception which is for all PIPs connecting CCIOn with
        # MUX_OUT_FREQ_REFn wires. For those the feature should no be emitted.
        #
        # For more details refer to the fuzzer 045-hclk-cmt-pips in prjxray.
        if "FREQ_REF" not in feature_path[-2]:
            features.append('{}.{}_USED'.format(feature_path[0],
                                                feature_path[-1]))

        return ' '.join(features)

    m = HCLK_OUT.fullmatch(feature_path[-1])
    if m:
        return ' '.join([feature] + find_hclk_cmt_hclk_feature(
            feature_path[0], m.group(1), m.group(2)))

    m = CASCOUT_REGEX.fullmatch(feature_path[-2])
    if m:
        enable_cascout = '{}.CASCOUT_{}_ACTIVE'.format(feature_path[0],
                                                       m.group(1))

        return ' '.join((feature, enable_cascout))

    parts = feature.split('.')

    wire_feature = feature_when_routed(parts[1])
    if wire_feature is not None:
        return '{} {}.{}'.format(feature, parts[0], wire_feature)

    return feature
Example #3
0
def check_feature(feature):
    """ Check if enabling this feature requires other features to be enabled.

    Some pips imply other features.  Example:

    .HCLK_LEAF_CLK_B_BOTL0.HCLK_CK_BUFHCLK10
    implies:
    .ENABLE_BUFFER.HCLK_CK_BUFHCLK10
    """

    feature_path = feature.split('.')

    rebuf_key = (feature_path[0], feature_path[1])
    if rebuf_key in REBUF_SOURCES:
        return ' '.join([feature] + REBUF_NODES[REBUF_SOURCES[rebuf_key]])

    if HCLK_CK_BUFHCLK_REGEX.fullmatch(feature_path[-1]):
        enable_buffer_feature = '{}.ENABLE_BUFFER.{}'.format(
            feature_path[0], feature_path[-1])

        return ' '.join((feature, enable_buffer_feature))

    #BUFHCE sites are now routed through, without the need of placing them, therefore,
    #when the relative pip is traversed, the correct fasm feature needs to be added.
    #The relevant features are:
    #    - IN_USE: to enable the BUFHCE site
    #    - ZINV_CE: to disable the inverter on CE input which is connected to VCC.
    #               This sets the CE signal to constant 1
    m = CLK_HROW_CK_MUX_REGEX.fullmatch(feature_path[-1])
    if m:
        x_loc_str = m.group(1)
        if 'L' in x_loc_str:
            x_loc = 0
        elif 'R' in x_loc_str:
            x_loc = 1
        else:
            assert False, "Impossible to determine X location of BUFHCE"

        y_loc = m.group(2)
        bufhce_loc = 'BUFHCE_X{}Y{}'.format(x_loc, y_loc)

        enable_bufhce_in_use = '{}.BUFHCE.{}.IN_USE'.format(
            feature_path[0], bufhce_loc)
        enable_bufhce_zinv_ce = '{}.BUFHCE.{}.ZINV_CE=1\'b1'.format(
            feature_path[0], bufhce_loc)

        return ' '.join((feature, enable_bufhce_in_use, enable_bufhce_zinv_ce))

    if BUFG_CLK_IN_REGEX.fullmatch(feature_path[-1]):
        enable_feature = '{}.{}_ACTIVE'.format(feature_path[0],
                                               feature_path[-1])

        return ' '.join((feature, enable_feature))

    if BUFG_CLK_OUT_REGEX.fullmatch(feature_path[-1]):
        enable_feature = '{}.{}_ACTIVE'.format(feature_path[0],
                                               feature_path[-1])

        return ' '.join((feature, enable_feature))

    if CCIO_ACTIVE_REGEX.fullmatch(feature_path[-1]):
        features = [feature]
        features.append('{}.{}_ACTIVE'.format(feature_path[0],
                                              feature_path[-1]))
        features.append('{}.{}_USED'.format(feature_path[0], feature_path[-1]))

        return ' '.join(features)

    m = HCLK_OUT.fullmatch(feature_path[-1])
    if m:
        return ' '.join((feature,
                         find_hclk_cmt_hclk_feature(feature_path[0],
                                                    m.group(1), m.group(2))))

    m = CASCOUT_REGEX.fullmatch(feature_path[-2])
    if m:
        enable_cascout = '{}.CASCOUT_{}_ACTIVE'.format(feature_path[0],
                                                       m.group(1))

        return ' '.join((feature, enable_cascout))

    parts = feature.split('.')

    wire_feature = feature_when_routed(parts[1])
    if wire_feature is not None:
        return '{} {}.{}'.format(feature, parts[0], wire_feature)

    return feature
Example #4
0
def check_feature(feature):
    """ Check if enabling this feature requires other features to be enabled.

    Some pips imply other features.  Example:

    .HCLK_LEAF_CLK_B_BOTL0.HCLK_CK_BUFHCLK10
    implies:
    .ENABLE_BUFFER.HCLK_CK_BUFHCLK10
    """

    feature_path = feature.split('.')

    rebuf_key = (feature_path[0], feature_path[1])
    if rebuf_key in REBUF_SOURCES:
        return ' '.join([feature] + REBUF_NODES[REBUF_SOURCES[rebuf_key]])

    if HCLK_CK_BUFHCLK_REGEX.fullmatch(feature_path[-1]):
        enable_buffer_feature = '{}.ENABLE_BUFFER.{}'.format(
            feature_path[0], feature_path[-1])

        return ' '.join((feature, enable_buffer_feature))

    if BUFG_CLK_IN_REGEX.fullmatch(feature_path[-1]):
        enable_feature = '{}.{}_ACTIVE'.format(feature_path[0],
                                               feature_path[-1])

        return ' '.join((feature, enable_feature))

    if BUFG_CLK_OUT_REGEX.fullmatch(feature_path[-1]):
        enable_feature = '{}.{}_ACTIVE'.format(feature_path[0],
                                               feature_path[-1])

        return ' '.join((feature, enable_feature))

    if CCIO_ACTIVE_REGEX.fullmatch(feature_path[-1]):
        features = [feature]
        features.append('{}.{}_ACTIVE'.format(feature_path[0],
                                              feature_path[-1]))
        features.append('{}.{}_USED'.format(feature_path[0], feature_path[-1]))

        return ' '.join(features)

    m = HCLK_OUT.fullmatch(feature_path[-1])
    if m:
        return ' '.join((feature,
                         find_hclk_cmt_hclk_feature(feature_path[0],
                                                    m.group(1), m.group(2))))

    m = CASCOUT_REGEX.fullmatch(feature_path[-2])
    if m:
        enable_cascout = '{}.CASCOUT_{}_ACTIVE'.format(feature_path[0],
                                                       m.group(1))

        return ' '.join((feature, enable_cascout))

    parts = feature.split('.')

    wire_feature = feature_when_routed(parts[1])
    if wire_feature is not None:
        return '{} {}.{}'.format(feature, parts[0], wire_feature)

    return feature
Example #5
0
def check_feature(feature):
    """ Check if enabling this feature requires other features to be enabled.

    Some pips imply other features.  Example:

    .HCLK_LEAF_CLK_B_BOTL0.HCLK_CK_BUFHCLK10
    implies:
    .ENABLE_BUFFER.HCLK_CK_BUFHCLK10
    """

    feature_path = feature.split('.')

    # IOB_DIFFO_OUT0->IOB_DIFFO_IN1
    #
    # When this PIP is active the IOB operates in the differential output mode.
    # There is no feature assosciated with that PIP in the prjxray db but there
    # is a tile-wide feature named "DIFF_OUT".
    #
    # The "DIFF_OUT" cannot be set in the architecture as it is defined one
    # level up in the hierarchy (its tile-wide, not site-wide). So here we
    # map the PIP's feature to "DIFF_OUT"
    if feature_path[2] == "IOB_DIFFO_OUT0" and \
       feature_path[1] == "IOB_DIFFO_IN1":
        return '{}.OUT_DIFF'.format(feature_path[0])

    rebuf_key = (feature_path[0], feature_path[1])
    if rebuf_key in REBUF_SOURCES:
        return ' '.join([feature] + REBUF_NODES[REBUF_SOURCES[rebuf_key]])

    m = IOI_OCLK.fullmatch(feature_path[1])
    if m:
        enable_oclkm_feature = '{}.IOI_OCLKM_{}.{}'.format(
            feature_path[0], m.group(1), feature_path[-1]
        )

        return ' '.join((feature, enable_oclkm_feature))

    if HCLK_CK_BUFHCLK_REGEX.fullmatch(feature_path[-1]):
        enable_buffer_feature = '{}.ENABLE_BUFFER.{}'.format(
            feature_path[0], feature_path[-1]
        )

        return ' '.join((feature, enable_buffer_feature))

    #BUFHCE sites are now routed through, without the need of placing them, therefore,
    #when the relative pip is traversed, the correct fasm feature needs to be added.
    #The relevant features are:
    #    - IN_USE: to enable the BUFHCE site
    #    - ZINV_CE: to disable the inverter on CE input which is connected to VCC.
    #               This sets the CE signal to constant 1
    m = CLK_HROW_CK_MUX_REGEX.fullmatch(feature_path[-1])
    if m:
        x_loc_str = m.group(1)
        if 'L' in x_loc_str:
            x_loc = 0
        elif 'R' in x_loc_str:
            x_loc = 1
        else:
            assert False, "Impossible to determine X location of BUFHCE"

        y_loc = m.group(2)
        bufhce_loc = 'BUFHCE_X{}Y{}'.format(x_loc, y_loc)

        enable_bufhce_in_use = '{}.BUFHCE.{}.IN_USE'.format(
            feature_path[0], bufhce_loc
        )
        enable_bufhce_zinv_ce = '{}.BUFHCE.{}.ZINV_CE=1\'b1'.format(
            feature_path[0], bufhce_loc
        )

        return ' '.join((feature, enable_bufhce_in_use, enable_bufhce_zinv_ce))

    if BUFG_CLK_IN_REGEX.fullmatch(feature_path[-1]):
        enable_feature = '{}.{}_ACTIVE'.format(
            feature_path[0], feature_path[-1]
        )

        return ' '.join((feature, enable_feature))

    if BUFG_CLK_OUT_REGEX.fullmatch(feature_path[-1]):
        enable_feature = '{}.{}_ACTIVE'.format(
            feature_path[0], feature_path[-1]
        )

        return ' '.join((feature, enable_feature))

    if CCIO_ACTIVE_REGEX.fullmatch(feature_path[-1]):
        features = [feature]
        features.append(
            '{}.{}_ACTIVE'.format(feature_path[0], feature_path[-1])
        )
        features.append('{}.{}_USED'.format(feature_path[0], feature_path[-1]))

        return ' '.join(features)

    m = HCLK_OUT.fullmatch(feature_path[-1])
    if m:
        return ' '.join(
            [feature] + find_hclk_cmt_hclk_feature(
                feature_path[0], m.group(1), m.group(2)
            )
        )

    m = CASCOUT_REGEX.fullmatch(feature_path[-2])
    if m:
        enable_cascout = '{}.CASCOUT_{}_ACTIVE'.format(
            feature_path[0], m.group(1)
        )

        return ' '.join((feature, enable_cascout))

    parts = feature.split('.')

    wire_feature = feature_when_routed(parts[1])
    if wire_feature is not None:
        return '{} {}.{}'.format(feature, parts[0], wire_feature)

    return feature