aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/design_utils.cc2
-rw-r--r--ecp5/cells.cc45
-rw-r--r--ecp5/cells.h2
-rw-r--r--ecp5/pack.cc17
4 files changed, 66 insertions, 0 deletions
diff --git a/common/design_utils.cc b/common/design_utils.cc
index 7ad7f749..e3051d20 100644
--- a/common/design_utils.cc
+++ b/common/design_utils.cc
@@ -76,6 +76,8 @@ void print_utilisation(const Context *ctx)
// Connect a net to a port
void connect_port(const Context *ctx, NetInfo *net, CellInfo *cell, IdString port_name)
{
+ if (net == nullptr)
+ return;
PortInfo &port = cell->ports.at(port_name);
NPNR_ASSERT(port.net == nullptr);
port.net = net;
diff --git a/ecp5/cells.cc b/ecp5/cells.cc
index 7e101ab2..048db1d7 100644
--- a/ecp5/cells.cc
+++ b/ecp5/cells.cc
@@ -238,4 +238,49 @@ void ccu2c_to_slice(Context *ctx, CellInfo *ccu, CellInfo *lc)
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
diff --git a/ecp5/cells.h b/ecp5/cells.h
index d2ea5490..c68d1dd3 100644
--- a/ecp5/cells.h
+++ b/ecp5/cells.h
@@ -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 lut_to_slice(Context *ctx, CellInfo *lut, CellInfo *lc, int index);
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
diff --git a/ecp5/pack.cc b/ecp5/pack.cc
index 14b387d5..2c7ce020 100644
--- a/ecp5/pack.cc
+++ b/ecp5/pack.cc
@@ -555,6 +555,23 @@ class Ecp5Packer
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
void pack_lut_pairs()
{