Place DFF chains
This commit is contained in:
parent
7229fb73f5
commit
dddf12a42b
@ -206,6 +206,7 @@ enum ClusterPlacement
|
||||
PLACE_FIFO_WEQ2,
|
||||
PLACE_FIFO_REQ2,
|
||||
PLACE_LUT_CHAIN,
|
||||
PLACE_DFF_CHAIN,
|
||||
};
|
||||
|
||||
enum PipExtra
|
||||
|
@ -471,7 +471,7 @@ Loc getNextLocInCYChain(Loc loc)
|
||||
return result;
|
||||
}
|
||||
|
||||
Loc getNextLocInLutChain(Loc loc)
|
||||
Loc getNextLocInLUTChain(Loc loc)
|
||||
{
|
||||
Loc result = loc;
|
||||
result.x = loc.x;
|
||||
@ -480,6 +480,24 @@ Loc getNextLocInLutChain(Loc loc)
|
||||
return result;
|
||||
}
|
||||
|
||||
Loc getNextLocInDFFChain(Loc loc)
|
||||
{
|
||||
Loc result = loc;
|
||||
if (loc.z == 31) {
|
||||
if ((loc.x & 3) == 3) {
|
||||
result.z = -1; // End of chain
|
||||
return result;
|
||||
}
|
||||
result.z = 0;
|
||||
result.x++;
|
||||
return result;
|
||||
}
|
||||
int z = loc.z + 8;
|
||||
if (z>31) z++;
|
||||
result.z = z % 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,7 +29,8 @@ namespace ng_ultra {
|
||||
|
||||
Loc getNextLocInDSPChain(const NgUltraImpl *impl, Loc loc);
|
||||
Loc getNextLocInCYChain(Loc loc);
|
||||
Loc getNextLocInLutChain(Loc loc);
|
||||
Loc getNextLocInLUTChain(Loc loc);
|
||||
Loc getNextLocInDFFChain(Loc loc);
|
||||
Loc getCYFE(Loc root, int pos);
|
||||
Loc getXLUTFE(Loc root, int pos);
|
||||
Loc getXRFFE(Loc root, int pos);
|
||||
|
@ -644,7 +644,8 @@ 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_LUT_CHAIN : { Loc l = getNextLocInLUTChain(prev); prev = l; return l; }
|
||||
case PLACE_DFF_CHAIN : { Loc l = getNextLocInDFFChain(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,71 @@ void NgUltraPacker::pack_xluts(void)
|
||||
flush_cells();
|
||||
}
|
||||
|
||||
void NgUltraPacker::pack_multi_dffs(void)
|
||||
{
|
||||
log_info("Pack multi DFFs...\n");
|
||||
std::vector<CellInfo*> dff_chain_start;
|
||||
for (auto &cell : ctx->cells) {
|
||||
CellInfo &ci = *cell.second;
|
||||
if (!ci.type.in(id_NX_DFF))
|
||||
continue;
|
||||
NetInfo *inp = ci.getPort(id_I);
|
||||
if (!inp || (inp->driver.cell && inp->driver.cell->type.in(id_NX_DFF))) continue;
|
||||
int cnt = 0;
|
||||
CellInfo *dff = &ci;
|
||||
while(1) {
|
||||
NetInfo *o = dff->getPort(id_O);
|
||||
if (o->users.entries() != 1) break;
|
||||
dff = (*o->users.begin()).cell;
|
||||
if (dff->type == id_NX_DFF && (*o->users.begin()).port == id_I) {
|
||||
cnt++;
|
||||
} else break;
|
||||
}
|
||||
if (cnt)
|
||||
dff_chain_start.push_back(&ci);
|
||||
}
|
||||
|
||||
int dff_only = 0, lut_and_ff = 0;
|
||||
for (auto dff : dff_chain_start) {
|
||||
CellInfo *root = create_cell_ptr(id_BEYOND_FE, ctx->id(dff->name.str(ctx) + "$fe"));
|
||||
root->cluster = root->name;
|
||||
NetInfo *net = dff->getPort(id_I);
|
||||
NetInfo *o = dff->getPort(id_O);
|
||||
if (net && net->driver.cell->type == id_NX_LUT && net->users.entries()==1) {
|
||||
CellInfo *lut = net->driver.cell;
|
||||
if (!lut->params.count(id_lut_table))
|
||||
log_error("Cell '%s' missing lut_table\n", lut->name.c_str(ctx));
|
||||
lut_to_fe(lut, root, false, lut->params[id_lut_table]);
|
||||
packed_cells.insert(lut->name);
|
||||
dff_to_fe(dff, root, false);
|
||||
packed_cells.insert(dff->name);
|
||||
++lut_and_ff;
|
||||
} else {
|
||||
dff_to_fe(dff, root, true);
|
||||
packed_cells.insert(dff->name);
|
||||
++dff_only;
|
||||
}
|
||||
while(1) {
|
||||
if (o->users.entries() != 1) break;
|
||||
dff = (*o->users.begin()).cell;
|
||||
if (!(dff->type == id_NX_DFF && (*o->users.begin()).port == id_I)) break;
|
||||
o = dff->getPort(id_O);
|
||||
CellInfo *new_cell = create_cell_ptr(id_BEYOND_FE, ctx->id(dff->name.str(ctx) + "$fe"));
|
||||
dff_to_fe(dff, new_cell, true);
|
||||
++dff_only;
|
||||
root->constr_children.push_back(new_cell);
|
||||
new_cell->cluster = root->cluster;
|
||||
new_cell->constr_z = PLACE_DFF_CHAIN;
|
||||
packed_cells.insert(dff->name);
|
||||
}
|
||||
}
|
||||
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_lut_multi_dffs(void)
|
||||
{
|
||||
log_info("Pack LUT-multi DFFs...\n");
|
||||
@ -1994,6 +2059,7 @@ void NgUltraImpl::pack()
|
||||
packer.pack_cys();
|
||||
packer.pack_xluts();
|
||||
packer.pack_lut_multi_dffs();
|
||||
packer.pack_multi_dffs();
|
||||
packer.pack_lut_dffs();
|
||||
packer.pack_dffs();
|
||||
|
||||
|
@ -48,6 +48,7 @@ struct NgUltraPacker
|
||||
void update_dffs();
|
||||
void pack_xluts();
|
||||
void pack_lut_multi_dffs();
|
||||
void pack_multi_dffs();
|
||||
void pack_lut_dffs();
|
||||
void pack_dffs();
|
||||
void pack_cys();
|
||||
|
Loading…
Reference in New Issue
Block a user