diff options
-rw-r--r-- | common/nextpnr.h | 21 | ||||
-rw-r--r-- | common/place_sa.cc | 28 | ||||
-rw-r--r-- | common/place_sa.h | 2 | ||||
-rw-r--r-- | common/route.cc | 9 | ||||
-rw-r--r-- | frontend/json/jsonparse.cc | 11 | ||||
-rw-r--r-- | ice40/arch.h | 1 | ||||
-rw-r--r-- | ice40/main.cc | 15 | ||||
-rw-r--r-- | ice40/pack.cc | 3 | ||||
-rw-r--r-- | ice40/pack.h | 2 |
9 files changed, 60 insertions, 32 deletions
diff --git a/common/nextpnr.h b/common/nextpnr.h index 6d0dab86..2d614058 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -273,6 +273,7 @@ NEXTPNR_NAMESPACE_BEGIN struct Context : Arch { bool verbose = false; + bool force = false; Context(ArchArgs args) : Arch(args) {} @@ -290,10 +291,7 @@ struct Context : Arch return rngstate * 0x2545F4914F6CDD1D; } - int rng() - { - return rng64() & 0x3fffffff; - } + int rng() { return rng64() & 0x3fffffff; } int rng(int n) { @@ -309,22 +307,25 @@ struct Context : Arch m += 1; while (1) { - int x = rng64() & (m-1); - if (x < n) return x; + int x = rng64() & (m - 1); + if (x < n) + return x; } } void rngseed(uint64_t seed) { rngstate = seed ? seed : 0x3141592653589793; - for (int i = 0; i < 5; i++) rng64(); + for (int i = 0; i < 5; i++) + rng64(); } - template<typename T> - void shuffle(std::vector<T> &a) { + template <typename T> void shuffle(std::vector<T> &a) + { for (size_t i = 0; i != a.size(); i++) { size_t j = i + rng(a.size() - i); - if (j > i) std::swap(a[i], a[j]); + if (j > i) + std::swap(a[i], a[j]); } } }; diff --git a/common/place_sa.cc b/common/place_sa.cc index 91711266..c94c8699 100644 --- a/common/place_sa.cc +++ b/common/place_sa.cc @@ -259,7 +259,7 @@ BelId random_bel_for_cell(Context *ctx, CellInfo *cell, SAState &state) } } -void place_design_sa(Context *ctx) +bool place_design_sa(Context *ctx) { SAState state; state.checker = new PlaceValidityChecker(ctx); @@ -294,9 +294,10 @@ void place_design_sa(Context *ctx) visit_cells.push(cell); } } - log_info("place_constraints placed %d\n", int(placed_cells)); - std::vector<CellInfo *> autoplaced; + log_info("Placed %d cells based on constraints.\n", int(placed_cells)); + // Sort to-place cells for deterministic initial placement + std::vector<CellInfo *> autoplaced; for (auto cell : ctx->cells) { CellInfo *ci = cell.second; if (ci->bel == BelId()) { @@ -305,11 +306,18 @@ void place_design_sa(Context *ctx) } std::sort(autoplaced.begin(), autoplaced.end(), [](CellInfo *a, CellInfo *b) { return a->name < b->name; }); + ctx->shuffle(autoplaced); + // Place cells randomly initially + log_info("Creating initial placement for remaining %d cells.\n", + int(autoplaced.size())); for (auto cell : autoplaced) { place_initial(ctx, cell, state.checker); placed_cells++; } + + log_info("Running simulated annealing placer.\n"); + // Build up a fast position/type to Bel lookup table int max_x = 0, max_y = 0; int bel_types = 0; @@ -335,6 +343,7 @@ void place_design_sa(Context *ctx) state.fast_bels.at(type_idx).at(x).at(y).push_back(bel); } state.diameter = std::max(max_x, max_y) + 1; + // Calculate wirelength after initial placement state.curr_wirelength = 0; for (auto net : ctx->nets) { @@ -352,9 +361,9 @@ void place_design_sa(Context *ctx) state.n_move = state.n_accept = 0; state.improved = false; - if (iter % 5 == 0) - log(" at iteration #%d: temp = %f, wire length = %f\n", iter, - state.temp, state.curr_wirelength); + if (iter % 5 == 0 || iter == 1) + log_info(" at iteration #%d: temp = %f, wire length = %f\n", iter, + state.temp, state.curr_wirelength); for (int m = 0; m < 15; ++m) { // Loop through all automatically placed cells @@ -374,8 +383,12 @@ void place_design_sa(Context *ctx) } else ++n_no_progress; - if (state.temp <= 1e-3 && n_no_progress >= 5) + if (state.temp <= 1e-3 && n_no_progress >= 5) { + if (iter % 5 != 0) + log_info(" at iteration #%d: temp = %f, wire length = %f\n", + iter, state.temp, state.curr_wirelength); break; + } double Raccept = (double)state.n_accept / (double)state.n_move; @@ -415,6 +428,7 @@ void place_design_sa(Context *ctx) } } delete state.checker; + return true; } NEXTPNR_NAMESPACE_END diff --git a/common/place_sa.h b/common/place_sa.h index 8eb4fe77..3c49c031 100644 --- a/common/place_sa.h +++ b/common/place_sa.h @@ -23,7 +23,7 @@ NEXTPNR_NAMESPACE_BEGIN -extern void place_design_sa(Context *ctx); +extern bool place_design_sa(Context *ctx); NEXTPNR_NAMESPACE_END diff --git a/common/route.cc b/common/route.cc index 04f0f4c2..d623b2cf 100644 --- a/common/route.cc +++ b/common/route.cc @@ -67,7 +67,8 @@ struct Router delay_t maxDelay = 0.0; WireId failedDest; - Router(Context *ctx, IdString net_name, bool ripup = false, delay_t ripup_penalty = 0) + Router(Context *ctx, IdString net_name, bool ripup = false, + delay_t ripup_penalty = 0) { auto net_info = ctx->nets.at(net_name); @@ -438,7 +439,8 @@ bool route_design(Context *ctx) netCnt = 0; int ripCnt = 0; - std::vector<IdString> ripupArray(ripupQueue.begin(), ripupQueue.end()); + std::vector<IdString> ripupArray(ripupQueue.begin(), + ripupQueue.end()); ctx->shuffle(ripupArray); for (auto net_name : ripupArray) { @@ -447,7 +449,8 @@ bool route_design(Context *ctx) net_name.c_str(ctx), int(ctx->nets.at(net_name)->users.size())); - Router router(ctx, net_name, true, ripup_penalty * (iterCnt - 1)); + Router router(ctx, net_name, true, + ripup_penalty * (iterCnt - 1)); netCnt++; visitCnt += router.visitCnt; diff --git a/frontend/json/jsonparse.cc b/frontend/json/jsonparse.cc index b3d6f718..cfe2739c 100644 --- a/frontend/json/jsonparse.cc +++ b/frontend/json/jsonparse.cc @@ -748,12 +748,11 @@ void json_import(Context *ctx, string modname, JsonNode *node) int netid = bits->data_array.at(i)->data_number; if (netid >= netnames.size()) netnames.resize(netid + 1); - netnames.at(netid) = - ctx->id(basename + - (num_bits == 1 ? "" - : std::string("[") + - std::to_string(i) + - std::string("]"))); + netnames.at(netid) = ctx->id( + basename + + (num_bits == 1 ? "" : std::string("[") + + std::to_string(i) + + std::string("]"))); } } } diff --git a/ice40/arch.h b/ice40/arch.h index 290bc9d3..c1256a41 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -282,6 +282,7 @@ template <> struct hash<NEXTPNR_NAMESPACE_PREFIX PipId> template <> struct hash<NEXTPNR_NAMESPACE_PREFIX BelType> : hash<int> { }; + template <> struct hash<NEXTPNR_NAMESPACE_PREFIX PortPin> : hash<int> { }; diff --git a/ice40/main.cc b/ice40/main.cc index 0ea3dc98..802a08b8 100644 --- a/ice40/main.cc +++ b/ice40/main.cc @@ -68,6 +68,7 @@ int main(int argc, char *argv[]) po::options_description options("Allowed options"); options.add_options()("help,h", "show help"); options.add_options()("verbose,v", "verbose output"); + options.add_options()("force,f", "keep running after errors"); options.add_options()("gui", "start gui"); options.add_options()("svg", "dump SVG file"); options.add_options()("pack-only", @@ -196,6 +197,10 @@ int main(int argc, char *argv[]) ctx.verbose = true; } + if (vm.count("force")) { + ctx.force = true; + } + if (vm.count("seed")) { ctx.rngseed(vm["seed"].as<int>()); } @@ -225,12 +230,16 @@ int main(int argc, char *argv[]) apply_pcf(&ctx, pcf); } - pack_design(&ctx); + if (!pack_design(&ctx) && !ctx.force) + log_error("Packing design failed.\n"); + print_utilisation(&ctx); if (!vm.count("pack-only")) { - place_design_sa(&ctx); - route_design(&ctx); + if (!place_design_sa(&ctx) && !ctx.force) + log_error("Placing design failed.\n"); + if (!route_design(&ctx) && !ctx.force) + log_error("Routing design failed.\n"); } } diff --git a/ice40/pack.cc b/ice40/pack.cc index 0eb6f77d..d3f07118 100644 --- a/ice40/pack.cc +++ b/ice40/pack.cc @@ -405,7 +405,7 @@ static void promote_globals(Context *ctx) } // Main pack function -void pack_design(Context *ctx) +bool pack_design(Context *ctx) { pack_constants(ctx); promote_globals(ctx); @@ -413,6 +413,7 @@ void pack_design(Context *ctx) pack_lut_lutffs(ctx); pack_nonlut_ffs(ctx); pack_ram(ctx); + return true; } NEXTPNR_NAMESPACE_END diff --git a/ice40/pack.h b/ice40/pack.h index 5495c986..92b76653 100644 --- a/ice40/pack.h +++ b/ice40/pack.h @@ -25,7 +25,7 @@ NEXTPNR_NAMESPACE_BEGIN -void pack_design(Context *ctx); +bool pack_design(Context *ctx); NEXTPNR_NAMESPACE_END |