CDC packing
This commit is contained in:
parent
50485371fa
commit
61073f5aa7
@ -97,6 +97,38 @@ enum ClusterPlacement
|
||||
PLACE_XRF_WE,
|
||||
PLACE_XRF_WEA,
|
||||
PLACE_DSP_CHAIN,
|
||||
PLACE_CDC_AI1,
|
||||
PLACE_CDC_AI2,
|
||||
PLACE_CDC_AI3,
|
||||
PLACE_CDC_AI4,
|
||||
PLACE_CDC_AI5,
|
||||
PLACE_CDC_AI6,
|
||||
PLACE_CDC_BI1,
|
||||
PLACE_CDC_BI2,
|
||||
PLACE_CDC_BI3,
|
||||
PLACE_CDC_BI4,
|
||||
PLACE_CDC_BI5,
|
||||
PLACE_CDC_BI6,
|
||||
PLACE_CDC_ASRSTI,
|
||||
PLACE_CDC_ADRSTI,
|
||||
PLACE_CDC_BSRSTI,
|
||||
PLACE_CDC_BDRSTI,
|
||||
PLACE_CDC_CI1,
|
||||
PLACE_CDC_CI2,
|
||||
PLACE_CDC_CI3,
|
||||
PLACE_CDC_CI4,
|
||||
PLACE_CDC_CI5,
|
||||
PLACE_CDC_CI6,
|
||||
PLACE_CDC_DI1,
|
||||
PLACE_CDC_DI2,
|
||||
PLACE_CDC_DI3,
|
||||
PLACE_CDC_DI4,
|
||||
PLACE_CDC_DI5,
|
||||
PLACE_CDC_DI6,
|
||||
PLACE_CDC_CSRSTI,
|
||||
PLACE_CDC_CDRSTI,
|
||||
PLACE_CDC_DSRSTI,
|
||||
PLACE_CDC_DDRSTI,
|
||||
};
|
||||
|
||||
enum PipExtra
|
||||
|
@ -409,6 +409,14 @@ IdString NgUltraImpl::getBelBucketForCellType(IdString cell_type) const
|
||||
return id_RF;
|
||||
else if (cell_type.in(id_XHRF, id_XWRF, id_XPRF))
|
||||
return id_XRF;
|
||||
else if (cell_type.in(id_DDE, id_TDE, id_CDC, id_BGC, id_GBC))
|
||||
return id_CDC;
|
||||
else if (cell_type.in(id_XCDC))
|
||||
return id_XCDC;
|
||||
else if (cell_type.in(id_FIFO))
|
||||
return id_FIFO;
|
||||
else if (cell_type.in(id_XHFIFO, id_XWFIFO))
|
||||
return id_XFIFO;
|
||||
else if (cell_type.in(id_WFB, id_WFG))
|
||||
return id_WFG;
|
||||
else
|
||||
@ -430,6 +438,14 @@ bool NgUltraImpl::isValidBelForCellType(IdString cell_type, BelId bel) const
|
||||
return cell_type.in(id_RF,id_RFSP);
|
||||
else if (bel_type == id_XRF)
|
||||
return cell_type.in(id_XHRF,id_XWRF,id_XPRF);
|
||||
else if (bel_type == id_CDC)
|
||||
return cell_type.in(id_DDE, id_TDE, id_CDC, id_BGC, id_GBC);
|
||||
else if (bel_type == id_XCDC)
|
||||
return cell_type.in(id_XCDC);
|
||||
else if (bel_type == id_FIFO)
|
||||
return cell_type.in(id_FIFO);
|
||||
else if (bel_type == id_XFIFO)
|
||||
return cell_type.in(id_XHFIFO, id_XWFIFO);
|
||||
else if (bel_type == id_WFG)
|
||||
return cell_type.in(id_WFB,id_WFG);
|
||||
else
|
||||
@ -575,6 +591,109 @@ Loc getXRFFE(Loc root, int pos)
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Loc getCDCFE(Loc root, int pos)
|
||||
{
|
||||
static const std::vector<Loc> cdc1 =
|
||||
{
|
||||
Loc(+1, 0, 1), // AI1
|
||||
Loc(+1, 0, 2), // AI2
|
||||
Loc(+1, 0, 9), // AI3
|
||||
Loc(+1, 0, 17),// AI4
|
||||
Loc(+1, 0, 18),// AI5
|
||||
Loc(+1, 0, 25),// AI6
|
||||
|
||||
Loc(+1, 0, 3), // BI1
|
||||
Loc(+1, 0, 10),// BI2
|
||||
Loc(+1, 0, 11),// BI3
|
||||
Loc(+1, 0, 19),// BI4
|
||||
Loc(+1, 0, 26),// BI5
|
||||
Loc(+1, 0, 27),// BI6
|
||||
|
||||
Loc( 0, 0, 22),// ASRSTI
|
||||
Loc( 0, 0, 30),// ADRSTI
|
||||
Loc(+1, 0, 24),// BSRSTI
|
||||
Loc(+1, 0, 8), // BDRSTI
|
||||
};
|
||||
|
||||
static const std::vector<Loc> cdc2 =
|
||||
{
|
||||
Loc(-1, 0, 4), // AI1
|
||||
Loc(-1, 0, 5), // AI2
|
||||
Loc(-1, 0, 12),// AI3
|
||||
Loc(-1, 0, 20),// AI4
|
||||
Loc(-1, 0, 21),// AI5
|
||||
Loc(-1, 0, 28),// AI6
|
||||
|
||||
Loc(-1, 0, 6), // BI1
|
||||
Loc(-1, 0, 13),// BI2
|
||||
Loc(-1, 0, 14),// BI3
|
||||
Loc(-1, 0, 22),// BI4
|
||||
Loc(-1, 0, 29),// BI5
|
||||
Loc(-1, 0, 30),// BI6
|
||||
|
||||
Loc( 0, 0, 22),// ASRSTI
|
||||
Loc( 0, 0, 30),// ADRSTI
|
||||
Loc(-1, 0, 23),// BSRSTI
|
||||
Loc(-1, 0, 7), // BDRSTI
|
||||
};
|
||||
|
||||
static const std::vector<Loc> xcdc =
|
||||
{
|
||||
Loc( 0, 0, 1), // AI1
|
||||
Loc( 0, 0, 2), // AI2
|
||||
Loc( 0, 0, 9), // AI3
|
||||
Loc( 0, 0, 17),// AI4
|
||||
Loc( 0, 0, 18),// AI5
|
||||
Loc( 0, 0, 25),// AI6
|
||||
|
||||
Loc( 0, 0, 4), // BI1
|
||||
Loc( 0, 0, 5), // BI2
|
||||
Loc( 0, 0, 12),// BI3
|
||||
Loc( 0, 0, 20),// BI4
|
||||
Loc( 0, 0, 21),// BI5
|
||||
Loc( 0, 0, 28),// BI6
|
||||
|
||||
Loc(-1, 0, 22),// ASRSTI
|
||||
Loc(-1, 0, 30),// ADRSTI
|
||||
Loc(+1, 0, 22),// BSRSTI
|
||||
Loc(+1, 0, 30),// BDRSTI
|
||||
|
||||
Loc( 0, 0, 3), // CI1
|
||||
Loc( 0, 0, 10),// CI2
|
||||
Loc( 0, 0, 11),// CI3
|
||||
Loc( 0, 0, 19),// CI4
|
||||
Loc( 0, 0, 26),// CI5
|
||||
Loc( 0, 0, 27),// CI6
|
||||
|
||||
Loc( 0, 0, 6), // DI1
|
||||
Loc( 0, 0, 13),// DI2
|
||||
Loc( 0, 0, 14),// DI3
|
||||
Loc( 0, 0, 22),// DI4
|
||||
Loc( 0, 0, 29),// DI5
|
||||
Loc( 0, 0, 30),// DI6
|
||||
|
||||
Loc( 0, 0, 24),// CSRSTI
|
||||
Loc( 0, 0, 8), // CDRSTI
|
||||
Loc( 0, 0, 23),// DSRSTI
|
||||
Loc( 0, 0, 7), // DDRSTI
|
||||
};
|
||||
|
||||
Loc result;
|
||||
if (root.z == BEL_CDC_Z) {
|
||||
result = cdc1.at(pos);
|
||||
} else if (root.z == BEL_CDC_Z+1) {
|
||||
result = cdc2.at(pos);
|
||||
} else if (root.z == BEL_XCDC_Z) {
|
||||
result = xcdc.at(pos);
|
||||
} else {
|
||||
log_error("Trying to place CDC on wrong location.\n");
|
||||
}
|
||||
result.x += root.x;
|
||||
result.y = root.y;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool NgUltraImpl::getChildPlacement(const BaseClusterInfo *cluster, Loc root_loc,
|
||||
std::vector<std::pair<CellInfo *, BelId>> &placement) const
|
||||
{
|
||||
@ -589,6 +708,8 @@ bool NgUltraImpl::getChildPlacement(const BaseClusterInfo *cluster, Loc root_loc
|
||||
case PLACE_CY_FE4: return getCYFE(root_loc,3);
|
||||
case PLACE_XRF_I1 ... PLACE_XRF_WEA:
|
||||
return getXRFFE(root_loc, child->constr_z - PLACE_XRF_I1 );
|
||||
case PLACE_CDC_AI1 ... PLACE_CDC_DDRSTI:
|
||||
return getCDCFE(root_loc, child->constr_z - PLACE_CDC_AI1 );
|
||||
case PLACE_DSP_CHAIN : { Loc l = getNextLocInDSPChain(this, prev); prev = l; return l; }
|
||||
default:
|
||||
Loc result;
|
||||
|
@ -988,6 +988,172 @@ void NgUltraPacker::pack_rfs(void)
|
||||
flush_cells();
|
||||
}
|
||||
|
||||
void NgUltraPacker::pack_cdcs(void)
|
||||
{
|
||||
log_info("Packing CDCs..\n");
|
||||
int lut_only = 0, lut_and_ff = 0, dff_only = 0;
|
||||
for (auto &cell : ctx->cells) {
|
||||
CellInfo &ci = *cell.second;
|
||||
if (!ci.type.in(id_NX_CDC_U))
|
||||
continue;
|
||||
int mode = int_or_default(ci.params, ctx->id("mode"), 0);
|
||||
switch(mode) {
|
||||
case 0 : ci.type = id_DDE; break;
|
||||
case 1 : ci.type = id_TDE; break;
|
||||
case 2 : ci.type = id_CDC; break;
|
||||
case 3 : ci.type = id_BGC; break;
|
||||
case 4 : ci.type = id_GBC; break;
|
||||
case 5 : ci.type = id_XCDC; break;
|
||||
default:
|
||||
log_error("Unknown mode %d for cell '%s'.\n", mode, ci.name.c_str(ctx));
|
||||
}
|
||||
ci.cluster = ci.name;
|
||||
|
||||
// If unconnected, connect GND to inputs that are actually used as outputs
|
||||
for (int i = 1; i <= 6; i++) {
|
||||
if (ci.getPort(ctx->idf("AO%d",i))) {
|
||||
connect_gnd_if_unconnected(&ci, ctx->idf("AI%d",i));
|
||||
pack_xrf_input_and_output(&ci, ci.name, ctx->idf("AI%d",i), ctx->idf("AO%d",i), ClusterPlacement(PLACE_CDC_AI1 + i-1), lut_only, lut_and_ff, dff_only);
|
||||
} else
|
||||
disconnect_unused(&ci, ctx->idf("AI%d",i));
|
||||
if (ci.getPort(ctx->idf("BO%d",i))) {
|
||||
connect_gnd_if_unconnected(&ci, ctx->idf("BI%d",i));
|
||||
pack_xrf_input_and_output(&ci, ci.name, ctx->idf("BI%d",i), ctx->idf("BO%d",i), ClusterPlacement(PLACE_CDC_BI1 + i-1), lut_only, lut_and_ff, dff_only);
|
||||
} else
|
||||
disconnect_unused(&ci, ctx->idf("BI%d",i));
|
||||
if (ci.type.in(id_XCDC)) {
|
||||
if (ci.getPort(ctx->idf("CO%d",i))) {
|
||||
connect_gnd_if_unconnected(&ci, ctx->idf("CI%d",i));
|
||||
pack_xrf_input_and_output(&ci, ci.name, ctx->idf("CI%d",i), ctx->idf("CO%d",i), ClusterPlacement(PLACE_CDC_CI1 + i-1), lut_only, lut_and_ff, dff_only);
|
||||
} else
|
||||
disconnect_unused(&ci, ctx->idf("CI%d",i));
|
||||
if (ci.getPort(ctx->idf("DO%d",i))) {
|
||||
connect_gnd_if_unconnected(&ci, ctx->idf("DI%d",i));
|
||||
pack_xrf_input_and_output(&ci, ci.name, ctx->idf("DI%d",i), ctx->idf("DO%d",i), ClusterPlacement(PLACE_CDC_DI1 + i-1), lut_only, lut_and_ff, dff_only);
|
||||
} else
|
||||
disconnect_unused(&ci, ctx->idf("DI%d",i));
|
||||
}
|
||||
}
|
||||
|
||||
// Remove inputs and outputs that are not used for specific types
|
||||
if (ci.type.in(id_BGC, id_GBC)) {
|
||||
disconnect_unused(&ci, id_CK1);
|
||||
disconnect_unused(&ci, id_CK2);
|
||||
disconnect_unused(&ci, id_ADRSTI);
|
||||
disconnect_unused(&ci, id_ADRSTO);
|
||||
disconnect_unused(&ci, id_BDRSTI);
|
||||
disconnect_unused(&ci, id_BDRSTO);
|
||||
} else {
|
||||
connect_gnd_if_unconnected(&ci, id_ADRSTI);
|
||||
pack_xrf_input_and_output(&ci, ci.name, id_ADRSTI, id_ADRSTO, PLACE_CDC_ADRSTI, lut_only, lut_and_ff, dff_only);
|
||||
connect_gnd_if_unconnected(&ci, id_BDRSTI);
|
||||
pack_xrf_input_and_output(&ci, ci.name, id_BDRSTI, id_BDRSTO, PLACE_CDC_BDRSTI, lut_only, lut_and_ff, dff_only);
|
||||
}
|
||||
if (ci.type.in(id_BGC, id_GBC, id_DDE)) {
|
||||
disconnect_unused(&ci, id_ASRSTI);
|
||||
disconnect_unused(&ci, id_ASRSTO);
|
||||
disconnect_unused(&ci, id_BSRSTI);
|
||||
disconnect_unused(&ci, id_BSRSTO);
|
||||
} else {
|
||||
connect_gnd_if_unconnected(&ci, id_ASRSTI);
|
||||
pack_xrf_input_and_output(&ci, ci.name, id_ASRSTI, id_ASRSTO, PLACE_CDC_ASRSTI, lut_only, lut_and_ff, dff_only);
|
||||
connect_gnd_if_unconnected(&ci, id_BSRSTI);
|
||||
pack_xrf_input_and_output(&ci, ci.name, id_BSRSTI, id_BSRSTO, PLACE_CDC_BSRSTI, lut_only, lut_and_ff, dff_only);
|
||||
}
|
||||
|
||||
// Only XCDC is using these ports, remove from others if used
|
||||
if (!ci.type.in(id_XCDC)) {
|
||||
disconnect_unused(&ci, id_CDRSTI);
|
||||
disconnect_unused(&ci, id_CDRSTO);
|
||||
for (int i = 1; i <= 6; i++) {
|
||||
disconnect_unused(&ci,ctx->idf("CI%d",i));
|
||||
disconnect_unused(&ci,ctx->idf("CO%d",i));
|
||||
}
|
||||
disconnect_unused(&ci, id_CSRSTI);
|
||||
disconnect_unused(&ci, id_CSRSTO);
|
||||
|
||||
disconnect_unused(&ci, id_DDRSTI);
|
||||
disconnect_unused(&ci, id_DDRSTO);
|
||||
for (int i = 1; i <= 6; i++) {
|
||||
disconnect_unused(&ci,ctx->idf("DI%d",i));
|
||||
disconnect_unused(&ci,ctx->idf("DO%d",i));
|
||||
}
|
||||
disconnect_unused(&ci, id_DSRSTI);
|
||||
disconnect_unused(&ci, id_DSRSTO);
|
||||
} else {
|
||||
connect_gnd_if_unconnected(&ci, id_CDRSTI);
|
||||
pack_xrf_input_and_output(&ci, ci.name, id_CDRSTI, id_CDRSTO, PLACE_CDC_CDRSTI, lut_only, lut_and_ff, dff_only);
|
||||
connect_gnd_if_unconnected(&ci, id_DDRSTI);
|
||||
pack_xrf_input_and_output(&ci, ci.name, id_DDRSTI, id_DDRSTO, PLACE_CDC_DDRSTI, lut_only, lut_and_ff, dff_only);
|
||||
connect_gnd_if_unconnected(&ci, id_CSRSTI);
|
||||
pack_xrf_input_and_output(&ci, ci.name, id_CSRSTI, id_CSRSTO, PLACE_CDC_CSRSTI, lut_only, lut_and_ff, dff_only);
|
||||
connect_gnd_if_unconnected(&ci, id_DSRSTI);
|
||||
pack_xrf_input_and_output(&ci, ci.name, id_DSRSTI, id_DSRSTO, PLACE_CDC_DSRSTI, lut_only, lut_and_ff, dff_only);
|
||||
}
|
||||
}
|
||||
if (lut_only)
|
||||
log_info(" %6d FEs used as LUT only\n", lut_only);
|
||||
if (lut_and_ff)
|
||||
log_info(" %6d FEs used as LUT and DFF\n", lut_and_ff);
|
||||
if (dff_only)
|
||||
log_info(" %6d FEs used as DFF only\n", dff_only);
|
||||
flush_cells();
|
||||
}
|
||||
|
||||
void NgUltraPacker::pack_fifos(void)
|
||||
{
|
||||
log_info("Packing FIFOs..\n");
|
||||
int lut_only = 0, lut_and_ff = 0, dff_only = 0;
|
||||
for (auto &cell : ctx->cells) {
|
||||
CellInfo &ci = *cell.second;
|
||||
if (!ci.type.in(id_NX_FIFO_U))
|
||||
continue;
|
||||
int mode = int_or_default(ci.params, ctx->id("mode"), 0);
|
||||
switch(mode) {
|
||||
case 0 : ci.type = id_FIFO; break;
|
||||
case 1 : ci.type = id_XHFIFO; break;
|
||||
case 2 : ci.type = id_XWFIFO; break;
|
||||
default:
|
||||
log_error("Unknown mode %d for cell '%s'.\n", mode, ci.name.c_str(ctx));
|
||||
}
|
||||
//ci.cluster = ci.name;
|
||||
|
||||
if (mode > 0) {
|
||||
// XFIFO
|
||||
ci.ports[id_WCK1].name = id_WCK1;
|
||||
ci.ports[id_WCK1].type = PORT_IN;
|
||||
ci.ports[id_WCK2].name = id_WCK2;
|
||||
ci.ports[id_WCK2].type = PORT_IN;
|
||||
ci.ports[id_RCK1].name = id_RCK1;
|
||||
ci.ports[id_RCK1].type = PORT_IN;
|
||||
ci.ports[id_RCK2].name = id_RCK2;
|
||||
ci.ports[id_RCK2].type = PORT_IN;
|
||||
NetInfo *net = ci.getPort(id_WCK);
|
||||
if (net) {
|
||||
ci.disconnectPort(id_WCK);
|
||||
|
||||
ci.connectPort(id_WCK1, net);
|
||||
ci.connectPort(id_WCK2, net);
|
||||
}
|
||||
net = ci.getPort(id_RCK);
|
||||
if (net) {
|
||||
ci.disconnectPort(id_RCK);
|
||||
|
||||
ci.connectPort(id_RCK1, net);
|
||||
ci.connectPort(id_RCK2, net);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (lut_only)
|
||||
log_info(" %6d FEs used as LUT only\n", lut_only);
|
||||
if (lut_and_ff)
|
||||
log_info(" %6d FEs used as LUT and DFF\n", lut_and_ff);
|
||||
if (dff_only)
|
||||
log_info(" %6d FEs used as DFF only\n", dff_only);
|
||||
flush_cells();
|
||||
}
|
||||
|
||||
void NgUltraPacker::insert_ioms()
|
||||
{
|
||||
std::vector<IdString> pins_needing_iom;
|
||||
@ -1404,6 +1570,22 @@ void NgUltraPacker::pack_dsps(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NgUltraPacker::remove_not_used()
|
||||
{
|
||||
for (auto &cell : ctx->cells) {
|
||||
CellInfo &ci = *cell.second;
|
||||
for (auto &p : ci.ports) {
|
||||
if (p.second.type == PortType::PORT_OUT) {
|
||||
NetInfo *net = ci.getPort(p.first);
|
||||
if (net && net->users.entries()==0) {
|
||||
ci.disconnectPort(p.first);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NgUltraPacker::setup()
|
||||
{
|
||||
// Note: These are per Cell type not Bel type
|
||||
@ -1484,6 +1666,7 @@ void NgUltraImpl::pack()
|
||||
// Setup
|
||||
NgUltraPacker packer(ctx, this);
|
||||
packer.setup();
|
||||
packer.remove_not_used();
|
||||
packer.pack_constants();
|
||||
packer.update_lut_init();
|
||||
packer.update_dffs();
|
||||
@ -1494,6 +1677,8 @@ void NgUltraImpl::pack()
|
||||
|
||||
// TILE
|
||||
packer.pack_rfs();
|
||||
packer.pack_cdcs();
|
||||
packer.pack_fifos();
|
||||
packer.pack_cys();
|
||||
packer.pack_lut_dffs();
|
||||
packer.pack_dffs();
|
||||
@ -1549,7 +1734,7 @@ void NgUltraPacker::pre_place(void)
|
||||
NetInfo *ref = ci.getPort(id_REF);
|
||||
if (ref && ref->driver.cell && ref->driver.cell->type == id_IOM) {
|
||||
IdString bank= uarch->tile_name_id(ref->driver.cell->bel.tile);
|
||||
bool found = false;
|
||||
//bool found = false;
|
||||
for (auto &item : uarch->unused_pll) {
|
||||
BelId bel = item.first;
|
||||
std::pair<IdString,IdString>& ckgs = uarch->bank_to_ckg[bank];
|
||||
@ -1557,7 +1742,7 @@ void NgUltraPacker::pre_place(void)
|
||||
uarch->unused_pll.erase(bel);
|
||||
log_info(" Using PLL in '%s' for cell '%s'.\n", uarch->tile_name(bel.tile).c_str(), ci.name.c_str(ctx));
|
||||
ctx->bindBel(bel, &ci, PlaceStrength::STRENGTH_LOCKED);
|
||||
found = true;
|
||||
//found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ struct NgUltraPacker
|
||||
{
|
||||
NgUltraPacker(Context *ctx, NgUltraImpl *uarch) : ctx(ctx), uarch(uarch) { h.init(ctx); };
|
||||
|
||||
void remove_not_used();
|
||||
// Constants
|
||||
void pack_constants();
|
||||
void remove_constants();
|
||||
@ -49,6 +50,8 @@ struct NgUltraPacker
|
||||
void pack_dffs();
|
||||
void pack_cys();
|
||||
void pack_rfs();
|
||||
void pack_cdcs();
|
||||
void pack_fifos();
|
||||
|
||||
void pack_rams();
|
||||
void pack_dsps();
|
||||
|
Loading…
Reference in New Issue
Block a user