aboutsummaryrefslogtreecommitdiffstats
path: root/gowin/pack.cc
diff options
context:
space:
mode:
authorYRabbit <rabbit@yrabbit.cyou>2022-07-05 19:43:24 +1000
committerYRabbit <rabbit@yrabbit.cyou>2022-07-05 19:43:24 +1000
commit3364a3b6746c6df62a36e1dd319afaa97259d6ad (patch)
treefe7e96804ecee6f46ffef4522a1a3bba290fd86a /gowin/pack.cc
parent5d915a550ba8a825fa29a2cab3851adea20f40fb (diff)
parent86396c41d64d2583ec1dffca4298e83d927f0762 (diff)
downloadnextpnr-3364a3b6746c6df62a36e1dd319afaa97259d6ad.tar.gz
nextpnr-3364a3b6746c6df62a36e1dd319afaa97259d6ad.tar.bz2
nextpnr-3364a3b6746c6df62a36e1dd319afaa97259d6ad.zip
Merge branch 'master' into clock-wip
Diffstat (limited to 'gowin/pack.cc')
-rw-r--r--gowin/pack.cc90
1 files changed, 90 insertions, 0 deletions
diff --git a/gowin/pack.cc b/gowin/pack.cc
index 5b304f10..dbf949d4 100644
--- a/gowin/pack.cc
+++ b/gowin/pack.cc
@@ -694,6 +694,95 @@ static void pack_gsr(Context *ctx)
}
}
+// Pack shadow RAM
+void pack_sram(Context *ctx)
+{
+ log_info("Packing Shadow RAM..\n");
+
+ pool<IdString> packed_cells;
+ std::vector<std::unique_ptr<CellInfo>> new_cells;
+
+ for (auto &cell : ctx->cells) {
+ CellInfo *ci = cell.second.get();
+ if (is_sram(ctx, ci)) {
+
+ // Create RAMW slice
+ std::unique_ptr<CellInfo> ramw_slice =
+ create_generic_cell(ctx, id_RAMW, ci->name.str(ctx) + "$RAMW_SLICE");
+ sram_to_ramw_split(ctx, ci, ramw_slice.get());
+ ramw_slice->connectPort(id_CE, ctx->nets[ctx->id("$PACKER_VCC_NET")].get());
+
+ // Create actual RAM slices
+ std::unique_ptr<CellInfo> ram_comb[4];
+ for (int i = 0; i < 4; i++) {
+ ram_comb[i] = create_generic_cell(ctx, id_SLICE,
+ ci->name.str(ctx) + "$SRAM_SLICE" + std::to_string(i));
+ ram_comb[i]->params[id_FF_USED] = 1;
+ ram_comb[i]->params[id_FF_TYPE] = std::string("RAM");
+ sram_to_slice(ctx, ci, ram_comb[i].get(), i);
+ }
+ // Create 'block' SLICEs as a placement hint that these cells are mutually exclusive with the RAMW
+ std::unique_ptr<CellInfo> ramw_block[2];
+ for (int i = 0; i < 2; i++) {
+ ramw_block[i] = create_generic_cell(ctx, id_SLICE,
+ ci->name.str(ctx) + "$RAMW_BLOCK" + std::to_string(i));
+ ram_comb[i]->params[id_FF_USED] = 1;
+ ramw_block[i]->params[id_FF_TYPE] = std::string("RAM");
+ }
+
+ // Disconnect ports of original cell after packing
+ // ci->disconnectPort(id_WCK);
+ // ci->disconnectPort(id_WRE);
+
+ for (int i = 0; i < 4; i++)
+ ci->disconnectPort(ctx->id(stringf("RAD[%d]", i)));
+
+ // Setup placement constraints
+ // Use the 0th bit as an anchor
+ ram_comb[0]->constr_abs_z = true;
+ ram_comb[0]->constr_z = 0;
+ ram_comb[0]->cluster = ram_comb[0]->name;
+ for (int i = 1; i < 4; i++) {
+ ram_comb[i]->cluster = ram_comb[0]->name;
+ ram_comb[i]->constr_abs_z = true;
+ ram_comb[i]->constr_x = 0;
+ ram_comb[i]->constr_y = 0;
+ ram_comb[i]->constr_z = i;
+ ram_comb[0]->constr_children.push_back(ram_comb[i].get());
+ }
+ for (int i = 0; i < 2; i++) {
+ ramw_block[i]->cluster = ram_comb[0]->name;
+ ramw_block[i]->constr_abs_z = true;
+ ramw_block[i]->constr_x = 0;
+ ramw_block[i]->constr_y = 0;
+ ramw_block[i]->constr_z = i + 4;
+ ram_comb[0]->constr_children.push_back(ramw_block[i].get());
+ }
+
+ ramw_slice->cluster = ram_comb[0]->name;
+ ramw_slice->constr_abs_z = true;
+ ramw_slice->constr_x = 0;
+ ramw_slice->constr_y = 0;
+ ramw_slice->constr_z = BelZ::lutram_0_z;
+ ram_comb[0]->constr_children.push_back(ramw_slice.get());
+
+ for (int i = 0; i < 4; i++)
+ new_cells.push_back(std::move(ram_comb[i]));
+ for (int i = 0; i < 2; i++)
+ new_cells.push_back(std::move(ramw_block[i]));
+ new_cells.push_back(std::move(ramw_slice));
+ packed_cells.insert(ci->name);
+ }
+ }
+ for (auto pcell : packed_cells) {
+ ctx->cells.erase(pcell);
+ }
+ for (auto &ncell : new_cells) {
+ ctx->cells[ncell->name] = std::move(ncell);
+ }
+}
+
+
static bool is_nextpnr_iob(const Context *ctx, CellInfo *cell)
{
return cell->type == ctx->id("$nextpnr_ibuf") || cell->type == ctx->id("$nextpnr_obuf") ||
@@ -1013,6 +1102,7 @@ bool Arch::pack()
log_break();
pre_pack(ctx);
pack_constants(ctx);
+ pack_sram(ctx);
pack_gsr(ctx);
pack_io(ctx);
pack_diff_io(ctx);