aboutsummaryrefslogtreecommitdiffstats
path: root/gowin/arch.cc
diff options
context:
space:
mode:
authorYRabbit <rabbit@yrabbit.cyou>2022-02-03 11:26:45 +1000
committerYRabbit <rabbit@yrabbit.cyou>2022-02-03 11:26:45 +1000
commit604260a0d7344627cea82198512384319c705105 (patch)
treec96c298183f5c8e83f7b4a15bdb77fbd7b795d2a /gowin/arch.cc
parent6fceac95c02b16a208dd17123dba46bc3618c1fb (diff)
downloadnextpnr-604260a0d7344627cea82198512384319c705105.tar.gz
nextpnr-604260a0d7344627cea82198512384319c705105.tar.bz2
nextpnr-604260a0d7344627cea82198512384319c705105.zip
gowin: Add a DS location recognition
For differential signals it is necessary to set the position of two pins at once: P and N. This commit adds that capability and also adds another style of location setting --- with the pin letter in square brackets used in vendor tools. Signed-off-by: YRabbit <rabbit@yrabbit.cyou>
Diffstat (limited to 'gowin/arch.cc')
-rw-r--r--gowin/arch.cc30
1 files changed, 18 insertions, 12 deletions
diff --git a/gowin/arch.cc b/gowin/arch.cc
index 8c654b2e..1c401a43 100644
--- a/gowin/arch.cc
+++ b/gowin/arch.cc
@@ -505,10 +505,13 @@ static Loc getLoc(std::smatch match, int maxX, int maxY)
void Arch::read_cst(std::istream &in)
{
- std::regex iobre = std::regex("IO_LOC +\"([^\"]+)\" +([^ ;]+) *;.*");
+ // If two locations are specified separated by commas (for differential I/O buffers),
+ // only the first location is actually recognized and used.
+ // And pin A will be Positive and pin B will be Negative in any case.
+ std::regex iobre = std::regex("IO_LOC +\"([^\"]+)\" +([^ ,;]+)(, *[^ ;]+)? *;.*");
std::regex portre = std::regex("IO_PORT +\"([^\"]+)\" +([^;]+;).*");
std::regex port_attrre = std::regex("([^ =;]+=[^ =;]+) *([^;]*;)");
- std::regex iobelre = std::regex("IO([TRBL])([0-9]+)([A-Z])");
+ 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])\\] *;.*");
std::smatch match, match_attr, match_pinloc;
std::string line, pinline;
@@ -551,17 +554,20 @@ void Arch::read_cst(std::istream &in)
if (belname != nullptr) {
std::string bel = IdString(belname->src_id).str(this);
it->second->setAttr(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->setAttr(IdString(ID_BEL), belname);
} else {
- log_error("Pin %s not found\n", pinname.c_str(this));
+ 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 (TRBL style). \n", pinline.c_str());
+ }
+ std::string belname = getCtx()->nameOfBel(bel);
+ it->second->setAttr(IdString(ID_BEL), belname);
+ } else {
+ std::cout << "plain error:[" << pinline << "]" << std::endl;
+ log_error("Pin %s not found (pin# style)\n", pinname.c_str(this));
+ }
}
} break;
case insloc: { // INS_LOC