Merge branch 'diego/memattr' of https://github.com/dh73/Yosys into diego/memattr
diff --git a/passes/memory/memory_bram.cc b/passes/memory/memory_bram.cc
index aa8f941..2d2897e 100644
--- a/passes/memory/memory_bram.cc
+++ b/passes/memory/memory_bram.cc
@@ -134,6 +134,7 @@
dict<string, int> min_limits, max_limits;
bool or_next_if_better, make_transp, make_outreg;
char shuffle_enable;
+ std::string memattr;
};
dict<IdString, vector<bram_t>> brams;
@@ -327,6 +328,11 @@
continue;
}
+ if (GetSize(tokens) == 3 && tokens[0] == "attribute") {
+ data.memattr = tokens[2].c_str();
+ continue;
+ }
+
syntax_error();
}
}
@@ -362,6 +368,20 @@
}
};
+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;
@@ -788,7 +808,6 @@
match_properties["dcells"] = ((mem_width + bram.dbits - 1) / bram.dbits);
match_properties["acells"] = ((mem_size + (1 << bram.abits) - 1) / (1 << bram.abits));
match_properties["cells"] = match_properties["dcells"] * match_properties["acells"] * match_properties["dups"];
-
log(" Updated properties: dups=%d waste=%d efficiency=%d\n",
match_properties["dups"], match_properties["waste"], match_properties["efficiency"]);
@@ -798,6 +817,8 @@
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;
@@ -997,6 +1018,7 @@
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();
@@ -1015,6 +1037,10 @@
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);
@@ -1082,6 +1108,8 @@
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;
@@ -1242,6 +1270,9 @@
log("A match containing the command 'shuffle_enable A' will re-organize\n");
log("the data bits to accommodate the enable pattern of port A.\n");
log("\n");
+ log("A match containing the command 'attribute' will bypass min bits/efficiency\n");
+ log("to select the type of memory.\n");
+ log("\n");
}
void execute(vector<string> args, Design *design) YS_OVERRIDE
{
diff --git a/techlibs/xilinx/xc7_xcu_brams.txt b/techlibs/xilinx/xc7_xcu_brams.txt
index f116111..da663ce 100644
--- a/techlibs/xilinx/xc7_xcu_brams.txt
+++ b/techlibs/xilinx/xc7_xcu_brams.txt
@@ -85,6 +85,7 @@
min efficiency 5
shuffle_enable B
make_transp
+ attribute ram_style block
or_next_if_better
endmatch