ecp5: First stages of carry packing
Signed-off-by: David Shah <davey1576@gmail.com>
This commit is contained in:
parent
e81a95cf7e
commit
fef29d8762
66
ecp5/pack.cc
66
ecp5/pack.cc
@ -357,7 +357,8 @@ class Ecp5Packer
|
|||||||
connect_port(ctx, new_carry.get(), chain_in.cell, chain_in.port);
|
connect_port(ctx, new_carry.get(), chain_in.cell, chain_in.port);
|
||||||
|
|
||||||
CellInfo *feedin_ptr = feedin.get();
|
CellInfo *feedin_ptr = feedin.get();
|
||||||
new_cells.push_back(std::move(feedin));
|
IdString feedin_name = feedin->name;
|
||||||
|
ctx->cells[feedin_name] = std::move(feedin);
|
||||||
IdString new_carry_name = new_carry->name;
|
IdString new_carry_name = new_carry->name;
|
||||||
ctx->nets[new_carry_name] = std::move(new_carry);
|
ctx->nets[new_carry_name] = std::move(new_carry);
|
||||||
return feedin_ptr;
|
return feedin_ptr;
|
||||||
@ -404,7 +405,8 @@ class Ecp5Packer
|
|||||||
}
|
}
|
||||||
|
|
||||||
CellInfo *feedout_ptr = feedout.get();
|
CellInfo *feedout_ptr = feedout.get();
|
||||||
new_cells.push_back(std::move(feedout));
|
IdString feedout_name = feedout->name;
|
||||||
|
ctx->cells[feedout_name] = std::move(feedout);
|
||||||
|
|
||||||
IdString new_cin_name = new_cin->name;
|
IdString new_cin_name = new_cin->name;
|
||||||
ctx->nets[new_cin_name] = std::move(new_cin);
|
ctx->nets[new_cin_name] = std::move(new_cin);
|
||||||
@ -464,7 +466,8 @@ class Ecp5Packer
|
|||||||
void pack_carries()
|
void pack_carries()
|
||||||
{
|
{
|
||||||
log_info("Packing carries...\n");
|
log_info("Packing carries...\n");
|
||||||
auto chains = find_chains(
|
// Find all chains (including single carry cells)
|
||||||
|
auto carry_chains = find_chains(
|
||||||
ctx, [](const Context *ctx, const CellInfo *cell) { return is_carry(ctx, cell); },
|
ctx, [](const Context *ctx, const CellInfo *cell) { return is_carry(ctx, cell); },
|
||||||
[](const Context *ctx, const CellInfo *cell) {
|
[](const Context *ctx, const CellInfo *cell) {
|
||||||
return net_driven_by(ctx, cell->ports.at(ctx->id("CIN")).net, is_carry, ctx->id("COUT"));
|
return net_driven_by(ctx, cell->ports.at(ctx->id("CIN")).net, is_carry, ctx->id("COUT"));
|
||||||
@ -473,6 +476,63 @@ class Ecp5Packer
|
|||||||
return net_only_drives(ctx, cell->ports.at(ctx->id("COUT")).net, is_carry, ctx->id("CIN"), false);
|
return net_only_drives(ctx, cell->ports.at(ctx->id("COUT")).net, is_carry, ctx->id("CIN"), false);
|
||||||
},
|
},
|
||||||
1);
|
1);
|
||||||
|
std::vector<CellChain> all_chains;
|
||||||
|
|
||||||
|
// Chain splitting
|
||||||
|
for (auto &base_chain : carry_chains) {
|
||||||
|
if (ctx->verbose) {
|
||||||
|
log_info("Found carry chain: \n");
|
||||||
|
for (auto entry : base_chain.cells)
|
||||||
|
log_info(" %s\n", entry->name.c_str(ctx));
|
||||||
|
log_info("\n");
|
||||||
|
}
|
||||||
|
std::vector<CellChain> split_chains = split_carry_chain(base_chain);
|
||||||
|
for (auto &chain : split_chains) {
|
||||||
|
all_chains.push_back(chain);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Chain packing
|
||||||
|
for (auto &chain : all_chains) {
|
||||||
|
int cell_count = 0;
|
||||||
|
std::vector<CellInfo *> tile_ffs;
|
||||||
|
for (auto &cell : chain.cells) {
|
||||||
|
if (cell_count % 4 == 0)
|
||||||
|
tile_ffs.clear();
|
||||||
|
std::unique_ptr<CellInfo> slice =
|
||||||
|
create_ecp5_cell(ctx, ctx->id("TRELLIS_SLICE"), cell->name.str(ctx) + "$CCU2_SLICE");
|
||||||
|
|
||||||
|
ccu2c_to_slice(ctx, cell, slice.get());
|
||||||
|
|
||||||
|
CellInfo *ff0 = nullptr;
|
||||||
|
NetInfo *f0net = slice->ports.at(ctx->id("F0")).net;
|
||||||
|
if (f0net != nullptr) {
|
||||||
|
ff0 = net_only_drives(ctx, f0net, is_ff, ctx->id("DI"), false);
|
||||||
|
if (ff0 != nullptr && can_add_ff_to_file(tile_ffs, ff0)) {
|
||||||
|
ff_to_slice(ctx, ff0, slice.get(), 0, true);
|
||||||
|
tile_ffs.push_back(ff0);
|
||||||
|
packed_cells.insert(ff0->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CellInfo *ff1 = nullptr;
|
||||||
|
NetInfo *f1net = slice->ports.at(ctx->id("F1")).net;
|
||||||
|
if (f1net != nullptr) {
|
||||||
|
ff1 = net_only_drives(ctx, f1net, is_ff, ctx->id("DI"), false);
|
||||||
|
if (ff1 != nullptr && (ff0 == nullptr || can_pack_ffs(ff0, ff1)) &&
|
||||||
|
can_add_ff_to_file(tile_ffs, ff1)) {
|
||||||
|
ff_to_slice(ctx, ff1, slice.get(), 1, true);
|
||||||
|
tile_ffs.push_back(ff1);
|
||||||
|
packed_cells.insert(ff1->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
new_cells.push_back(std::move(slice));
|
||||||
|
packed_cells.insert(cell->name);
|
||||||
|
cell_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
flush_cells();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pack LUTs that have been paired together
|
// Pack LUTs that have been paired together
|
||||||
|
Loading…
Reference in New Issue
Block a user