Support post-routing CSC and SCC
This commit is contained in:
parent
9ba4e1381d
commit
fb4171a63d
@ -366,8 +366,8 @@ def create_tile_types(ch: Chip, bels, bel_pins, crossbars, interconnects, muxes,
|
||||
vi.extra_data = PipExtraData(ch.strs.id(name),PIP_EXTRA_VIRTUAL,0,0)
|
||||
vi = tt.create_pip(f"{name}.DJ",f"{name}.DC","Virtual")
|
||||
vi.extra_data = PipExtraData(ch.strs.id(name),PIP_EXTRA_VIRTUAL,0,0)
|
||||
#vi = tt.create_pip(f"{name}.DJ",f"{name}.DS","Virtual")
|
||||
#vi.extra_data = PipExtraData(ch.strs.id(name),PIP_EXTRA_VIRTUAL,0,0)
|
||||
vi = tt.create_pip(f"{name}.DJ",f"{name}.DS","Virtual")
|
||||
vi.extra_data = PipExtraData(ch.strs.id(name),PIP_EXTRA_VIRTUAL,0,0)
|
||||
vi = tt.create_pip(f"{name}.DJ",f"{name}.DK","Virtual")
|
||||
vi.extra_data = PipExtraData(ch.strs.id(name),PIP_EXTRA_VIRTUAL,0,0)
|
||||
# DFF bypass
|
||||
|
@ -262,12 +262,60 @@ bool NgUltraImpl::get_mux_data(WireId wire, uint8_t *value)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NgUltraImpl::update_bff_to_csc(CellInfo *cell, BelId bel, PipId dst_pip)
|
||||
{
|
||||
const auto &bel_data = chip_bel_info(ctx->chip_info, bel);
|
||||
const auto &extra_data = *reinterpret_cast<const NGUltraBelExtraDataPOD *>(bel_data.extra_data.get());
|
||||
// Check if CSC mode only if FE is capable
|
||||
if (extra_data.flags & BEL_EXTRA_FE_CSC) {
|
||||
WireId dwire = ctx->getPipDstWire(dst_pip);
|
||||
for (PipId pip : ctx->getPipsDownhill(dwire)) {
|
||||
if (!ctx->getBoundPipNet(pip))
|
||||
continue;
|
||||
for (PipId pip2 : ctx->getPipsDownhill(ctx->getPipDstWire(pip))) {
|
||||
if (!ctx->getBoundPipNet(pip2))
|
||||
continue;
|
||||
IdString dst = ctx->getWireName(ctx->getPipDstWire(pip2))[1];
|
||||
if (boost::ends_with(dst.c_str(ctx),".DS")) {
|
||||
cell->setParam(ctx->id("type"), Property("CSC"));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NgUltraImpl::update_bff_to_scc(CellInfo *cell, BelId bel, PipId dst_pip)
|
||||
{
|
||||
const auto &bel_data = chip_bel_info(ctx->chip_info, bel);
|
||||
const auto &extra_data = *reinterpret_cast<const NGUltraBelExtraDataPOD *>(bel_data.extra_data.get());
|
||||
// Check if SCC mode only if FE is capable
|
||||
if (extra_data.flags & BEL_EXTRA_FE_SCC) {
|
||||
WireId dwire = ctx->getPipDstWire(dst_pip);
|
||||
for (PipId pip : ctx->getPipsUphill(dwire)) {
|
||||
if (!ctx->getBoundPipNet(pip))
|
||||
continue;
|
||||
for (PipId pip2 : ctx->getPipsUphill(ctx->getPipSrcWire(pip))) {
|
||||
if (!ctx->getBoundPipNet(pip2))
|
||||
continue;
|
||||
IdString dst = ctx->getWireName(ctx->getPipSrcWire(pip2))[1];
|
||||
if (boost::starts_with(dst.c_str(ctx),"SYSTEM.ST1")) {
|
||||
cell->setParam(ctx->id("type"), Property("SCC"));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void NgUltraImpl::postRoute()
|
||||
{
|
||||
ctx->assignArchInfo();
|
||||
log_break();
|
||||
log_info("Resources spent on routing:\n");
|
||||
int dff_bypass = 0, lut_bypass = 0, fe_new = 0, wfg_bypass = 0, gck_bypass = 0;
|
||||
int bff_count = 0, csc_count = 0, scc_count = 0, lut_bypass = 0, fe_new = 0, wfg_bypass = 0, gck_bypass = 0;
|
||||
for (auto &net : ctx->nets) {
|
||||
NetInfo *ni = net.second.get();
|
||||
for (auto &w : ni->wires) {
|
||||
@ -288,10 +336,16 @@ void NgUltraImpl::postRoute()
|
||||
switch(type.index) {
|
||||
case id_BEYOND_FE.index :
|
||||
if (extra_data.input==0) {
|
||||
dff_bypass++;
|
||||
// set bypass mode for DFF
|
||||
cell->setParam(ctx->id("type"), Property("BFF"));
|
||||
cell->params[id_dff_used] = Property(1,1);
|
||||
// Note: no conflict, CSC and SCC modes are never available on same position
|
||||
if (update_bff_to_csc(cell, bel, w.second.pip))
|
||||
csc_count++;
|
||||
else if(update_bff_to_scc(cell, bel, w.second.pip))
|
||||
scc_count++;
|
||||
else
|
||||
bff_count++;
|
||||
} else {
|
||||
lut_bypass++;
|
||||
cell->params[id_lut_used] = Property(1,1);
|
||||
@ -311,11 +365,20 @@ void NgUltraImpl::postRoute()
|
||||
}
|
||||
}
|
||||
}
|
||||
log_info(" %6d DFFs used in bypass mode (BFF)\n", dff_bypass);
|
||||
log_info(" %6d LUTs used in bypass mode\n", lut_bypass);
|
||||
log_info(" %6d newly allocated FEs\n", fe_new);
|
||||
log_info(" %6d WFGs used as WFB\n", wfg_bypass);
|
||||
log_info(" %6d GCK\n", gck_bypass);
|
||||
if (bff_count)
|
||||
log_info(" %6d DFFs used as BFF\n", bff_count);
|
||||
if (csc_count)
|
||||
log_info(" %6d DFFs used as CSC\n", csc_count);
|
||||
if (scc_count)
|
||||
log_info(" %6d DFFs used as SCC\n", scc_count);
|
||||
if(lut_bypass)
|
||||
log_info(" %6d LUTs used in bypass mode\n", lut_bypass);
|
||||
if (fe_new)
|
||||
log_info(" %6d newly allocated FEs\n", fe_new);
|
||||
if (wfg_bypass)
|
||||
log_info(" %6d WFGs used as WFB\n", wfg_bypass);
|
||||
if (gck_bypass)
|
||||
log_info(" %6d GCK\n", gck_bypass);
|
||||
|
||||
// Handle LUT permutation
|
||||
for (auto &cell : ctx->cells) {
|
||||
|
@ -99,6 +99,9 @@ TESTABLE_PRIVATE:
|
||||
void route_lowskew();
|
||||
void parse_csv(const std::string &filename);
|
||||
void remove_constants();
|
||||
bool update_bff_to_csc(CellInfo *cell, BelId bel, PipId dst_pip);
|
||||
bool update_bff_to_scc(CellInfo *cell, BelId bel, PipId dst_pip);
|
||||
void disable_beyond_fe_s_output(BelId bel);
|
||||
|
||||
// Misc utility functions
|
||||
bool get_mux_data(BelId bel, IdString port, uint8_t *value);
|
||||
|
@ -1984,35 +1984,58 @@ void NgUltraPacker::pre_place(void)
|
||||
}
|
||||
}
|
||||
|
||||
void NgUltraImpl::disable_beyond_fe_s_output(BelId bel)
|
||||
{
|
||||
WireId dwire = ctx->getBelPinWire(bel, id_DO);
|
||||
for (PipId pip : ctx->getPipsDownhill(dwire)) {
|
||||
for (PipId pip2 : ctx->getPipsDownhill(ctx->getPipDstWire(pip))) {
|
||||
IdString dst = ctx->getWireName(ctx->getPipDstWire(pip2))[1];
|
||||
if (boost::ends_with(dst.c_str(ctx),".DS")) {
|
||||
blocked_pips.emplace(pip2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NgUltraImpl::postPlace()
|
||||
{
|
||||
log_break();
|
||||
log_info("Limiting routing...\n");
|
||||
for (auto &cell : ctx->cells) {
|
||||
CellInfo &ci = *cell.second;
|
||||
if (!ci.type.in(id_CY))
|
||||
continue;
|
||||
// In case A input is actually used, but it is connectd to GND
|
||||
// it is considered that signal is comming from RI1 crossbar.
|
||||
// We need to prevent router to use that crossbar output for
|
||||
// any other signal.
|
||||
for (int i=1;i<=4;i++) {
|
||||
IdString port = ctx->idf("A%d",i);
|
||||
NetInfo *net = ci.getPort(port);
|
||||
if (!net)
|
||||
continue;
|
||||
if (net->name.in(ctx->id("$PACKER_GND"))) {
|
||||
WireId dwire = ctx->getBelPinWire(ci.bel, port);
|
||||
for (PipId pip : ctx->getPipsUphill(dwire)) {
|
||||
WireId src = ctx->getPipSrcWire(pip);
|
||||
const std::string src_name = ctx->getWireName(src)[1].str(ctx);
|
||||
if (boost::starts_with(src_name,"RI1")) {
|
||||
for (PipId pip2 : ctx->getPipsDownhill(src)) {
|
||||
blocked_pips.emplace(pip2);
|
||||
if (ci.type == id_BEYOND_FE) {
|
||||
const auto &bel_data = chip_bel_info(ctx->chip_info, ci.bel);
|
||||
const auto &extra_data = *reinterpret_cast<const NGUltraBelExtraDataPOD *>(bel_data.extra_data.get());
|
||||
// Check if CSC mode only if FE is capable
|
||||
if ((extra_data.flags & BEL_EXTRA_FE_CSC)) {
|
||||
if (str_or_default(ci.params, ctx->id("type"), "")!="DFF") continue;
|
||||
// Disable routing to S output if DFF used
|
||||
disable_beyond_fe_s_output(ci.bel);
|
||||
}
|
||||
} else if (ci.type == id_CY) {
|
||||
// In case A input is actually used, but it is connectd to GND
|
||||
// it is considered that signal is comming from RI1 crossbar.
|
||||
// We need to prevent router to use that crossbar output for
|
||||
// any other signal.
|
||||
for (int i=1;i<=4;i++) {
|
||||
IdString port = ctx->idf("A%d",i);
|
||||
NetInfo *net = ci.getPort(port);
|
||||
if (!net)
|
||||
continue;
|
||||
if (net->name.in(ctx->id("$PACKER_GND"))) {
|
||||
WireId dwire = ctx->getBelPinWire(ci.bel, port);
|
||||
for (PipId pip : ctx->getPipsUphill(dwire)) {
|
||||
WireId src = ctx->getPipSrcWire(pip);
|
||||
const std::string src_name = ctx->getWireName(src)[1].str(ctx);
|
||||
if (boost::starts_with(src_name,"RI1")) {
|
||||
for (PipId pip2 : ctx->getPipsDownhill(src)) {
|
||||
blocked_pips.emplace(pip2);
|
||||
}
|
||||
}
|
||||
}
|
||||
ci.disconnectPort(port); // Disconnect A
|
||||
}
|
||||
ci.disconnectPort(port); // Disconnect A
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user