Merge pull request #952 from antmicro/mdudek/nexus_pll
Nexus: Fixed OSCA parameters, add pll default parameters
This commit is contained in:
commit
5850cb6336
@ -1408,7 +1408,8 @@ struct Arch : BaseArch<ArchRanges>
|
|||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
|
|
||||||
// Parse a possibly-Lattice-style (C literal in Verilog string) style parameter
|
// Parse a possibly-Lattice-style (C literal in Verilog string) style parameter
|
||||||
Property parse_lattice_param(const CellInfo *ci, IdString prop, int width, int64_t defval) const;
|
Property parse_lattice_param_from_cell(const CellInfo *ci, IdString prop, int width, int64_t defval) const;
|
||||||
|
Property parse_lattice_param(const Property &val, IdString prop, int width, const char* ci="") const;
|
||||||
|
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
|
|
||||||
|
161
nexus/fasm.cc
161
nexus/fasm.cc
@ -521,8 +521,10 @@ struct NexusFasmWriter
|
|||||||
write_enum(cell, "HFDIV_FABRIC_EN", "ENABLED");
|
write_enum(cell, "HFDIV_FABRIC_EN", "ENABLED");
|
||||||
write_enum(cell, "LF_FABRIC_EN");
|
write_enum(cell, "LF_FABRIC_EN");
|
||||||
write_enum(cell, "LF_OUTPUT_EN");
|
write_enum(cell, "LF_OUTPUT_EN");
|
||||||
|
write_enum(cell, "DTR_EN", "ENABLED");
|
||||||
write_enum(cell, "DEBUG_N", "DISABLED");
|
write_enum(cell, "DEBUG_N", "DISABLED");
|
||||||
write_int_vector(stringf("HF_CLK_DIV[7:0]"), ctx->parse_lattice_param(cell, id_HF_CLK_DIV, 8, 0).intval, 8);
|
write_int_vector(stringf("HF_CLK_DIV[7:0]"), ctx->parse_lattice_param_from_cell(cell, id_HF_CLK_DIV, 8, 0).intval, 8);
|
||||||
|
write_int_vector(stringf("HF_SED_SEC_DIV[7:0]"), 1, 8);
|
||||||
write_cell_muxes(cell);
|
write_cell_muxes(cell);
|
||||||
pop(2);
|
pop(2);
|
||||||
}
|
}
|
||||||
@ -681,6 +683,125 @@ struct NexusFasmWriter
|
|||||||
{"V2I_PP_ICTRL", 5},
|
{"V2I_PP_ICTRL", 5},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const dict<std::string, std::string> pll_default_params = {
|
||||||
|
{"BW_CTL_BIAS", "0b0101"},
|
||||||
|
{"CLKOP_TRIM", "0b0000"},
|
||||||
|
{"CLKOS_TRIM", "0b0000"},
|
||||||
|
{"CLKOS2_TRIM", "0b0000"},
|
||||||
|
{"CLKOS3_TRIM", "0b0000"},
|
||||||
|
{"CLKOS4_TRIM", "0b0000"},
|
||||||
|
{"CLKOS5_TRIM", "0b0000"},
|
||||||
|
{"CRIPPLE", "5P"},
|
||||||
|
{"CSET", "40P"},
|
||||||
|
{"DELAY_CTRL", "200PS"},
|
||||||
|
{"DELA", "0"},
|
||||||
|
{"DELB", "0"},
|
||||||
|
{"DELC", "0"},
|
||||||
|
{"DELD", "0"},
|
||||||
|
{"DELE", "0"},
|
||||||
|
{"DELF", "0"},
|
||||||
|
{"DIRECTION", "DISABLED"},
|
||||||
|
{"DIVA", "0"},
|
||||||
|
{"DIVB", "0"},
|
||||||
|
{"DIVC", "0"},
|
||||||
|
{"DIVD", "0"},
|
||||||
|
{"DIVE", "0"},
|
||||||
|
{"DIVF", "0"},
|
||||||
|
{"DYN_SEL", "0b000"},
|
||||||
|
{"DYN_SOURCE", "STATIC"},
|
||||||
|
{"ENCLK_CLKOP", "DISABLED"},
|
||||||
|
{"ENCLK_CLKOS", "DISABLED"},
|
||||||
|
{"ENCLK_CLKOS2", "DISABLED"},
|
||||||
|
{"ENCLK_CLKOS3", "DISABLED"},
|
||||||
|
{"ENCLK_CLKOS4", "DISABLED"},
|
||||||
|
{"ENCLK_CLKOS5", "DISABLED"},
|
||||||
|
{"ENABLE_SYNC", "DISABLED"},
|
||||||
|
{"FAST_LOCK_EN", "ENABLED"},
|
||||||
|
{"V2I_1V_EN", "DISABLED"},
|
||||||
|
{"FBK_CUR_BLE", "0b00000000"},
|
||||||
|
{"FBK_EDGE_SEL", "POSITIVE"},
|
||||||
|
{"FBK_IF_TIMING_CTL", "0b00"},
|
||||||
|
{"FBK_INTEGER_MODE", "DISABLED"},
|
||||||
|
{"FBK_MASK", "0b00001000"},
|
||||||
|
{"FBK_MMD_DIG", "8"},
|
||||||
|
{"FBK_MMD_PULS_CTL", "0b0000"},
|
||||||
|
{"FBK_MODE", "0b00"},
|
||||||
|
{"FBK_PI_BYPASS", "NOT_BYPASSED"},
|
||||||
|
{"FBK_PI_RC", "0b1100"},
|
||||||
|
{"FBK_PR_CC", "0b0000"},
|
||||||
|
{"FBK_PR_IC", "0b1000"},
|
||||||
|
{"FLOAT_CP", "DISABLED"},
|
||||||
|
{"FLOCK_CTRL", "2X"},
|
||||||
|
{"FLOCK_EN", "ENABLED"},
|
||||||
|
{"FLOCK_SRC_SEL", "REFCLK"},
|
||||||
|
{"FORCE_FILTER", "DISABLED"},
|
||||||
|
{"I_CTRL", "10UA"},
|
||||||
|
{"IPI_CMP", "0b1000"},
|
||||||
|
{"IPI_CMPN", "0b0011"},
|
||||||
|
{"IPI_COMP_EN", "DISABLED"},
|
||||||
|
{"IPP_CTRL", "0b1000"},
|
||||||
|
{"IPP_SEL", "0b1111"},
|
||||||
|
{"KP_VCO", "0b11001"},
|
||||||
|
{"LDT_INT_LOCK_STICKY", "DISABLED"},
|
||||||
|
{"LDT_LOCK", "1536CYC"},
|
||||||
|
{"LDT_LOCK_SEL", "U_FREQ"},
|
||||||
|
{"LEGACY_ATT", "DISABLED"},
|
||||||
|
{"LOAD_REG", "DISABLED"},
|
||||||
|
{"OPENLOOP_EN", "DISABLED"},
|
||||||
|
{"PHIA", "0"},
|
||||||
|
{"PHIB", "0"},
|
||||||
|
{"PHIC", "0"},
|
||||||
|
{"PHID", "0"},
|
||||||
|
{"PHIE", "0"},
|
||||||
|
{"PHIF", "0"},
|
||||||
|
{"PLLPDN_EN", "DISABLED"},
|
||||||
|
{"PLLPD_N", "UNUSED"},
|
||||||
|
{"PLLRESET_ENA", "DISABLED"},
|
||||||
|
{"REF_INTEGER_MODE", "DISABLED"},
|
||||||
|
{"REF_MASK", "0b00000000"},
|
||||||
|
{"REF_MMD_DIG", "8"},
|
||||||
|
{"REF_MMD_IN", "0b00001000"},
|
||||||
|
{"REF_MMD_PULS_CTL", "0b0000"},
|
||||||
|
{"REF_TIMING_CTL", "0b00"},
|
||||||
|
{"REFIN_RESET", "SET"},
|
||||||
|
{"RESET_LF", "DISABLED"},
|
||||||
|
{"ROTATE", "DISABLED"},
|
||||||
|
{"SEL_OUTA", "DISABLED"},
|
||||||
|
{"SEL_OUTB", "DISABLED"},
|
||||||
|
{"SEL_OUTC", "DISABLED"},
|
||||||
|
{"SEL_OUTD", "DISABLED"},
|
||||||
|
{"SEL_OUTE", "DISABLED"},
|
||||||
|
{"SEL_OUTF", "DISABLED"},
|
||||||
|
{"SLEEP", "DISABLED"},
|
||||||
|
{"SSC_DELTA", "0b000000000000000"},
|
||||||
|
{"SSC_DELTA_CTL", "0b00"},
|
||||||
|
{"SSC_DITHER", "DISABLED"},
|
||||||
|
{"SSC_EN_CENTER_IN", "DOWN_TRIANGLE"},
|
||||||
|
{"SSC_EN_SDM", "DISABLED"},
|
||||||
|
{"SSC_EN_SSC", "DISABLED"},
|
||||||
|
{"SSC_F_CODE", "0b000000000000000"},
|
||||||
|
{"SSC_N_CODE", "0b000010100"},
|
||||||
|
{"SSC_ORDER", "SDM_ORDER2"},
|
||||||
|
{"SSC_PI_BYPASS", "NOT_BYPASSED"},
|
||||||
|
{"SSC_REG_WEIGHTING_SEL", "0b000"},
|
||||||
|
{"SSC_SQUARE_MODE", "DISABLED"},
|
||||||
|
{"SSC_STEP_IN", "0b0000000"},
|
||||||
|
{"SSC_TBASE", "0b000000000000"},
|
||||||
|
{"STDBY_ATT", "DISABLED"},
|
||||||
|
{"TRIMOP_BYPASS_N", "BYPASSED"},
|
||||||
|
{"TRIMOS_BYPASS_N", "BYPASSED"},
|
||||||
|
{"TRIMOS2_BYPASS_N", "BYPASSED"},
|
||||||
|
{"TRIMOS3_BYPASS_N", "BYPASSED"},
|
||||||
|
{"TRIMOS4_BYPASS_N", "BYPASSED"},
|
||||||
|
{"TRIMOS5_BYPASS_N", "BYPASSED"},
|
||||||
|
{"V2I_KVCO_SEL", "85"},
|
||||||
|
{"V2I_PP_ICTRL", "0b00110"},
|
||||||
|
{"V2I_PP_RES", "10K"},
|
||||||
|
{"CLKMUX_FB", "CMUX_CLKOP"},
|
||||||
|
{"SEL_FBK", "DIVA"},
|
||||||
|
{"DIV_DEL", "0b0000001"},
|
||||||
|
};
|
||||||
|
|
||||||
// Which MIPI params are 'word' values
|
// Which MIPI params are 'word' values
|
||||||
const dict<std::string, int> dphy_word_params = {
|
const dict<std::string, int> dphy_word_params = {
|
||||||
{"CM", 8}, {"CN", 5}, {"CO", 3}, {"RSEL", 2}, {"RXCDRP", 2},
|
{"CM", 8}, {"CN", 5}, {"CO", 3}, {"RSEL", 2}, {"RXCDRP", 2},
|
||||||
@ -691,6 +812,14 @@ struct NexusFasmWriter
|
|||||||
};
|
};
|
||||||
/* clang-format on */
|
/* clang-format on */
|
||||||
|
|
||||||
|
static bool is_number(std::string s) {
|
||||||
|
for (auto c : s) {
|
||||||
|
if(!isdigit(c))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Write out config for some kind of PLL cell
|
// Write out config for some kind of PLL cell
|
||||||
void write_pll(const CellInfo *cell)
|
void write_pll(const CellInfo *cell)
|
||||||
{
|
{
|
||||||
@ -701,17 +830,33 @@ struct NexusFasmWriter
|
|||||||
write_cell_muxes(cell);
|
write_cell_muxes(cell);
|
||||||
pop();
|
pop();
|
||||||
push(stringf("IP_%s", ctx->nameOf(IdString(ctx->bel_data(bel).name))));
|
push(stringf("IP_%s", ctx->nameOf(IdString(ctx->bel_data(bel).name))));
|
||||||
for (auto ¶m : cell->params) {
|
for (auto &value : pll_default_params) {
|
||||||
const std::string &name = param.first.str(ctx);
|
IdString n = IdString(ctx, value.first);
|
||||||
|
Property temp;
|
||||||
|
if (is_number(value.second))
|
||||||
|
temp = Property(std::stoi(value.second), 32);
|
||||||
|
else
|
||||||
|
temp = Property::from_string(value.second);
|
||||||
|
const std::string &name = n.str(ctx);
|
||||||
if (is_mux_param(name) || name == "CLKMUX_FB" || name == "SEL_FBK")
|
if (is_mux_param(name) || name == "CLKMUX_FB" || name == "SEL_FBK")
|
||||||
continue;
|
continue;
|
||||||
auto fnd_word = pll_word_params.find(name);
|
auto fnd_word = pll_word_params.find(name);
|
||||||
if (fnd_word != pll_word_params.end()) {
|
if (fnd_word != pll_word_params.end()) {
|
||||||
write_int_vector(stringf("%s[%d:0]", name.c_str(), fnd_word->second - 1),
|
if (cell->params.count(n)) {
|
||||||
ctx->parse_lattice_param(cell, param.first, fnd_word->second, 0).as_int64(),
|
write_int_vector(stringf("%s[%d:0]", name.c_str(), fnd_word->second - 1),
|
||||||
fnd_word->second);
|
ctx->parse_lattice_param_from_cell(cell, n, fnd_word->second, 0).as_int64(),
|
||||||
|
fnd_word->second);
|
||||||
|
} else {
|
||||||
|
write_int_vector(stringf("%s[%d:0]", name.c_str(), fnd_word->second - 1),
|
||||||
|
ctx->parse_lattice_param(temp, n, fnd_word->second).as_int64(),
|
||||||
|
fnd_word->second);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
write_bit(stringf("%s.%s", name.c_str(), param.second.as_string().c_str()));
|
if (cell->params.count(n)) {
|
||||||
|
write_bit(stringf("%s.%s", name.c_str(), cell->params.at(n).as_string().c_str()));
|
||||||
|
} else {
|
||||||
|
write_bit(stringf("%s.%s", name.c_str(), temp.as_string().c_str()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pop();
|
pop();
|
||||||
@ -729,7 +874,7 @@ struct NexusFasmWriter
|
|||||||
auto fnd_word = dphy_word_params.find(name);
|
auto fnd_word = dphy_word_params.find(name);
|
||||||
if (fnd_word != dphy_word_params.end()) {
|
if (fnd_word != dphy_word_params.end()) {
|
||||||
write_int_vector(stringf("%s[%d:0]", name.c_str(), fnd_word->second - 1),
|
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(),
|
ctx->parse_lattice_param_from_cell(cell, param.first, fnd_word->second, 0).as_int64(),
|
||||||
fnd_word->second);
|
fnd_word->second);
|
||||||
} else {
|
} else {
|
||||||
write_bit(stringf("%s.%s", name.c_str(), param.second.as_string().c_str()));
|
write_bit(stringf("%s.%s", name.c_str(), param.second.as_string().c_str()));
|
||||||
|
@ -32,13 +32,17 @@ namespace {
|
|||||||
bool is_enabled(CellInfo *ci, IdString prop) { return str_or_default(ci->params, prop, "") == "ENABLED"; }
|
bool is_enabled(CellInfo *ci, IdString prop) { return str_or_default(ci->params, prop, "") == "ENABLED"; }
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
// Parse a possibly-Lattice-style (C literal in Verilog string) style parameter
|
Property Arch::parse_lattice_param_from_cell(const CellInfo *ci, IdString prop, int width, int64_t defval) const
|
||||||
Property Arch::parse_lattice_param(const CellInfo *ci, IdString prop, int width, int64_t defval) const
|
|
||||||
{
|
{
|
||||||
auto fnd = ci->params.find(prop);
|
auto fnd = ci->params.find(prop);
|
||||||
if (fnd == ci->params.end())
|
if (fnd == ci->params.end())
|
||||||
return Property(defval, width);
|
return Property(defval, width);
|
||||||
const auto &val = fnd->second;
|
return this->parse_lattice_param(fnd->second, prop, width, nameOf(ci));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse a possibly-Lattice-style (C literal in Verilog string) style parameter
|
||||||
|
Property Arch::parse_lattice_param(const Property &val, IdString prop, int width, const char* ci) const
|
||||||
|
{
|
||||||
if (val.is_string) {
|
if (val.is_string) {
|
||||||
const std::string &s = val.str;
|
const std::string &s = val.str;
|
||||||
Property temp;
|
Property temp;
|
||||||
@ -47,7 +51,7 @@ Property Arch::parse_lattice_param(const CellInfo *ci, IdString prop, int width,
|
|||||||
for (int i = int(s.length()) - 1; i >= 2; i--) {
|
for (int i = int(s.length()) - 1; i >= 2; i--) {
|
||||||
char c = s.at(i);
|
char c = s.at(i);
|
||||||
if (c != '0' && c != '1' && c != 'x')
|
if (c != '0' && c != '1' && c != 'x')
|
||||||
log_error("Invalid binary digit '%c' in property %s.%s\n", c, nameOf(ci), nameOf(prop));
|
log_error("Invalid binary digit '%c' in property %s.%s\n", c, ci, nameOf(prop));
|
||||||
temp.str.push_back(c);
|
temp.str.push_back(c);
|
||||||
}
|
}
|
||||||
} else if (boost::starts_with(s, "0x")) {
|
} else if (boost::starts_with(s, "0x")) {
|
||||||
@ -61,7 +65,7 @@ Property Arch::parse_lattice_param(const CellInfo *ci, IdString prop, int width,
|
|||||||
else if (c >= 'A' && c <= 'F')
|
else if (c >= 'A' && c <= 'F')
|
||||||
nibble = (c - 'A') + 10;
|
nibble = (c - 'A') + 10;
|
||||||
else
|
else
|
||||||
log_error("Invalid hex digit '%c' in property %s.%s\n", c, nameOf(ci), nameOf(prop));
|
log_error("Invalid hex digit '%c' in property %s.%s\n", c, ci, nameOf(prop));
|
||||||
for (int j = 0; j < 4; j++)
|
for (int j = 0; j < 4; j++)
|
||||||
temp.str.push_back(((nibble >> j) & 0x1) ? Property::S1 : Property::S0);
|
temp.str.push_back(((nibble >> j) & 0x1) ? Property::S1 : Property::S0);
|
||||||
}
|
}
|
||||||
@ -73,14 +77,14 @@ Property Arch::parse_lattice_param(const CellInfo *ci, IdString prop, int width,
|
|||||||
else
|
else
|
||||||
ival = std::stoll(s);
|
ival = std::stoll(s);
|
||||||
} catch (std::runtime_error &e) {
|
} catch (std::runtime_error &e) {
|
||||||
log_error("Invalid decimal value for property %s.%s", nameOf(ci), nameOf(prop));
|
log_error("Invalid decimal value for property %s.%s", ci, nameOf(prop));
|
||||||
}
|
}
|
||||||
temp = Property(ival);
|
temp = Property(ival);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto b : temp.str.substr(width)) {
|
for (auto b : temp.str.substr(width)) {
|
||||||
if (b == Property::S1)
|
if (b == Property::S1)
|
||||||
log_error("Found value for property %s.%s with width greater than %d\n", nameOf(ci), nameOf(prop),
|
log_error("Found value for property %s.%s with width greater than %d\n", ci, nameOf(prop),
|
||||||
width);
|
width);
|
||||||
}
|
}
|
||||||
temp.update_intval();
|
temp.update_intval();
|
||||||
@ -90,7 +94,7 @@ Property Arch::parse_lattice_param(const CellInfo *ci, IdString prop, int width,
|
|||||||
if (b == Property::S1)
|
if (b == Property::S1)
|
||||||
log_error("Found bitvector value for property %s.%s with width greater than %d - perhaps a string was "
|
log_error("Found bitvector value for property %s.%s with width greater than %d - perhaps a string was "
|
||||||
"converted to bits?\n",
|
"converted to bits?\n",
|
||||||
nameOf(ci), nameOf(prop), width);
|
ci, nameOf(prop), width);
|
||||||
}
|
}
|
||||||
return val.extract(0, width);
|
return val.extract(0, width);
|
||||||
}
|
}
|
||||||
@ -170,7 +174,7 @@ struct NexusPacker
|
|||||||
int64_t def;
|
int64_t def;
|
||||||
for (const auto &p : rule.parse_params) {
|
for (const auto &p : rule.parse_params) {
|
||||||
std::tie(old_param, new_param, width, def) = p;
|
std::tie(old_param, new_param, width, def) = p;
|
||||||
ci->params[new_param] = ctx->parse_lattice_param(ci, old_param, width, def);
|
ci->params[new_param] = ctx->parse_lattice_param_from_cell(ci, old_param, width, def);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -953,7 +957,7 @@ struct NexusPacker
|
|||||||
ramw->connectPort(id_WCKO, int_wck);
|
ramw->connectPort(id_WCKO, int_wck);
|
||||||
ramw->connectPort(id_WREO, int_wre);
|
ramw->connectPort(id_WREO, int_wre);
|
||||||
|
|
||||||
uint64_t initval = ctx->parse_lattice_param(ci, id_INITVAL, 64, 0).as_int64();
|
uint64_t initval = ctx->parse_lattice_param_from_cell(ci, id_INITVAL, 64, 0).as_int64();
|
||||||
|
|
||||||
// Rewiring - buses
|
// Rewiring - buses
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
@ -1272,8 +1276,8 @@ struct NexusPacker
|
|||||||
combs[1]->connectPort(id_F, f1);
|
combs[1]->connectPort(id_F, f1);
|
||||||
combs[0]->connectPort(id_F1, f1);
|
combs[0]->connectPort(id_F1, f1);
|
||||||
|
|
||||||
combs[0]->params[id_INIT] = ctx->parse_lattice_param(ci, id_INIT0, 16, 0);
|
combs[0]->params[id_INIT] = ctx->parse_lattice_param_from_cell(ci, id_INIT0, 16, 0);
|
||||||
combs[1]->params[id_INIT] = ctx->parse_lattice_param(ci, id_INIT1, 16, 0);
|
combs[1]->params[id_INIT] = ctx->parse_lattice_param_from_cell(ci, id_INIT1, 16, 0);
|
||||||
|
|
||||||
combs[1]->cluster = combs[0]->name;
|
combs[1]->cluster = combs[0]->name;
|
||||||
combs[1]->constr_x = 0;
|
combs[1]->constr_x = 0;
|
||||||
@ -1329,8 +1333,8 @@ struct NexusPacker
|
|||||||
// Copy parameters
|
// Copy parameters
|
||||||
if (ci->params.count(id_INJECT))
|
if (ci->params.count(id_INJECT))
|
||||||
combs[0]->params[id_INJECT] = ci->params[id_INJECT];
|
combs[0]->params[id_INJECT] = ci->params[id_INJECT];
|
||||||
combs[0]->params[id_INIT] = ctx->parse_lattice_param(ci, id_INIT0, 16, 0);
|
combs[0]->params[id_INIT] = ctx->parse_lattice_param_from_cell(ci, id_INIT0, 16, 0);
|
||||||
combs[1]->params[id_INIT] = ctx->parse_lattice_param(ci, id_INIT1, 16, 0);
|
combs[1]->params[id_INIT] = ctx->parse_lattice_param_from_cell(ci, id_INIT1, 16, 0);
|
||||||
|
|
||||||
// Internal carry net between the two split COMB cells
|
// Internal carry net between the two split COMB cells
|
||||||
NetInfo *int_cy = ctx->createNet(ctx->id(stringf("%s$widefn_int_cy$", ctx->nameOf(ci))));
|
NetInfo *int_cy = ctx->createNet(ctx->id(stringf("%s$widefn_int_cy$", ctx->nameOf(ci))));
|
||||||
@ -2026,9 +2030,9 @@ struct NexusPacker
|
|||||||
log_info(" Input frequency of PLL '%s' is constrained to %.1f MHz\n", ci->name.c_str(ctx),
|
log_info(" Input frequency of PLL '%s' is constrained to %.1f MHz\n", ci->name.c_str(ctx),
|
||||||
MHz(period_in));
|
MHz(period_in));
|
||||||
|
|
||||||
int input_div = ctx->parse_lattice_param(ci, id_REF_MMD_DIG, 8, 1).as_int64();
|
int input_div = ctx->parse_lattice_param_from_cell(ci, id_REF_MMD_DIG, 8, 1).as_int64();
|
||||||
period_in *= input_div;
|
period_in *= input_div;
|
||||||
int feedback_div = ctx->parse_lattice_param(ci, id_REF_MMD_DIG, 8, 1).as_int64();
|
int feedback_div = ctx->parse_lattice_param_from_cell(ci, id_REF_MMD_DIG, 8, 1).as_int64();
|
||||||
bool found_fbk = false;
|
bool found_fbk = false;
|
||||||
std::string clkmux_fb = str_or_default(ci->params, id_CLKMUX_FB, "CMUX_CLKOP");
|
std::string clkmux_fb = str_or_default(ci->params, id_CLKMUX_FB, "CMUX_CLKOP");
|
||||||
for (int i = 0; i < 6; i++) {
|
for (int i = 0; i < 6; i++) {
|
||||||
@ -2036,7 +2040,7 @@ struct NexusPacker
|
|||||||
if (clkmux_fb != stringf("CMUX_%s", output[i].c_str(ctx)))
|
if (clkmux_fb != stringf("CMUX_%s", output[i].c_str(ctx)))
|
||||||
continue;
|
continue;
|
||||||
// Multiply feedback output divider with
|
// Multiply feedback output divider with
|
||||||
feedback_div *= (ctx->parse_lattice_param(ci, div[i], 7, 0).as_int64() + 1);
|
feedback_div *= (ctx->parse_lattice_param_from_cell(ci, div[i], 7, 0).as_int64() + 1);
|
||||||
found_fbk = true;
|
found_fbk = true;
|
||||||
}
|
}
|
||||||
if (!found_fbk) {
|
if (!found_fbk) {
|
||||||
@ -2050,7 +2054,7 @@ struct NexusPacker
|
|||||||
MHz(vco_period));
|
MHz(vco_period));
|
||||||
for (int i = 0; i < 6; i++) {
|
for (int i = 0; i < 6; i++) {
|
||||||
set_period(ci, output[i],
|
set_period(ci, output[i],
|
||||||
(ctx->parse_lattice_param(ci, div[i], 7, 0).as_int64() + 1) * vco_period);
|
(ctx->parse_lattice_param_from_cell(ci, div[i], 7, 0).as_int64() + 1) * vco_period);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user