| #include "DedupChipdb.hpp" | |
| #include "Chip.hpp" | |
| namespace Trellis { | |
| namespace DDChipDb { | |
| checksum_t LocationData::checksum() const | |
| { | |
| pair<uint64_t, uint64_t> cs = make_pair(0, 0); | |
| const uint64_t magic1 = 0x9e3779b97f4a7c15ULL; | |
| const uint64_t magic2 = 0xf476452575661fbeULL; | |
| for (const auto &wire : wires) { | |
| cs.first = magic1 + std::hash<WireData>()(wire) + (cs.first << 12UL) + (cs.second >> 2UL); | |
| cs.second = magic2 + std::hash<WireData>()(wire) + (cs.second << 17UL) + (cs.first >> 1UL); | |
| } | |
| for (const auto &bel : bels) { | |
| cs.first = magic1 + std::hash<BelData>()(bel) + (cs.first << 12UL) + (cs.second >> 2UL); | |
| cs.second = magic2 + std::hash<BelData>()(bel) + (cs.second << 17UL) + (cs.first >> 1UL); | |
| } | |
| for (const auto &arc : arcs) { | |
| cs.first = magic1 + std::hash<DdArcData>()(arc) + (cs.first << 12UL) + (cs.second >> 2UL); | |
| cs.second = magic2 + std::hash<DdArcData>()(arc) + (cs.second << 17UL) + (cs.first >> 1UL); | |
| } | |
| return cs; | |
| } | |
| DedupChipdb::DedupChipdb() | |
| { | |
| } | |
| DedupChipdb::DedupChipdb(const IdStore &base) : IdStore(base) | |
| {} | |
| shared_ptr<DedupChipdb> make_dedup_chipdb(Chip &chip) | |
| { | |
| shared_ptr<RoutingGraph> graph = chip.get_routing_graph(); | |
| for (auto &loc : graph->tiles) { | |
| const auto &td = loc.second; | |
| // Index bels, wires and arcs | |
| int bel_id = 0, wire_id = 0, arc_id = 0; | |
| for (auto &bel : td.bels) { | |
| RoutingId rid; | |
| rid.loc = loc.first; | |
| rid.id = bel.first; | |
| bel.second.cdb_id = bel_id++; | |
| } | |
| for (auto &wire : td.wires) { | |
| RoutingId rid; | |
| rid.loc = loc.first; | |
| rid.id = wire.first; | |
| wire.second.cdb_id = wire_id++; | |
| } | |
| for (auto &arc : td.arcs) { | |
| RoutingId rid; | |
| rid.loc = loc.first; | |
| rid.id = arc.first; | |
| arc.second.cdb_id = arc_id++; | |
| } | |
| } | |
| shared_ptr<DedupChipdb> cdb = make_shared<DedupChipdb>(IdStore(*graph)); | |
| for (const auto &loc : graph->tiles) { | |
| int x = loc.first.x, y = loc.first.y; | |
| LocationData ld; | |
| const auto &td = loc.second; | |
| for (const auto &bel : td.bels) { | |
| const RoutingBel &rb = bel.second; | |
| BelData bd; | |
| bd.name = rb.name; | |
| bd.type = rb.type; | |
| bd.z = rb.z; | |
| for (const auto &wire : rb.pins) { | |
| BelWire bw; | |
| bw.pin = wire.first; | |
| bw.wire = RelId{Location(wire.second.first.loc.x - x, wire.second.first.loc.y - y), graph->tiles.at(wire.second.first.loc).wires.at(wire.second.first.id).cdb_id}; | |
| bw.dir = wire.second.second; | |
| bd.wires.push_back(bw); | |
| } | |
| ld.bels.push_back(bd); | |
| } | |
| for (const auto &arc : td.arcs) { | |
| const RoutingArc &ra = arc.second; | |
| DdArcData ad; | |
| ad.tiletype = ra.tiletype; | |
| ad.cls = ra.configurable ? ARC_STANDARD : ARC_FIXED; | |
| ad.delay = 1; | |
| ad.sinkWire = RelId{Location(ra.sink.loc.x - x, ra.sink.loc.y - y), graph->tiles.at(ra.sink.loc).wires.at(ra.sink.id).cdb_id}; | |
| ad.srcWire = RelId{Location(ra.source.loc.x - x, ra.source.loc.y - y), graph->tiles.at(ra.source.loc).wires.at(ra.source.id).cdb_id}; | |
| ld.arcs.push_back(ad); | |
| } | |
| for (const auto &wire : td.wires) { | |
| const RoutingWire &rw = wire.second; | |
| WireData wd; | |
| wd.name = rw.id; | |
| for (const auto &dh : rw.downhill) | |
| wd.arcsDownhill.insert(RelId{Location(dh.loc.x - x, dh.loc.y - y), graph->tiles.at(dh.loc).arcs.at(dh.id).cdb_id}); | |
| for (const auto &uh : rw.uphill) | |
| wd.arcsUphill.insert(RelId{Location(uh.loc.x - x, uh.loc.y - y), graph->tiles.at(uh.loc).arcs.at(uh.id).cdb_id}); | |
| for (const auto &bdh : rw.belsDownhill) { | |
| BelPort bp; | |
| bp.pin = bdh.second; | |
| bp.bel = RelId{Location(bdh.first.loc.x - x, bdh.first.loc.y - y), graph->tiles.at(bdh.first.loc).bels.at(bdh.first.id).cdb_id}; | |
| wd.belPins.push_back(bp); | |
| } | |
| assert(rw.belsUphill.size() <= 1); | |
| if (rw.belsUphill.size() == 1) { | |
| const auto &buh = rw.belsUphill[0]; | |
| BelPort uh; | |
| uh.bel = RelId{Location(buh.first.loc.x - x, buh.first.loc.y - y), graph->tiles.at(buh.first.loc).bels.at(buh.first.id).cdb_id}; | |
| uh.pin = buh.second; | |
| wd.belPins.push_back(uh); | |
| } | |
| ld.wires.push_back(wd); | |
| } | |
| checksum_t cs = ld.checksum(); | |
| if (cdb->locationTypes.find(cs) == cdb->locationTypes.end()) { | |
| cdb->locationTypes[cs] = ld; | |
| } else { | |
| if (!(ld == cdb->locationTypes[cs])) | |
| terminate(); | |
| } | |
| cdb->typeAtLocation[loc.first] = cs; | |
| } | |
| return cdb; | |
| } | |
| LocationData DedupChipdb::get_cs_data(checksum_t id) { | |
| return locationTypes.at(id); | |
| } | |
| } | |
| } |