diff options
-rw-r--r-- | .cirrus/Dockerfile.ubuntu20.04 | 2 | ||||
-rw-r--r-- | gowin/CMakeLists.txt | 2 | ||||
-rw-r--r-- | gowin/arch.cc | 29 | ||||
-rw-r--r-- | gowin/gfx.cc | 8 | ||||
-rw-r--r-- | gowin/main.cc | 17 |
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)); } |