blob: d332428097c211e7d2c5eafb9cf6d030a5d52ec6 [file] [log] [blame]
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