From a76f5c5678980c8b2e958252a68ba03676d63229 Mon Sep 17 00:00:00 2001 From: David Shah Date: Wed, 13 Jun 2018 10:50:05 +0200 Subject: Remove IO buffers when fed by SB_IO Signed-off-by: David Shah --- ice40/pack.cc | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) (limited to 'ice40/pack.cc') diff --git a/ice40/pack.cc b/ice40/pack.cc index 8f770a07..73ba0e3d 100644 --- a/ice40/pack.cc +++ b/ice40/pack.cc @@ -134,10 +134,69 @@ static void pack_constants(Design *design) } } +static bool is_nextpnr_iob(CellInfo *cell) +{ + return cell->type == "$nextpnr_ibuf" || cell->type == "$nextpnr_obuf" || + cell->type == "$nextpnr_iobuf"; +} + +// Pack IO buffers +static void pack_io(Design *design) +{ + std::unordered_set packed_cells; + std::vector new_cells; + + for (auto cell : design->cells) { + CellInfo *ci = cell.second; + if (is_nextpnr_iob(ci)) { + if (ci->type == "$nextpnr_ibuf" || ci->type == "$nextpnr_iobuf") { + CellInfo *sb = net_only_drives(ci->ports.at("O").net, is_sb_io, + "PACKAGE_PIN", true, ci); + if (sb != nullptr) { + // Trivial case, SB_IO used. Just destroy the net and the + // iobuf + packed_cells.insert(ci->name); + log_info("%s feeds SB_IO %s, removing %s %s.\n", + ci->name.c_str(), sb->name.c_str(), + ci->type.c_str(), ci->name.c_str()); + NetInfo *net = sb->ports.at("PACKAGE_PIN").net; + if (net != nullptr) { + design->nets.erase(net->name); + sb->ports.at("PACKAGE_PIN").net = nullptr; + } + } + } else if (ci->type == "$nextpnr_obuf") { + CellInfo *sb = net_only_drives(ci->ports.at("I").net, is_sb_io, + "PACKAGE_PIN", true, ci); + if (sb != nullptr) { + // Trivial case, SB_IO used. Just destroy the net and the + // iobuf + packed_cells.insert(ci->name); + log_info("%s feeds SB_IO %s, removing %s %s.\n", + ci->name.c_str(), sb->name.c_str(), + ci->type.c_str(), ci->name.c_str()); + NetInfo *net = sb->ports.at("PACKAGE_PIN").net; + if (net != nullptr) { + design->nets.erase(net->name); + sb->ports.at("PACKAGE_PIN").net = nullptr; + } + } + } + } + } + for (auto pcell : packed_cells) { + design->cells.erase(pcell); + } + for (auto ncell : new_cells) { + design->cells[ncell->name] = ncell; + } +} + // Main pack function void pack_design(Design *design) { pack_constants(design); + pack_io(design); pack_lut_lutffs(design); pack_nonlut_ffs(design); } -- cgit v1.2.3