aboutsummaryrefslogtreecommitdiffstats
path: root/nexus/fasm.cc
diff options
context:
space:
mode:
Diffstat (limited to 'nexus/fasm.cc')
-rw-r--r--nexus/fasm.cc56
1 files changed, 56 insertions, 0 deletions
diff --git a/nexus/fasm.cc b/nexus/fasm.cc
index 5da809c6..fcbe0b8c 100644
--- a/nexus/fasm.cc
+++ b/nexus/fasm.cc
@@ -542,6 +542,60 @@ struct NexusFasmWriter
write_cell_muxes(cell);
pop();
}
+
+ // Which PLL params are 'word' values
+ /* clang-format off */
+ const std::unordered_map<std::string, int> pll_word_params = {
+ {"DIVA", 7}, {"DELA", 7}, {"PHIA", 3}, {"DIVB", 7},
+ {"DELB", 7}, {"PHIB", 3}, {"DIVC", 7}, {"DELC", 7},
+ {"PHIC", 3}, {"DIVD", 7}, {"DELD", 7}, {"PHID", 3},
+ {"DIVE", 7}, {"DELE", 7}, {"PHIE", 3}, {"DIVF", 7},
+ {"DELF", 7}, {"PHIF", 3}, {"BW_CTL_BIAS", 4},
+ {"CLKOP_TRIM", 4}, {"CLKOS_TRIM", 4}, {"CLKOS2_TRIM", 4},
+ {"CLKOS3_TRIM", 4}, {"CLKOS4_TRIM", 4}, {"CLKOS5_TRIM", 4},
+ {"DIV_DEL", 7}, {"DYN_SEL", 3}, {"FBK_CUR_BLE", 8}, {"FBK_IF_TIMING_CTL", 2},
+ {"FBK_MASK", 8}, {"FBK_MMD_DIG", 8}, {"FBK_MMD_PULS_CTL", 4},
+ {"FBK_MODE", 2}, {"FBK_PI_RC", 4}, {"FBK_PR_CC", 4},
+ {"FBK_PR_IC", 4}, {"FBK_RSV", 16},
+ {"IPI_CMP", 4}, {"IPI_CMPN", 4},
+ {"IPP_CTRL", 4}, {"IPP_SEL", 4},
+ {"KP_VCO", 5},
+ {"MFG_CTRL", 4}, {"MFGOUT1_SEL", 3}, {"MFGOUT2_SEL", 3},
+ {"REF_MASK", 8}, {"REF_MMD_DIG", 8}, {"REF_MMD_IN", 8},
+ {"REF_MMD_PULS_CTL", 4}, {"REF_TIMING_CTL", 2},
+ {"RESERVED", 7}, {"SSC_DELTA", 15},
+ {"SSC_DELTA_CTL", 2}, {"SSC_F_CODE", 15},
+ {"SSC_N_CODE", 9}, {"SSC_REG_WEIGHTING_SEL", 3},
+ {"SSC_STEP_IN", 7}, {"SSC_TBASE", 12},
+ {"V2I_PP_ICTRL", 5},
+ };
+ /* clang-format on */
+
+ // Write out config for some kind of PLL cell
+ void write_pll(const CellInfo *cell)
+ {
+ BelId bel = cell->bel;
+ push_bel(bel);
+ write_bit("MODE.PLL_CORE");
+ write_enum(cell, "CLKMUX_FB");
+ write_cell_muxes(cell);
+ pop();
+ push(stringf("IP_%s", ctx->nameOf(ctx->bel_data(bel).name)));
+ for (auto param : sorted_cref(cell->params)) {
+ const std::string &name = param.first.str(ctx);
+ if (is_mux_param(name) || name == "CLKMUX_FB" || name == "SEL_FBK")
+ continue;
+ auto fnd_word = pll_word_params.find(name);
+ if (fnd_word != pll_word_params.end()) {
+ write_int_vector(stringf("%s[%d:0]", name.c_str(), fnd_word->second - 1),
+ ctx->parse_lattice_param(cell, param.first, fnd_word->second, 0).as_int64(),
+ fnd_word->second);
+ } else {
+ write_bit(stringf("%s.%s", name.c_str(), param.second.as_string().c_str()));
+ }
+ }
+ pop();
+ }
// Write out FASM for unused bels where needed
void write_unused()
{
@@ -654,6 +708,8 @@ struct NexusFasmWriter
ci->type == id_MULT18X36_CORE || ci->type == id_MULT36_CORE || ci->type == id_REG18_CORE ||
ci->type == id_ACC54_CORE)
write_dsp(ci);
+ else if (ci->type == id_PLL_CORE)
+ write_pll(ci);
blank();
}
// Write config for unused bels