From d4b3c1d819703667b604ad144a36415c2f3bcdf5 Mon Sep 17 00:00:00 2001 From: Daniel Serpell Date: Sat, 1 Dec 2018 22:27:04 -0300 Subject: [PATCH] ice40: Add support for placing SB_LEDDA_IP block. Signed-off-by: Daniel Serpell --- ice40/arch.cc | 4 ++++ ice40/bitstream.cc | 3 ++- ice40/cells.cc | 14 ++++++++++++++ ice40/cells.h | 2 ++ ice40/pack.cc | 4 ++++ 5 files changed, 26 insertions(+), 1 deletion(-) diff --git a/ice40/arch.cc b/ice40/arch.cc index ddf25270..ada78020 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -950,6 +950,10 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, in if (port == id_RGB0 || port == id_RGB1 || port == id_RGB2) return TMG_IGNORE; return TMG_ENDPOINT; + } else if (cell->type == id_SB_LEDDA_IP) { + if (port == id_CLK || port == id_CLOCK) + return TMG_CLOCK_INPUT; + return TMG_IGNORE; } log_error("cell type '%s' is unsupported (instantiated as '%s')\n", cell->type.c_str(this), cell->name.c_str(this)); } diff --git a/ice40/bitstream.cc b/ice40/bitstream.cc index e20d372a..87d77b9d 100644 --- a/ice40/bitstream.cc +++ b/ice40/bitstream.cc @@ -591,7 +591,8 @@ void write_asc(const Context *ctx, std::ostream &out) {"CURRENT_MODE", 1}, {"RGB0_CURRENT", 6}, {"RGB1_CURRENT", 6}, {"RGB2_CURRENT", 6}}; configure_extra_cell(config, ctx, cell.second.get(), rgba_params, true, std::string("IpConfig.")); set_ec_cbit(config, ctx, get_ec_config(ctx->chip_info, cell.second->bel), "RGBA_DRV_EN", true, "IpConfig."); - } else if (cell.second->type == ctx->id("SB_WARMBOOT") || cell.second->type == ctx->id("ICESTORM_LFOSC")) { + } else if (cell.second->type == ctx->id("SB_WARMBOOT") || cell.second->type == ctx->id("ICESTORM_LFOSC") || + cell.second->type == ctx->id("SB_LEDDA_IP") ) { // No config needed } else if (cell.second->type == ctx->id("ICESTORM_SPRAM")) { const BelInfoPOD &beli = ci.bel_data[bel.index]; diff --git a/ice40/cells.cc b/ice40/cells.cc index dbb75c2c..aad719b1 100644 --- a/ice40/cells.cc +++ b/ice40/cells.cc @@ -260,6 +260,20 @@ std::unique_ptr create_ice_cell(Context *ctx, IdString type, std::stri add_port(ctx, new_cell.get(), "RGB0", PORT_OUT); add_port(ctx, new_cell.get(), "RGB1", PORT_OUT); add_port(ctx, new_cell.get(), "RGB2", PORT_OUT); + } else if (type == ctx->id("SB_LEDDA_IP")) { + add_port(ctx, new_cell.get(), "LEDDCS", PORT_IN); + add_port(ctx, new_cell.get(), "LEDDCLK", PORT_IN); + for (int i = 0; i < 8; i++) + add_port(ctx, new_cell.get(), "LEDDDAT" + std::to_string(i), PORT_IN); + for (int i = 0; i < 3; i++) + add_port(ctx, new_cell.get(), "LEDDADDR" + std::to_string(i), PORT_IN); + add_port(ctx, new_cell.get(), "LEDDDEN", PORT_IN); + add_port(ctx, new_cell.get(), "LEDDEXE", PORT_IN); + add_port(ctx, new_cell.get(), "LEDDRST", PORT_IN); //doesn't actually exist, for icecube code compatibility only + add_port(ctx, new_cell.get(), "PWMOUT0", PORT_OUT); + add_port(ctx, new_cell.get(), "PWMOUT1", PORT_OUT); + add_port(ctx, new_cell.get(), "PWMOUT2", PORT_OUT); + add_port(ctx, new_cell.get(), "LEDDON", PORT_OUT); } else { log_error("unable to create iCE40 cell of type %s", type.c_str(ctx)); } diff --git a/ice40/cells.h b/ice40/cells.h index 1fbd9073..93ef3db4 100644 --- a/ice40/cells.h +++ b/ice40/cells.h @@ -76,6 +76,8 @@ inline bool is_sb_mac16(const BaseCtx *ctx, const CellInfo *cell) { return cell- inline bool is_sb_rgba_drv(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == ctx->id("SB_RGBA_DRV"); } +inline bool is_sb_ledda_ip(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == ctx->id("SB_LEDDA_IP"); } + inline bool is_sb_pll40(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == ctx->id("SB_PLL40_PAD") || cell->type == ctx->id("SB_PLL40_2_PAD") || diff --git a/ice40/pack.cc b/ice40/pack.cc index 523a2642..17d2df8b 100644 --- a/ice40/pack.cc +++ b/ice40/pack.cc @@ -1044,6 +1044,10 @@ static void pack_special(Context *ctx) ci->ports.erase(ctx->id("RGB0")); ci->ports.erase(ctx->id("RGB1")); ci->ports.erase(ctx->id("RGB2")); + } else if (is_sb_ledda_ip(ctx, ci)) { + /* Force placement (no choices anyway) */ + cell_place_unique(ctx, ci); + } else if (is_sb_pll40(ctx, ci)) { bool is_pad = is_sb_pll40_pad(ctx, ci); bool is_core = !is_pad;