mirror of https://github.com/YosysHQ/nextpnr.git
Merge d60c52e315 into 7bd1336f88
This commit is contained in:
commit
8acfed10bb
|
|
@ -167,6 +167,7 @@ struct GateMateCCFReader
|
|||
};
|
||||
lineno = 0;
|
||||
count = std::vector<int>(uarch->dies, 0);
|
||||
bool floorplanning = false;
|
||||
while (std::getline(in, line)) {
|
||||
++lineno;
|
||||
// Both // and # are considered start of comment
|
||||
|
|
@ -180,6 +181,103 @@ struct GateMateCCFReader
|
|||
continue;
|
||||
linebuf += line;
|
||||
|
||||
boost::algorithm::to_lower(line);
|
||||
if (line.find("start floorplanning") != std::string::npos) {
|
||||
floorplanning = true;
|
||||
linebuf = "";
|
||||
continue;
|
||||
} else if (line.find("end floorplanning") != std::string::npos) {
|
||||
floorplanning = false;
|
||||
linebuf = "";
|
||||
continue;
|
||||
}
|
||||
if (floorplanning) {
|
||||
// int size = -1;
|
||||
std::string src_location;
|
||||
|
||||
std::string s = linebuf;
|
||||
boost::trim(s);
|
||||
|
||||
// split input into segments by ';'
|
||||
std::vector<std::string> segments;
|
||||
boost::split(segments, s, boost::is_any_of(";"));
|
||||
for (auto &seg : segments)
|
||||
boost::trim(seg);
|
||||
|
||||
if (!segments.empty()) {
|
||||
std::vector<std::string> parts;
|
||||
boost::split(parts, segments[0], boost::is_any_of(":"));
|
||||
for (auto &p : parts)
|
||||
boost::trim(p);
|
||||
|
||||
// index is numeric token
|
||||
// int index = -1;
|
||||
if (!parts.empty() && !parts[0].empty() &&
|
||||
std::all_of(parts[0].begin(), parts[0].end(), ::isdigit)) {
|
||||
// index = std::stoi(parts[0]);
|
||||
parts.erase(parts.begin());
|
||||
}
|
||||
|
||||
// find size
|
||||
// size = -1;
|
||||
for (size_t i = 0; i + 1 < parts.size(); ++i) {
|
||||
if (boost::iequals(parts[i], "size")) {
|
||||
if (!parts[i + 1].empty() &&
|
||||
std::all_of(parts[i + 1].begin(), parts[i + 1].end(), ::isdigit)) {
|
||||
// size = std::stoi(parts[i + 1]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// always the last piece of the main segment
|
||||
if (!parts.empty()) {
|
||||
src_location = parts.back();
|
||||
boost::trim(src_location);
|
||||
}
|
||||
}
|
||||
|
||||
if (segments.size() > 1) {
|
||||
std::string &tmp = segments[1];
|
||||
boost::trim(tmp);
|
||||
|
||||
if (!tmp.empty()) {
|
||||
std::vector<std::string> subparts;
|
||||
boost::split(subparts, tmp, boost::is_any_of(":"));
|
||||
for (auto &p : subparts)
|
||||
boost::trim(p);
|
||||
|
||||
if (!subparts.empty() && boost::iequals(subparts[0], "pb")) {
|
||||
if (subparts.size() == 2) {
|
||||
std::string pb_position = subparts[1];
|
||||
|
||||
std::regex pb_regex(R"(x(\d+)y(\d+)x(\d+)y(\d+))");
|
||||
std::smatch match;
|
||||
if (std::regex_match(pb_position, match, pb_regex)) {
|
||||
int x1 = std::stoi(match[1]);
|
||||
int y1 = std::stoi(match[2]);
|
||||
int x2 = std::stoi(match[3]);
|
||||
int y2 = std::stoi(match[4]);
|
||||
|
||||
IdString scopename(ctx, src_location.c_str());
|
||||
ctx->createRectangularRegion(scopename, x1, y1, x2, y2);
|
||||
uarch->scopenames.emplace(scopename);
|
||||
} else {
|
||||
log_error("Placebox format invalid: %s in line %d\n", pb_position.c_str(), lineno);
|
||||
}
|
||||
} else {
|
||||
log_error("Missing data for pB (in line %d)\n", lineno);
|
||||
}
|
||||
} else {
|
||||
log_error("Unexpected content in last segment (in line %d)\n", lineno);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
linebuf = "";
|
||||
continue;
|
||||
}
|
||||
|
||||
size_t pos = linebuf.find(';');
|
||||
// Need to concatenate lines until there is closing ; sign
|
||||
while (pos != std::string::npos) {
|
||||
|
|
@ -222,6 +320,14 @@ struct GateMateCCFReader
|
|||
parse_params(params, false, &cell->params);
|
||||
} else
|
||||
log_warning("Pad with name '%s' not found in netlist.\n", pin_name.c_str());
|
||||
} else if (type == "start" || type == "end") {
|
||||
std::string word2 = words.at(1);
|
||||
boost::algorithm::to_lower(word2);
|
||||
if (word2 == "floorplanning") {
|
||||
log("Found floor planning\n");
|
||||
} else
|
||||
log_error("unknown command '%s' in line %d.\n", word2.c_str(), lineno);
|
||||
|
||||
} else {
|
||||
log_error("unknown type '%s' in line %d.\n", type.c_str(), lineno);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,6 +109,7 @@ struct GateMateImpl : HimbaechelAPI
|
|||
MultiDieStrategy strategy;
|
||||
dict<int, IdString> index_to_die;
|
||||
dict<IdString, int> die_to_index;
|
||||
pool<IdString> scopenames;
|
||||
|
||||
private:
|
||||
bool getChildPlacement(const BaseClusterInfo *cluster, Loc root_loc,
|
||||
|
|
|
|||
|
|
@ -519,6 +519,17 @@ void GateMatePacker::assign_regions()
|
|||
log_info("Assign cell region based on attributes..\n");
|
||||
for (auto &cell : ctx->cells) {
|
||||
CellInfo &ci = *cell.second;
|
||||
std::string scope = "top";
|
||||
if (ci.attrs.count(ctx->id("scopename"))) {
|
||||
scope = str_or_default(ci.attrs, ctx->id("scopename"), "");
|
||||
scope = "top " + scope;
|
||||
} else if (ci.attrs.count(ctx->id("hdlname"))) {
|
||||
scope = str_or_default(ci.attrs, ctx->id("hdlname"), "");
|
||||
scope = "top " + scope;
|
||||
}
|
||||
IdString name = IdString(ctx, scope.c_str());
|
||||
if (uarch->scopenames.count(name))
|
||||
ctx->constrainCellToRegion(ci.name, name);
|
||||
if (ci.attrs.count(id_GATEMATE_DIE) != 0) {
|
||||
std::string die_name = str_or_default(ci.attrs, id_GATEMATE_DIE, "");
|
||||
IdString die = ctx->id(die_name);
|
||||
|
|
|
|||
Loading…
Reference in New Issue