Himbaechel xilinx : More flexibility about types of DSP parameters
This commit is contained in:
parent
81bf92a855
commit
2031a067a0
@ -102,6 +102,51 @@ bool bool_or_default(const Container &ct, const KeyType &key, bool def = false)
|
|||||||
return bool(int_or_default(ct, key, int(def)));
|
return bool(int_or_default(ct, key, int(def)));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Get a bool from a map-style container, returning default if value is not found
|
||||||
|
// Also tolerate string representation of boolean for interoperability purposes
|
||||||
|
template <typename KeyType>
|
||||||
|
bool boolstr_or_default(const dict<KeyType, Property> &ct, const KeyType &key, bool def = false)
|
||||||
|
{
|
||||||
|
auto found = ct.find(key);
|
||||||
|
if (found == ct.end())
|
||||||
|
return def;
|
||||||
|
if (!found->second.is_string)
|
||||||
|
bool(found->second.as_int64());
|
||||||
|
const char* str = found->second.as_string().c_str();
|
||||||
|
if(!strcmp(str, "0") || !strcasecmp(str, "false"))
|
||||||
|
return false;
|
||||||
|
else if(!strcmp(str, "1") || !strcasecmp(str, "true"))
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
log_error("Expecting bool-compatible value but got '%s'.\n", found->second.as_string().c_str());
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get a vector of bool from a map-style container, returning default if value is not found
|
||||||
|
// Also tolerate string representation of vector for interoperability purposes
|
||||||
|
template <typename KeyType>
|
||||||
|
bool boolvec_populate(const dict<KeyType, Property> &ct, const KeyType &key, std::vector<bool>& vec)
|
||||||
|
{
|
||||||
|
auto found = ct.find(key);
|
||||||
|
if (found == ct.end())
|
||||||
|
return false;
|
||||||
|
if (!found->second.is_string)
|
||||||
|
{
|
||||||
|
size_t val = found->second.as_int64();
|
||||||
|
for (size_t i = 0; i < vec.size(); ++i, val>>=1) {
|
||||||
|
vec[i] = (val & 0x1) != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const std::string& str = found->second.as_string();
|
||||||
|
size_t i = 0;
|
||||||
|
for (auto it = str.crbegin(); it != str.crend() && i < vec.size(); ++i, ++it) {
|
||||||
|
vec[i] = *it == '1';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
// Get only value from a forward iterator begin/end pair.
|
// Get only value from a forward iterator begin/end pair.
|
||||||
//
|
//
|
||||||
// Generates assertion failure if std::distance(begin, end) != 1.
|
// Generates assertion failure if std::distance(begin, end) != 1.
|
||||||
|
@ -1536,8 +1536,9 @@ struct FasmBackend
|
|||||||
if (binput == "CASCADE")
|
if (binput == "CASCADE")
|
||||||
write_bit("B_INPUT[0]");
|
write_bit("B_INPUT[0]");
|
||||||
|
|
||||||
auto use_dport = str_or_default(ci->params, ctx->id("USE_DPORT"), "FALSE");
|
// Tolerate both int and string types for interoperability purposes
|
||||||
if (use_dport == "TRUE")
|
auto use_dport = boolstr_or_default(ci->params, ctx->id("USE_DPORT"), false);
|
||||||
|
if (use_dport == true)
|
||||||
write_bit("USE_DPORT[0]");
|
write_bit("USE_DPORT[0]");
|
||||||
|
|
||||||
auto use_simd = str_or_default(ci->params, ctx->id("USE_SIMD"), "ONE48");
|
auto use_simd = str_or_default(ci->params, ctx->id("USE_SIMD"), "ONE48");
|
||||||
@ -1547,14 +1548,10 @@ struct FasmBackend
|
|||||||
write_bit("USE_SIMD_FOUR12");
|
write_bit("USE_SIMD_FOUR12");
|
||||||
|
|
||||||
// PATTERN
|
// PATTERN
|
||||||
auto pattern_str = str_or_default(ci->params, ctx->id("PATTERN"), "");
|
const size_t pattern_size = 48;
|
||||||
if (!boost::empty(pattern_str)) {
|
std::vector<bool> pattern_vector(pattern_size, false);
|
||||||
const size_t pattern_size = 48;
|
bool pattern_found = boolvec_populate(ci->params, ctx->id("PATTERN"), pattern_vector);
|
||||||
std::vector<bool> pattern_vector(pattern_size, true);
|
if (pattern_found) {
|
||||||
size_t i = 0;
|
|
||||||
for (auto it = pattern_str.crbegin(); it != pattern_str.crend() && i < pattern_size; ++i, ++it) {
|
|
||||||
pattern_vector[i] = *it == '1';
|
|
||||||
}
|
|
||||||
write_vector("PATTERN[47:0]", pattern_vector);
|
write_vector("PATTERN[47:0]", pattern_vector);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1565,16 +1562,15 @@ struct FasmBackend
|
|||||||
write_bit("AUTORESET_PATDET_RESET_NOT_MATCH");
|
write_bit("AUTORESET_PATDET_RESET_NOT_MATCH");
|
||||||
|
|
||||||
// MASK
|
// MASK
|
||||||
auto mask_str = str_or_default(ci->params, ctx->id("MASK"), "001111111111111111111111111111111111111111111111");
|
|
||||||
// Yosys gives us 48 bit, but prjxray only recognizes 46 bits
|
// Yosys gives us 48 bit, but prjxray only recognizes 46 bits
|
||||||
// The most significant two bits seem to be zero, so let us just truncate them
|
// The most significant two bits seem to be zero, so let us just truncate them
|
||||||
const size_t mask_size = 46;
|
const size_t mask_size = 48;
|
||||||
std::vector<bool> mask_vector(mask_size, true);
|
std::vector<bool> mask_vector(mask_size, true);
|
||||||
size_t i = 0;
|
bool mask_found = boolvec_populate(ci->params, ctx->id("MASK"), mask_vector);
|
||||||
for (auto it = mask_str.crbegin(); it != mask_str.crend() && i < mask_size; ++i, ++it) {
|
if (mask_found) {
|
||||||
mask_vector[i] = *it == '1';
|
mask_vector.resize(46);
|
||||||
|
write_vector("MASK[45:0]", mask_vector);
|
||||||
}
|
}
|
||||||
write_vector("MASK[45:0]", mask_vector);
|
|
||||||
|
|
||||||
auto sel_mask = str_or_default(ci->params, ctx->id("SEL_MASK"), "MASK");
|
auto sel_mask = str_or_default(ci->params, ctx->id("SEL_MASK"), "MASK");
|
||||||
if (sel_mask == "C")
|
if (sel_mask == "C")
|
||||||
@ -1599,7 +1595,7 @@ struct FasmBackend
|
|||||||
write_bit("ZMREG[0]", !bool_or_default(ci->params, ctx->id("MREG")));
|
write_bit("ZMREG[0]", !bool_or_default(ci->params, ctx->id("MREG")));
|
||||||
write_bit("ZOPMODEREG[0]", !bool_or_default(ci->params, ctx->id("OPMODEREG")));
|
write_bit("ZOPMODEREG[0]", !bool_or_default(ci->params, ctx->id("OPMODEREG")));
|
||||||
write_bit("ZPREG[0]", !bool_or_default(ci->params, ctx->id("PREG")));
|
write_bit("ZPREG[0]", !bool_or_default(ci->params, ctx->id("PREG")));
|
||||||
write_bit("USE_DPORT[0]", str_or_default(ci->params, ctx->id("USE_DPORT"), "FALSE") == "TRUE");
|
write_bit("USE_DPORT[0]", boolstr_or_default(ci->params, ctx->id("USE_DPORT"), false));
|
||||||
write_bit("ZIS_CLK_INVERTED", !bool_or_default(ci->params, ctx->id("IS_CLK_INVERTED")));
|
write_bit("ZIS_CLK_INVERTED", !bool_or_default(ci->params, ctx->id("IS_CLK_INVERTED")));
|
||||||
write_bit("ZIS_CARRYIN_INVERTED", !bool_or_default(ci->params, ctx->id("IS_CARRYIN_INVERTED")));
|
write_bit("ZIS_CARRYIN_INVERTED", !bool_or_default(ci->params, ctx->id("IS_CARRYIN_INVERTED")));
|
||||||
pop(2);
|
pop(2);
|
||||||
|
Loading…
Reference in New Issue
Block a user