Skip to content

Commit

Permalink
Merge pull request YosysHQ#141 from cr1901/nets-refactor
Browse files Browse the repository at this point in the history
Refactor `nets` module to support more families.
  • Loading branch information
gatecat committed May 25, 2020
2 parents d476073 + b783544 commit 1e03e4e
Show file tree
Hide file tree
Showing 12 changed files with 189 additions and 158 deletions.
2 changes: 1 addition & 1 deletion fuzzers/ECP5/001-plc2_routing/fuzzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def main():
def nn_filter(net, netnames):
""" Match nets that are: in the tile according to Tcl, global nets, or span-1 nets that are accidentally
left out by Tcl"""
return net in netnames or nets.is_global(net) or span1_re.match(net)
return net in netnames or nets.ecp5.is_global(net) or span1_re.match(net)

interconnect.fuzz_interconnect(config=cfg, location=(19, 33),
netname_predicate=nn_filter,
Expand Down
2 changes: 1 addition & 1 deletion fuzzers/ECP5/030-cib_routing/fuzzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def main():
def nn_filter(net, netnames):
""" Match nets that are: in the tile according to Tcl, global nets, or span-1 nets that are accidentally
left out by Tcl"""
return ((net in netnames or span1_re.match(net)) and nets.is_cib(net)) or nets.is_global(net)
return ((net in netnames or span1_re.match(net)) and nets.is_cib(net)) or nets.ecp5.is_global(net)

def fc_filter(arc, netnames):
""" Ignore connections between two general routing nets. These are edge buffers which vary based on location
Expand Down
2 changes: 1 addition & 1 deletion fuzzers/ECP5/031-cib_lr_routing/fuzzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def main():
def nn_filter(net, netnames):
""" Match nets that are: in the tile according to Tcl, global nets, or span-1 nets that are accidentally
left out by Tcl"""
return ((net in netnames or span1_re.match(net)) and nets.is_cib(net)) or nets.is_global(net)
return ((net in netnames or span1_re.match(net)) and nets.is_cib(net)) or nets.ecp5.is_global(net)

def fc_filter(arc, netnames):
""" Ignore connections between two general routing nets. These are edge buffers which vary based on location
Expand Down
4 changes: 2 additions & 2 deletions tools/connectivity.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def get_fanin(net):
if net.startswith("G_"):
tnet = net
else:
tnet = nets.normalise_name(chip_size, tname, net, bias)
tnet = nets.normalise_name(chip_size, tname, net, c.info.family)
tdb = pytrellis.get_tile_bitdata(pytrellis.TileLocator(c.info.family, c.info.name, tinf.type))
try:
mux = tdb.get_mux_data_for_sink(tnet)
Expand All @@ -66,7 +66,7 @@ def get_fanout(net):
if net.startswith("G_"):
tnet = net
else:
tnet = nets.normalise_name(chip_size, tname, net, bias)
tnet = nets.normalise_name(chip_size, tname, net, c.info.family)
tdb = pytrellis.get_tile_bitdata(pytrellis.TileLocator(c.info.family, c.info.name, tinf.type))
for sink in tdb.get_sinks():
mux = tdb.get_mux_data_for_sink(sink)
Expand Down
6 changes: 3 additions & 3 deletions tools/demobuilder/route.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def get_arcs_downhill(self, wire):
if wire.startswith("G_"):
twire = wire
else:
twire = nets.normalise_name(self.chip_size, tname, wire, self.bias)
twire = nets.normalise_name(self.chip_size, tname, wire, self.chip.info.family)

tdb = pytrellis.get_tile_bitdata(
pytrellis.TileLocator(self.chip.info.family, self.chip.info.name, tinf.type))
Expand All @@ -74,8 +74,8 @@ def bind_arc(self, net, uphill_wire, arc, config):
else:
self.net_to_wire[net] = {dest_wire}
if configurable and not exists:
src_wirename = nets.normalise_name(self.chip_size, tile, uphill_wire, self.bias)
sink_wirename = nets.normalise_name(self.chip_size, tile, dest_wire, self.bias)
src_wirename = nets.normalise_name(self.chip_size, tile, uphill_wire, self.chip.info.family)
sink_wirename = nets.normalise_name(self.chip_size, tile, dest_wire, self.chip.info.family)
config[tile].add_arc(sink_wirename, src_wirename)

# Bind a net to a wire (used for port connections)
Expand Down
4 changes: 4 additions & 0 deletions util/common/nets/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from .general import *
import ecp5
import machxo2
from .util import *
25 changes: 25 additions & 0 deletions util/common/nets/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from nets import *

assert ecp5.is_global("R2C7_HPBX0100")
assert ecp5.is_global("R24C12_VPTX0700")
assert ecp5.is_global("R22C40_HPRX0300")
assert ecp5.is_global("R34C67_ULPCLK7")
assert not ecp5.is_global("R22C67_H06E0003")
assert ecp5.is_global("R24C67_VPFS0800")
assert ecp5.is_global("R1C67_JPCLKT01")

assert is_cib("R47C61_Q4")
assert is_cib("R47C58_H06W0003")
assert is_cib("R47C61_CLK0")

assert normalise_name((95, 126), "R48C26", "R48C26_B1", "ECP5") == "B1"
assert normalise_name((95, 126), "R48C26", "R48C26_HPBX0600", "ECP5") == "G_HPBX0600"
assert normalise_name((95, 126), "R48C26", "R48C25_H02E0001", "ECP5") == "W1_H02E0001"
assert normalise_name((95, 126), "R48C1", "R48C1_H02E0002", "ECP5") == "W1_H02E0001"
assert normalise_name((95, 126), "R82C90", "R79C90_V06S0003", "ECP5") == "N3_V06S0003"
assert normalise_name((95, 126), "R5C95", "R3C95_V06S0004", "ECP5") == "N3_V06S0003"
assert normalise_name((95, 126), "R1C95", "R1C95_V06S0006", "ECP5") == "N3_V06S0003"
assert normalise_name((95, 126), "R3C95", "R2C95_V06S0005", "ECP5") == "N3_V06S0003"
assert normalise_name((95, 126), "R82C95", "R85C95_V06N0303", "ECP5") == "S3_V06N0303"
assert normalise_name((95, 126), "R90C95", "R92C95_V06N0304", "ECP5") == "S3_V06N0303"
assert normalise_name((95, 126), "R93C95", "R94C95_V06N0305", "ECP5") == "S3_V06N0303"
104 changes: 104 additions & 0 deletions util/common/nets/ecp5.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
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

0 comments on commit 1e03e4e

Please sign in to comment.