aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Shah <davey1576@gmail.com>2018-06-26 15:06:59 +0200
committerDavid Shah <davey1576@gmail.com>2018-06-26 15:06:59 +0200
commit6f12f2b7e8c58a0b14c6f1f3df2112b8860a6e4f (patch)
treeb8617ab8460f4b59c8d074660b6572fb4a84ba26
parent29df577f14c8e6f870c4dfbd633effc664219252 (diff)
downloadnextpnr-6f12f2b7e8c58a0b14c6f1f3df2112b8860a6e4f.tar.gz
nextpnr-6f12f2b7e8c58a0b14c6f1f3df2112b8860a6e4f.tar.bz2
nextpnr-6f12f2b7e8c58a0b14c6f1f3df2112b8860a6e4f.zip
Working on debugging the carry legaliser
Signed-off-by: David Shah <davey1576@gmail.com>
-rw-r--r--common/util.h10
-rwxr-xr-xice40/carry_tests/test.sh22
-rw-r--r--ice40/main.cc2
-rw-r--r--ice40/pack.cc8
-rw-r--r--ice40/place_legaliser.cc38
5 files changed, 64 insertions, 16 deletions
diff --git a/common/util.h b/common/util.h
index c888c8b8..a9ad2172 100644
--- a/common/util.h
+++ b/common/util.h
@@ -21,6 +21,7 @@
#define UTIL_H
#include <map>
+#include <set>
#include <string>
#include "nextpnr.h"
@@ -65,6 +66,15 @@ template <typename K, typename V> std::map<K, V *> sorted(const std::unordered_m
return retVal;
};
+// Wrap an unordered_set, and allow it to be iterated over sorted by key
+template <typename K> std::set<K> sorted(const std::unordered_set<K> &orig)
+{
+ std::set<K> retVal;
+ for (auto &item : orig)
+ retVal.insert(item);
+ return retVal;
+};
+
NEXTPNR_NAMESPACE_END
#endif
diff --git a/ice40/carry_tests/test.sh b/ice40/carry_tests/test.sh
index 47a9e5ef..9f6b00b2 100755
--- a/ice40/carry_tests/test.sh
+++ b/ice40/carry_tests/test.sh
@@ -2,15 +2,15 @@
set -ex
NAME=${1%.v}
yosys -p "synth_ice40 -top top; write_json ${NAME}.json" $1
-../../nextpnr-ice40 --json ${NAME}.json --pcf test.pcf --asc ${NAME}.asc --verbose
-icebox_vlog -p test.pcf ${NAME}.asc > ${NAME}_out.v
+../../nextpnr-ice40 --force --json ${NAME}.json --pcf test.pcf --asc ${NAME}.asc --verbose ../../python/dump_design.py
+#icebox_vlog -p test.pcf ${NAME}.asc > ${NAME}_out.v
-yosys -p "read_verilog +/ice40/cells_sim.v;\
- rename chip gate;\
- read_verilog $1;\
- rename top gold;\
- hierarchy;\
- proc;\
- clk2fflogic;\
- miter -equiv -flatten -ignore_gold_x -make_outputs -make_outcmp gold gate miter;\
- sat -dump_vcd equiv_${NAME}.vcd -verify-no-timeout -timeout 60 -seq 50 -prove trigger 0 -prove-skip 1 -show-inputs -show-outputs miter" ${NAME}_out.v
+#yosys -p "read_verilog +/ice40/cells_sim.v;\
+# rename chip gate;\
+# read_verilog $1;\
+# rename top gold;\
+# hierarchy;\
+# proc;\
+# clk2fflogic;\
+# miter -equiv -flatten -ignore_gold_x -make_outputs -make_outcmp gold gate miter;\
+# sat -dump_vcd equiv_${NAME}.vcd -verify-no-timeout -timeout 60 -seq 50 -prove trigger 0 -prove-skip 1 -show-inputs -show-outputs miter" ${NAME}_out.v
diff --git a/ice40/main.cc b/ice40/main.cc
index 8babf8b9..7f913bb3 100644
--- a/ice40/main.cc
+++ b/ice40/main.cc
@@ -45,6 +45,7 @@
#include "route.h"
#include "timing.h"
#include "version.h"
+#include "place_legaliser.h"
USING_NEXTPNR_NAMESPACE
@@ -375,6 +376,7 @@ int main(int argc, char *argv[])
if (!vm.count("pack-only")) {
if (!place_design_sa(&ctx, timing_driven) && !ctx.force)
log_error("Placing design failed.\n");
+ legalise_design(&ctx);
if (!route_design(&ctx) && !ctx.force)
log_error("Routing design failed.\n");
}
diff --git a/ice40/pack.cc b/ice40/pack.cc
index 3a255257..0d48d58c 100644
--- a/ice40/pack.cc
+++ b/ice40/pack.cc
@@ -126,7 +126,6 @@ static void pack_carries(Context *ctx)
packed_cells.insert(cell.first);
CellInfo *carry_ci_lc = net_only_drives(ctx, ci->ports.at(ctx->id("CI")).net, is_lc, ctx->id("I3"), false);
-
std::set<IdString> i0_matches, i1_matches;
NetInfo *i0_net = ci->ports.at(ctx->id("I0")).net;
NetInfo *i1_net = ci->ports.at(ctx->id("I1")).net;
@@ -161,9 +160,9 @@ static void pack_carries(Context *ctx)
if (carry_ci_lc) {
if (carry_lcs.find(carry_ci_lc->name) == carry_lcs.end()) {
if (ctx->verbose) {
- for(auto i0 : i0_matches)
+ for (auto i0 : i0_matches)
log_info("I0 candidate: '%s'\n", i0.c_str(ctx));
- for(auto i1 : i1_matches)
+ for (auto i1 : i1_matches)
log_info("I1 candidate: '%s'\n", i1.c_str(ctx));
log_info("I3 connects to: '%s'\n", carry_ci_lc->name.c_str(ctx));
}
@@ -275,7 +274,8 @@ static void set_net_constant(const Context *ctx, NetInfo *orig, NetInfo *constne
CellInfo *uc = user.cell;
if (ctx->verbose)
log_info("%s user %s\n", orig->name.c_str(ctx), uc->name.c_str(ctx));
- if ((is_lut(ctx, uc) || is_lc(ctx, uc) || is_carry(ctx, uc)) && (user.port.str(ctx).at(0) == 'I') && !constval) {
+ if ((is_lut(ctx, uc) || is_lc(ctx, uc) || is_carry(ctx, uc)) && (user.port.str(ctx).at(0) == 'I') &&
+ !constval) {
uc->ports[user.port].net = nullptr;
} else {
uc->ports[user.port].net = constnet;
diff --git a/ice40/place_legaliser.cc b/ice40/place_legaliser.cc
index 29dab0a0..8f5680bf 100644
--- a/ice40/place_legaliser.cc
+++ b/ice40/place_legaliser.cc
@@ -93,11 +93,13 @@ class PlacementLegaliser
bool legalise()
{
+ log_info("Legalising design..\n");
init_logic_cells();
bool legalised_carries = legalise_carries();
if (!legalised_carries && !ctx->force)
return false;
- return legalised_carries;
+ bool replaced_cells = replace_cells();
+ return legalised_carries && replaced_cells;
}
private:
@@ -313,6 +315,40 @@ class PlacementLegaliser
return ctx->cells[name].get();
}
+ // Replace ripped-up cells
+ bool replace_cells()
+ {
+ bool success = true;
+ for (auto cell : sorted(rippedCells)) {
+ CellInfo *ci = ctx->cells.at(cell).get();
+ bool placed = place_single_cell(ci);
+ if (!placed) {
+ if (ctx->force) {
+ log_warning("failed to place cell '%s' of type '%s'\n", cell.c_str(ctx),
+ ci->type.c_str(ctx));
+ success = false;
+ } else {
+ log_error("failed to place cell '%s' of type '%s'\n", cell.c_str(ctx),
+ ci->type.c_str(ctx));
+ }
+ }
+ }
+ return success;
+ }
+
+ // Place a single cell in the first valid location
+ bool place_single_cell(CellInfo *cell)
+ {
+ BelType tgtType = ctx->belTypeFromId(cell->type);
+ for (auto bel : ctx->getBels()) {
+ if (ctx->getBelType(bel) == tgtType && ctx->checkBelAvail(bel) && ctx->isValidBelForCell(cell, bel)) {
+ ctx->bindBel(bel, cell->name, STRENGTH_WEAK);
+ return true;
+ }
+ }
+ return false;
+ }
+
Context *ctx;
std::unordered_set<IdString> rippedCells;
std::unordered_set<IdString> createdCells;