From 3fc5455ec5fdaef0df0b01115e1ee0f9c9af8892 Mon Sep 17 00:00:00 2001 From: "D. Shah" Date: Wed, 27 Jan 2021 19:39:19 +0000 Subject: ecp5: Switch from RelPtr to RelSlice This replaces RelPtrs and a separate length field with a Rust-style slice containing both a pointer and a length; with bounds checking always enforced. Thus iterating over these structures is both cleaner and safer. Signed-off-by: D. Shah --- ecp5/arch.cc | 120 +++++++++++++++++++++-------------------------- ecp5/arch.h | 123 +++++++++++++++++++++++++------------------------ ecp5/trellis_import.py | 65 +++++++++++--------------- 3 files changed, 143 insertions(+), 165 deletions(-) diff --git a/ecp5/arch.cc b/ecp5/arch.cc index 99ff59f7..8ebb7425 100644 --- a/ecp5/arch.cc +++ b/ecp5/arch.cc @@ -87,8 +87,8 @@ std::vector Arch::getSupportedPackages(ArchArgs::ArchArgsTypes chip { const ChipInfoPOD *chip_info = get_chip_info(chip); std::vector packages; - for (int i = 0; i < chip_info->num_packages; i++) - packages.push_back(chip_info->package_info[i].name.get()); + for (auto &pkg : chip_info->package_info) + packages.push_back(pkg.name.get()); return packages; } @@ -104,9 +104,9 @@ Arch::Arch(ArchArgs args) : args(args) "maintainer)!\n"); package_info = nullptr; - for (int i = 0; i < chip_info->num_packages; i++) { - if (args.package == chip_info->package_info[i].name.get()) { - package_info = &(chip_info->package_info[i]); + for (auto &pkg : chip_info->package_info) { + if (args.package == pkg.name.get()) { + package_info = &pkg; break; } } @@ -207,7 +207,7 @@ BelId Arch::getBelByName(IdString name) const std::tie(loc.x, loc.y, basename) = split_identifier_name(name.str(this)); ret.location = loc; const LocationTypePOD *loci = locInfo(ret); - for (int i = 0; i < loci->num_bels; i++) { + for (int i = 0; i < int(loci->bel_data.size()); i++) { if (std::strcmp(loci->bel_data[i].name.get(), basename.c_str()) == 0) { ret.index = i; break; @@ -225,7 +225,7 @@ BelRange Arch::getBelsByTile(int x, int y) const br.b.cursor_tile = y * chip_info->width + x; br.e.cursor_tile = y * chip_info->width + x; br.b.cursor_index = 0; - br.e.cursor_index = chip_info->locations[chip_info->location_type[br.b.cursor_tile]].num_bels - 1; + br.e.cursor_index = int(chip_info->locations[chip_info->location_type[br.b.cursor_tile]].bel_data.size()) - 1; br.b.chip = chip_info; br.e.chip = chip_info; if (br.e.cursor_index == -1) @@ -241,12 +241,10 @@ WireId Arch::getBelPinWire(BelId bel, IdString pin) const NPNR_ASSERT(bel != BelId()); - int num_bel_wires = locInfo(bel)->bel_data[bel.index].num_bel_wires; - const BelWirePOD *bel_wires = locInfo(bel)->bel_data[bel.index].bel_wires.get(); - for (int i = 0; i < num_bel_wires; i++) - if (bel_wires[i].port == pin.index) { - ret.location = bel.location + bel_wires[i].rel_wire_loc; - ret.index = bel_wires[i].wire_index; + for (auto &bw : locInfo(bel)->bel_data[bel.index].bel_wires) + if (bw.port == pin.index) { + ret.location = bel.location + bw.rel_wire_loc; + ret.index = bw.wire_index; break; } @@ -257,12 +255,9 @@ PortType Arch::getBelPinType(BelId bel, IdString pin) const { NPNR_ASSERT(bel != BelId()); - int num_bel_wires = locInfo(bel)->bel_data[bel.index].num_bel_wires; - const BelWirePOD *bel_wires = locInfo(bel)->bel_data[bel.index].bel_wires.get(); - - for (int i = 0; i < num_bel_wires; i++) - if (bel_wires[i].port == pin.index) - return PortType(bel_wires[i].type); + for (auto &bw : locInfo(bel)->bel_data[bel.index].bel_wires) + if (bw.port == pin.index) + return PortType(bw.type); return PORT_INOUT; } @@ -281,7 +276,7 @@ WireId Arch::getWireByName(IdString name) const std::tie(loc.x, loc.y, basename) = split_identifier_name(name.str(this)); ret.location = loc; const LocationTypePOD *loci = locInfo(ret); - for (int i = 0; i < loci->num_wires; i++) { + for (int i = 0; i < int(loci->wire_data.size()); i++) { if (std::strcmp(loci->wire_data[i].name.get(), basename.c_str()) == 0) { ret.index = i; ret.location = loc; @@ -309,7 +304,7 @@ PipId Arch::getPipByName(IdString name) const std::tie(loc.x, loc.y, basename) = split_identifier_name(name.str(this)); ret.location = loc; const LocationTypePOD *loci = locInfo(ret); - for (int i = 0; i < loci->num_pips; i++) { + for (int i = 0; i < int(loci->pip_data.size()); i++) { PipId curr; curr.location = loc; curr.index = i; @@ -340,11 +335,11 @@ IdString Arch::getPipName(PipId pip) const BelId Arch::getPackagePinBel(const std::string &pin) const { - for (int i = 0; i < package_info->num_pins; i++) { - if (package_info->pin_data[i].name.get() == pin) { + for (auto &ppin : package_info->pin_data) { + if (ppin.name.get() == pin) { BelId bel; - bel.location = package_info->pin_data[i].abs_loc; - bel.index = package_info->pin_data[i].bel_index; + bel.location = ppin.abs_loc; + bel.index = ppin.bel_index; return bel; } } @@ -353,10 +348,9 @@ BelId Arch::getPackagePinBel(const std::string &pin) const std::string Arch::getBelPackagePin(BelId bel) const { - for (int i = 0; i < package_info->num_pins; i++) { - if (Location(package_info->pin_data[i].abs_loc) == bel.location && - package_info->pin_data[i].bel_index == bel.index) { - return package_info->pin_data[i].name.get(); + for (auto &ppin : package_info->pin_data) { + if (Location(ppin.abs_loc) == bel.location && ppin.bel_index == bel.index) { + return ppin.name.get(); } } return ""; @@ -364,9 +358,9 @@ std::string Arch::getBelPackagePin(BelId bel) const int Arch::getPioBelBank(BelId bel) const { - for (int i = 0; i < chip_info->num_pios; i++) { - if (Location(chip_info->pio_info[i].abs_loc) == bel.location && chip_info->pio_info[i].bel_index == bel.index) { - return chip_info->pio_info[i].bank; + for (auto &pio : chip_info->pio_info) { + if (Location(pio.abs_loc) == bel.location && pio.bel_index == bel.index) { + return pio.bank; } } NPNR_ASSERT_FALSE("failed to find PIO"); @@ -374,9 +368,9 @@ int Arch::getPioBelBank(BelId bel) const std::string Arch::getPioFunctionName(BelId bel) const { - for (int i = 0; i < chip_info->num_pios; i++) { - if (Location(chip_info->pio_info[i].abs_loc) == bel.location && chip_info->pio_info[i].bel_index == bel.index) { - const char *func = chip_info->pio_info[i].function_name.get(); + for (auto &pio : chip_info->pio_info) { + if (Location(pio.abs_loc) == bel.location && pio.bel_index == bel.index) { + const char *func = pio.function_name.get(); if (func == nullptr) return ""; else @@ -388,12 +382,12 @@ std::string Arch::getPioFunctionName(BelId bel) const BelId Arch::getPioByFunctionName(const std::string &name) const { - for (int i = 0; i < chip_info->num_pios; i++) { - const char *func = chip_info->pio_info[i].function_name.get(); + for (auto &pio : chip_info->pio_info) { + const char *func = pio.function_name.get(); if (func != nullptr && func == name) { BelId bel; - bel.location = chip_info->pio_info[i].abs_loc; - bel.index = chip_info->pio_info[i].bel_index; + bel.location = pio.abs_loc; + bel.index = pio.bel_index; return bel; } } @@ -405,12 +399,9 @@ std::vector Arch::getBelPins(BelId bel) const std::vector ret; NPNR_ASSERT(bel != BelId()); - int num_bel_wires = locInfo(bel)->bel_data[bel.index].num_bel_wires; - const BelWirePOD *bel_wires = locInfo(bel)->bel_data[bel.index].bel_wires.get(); - - for (int i = 0; i < num_bel_wires; i++) { + for (auto &bw : locInfo(bel)->bel_data[bel.index].bel_wires) { IdString id; - id.index = bel_wires[i].port; + id.index = bw.port; ret.push_back(id); } @@ -422,7 +413,7 @@ BelId Arch::getBelByLocation(Loc loc) const if (loc.x >= chip_info->width || loc.y >= chip_info->height) return BelId(); const LocationTypePOD &locI = chip_info->locations[chip_info->location_type[loc.y * chip_info->width + loc.x]]; - for (int i = 0; i < locI.num_bels; i++) { + for (int i = 0; i < int(locI.bel_data.size()); i++) { if (locI.bel_data[i].z == loc.z) { BelId bi; bi.location.x = loc.x; @@ -438,7 +429,7 @@ BelId Arch::getBelByLocation(Loc loc) const delay_t Arch::estimateDelay(WireId src, WireId dst) const { - int num_uh = locInfo(dst)->wire_data[dst.index].num_uphill; + int num_uh = locInfo(dst)->wire_data[dst.index].pips_uphill.size(); if (num_uh < 6) { for (auto uh : getPipsUphill(dst)) { if (getPipSrcWire(uh) == src) @@ -451,13 +442,13 @@ delay_t Arch::estimateDelay(WireId src, WireId dst) const if (w == gsrclk_wire) { auto phys_wire = getPipSrcWire(*(getPipsUphill(w).begin())); return std::make_pair(int(phys_wire.location.x), int(phys_wire.location.y)); - } else if (wire.num_bel_pins > 0) { + } else if (wire.bel_pins.size() > 0) { return std::make_pair(w.location.x + wire.bel_pins[0].rel_bel_loc.x, w.location.y + wire.bel_pins[0].rel_bel_loc.y); - } else if (wire.num_downhill > 0) { + } else if (wire.pips_downhill.size() > 0) { return std::make_pair(w.location.x + wire.pips_downhill[0].rel_loc.x, w.location.y + wire.pips_downhill[0].rel_loc.y); - } else if (wire.num_uphill > 0) { + } else if (wire.pips_uphill.size() > 0) { return std::make_pair(w.location.x + wire.pips_uphill[0].rel_loc.x, w.location.y + wire.pips_uphill[0].rel_loc.y); } else { @@ -500,13 +491,13 @@ ArcBounds Arch::getRouteBoundingBox(WireId src, WireId dst) const if (w == gsrclk_wire) { auto phys_wire = getPipSrcWire(*(getPipsUphill(w).begin())); return std::make_pair(int(phys_wire.location.x), int(phys_wire.location.y)); - } else if (wire.num_bel_pins > 0) { + } else if (wire.bel_pins.size() > 0) { return std::make_pair(w.location.x + wire.bel_pins[0].rel_bel_loc.x, w.location.y + wire.bel_pins[0].rel_bel_loc.y); - } else if (wire.num_downhill > 0) { + } else if (wire.pips_downhill.size() > 0) { return std::make_pair(w.location.x + wire.pips_downhill[0].rel_loc.x, w.location.y + wire.pips_downhill[0].rel_loc.y); - } else if (wire.num_uphill > 0) { + } else if (wire.pips_uphill.size() > 0) { return std::make_pair(w.location.x + wire.pips_uphill[0].rel_loc.x, w.location.y + wire.pips_uphill[0].rel_loc.y); } else { @@ -763,11 +754,9 @@ bool Arch::getDelayFromTimingDatabase(IdString tctype, IdString from, IdString t delay = fnd_dk->second.second; return fnd_dk->second.first; } - for (int i = 0; i < speed_grade->num_cell_timings; i++) { - const auto &tc = speed_grade->cell_timings[i]; + for (auto &tc : speed_grade->cell_timings) { if (tc.cell_type == tctype.index) { - for (int j = 0; j < tc.num_prop_delays; j++) { - const auto &dly = tc.prop_delays[j]; + for (auto &dly : tc.prop_delays) { if (dly.from_port == from.index && dly.to_port == to.index) { delay.max_delay = dly.max_delay; delay.min_delay = dly.min_delay; @@ -785,11 +774,9 @@ bool Arch::getDelayFromTimingDatabase(IdString tctype, IdString from, IdString t void Arch::getSetupHoldFromTimingDatabase(IdString tctype, IdString clock, IdString port, DelayInfo &setup, DelayInfo &hold) const { - for (int i = 0; i < speed_grade->num_cell_timings; i++) { - const auto &tc = speed_grade->cell_timings[i]; + for (auto &tc : speed_grade->cell_timings) { if (tc.cell_type == tctype.index) { - for (int j = 0; j < tc.num_setup_holds; j++) { - const auto &sh = tc.setup_holds[j]; + for (auto &sh : tc.setup_holds) { if (sh.clock_port == clock.index && sh.sig_port == port.index) { setup.max_delay = sh.max_setup; setup.min_delay = sh.min_setup; @@ -1165,9 +1152,8 @@ std::vector> Arch::getTilesAtLocation(int ro { std::vector> ret; auto &tileloc = chip_info->tile_info[row * chip_info->width + col]; - for (int i = 0; i < tileloc.num_tiles; i++) { - ret.push_back(std::make_pair(tileloc.tile_names[i].name.get(), - chip_info->tiletype_names[tileloc.tile_names[i].type_idx].get())); + for (auto &tn : tileloc.tile_names) { + ret.push_back(std::make_pair(tn.name.get(), chip_info->tiletype_names[tn.type_idx].get())); } return ret; } @@ -1180,9 +1166,9 @@ GlobalInfoPOD Arch::globalInfoAtLoc(Location loc) bool Arch::getPIODQSGroup(BelId pio, bool &dqsright, int &dqsrow) { - for (int i = 0; i < chip_info->num_pios; i++) { - if (Location(chip_info->pio_info[i].abs_loc) == pio.location && chip_info->pio_info[i].bel_index == pio.index) { - int dqs = chip_info->pio_info[i].dqsgroup; + for (auto &ppio : chip_info->pio_info) { + if (Location(ppio.abs_loc) == pio.location && ppio.bel_index == pio.index) { + int dqs = ppio.dqsgroup; if (dqs == -1) return false; else { @@ -1200,7 +1186,7 @@ BelId Arch::getDQSBUF(bool dqsright, int dqsrow) BelId bel; bel.location.y = dqsrow; bel.location.x = (dqsright ? (chip_info->width - 1) : 0); - for (int i = 0; i < locInfo(bel)->num_bels; i++) { + for (int i = 0; i < int(locInfo(bel)->bel_data.size()); i++) { auto &bd = locInfo(bel)->bel_data[i]; if (bd.type == id_DQSBUFM.index) { bel.index = i; diff --git a/ecp5/arch.h b/ecp5/arch.h index 32dc31d6..458ff935 100644 --- a/ecp5/arch.h +++ b/ecp5/arch.h @@ -33,11 +33,6 @@ template struct RelPtr { int32_t offset; - // void set(const T *ptr) { - // offset = reinterpret_cast(ptr) - - // reinterpret_cast(this); - // } - const T *get() const { return reinterpret_cast(reinterpret_cast(this) + offset); } const T &operator[](size_t index) const { return get()[index]; } @@ -50,6 +45,28 @@ template struct RelPtr RelPtr &operator=(const RelPtr &) = delete; }; +NPNR_PACKED_STRUCT(template struct RelSlice { + int32_t offset; + uint32_t length; + + const T *get() const { return reinterpret_cast(reinterpret_cast(this) + offset); } + + const T &operator[](size_t index) const + { + NPNR_ASSERT(index < length); + return get()[index]; + } + + const T *begin() const { return get(); } + const T *end() const { return get() + length; } + + const size_t size() const { return length; } + + const T &operator*() const { return *(get()); } + + const T *operator->() const { return get(); } +}); + NPNR_PACKED_STRUCT(struct BelWirePOD { LocationPOD rel_wire_loc; int32_t wire_index; @@ -61,8 +78,7 @@ NPNR_PACKED_STRUCT(struct BelInfoPOD { RelPtr name; int32_t type; int32_t z; - int32_t num_bel_wires; - RelPtr bel_wires; + RelSlice bel_wires; }); NPNR_PACKED_STRUCT(struct BelPortPOD { @@ -89,18 +105,14 @@ NPNR_PACKED_STRUCT(struct WireInfoPOD { RelPtr name; int32_t type; int32_t tile_wire; - int32_t num_uphill, num_downhill; - RelPtr pips_uphill, pips_downhill; - - int32_t num_bel_pins; - RelPtr bel_pins; + RelSlice pips_uphill, pips_downhill; + RelSlice bel_pins; }); NPNR_PACKED_STRUCT(struct LocationTypePOD { - int32_t num_bels, num_wires, num_pips; - RelPtr bel_data; - RelPtr wire_data; - RelPtr pip_data; + RelSlice bel_data; + RelSlice wire_data; + RelSlice pip_data; }); NPNR_PACKED_STRUCT(struct PIOInfoPOD { @@ -119,8 +131,7 @@ NPNR_PACKED_STRUCT(struct PackagePinPOD { NPNR_PACKED_STRUCT(struct PackageInfoPOD { RelPtr name; - int32_t num_pins; - RelPtr pin_data; + RelSlice pin_data; }); NPNR_PACKED_STRUCT(struct TileNamePOD { @@ -129,10 +140,7 @@ NPNR_PACKED_STRUCT(struct TileNamePOD { int16_t padding; }); -NPNR_PACKED_STRUCT(struct TileInfoPOD { - int32_t num_tiles; - RelPtr tile_names; -}); +NPNR_PACKED_STRUCT(struct TileInfoPOD { RelSlice tile_names; }); enum TapDirection : int8_t { @@ -174,10 +182,8 @@ NPNR_PACKED_STRUCT(struct CellSetupHoldPOD { NPNR_PACKED_STRUCT(struct CellTimingPOD { int32_t cell_type; - int32_t num_prop_delays; - int32_t num_setup_holds; - RelPtr prop_delays; - RelPtr setup_holds; + RelSlice prop_delays; + RelSlice setup_holds; }); NPNR_PACKED_STRUCT(struct PipDelayPOD { @@ -188,26 +194,22 @@ NPNR_PACKED_STRUCT(struct PipDelayPOD { }); NPNR_PACKED_STRUCT(struct SpeedGradePOD { - int32_t num_cell_timings; - int32_t num_pip_classes; - RelPtr cell_timings; - RelPtr pip_classes; + RelSlice cell_timings; + RelSlice pip_classes; }); NPNR_PACKED_STRUCT(struct ChipInfoPOD { int32_t width, height; int32_t num_tiles; - int32_t num_location_types; - int32_t num_packages, num_pios; int32_t const_id_count; - RelPtr locations; - RelPtr location_type; - RelPtr location_glbinfo; - RelPtr> tiletype_names; - RelPtr package_info; - RelPtr pio_info; - RelPtr tile_info; - RelPtr speed_grades; + RelSlice locations; + RelSlice location_type; + RelSlice location_glbinfo; + RelSlice> tiletype_names; + RelSlice package_info; + RelSlice pio_info; + RelSlice tile_info; + RelSlice speed_grades; }); /************************ End of chipdb section. ************************/ @@ -222,7 +224,7 @@ struct BelIterator { cursor_index++; while (cursor_tile < chip->num_tiles && - cursor_index >= chip->locations[chip->location_type[cursor_tile]].num_bels) { + cursor_index >= int(chip->locations[chip->location_type[cursor_tile]].bel_data.size())) { cursor_index = 0; cursor_tile++; } @@ -300,7 +302,7 @@ struct WireIterator { cursor_index++; while (cursor_tile < chip->num_tiles && - cursor_index >= chip->locations[chip->location_type[cursor_tile]].num_wires) { + cursor_index >= int(chip->locations[chip->location_type[cursor_tile]].wire_data.size())) { cursor_index = 0; cursor_tile++; } @@ -352,7 +354,7 @@ struct AllPipIterator { cursor_index++; while (cursor_tile < chip->num_tiles && - cursor_index >= chip->locations[chip->location_type[cursor_tile]].num_pips) { + cursor_index >= int(chip->locations[chip->location_type[cursor_tile]].pip_data.size())) { cursor_index = 0; cursor_tile++; } @@ -617,9 +619,9 @@ struct Arch : BaseCtx { BelPinRange range; NPNR_ASSERT(wire != WireId()); - range.b.ptr = locInfo(wire)->wire_data[wire.index].bel_pins.get(); + range.b.ptr = locInfo(wire)->wire_data[wire.index].bel_pins.begin(); range.b.wire_loc = wire.location; - range.e.ptr = range.b.ptr + locInfo(wire)->wire_data[wire.index].num_bel_pins; + range.e.ptr = locInfo(wire)->wire_data[wire.index].bel_pins.end(); range.e.wire_loc = wire.location; return range; } @@ -735,7 +737,7 @@ struct Arch : BaseCtx { WireId wireId; wireId.location = loc; - for (int i = 0; i < locInfo(wireId)->num_wires; i++) { + for (int i = 0; i < int(locInfo(wireId)->wire_data.size()); i++) { if (locInfo(wireId)->wire_data[i].name.get() == basename) { wireId.index = i; return wireId; @@ -857,7 +859,6 @@ struct Arch : BaseCtx auto fnd_fanout = wire_fanout.find(getPipSrcWire(pip)); if (fnd_fanout != wire_fanout.end()) fanout = fnd_fanout->second; - NPNR_ASSERT(locInfo(pip)->pip_data[pip.index].timing_class < speed_grade->num_pip_classes); delay.min_delay = speed_grade->pip_classes[locInfo(pip)->pip_data[pip.index].timing_class].min_base_delay + fanout * speed_grade->pip_classes[locInfo(pip)->pip_data[pip.index].timing_class].min_fanout_adder; @@ -873,7 +874,7 @@ struct Arch : BaseCtx NPNR_ASSERT(wire != WireId()); range.b.cursor = locInfo(wire)->wire_data[wire.index].pips_downhill.get(); range.b.wire_loc = wire.location; - range.e.cursor = range.b.cursor + locInfo(wire)->wire_data[wire.index].num_downhill; + range.e.cursor = range.b.cursor + locInfo(wire)->wire_data[wire.index].pips_downhill.size(); range.e.wire_loc = wire.location; return range; } @@ -884,7 +885,7 @@ struct Arch : BaseCtx NPNR_ASSERT(wire != WireId()); range.b.cursor = locInfo(wire)->wire_data[wire.index].pips_uphill.get(); range.b.wire_loc = wire.location; - range.e.cursor = range.b.cursor + locInfo(wire)->wire_data[wire.index].num_uphill; + range.e.cursor = range.b.cursor + locInfo(wire)->wire_data[wire.index].pips_uphill.size(); range.e.wire_loc = wire.location; return range; } @@ -892,9 +893,9 @@ struct Arch : BaseCtx std::string getPipTilename(PipId pip) const { auto &tileloc = chip_info->tile_info[pip.location.y * chip_info->width + pip.location.x]; - for (int i = 0; i < tileloc.num_tiles; i++) { - if (tileloc.tile_names[i].type_idx == locInfo(pip)->pip_data[pip.index].tile_type) - return tileloc.tile_names[i].name.get(); + for (auto &tn : tileloc.tile_names) { + if (tn.type_idx == locInfo(pip)->pip_data[pip.index].tile_type) + return tn.name.get(); } NPNR_ASSERT_FALSE("failed to find Pip tile"); } @@ -999,9 +1000,9 @@ struct Arch : BaseCtx std::string getTileByTypeAndLocation(int row, int col, std::string type) const { auto &tileloc = chip_info->tile_info[row * chip_info->width + col]; - for (int i = 0; i < tileloc.num_tiles; i++) { - if (chip_info->tiletype_names[tileloc.tile_names[i].type_idx].get() == type) - return tileloc.tile_names[i].name.get(); + for (auto &tn : tileloc.tile_names) { + if (chip_info->tiletype_names[tn.type_idx].get() == type) + return tn.name.get(); } NPNR_ASSERT_FALSE_STR("no tile at (" + std::to_string(col) + ", " + std::to_string(row) + ") with type " + type); @@ -1010,9 +1011,9 @@ struct Arch : BaseCtx std::string getTileByTypeAndLocation(int row, int col, const std::set &type) const { auto &tileloc = chip_info->tile_info[row * chip_info->width + col]; - for (int i = 0; i < tileloc.num_tiles; i++) { - if (type.count(chip_info->tiletype_names[tileloc.tile_names[i].type_idx].get())) - return tileloc.tile_names[i].name.get(); + for (auto &tn : tileloc.tile_names) { + if (type.count(chip_info->tiletype_names[tn.type_idx].get())) + return tn.name.get(); } NPNR_ASSERT_FALSE_STR("no tile at (" + std::to_string(col) + ", " + std::to_string(row) + ") with type in set"); } @@ -1021,9 +1022,9 @@ struct Arch : BaseCtx { for (int i = 0; i < chip_info->height * chip_info->width; i++) { auto &tileloc = chip_info->tile_info[i]; - for (int j = 0; j < tileloc.num_tiles; j++) - if (chip_info->tiletype_names[tileloc.tile_names[j].type_idx].get() == type) - return tileloc.tile_names[j].name.get(); + for (auto &tn : tileloc.tile_names) + if (chip_info->tiletype_names[tn.type_idx].get() == type) + return tn.name.get(); } NPNR_ASSERT_FALSE_STR("no tile with type " + type); } diff --git a/ecp5/trellis_import.py b/ecp5/trellis_import.py index 174f475f..945f6e93 100755 --- a/ecp5/trellis_import.py +++ b/ecp5/trellis_import.py @@ -184,6 +184,13 @@ class BinaryBlobAssembler: else: print("ref %s %s" % (name, comment)) + def r_slice(self, name, length, comment): + if comment is None: + print("ref %s" % (name,)) + else: + print("ref %s %s" % (name, comment)) + print ("u32 %d" % (length, )) + def s(self, s, comment): assert "|" not in s print("str |%s| %s" % (s, comment)) @@ -445,12 +452,9 @@ def write_database(dev_name, chip, ddrg, endianness): bba.u32(gfx_wire_ids["TILE_WIRE_" + ddrg.to_str(wire.name)], "tile_wire") else: bba.u32(0, "tile_wire") - bba.u32(len(wire.arcsUphill), "num_uphill") - bba.u32(len(wire.arcsDownhill), "num_downhill") - bba.r("loc%d_wire%d_uppips" % (idx, wire_idx) if len(wire.arcsUphill) > 0 else None, "pips_uphill") - bba.r("loc%d_wire%d_downpips" % (idx, wire_idx) if len(wire.arcsDownhill) > 0 else None, "pips_downhill") - bba.u32(len(wire.belPins), "num_bel_pins") - bba.r("loc%d_wire%d_belpins" % (idx, wire_idx) if len(wire.belPins) > 0 else None, "bel_pins") + bba.r_slice("loc%d_wire%d_uppips" % (idx, wire_idx) if len(wire.arcsUphill) > 0 else None, len(wire.arcsUphill), "pips_uphill") + bba.r_slice("loc%d_wire%d_downpips" % (idx, wire_idx) if len(wire.arcsDownhill) > 0 else None, len(wire.arcsDownhill), "pips_downhill") + bba.r_slice("loc%d_wire%d_belpins" % (idx, wire_idx) if len(wire.belPins) > 0 else None, len(wire.belPins), "bel_pins") if len(loctype.bels) > 0: for bel_idx in range(len(loctype.bels)): @@ -467,18 +471,14 @@ def write_database(dev_name, chip, ddrg, endianness): bba.s(ddrg.to_str(bel.name), "name") bba.u32(constids[ddrg.to_str(bel.type)], "type") bba.u32(bel.z, "z") - bba.u32(len(bel.wires), "num_bel_wires") - bba.r("loc%d_bel%d_wires" % (idx, bel_idx), "bel_wires") + bba.r_slice("loc%d_bel%d_wires" % (idx, bel_idx), len(bel.wires), "bel_wires") bba.l("locations", "LocationTypePOD") for idx in range(len(loctypes)): loctype = ddrg.locationTypes[loctypes[idx]] - bba.u32(len(loctype.bels), "num_bels") - bba.u32(len(loctype.wires), "num_wires") - bba.u32(len(loctype.arcs), "num_pips") - bba.r("loc%d_bels" % idx if len(loctype.bels) > 0 else None, "bel_data") - bba.r("loc%d_wires" % idx if len(loctype.wires) > 0 else None, "wire_data") - bba.r("loc%d_pips" % idx if len(loctype.arcs) > 0 else None, "pips_data") + bba.r_slice("loc%d_bels" % idx if len(loctype.bels) > 0 else None, len(loctype.bels), "bel_data") + bba.r_slice("loc%d_wires" % idx if len(loctype.wires) > 0 else None, len(loctype.wires), "wire_data") + bba.r_slice("loc%d_pips" % idx if len(loctype.arcs) > 0 else None, len(loctype.arcs), "pips_data") for y in range(0, max_row+1): for x in range(0, max_col+1): @@ -491,8 +491,7 @@ def write_database(dev_name, chip, ddrg, endianness): bba.l("tiles_info", "TileInfoPOD") for y in range(0, max_row+1): for x in range(0, max_col+1): - bba.u32(len(chip.get_tiles_by_position(y, x)), "num_tiles") - bba.r("tile_info_%d_%d" % (x, y), "tile_names") + bba.r_slice("tile_info_%d_%d" % (x, y), len(chip.get_tiles_by_position(y, x)), "tile_names") bba.l("location_types", "int32_t") for y in range(0, max_row+1): @@ -519,8 +518,7 @@ def write_database(dev_name, chip, ddrg, endianness): bba.l("package_data", "PackageInfoPOD") for package, pkgdata in sorted(packages.items()): bba.s(package, "name") - bba.u32(len(pkgdata), "num_pins") - bba.r("package_data_%s" % package, "pin_data") + bba.r_slice("package_data_%s" % package, len(pkgdata), "pin_data") bba.l("pio_info", "PIOInfoPOD") for pin in pindata: @@ -563,10 +561,8 @@ def write_database(dev_name, chip, ddrg, endianness): for cell in speed_grade_cells[grade]: celltype, delays, setupholds = cell bba.u32(celltype, "cell_type") - bba.u32(len(delays), "num_delays") - bba.u32(len(setupholds), "num_setup_hold") - bba.r("cell_%d_delays_%s" % (celltype, grade) if len(delays) > 0 else None, "delays") - bba.r("cell_%d_setupholds_%s" % (celltype, grade) if len(delays) > 0 else None, "setupholds") + bba.r_slice("cell_%d_delays_%s" % (celltype, grade) if len(delays) > 0 else None, len(delays), "delays") + bba.r_slice("cell_%d_setupholds_%s" % (celltype, grade) if len(delays) > 0 else None, len(setupholds), "setupholds") bba.l("pip_timing_data_%s" % grade) for pipclass in speed_grade_pips[grade]: min_delay, max_delay, min_fanout, max_fanout = pipclass @@ -576,28 +572,23 @@ def write_database(dev_name, chip, ddrg, endianness): bba.u32(max_fanout, "max_fanout") bba.l("speed_grade_data") for grade in speed_grade_names: - bba.u32(len(speed_grade_cells[grade]), "num_cell_timings") - bba.u32(len(speed_grade_pips[grade]), "num_pip_classes") - bba.r("cell_timing_data_%s" % grade, "cell_timings") - bba.r("pip_timing_data_%s" % grade, "pip_classes") + bba.r_slice("cell_timing_data_%s" % grade, len(speed_grade_cells[grade]), "cell_timings") + bba.r_slice("pip_timing_data_%s" % grade, len(speed_grade_pips[grade]), "pip_classes") bba.l("chip_info") bba.u32(max_col + 1, "width") bba.u32(max_row + 1, "height") bba.u32((max_col + 1) * (max_row + 1), "num_tiles") - bba.u32(len(location_types), "num_location_types") - bba.u32(len(packages), "num_packages") - bba.u32(len(pindata), "num_pios") bba.u32(const_id_count, "const_id_count") - bba.r("locations", "locations") - bba.r("location_types", "location_type") - bba.r("location_glbinfo", "location_glbinfo") - bba.r("tiletype_names", "tiletype_names") - bba.r("package_data", "package_info") - bba.r("pio_info", "pio_info") - bba.r("tiles_info", "tile_info") - bba.r("speed_grade_data", "speed_grades") + bba.r_slice("locations", len(loctypes), "locations") + bba.r_slice("location_types", (max_col + 1) * (max_row + 1), "location_type") + bba.r_slice("location_glbinfo", (max_col + 1) * (max_row + 1), "location_glbinfo") + bba.r_slice("tiletype_names", len(tiletype_names), "tiletype_names") + bba.r_slice("package_data", len(packages), "package_info") + bba.r_slice("pio_info", len(pindata), "pio_info") + bba.r_slice("tiles_info", (max_col + 1) * (max_row + 1), "tile_info") + bba.r_slice("speed_grade_data", len(speed_grade_names), "speed_grades") bba.pop() return bba -- cgit v1.2.3