From 42214b226fda6647a954cfe4895cfceee9a8cd72 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Mon, 23 Nov 2020 16:56:41 -0500 Subject: machxo2: Add constant packing implementation, fix bugs in create_machxo2_cell. --- machxo2/cells.cc | 5 ++-- machxo2/pack.cc | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 2 deletions(-) (limited to 'machxo2') diff --git a/machxo2/cells.cc b/machxo2/cells.cc index aed96e3d..d56c6d71 100644 --- a/machxo2/cells.cc +++ b/machxo2/cells.cc @@ -46,6 +46,7 @@ std::unique_ptr create_machxo2_cell(Context *ctx, IdString type, std:: } else { new_cell->name = ctx->id(name); } + new_cell->type = type; if (type == id_FACADE_SLICE) { new_cell->params[id_MODE] = std::string("LOGIC"); @@ -55,8 +56,8 @@ std::unique_ptr create_machxo2_cell(Context *ctx, IdString type, std:: new_cell->params[id_CLKMUX] = std::string("0"); new_cell->params[id_LSRMUX] = std::string("LSR"); new_cell->params[id_LSRONMUX] = std::string("LSRMUX"); - new_cell->params[id_LUT0_INITVAL] = Property(16, 0xFFFF); - new_cell->params[id_LUT1_INITVAL] = Property(16, 0xFFFF); + new_cell->params[id_LUT0_INITVAL] = Property(0xFFFF, 16); + new_cell->params[id_LUT1_INITVAL] = Property(0xFFFF, 16); new_cell->params[id_REG0_SD] = std::string("1"); new_cell->params[id_REG1_SD] = std::string("1"); new_cell->params[id_REG0_REGSET] = std::string("SET"); diff --git a/machxo2/pack.cc b/machxo2/pack.cc index 38edc7aa..6af7a58b 100644 --- a/machxo2/pack.cc +++ b/machxo2/pack.cc @@ -27,6 +27,75 @@ NEXTPNR_NAMESPACE_BEGIN +// Merge a net into a constant net +static void set_net_constant(const Context *ctx, NetInfo *orig, NetInfo *constnet, bool constval) +{ + (void) constval; + + orig->driver.cell = nullptr; + for (auto user : orig->users) { + if (user.cell != nullptr) { + CellInfo *uc = user.cell; + if (ctx->verbose) + log_info("%s user %s\n", orig->name.c_str(ctx), uc->name.c_str(ctx)); + + uc->ports[user.port].net = constnet; + constnet->users.push_back(user); + } + } + orig->users.clear(); +} + + +// Pack constants (based on simple implementation in generic). +// VCC/GND cells provided by nextpnr automatically. +static void pack_constants(Context *ctx) +{ + log_info("Packing constants..\n"); + + std::unique_ptr const_cell = create_machxo2_cell(ctx, id_FACADE_SLICE, "$PACKER_CONST"); + const_cell->params[id_LUT0_INITVAL] = Property(0, 16); + const_cell->params[id_LUT1_INITVAL] = Property(0xFFFF, 16); + + std::unique_ptr gnd_net = std::unique_ptr(new NetInfo); + gnd_net->name = ctx->id("$PACKER_GND_NET"); + gnd_net->driver.cell = const_cell.get(); + gnd_net->driver.port = id_F0; + const_cell->ports.at(id_F0).net = gnd_net.get(); + + std::unique_ptr vcc_net = std::unique_ptr(new NetInfo); + vcc_net->name = ctx->id("$PACKER_VCC_NET"); + vcc_net->driver.cell = const_cell.get(); + vcc_net->driver.port = id_F1; + const_cell->ports.at(id_F1).net = vcc_net.get(); + + std::vector dead_nets; + + for (auto net : sorted(ctx->nets)) { + NetInfo *ni = net.second; + if (ni->driver.cell != nullptr && ni->driver.cell->type == ctx->id("GND")) { + IdString drv_cell = ni->driver.cell->name; + set_net_constant(ctx, ni, gnd_net.get(), false); + dead_nets.push_back(net.first); + ctx->cells.erase(drv_cell); + } else if (ni->driver.cell != nullptr && ni->driver.cell->type == ctx->id("VCC")) { + IdString drv_cell = ni->driver.cell->name; + set_net_constant(ctx, ni, vcc_net.get(), true); + dead_nets.push_back(net.first); + ctx->cells.erase(drv_cell); + } + } + + ctx->cells[const_cell->name] = std::move(const_cell); + ctx->nets[gnd_net->name] = std::move(gnd_net); + ctx->nets[vcc_net->name] = std::move(vcc_net); + + for (auto dn : dead_nets) { + ctx->nets.erase(dn); + } +} + + // Main pack function bool Arch::pack() { @@ -34,6 +103,7 @@ bool Arch::pack() log_info("Packing implementation goes here.."); try { log_break(); + pack_constants(ctx); ctx->settings[ctx->id("pack")] = 1; ctx->assignArchInfo(); log_info("Checksum: 0x%08x\n", ctx->checksum()); -- cgit v1.2.3