Skip to content

Commit

Permalink
Merge pull request #181 from YosysHQ/gatecat/ecp5-lutperm
Browse files Browse the repository at this point in the history
libtrellis: LUT permutation support for ECP5
  • Loading branch information
gatecat authored Dec 14, 2021
2 parents 03e0070 + 7239331 commit 2f06397
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 12 deletions.
4 changes: 2 additions & 2 deletions libtrellis/include/Chip.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ class Chip
int get_max_col() const;

// Build the routing graph for the chip
shared_ptr<RoutingGraph> get_routing_graph();
shared_ptr<RoutingGraph> get_routing_graph(bool include_lutperm_pips = false);

vector<vector<vector<pair<string, string>>>> tiles_at_location;

Expand All @@ -191,7 +191,7 @@ class Chip

private:
// Factory functions
shared_ptr<RoutingGraph> get_routing_graph_ecp5();
shared_ptr<RoutingGraph> get_routing_graph_ecp5(bool include_lutperm_pips = false);
shared_ptr<RoutingGraph> get_routing_graph_machxo2();
};

Expand Down
6 changes: 4 additions & 2 deletions libtrellis/include/DedupChipdb.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,13 @@ struct DdArcData
ArcClass cls;
int32_t delay;
ident_t tiletype;
int16_t lutperm_flags;
};

inline bool operator==(const DdArcData &a, const DdArcData &b)
{
return a.srcWire == b.srcWire && a.sinkWire == b.sinkWire && a.cls == b.cls && a.delay == b.delay &&
a.tiletype == b.tiletype;
a.tiletype == b.tiletype && a.lutperm_flags == b.lutperm_flags;
}

struct WireData
Expand Down Expand Up @@ -241,6 +242,7 @@ struct hash<Trellis::DDChipDb::DdArcData>
boost::hash_combine(seed, hash<int8_t>()(arc.cls));
boost::hash_combine(seed, hash<int32_t>()(arc.delay));
boost::hash_combine(seed, hash<Trellis::ident_t>()(arc.tiletype));
boost::hash_combine(seed, hash<uint16_t>()(arc.lutperm_flags));
return seed;
}
};
Expand Down Expand Up @@ -355,7 +357,7 @@ struct DedupChipdb : public IdStore
LocationData get_cs_data(checksum_t id);
};

shared_ptr<DedupChipdb> make_dedup_chipdb(Chip &chip);
shared_ptr<DedupChipdb> make_dedup_chipdb(Chip &chip, bool include_lutperm_pips = false);

/*
An optimized chip database is a database with the following properties, intended to be used in place-and-route flows.
Expand Down
1 change: 1 addition & 0 deletions libtrellis/include/RoutingGraph.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ struct RoutingArc
RoutingId source;
RoutingId sink;
bool configurable = false;
uint16_t lutperm_flags = 0;
mutable int cdb_id = 0;
};

Expand Down
32 changes: 28 additions & 4 deletions libtrellis/src/Chip.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,17 +113,17 @@ ChipDelta operator-(const Chip &a, const Chip &b)
return delta;
}

shared_ptr<RoutingGraph> Chip::get_routing_graph()
shared_ptr<RoutingGraph> Chip::get_routing_graph(bool include_lutperm_pips)
{
if(info.family == "ECP5") {
return get_routing_graph_ecp5();
return get_routing_graph_ecp5(include_lutperm_pips);
} else if(info.family == "MachXO2") {
return get_routing_graph_machxo2();
} else
throw runtime_error("Unknown chip family: " + info.family);
}

shared_ptr<RoutingGraph> Chip::get_routing_graph_ecp5()
shared_ptr<RoutingGraph> Chip::get_routing_graph_ecp5(bool include_lutperm_pips)
{
shared_ptr<RoutingGraph> rg(new RoutingGraph(*this));
//cout << "Building routing graph" << endl;
Expand All @@ -136,8 +136,32 @@ shared_ptr<RoutingGraph> Chip::get_routing_graph_ecp5()
tie(y, x) = tile->info.get_row_col();
// SLICE Bels
if (tile->info.type == "PLC2") {
for (int z = 0; z < 4; z++)
for (int z = 0; z < 4; z++) {
Ecp5Bels::add_lc(*rg, x, y, z);
if (include_lutperm_pips) {
// Add permutation pseudo-pips as a crossbar in front of each LUT's inputs
Location loc(x, y);
const string abcd = "ABCD";
for (int k = (z*2); k < ((z+1)*2); k++) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (i == j)
continue;
string input = fmt(abcd[j] << k);
string output = fmt(abcd[i] << k << "_SLICE");
RoutingArc rarc;
rarc.id = rg->ident(fmt(input << "->" << output));
rarc.source = RoutingId{loc, rg->ident(input)};
rarc.sink = RoutingId{loc, rg->ident(output)};
rarc.tiletype = rg->ident(tile->info.type);
rarc.configurable = false;
rarc.lutperm_flags = (0x4000 | (k << 4) | ((i & 0x3) << 2) |(j & 0x3));
rg->add_arc(loc, rarc);
}
}
}
}
}
}
// PIO Bels
if (tile->info.type.find("PICL0") != string::npos || tile->info.type.find("PICR0") != string::npos)
Expand Down
5 changes: 3 additions & 2 deletions libtrellis/src/DedupChipdb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ DedupChipdb::DedupChipdb()
DedupChipdb::DedupChipdb(const IdStore &base) : IdStore(base)
{}

shared_ptr<DedupChipdb> make_dedup_chipdb(Chip &chip)
shared_ptr<DedupChipdb> make_dedup_chipdb(Chip &chip, bool include_lutperm_pips)
{
shared_ptr<RoutingGraph> graph = chip.get_routing_graph();
shared_ptr<RoutingGraph> graph = chip.get_routing_graph(include_lutperm_pips);
for (auto &loc : graph->tiles) {
const auto &td = loc.second;
// Index bels, wires and arcs
Expand Down Expand Up @@ -87,6 +87,7 @@ shared_ptr<DedupChipdb> make_dedup_chipdb(Chip &chip)
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};
ad.lutperm_flags = ra.lutperm_flags;
ld.arcs.push_back(ad);
}

Expand Down
6 changes: 4 additions & 2 deletions libtrellis/src/PyTrellis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,8 @@ PYBIND11_MODULE (pytrellis, m)
.def_readwrite("sinkWire", &DdArcData::sinkWire)
.def_readwrite("cls", &DdArcData::cls)
.def_readwrite("delay", &DdArcData::delay)
.def_readwrite("tiletype", &DdArcData::tiletype);
.def_readwrite("tiletype", &DdArcData::tiletype)
.def_readwrite("lutperm_flags", &DdArcData::lutperm_flags);

class_<WireData>(m, "WireData")
.def_readwrite("name", &WireData::name)
Expand Down Expand Up @@ -546,7 +547,8 @@ PYBIND11_MODULE (pytrellis, m)
.def("ident", &DedupChipdb::ident)
.def("to_str", &DedupChipdb::to_str);

m.def("make_dedup_chipdb", make_dedup_chipdb);
m.def("make_dedup_chipdb", make_dedup_chipdb,
py::arg("chip"), py::arg("include_lutperm_pips")=false);

class_<OptimizedChipdb, shared_ptr<OptimizedChipdb>>(m, "OptimizedChipdb")
.def_readwrite("tiles", &OptimizedChipdb::tiles)
Expand Down

0 comments on commit 2f06397

Please sign in to comment.