diff options
author | Diego H <diego@symbioticeda.com> | 2019-12-13 15:43:24 -0600 |
---|---|---|
committer | Diego H <diego@symbioticeda.com> | 2019-12-13 15:43:24 -0600 |
commit | 266993408a2b926ffefcf536feb92b36b11e398e (patch) | |
tree | 1618b4ed1ed4237015b5b14ea4f0f7843e67d50f /passes/memory | |
parent | 52875b0d61b2b1cc83a9e9d51964a92027c3758c (diff) | |
download | yosys-266993408a2b926ffefcf536feb92b36b11e398e.tar.gz yosys-266993408a2b926ffefcf536feb92b36b11e398e.tar.bz2 yosys-266993408a2b926ffefcf536feb92b36b11e398e.zip |
Refactoring memory attribute matching based on IEEE 1364.1 and Tool specific
Diffstat (limited to 'passes/memory')
-rw-r--r-- | passes/memory/memory_bram.cc | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/passes/memory/memory_bram.cc b/passes/memory/memory_bram.cc index aa8f94149..35cd0647a 100644 --- a/passes/memory/memory_bram.cc +++ b/passes/memory/memory_bram.cc @@ -327,6 +327,20 @@ struct rules_t continue; } + if (GetSize(tokens) >= 2 && tokens[0] == "attribute") { + for (int idx=1; idx<= GetSize(tokens)-1; idx++) { + size_t val = tokens[idx].find_first_of("!="); + if (val != std::string::npos) { + if (val == 0) { + data.attr_unmatch[RTLIL::escape_id(tokens[idx].substr(val+1))]; + } + else { + data.attr_match[RTLIL::escape_id(tokens[idx].substr(0, val))] = tokens[idx].substr(val+1); + } + } + } + continue; + } syntax_error(); } } @@ -813,6 +827,27 @@ grow_read_ports:; return false; } + if (!match.attr_match.empty()) { + for (auto iter: match.attr_match) { + auto it = cell->attributes.find(iter.first); + + if (iter.second.empty()) { + log(" Rule for bram type %s is rejected: requirement 'attribute %s=\"%s\"' not met.\n", + log_id(match.name), iter.first.c_str(), iter.second.decode_string().c_str()); + return false; + } + + if (it != cell->attributes.end()) { + if (it->second == iter.second) + continue; + log(" Rule for bram type %s is rejected: requirement 'attribute %s=\"%s\"' not met.\n", + log_id(match.name), iter.first.c_str(), iter.second.decode_string().c_str()); + return false; + } + continue; + } + } + if (mode == 1) return true; } @@ -997,6 +1032,7 @@ void handle_cell(Cell *cell, const rules_t &rules) log("Processing %s.%s:\n", log_id(cell->module), log_id(cell)); bool cell_init = !SigSpec(cell->getParam("\\INIT")).is_fully_undef(); + int access = 0; dict<string, int> match_properties; match_properties["words"] = cell->getParam("\\SIZE").as_int(); @@ -1100,6 +1136,42 @@ void handle_cell(Cell *cell, const rules_t &rules) goto next_match_rule; } + for (auto iter: match.attr_unmatch) { + auto it = cell->attributes.find(iter.first); + + if (it != cell->attributes.end()) { + log(" Rule for bram type %s is rejected: requirement 'attribute %s' is met.\n", + log_id(match.name), iter.first.c_str()); + goto next_match_rule; + } + continue; + } + + if (!match.attr_match.empty()) { + for (auto iter: match.attr_match) { + int len=std::tuple_size<decltype(iter)>::value; + auto it = cell->attributes.find(iter.first); + + if (iter.second.empty()) { + log(" Rule for bram type %s is rejected: requirement 'attribute %s=\"%s\"' not met.\n", + log_id(match.name), iter.first.c_str(), iter.second.decode_string().c_str()); + continue; + } + + if (it != cell->attributes.end()) { + if (it->second == iter.second) + continue; + log(" Rule for bram type %s is rejected: requirement 'attribute %s=\"%s\"' not met.\n", + log_id(match.name), iter.first.c_str(), iter.second.decode_string().c_str()); + } + access ++; + if (access == len) { + access = 0; + 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()) @@ -1225,6 +1297,11 @@ struct MemoryBramPass : public Pass { log(" dcells ....... number of cells in 'data-direction'\n"); log(" cells ........ total number of cells (acells*dcells*dups)\n"); log("\n"); + log("A match containing the condition 'attribute' followed by a name and optional\n"); + log("value requires that the memory contains the given attribute name and value\n"); + log("(if specified) or that the attribute is not present (prepending a '!')\n"); + log("or the value is empty (if value is not specified\n)."); + log("\n"); log("The interface for the created bram instances is derived from the bram\n"); log("description. Use 'techmap' to convert the created bram instances into\n"); log("instances of the actual bram cells of your target architecture.\n"); |