aboutsummaryrefslogtreecommitdiffstats
path: root/ecp5
diff options
context:
space:
mode:
authorDavid Shah <davey1576@gmail.com>2018-10-01 17:05:02 +0100
committerDavid Shah <davey1576@gmail.com>2018-10-01 17:05:02 +0100
commit9518c5d7629bfac996f9a3585a8d7bd86789357d (patch)
tree5ac6ecd4ffebe0f6a5444e6a54b9ad733dcdc8d5 /ecp5
parent885fae8236c0bdb73c99b0605e1d7bdf14000dd4 (diff)
downloadnextpnr-9518c5d7629bfac996f9a3585a8d7bd86789357d.tar.gz
nextpnr-9518c5d7629bfac996f9a3585a8d7bd86789357d.tar.bz2
nextpnr-9518c5d7629bfac996f9a3585a8d7bd86789357d.zip
ecp5: Working on DRAM packing
Signed-off-by: David Shah <davey1576@gmail.com>
Diffstat (limited to 'ecp5')
-rw-r--r--ecp5/cells.h2
-rw-r--r--ecp5/pack.cc67
2 files changed, 68 insertions, 1 deletions
diff --git a/ecp5/cells.h b/ecp5/cells.h
index c68d1dd3..a5229fe0 100644
--- a/ecp5/cells.h
+++ b/ecp5/cells.h
@@ -50,7 +50,7 @@ void ff_to_slice(Context *ctx, CellInfo *ff, CellInfo *lc, int index, bool drive
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);
+void dram_to_ram_slice(Context *ctx, CellInfo *ram, CellInfo *lc, CellInfo *ramw, int index);
NEXTPNR_NAMESPACE_END
diff --git a/ecp5/pack.cc b/ecp5/pack.cc
index 2c7ce020..fbe3879a 100644
--- a/ecp5/pack.cc
+++ b/ecp5/pack.cc
@@ -561,10 +561,77 @@ class Ecp5Packer
for (auto cell : sorted(ctx->cells)) {
CellInfo *ci = cell.second;
if (is_dpram(ctx, ci)) {
+
+ // Create RAMW slice
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());
+ // Create actual RAM slices
+ std::unique_ptr<CellInfo> ram0_slice =
+ create_ecp5_cell(ctx, ctx->id("TRELLIS_SLICE"), ci->name.str(ctx) + "$DPRAM0_SLICE");
+ dram_to_ram_slice(ctx, ci, ram0_slice.get(), ramw_slice.get(), 0);
+
+ std::unique_ptr<CellInfo> ram1_slice =
+ create_ecp5_cell(ctx, ctx->id("TRELLIS_SLICE"), ci->name.str(ctx) + "$DPRAM1_SLICE");
+ dram_to_ram_slice(ctx, ci, ram1_slice.get(), ramw_slice.get(), 1);
+
+ // Disconnect ports of original cell after packing
+ disconnect_port(ctx, ci, id_WCK);
+ disconnect_port(ctx, ci, id_WRE);
+
+ disconnect_port(ctx, ci, ctx->id("RAD[0]"));
+ disconnect_port(ctx, ci, ctx->id("RAD[1]"));
+ disconnect_port(ctx, ci, ctx->id("RAD[2]"));
+ disconnect_port(ctx, ci, ctx->id("RAD[3]"));
+
+ // Attempt to pack FFs into RAM slices
+ std::vector<CellInfo *> tile_ffs;
+ for (auto slice : {ram0_slice.get(), ram1_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, 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, 1, true);
+ tile_ffs.push_back(ff1);
+ packed_cells.insert(ff1->name);
+ }
+ }
+ }
+
+ // Setup placement constraints
+ ram0_slice->constr_abs_z = true;
+ ram0_slice->constr_z = 0;
+
+ ram1_slice->constr_parent = ram0_slice.get();
+ ram1_slice->constr_abs_z = true;
+ ram1_slice->constr_x = 0;
+ ram1_slice->constr_y = 0;
+ ram1_slice->constr_z = 1;
+ ram0_slice->constr_children.push_back(ram1_slice.get());
+
+ ramw_slice->constr_parent = ram0_slice.get();
+ ramw_slice->constr_abs_z = true;
+ ramw_slice->constr_x = 0;
+ ramw_slice->constr_y = 0;
+ ramw_slice->constr_z = 2;
+ ram0_slice->constr_children.push_back(ramw_slice.get());
+
+ new_cells.push_back(std::move(ram0_slice));
+ new_cells.push_back(std::move(ram1_slice));
new_cells.push_back(std::move(ramw_slice));
packed_cells.insert(ci->name);
}