place_sa: Add a rip-up feature when initial placement fails

Signed-off-by: David Shah <davey1576@gmail.com>
This commit is contained in:
David Shah 2018-06-17 14:36:19 +02:00
parent 153b800f6a
commit 681c9654d7
3 changed files with 60 additions and 30 deletions

View File

@ -72,33 +72,58 @@ static int random_int_between(rnd_state &rnd, int a, int b)
// Initial random placement // Initial random placement
static void place_initial(Design *design, CellInfo *cell, rnd_state &rnd) static void place_initial(Design *design, CellInfo *cell, rnd_state &rnd)
{ {
BelId best_bel = BelId(); bool all_placed = false;
float best_score = std::numeric_limits<float>::infinity(); int iters = 25;
Chip &chip = design->chip; while(!all_placed) {
if (cell->bel != BelId()) { BelId best_bel = BelId();
chip.unbindBel(cell->bel); float best_score = std::numeric_limits<float>::infinity(), best_ripup_score = std::numeric_limits<float>::infinity();
cell->bel = BelId(); Chip &chip = design->chip;
} CellInfo *ripup_target = nullptr;
BelType targetType = belTypeFromId(cell->type); BelId ripup_bel = BelId();
for (auto bel : chip.getBels()) { if (cell->bel != BelId()) {
if (chip.getBelType(bel) == targetType && chip.checkBelAvail(bel) && chip.unbindBel(cell->bel);
isValidBelForCell(design, cell, bel)) { cell->bel = BelId();
float score = random_float_upto(rnd, 1.0); }
if (score <= best_score) { BelType targetType = belTypeFromId(cell->type);
best_score = score; for (auto bel : chip.getBels()) {
best_bel = bel; if (chip.getBelType(bel) == targetType && isValidBelForCell(design, cell, bel)) {
if (chip.checkBelAvail(bel)) {
float score = random_float_upto(rnd, 1.0);
if (score <= best_score) {
best_score = score;
best_bel = bel;
}
} else {
float score = random_float_upto(rnd, 1.0);
if (score <= best_ripup_score) {
best_ripup_score = score;
ripup_target = design->cells.at(chip.getBelCell(bel, true));
ripup_bel = bel;
}
}
} }
} }
} if (best_bel == BelId()) {
if (best_bel == BelId()) { if (iters == 0 || ripup_bel == BelId())
log_error("failed to place cell '%s' of type '%s'\n", log_error("failed to place cell '%s' of type '%s'\n",
cell->name.c_str(), cell->type.c_str()); cell->name.c_str(), cell->type.c_str());
} --iters;
cell->bel = best_bel; chip.unbindBel(ripup_target->bel);
chip.bindBel(cell->bel, cell->name); ripup_target->bel = BelId();
best_bel = ripup_bel;
} else {
all_placed = true;
}
cell->bel = best_bel;
chip.bindBel(cell->bel, cell->name);
// Back annotate location
cell->attrs["BEL"] = chip.getBelName(cell->bel).str();
cell = ripup_target;
}
// Back annotate location
cell->attrs["BEL"] = chip.getBelName(cell->bel).str();
} }
// Stores the state of the SA placer // Stores the state of the SA placer

View File

@ -38,7 +38,8 @@ static bool logicCellsCompatible(const std::vector<const CellInfo *> &cells)
{ {
bool dffs_exist = false, dffs_neg = false; bool dffs_exist = false, dffs_neg = false;
const NetInfo *cen = nullptr, *clk = nullptr, *sr = nullptr; const NetInfo *cen = nullptr, *clk = nullptr, *sr = nullptr;
std::unordered_set<const NetInfo *> locals; static std::unordered_set<const NetInfo *> locals;
locals.clear();
for (auto cell : cells) { for (auto cell : cells) {
if (bool_or_default(cell->params, "DFF_ENABLE")) { if (bool_or_default(cell->params, "DFF_ENABLE")) {

View File

@ -279,7 +279,9 @@ static void pack_io(Design *design)
static void insert_global(Design *design, NetInfo *net, bool is_reset, static void insert_global(Design *design, NetInfo *net, bool is_reset,
bool is_cen) bool is_cen)
{ {
CellInfo *gb = create_ice_cell(design, "SB_GB"); std::string glb_name = net->name.str() + std::string("_$glb_") +
(is_reset ? "sr" : (is_cen ? "ce" : "clk"));
CellInfo *gb = create_ice_cell(design, "SB_GB", "$gbuf_" + glb_name);
gb->ports["USER_SIGNAL_TO_GLOBAL_BUFFER"].net = net; gb->ports["USER_SIGNAL_TO_GLOBAL_BUFFER"].net = net;
PortRef pr; PortRef pr;
pr.cell = gb; pr.cell = gb;
@ -289,8 +291,7 @@ static void insert_global(Design *design, NetInfo *net, bool is_reset,
pr.cell = gb; pr.cell = gb;
pr.port = "GLOBAL_BUFFER_OUTPUT"; pr.port = "GLOBAL_BUFFER_OUTPUT";
NetInfo *glbnet = new NetInfo(); NetInfo *glbnet = new NetInfo();
glbnet->name = net->name.str() + std::string("_glb_") + glbnet->name = glb_name;
(is_reset ? "sr" : (is_cen ? "ce" : "clk"));
glbnet->driver = pr; glbnet->driver = pr;
design->nets[glbnet->name] = glbnet; design->nets[glbnet->name] = glbnet;
gb->ports["GLOBAL_BUFFER_OUTPUT"].net = glbnet; gb->ports["GLOBAL_BUFFER_OUTPUT"].net = glbnet;
@ -363,19 +364,22 @@ static void promote_globals(Design *design)
++prom_resets; ++prom_resets;
clock_count.erase(rstnet->name); clock_count.erase(rstnet->name);
reset_count.erase(rstnet->name); reset_count.erase(rstnet->name);
cen_count.erase(rstnet->name);
} else if (global_cen->second > global_clock->second && prom_cens < 4) { } else if (global_cen->second > global_clock->second && prom_cens < 4) {
NetInfo *cennet = design->nets[global_cen->first]; NetInfo *cennet = design->nets[global_cen->first];
insert_global(design, cennet, false, true); insert_global(design, cennet, false, true);
++prom_globals; ++prom_globals;
++prom_cens; ++prom_cens;
cen_count.erase(cennet->name);
clock_count.erase(cennet->name); clock_count.erase(cennet->name);
reset_count.erase(cennet->name);
cen_count.erase(cennet->name);
} else if (global_clock->second != 0) { } else if (global_clock->second != 0) {
NetInfo *clknet = design->nets[global_clock->first]; NetInfo *clknet = design->nets[global_clock->first];
insert_global(design, clknet, false, false); insert_global(design, clknet, false, false);
++prom_globals; ++prom_globals;
clock_count.erase(clknet->name); clock_count.erase(clknet->name);
reset_count.erase(clknet->name);
cen_count.erase(clknet->name);
} else { } else {
break; break;
} }