From eb773f246d3364ad9faab54680340aed1a664cee Mon Sep 17 00:00:00 2001 From: David Shah Date: Tue, 17 Jul 2018 13:41:33 +0200 Subject: ecp5: Working on packer Signed-off-by: David Shah --- ecp5/pack.cc | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 74 insertions(+), 9 deletions(-) diff --git a/ecp5/pack.cc b/ecp5/pack.cc index ba1a43ab..c44c0c4c 100644 --- a/ecp5/pack.cc +++ b/ecp5/pack.cc @@ -39,11 +39,22 @@ class Ecp5Packer Ecp5Packer(Context *ctx) : ctx(ctx){}; private: + // Process the contents of packed_cells and new_cells + void flush_cells() + { + for (auto pcell : packed_cells) { + ctx->cells.erase(pcell); + } + for (auto &ncell : new_cells) { + ctx->cells[ncell->name] = std::move(ncell); + } + packed_cells.clear(); + new_cells.clear(); + } + // Simple "packer" to remove nextpnr IOBUFs, this assumes IOBUFs are manually instantiated - void pack_io(Context *ctx) + void pack_io() { - std::unordered_set packed_cells; - std::vector> new_cells; log_info("Packing IOs..\n"); for (auto cell : sorted(ctx->cells)) { @@ -79,19 +90,73 @@ class Ecp5Packer std::copy(ci->attrs.begin(), ci->attrs.end(), std::inserter(trio->attrs, trio->attrs.begin())); } } - for (auto pcell : packed_cells) { - ctx->cells.erase(pcell); - } - for (auto &ncell : new_cells) { - ctx->cells[ncell->name] = std::move(ncell); + flush_cells(); + } + + // Pass to pack LUT5s into a newly created slice + void pack_lut5s() + { + log_info("Packing LUT5s...\n"); + for (auto cell : sorted(ctx->cells)) { + CellInfo *ci = cell.second; + if (is_pfumx(ctx, ci)) { + std::unique_ptr packed = + create_ecp5_cell(ctx, ctx->id("TRELLIS_SLICE"), ci->name.str(ctx) + "_SLICE"); + NetInfo *f0 = ci->ports.at(ctx->id("BLUT")).net; + if (f0 == nullptr) + log_error("PFUMX '%s' has disconnected port 'BLUT'\n", ci->name.c_str(ctx)); + NetInfo *f1 = ci->ports.at(ctx->id("ALUT")).net; + if (f1 == nullptr) + log_error("PFUMX '%s' has disconnected port 'ALUT'\n", ci->name.c_str(ctx)); + CellInfo *lc0 = net_driven_by(ctx, f0, is_lut, ctx->id("Z")); + CellInfo *lc1 = net_driven_by(ctx, f1, is_lut, ctx->id("Z")); + if (lc0 == nullptr) + log_error("PFUMX '%s' has BLUT driven by cell other than a LUT\n", ci->name.c_str(ctx)); + if (lc1 == nullptr) + log_error("PFUMX '%s' has ALUT driven by cell other than a LUT\n", ci->name.c_str(ctx)); + replace_port(lc0, ctx->id("A"), packed.get(), ctx->id("A0")); + replace_port(lc0, ctx->id("B"), packed.get(), ctx->id("B0")); + replace_port(lc0, ctx->id("C"), packed.get(), ctx->id("C0")); + replace_port(lc0, ctx->id("D"), packed.get(), ctx->id("D0")); + replace_port(lc1, ctx->id("A"), packed.get(), ctx->id("A1")); + replace_port(lc1, ctx->id("B"), packed.get(), ctx->id("B1")); + replace_port(lc1, ctx->id("C"), packed.get(), ctx->id("C1")); + replace_port(lc1, ctx->id("D"), packed.get(), ctx->id("D1")); + replace_port(ci, ctx->id("C0"), packed.get(), ctx->id("M0")); + replace_port(ci, ctx->id("Z"), packed.get(), ctx->id("OFX0")); + ctx->nets.erase(f0->name); + ctx->nets.erase(f1->name); + new_cells.push_back(std::move(packed)); + packed_cells.insert(lc0->name); + packed_cells.insert(lc1->name); + packed_cells.insert(ci->name); + } } + flush_cells(); } public: - void pack() { pack_io(ctx); } + void pack() + { + pack_io(); + pack_lut5s(); + } private: Context *ctx; + + std::unordered_set packed_cells; + std::vector> new_cells; + + struct SliceUsage + { + bool lut0_used = false, lut1_used = false; + bool ccu2_used = false, dpram_used = false, ramw_used = false; + bool ff0_used = false, ff1_used = false; + bool mux5_used = false, muxx_used = false; + }; + + std::unordered_map sliceUsage; }; // Main pack function -- cgit v1.2.3