Initial implementation of split SLICE bels Signed-off-by: David Shah <dave@ds0.me>
diff --git a/libtrellis/include/Bels.hpp b/libtrellis/include/Bels.hpp index cb4b5ea..c1801d1 100644 --- a/libtrellis/include/Bels.hpp +++ b/libtrellis/include/Bels.hpp
@@ -8,6 +8,12 @@ namespace Bels { void add_lc(RoutingGraph &graph, int x, int y, int z); + +// Split SLICE Bels +void add_logic_comb(RoutingGraph &graph, int x, int y, int z); +void add_ff(RoutingGraph &graph, int x, int y, int z); +void add_ramw(RoutingGraph &graph, int x, int y); + void add_pio(RoutingGraph &graph, int x, int y, int z); void add_dcc(RoutingGraph &graph, int x, int y, string side, string z); void add_bram(RoutingGraph &graph, int x, int y, int z);
diff --git a/libtrellis/include/Chip.hpp b/libtrellis/include/Chip.hpp index 1c12c3b..70dafe0 100644 --- a/libtrellis/include/Chip.hpp +++ b/libtrellis/include/Chip.hpp
@@ -150,6 +150,11 @@ // Globals data GlobalsInfo global_data; + + void set_split_slice_mode(bool mode); + +private: + bool split_slice_flag = false; // for routing graph gen }; ChipDelta operator-(const Chip &a, const Chip &b);
diff --git a/libtrellis/src/Bels.cpp b/libtrellis/src/Bels.cpp index bbcd7d8..f77908c 100644 --- a/libtrellis/src/Bels.cpp +++ b/libtrellis/src/Bels.cpp
@@ -83,6 +83,136 @@ graph.add_bel(bel); } +void add_logic_comb(RoutingGraph &graph, int x, int y, int z) { + char l = "ABCD"[z/2]; + char i = "01"[z%2]; + string name = string("SLICE") + l + string(".K") + i; + RoutingBel bel; + bel.name = graph.ident(name); + bel.type = graph.ident("TRELLIS_COMB"); + bel.loc.x = x; + bel.loc.y = y; + bel.z = z * 4; + // LUT inputs + graph.add_bel_input(bel, graph.ident("A"), x, y, graph.ident(fmt("A" << z << "_SLICE"))); + graph.add_bel_input(bel, graph.ident("B"), x, y, graph.ident(fmt("B" << z << "_SLICE"))); + graph.add_bel_input(bel, graph.ident("C"), x, y, graph.ident(fmt("C" << z << "_SLICE"))); + graph.add_bel_input(bel, graph.ident("D"), x, y, graph.ident(fmt("D" << z << "_SLICE"))); + // MUX select input + graph.add_bel_input(bel, graph.ident("M"), x, y, graph.ident(fmt("M" << z << "_SLICE"))); + + // Distributed RAM inputs + if (z < 4) { + // Write address + graph.add_bel_input(bel, graph.ident("WAD0"), x, y, graph.ident(fmt("WAD0" << l << "_SLICE"))); + graph.add_bel_input(bel, graph.ident("WAD1"), x, y, graph.ident(fmt("WAD1" << l << "_SLICE"))); + graph.add_bel_input(bel, graph.ident("WAD2"), x, y, graph.ident(fmt("WAD2" << l << "_SLICE"))); + graph.add_bel_input(bel, graph.ident("WAD3"), x, y, graph.ident(fmt("WAD3" << l << "_SLICE"))); + // Write data + graph.add_bel_input(bel, graph.ident("WD"), x, y, graph.ident(fmt("WD" << i << l << "_SLICE"))); + // Write enable and clock + graph.add_bel_input(bel, graph.ident("WRE"), x, y, graph.ident(fmt("WRE" << (z/2) << "_SLICE"))); + graph.add_bel_input(bel, graph.ident("WCK"), x, y, graph.ident(fmt("WCK" << (z/2) << "_SLICE"))); + } + + // Carry input + if (z == 0) + graph.add_bel_input(bel, graph.ident("FCI"), x, y, graph.ident("FCI_SLICE")); + else if ((z % 2) == 0) + graph.add_bel_input(bel, graph.ident("FCI"), x, y, graph.ident(fmt("FCI" << l << "_SLICE"))); + else + graph.add_bel_input(bel, graph.ident("FCI"), x, y, graph.ident(fmt("FCI" << l << "1_SLICE"))); + + // LUT output + graph.add_bel_output(bel, graph.ident("F"), x, y, graph.ident(fmt("F" << z << "_SLICE"))); + if ((z % 2) == 0) { + // Loopback from F1 side to LUT5 mux 'B' input + graph.add_bel_input(bel, graph.ident("F1"), x, y, graph.ident(fmt("F" << (z + 1) << "_SLICE"))); + // LUT5 mux output + graph.add_bel_output(bel, graph.ident("OFX"), x, y, graph.ident(fmt("F5" << l << "_SLICE"))); + } else { + // LUT[678] mux inputs + graph.add_bel_input(bel, graph.ident("FXA"), x, y, graph.ident(fmt("FXA" << l << "_SLICE"))); + graph.add_bel_input(bel, graph.ident("FXB"), x, y, graph.ident(fmt("FXB" << l << "_SLICE"))); + // LUT[678] mux outputs + graph.add_bel_output(bel, graph.ident("OFX"), x, y, graph.ident(fmt("FX" << l << "_SLICE"))); + } + + // Carry output + if (z == 7) + graph.add_bel_output(bel, graph.ident("FCO"), x, y, graph.ident("FCO_SLICE")); + else if ((z % 2) == 1) + graph.add_bel_output(bel, graph.ident("FCO"), x, y, graph.ident(fmt("FCO" << l << "_SLICE"))); + else + graph.add_bel_output(bel, graph.ident("FCO"), x, y, graph.ident(fmt("FCI" << l << "1_SLICE"))); + + graph.add_bel(bel); +} + +void add_ff(RoutingGraph &graph, int x, int y, int z) { + char l = "ABCD"[z/2]; + char i = "01"[z%2]; + string name = string("SLICE") + l + string(".FF") + i; + RoutingBel bel; + bel.name = graph.ident(name); + bel.type = graph.ident("TRELLIS_FF"); + bel.loc.x = x; + bel.loc.y = y; + bel.z = z * 4 + 1; + // DI from COMB + graph.add_bel_input(bel, graph.ident("DI"), x, y, graph.ident(fmt("DI" << z << "_SLICE"))); + // DI from fabric + graph.add_bel_input(bel, graph.ident("M"), x, y, graph.ident(fmt("M" << z << "_SLICE"))); + + // Control set + graph.add_bel_input(bel, graph.ident("CLK"), x, y, graph.ident(fmt("CLK" << (z/2) << "_SLICE"))); + graph.add_bel_input(bel, graph.ident("LSR"), x, y, graph.ident(fmt("LSR" << (z/2) << "_SLICE"))); + graph.add_bel_input(bel, graph.ident("CE"), x, y, graph.ident(fmt("CE" << (z/2) << "_SLICE"))); + + // Output + graph.add_bel_output(bel, graph.ident("Q"), x, y, graph.ident(fmt("Q" << z << "_SLICE"))); + + graph.add_bel(bel); +} + + +void add_ramw(RoutingGraph &graph, int x, int y) { + string name = string("SLICEC.RAMW"); + RoutingBel bel; + bel.name = graph.ident(name); + bel.type = graph.ident("TRELLIS_RAMW"); + bel.loc.x = x; + bel.loc.y = y; + bel.z = 4 * 4 + 2; + + int lc0 = 4; + int lc1 = 5; + + // Input + graph.add_bel_input(bel, graph.ident("A0"), x, y, graph.ident(fmt("A" << lc0 << "_SLICE"))); + graph.add_bel_input(bel, graph.ident("B0"), x, y, graph.ident(fmt("B" << lc0 << "_SLICE"))); + graph.add_bel_input(bel, graph.ident("C0"), x, y, graph.ident(fmt("C" << lc0 << "_SLICE"))); + graph.add_bel_input(bel, graph.ident("D0"), x, y, graph.ident(fmt("D" << lc0 << "_SLICE"))); + + graph.add_bel_input(bel, graph.ident("A1"), x, y, graph.ident(fmt("A" << lc1 << "_SLICE"))); + graph.add_bel_input(bel, graph.ident("B1"), x, y, graph.ident(fmt("B" << lc1 << "_SLICE"))); + graph.add_bel_input(bel, graph.ident("C1"), x, y, graph.ident(fmt("C" << lc1 << "_SLICE"))); + graph.add_bel_input(bel, graph.ident("D1"), x, y, graph.ident(fmt("D" << lc1 << "_SLICE"))); + + // Output + graph.add_bel_output(bel, graph.ident("WDO0"), x, y, graph.ident("WDO0C_SLICE")); + graph.add_bel_output(bel, graph.ident("WDO1"), x, y, graph.ident("WDO1C_SLICE")); + graph.add_bel_output(bel, graph.ident("WDO2"), x, y, graph.ident("WDO2C_SLICE")); + graph.add_bel_output(bel, graph.ident("WDO3"), x, y, graph.ident("WDO3C_SLICE")); + + graph.add_bel_output(bel, graph.ident("WADO0"), x, y, graph.ident("WADO0C_SLICE")); + graph.add_bel_output(bel, graph.ident("WADO1"), x, y, graph.ident("WADO1C_SLICE")); + graph.add_bel_output(bel, graph.ident("WADO2"), x, y, graph.ident("WADO2C_SLICE")); + graph.add_bel_output(bel, graph.ident("WADO3"), x, y, graph.ident("WADO3C_SLICE")); + graph.add_bel(bel); +} + + void add_pio(RoutingGraph &graph, int x, int y, int z) { char l = "ABCD"[z]; string name = string("PIO") + l; @@ -634,4 +764,4 @@ } -} \ No newline at end of file +}
diff --git a/libtrellis/src/Chip.cpp b/libtrellis/src/Chip.cpp index e983fa4..c846233 100644 --- a/libtrellis/src/Chip.cpp +++ b/libtrellis/src/Chip.cpp
@@ -107,6 +107,11 @@ return delta; } +void Chip::set_split_slice_mode(bool mode) +{ + split_slice_flag = mode; +} + shared_ptr<RoutingGraph> Chip::get_routing_graph() { shared_ptr<RoutingGraph> rg(new RoutingGraph(*this)); @@ -120,8 +125,16 @@ tie(y, x) = tile->info.get_row_col(); // SLICE Bels if (tile->info.type == "PLC2") { - for (int z = 0; z < 4; z++) - Bels::add_lc(*rg, x, y, z); + if (split_slice_flag) { + for (int z = 0; z < 8; z++) { + Bels::add_logic_comb(*rg, x, y, z); + Bels::add_ff(*rg, x, y, z); + } + Bels::add_ramw(*rg, x, y); + } else { + for (int z = 0; z < 4; z++) + Bels::add_lc(*rg, x, y, z); + } } // PIO Bels if (tile->info.type.find("PICL0") != string::npos || tile->info.type.find("PICR0") != string::npos)
diff --git a/libtrellis/src/PyTrellis.cpp b/libtrellis/src/PyTrellis.cpp index ac07c35..a8a5ade 100644 --- a/libtrellis/src/PyTrellis.cpp +++ b/libtrellis/src/PyTrellis.cpp
@@ -143,6 +143,7 @@ .def("get_max_row", &Chip::get_max_row) .def("get_max_col", &Chip::get_max_col) .def("get_routing_graph", &Chip::get_routing_graph) + .def("set_split_slice_mode", &Chip::set_split_slice_mode) .def_readonly("info", &Chip::info) .def_readwrite("cram", &Chip::cram) .def_readwrite("tiles", &Chip::tiles)