Merge pull request #149 from smunaut/issue_148
Fixes for global promotion
This commit is contained in:
commit
86108bfd39
@ -337,9 +337,10 @@ class SAPlacer
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
uint64_t score = ctx->rng64();
|
uint64_t score = ctx->rng64();
|
||||||
if (score <= best_ripup_score) {
|
CellInfo *bound_cell = ctx->getBoundBelCell(bel);
|
||||||
|
if (score <= best_ripup_score && bound_cell->belStrength < STRENGTH_STRONG) {
|
||||||
best_ripup_score = score;
|
best_ripup_score = score;
|
||||||
ripup_target = ctx->getBoundBelCell(bel);
|
ripup_target = bound_cell;
|
||||||
ripup_bel = bel;
|
ripup_bel = bel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -884,6 +884,13 @@ struct Arch : BaseCtx
|
|||||||
}
|
}
|
||||||
NPNR_ASSERT_FALSE("Expected PLL pin to share an output with an SB_IO D_IN_{0,1}");
|
NPNR_ASSERT_FALSE("Expected PLL pin to share an output with an SB_IO D_IN_{0,1}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int getDrivenGlobalNetwork(BelId bel) const
|
||||||
|
{
|
||||||
|
NPNR_ASSERT(getBelType(bel) == id_SB_GB);
|
||||||
|
IdString glb_net = getWireName(getBelPinWire(bel, id_GLOBAL_BUFFER_OUTPUT));
|
||||||
|
return std::stoi(std::string("") + glb_net.str(this).back());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void ice40DelayFuzzerMain(Context *ctx);
|
void ice40DelayFuzzerMain(Context *ctx);
|
||||||
|
@ -165,8 +165,7 @@ bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const
|
|||||||
return true;
|
return true;
|
||||||
NPNR_ASSERT(cell->ports.at(id_GLOBAL_BUFFER_OUTPUT).net != nullptr);
|
NPNR_ASSERT(cell->ports.at(id_GLOBAL_BUFFER_OUTPUT).net != nullptr);
|
||||||
const NetInfo *net = cell->ports.at(id_GLOBAL_BUFFER_OUTPUT).net;
|
const NetInfo *net = cell->ports.at(id_GLOBAL_BUFFER_OUTPUT).net;
|
||||||
IdString glb_net = getWireName(getBelPinWire(bel, id_GLOBAL_BUFFER_OUTPUT));
|
int glb_id = getDrivenGlobalNetwork(bel);
|
||||||
int glb_id = std::stoi(std::string("") + glb_net.str(this).back());
|
|
||||||
if (net->is_reset && net->is_enable)
|
if (net->is_reset && net->is_enable)
|
||||||
return false;
|
return false;
|
||||||
else if (net->is_reset)
|
else if (net->is_reset)
|
||||||
|
@ -587,10 +587,36 @@ static void promote_globals(Context *ctx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
int prom_globals = 0, prom_resets = 0, prom_cens = 0, prom_logics = 0;
|
int prom_globals = 0, prom_resets = 0, prom_cens = 0, prom_logics = 0;
|
||||||
int gbs_available = 8;
|
int gbs_available = 8, resets_available = 4, cens_available = 4;
|
||||||
for (auto &cell : ctx->cells)
|
for (auto &cell : ctx->cells)
|
||||||
if (is_gbuf(ctx, cell.second.get()))
|
if (is_gbuf(ctx, cell.second.get())) {
|
||||||
|
/* One less buffer available */
|
||||||
--gbs_available;
|
--gbs_available;
|
||||||
|
|
||||||
|
/* And possibly limits what we can promote */
|
||||||
|
if (cell.second->attrs.find(ctx->id("BEL")) != cell.second->attrs.end()) {
|
||||||
|
/* If the SB_GB is locked, doesn't matter what it drives */
|
||||||
|
BelId bel = ctx->getBelByName(ctx->id(cell.second->attrs[ctx->id("BEL")]));
|
||||||
|
int glb_id = ctx->getDrivenGlobalNetwork(bel);
|
||||||
|
if ((glb_id % 2) == 0)
|
||||||
|
resets_available--;
|
||||||
|
else if ((glb_id % 2) == 1)
|
||||||
|
cens_available--;
|
||||||
|
} else {
|
||||||
|
/* If it's free to move around, then look at what it drives */
|
||||||
|
NetInfo *ni = cell.second->ports[id_GLOBAL_BUFFER_OUTPUT].net;
|
||||||
|
|
||||||
|
for (auto user : ni->users) {
|
||||||
|
if (is_reset_port(ctx, user)) {
|
||||||
|
resets_available--;
|
||||||
|
break;
|
||||||
|
} else if (is_enable_port(ctx, user)) {
|
||||||
|
cens_available--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
while (prom_globals < gbs_available) {
|
while (prom_globals < gbs_available) {
|
||||||
auto global_clock = std::max_element(clock_count.begin(), clock_count.end(),
|
auto global_clock = std::max_element(clock_count.begin(), clock_count.end(),
|
||||||
[](const std::pair<IdString, int> &a, const std::pair<IdString, int> &b) {
|
[](const std::pair<IdString, int> &a, const std::pair<IdString, int> &b) {
|
||||||
@ -610,8 +636,8 @@ static void promote_globals(Context *ctx)
|
|||||||
return a.second < b.second;
|
return a.second < b.second;
|
||||||
});
|
});
|
||||||
if (global_clock->second == 0 && prom_logics < 4 && global_logic->second > logic_fanout_thresh &&
|
if (global_clock->second == 0 && prom_logics < 4 && global_logic->second > logic_fanout_thresh &&
|
||||||
(global_logic->second > global_cen->second || prom_cens >= 4) &&
|
(global_logic->second > global_cen->second || prom_cens >= cens_available) &&
|
||||||
(global_logic->second > global_reset->second || prom_resets >= 4)) {
|
(global_logic->second > global_reset->second || prom_resets >= resets_available)) {
|
||||||
NetInfo *logicnet = ctx->nets[global_logic->first].get();
|
NetInfo *logicnet = ctx->nets[global_logic->first].get();
|
||||||
insert_global(ctx, logicnet, false, false, true);
|
insert_global(ctx, logicnet, false, false, true);
|
||||||
++prom_globals;
|
++prom_globals;
|
||||||
@ -620,7 +646,7 @@ static void promote_globals(Context *ctx)
|
|||||||
reset_count.erase(logicnet->name);
|
reset_count.erase(logicnet->name);
|
||||||
cen_count.erase(logicnet->name);
|
cen_count.erase(logicnet->name);
|
||||||
logic_count.erase(logicnet->name);
|
logic_count.erase(logicnet->name);
|
||||||
} else if (global_reset->second > global_clock->second && prom_resets < 4) {
|
} else if (global_reset->second > global_clock->second && prom_resets < resets_available) {
|
||||||
NetInfo *rstnet = ctx->nets[global_reset->first].get();
|
NetInfo *rstnet = ctx->nets[global_reset->first].get();
|
||||||
insert_global(ctx, rstnet, true, false, false);
|
insert_global(ctx, rstnet, true, false, false);
|
||||||
++prom_globals;
|
++prom_globals;
|
||||||
@ -629,7 +655,7 @@ static void promote_globals(Context *ctx)
|
|||||||
reset_count.erase(rstnet->name);
|
reset_count.erase(rstnet->name);
|
||||||
cen_count.erase(rstnet->name);
|
cen_count.erase(rstnet->name);
|
||||||
logic_count.erase(rstnet->name);
|
logic_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 < cens_available &&
|
||||||
global_cen->second > enable_fanout_thresh) {
|
global_cen->second > enable_fanout_thresh) {
|
||||||
NetInfo *cennet = ctx->nets[global_cen->first].get();
|
NetInfo *cennet = ctx->nets[global_cen->first].get();
|
||||||
insert_global(ctx, cennet, false, true, false);
|
insert_global(ctx, cennet, false, true, false);
|
||||||
|
Loading…
Reference in New Issue
Block a user