aboutsummaryrefslogtreecommitdiffstats
path: root/ice40/pack.cc
diff options
context:
space:
mode:
authorDavid Shah <davey1576@gmail.com>2019-03-26 08:03:37 +0000
committerGitHub <noreply@github.com>2019-03-26 08:03:37 +0000
commited4fc888debb2eb100d1476e92c87c65d72cf545 (patch)
treefe46510d61a491a9d1b85ffba102e0eb9c69b8c2 /ice40/pack.cc
parentc2d87846d8e6c9603f432c1b021f58023f7625b4 (diff)
parentd401e3e1a09e2e5d78f18f32405c82293ce68545 (diff)
downloadnextpnr-ed4fc888debb2eb100d1476e92c87c65d72cf545.tar.gz
nextpnr-ed4fc888debb2eb100d1476e92c87c65d72cf545.tar.bz2
nextpnr-ed4fc888debb2eb100d1476e92c87c65d72cf545.zip
Merge pull request #255 from smunaut/i2c_spi
ice40: Add support for SB_I2C and SB_SPI
Diffstat (limited to 'ice40/pack.cc')
-rw-r--r--ice40/pack.cc19
1 files changed, 18 insertions, 1 deletions
diff --git a/ice40/pack.cc b/ice40/pack.cc
index c22c4e8c..4de88abd 100644
--- a/ice40/pack.cc
+++ b/ice40/pack.cc
@@ -1056,7 +1056,24 @@ static void pack_special(Context *ctx)
} else if (is_sb_ledda_ip(ctx, ci)) {
/* Force placement (no choices anyway) */
cell_place_unique(ctx, ci);
-
+ } else if (is_sb_i2c(ctx, ci) || is_sb_spi(ctx, ci)) {
+ const std::map<std::tuple<IdString, std::string>, Loc> map_ba74 = {
+ {std::make_tuple(id_SB_SPI, "0b0000"), Loc(0, 0, 0)},
+ {std::make_tuple(id_SB_I2C, "0b0001"), Loc(0, 31, 0)},
+ {std::make_tuple(id_SB_SPI, "0b0010"), Loc(25, 0, 1)},
+ {std::make_tuple(id_SB_I2C, "0b0011"), Loc(25, 31, 0)},
+ };
+ if (map_ba74.find(std::make_tuple(ci->type, ci->params[ctx->id("BUS_ADDR74")])) == map_ba74.end())
+ log_error("Invalid value for BUS_ADDR74 for cell '%s' of type '%s'\n", ci->name.c_str(ctx),
+ ci->type.c_str(ctx));
+ Loc bel_loc = map_ba74.at(std::make_tuple(ci->type, ci->params[ctx->id("BUS_ADDR74")]));
+ BelId bel = ctx->getBelByLocation(bel_loc);
+ if (bel == BelId() || ctx->getBelType(bel) != ci->type)
+ log_error("Unable to find placement for cell '%s' of type '%s'\n", ci->name.c_str(ctx),
+ ci->type.c_str(ctx));
+ IdString bel_name = ctx->getBelName(bel);
+ ci->attrs[ctx->id("BEL")] = bel_name.str(ctx);
+ log_info(" constrained %s '%s' to %s\n", ci->type.c_str(ctx), ci->name.c_str(ctx), bel_name.c_str(ctx));
} else if (is_sb_pll40(ctx, ci)) {
bool is_pad = is_sb_pll40_pad(ctx, ci);
bool is_core = !is_pad;