From 2ee86ab5a80fdc2c49c6c6e34a2c0d31ae291c63 Mon Sep 17 00:00:00 2001 From: David Shah Date: Mon, 24 Sep 2018 15:25:37 +0100 Subject: [PATCH] ice40: Tristate IO support fixes Signed-off-by: David Shah --- ice40/cells.cc | 12 ++++++++---- ice40/cells.h | 2 +- ice40/pack.cc | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/ice40/cells.cc b/ice40/cells.cc index e79a1fda..70b89631 100644 --- a/ice40/cells.cc +++ b/ice40/cells.cc @@ -312,7 +312,7 @@ void dff_to_lc(const Context *ctx, CellInfo *dff, CellInfo *lc, bool pass_thru_l replace_port(dff, ctx->id("Q"), lc, ctx->id("O")); } -void nxio_to_sb(Context *ctx, CellInfo *nxio, CellInfo *sbio) +void nxio_to_sb(Context *ctx, CellInfo *nxio, CellInfo *sbio, std::unordered_set &todelete_cells) { if (nxio->type == ctx->id("$nextpnr_ibuf")) { sbio->params[ctx->id("PIN_TYPE")] = "1"; @@ -339,12 +339,16 @@ void nxio_to_sb(Context *ctx, CellInfo *nxio, CellInfo *sbio) sbio->params[ctx->id("PIN_TYPE")] = "41"; replace_port(tbuf, ctx->id("A"), sbio, ctx->id("D_OUT_0")); replace_port(tbuf, ctx->id("E"), sbio, ctx->id("OUTPUT_ENABLE")); - ctx->nets.erase(donet->name); - if (!donet->users.empty()) + + 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 SB_IO manually to ensure correct behaviour\n", nxio->name.c_str(ctx)); - ctx->cells.erase(tbuf->name); + } + ctx->nets.erase(donet->name); + todelete_cells.insert(tbuf->name); } } diff --git a/ice40/cells.h b/ice40/cells.h index 16135448..054388ac 100644 --- a/ice40/cells.h +++ b/ice40/cells.h @@ -98,7 +98,7 @@ void lut_to_lc(const Context *ctx, CellInfo *lut, CellInfo *lc, bool no_dff = tr void dff_to_lc(const Context *ctx, CellInfo *dff, CellInfo *lc, bool pass_thru_lut = false); // Convert a nextpnr IO buffer to a SB_IO -void nxio_to_sb(Context *ctx, CellInfo *nxio, CellInfo *sbio); +void nxio_to_sb(Context *ctx, CellInfo *nxio, CellInfo *sbio, std::unordered_set &todelete_cells); // Return true if a port is a clock port bool is_clock_port(const BaseCtx *ctx, const PortRef &port); diff --git a/ice40/pack.cc b/ice40/pack.cc index 7c853e0e..feca8a77 100644 --- a/ice40/pack.cc +++ b/ice40/pack.cc @@ -424,7 +424,7 @@ static void pack_io(Context *ctx) // Create a SB_IO buffer std::unique_ptr ice_cell = create_ice_cell(ctx, ctx->id("SB_IO"), ci->name.str(ctx) + "$sb_io"); - nxio_to_sb(ctx, ci, ice_cell.get()); + nxio_to_sb(ctx, ci, ice_cell.get(), packed_cells); new_cells.push_back(std::move(ice_cell)); sb = new_cells.back().get(); }