aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.cirrus/Dockerfile.ubuntu20.042
-rw-r--r--gowin/CMakeLists.txt2
-rw-r--r--gowin/arch.cc29
-rw-r--r--gowin/gfx.cc8
-rw-r--r--gowin/main.cc17
5 files changed, 34 insertions, 24 deletions
diff --git a/.cirrus/Dockerfile.ubuntu20.04 b/.cirrus/Dockerfile.ubuntu20.04
index 934bbbcb..a4233f3d 100644
--- a/.cirrus/Dockerfile.ubuntu20.04
+++ b/.cirrus/Dockerfile.ubuntu20.04
@@ -65,4 +65,4 @@ RUN set -e -x ;\
PATH=$PATH:$HOME/.cargo/bin cargo install --path prjoxide
RUN set -e -x ;\
- pip3 install apycula==0.2a2
+ pip3 install apycula==0.2a3
diff --git a/gowin/CMakeLists.txt b/gowin/CMakeLists.txt
index 5ec32128..34af9dc6 100644
--- a/gowin/CMakeLists.txt
+++ b/gowin/CMakeLists.txt
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.5)
project(chipdb-gowin NONE)
-set(ALL_GOWIN_DEVICES GW1N-1 GW1N-4 GW1N-9 GW1NS-2 GW1NS-4)
+set(ALL_GOWIN_DEVICES GW1N-1 GW1N-4 GW1N-9 GW1N-9C GW1NS-2 GW1NS-4)
set(GOWIN_DEVICES ${ALL_GOWIN_DEVICES} CACHE STRING
"Include support for these Gowin devices (available: ${ALL_GOWIN_DEVICES})")
message(STATUS "Enabled Gowin devices: ${GOWIN_DEVICES}")
diff --git a/gowin/arch.cc b/gowin/arch.cc
index c55d4a71..07938326 100644
--- a/gowin/arch.cc
+++ b/gowin/arch.cc
@@ -671,10 +671,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;
@@ -718,17 +721,19 @@ 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 {
+ log_error("Pin %s not found (pin# style)\n", pinname.c_str(this));
+ }
}
} break;
case insloc: { // INS_LOC
diff --git a/gowin/gfx.cc b/gowin/gfx.cc
index a851f53a..daae5c71 100644
--- a/gowin/gfx.cc
+++ b/gowin/gfx.cc
@@ -5260,7 +5260,8 @@ void gfxSetWireDefaultDecal(Arch *arch, WireInfo &wire)
snprintf(buf, sizeof(buf), "%s_active", wire.name.c_str(arch));
active_id = arch->id(buf);
active.decal = active_id;
- inactive_id = IdString();
+ snprintf(buf, sizeof(buf), "%s_inactive", wire.name.c_str(arch));
+ inactive_id = arch->id(buf);
inactive.decal = inactive_id;
active.x = inactive.x = 0;
active.y = inactive.y = 0;
@@ -5301,9 +5302,8 @@ void gfxSetWireDefaultDecal(Arch *arch, WireInfo &wire)
snprintf(buf, sizeof(buf), "%s_active", wire.name.c_str(arch));
active_id = arch->id(buf);
active.decal = active_id;
- // snprintf(buf, sizeof(buf), "%s_inactive", wire.name.c_str(arch));
- // inactive_id = arch->id(buf);
- inactive_id = IdString();
+ snprintf(buf, sizeof(buf), "%s_inactive", wire.name.c_str(arch));
+ inactive_id = arch->id(buf);
inactive.decal = inactive_id;
active.x = inactive.x = 0;
active.y = inactive.y = 0;
diff --git a/gowin/main.cc b/gowin/main.cc
index fb9df48d..343d922b 100644
--- a/gowin/main.cc
+++ b/gowin/main.cc
@@ -48,6 +48,7 @@ po::options_description GowinCommandHandler::getArchOptions()
{
po::options_description specific("Architecture specific options");
specific.add_options()("device", po::value<std::string>(), "device name");
+ specific.add_options()("family", po::value<std::string>(), "family name");
specific.add_options()("cst", po::value<std::string>(), "physical constraints file");
return specific;
}
@@ -62,12 +63,16 @@ std::unique_ptr<Context> GowinCommandHandler::createContext(dict<std::string, Pr
}
ArchArgs chipArgs;
chipArgs.gui = vm.count("gui") != 0;
- char buf[36];
- // GW1N and GW1NR variants share the same database.
- // Most Gowin devices are a System in Package with some SDRAM wirebonded to a GPIO bank.
- // However, it appears that the S series with embedded ARM core are unique silicon.
- snprintf(buf, 36, "GW1N%s-%s", match[1].str().c_str(), match[3].str().c_str());
- chipArgs.family = buf;
+ if (vm.count("family")) {
+ chipArgs.family = vm["family"].as<std::string>();
+ } else {
+ char buf[36];
+ // GW1N and GW1NR variants share the same database.
+ // Most Gowin devices are a System in Package with some SDRAM wirebonded to a GPIO bank.
+ // However, it appears that the S series with embedded ARM core are unique silicon.
+ snprintf(buf, 36, "GW1N%s-%s", match[1].str().c_str(), match[3].str().c_str());
+ chipArgs.family = buf;
+ }
chipArgs.partnumber = match[0];
return std::unique_ptr<Context>(new Context(chipArgs));
}