| import re | |
| import tiles | |
| # REGEXs for global/clock signals | |
| # Globals | |
| global_entry_re = re.compile(r'R\d+C\d+_VPRX(\d){2}00') | |
| global_left_right_re = re.compile(r'R\d+C\d+_HPSX(\d){2}00') | |
| global_up_down_re = re.compile(r'R\d+C\d+_VPTX(\d){2}00') | |
| global_branch_re = re.compile(r'R\d+C\d+_HPBX(\d){2}00') | |
| # High Fanout Secondary Nets | |
| hfsn_entry_re = re.compile(r'R\d+C\d+_VSRX(\d){2}00') | |
| hfsn_left_right_re = re.compile(r'R\d+C\d+_HSSX(\d){2}00') | |
| # L2Rs control bidirectional portion of HFSNs!! | |
| hfsn_l2r_re = re.compile(r'R\d+C\d+_HSSX(\d){2}00_[RL]2[LR]') | |
| hfsn_up_down_re = re.compile(r'R\d+C\d+_VSTX(\d){2}00') | |
| # HSBX(\d){2}00 are fixed connections to HSBX(\d){2}01s. | |
| hfsn_branch_re = re.compile(r'R\d+C\d+_HSBX(\d){2}0[01]') | |
| # Center Mux | |
| # Outputs- entry to DCCs connected to globals (VPRXI -> DCC -> VPRX) * | |
| center_mux_glb_out_re = re.compile(r'R\d+C\d+_VPRXCLKI\d+') | |
| # Outputs- connected to ECLKBRIDGEs * | |
| center_mux_ebrg_out_re = re.compile(r'R\d+C\d+_EBRG(\d){1}CLK(\d){1}') | |
| # Inputs- CIB routing to HFSNs | |
| cib_out_to_hfsn_re = re.compile(r'R\d+C\d+_JSNETCIB([TBRL]|MID)(\d){1}') | |
| # Inputs- CIB routing to globals | |
| cib_out_to_glb_re = re.compile(r'R\d+C\d+_J?PCLKCIB(L[TBRL]Q|MID|VIQ[TBRL])(\d){1}') | |
| # Inputs- CIB routing to ECLKBRIDGEs | |
| cib_out_to_eclk_re = re.compile(r'R\d+C\d+_J?ECLKCIB[TBRL](\d){1}') | |
| # Inputs- Edge clocks dividers | |
| eclk_out_re = re.compile(r'R\d+C\d+_J?[TBRL]CDIV(X(\d){1}|(\d){2})') | |
| # Inputs- PLL | |
| pll_out_re = re.compile(r'R\d+C\d+_J?[LR]PLLCLK\d+') | |
| # Inputs- Clock pads | |
| clock_pin_re = re.compile(r'R\d+C\d+_J?PCLK[TBLR]\d+') | |
| # Part of center-mux but can also be found elsewhere | |
| # DCCs connected to globals * | |
| dcc_sig_re = re.compile(r'R\d+C\d+_J?(CLK[IO]|CE)(\d){1}[TB]?_DCC') | |
| # DCMs- connected to DCCs on globals 6 and 7 * | |
| dcm_sig_re = re.compile(r'R\d+C\d+_J?(CLK(\d){1}_|SEL|DCMOUT)(\d){1}_DCM') | |
| # ECLKBRIDGEs- TODO | |
| eclkbridge_sig_re = re.compile(r'R\d+C\d+_J?(CLK(\d){1}_|SEL|ECSOUT)(\d){1}_ECLKBRIDGECS') | |
| # Oscillator output | |
| osc_clk_re = re.compile(r'R\d+C\d+_J?OSC') | |
| # Soft Error Detection Clock * | |
| sed_clk_re = re.compile(r'R\d+C\d+_J?SEDCLKOUT') | |
| # PLL/DLL Clocks | |
| pll_clk_re = re.compile(r'R\d+C\d+_[TB]ECLK\d') | |
| # PG/INRD/LVDS | |
| pg_re = re.compile(r'R\d+C\d+_PG') | |
| inrd_re = re.compile(r'R\d+C\d+_INRD') | |
| lvds_re = re.compile(r'R\d+C\d+_LVDS') | |
| # DDR | |
| ddrclkpol_re = re.compile(r'R\d+C\d+_DDRCLKPOL') | |
| dqsr90_re = re.compile(r'R\d+C\d+_DQSR90') | |
| dqsw90_re = re.compile(r'R\d+C\d+_DQSW90') | |
| def is_global(wire): | |
| """Return true if a wire is part of the global clock network""" | |
| return bool(global_entry_re.match(wire) or | |
| global_left_right_re.match(wire) or | |
| global_up_down_re.match(wire) or | |
| global_branch_re.match(wire) or | |
| hfsn_entry_re.match(wire) or | |
| hfsn_left_right_re.match(wire) or | |
| hfsn_l2r_re.match(wire) or | |
| hfsn_up_down_re.match(wire) or | |
| hfsn_branch_re.match(wire) or | |
| center_mux_glb_out_re.match(wire) or | |
| center_mux_ebrg_out_re.match(wire) or | |
| cib_out_to_hfsn_re.match(wire) or | |
| cib_out_to_glb_re.match(wire) or | |
| cib_out_to_eclk_re.match(wire) or | |
| eclk_out_re.match(wire) or | |
| pll_out_re.match(wire) or | |
| clock_pin_re.match(wire) or | |
| dcc_sig_re.match(wire) or | |
| dcm_sig_re.match(wire) or | |
| eclkbridge_sig_re.match(wire) or | |
| osc_clk_re.match(wire) or | |
| sed_clk_re.match(wire) or | |
| pll_clk_re.match(wire) or | |
| pg_re.match(wire) or | |
| inrd_re.match(wire) or | |
| lvds_re.match(wire) or | |
| ddrclkpol_re.match(wire) or | |
| dqsr90_re.match(wire) or | |
| dqsw90_re.match(wire)) | |
| def handle_family_net(tile, wire, prefix_pos, tile_pos, netname): | |
| if tile.startswith("CENTER") and global_left_right_re.match(wire): | |
| if prefix_pos[1] < tile_pos[1]: | |
| return "L_" + netname | |
| elif prefix_pos[1] > tile_pos[1]: | |
| return "R_" + netname | |
| else: | |
| assert False, "bad CENTER netname" | |
| elif "CIB_EBR" in tile and global_up_down_re.match(wire): | |
| if prefix_pos[0] < tile_pos[0]: | |
| return "U_" + netname | |
| elif prefix_pos[0] > tile_pos[0]: | |
| return "D_" + netname | |
| else: | |
| assert False, "bad CIB_EBR netname" | |
| elif global_branch_re.match(wire): | |
| return "BRANCH_" + netname | |
| elif is_global(wire): | |
| return "G_" + netname | |
| else: | |
| return None |