aboutsummaryrefslogtreecommitdiffstats
path: root/ice40/pack.cc
diff options
context:
space:
mode:
authorDavid Shah <davey1576@gmail.com>2018-06-12 15:13:33 +0200
committerDavid Shah <davey1576@gmail.com>2018-06-12 15:13:50 +0200
commit6707b985b4b62cf201778735bb1fef3e12567ec9 (patch)
tree6f0df9f30ed2f395fb24a79e18b37c359d4cc68c /ice40/pack.cc
parenta139654980b2d2560667b12c886de7518ec97c40 (diff)
downloadnextpnr-6707b985b4b62cf201778735bb1fef3e12567ec9.tar.gz
nextpnr-6707b985b4b62cf201778735bb1fef3e12567ec9.tar.bz2
nextpnr-6707b985b4b62cf201778735bb1fef3e12567ec9.zip
ice40: Add support for LC placement constraints in packer
Signed-off-by: David Shah <davey1576@gmail.com>
Diffstat (limited to 'ice40/pack.cc')
-rw-r--r--ice40/pack.cc34
1 files changed, 25 insertions, 9 deletions
diff --git a/ice40/pack.cc b/ice40/pack.cc
index a971dcc3..4e03eab2 100644
--- a/ice40/pack.cc
+++ b/ice40/pack.cc
@@ -19,12 +19,12 @@
*/
#include "pack.h"
+#include <algorithm>
+#include <unordered_set>
#include "cells.h"
#include "design_utils.h"
#include "log.h"
-#include <unordered_set>
-
NEXTPNR_NAMESPACE_BEGIN
// Pack LUTs and LUT-FF pairs
@@ -39,6 +39,8 @@ static void pack_lut_lutffs(Design *design)
if (is_lut(ci)) {
CellInfo *packed = create_ice_cell(design, "ICESTORM_LC",
ci->name.str() + "_LC");
+ std::copy(ci->attrs.begin(), ci->attrs.end(),
+ std::inserter(packed->attrs, packed->attrs.begin()));
packed_cells.insert(ci->name);
new_cells.push_back(packed);
log_info("packed cell %s into %s\n", ci->name.c_str(),
@@ -47,14 +49,26 @@ static void pack_lut_lutffs(Design *design)
// TODO: LUT cascade
NetInfo *o = ci->ports.at("O").net;
CellInfo *dff = net_only_drives(o, is_ff, "D", true);
+ auto lut_bel = ci->attrs.find("BEL");
+ bool packed_dff = false;
if (dff) {
- lut_to_lc(ci, packed, false);
- dff_to_lc(dff, packed, false);
- design->nets.erase(o->name);
- packed_cells.insert(dff->name);
- log_info("packed cell %s into %s\n", dff->name.c_str(),
- packed->name.c_str());
- } else {
+ auto dff_bel = dff->attrs.find("BEL");
+ if (lut_bel != ci->attrs.end() && dff_bel != dff->attrs.end() &&
+ lut_bel->second != dff_bel->second) {
+ // Locations don't match, can't pack
+ } else {
+ lut_to_lc(ci, packed, false);
+ dff_to_lc(dff, packed, false);
+ design->nets.erase(o->name);
+ if (dff_bel != dff->attrs.end())
+ packed->attrs["BEL"] = dff_bel->second;
+ packed_cells.insert(dff->name);
+ log_info("packed cell %s into %s\n", dff->name.c_str(),
+ packed->name.c_str());
+ packed_dff = true;
+ }
+ }
+ if (!packed_dff) {
lut_to_lc(ci, packed, true);
}
}
@@ -78,6 +92,8 @@ static void pack_nonlut_ffs(Design *design)
if (is_ff(ci)) {
CellInfo *packed = create_ice_cell(design, "ICESTORM_LC",
ci->name.str() + "_LC");
+ std::copy(ci->attrs.begin(), ci->attrs.end(),
+ std::inserter(packed->attrs, packed->attrs.begin()));
packed_cells.insert(ci->name);
new_cells.push_back(packed);
dff_to_lc(ci, packed, true);