Skip to content

Himbaechel Gowin: HCLK Support #1340

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Aug 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions himbaechel/uarch/gowin/constids.inc
Original file line number Diff line number Diff line change
Expand Up @@ -1239,3 +1239,16 @@ X(DQCE_PIP)
X(DCS_USED)
X(SELFORCE)

//HCLK Bels
X(CLKDIV)
X(CLKDIV2)

//HCLK Ports
X(HCLKIN)
X(RESETN)
// X(CALIB)
// X(CLKOUT)

//HCLK Parameters
X(DIV_MODE)
X(GSREN)
58 changes: 54 additions & 4 deletions himbaechel/uarch/gowin/cst.cc
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,27 @@ struct GowinCstReader
return Loc(col - 1, row - 1, z);
}

BelId getConstrainedHCLKBel(std::smatch match, int maxX, int maxY)
{
int idx = std::stoi(match[3]);
int bel_z = BelZ::CLKDIV_0_Z + 2 * idx;

std::string side = match[2].str();
bool lr = (side == "LEFT") || (side == "RIGHT");
int y_coord = (side == "BOTTOM") ? maxY - 1 : 0;
int x_coord = (side == "RIGHT") ? maxX - 1 : 0;

for (auto &bel : ctx->getBelsInBucket(ctx->getBelBucketForCellType(id_CLKDIV))) {
auto this_loc = ctx->getBelLocation(bel);
if (lr && this_loc.x == x_coord && this_loc.z == bel_z && this_loc.y != 0 &&
this_loc.y != maxY - 1) // left or right side
return bel;
else if (!lr && this_loc.y == y_coord && this_loc.z == bel_z) // top or bottom side
return bel;
}
return BelId();
}

bool run(void)
{
pool<std::pair<IdString, IdStringList>> constrained_cells;
Expand All @@ -71,15 +92,19 @@ struct GowinCstReader
std::regex iobelre = std::regex("IO([TRBL])([0-9]+)\\[?([A-Z])\\]?");
std::regex inslocre =
std::regex("INS_LOC +\"([^\"]+)\" +R([0-9]+)C([0-9]+)\\[([0-9])\\]\\[([AB])\\] *;.*[\\s\\S]*");
std::regex hclkre =
std::regex("INS_LOC +\"([^\"]+)\" +(TOP|RIGHT|BOTTOM|LEFT)SIDE\\[([0,1])\\] *;*[\\s\\S]*");
std::regex clockre = std::regex("CLOCK_LOC +\"([^\"]+)\" +BUF([GS])(\\[([0-7])\\])?[^;]*;.*[\\s\\S]*");
std::smatch match, match_attr, match_pinloc;
std::string line, pinline;
std::vector<IdStringList> constrained_clkdivs;
enum
{
ioloc,
ioport,
insloc,
clock
clock,
hclk
} cst_type;

while (!in.eof()) {
Expand All @@ -95,10 +120,14 @@ struct GowinCstReader
if (std::regex_match(line, match, inslocre)) {
cst_type = insloc;
} else {
if ((!line.empty()) && (line.rfind("//", 0) == std::string::npos)) {
log_warning("Invalid constraint: %s\n", line.c_str());
if (std::regex_match(line, match, hclkre)) {
cst_type = hclk;
} else {
if ((!line.empty()) && (line.rfind("//", 0) == std::string::npos)) {
log_warning("Invalid constraint: %s\n", line.c_str());
}
continue;
}
continue;
}
}
}
Expand Down Expand Up @@ -166,6 +195,27 @@ struct GowinCstReader
}
}
} break;
case hclk: {
IdString cell_type = it->second->type;
if (cell_type != id_CLKDIV) {
log_error("Unsupported or invalid cell type %s for hclk\n", cell_type.c_str(ctx));
}
BelId hclk_bel = getConstrainedHCLKBel(match, ctx->getGridDimX(), ctx->getGridDimY());
if (hclk_bel != BelId()) {
auto hclk_bel_name = ctx->getBelName(hclk_bel);
if (std::find(constrained_clkdivs.begin(), constrained_clkdivs.end(), hclk_bel_name) !=
constrained_clkdivs.end()) {
log_error("Only one CLKDIV can be placed at %sSIDE[%s]\n", match[2].str().c_str(),
match[3].str().c_str());
}
constrained_clkdivs.push_back(hclk_bel_name);
it->second->setAttr(id_BEL, ctx->getBelName(hclk_bel).str(ctx));
debug_cell(it->second->name, ctx->getBelName(hclk_bel));
} else {
log_error("No Bel of type CLKDIV found at constrained location %sSIDE[%s]\n",
match[2].str().c_str(), match[3].str().c_str());
}
} break;
default: { // IO_PORT attr=value
std::string attr_val = match[2];
while (std::regex_match(attr_val, match_attr, port_attrre)) {
Expand Down
10 changes: 10 additions & 0 deletions himbaechel/uarch/gowin/globals.cc
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,16 @@ struct GowinGlobalRouter
return true;
}
}
// HCLK outputs
if (driver.cell->type.in(id_CLKDIV, id_CLKDIV2)) {
if (driver.port.in(id_CLKOUT)) {
if (ctx->debug) {
log_info("%s out:%s:%s\n", driver.cell->type.c_str(ctx),
ctx->getBelName(driver.cell->bel).str(ctx).c_str(), driver.port.c_str(ctx));
}
return true;
}
}
return false;
}

Expand Down
Loading