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