Pack LUT and multiple DFF in stripe
This commit is contained in:
parent
caeefbd0ed
commit
7229fb73f5
@ -205,6 +205,7 @@ enum ClusterPlacement
|
||||
PLACE_FIFO_REQ1,
|
||||
PLACE_FIFO_WEQ2,
|
||||
PLACE_FIFO_REQ2,
|
||||
PLACE_LUT_CHAIN,
|
||||
};
|
||||
|
||||
enum PipExtra
|
||||
|
@ -471,6 +471,15 @@ Loc getNextLocInCYChain(Loc loc)
|
||||
return result;
|
||||
}
|
||||
|
||||
Loc getNextLocInLutChain(Loc loc)
|
||||
{
|
||||
Loc result = loc;
|
||||
result.x = loc.x;
|
||||
result.y = loc.y;
|
||||
result.z = (loc.z + 8) % 32; // BEL_LUT_Z is 0
|
||||
return result;
|
||||
}
|
||||
|
||||
Loc getCYFE(Loc root, int pos)
|
||||
{
|
||||
int p[] = { 2-1, 25-1, 10-1, 17-1 };
|
||||
|
@ -29,6 +29,7 @@ namespace ng_ultra {
|
||||
|
||||
Loc getNextLocInDSPChain(const NgUltraImpl *impl, Loc loc);
|
||||
Loc getNextLocInCYChain(Loc loc);
|
||||
Loc getNextLocInLutChain(Loc loc);
|
||||
Loc getCYFE(Loc root, int pos);
|
||||
Loc getXLUTFE(Loc root, int pos);
|
||||
Loc getXRFFE(Loc root, int pos);
|
||||
|
@ -644,6 +644,7 @@ bool NgUltraImpl::getChildPlacement(const BaseClusterInfo *cluster, Loc root_loc
|
||||
Loc child_loc = if_using_basecluster<Loc>(child, [&](const BaseClusterInfo *child) {
|
||||
switch(child->constr_z) {
|
||||
case PLACE_CY_CHAIN : { Loc l = getNextLocInCYChain(prev); prev = l; return l; }
|
||||
case PLACE_LUT_CHAIN : { Loc l = getNextLocInLutChain(prev); prev = l; return l; }
|
||||
case PLACE_CY_FE1 ... PLACE_CY_FE4: return getCYFE(root_loc, child->constr_z - PLACE_CY_FE1 );
|
||||
case PLACE_XLUT_FE1 ... PLACE_XLUT_FE4: return getXLUTFE(root_loc, child->constr_z - PLACE_XLUT_FE1 );
|
||||
case PLACE_XRF_I1 ... PLACE_XRF_WEA:
|
||||
|
@ -382,6 +382,93 @@ void NgUltraPacker::pack_xluts(void)
|
||||
flush_cells();
|
||||
}
|
||||
|
||||
void NgUltraPacker::pack_lut_multi_dffs(void)
|
||||
{
|
||||
log_info("Pack LUT-multi DFFs...\n");
|
||||
|
||||
int dff_only = 0, lut_and_ff = 0, bff_only = 0;;
|
||||
for (auto &cell : ctx->cells) {
|
||||
CellInfo &ci = *cell.second;
|
||||
if (!ci.type.in(id_NX_LUT))
|
||||
continue;
|
||||
if (!ci.params.count(id_lut_table))
|
||||
log_error("Cell '%s' missing lut_table\n", ci.name.c_str(ctx));
|
||||
|
||||
NetInfo *o = ci.getPort(id_O);
|
||||
if (o) {
|
||||
if (o->users.entries()<2) continue;
|
||||
|
||||
int cnt = 0;
|
||||
for (auto u : o->users)
|
||||
{
|
||||
if (u.cell->type == id_NX_DFF && u.cell->getPort(id_I) == o)
|
||||
cnt++;
|
||||
}
|
||||
if (cnt<2) continue;
|
||||
|
||||
CellInfo *root = create_cell_ptr(id_BEYOND_FE, ctx->id(ci.name.str(ctx) + "$fe"));
|
||||
packed_cells.insert(ci.name);
|
||||
bind_attr_loc(root, &ci.attrs);
|
||||
lut_to_fe(&ci, root, false, ci.params[id_lut_table]);
|
||||
root->cluster = root->name;
|
||||
|
||||
int max_use = (cnt==4 && o->users.entries()==4) ? 4 : 3;
|
||||
bool use_bff = max_use!=4 && cnt>=4;
|
||||
int i = 0;
|
||||
std::vector<PortRef> users;
|
||||
for (auto u : o->users)
|
||||
{
|
||||
if (u.cell->type == id_NX_DFF && u.cell->getPort(id_I) == o) {
|
||||
if (i==0) {
|
||||
packed_cells.insert(u.cell->name);
|
||||
dff_to_fe(u.cell, root, false);
|
||||
++lut_and_ff;
|
||||
} else if (i < max_use) {
|
||||
packed_cells.insert(u.cell->name);
|
||||
CellInfo *new_cell = create_cell_ptr(id_BEYOND_FE, ctx->id(u.cell->name.str(ctx) + "$fe"));
|
||||
dff_to_fe(u.cell, new_cell, false);
|
||||
root->constr_children.push_back(new_cell);
|
||||
new_cell->cluster = root->cluster;
|
||||
new_cell->constr_z = PLACE_LUT_CHAIN;
|
||||
++dff_only;
|
||||
} else {
|
||||
use_bff = true;
|
||||
users.push_back(u);
|
||||
u.cell->disconnectPort(u.port);
|
||||
}
|
||||
i++;
|
||||
} else {
|
||||
use_bff = true;
|
||||
users.push_back(u);
|
||||
u.cell->disconnectPort(u.port);
|
||||
}
|
||||
}
|
||||
if (use_bff) {
|
||||
CellInfo *new_cell = create_cell_ptr(id_BEYOND_FE, ctx->id(ci.name.str(ctx) + "$bff"));
|
||||
new_cell->params[id_dff_used] = Property(1,1);
|
||||
new_cell->setParam(ctx->id("type"), Property("BFF"));
|
||||
new_cell->connectPort(id_DI, o);
|
||||
root->constr_children.push_back(new_cell);
|
||||
new_cell->cluster = root->cluster;
|
||||
new_cell->constr_z = PLACE_LUT_CHAIN;
|
||||
bff_only++;
|
||||
NetInfo *new_out = ctx->createNet(ctx->id(o->name.str(ctx) + "$new"));
|
||||
new_cell->connectPort(id_DO, new_out);
|
||||
for(auto &user : users) {
|
||||
user.cell->connectPort(user.port, new_out);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dff_only)
|
||||
log_info(" %6d FEs used as DFF only\n", dff_only);
|
||||
if (bff_only)
|
||||
log_info(" %6d FEs used as BFF only\n", bff_only);
|
||||
if (lut_and_ff)
|
||||
log_info(" %6d FEs used as LUT and DFF\n", lut_and_ff);
|
||||
flush_cells();
|
||||
}
|
||||
|
||||
void NgUltraPacker::pack_lut_dffs(void)
|
||||
{
|
||||
log_info("Pack LUT-DFFs...\n");
|
||||
@ -1906,6 +1993,7 @@ void NgUltraImpl::pack()
|
||||
packer.pack_fifos();
|
||||
packer.pack_cys();
|
||||
packer.pack_xluts();
|
||||
packer.pack_lut_multi_dffs();
|
||||
packer.pack_lut_dffs();
|
||||
packer.pack_dffs();
|
||||
|
||||
|
@ -47,6 +47,7 @@ struct NgUltraPacker
|
||||
void update_lut_init();
|
||||
void update_dffs();
|
||||
void pack_xluts();
|
||||
void pack_lut_multi_dffs();
|
||||
void pack_lut_dffs();
|
||||
void pack_dffs();
|
||||
void pack_cys();
|
||||
|
Loading…
Reference in New Issue
Block a user