gowin: Add the IO[TRBL]style placement recognition
Specifying pin placement with this notation (e.g. IOR4B) allows to use the same constraint file without changes for different packages and even different families. The vendor router also understands this notation. Signed-off-by: YRabbit <rabbit@yrabbit.cyou>
This commit is contained in:
parent
897a2fccb6
commit
e4196f32d3
@ -482,14 +482,34 @@ DelayQuad Arch::getWireTypeDelay(IdString wire)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Loc getLoc(std::smatch match, int maxX, int maxY)
|
||||||
|
{
|
||||||
|
int col = std::stoi(match[2]);
|
||||||
|
int row = 1; // Top
|
||||||
|
std::string side = match[1].str();
|
||||||
|
if (side == "R") {
|
||||||
|
row = col;
|
||||||
|
col = maxX;
|
||||||
|
} else if (side == "B") {
|
||||||
|
row = maxY;
|
||||||
|
} else if (side == "L") {
|
||||||
|
row = col;
|
||||||
|
col = 1;
|
||||||
|
}
|
||||||
|
int z = match[3].str()[0] - 'A';
|
||||||
|
return Loc(col - 1, row - 1, z);
|
||||||
|
}
|
||||||
|
|
||||||
void Arch::read_cst(std::istream &in)
|
void Arch::read_cst(std::istream &in)
|
||||||
{
|
{
|
||||||
std::regex iobre = std::regex("IO_LOC +\"([^\"]+)\" +([^ ;]+) *;.*");
|
std::regex iobre = std::regex("IO_LOC +\"([^\"]+)\" +([^ ;]+) *;.*");
|
||||||
std::regex portre = std::regex("IO_PORT +\"([^\"]+)\" +([^;]+;).*");
|
std::regex portre = std::regex("IO_PORT +\"([^\"]+)\" +([^;]+;).*");
|
||||||
std::regex port_attrre = std::regex("([^ =;]+=[^ =;]+) *([^;]*;)");
|
std::regex port_attrre = std::regex("([^ =;]+=[^ =;]+) *([^;]*;)");
|
||||||
std::smatch match, match_attr;
|
std::regex iobelre = std::regex("IO([TRBL])([0-9]+)([A-Z])");
|
||||||
std::string line;
|
std::smatch match, match_attr, match_pinloc;
|
||||||
|
std::string line, pinline;
|
||||||
bool io_loc;
|
bool io_loc;
|
||||||
|
|
||||||
while (!in.eof()) {
|
while (!in.eof()) {
|
||||||
std::getline(in, line);
|
std::getline(in, line);
|
||||||
io_loc = true;
|
io_loc = true;
|
||||||
@ -512,11 +532,23 @@ void Arch::read_cst(std::istream &in)
|
|||||||
}
|
}
|
||||||
if (io_loc) { // IO_LOC name pin
|
if (io_loc) { // IO_LOC name pin
|
||||||
IdString pinname = id(match[2]);
|
IdString pinname = id(match[2]);
|
||||||
|
pinline = match[2];
|
||||||
const PairPOD *belname = pairLookup(package->pins.get(), package->num_pins, pinname.index);
|
const PairPOD *belname = pairLookup(package->pins.get(), package->num_pins, pinname.index);
|
||||||
if (belname == nullptr)
|
if (belname != nullptr) {
|
||||||
|
std::string bel = IdString(belname->src_id).str(this);
|
||||||
|
it->second->attrs[IdString(ID_BEL)] = bel;
|
||||||
|
} else if (std::regex_match(pinline, match_pinloc, iobelre)) {
|
||||||
|
// may be it's IOx#[AB] style?
|
||||||
|
Loc loc = getLoc(match_pinloc, getGridDimX(), getGridDimY());
|
||||||
|
BelId bel = getBelByLocation(loc);
|
||||||
|
if (bel == BelId()) {
|
||||||
|
log_error("Pin %s not found\n", pinline.c_str());
|
||||||
|
}
|
||||||
|
std::string belname = getCtx()->nameOfBel(bel);
|
||||||
|
it->second->attrs[IdString(ID_BEL)] = belname;
|
||||||
|
} else {
|
||||||
log_error("Pin %s not found\n", pinname.c_str(this));
|
log_error("Pin %s not found\n", pinname.c_str(this));
|
||||||
std::string bel = IdString(belname->src_id).str(this);
|
}
|
||||||
it->second->attrs[IdString(ID_BEL)] = bel;
|
|
||||||
} else { // IO_PORT attr=value
|
} else { // IO_PORT attr=value
|
||||||
std::string attr_val = match[2];
|
std::string attr_val = match[2];
|
||||||
while (std::regex_match(attr_val, match_attr, port_attrre)) {
|
while (std::regex_match(attr_val, match_attr, port_attrre)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user