aboutsummaryrefslogtreecommitdiffstats
path: root/ice40/cells.cc
diff options
context:
space:
mode:
authorSergiusz Bazanski <q3k@q3k.org>2018-07-22 13:42:07 +0100
committerSergiusz Bazanski <q3k@q3k.org>2018-07-24 02:38:10 +0100
commit2b1f7875bb8c3a761dfb9db21706f918b58be9c3 (patch)
tree0fb0e8c7162cd3291f32ad6588e803105902f1e3 /ice40/cells.cc
parent139f7e0903b6c299b7c85bebfd7674933e952a50 (diff)
downloadnextpnr-2b1f7875bb8c3a761dfb9db21706f918b58be9c3.tar.gz
nextpnr-2b1f7875bb8c3a761dfb9db21706f918b58be9c3.tar.bz2
nextpnr-2b1f7875bb8c3a761dfb9db21706f918b58be9c3.zip
ice40: Implement emitting PLLs
Diffstat (limited to 'ice40/cells.cc')
-rw-r--r--ice40/cells.cc49
1 files changed, 49 insertions, 0 deletions
diff --git a/ice40/cells.cc b/ice40/cells.cc
index 71a65d44..3215a38c 100644
--- a/ice40/cells.cc
+++ b/ice40/cells.cc
@@ -207,6 +207,40 @@ std::unique_ptr<CellInfo> create_ice_cell(Context *ctx, IdString type, std::stri
add_port(ctx, new_cell.get(), "ACCUMCO", PORT_OUT);
add_port(ctx, new_cell.get(), "SIGNEXTOUT", PORT_OUT);
+ } else if (type == ctx->id("ICESTORM_PLL")) {
+ new_cell->params[ctx->id("DELAY_ADJMODE_FB")] = "0";
+ new_cell->params[ctx->id("DELAY_ADJMODE_REL")] = "0";
+
+ new_cell->params[ctx->id("DIVF")] = "0";
+ new_cell->params[ctx->id("DIVQ")] = "0";
+ new_cell->params[ctx->id("DIVR")] = "0";
+
+ new_cell->params[ctx->id("FDA_FEEDBACK")] = "0";
+ new_cell->params[ctx->id("FDA_RELATIVE")] = "0";
+ new_cell->params[ctx->id("FEEDBACK_PATH")] = "0";
+ new_cell->params[ctx->id("FILTER_RANGE")] = "0";
+
+ new_cell->params[ctx->id("PLLOUT_SELECT_A")] = "0";
+ new_cell->params[ctx->id("PLLOUT_SELECT_B")] = "0";
+
+ new_cell->params[ctx->id("PLLTYPE")] = "0";
+ new_cell->params[ctx->id("SHIFTREG_DIVMODE")] = "0";
+ new_cell->params[ctx->id("TEST_MODE")] = "0";
+
+ add_port(ctx, new_cell.get(), "BYPASS", PORT_IN);
+ add_port(ctx, new_cell.get(), "DYNAMICDELAY", PORT_IN);
+ add_port(ctx, new_cell.get(), "EXTFEEDBACK", PORT_IN);
+ add_port(ctx, new_cell.get(), "LATCHINPUTVALUE", PORT_IN);
+ add_port(ctx, new_cell.get(), "REFERENCECLK", PORT_IN);
+ add_port(ctx, new_cell.get(), "RESETB", PORT_IN);
+
+ add_port(ctx, new_cell.get(), "SCLK", PORT_IN);
+ add_port(ctx, new_cell.get(), "SDI", PORT_IN);
+ add_port(ctx, new_cell.get(), "SDI", PORT_OUT);
+
+ add_port(ctx, new_cell.get(), "LOCK", PORT_OUT);
+ add_port(ctx, new_cell.get(), "PLLOUT_A", PORT_OUT);
+ add_port(ctx, new_cell.get(), "PLLOUT_B", PORT_OUT);
} else {
log_error("unable to create iCE40 cell of type %s", type.c_str(ctx));
}
@@ -312,6 +346,21 @@ void nxio_to_sb(Context *ctx, CellInfo *nxio, CellInfo *sbio)
}
}
+uint8_t sb_pll40_type(const BaseCtx *ctx, const CellInfo *cell)
+{
+ if (cell->type == ctx->id("SB_PLL40_PAD"))
+ return 2;
+ if (cell->type == ctx->id("SB_PLL40_2_PAD"))
+ return 4;
+ if (cell->type == ctx->id("SB_PLL40_2F_PAD"))
+ return 5;
+ if (cell->type == ctx->id("SB_PLL40_CORE"))
+ return 3;
+ if (cell->type == ctx->id("SB_PLL40_2F_CORE"))
+ return 7;
+ NPNR_ASSERT(0);
+}
+
bool is_clock_port(const BaseCtx *ctx, const PortRef &port)
{
if (port.cell == nullptr)