Use attr/value from rules file, add use new match rule
diff --git a/passes/memory/memory_bram.cc b/passes/memory/memory_bram.cc index 2d2897e..52e7ac7 100644 --- a/passes/memory/memory_bram.cc +++ b/passes/memory/memory_bram.cc
@@ -134,7 +134,8 @@ dict<string, int> min_limits, max_limits; bool or_next_if_better, make_transp, make_outreg; char shuffle_enable; - std::string memattr; + IdString attr; + Const value; }; dict<IdString, vector<bram_t>> brams; @@ -328,8 +329,10 @@ continue; } - if (GetSize(tokens) == 3 && tokens[0] == "attribute") { - data.memattr = tokens[2].c_str(); + if (GetSize(tokens) >= 2 && tokens[0] == "attribute") { + data.attr = RTLIL::escape_id(tokens[1]); + if (GetSize(tokens) > 2) + data.value = tokens[2]; continue; } @@ -368,20 +371,6 @@ } }; -bool check_memory_attribute(Cell *cell, std::string match) -{ - std::string memory_attribute = cell->attributes["\\ram_style"].decode_string(); - bool attribute_set_match = 0; - - if (memory_attribute != "") - { - attribute_set_match = match.compare(memory_attribute); - if (!attribute_set_match) - return true; - } - return false; -} - bool replace_cell(Cell *cell, const rules_t &rules, const rules_t::bram_t &bram, const rules_t::match_t &match, dict<string, int> &match_properties, int mode) { Module *module = cell->module; @@ -817,8 +806,6 @@ it.first.c_str(), log_id(match.name)); if (match_properties[it.first] >= it.second) continue; - if (check_memory_attribute(cell, match.memattr)) - continue; log(" Rule for bram type %s rejected: requirement 'min %s %d' not met.\n", log_id(match.name), it.first.c_str(), it.second); return false; @@ -827,13 +814,28 @@ if (!match_properties.count(it.first)) log_error("Unknown property '%s' in match rule for bram type %s.\n", it.first.c_str(), log_id(match.name)); - if (match_properties[it.first] <= it.second) - continue; log(" Rule for bram type %s rejected: requirement 'max %s %d' not met.\n", log_id(match.name), it.first.c_str(), it.second); return false; } + if (!match.attr.empty()) { + auto it = cell->attributes.find(match.attr); + if (it == cell->attributes.end()) { + if (!match.value.empty()) + log(" Rule for bram type %s rejected: requirement 'attribute %s=\"%s\"' not met.\n", + log_id(match.name), log_id(match.attr), match.value.decode_string().c_str()); + return false; + } + else { + if (it->second != match.value) { + log(" Rule for bram type %s rejected: requirement 'attribute %s=\"%s\"' not met.\n", + log_id(match.name), log_id(match.attr), match.value.decode_string().c_str()); + return false; + } + } + } + if (mode == 1) return true; } @@ -1018,7 +1020,6 @@ log("Processing %s.%s:\n", log_id(cell->module), log_id(cell)); bool cell_init = !SigSpec(cell->getParam("\\INIT")).is_fully_undef(); - std::string cell_attribute = cell->attributes["\\ram_style"].decode_string(); dict<string, int> match_properties; match_properties["words"] = cell->getParam("\\SIZE").as_int(); @@ -1037,10 +1038,6 @@ pool<pair<IdString, int>> failed_brams; dict<pair<int, int>, tuple<int, int, int>> best_rule_cache; - if (cell_attribute != "") - log(" Found memory attribute '%s' in object %s.\n", cell_attribute.c_str(), - cell->name.c_str()); - for (int i = 0; i < GetSize(rules.matches); i++) { auto &match = rules.matches.at(i); @@ -1108,8 +1105,6 @@ it.first.c_str(), log_id(match.name)); if (match_properties[it.first] >= it.second) continue; - if (check_memory_attribute(cell, match.memattr)) - continue; log(" Rule #%d for bram type %s (variant %d) rejected: requirement 'min %s %d' not met.\n", i+1, log_id(bram.name), bram.variant, it.first.c_str(), it.second); goto next_match_rule; @@ -1128,6 +1123,24 @@ goto next_match_rule; } + if (!match.attr.empty()) { + auto it = cell->attributes.find(match.attr); + if (it == cell->attributes.end()) { + if (!match.value.empty()) { + log(" Rule for bram type %s rejected: requirement 'attribute %s=\"%s\"' not met.\n", + log_id(match.name), log_id(match.attr), match.value.decode_string().c_str()); + goto next_match_rule; + } + } + else { + if (it->second != match.value) { + log(" Rule for bram type %s rejected: requirement 'attribute %s=\"%s\"' not met.\n", + log_id(match.name), log_id(match.attr), match.value.decode_string().c_str()); + goto next_match_rule; + } + } + } + log(" Rule #%d for bram type %s (variant %d) accepted.\n", i+1, log_id(bram.name), bram.variant); if (or_next_if_better || !best_rule_cache.empty())
diff --git a/techlibs/xilinx/xc7_xcu_brams.txt b/techlibs/xilinx/xc7_xcu_brams.txt index da663ce..aa20673 100644 --- a/techlibs/xilinx/xc7_xcu_brams.txt +++ b/techlibs/xilinx/xc7_xcu_brams.txt
@@ -85,6 +85,13 @@ min efficiency 5 shuffle_enable B make_transp + attribute ram_style + or_next_if_better +endmatch + +match $__XILINX_RAMB18_SDP + shuffle_enable B + make_transp attribute ram_style block or_next_if_better endmatch