diff options
-rw-r--r-- | ice40/arch.cc | 55 | ||||
-rw-r--r-- | ice40/arch.h | 39 | ||||
-rw-r--r-- | ice40/arch_place.cc | 2 | ||||
-rw-r--r-- | ice40/chipdb.py | 21 | ||||
-rw-r--r-- | ice40/pack.cc | 28 |
5 files changed, 88 insertions, 57 deletions
diff --git a/ice40/arch.cc b/ice40/arch.cc index 6fe77e4b..43308a52 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -110,6 +110,17 @@ Arch::Arch(ArchArgs args) : args(args) if (package_info == nullptr) log_error("Unsupported package '%s'.\n", args.package.c_str()); + for (int i = 0; i < chip_info->width; i++) { + IdString x_id = id(stringf("X%d", i)); + x_ids.push_back(x_id); + id_to_x[x_id] = i; + } + for (int i = 0; i < chip_info->height; i++) { + IdString y_id = id(stringf("Y%d", i)); + y_ids.push_back(y_id); + id_to_y[y_id] = i; + } + bel_carry.resize(chip_info->bel_data.size()); bel_to_cell.resize(chip_info->bel_data.size()); wire_to_net.resize(chip_info->wire_data.size()); @@ -196,13 +207,16 @@ IdString Arch::archArgsToId(ArchArgs args) const // ----------------------------------------------------------------------- -BelId Arch::getBelByName(IdString name) const +BelId Arch::getBelByName(IdStringList name) const { BelId ret; if (bel_by_name.empty()) { - for (size_t i = 0; i < chip_info->bel_data.size(); i++) - bel_by_name[id(chip_info->bel_data[i].name.get())] = i; + for (size_t i = 0; i < chip_info->bel_data.size(); i++) { + BelId b; + b.index = i; + bel_by_name[getBelName(b)] = i; + } } auto it = bel_by_name.find(name); @@ -357,13 +371,16 @@ bool Arch::isBelLocked(BelId bel) const // ----------------------------------------------------------------------- -WireId Arch::getWireByName(IdString name) const +WireId Arch::getWireByName(IdStringList name) const { WireId ret; if (wire_by_name.empty()) { - for (int i = 0; i < int(chip_info->wire_data.size()); i++) - wire_by_name[id(chip_info->wire_data[i].name.get())] = i; + for (int i = 0; i < int(chip_info->wire_data.size()); i++) { + WireId w; + w.index = i; + wire_by_name[getWireName(w)] = i; + } } auto it = wire_by_name.find(name); @@ -427,7 +444,7 @@ std::vector<std::pair<IdString, std::string>> Arch::getWireAttrs(WireId wire) co // ----------------------------------------------------------------------- -PipId Arch::getPipByName(IdString name) const +PipId Arch::getPipByName(IdStringList name) const { PipId ret; @@ -446,24 +463,21 @@ PipId Arch::getPipByName(IdString name) const return ret; } -IdString Arch::getPipName(PipId pip) const +IdStringList Arch::getPipName(PipId pip) const { NPNR_ASSERT(pip != PipId()); -#if 1 int x = chip_info->pip_data[pip.index].x; int y = chip_info->pip_data[pip.index].y; - std::string src_name = chip_info->wire_data[chip_info->pip_data[pip.index].src].name.get(); - std::replace(src_name.begin(), src_name.end(), '/', '.'); + auto &src_wire = chip_info->wire_data[chip_info->pip_data[pip.index].src]; + auto &dst_wire = chip_info->wire_data[chip_info->pip_data[pip.index].dst]; - std::string dst_name = chip_info->wire_data[chip_info->pip_data[pip.index].dst].name.get(); - std::replace(dst_name.begin(), dst_name.end(), '/', '.'); + std::string src_name = stringf("%d.%d.%s", int(src_wire.name_x), int(src_wire.name_y), src_wire.name.get()); + std::string dst_name = stringf("%d.%d.%s", int(dst_wire.name_x), int(dst_wire.name_y), dst_wire.name.get()); - return id("X" + std::to_string(x) + "/Y" + std::to_string(y) + "/" + src_name + ".->." + dst_name); -#else - return id(chip_info->pip_data[pip.index].name.get()); -#endif + std::array<IdString, 3> ids{x_ids.at(x), y_ids.at(y), id(src_name + ".->." + dst_name)}; + return IdStringList(ids); } IdString Arch::getPipType(PipId pip) const { return IdString(); } @@ -503,7 +517,7 @@ std::string Arch::getBelPackagePin(BelId bel) const // ----------------------------------------------------------------------- -GroupId Arch::getGroupByName(IdString name) const +GroupId Arch::getGroupByName(IdStringList name) const { for (auto g : getGroups()) if (getGroupName(g) == name) @@ -511,7 +525,7 @@ GroupId Arch::getGroupByName(IdString name) const return GroupId(); } -IdString Arch::getGroupName(GroupId group) const +IdStringList Arch::getGroupName(GroupId group) const { std::string suffix; @@ -553,7 +567,8 @@ IdString Arch::getGroupName(GroupId group) const return IdString(); } - return id("X" + std::to_string(group.x) + "/Y" + std::to_string(group.y) + "/" + suffix); + std::array<IdString, 3> ids{x_ids.at(group.x), y_ids.at(group.y), id(suffix)}; + return IdStringList(ids); } std::vector<GroupId> Arch::getGroups() const diff --git a/ice40/arch.h b/ice40/arch.h index b9934dad..1987f17a 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -91,6 +91,8 @@ NPNR_PACKED_STRUCT(struct WireInfoPOD { }; RelPtr<char> name; + int8_t name_x, name_y; + int16_t padding; RelSlice<int32_t> pips_uphill, pips_downhill; RelSlice<BelPortPOD> bel_pins; @@ -378,9 +380,9 @@ struct Arch : BaseCtx const ChipInfoPOD *chip_info; const PackageInfoPOD *package_info; - mutable std::unordered_map<IdString, int> bel_by_name; - mutable std::unordered_map<IdString, int> wire_by_name; - mutable std::unordered_map<IdString, int> pip_by_name; + mutable std::unordered_map<IdStringList, int> bel_by_name; + mutable std::unordered_map<IdStringList, int> wire_by_name; + mutable std::unordered_map<IdStringList, int> pip_by_name; mutable std::unordered_map<Loc, int> bel_by_loc; std::vector<bool> bel_carry; @@ -389,6 +391,11 @@ struct Arch : BaseCtx std::vector<NetInfo *> pip_to_net; std::vector<WireId> switches_locked; + // fast access to X and Y IdStrings for building object names + std::vector<IdString> x_ids, y_ids; + // inverse of the above for name->object mapping + std::unordered_map<IdString, int> id_to_x, id_to_y; + ArchArgs args; Arch(ArchArgs args); @@ -411,12 +418,14 @@ struct Arch : BaseCtx // ------------------------------------------------- - BelId getBelByName(IdString name) const; + BelId getBelByName(IdStringList name) const; - IdString getBelName(BelId bel) const + IdStringList getBelName(BelId bel) const { NPNR_ASSERT(bel != BelId()); - return id(chip_info->bel_data[bel.index].name.get()); + auto &data = chip_info->bel_data[bel.index]; + std::array<IdString, 3> ids{x_ids.at(data.x), y_ids.at(data.y), id(data.name.get())}; + return IdStringList(ids); } uint32_t getBelChecksum(BelId bel) const { return bel.index; } @@ -501,12 +510,14 @@ struct Arch : BaseCtx // ------------------------------------------------- - WireId getWireByName(IdString name) const; + WireId getWireByName(IdStringList name) const; - IdString getWireName(WireId wire) const + IdStringList getWireName(WireId wire) const { NPNR_ASSERT(wire != WireId()); - return id(chip_info->wire_data[wire.index].name.get()); + auto &data = chip_info->wire_data[wire.index]; + std::array<IdString, 3> ids{x_ids.at(data.name_x), y_ids.at(data.name_y), id(data.name.get())}; + return IdStringList(ids); } IdString getWireType(WireId wire) const; @@ -594,7 +605,7 @@ struct Arch : BaseCtx // ------------------------------------------------- - PipId getPipByName(IdString name) const; + PipId getPipByName(IdStringList name) const; void bindPip(PipId pip, NetInfo *net, PlaceStrength strength) { @@ -704,7 +715,7 @@ struct Arch : BaseCtx return loc; } - IdString getPipName(PipId pip) const; + IdStringList getPipName(PipId pip) const; IdString getPipType(PipId pip) const; std::vector<std::pair<IdString, std::string>> getPipAttrs(PipId pip) const; @@ -761,8 +772,8 @@ struct Arch : BaseCtx // ------------------------------------------------- - GroupId getGroupByName(IdString name) const; - IdString getGroupName(GroupId group) const; + GroupId getGroupByName(IdStringList name) const; + IdStringList getGroupName(GroupId group) const; std::vector<GroupId> getGroups() const; std::vector<BelId> getGroupBels(GroupId group) const; std::vector<WireId> getGroupWires(GroupId group) const; @@ -896,7 +907,7 @@ struct Arch : BaseCtx int getDrivenGlobalNetwork(BelId bel) const { NPNR_ASSERT(getBelType(bel) == id_SB_GB); - IdString glb_net = getWireName(getBelPinWire(bel, id_GLOBAL_BUFFER_OUTPUT)); + IdString glb_net = getWireName(getBelPinWire(bel, id_GLOBAL_BUFFER_OUTPUT))[2]; return std::stoi(std::string("") + glb_net.str(this).back()); } diff --git a/ice40/arch_place.cc b/ice40/arch_place.cc index ede8d47f..e4f302fd 100644 --- a/ice40/arch_place.cc +++ b/ice40/arch_place.cc @@ -142,7 +142,7 @@ bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const break; // Are we perhaps a PAD INPUT Bel that can be placed here? - if (pll_cell->attrs[id("BEL_PAD_INPUT")] == getBelName(bel).str(this)) + if (pll_cell->attrs[id("BEL_PAD_INPUT")] == getBelName(bel).str(getCtx())) return true; // Conflict diff --git a/ice40/chipdb.py b/ice40/chipdb.py index b7c28ae3..cc3397eb 100644 --- a/ice40/chipdb.py +++ b/ice40/chipdb.py @@ -778,7 +778,7 @@ def add_bel_output(bel, wire, port): def add_bel_lc(x, y, z): bel = len(bel_name) - bel_name.append("X%d/Y%d/lc%d" % (x, y, z)) + bel_name.append((x, y, "lc%d" % z)) bel_type.append("ICESTORM_LC") bel_pos.append((x, y, z)) bel_wires.append(list()) @@ -837,7 +837,7 @@ def add_bel_lc(x, y, z): def add_bel_io(x, y, z): bel = len(bel_name) - bel_name.append("X%d/Y%d/io%d" % (x, y, z)) + bel_name.append((x, y, "io%d" % z)) bel_type.append("SB_IO") bel_pos.append((x, y, z)) bel_wires.append(list()) @@ -871,7 +871,7 @@ def add_bel_io(x, y, z): def add_bel_ram(x, y): bel = len(bel_name) - bel_name.append("X%d/Y%d/ram" % (x, y)) + bel_name.append((x, y, "ram")) bel_type.append("ICESTORM_RAM") bel_pos.append((x, y, 0)) bel_wires.append(list()) @@ -905,7 +905,7 @@ def add_bel_gb(xy, x, y, g): return bel = len(bel_name) - bel_name.append("X%d/Y%d/gb" % (x, y)) + bel_name.append((x, y, "gb")) bel_type.append("SB_GB") bel_pos.append((x, y, 2)) bel_wires.append(list()) @@ -942,7 +942,7 @@ def add_bel_ec(ec): ectype, x, y, z = ec bel = len(bel_name) extra_cell_config[bel] = [] - bel_name.append("X%d/Y%d/%s_%d" % (x, y, ectype.lower(), z)) + bel_name.append((x, y, "%s_%d" % (ectype.lower(), z))) bel_type.append(ectype) bel_pos.append((x, y, z)) bel_wires.append(list()) @@ -1140,7 +1140,7 @@ for bel in range(len(bel_name)): bba.l("bel_data_%s" % dev_name, "BelInfoPOD") for bel in range(len(bel_name)): - bba.s(bel_name[bel], "name") + bba.s(bel_name[bel][-1], "name") bba.u32(constids[bel_type[bel]], "type") bba.r_slice("bel_wires_%d" % bel, len(bel_wires[bel]), "bel_wires") bba.u8(bel_pos[bel][0], "x") @@ -1215,7 +1215,9 @@ for wire in range(num_wires): num_bel_pins = 0 info = dict() - info["name"] = "X%d/Y%d/%s" % wire_names_r[wire] + info["name"] = wire_names_r[wire][2] + info["name_x"] = wire_names_r[wire][0] + info["name_y"] = wire_names_r[wire][1] info["num_uphill"] = num_uphill info["list_uphill"] = list_uphill @@ -1263,7 +1265,7 @@ for package in packages: pins_info = [] for pin in pins: pinname, x, y, z = pin - pin_bel = "X%d/Y%d/io%d" % (x, y, z) + pin_bel = (x, y, "io%d" % z) bel_idx = bel_name.index(pin_bel) pins_info.append((pinname, bel_idx)) bba.l("package_%s_pins" % safename, "PackagePinPOD") @@ -1311,6 +1313,9 @@ for t in range(num_tile_types): bba.l("wire_data_%s" % dev_name, "WireInfoPOD") for wire, info in enumerate(wireinfo): bba.s(info["name"], "name") + bba.u8(info["name_x"], "name_x") + bba.u8(info["name_y"], "name_y") + bba.u16(0, "padding") bba.r_slice(info["list_uphill"], info["num_uphill"], "pips_uphill") bba.r_slice(info["list_downhill"], info["num_downhill"], "pips_downhill") bba.r_slice(info["list_bel_pins"], info["num_bel_pins"], "bel_pins") diff --git a/ice40/pack.cc b/ice40/pack.cc index 9add84cd..a909b08b 100644 --- a/ice40/pack.cc +++ b/ice40/pack.cc @@ -435,7 +435,7 @@ static std::unique_ptr<CellInfo> create_padin_gbuf(Context *ctx, CellInfo *cell, // Find the matching SB_GB BEL connected to the same global network if (!cell->attrs.count(ctx->id("BEL"))) log_error("Unconstrained SB_GB_IO %s is not supported.\n", ctx->nameOf(cell)); - BelId bel = ctx->getBelByName(ctx->id(cell->attrs[ctx->id("BEL")].as_string())); + BelId bel = ctx->getBelByNameStr(cell->attrs[ctx->id("BEL")].as_string()); BelId gb_bel = find_padin_gbuf(ctx, bel, port_name); NPNR_ASSERT(gb_bel != BelId()); @@ -666,7 +666,7 @@ static void promote_globals(Context *ctx) /* And possibly limits what we can promote */ if (cell.second->attrs.find(ctx->id("BEL")) != cell.second->attrs.end()) { /* If the SB_GB is locked, doesn't matter what it drives */ - BelId bel = ctx->getBelByName(ctx->id(cell.second->attrs[ctx->id("BEL")].as_string())); + BelId bel = ctx->getBelByNameStr(cell.second->attrs[ctx->id("BEL")].as_string()); int glb_id = ctx->getDrivenGlobalNetwork(bel); if ((glb_id % 2) == 0) resets_available--; @@ -785,7 +785,7 @@ static void place_plls(Context *ctx) // If it's constrained already, add to already used list if (ci->attrs.count(ctx->id("BEL"))) { - BelId bel_constrain = ctx->getBelByName(ctx->id(ci->attrs[ctx->id("BEL")].as_string())); + BelId bel_constrain = ctx->getBelByNameStr(ci->attrs[ctx->id("BEL")].as_string()); if (pll_all_bels.count(bel_constrain) == 0) log_error("PLL '%s' is constrained to invalid BEL '%s'\n", ci->name.c_str(ctx), ci->attrs[ctx->id("BEL")].as_string().c_str()); @@ -820,7 +820,7 @@ static void place_plls(Context *ctx) log_error("PLL '%s' PACKAGEPIN SB_IO '%s' is unconstrained\n", ci->name.c_str(ctx), io_cell->name.c_str(ctx)); - BelId io_bel = ctx->getBelByName(ctx->id(io_cell->attrs.at(ctx->id("BEL")).as_string())); + BelId io_bel = ctx->getBelByNameStr(io_cell->attrs.at(ctx->id("BEL")).as_string()); BelId found_bel; // Find the PLL BEL that would suit that connection @@ -845,7 +845,7 @@ static void place_plls(Context *ctx) // Is it user constrained ? if (ci->attrs.count(ctx->id("BEL"))) { // Yes. Check it actually matches ! - BelId bel_constrain = ctx->getBelByName(ctx->id(ci->attrs[ctx->id("BEL")].as_string())); + BelId bel_constrain = ctx->getBelByNameStr(ci->attrs[ctx->id("BEL")].as_string()); if (bel_constrain != found_bel) log_error("PLL '%s' is user constrained to %s but can only be placed in %s based on its PACKAGEPIN " "connection\n", @@ -857,7 +857,7 @@ static void place_plls(Context *ctx) } // Inform user - log_info(" constrained PLL '%s' to %s\n", ci->name.c_str(ctx), ctx->getBelName(found_bel).c_str(ctx)); + log_info(" constrained PLL '%s' to %s\n", ci->name.c_str(ctx), ctx->nameOfBel(found_bel)); } // Scan all SB_IOs to check for conflict with PLL BELs @@ -875,7 +875,7 @@ static void place_plls(Context *ctx) continue; // Check all placed PLL (either forced by user, or forced by PACKAGEPIN) - BelId io_bel = ctx->getBelByName(ctx->id(io_ci->attrs[ctx->id("BEL")].as_string())); + BelId io_bel = ctx->getBelByNameStr(io_ci->attrs[ctx->id("BEL")].as_string()); for (auto placed_pll : pll_used_bels) { BelPin pll_io_a, pll_io_b; @@ -909,7 +909,7 @@ static void place_plls(Context *ctx) continue; // Check all placed PLL (either forced by user, or forced by PACKAGEPIN) - BelId gb_bel = ctx->getBelByName(ctx->id(gb_ci->attrs[ctx->id("BEL")].as_string())); + BelId gb_bel = ctx->getBelByNameStr(gb_ci->attrs[ctx->id("BEL")].as_string()); for (auto placed_pll : pll_used_bels) { CellInfo *ci = placed_pll.second; @@ -968,7 +968,7 @@ static void place_plls(Context *ctx) bool could_be_pad = false; BelId pad_bel; if (ni->users.size() == 1 && is_sb_io(ctx, ni->driver.cell) && ni->driver.cell->attrs.count(ctx->id("BEL"))) - pad_bel = ctx->getBelByName(ctx->id(ni->driver.cell->attrs[ctx->id("BEL")].as_string())); + pad_bel = ctx->getBelByNameStr(ni->driver.cell->attrs[ctx->id("BEL")].as_string()); // Find a BEL for it BelId found_bel; @@ -1066,9 +1066,9 @@ static BelId cell_place_unique(Context *ctx, CellInfo *ci) continue; if (ctx->isBelLocked(bel)) continue; - IdString bel_name = ctx->getBelName(bel); + IdStringList bel_name = ctx->getBelName(bel); ci->attrs[ctx->id("BEL")] = bel_name.str(ctx); - log_info(" constrained %s '%s' to %s\n", ci->type.c_str(ctx), ci->name.c_str(ctx), bel_name.c_str(ctx)); + log_info(" constrained %s '%s' to %s\n", ci->type.c_str(ctx), ci->name.c_str(ctx), ctx->nameOfBel(bel)); return bel; } log_error("Unable to place cell '%s' of type '%s'\n", ci->name.c_str(ctx), ci->type.c_str(ctx)); @@ -1278,9 +1278,9 @@ static void pack_special(Context *ctx) if (bel == BelId() || ctx->getBelType(bel) != ci->type) log_error("Unable to find placement for cell '%s' of type '%s'\n", ci->name.c_str(ctx), ci->type.c_str(ctx)); - IdString bel_name = ctx->getBelName(bel); + IdStringList bel_name = ctx->getBelName(bel); ci->attrs[ctx->id("BEL")] = bel_name.str(ctx); - log_info(" constrained %s '%s' to %s\n", ci->type.c_str(ctx), ci->name.c_str(ctx), bel_name.c_str(ctx)); + log_info(" constrained %s '%s' to %s\n", ci->type.c_str(ctx), ci->name.c_str(ctx), ctx->nameOfBel(bel)); } } @@ -1497,7 +1497,7 @@ void pack_plls(Context *ctx) } constr_fail: // PLL must have been placed already in place_plls() - BelId pll_bel = ctx->getBelByName(ctx->id(packed->attrs[ctx->id("BEL")].as_string())); + BelId pll_bel = ctx->getBelByNameStr(packed->attrs[ctx->id("BEL")].as_string()); NPNR_ASSERT(pll_bel != BelId()); // Deal with PAD PLL peculiarities |