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.extra_data = PipExtraData(ch.strs.id(name),PIP_EXTRA_VIRTUAL,0,0)
|
||||||
vi = tt.create_pip(f"{name}.DJ",f"{name}.DC","Virtual")
|
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.extra_data = PipExtraData(ch.strs.id(name),PIP_EXTRA_VIRTUAL,0,0)
|
||||||
#vi = tt.create_pip(f"{name}.DJ",f"{name}.DS","Virtual")
|
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.extra_data = PipExtraData(ch.strs.id(name),PIP_EXTRA_VIRTUAL,0,0)
|
||||||
vi = tt.create_pip(f"{name}.DJ",f"{name}.DK","Virtual")
|
vi = tt.create_pip(f"{name}.DJ",f"{name}.DK","Virtual")
|
||||||
vi.extra_data = PipExtraData(ch.strs.id(name),PIP_EXTRA_VIRTUAL,0,0)
|
vi.extra_data = PipExtraData(ch.strs.id(name),PIP_EXTRA_VIRTUAL,0,0)
|
||||||
# DFF bypass
|
# DFF bypass
|
||||||
|
@ -262,12 +262,60 @@ bool NgUltraImpl::get_mux_data(WireId wire, uint8_t *value)
|
|||||||
return false;
|
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()
|
void NgUltraImpl::postRoute()
|
||||||
{
|
{
|
||||||
ctx->assignArchInfo();
|
ctx->assignArchInfo();
|
||||||
log_break();
|
log_break();
|
||||||
log_info("Resources spent on routing:\n");
|
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) {
|
for (auto &net : ctx->nets) {
|
||||||
NetInfo *ni = net.second.get();
|
NetInfo *ni = net.second.get();
|
||||||
for (auto &w : ni->wires) {
|
for (auto &w : ni->wires) {
|
||||||
@ -288,10 +336,16 @@ void NgUltraImpl::postRoute()
|
|||||||
switch(type.index) {
|
switch(type.index) {
|
||||||
case id_BEYOND_FE.index :
|
case id_BEYOND_FE.index :
|
||||||
if (extra_data.input==0) {
|
if (extra_data.input==0) {
|
||||||
dff_bypass++;
|
|
||||||
// set bypass mode for DFF
|
// set bypass mode for DFF
|
||||||
cell->setParam(ctx->id("type"), Property("BFF"));
|
cell->setParam(ctx->id("type"), Property("BFF"));
|
||||||
cell->params[id_dff_used] = Property(1,1);
|
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 {
|
} else {
|
||||||
lut_bypass++;
|
lut_bypass++;
|
||||||
cell->params[id_lut_used] = Property(1,1);
|
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);
|
if (bff_count)
|
||||||
log_info(" %6d LUTs used in bypass mode\n", lut_bypass);
|
log_info(" %6d DFFs used as BFF\n", bff_count);
|
||||||
log_info(" %6d newly allocated FEs\n", fe_new);
|
if (csc_count)
|
||||||
log_info(" %6d WFGs used as WFB\n", wfg_bypass);
|
log_info(" %6d DFFs used as CSC\n", csc_count);
|
||||||
log_info(" %6d GCK\n", gck_bypass);
|
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
|
// Handle LUT permutation
|
||||||
for (auto &cell : ctx->cells) {
|
for (auto &cell : ctx->cells) {
|
||||||
|
@ -99,6 +99,9 @@ TESTABLE_PRIVATE:
|
|||||||
void route_lowskew();
|
void route_lowskew();
|
||||||
void parse_csv(const std::string &filename);
|
void parse_csv(const std::string &filename);
|
||||||
void remove_constants();
|
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
|
// Misc utility functions
|
||||||
bool get_mux_data(BelId bel, IdString port, uint8_t *value);
|
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()
|
void NgUltraImpl::postPlace()
|
||||||
{
|
{
|
||||||
log_break();
|
log_break();
|
||||||
log_info("Limiting routing...\n");
|
log_info("Limiting routing...\n");
|
||||||
for (auto &cell : ctx->cells) {
|
for (auto &cell : ctx->cells) {
|
||||||
CellInfo &ci = *cell.second;
|
CellInfo &ci = *cell.second;
|
||||||
if (!ci.type.in(id_CY))
|
if (ci.type == id_BEYOND_FE) {
|
||||||
continue;
|
const auto &bel_data = chip_bel_info(ctx->chip_info, ci.bel);
|
||||||
// In case A input is actually used, but it is connectd to GND
|
const auto &extra_data = *reinterpret_cast<const NGUltraBelExtraDataPOD *>(bel_data.extra_data.get());
|
||||||
// it is considered that signal is comming from RI1 crossbar.
|
// Check if CSC mode only if FE is capable
|
||||||
// We need to prevent router to use that crossbar output for
|
if ((extra_data.flags & BEL_EXTRA_FE_CSC)) {
|
||||||
// any other signal.
|
if (str_or_default(ci.params, ctx->id("type"), "")!="DFF") continue;
|
||||||
for (int i=1;i<=4;i++) {
|
// Disable routing to S output if DFF used
|
||||||
IdString port = ctx->idf("A%d",i);
|
disable_beyond_fe_s_output(ci.bel);
|
||||||
NetInfo *net = ci.getPort(port);
|
}
|
||||||
if (!net)
|
} else if (ci.type == id_CY) {
|
||||||
continue;
|
// In case A input is actually used, but it is connectd to GND
|
||||||
if (net->name.in(ctx->id("$PACKER_GND"))) {
|
// it is considered that signal is comming from RI1 crossbar.
|
||||||
WireId dwire = ctx->getBelPinWire(ci.bel, port);
|
// We need to prevent router to use that crossbar output for
|
||||||
for (PipId pip : ctx->getPipsUphill(dwire)) {
|
// any other signal.
|
||||||
WireId src = ctx->getPipSrcWire(pip);
|
for (int i=1;i<=4;i++) {
|
||||||
const std::string src_name = ctx->getWireName(src)[1].str(ctx);
|
IdString port = ctx->idf("A%d",i);
|
||||||
if (boost::starts_with(src_name,"RI1")) {
|
NetInfo *net = ci.getPort(port);
|
||||||
for (PipId pip2 : ctx->getPipsDownhill(src)) {
|
if (!net)
|
||||||
blocked_pips.emplace(pip2);
|
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