aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSergiusz Bazanski <q3k@q3k.org>2018-07-24 01:24:07 +0100
committerSergiusz Bazanski <q3k@q3k.org>2018-07-24 02:55:40 +0100
commit065ea95eaba3e0d2389695a3bddde774e5251ee9 (patch)
tree965cfdaa810374ecbf6cc9d4fa6d70d0e951649a
parent1d3147e26a2d57085199b645c12df5ab4836850e (diff)
downloadnextpnr-065ea95eaba3e0d2389695a3bddde774e5251ee9.tar.gz
nextpnr-065ea95eaba3e0d2389695a3bddde774e5251ee9.tar.bz2
nextpnr-065ea95eaba3e0d2389695a3bddde774e5251ee9.zip
ice40: Move spliceLUT back to pack.cc
-rw-r--r--ice40/arch.cc49
-rw-r--r--ice40/arch.h5
-rw-r--r--ice40/pack.cc55
3 files changed, 53 insertions, 56 deletions
diff --git a/ice40/arch.cc b/ice40/arch.cc
index 6679217a..5c632faa 100644
--- a/ice40/arch.cc
+++ b/ice40/arch.cc
@@ -806,53 +806,4 @@ void Arch::assignCellInfo(CellInfo *cell)
}
}
-std::unique_ptr<CellInfo> Arch::spliceLUT(CellInfo *ci, IdString portId, bool onlyNonLUTs)
-{
- auto port = ci->ports[portId];
-
- NPNR_ASSERT(port.net != nullptr);
-
-
- // Create pass-through LUT.
- std::unique_ptr<CellInfo> pt =
- create_ice_cell(getCtx(), id("ICESTORM_LC"), ci->name.str(this) + "$nextpnr_ice40_pack_pll_lc");
- pt->params[id("LUT_INIT")] = "255"; // output is always I3
-
- // Create LUT output net.
- std::unique_ptr<NetInfo> out_net = std::unique_ptr<NetInfo>(new NetInfo);
- out_net->name = id(ci->name.str(this) + "$nextnr_ice40_pack_pll_net");
- out_net->driver.cell = pt.get();
- out_net->driver.port = id("O");
- pt->ports.at(id("O")).net = out_net.get();
-
- // New users of the original cell's port
- std::vector<PortRef> new_users;
- for (const auto &user : port.net->users) {
- if (onlyNonLUTs && user.cell->type == id("ICESTORM_LC")) {
- new_users.push_back(user);
- continue;
- }
- // Rewrite pointer into net in user.
- user.cell->ports[user.port].net = out_net.get();
- // Add user to net.
- PortRef pr;
- pr.cell = user.cell;
- pr.port = user.port;
- out_net->users.push_back(pr);
- }
-
- // Add LUT to new users.
- PortRef pr;
- pr.cell = pt.get();
- pr.port = id("I3");
- new_users.push_back(pr);
- pt->ports.at(id("I3")).net = port.net;
-
- // Replace users of the original net.
- port.net->users = new_users;
-
- nets[out_net->name] = std::move(out_net);
- return pt;
-}
-
NEXTPNR_NAMESPACE_END
diff --git a/ice40/arch.h b/ice40/arch.h
index 15422aa7..d4d71cfc 100644
--- a/ice40/arch.h
+++ b/ice40/arch.h
@@ -746,11 +746,6 @@ struct Arch : BaseCtx
IdString id_cen, id_clk, id_sr;
IdString id_i0, id_i1, id_i2, id_i3;
IdString id_dff_en, id_neg_clk;
-
-
- // -------------------------------------------------
- // Insert a LUT/LC in between a given output port of a cell and all its' users.
- std::unique_ptr<CellInfo> spliceLUT(CellInfo *ci, IdString portId, bool onlyNonLUTs);
};
NEXTPNR_NAMESPACE_END
diff --git a/ice40/pack.cc b/ice40/pack.cc
index dc0db578..14abc1d0 100644
--- a/ice40/pack.cc
+++ b/ice40/pack.cc
@@ -537,6 +537,57 @@ static void promote_globals(Context *ctx)
}
}
+// spliceLUT adds a pass-through LUT LC between the given cell's output port
+// and either all users or only non_LUT users.
+static std::unique_ptr<CellInfo> spliceLUT(Context *ctx, CellInfo *ci, IdString portId, bool onlyNonLUTs)
+{
+ auto port = ci->ports[portId];
+
+ NPNR_ASSERT(port.net != nullptr);
+
+
+ // Create pass-through LUT.
+ std::unique_ptr<CellInfo> pt =
+ create_ice_cell(ctx, ctx->id("ICESTORM_LC"), ci->name.str(ctx) + "$nextpnr_ice40_pack_pll_lc");
+ pt->params[ctx->id("LUT_INIT")] = "255"; // output is always I3
+
+ // Create LUT output net.
+ std::unique_ptr<NetInfo> out_net = std::unique_ptr<NetInfo>(new NetInfo);
+ out_net->name = ctx->id(ci->name.str(ctx) + "$nextnr_ice40_pack_pll_net");
+ out_net->driver.cell = pt.get();
+ out_net->driver.port = ctx->id("O");
+ pt->ports.at(ctx->id("O")).net = out_net.get();
+
+ // New users of the original cell's port
+ std::vector<PortRef> new_users;
+ for (const auto &user : port.net->users) {
+ if (onlyNonLUTs && user.cell->type == ctx->id("ICESTORM_LC")) {
+ new_users.push_back(user);
+ continue;
+ }
+ // Rewrite pointer into net in user.
+ user.cell->ports[user.port].net = out_net.get();
+ // Add user to net.
+ PortRef pr;
+ pr.cell = user.cell;
+ pr.port = user.port;
+ out_net->users.push_back(pr);
+ }
+
+ // Add LUT to new users.
+ PortRef pr;
+ pr.cell = pt.get();
+ pr.port = ctx->id("I3");
+ new_users.push_back(pr);
+ pt->ports.at(ctx->id("I3")).net = port.net;
+
+ // Replace users of the original net.
+ port.net->users = new_users;
+
+ ctx->nets[out_net->name] = std::move(out_net);
+ return pt;
+}
+
// Pack special functions
static void pack_special(Context *ctx)
{
@@ -674,12 +725,12 @@ static void pack_special(Context *ctx)
} else if (found_lut && !all_luts && lut_count < 8) {
// Strategy: create a pass-through LUT, move all non-LUT users behind it.
log_info(" LUT strategy for %s: move non-LUT users to new LUT\n", port.name.c_str(ctx));
- auto pt = ctx->spliceLUT(packed.get(), port.name, true);
+ auto pt = spliceLUT(ctx, packed.get(), port.name, true);
new_cells.push_back(std::move(pt));
} else {
// Strategy: create a pass-through LUT, move every user behind it.
log_info(" LUT strategy for %s: move all users to new LUT\n", port.name.c_str(ctx));
- auto pt = ctx->spliceLUT(packed.get(), port.name, false);
+ auto pt = spliceLUT(ctx, packed.get(), port.name, false);
new_cells.push_back(std::move(pt));
}