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
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
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
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