diff options
Diffstat (limited to 'machxo2')
-rw-r--r-- | machxo2/cells.cc | 97 | ||||
-rw-r--r-- | machxo2/cells.h | 12 |
2 files changed, 8 insertions, 101 deletions
diff --git a/machxo2/cells.cc b/machxo2/cells.cc index 21c233d0..522295b0 100644 --- a/machxo2/cells.cc +++ b/machxo2/cells.cc @@ -26,122 +26,29 @@ NEXTPNR_NAMESPACE_BEGIN void add_port(const Context *ctx, CellInfo *cell, std::string name, PortType dir) { - IdString id = ctx->id(name); - NPNR_ASSERT(cell->ports.count(id) == 0); - cell->ports[id] = PortInfo{id, nullptr, dir}; + } -std::unique_ptr<CellInfo> create_generic_cell(Context *ctx, IdString type, std::string name) +std::unique_ptr<CellInfo> create_machxo2_cell(Context *ctx, IdString type, std::string name) { static int auto_idx = 0; std::unique_ptr<CellInfo> new_cell = std::unique_ptr<CellInfo>(new CellInfo()); - if (name.empty()) { - new_cell->name = ctx->id("$nextpnr_" + type.str(ctx) + "_" + std::to_string(auto_idx++)); - } else { - new_cell->name = ctx->id(name); - } - new_cell->type = type; - if (type == ctx->id("GENERIC_SLICE")) { - new_cell->params[ctx->id("K")] = 4; - new_cell->params[ctx->id("INIT")] = 0; - new_cell->params[ctx->id("FF_USED")] = 0; - - for (int i = 0; i < 4; i++) - add_port(ctx, new_cell.get(), "I[" + std::to_string(i) + "]", PORT_IN); - - add_port(ctx, new_cell.get(), "CLK", PORT_IN); - - add_port(ctx, new_cell.get(), "F", PORT_OUT); - add_port(ctx, new_cell.get(), "Q", PORT_OUT); - } else if (type == ctx->id("GENERIC_IOB")) { - new_cell->params[ctx->id("INPUT_USED")] = 0; - new_cell->params[ctx->id("OUTPUT_USED")] = 0; - new_cell->params[ctx->id("ENABLE_USED")] = 0; - - add_port(ctx, new_cell.get(), "PAD", PORT_INOUT); - add_port(ctx, new_cell.get(), "I", PORT_IN); - add_port(ctx, new_cell.get(), "EN", PORT_IN); - add_port(ctx, new_cell.get(), "O", PORT_OUT); - } else { - log_error("unable to create generic cell of type %s", type.c_str(ctx)); - } return new_cell; } void lut_to_lc(const Context *ctx, CellInfo *lut, CellInfo *lc, bool no_dff) { - lc->params[ctx->id("INIT")] = lut->params[ctx->id("INIT")]; - int lut_k = int_or_default(lut->params, ctx->id("K"), 4); - NPNR_ASSERT(lut_k <= 4); - - for (int i = 0; i < lut_k; i++) { - IdString port = ctx->id("I[" + std::to_string(i) + "]"); - replace_port(lut, port, lc, port); - } - - if (no_dff) { - lc->params[ctx->id("FF_USED")] = 0; - replace_port(lut, ctx->id("Q"), lc, ctx->id("F")); - } } void dff_to_lc(const Context *ctx, CellInfo *dff, CellInfo *lc, bool pass_thru_lut) { - lc->params[ctx->id("FF_USED")] = 1; - replace_port(dff, ctx->id("CLK"), lc, ctx->id("CLK")); - - if (pass_thru_lut) { - // Fill LUT with alternating 10 - const int init_size = 1 << lc->params[ctx->id("K")].as_int64(); - std::string init; - init.reserve(init_size); - for (int i = 0; i < init_size; i += 2) - init.append("10"); - lc->params[ctx->id("INIT")] = Property::from_string(init); - - replace_port(dff, ctx->id("D"), lc, ctx->id("I[0]")); - } - replace_port(dff, ctx->id("Q"), lc, ctx->id("Q")); } void nxio_to_iob(Context *ctx, CellInfo *nxio, CellInfo *iob, std::unordered_set<IdString> &todelete_cells) { - if (nxio->type == ctx->id("$nextpnr_ibuf")) { - iob->params[ctx->id("INPUT_USED")] = 1; - replace_port(nxio, ctx->id("O"), iob, ctx->id("O")); - } else if (nxio->type == ctx->id("$nextpnr_obuf")) { - iob->params[ctx->id("OUTPUT_USED")] = 1; - replace_port(nxio, ctx->id("I"), iob, ctx->id("I")); - } else if (nxio->type == ctx->id("$nextpnr_iobuf")) { - // N.B. tristate will be dealt with below - iob->params[ctx->id("INPUT_USED")] = 1; - iob->params[ctx->id("OUTPUT_USED")] = 1; - replace_port(nxio, ctx->id("I"), iob, ctx->id("I")); - replace_port(nxio, ctx->id("O"), iob, ctx->id("O")); - } else { - NPNR_ASSERT(false); - } - NetInfo *donet = iob->ports.at(ctx->id("I")).net; - CellInfo *tbuf = net_driven_by( - ctx, donet, [](const Context *ctx, const CellInfo *cell) { return cell->type == ctx->id("$_TBUF_"); }, - ctx->id("Y")); - if (tbuf) { - iob->params[ctx->id("ENABLE_USED")] = 1; - replace_port(tbuf, ctx->id("A"), iob, ctx->id("I")); - replace_port(tbuf, ctx->id("E"), iob, ctx->id("EN")); - if (donet->users.size() > 1) { - for (auto user : donet->users) - log_info(" remaining tristate user: %s.%s\n", user.cell->name.c_str(ctx), user.port.c_str(ctx)); - log_error("unsupported tristate IO pattern for IO buffer '%s', " - "instantiate GENERIC_IOB manually to ensure correct behaviour\n", - nxio->name.c_str(ctx)); - } - ctx->nets.erase(donet->name); - todelete_cells.insert(tbuf->name); - } } NEXTPNR_NAMESPACE_END diff --git a/machxo2/cells.h b/machxo2/cells.h index 646d738d..b2971bda 100644 --- a/machxo2/cells.h +++ b/machxo2/cells.h @@ -19,22 +19,22 @@ #include "nextpnr.h" -#ifndef GENERIC_CELLS_H -#define GENERIC_CELLS_H +#ifndef MACHXO2_CELLS_H +#define MACHXO2_CELLS_H NEXTPNR_NAMESPACE_BEGIN // Create a generic arch cell and return it // Name will be automatically assigned if not specified -std::unique_ptr<CellInfo> create_generic_cell(Context *ctx, IdString type, std::string name = ""); +std::unique_ptr<CellInfo> create_machxo2_cell(Context *ctx, IdString type, std::string name = ""); // Return true if a cell is a LUT -inline bool is_lut(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == ctx->id("LUT"); } +inline bool is_lut(const BaseCtx *ctx, const CellInfo *cell) { return false; } // Return true if a cell is a flipflop -inline bool is_ff(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == ctx->id("DFF"); } +inline bool is_ff(const BaseCtx *ctx, const CellInfo *cell) { return false; } -inline bool is_lc(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == ctx->id("GENERIC_SLICE"); } +inline bool is_lc(const BaseCtx *ctx, const CellInfo *cell) { return false; } // Convert a LUT primitive to (part of) an GENERIC_SLICE, swapping ports // as needed. Set no_dff if a DFF is not being used, so that the output |