Working on debugging the carry legaliser

Signed-off-by: David Shah <davey1576@gmail.com>
This commit is contained in:
David Shah 2018-06-26 15:06:59 +02:00
parent 29df577f14
commit 6f12f2b7e8
5 changed files with 64 additions and 16 deletions

View File

@ -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

View File

@ -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

View File

@ -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");
}

View File

@ -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;
@ -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;

View File

@ -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;