Change signature for normalise_name to support family-specific normalisation. Remaining code not updated.
diff --git a/util/common/nets/__init__.py b/util/common/nets/__init__.py index 845adcb..d917991 100644 --- a/util/common/nets/__init__.py +++ b/util/common/nets/__init__.py
@@ -1,3 +1,4 @@ from .general import * -from .ecp5 import * +import ecp5 +import machxo2 from .util import *
diff --git a/util/common/nets/__main__.py b/util/common/nets/__main__.py index 844e24f..e7f6206 100644 --- a/util/common/nets/__main__.py +++ b/util/common/nets/__main__.py
@@ -1,25 +1,25 @@ from nets import * -assert is_global("R2C7_HPBX0100") -assert is_global("R24C12_VPTX0700") -assert is_global("R22C40_HPRX0300") -assert is_global("R34C67_ULPCLK7") -assert not is_global("R22C67_H06E0003") -assert is_global("R24C67_VPFS0800") -assert is_global("R1C67_JPCLKT01") +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", 0) == "B1" -assert normalise_name((95, 126), "R48C26", "R48C26_HPBX0600", 0) == "G_HPBX0600" -assert normalise_name((95, 126), "R48C26", "R48C25_H02E0001", 0) == "W1_H02E0001" -assert normalise_name((95, 126), "R48C1", "R48C1_H02E0002", 0) == "W1_H02E0001" -assert normalise_name((95, 126), "R82C90", "R79C90_V06S0003", 0) == "N3_V06S0003" -assert normalise_name((95, 126), "R5C95", "R3C95_V06S0004", 0) == "N3_V06S0003" -assert normalise_name((95, 126), "R1C95", "R1C95_V06S0006", 0) == "N3_V06S0003" -assert normalise_name((95, 126), "R3C95", "R2C95_V06S0005", 0) == "N3_V06S0003" -assert normalise_name((95, 126), "R82C95", "R85C95_V06N0303", 0) == "S3_V06N0303" -assert normalise_name((95, 126), "R90C95", "R92C95_V06N0304", 0) == "S3_V06N0303" -assert normalise_name((95, 126), "R93C95", "R94C95_V06N0305", 0) == "S3_V06N0303" +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"
diff --git a/util/common/nets/ecp5.py b/util/common/nets/ecp5.py index e96ac92..0158ca8 100644 --- a/util/common/nets/ecp5.py +++ b/util/common/nets/ecp5.py
@@ -80,3 +80,25 @@ 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
diff --git a/util/common/nets/general.py b/util/common/nets/general.py index 1639919..fa649e2 100644 --- a/util/common/nets/general.py +++ b/util/common/nets/general.py
@@ -1,7 +1,7 @@ import re import tiles -from .ecp5 import * +import ecp5 # General inter-tile routing @@ -128,7 +128,7 @@ return netname, wire_pos -def normalise_name(chip_size, tile, wire, bias): +def normalise_name(chip_size, tile, wire, family): """ Wire name normalisation for tile wires and fuzzing All net names that we have access too are canonical, global names @@ -156,33 +156,34 @@ chip_size: chip size as tuple (max_row, max_col) tile: name of the relevant tile wire: full Lattice name of the wire - bias: Use 1-based column indexing + family: Device family to normalise. Affects column indexing (e.g. MachXO2 uses 1-based + column indexing) and naming of global wires, TAP_DRIVEs, DQS, bank wires, + etc. Returns the normalised netname """ + + if family == "ECP5": + def handle_family_net(tile, wire, prefix_pos, tile_pos, netname): + return ecp5.handle_family_net(tile, wire, prefix_pos, tile_pos, netname) + bias = 0 + elif family == "MachXO2": + def handle_family_net(tile, wire, prefix_pos, tile_pos, netname): + return machxo2.handle_family_net(tile, wire, prefix_pos, tile_pos, netname) + bias = 1 + else: + raise ValueError("Unknown device family.") + upos = wire.index("_") prefix = wire[:upos] prefix_pos = tiles.pos_from_name(prefix, chip_size, bias) tile_pos = tiles.pos_from_name(tile, chip_size, bias) netname = wire[upos+1:] - 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 + + family_net = handle_family_net(tile, wire, prefix_pos, tile_pos, netname) + if family_net: + return family_net + netname, prefix_pos = handle_edge_name(chip_size, tile_pos, prefix_pos, netname) if tile_pos == prefix_pos: return netname
diff --git a/util/common/nets/machxo2.py b/util/common/nets/machxo2.py new file mode 100644 index 0000000..fbfd3e2 --- /dev/null +++ b/util/common/nets/machxo2.py
@@ -0,0 +1,14 @@ +import re +import tiles + +# REGEXs for global/clock signals + +# Oscillator output +osc_clk_re = re.compile(r'R\d+C\d+_J?OSC') + +def is_global(wire): + """Return true if a wire is part of the global clock network""" + return bool(osc_clk_re.match(wire)) + +def handle_family_net(tile, wire, prefix_pos, tile_pos, netname): + raise NotImplementedError("MachXO2 device family not implemented.")