blob: 828f63a6a47b1f8e64dc654bb473d34aedb48803 [file] [log] [blame]
#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);
}
}
}