Working on debugging the carry legaliser
Signed-off-by: David Shah <davey1576@gmail.com>
This commit is contained in:
parent
29df577f14
commit
6f12f2b7e8
@ -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
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user