ecp5: Improve mixed no-FF/FF placement

Signed-off-by: David Shah <davey1576@gmail.com>
This commit is contained in:
David Shah 2018-09-30 18:39:49 +01:00
parent 3e399c9f20
commit 6a1b49c311
4 changed files with 45 additions and 30 deletions

View File

@ -39,6 +39,7 @@ bool Arch::slicesCompatible(const std::vector<const CellInfo *> &cells) const
IdString CLKMUX, LSRMUX, SRMODE; IdString CLKMUX, LSRMUX, SRMODE;
bool first = true; bool first = true;
for (auto cell : cells) { for (auto cell : cells) {
if (cell->sliceInfo.using_dff) {
if (first) { if (first) {
clk_sig = cell->sliceInfo.clk_sig; clk_sig = cell->sliceInfo.clk_sig;
lsr_sig = cell->sliceInfo.lsr_sig; lsr_sig = cell->sliceInfo.lsr_sig;
@ -59,6 +60,7 @@ bool Arch::slicesCompatible(const std::vector<const CellInfo *> &cells) const
} }
first = false; first = false;
} }
}
return true; return true;
} }

View File

@ -143,6 +143,7 @@ struct ArchCellInfo
{ {
struct struct
{ {
bool using_dff;
IdString clk_sig, lsr_sig, clkmux, lsrmux, srmode; IdString clk_sig, lsr_sig, clkmux, lsrmux, srmode;
} sliceInfo; } sliceInfo;
}; };

View File

@ -244,18 +244,23 @@ void write_bitstream(Context *ctx, std::string base_config_file, std::string tex
cc.tiles[tname].add_enum(slice + ".REG1.REGSET", cc.tiles[tname].add_enum(slice + ".REG1.REGSET",
str_or_default(ci->params, ctx->id("REG1_REGSET"), "RESET")); str_or_default(ci->params, ctx->id("REG1_REGSET"), "RESET"));
cc.tiles[tname].add_enum(slice + ".CEMUX", str_or_default(ci->params, ctx->id("CEMUX"), "1")); cc.tiles[tname].add_enum(slice + ".CEMUX", str_or_default(ci->params, ctx->id("CEMUX"), "1"));
if (ci->sliceInfo.using_dff) {
NetInfo *lsrnet = nullptr; NetInfo *lsrnet = nullptr;
if (ci->ports.find(ctx->id("LSR")) != ci->ports.end() && ci->ports.at(ctx->id("LSR")).net != nullptr) if (ci->ports.find(ctx->id("LSR")) != ci->ports.end() && ci->ports.at(ctx->id("LSR")).net != nullptr)
lsrnet = ci->ports.at(ctx->id("LSR")).net; lsrnet = ci->ports.at(ctx->id("LSR")).net;
if (ctx->getBoundWireNet(ctx->getWireByName( if (ctx->getBoundWireNet(ctx->getWireByName(
ctx->id(fmt_str("X" << bel.location.x << "/Y" << bel.location.y << "/LSR0")))) == lsrnet) { ctx->id(fmt_str("X" << bel.location.x << "/Y" << bel.location.y << "/LSR0")))) == lsrnet) {
cc.tiles[tname].add_enum("LSR0.SRMODE", str_or_default(ci->params, ctx->id("SRMODE"), "LSR_OVER_CE")); cc.tiles[tname].add_enum("LSR0.SRMODE",
str_or_default(ci->params, ctx->id("SRMODE"), "LSR_OVER_CE"));
cc.tiles[tname].add_enum("LSR0.LSRMUX", str_or_default(ci->params, ctx->id("LSRMUX"), "LSR")); cc.tiles[tname].add_enum("LSR0.LSRMUX", str_or_default(ci->params, ctx->id("LSRMUX"), "LSR"));
} else if (ctx->getBoundWireNet(ctx->getWireByName(ctx->id( } else if (ctx->getBoundWireNet(ctx->getWireByName(ctx->id(
fmt_str("X" << bel.location.x << "/Y" << bel.location.y << "/LSR1")))) == lsrnet) { fmt_str("X" << bel.location.x << "/Y" << bel.location.y << "/LSR1")))) == lsrnet) {
cc.tiles[tname].add_enum("LSR1.SRMODE", str_or_default(ci->params, ctx->id("SRMODE"), "LSR_OVER_CE")); cc.tiles[tname].add_enum("LSR1.SRMODE",
str_or_default(ci->params, ctx->id("SRMODE"), "LSR_OVER_CE"));
cc.tiles[tname].add_enum("LSR1.LSRMUX", str_or_default(ci->params, ctx->id("LSRMUX"), "LSR")); cc.tiles[tname].add_enum("LSR1.LSRMUX", str_or_default(ci->params, ctx->id("LSRMUX"), "LSR"));
} }
}
if (str_or_default(ci->params, ctx->id("MODE"), "LOGIC") == "CCU2") { if (str_or_default(ci->params, ctx->id("MODE"), "LOGIC") == "CCU2") {
cc.tiles[tname].add_enum(slice + ".CCU2.INJECT1_0", cc.tiles[tname].add_enum(slice + ".CCU2.INJECT1_0",

View File

@ -493,7 +493,7 @@ class Ecp5Packer
} }
} }
std::vector<std::vector<CellInfo*>> packed_chains; std::vector<std::vector<CellInfo *>> packed_chains;
// Chain packing // Chain packing
for (auto &chain : all_chains) { for (auto &chain : all_chains) {
@ -797,6 +797,13 @@ void Arch::assignArchInfo()
for (auto cell : sorted(cells)) { for (auto cell : sorted(cells)) {
CellInfo *ci = cell.second; CellInfo *ci = cell.second;
if (ci->type == id_TRELLIS_SLICE) { if (ci->type == id_TRELLIS_SLICE) {
ci->sliceInfo.using_dff = false;
if (ci->ports.count(id_Q0) && ci->ports[id_Q0].net != nullptr)
ci->sliceInfo.using_dff = true;
if (ci->ports.count(id_Q1) && ci->ports[id_Q1].net != nullptr)
ci->sliceInfo.using_dff = true;
if (ci->ports.count(id_CLK) && ci->ports[id_CLK].net != nullptr) if (ci->ports.count(id_CLK) && ci->ports[id_CLK].net != nullptr)
ci->sliceInfo.clk_sig = ci->ports[id_CLK].net->name; ci->sliceInfo.clk_sig = ci->ports[id_CLK].net->name;
else else