| import re |
| import tiles |
| |
| # REGEXs for global/clock signals |
| |
| # Globals including spine inputs, TAP_DRIVE inputs and TAP_DRIVE outputs |
| global_spine_tap_re = re.compile(r'R\d+C\d+_[HV]P[TLBR]X(\d){2}00') |
| # CMUX outputs |
| global_cmux_out_re = re.compile(r'R\d+C\d+_[UL][LR]PCLK\d+') |
| # CMUX inputs |
| global_cmux_in_re = re.compile(r'R\d+C\d+_[HV]PF[NESW](\d){2}00') |
| # Clock pins |
| clock_pin_re = re.compile(r'R\d+C\d+_J?PCLK[TBLR]\d+') |
| # PLL global outputs |
| pll_out_re = re.compile(r'R\d+C\d+_J?[UL][LR][QC]PLL\dCLKO[PS]\d?') |
| |
| # CIB clock inputs |
| cib_clk_re = re.compile(r'R\d+C\d+_J?[ULTB][LR][QCM]PCLKCIB\d+') |
| # Oscillator output |
| osc_clk_re = re.compile(r'R\d+C\d+_J?OSC') |
| # Clock dividers |
| cdivx_clk_re = re.compile(r'R\d+C\d+_J?[UL]CDIVX\d+') |
| # SED clock output |
| sed_clk_re = re.compile(r'R\d+C\d+_J?SEDCLKOUT') |
| |
| # SERDES reference clocks |
| pcs_clk_re = re.compile(r'R\d+C\d+_J?PCS[AB][TR]XCLK\d') |
| |
| |
| # DDRDEL delay signals |
| ddr_delay_re = re.compile(r'R\d+C\d+_[UL][LR]DDRDEL') |
| |
| # DCC signals |
| dcc_clk_re = re.compile(r'R\d+C\d+_J?(CLK[IO]|CE)_[BLTR]?DCC(\d+|[BT][LR])') |
| # DCC inputs |
| dcc_clki_re = re.compile(r'R\d+C\d+_[BLTR]?DCC(\d+|[BT][LR])CLKI') |
| # DCS signals |
| dcs_sig_re = re.compile(r'R\d+C\d+_J?(CLK\d|SEL\d|DCSOUT|MODESEL)_DCS\d') |
| # DCS clocks |
| dcs_clk_re = re.compile(r'R\d+C\d+_DCS\d(CLK\d)?') |
| # Misc. center clocks |
| center_clk_re = re.compile(r'R\d+C\d+_J?(LE|RE)CLK\d') |
| |
| # Shared DQS signals |
| dqs_ssig_re = re.compile(r'R\d+C\d+_(DQS[RW]\d*|(RD|WR)PNTR\d)$') |
| |
| # Bank edge clocks |
| bnk_eclk_re = re.compile('R\d+C\d+_BANK\d+(ECLK\d+)') |
| # CIB ECLK inputs |
| cib_eclk_re = re.compile(r'R\d+C\d+_J?[ULTB][LR][QCM]ECLKCIB\d+') |
| |
| brg_eclk_re = re.compile(r'R\d+C(\d+)_JBRGECLK\d+') |
| |
| |
| def is_global_brgeclk(wire): |
| m = brg_eclk_re.match(wire) |
| if not m: |
| return False |
| if m: |
| x = int(m.group(1)) |
| return x > 5 and x < 67 |
| |
| def is_global(wire): |
| """Return true if a wire is part of the global clock network""" |
| return bool(global_spine_tap_re.match(wire) or |
| global_cmux_out_re.match(wire) or |
| global_cmux_in_re.match(wire) or |
| clock_pin_re.match(wire) or |
| pll_out_re.match(wire) or |
| cib_clk_re.match(wire) or |
| osc_clk_re.match(wire) or |
| cdivx_clk_re.match(wire) or |
| sed_clk_re.match(wire) or |
| ddr_delay_re.match(wire) or |
| dcc_clk_re.match(wire) or |
| dcc_clki_re.match(wire) or |
| dcs_sig_re.match(wire) or |
| dcs_clk_re.match(wire) or |
| pcs_clk_re.match(wire) or |
| center_clk_re.match(wire) or |
| cib_eclk_re.match(wire) or |
| is_global_brgeclk(wire)) |
| |
| def handle_family_net(tile, wire, prefix_pos, tile_pos, netname): |
| if tile.startswith("TAP") and netname.startswith("H"): |
| if prefix_pos[1] < tile_pos[1]: |
| return "L_" + netname |
| elif prefix_pos[1] > tile_pos[1]: |
| return "R_" + netname |
| else: |
| assert False, "bad TAP_DRIVE netname" |
| elif is_global(wire): |
| return "G_" + netname |
| elif dqs_ssig_re.match(wire): |
| return "DQSG_" + netname |
| elif bnk_eclk_re.match(wire): |
| if "ECLK" in tile: |
| return "G_" + netname |
| else: |
| return "BNK_" + bnk_eclk_re.match(wire).group(1) |
| elif netname in ("INRD", "LVDS"): |
| return "BNK_" + netname |
| else: |
| return None |