ecp5: Helper functions for distributed RAM support

Signed-off-by: David Shah <davey1576@gmail.com>
This commit is contained in:
David Shah 2018-10-01 15:23:12 +01:00
parent 931c78b1bb
commit d770eb672f
4 changed files with 66 additions and 0 deletions

View File

@ -76,6 +76,8 @@ void print_utilisation(const Context *ctx)
// Connect a net to a port // Connect a net to a port
void connect_port(const Context *ctx, NetInfo *net, CellInfo *cell, IdString port_name) void connect_port(const Context *ctx, NetInfo *net, CellInfo *cell, IdString port_name)
{ {
if (net == nullptr)
return;
PortInfo &port = cell->ports.at(port_name); PortInfo &port = cell->ports.at(port_name);
NPNR_ASSERT(port.net == nullptr); NPNR_ASSERT(port.net == nullptr);
port.net = net; port.net = net;

View File

@ -238,4 +238,49 @@ void ccu2c_to_slice(Context *ctx, CellInfo *ccu, CellInfo *lc)
replace_port(ccu, ctx->id("COUT"), lc, ctx->id("FCO")); replace_port(ccu, ctx->id("COUT"), lc, ctx->id("FCO"));
} }
void dram_to_ramw(Context *ctx, CellInfo *ram, CellInfo *lc)
{
lc->params[ctx->id("MODE")] = "RAMW";
replace_port(ram, ctx->id("WAD[0]"), lc, ctx->id("D0"));
replace_port(ram, ctx->id("WAD[1]"), lc, ctx->id("B0"));
replace_port(ram, ctx->id("WAD[2]"), lc, ctx->id("C0"));
replace_port(ram, ctx->id("WAD[3]"), lc, ctx->id("A0"));
replace_port(ram, ctx->id("DI[0]"), lc, ctx->id("C1"));
replace_port(ram, ctx->id("DI[1]"), lc, ctx->id("A1"));
replace_port(ram, ctx->id("DI[2]"), lc, ctx->id("D1"));
replace_port(ram, ctx->id("DI[3]"), lc, ctx->id("B1"));
}
void dram_to_ram_slice(Context *ctx, CellInfo *ram, CellInfo *lc, CellInfo *ramw, int index)
{
lc->params[ctx->id("MODE")] = "DPRAM";
lc->params[ctx->id("WREMUX")] = str_or_default(ram->params, ctx->id("WREMUX"), "WRE");
lc->params[ctx->id("WCKMUX")] = str_or_default(ram->params, ctx->id("WCKMUX"), "WCK");
// TODO: INIT
if (ram->ports.count(ctx->id("RAD[0]"))) {
connect_port(ctx, ram->ports.at(ctx->id("RAD[0]")).net, lc, ctx->id("D0"));
connect_port(ctx, ram->ports.at(ctx->id("RAD[0]")).net, lc, ctx->id("D1"));
}
if (ram->ports.count(ctx->id("RAD[1]"))) {
connect_port(ctx, ram->ports.at(ctx->id("RAD[1]")).net, lc, ctx->id("B0"));
connect_port(ctx, ram->ports.at(ctx->id("RAD[1]")).net, lc, ctx->id("B1"));
}
if (ram->ports.count(ctx->id("RAD[2]"))) {
connect_port(ctx, ram->ports.at(ctx->id("RAD[2]")).net, lc, ctx->id("C0"));
connect_port(ctx, ram->ports.at(ctx->id("RAD[2]")).net, lc, ctx->id("C1"));
}
if (ram->ports.count(ctx->id("RAD[3]"))) {
connect_port(ctx, ram->ports.at(ctx->id("RAD[3]")).net, lc, ctx->id("A0"));
connect_port(ctx, ram->ports.at(ctx->id("RAD[3]")).net, lc, ctx->id("A1"));
}
if (ram->ports.count(ctx->id("WRE")))
connect_port(ctx, ram->ports.at(ctx->id("WRE")).net, lc, ctx->id("WRE"));
if (ram->ports.count(ctx->id("WCK")))
connect_port(ctx, ram->ports.at(ctx->id("WCK")).net, lc, ctx->id("WCK"));
}
NEXTPNR_NAMESPACE_END NEXTPNR_NAMESPACE_END

View File

@ -49,6 +49,8 @@ inline bool is_l6mux(const BaseCtx *ctx, const CellInfo *cell) { return cell->ty
void ff_to_slice(Context *ctx, CellInfo *ff, CellInfo *lc, int index, bool driven_by_lut); void ff_to_slice(Context *ctx, CellInfo *ff, CellInfo *lc, int index, bool driven_by_lut);
void lut_to_slice(Context *ctx, CellInfo *lut, CellInfo *lc, int index); void lut_to_slice(Context *ctx, CellInfo *lut, CellInfo *lc, int index);
void ccu2c_to_slice(Context *ctx, CellInfo *ccu, CellInfo *lc); void ccu2c_to_slice(Context *ctx, CellInfo *ccu, CellInfo *lc);
void dram_to_ramw(Context *ctx, CellInfo *ram, CellInfo *lc);
void dram_to_ram_slice(Context *ctx, CellInfo *ram, CellInfo *lc, int index);
NEXTPNR_NAMESPACE_END NEXTPNR_NAMESPACE_END

View File

@ -555,6 +555,23 @@ class Ecp5Packer
flush_cells(); flush_cells();
} }
// Pack distributed RAM
void pack_dram()
{
for (auto cell : sorted(ctx->cells)) {
CellInfo *ci = cell.second;
if (is_dpram(ctx, ci)) {
std::unique_ptr<CellInfo> ramw_slice =
create_ecp5_cell(ctx, ctx->id("TRELLIS_SLICE"), ci->name.str(ctx) + "$RAMW_SLICE");
dram_to_ramw(ctx, ci, ramw_slice.get());
new_cells.push_back(std::move(ramw_slice));
packed_cells.insert(ci->name);
}
}
flush_cells();
}
// Pack LUTs that have been paired together // Pack LUTs that have been paired together
void pack_lut_pairs() void pack_lut_pairs()
{ {