diff options
Diffstat (limited to 'passes/memory/memory_bram.cc')
-rw-r--r-- | passes/memory/memory_bram.cc | 112 |
1 files changed, 70 insertions, 42 deletions
diff --git a/passes/memory/memory_bram.cc b/passes/memory/memory_bram.cc index 24478f2ee..0898ec288 100644 --- a/passes/memory/memory_bram.cc +++ b/passes/memory/memory_bram.cc @@ -105,11 +105,11 @@ struct rules_t log_error("Bram %s variants %d and %d have different values for 'groups'.\n", log_id(name), variant, other.variant); if (abits != other.abits) - variant_params["\\CFG_ABITS"] = abits; + variant_params[ID::CFG_ABITS] = abits; if (dbits != other.dbits) - variant_params["\\CFG_DBITS"] = dbits; + variant_params[ID::CFG_DBITS] = dbits; if (init != other.init) - variant_params["\\CFG_INIT"] = init; + variant_params[ID::CFG_INIT] = init; for (int i = 0; i < groups; i++) { @@ -137,9 +137,26 @@ struct rules_t vector<vector<std::tuple<bool,IdString,Const>>> attributes; }; + bool attr_icase; dict<IdString, vector<bram_t>> brams; vector<match_t> matches; + std::string map_case(std::string value) const + { + if (attr_icase) { + for (char &c : value) + c = tolower(c); + } + return value; + } + + RTLIL::Const map_case(RTLIL::Const value) const + { + if (value.flags & RTLIL::CONST_FLAG_STRING) + return map_case(value.decode_string()); + return value; + } + std::ifstream infile; vector<string> tokens; vector<string> labels; @@ -337,7 +354,7 @@ struct rules_t IdString key = RTLIL::escape_id(tokens[idx].substr(c1, c2)); Const val = c2 != std::string::npos ? tokens[idx].substr(c2+1) : RTLIL::Const(1); - data.attributes.back().emplace_back(exists, key, val); + data.attributes.back().emplace_back(exists, key, map_case(val)); } continue; } @@ -351,6 +368,7 @@ struct rules_t rewrite_filename(filename); infile.open(filename); linecount = 0; + attr_icase = false; if (infile.fail()) log_error("Can't open rules file `%s'.\n", filename.c_str()); @@ -360,6 +378,11 @@ struct rules_t if (!labels.empty()) syntax_error(); + if (GetSize(tokens) == 2 && tokens[0] == "attr_icase") { + attr_icase = atoi(tokens[1].c_str()); + continue; + } + if (tokens[0] == "bram") { parse_bram(); continue; @@ -414,44 +437,44 @@ bool replace_cell(Cell *cell, const rules_t &rules, const rules_t::bram_t &bram, log(" Mapping to bram type %s (variant %d):\n", log_id(bram.name), bram.variant); // bram.dump_config(); - int mem_size = cell->getParam("\\SIZE").as_int(); - int mem_abits = cell->getParam("\\ABITS").as_int(); - int mem_width = cell->getParam("\\WIDTH").as_int(); - // int mem_offset = cell->getParam("\\OFFSET").as_int(); + int mem_size = cell->getParam(ID::SIZE).as_int(); + int mem_abits = cell->getParam(ID::ABITS).as_int(); + int mem_width = cell->getParam(ID::WIDTH).as_int(); + // int mem_offset = cell->getParam(ID::OFFSET).as_int(); - bool cell_init = !SigSpec(cell->getParam("\\INIT")).is_fully_undef(); + bool cell_init = !SigSpec(cell->getParam(ID::INIT)).is_fully_undef(); vector<Const> initdata; if (cell_init) { - Const initparam = cell->getParam("\\INIT"); + Const initparam = cell->getParam(ID::INIT); initdata.reserve(mem_size); for (int i=0; i < mem_size; i++) initdata.push_back(initparam.extract(mem_width*i, mem_width, State::Sx)); } - int wr_ports = cell->getParam("\\WR_PORTS").as_int(); - auto wr_clken = SigSpec(cell->getParam("\\WR_CLK_ENABLE")); - auto wr_clkpol = SigSpec(cell->getParam("\\WR_CLK_POLARITY")); + int wr_ports = cell->getParam(ID::WR_PORTS).as_int(); + auto wr_clken = SigSpec(cell->getParam(ID::WR_CLK_ENABLE)); + auto wr_clkpol = SigSpec(cell->getParam(ID::WR_CLK_POLARITY)); wr_clken.extend_u0(wr_ports); wr_clkpol.extend_u0(wr_ports); - SigSpec wr_en = cell->getPort("\\WR_EN"); - SigSpec wr_clk = cell->getPort("\\WR_CLK"); - SigSpec wr_data = cell->getPort("\\WR_DATA"); - SigSpec wr_addr = cell->getPort("\\WR_ADDR"); + SigSpec wr_en = cell->getPort(ID::WR_EN); + SigSpec wr_clk = cell->getPort(ID::WR_CLK); + SigSpec wr_data = cell->getPort(ID::WR_DATA); + SigSpec wr_addr = cell->getPort(ID::WR_ADDR); - int rd_ports = cell->getParam("\\RD_PORTS").as_int(); - auto rd_clken = SigSpec(cell->getParam("\\RD_CLK_ENABLE")); - auto rd_clkpol = SigSpec(cell->getParam("\\RD_CLK_POLARITY")); - auto rd_transp = SigSpec(cell->getParam("\\RD_TRANSPARENT")); + int rd_ports = cell->getParam(ID::RD_PORTS).as_int(); + auto rd_clken = SigSpec(cell->getParam(ID::RD_CLK_ENABLE)); + auto rd_clkpol = SigSpec(cell->getParam(ID::RD_CLK_POLARITY)); + auto rd_transp = SigSpec(cell->getParam(ID::RD_TRANSPARENT)); rd_clken.extend_u0(rd_ports); rd_clkpol.extend_u0(rd_ports); rd_transp.extend_u0(rd_ports); - SigSpec rd_en = cell->getPort("\\RD_EN"); - SigSpec rd_clk = cell->getPort("\\RD_CLK"); - SigSpec rd_data = cell->getPort("\\RD_DATA"); - SigSpec rd_addr = cell->getPort("\\RD_ADDR"); + SigSpec rd_en = cell->getPort(ID::RD_EN); + SigSpec rd_clk = cell->getPort(ID::RD_CLK); + SigSpec rd_data = cell->getPort(ID::RD_DATA); + SigSpec rd_addr = cell->getPort(ID::RD_ADDR); if (match.shuffle_enable && bram.dbits >= portinfos.at(match.shuffle_enable - 'A').enable*2 && portinfos.at(match.shuffle_enable - 'A').enable > 0 && wr_ports > 0) { @@ -843,7 +866,7 @@ grow_read_ports:; } else if (!exists) continue; - if (it->second != value) + if (rules.map_case(it->second) != value) continue; found = true; break; @@ -855,7 +878,7 @@ grow_read_ports:; ss << "!"; IdString key = std::get<1>(sums.front()); ss << log_id(key); - const Const &value = std::get<2>(sums.front()); + const Const &value = rules.map_case(std::get<2>(sums.front())); if (exists && value != Const(1)) ss << "=\"" << value.decode_string() << "\""; @@ -915,7 +938,7 @@ grow_read_ports:; else initparam[i*bram.dbits+j] = padding; } - c->setParam("\\INIT", initparam); + c->setParam(ID::INIT, initparam); } for (auto &pi : portinfos) @@ -1048,14 +1071,14 @@ 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(); + bool cell_init = !SigSpec(cell->getParam(ID::INIT)).is_fully_undef(); dict<string, int> match_properties; - match_properties["words"] = cell->getParam("\\SIZE").as_int(); - match_properties["abits"] = cell->getParam("\\ABITS").as_int(); - match_properties["dbits"] = cell->getParam("\\WIDTH").as_int(); - match_properties["wports"] = cell->getParam("\\WR_PORTS").as_int(); - match_properties["rports"] = cell->getParam("\\RD_PORTS").as_int(); + match_properties["words"] = cell->getParam(ID::SIZE).as_int(); + match_properties["abits"] = cell->getParam(ID::ABITS).as_int(); + match_properties["dbits"] = cell->getParam(ID::WIDTH).as_int(); + match_properties["wports"] = cell->getParam(ID::WR_PORTS).as_int(); + match_properties["rports"] = cell->getParam(ID::RD_PORTS).as_int(); match_properties["bits"] = match_properties["words"] * match_properties["dbits"]; match_properties["ports"] = match_properties["wports"] + match_properties["rports"]; @@ -1079,9 +1102,6 @@ void handle_cell(Cell *cell, const rules_t &rules) auto &bram = rules.brams.at(match.name).at(vi); bool or_next_if_better = match.or_next_if_better || vi+1 < GetSize(rules.brams.at(match.name)); - if (failed_brams.count(pair<IdString, int>(bram.name, bram.variant))) - continue; - int avail_rd_ports = 0; int avail_wr_ports = 0; for (int j = 0; j < bram.groups; j++) { @@ -1117,6 +1137,9 @@ void handle_cell(Cell *cell, const rules_t &rules) int efficiency = (100 * match_properties["bits"]) / (dups * cells * bram.dbits * (1 << bram.abits)); match_properties["efficiency"] = efficiency; + if (failed_brams.count(pair<IdString, int>(bram.name, bram.variant))) + goto next_match_rule; + log(" Metrics for %s: awaste=%d dwaste=%d bwaste=%d waste=%d efficiency=%d\n", log_id(match.name), awaste, dwaste, bwaste, waste, efficiency); @@ -1167,7 +1190,7 @@ void handle_cell(Cell *cell, const rules_t &rules) } else if (!exists) continue; - if (it->second != value) + if (rules.map_case(it->second) != value) continue; found = true; break; @@ -1179,7 +1202,7 @@ void handle_cell(Cell *cell, const rules_t &rules) ss << "!"; IdString key = std::get<1>(sums.front()); ss << log_id(key); - const Const &value = std::get<2>(sums.front()); + const Const &value = rules.map_case(std::get<2>(sums.front())); if (exists && value != Const(1)) ss << "=\"" << value.decode_string() << "\""; @@ -1252,8 +1275,13 @@ struct MemoryBramPass : public Pass { log("The given rules file describes the available resources and how they should be\n"); log("used.\n"); log("\n"); - log("The rules file contains a set of block ram description and a sequence of match\n"); - log("rules. A block ram description looks like this:\n"); + log("The rules file contains configuration options, a set of block ram description\n"); + log("and a sequence of match rules.\n"); + log("\n"); + log("The option 'attr_icase' configures how attribute values are matched. The value 0\n"); + log("means case-sensitive, 1 means case-insensitive.\n"); + log("\n"); + log("A block ram description looks like this:\n"); log("\n"); log(" bram RAMB1024X32 # name of BRAM cell\n"); log(" init 1 # set to '1' if BRAM can be initialized\n"); @@ -1357,7 +1385,7 @@ struct MemoryBramPass : public Pass { for (auto mod : design->selected_modules()) for (auto cell : mod->selected_cells()) - if (cell->type == "$mem") + if (cell->type == ID($mem)) handle_cell(cell, rules); } } MemoryBramPass; |