Himbaechel xilinx : More flexibility about types of DSP parameters

This commit is contained in:
Adrien Prost-Boucle 2024-09-19 16:09:05 +02:00 committed by myrtle
parent 81bf92a855
commit 2031a067a0
2 changed files with 58 additions and 17 deletions

View File

@ -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.

View File

@ -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);