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