diff options
-rw-r--r-- | ecp5/bitstream.cc | 9 | ||||
-rw-r--r-- | fpga_interchange/globals.cc | 2 | ||||
-rw-r--r-- | gowin/arch.cc | 8 | ||||
-rw-r--r-- | gowin/cells.cc | 2 | ||||
-rw-r--r-- | gowin/constids.inc | 5 | ||||
-rw-r--r-- | gowin/pack.cc | 36 |
6 files changed, 59 insertions, 3 deletions
diff --git a/ecp5/bitstream.cc b/ecp5/bitstream.cc index a23e4cd2..40d843b9 100644 --- a/ecp5/bitstream.cc +++ b/ecp5/bitstream.cc @@ -131,7 +131,7 @@ static void tie_cib_signal(Context *ctx, ChipConfig &cc, WireId wire, bool value inline int chtohex(char c) { static const std::string hex = "0123456789ABCDEF"; - return hex.find(c); + return hex.find(std::toupper(c)); } std::vector<bool> parse_init_str(const Property &p, int length, const char *cellname) @@ -149,6 +149,8 @@ std::vector<bool> parse_init_str(const Property &p, int length, const char *cell for (int i = 0; i < int(str.length()) - 2; i++) { char c = str.at((str.size() - i) - 1); int nibble = chtohex(c); + if (nibble == (int)std::string::npos) + log_error("hex string has invalid char '%c' at position %d.\n", c, i); result.at(i * 4) = nibble & 0x1; if (i * 4 + 1 < length) result.at(i * 4 + 1) = nibble & 0x2; @@ -582,13 +584,16 @@ static std::vector<bool> parse_config_str(const Property &p, int length) if (base == "0b") { for (int i = 0; i < int(str.length()) - 2; i++) { char c = str.at((str.size() - 1) - i); - NPNR_ASSERT(c == '0' || c == '1'); + if (!(c == '0' || c == '1')) + log_error("binary string has invalid char '%c' at position %d.\n", c, i); word.at(i) = (c == '1'); } } else if (base == "0x") { for (int i = 0; i < int(str.length()) - 2; i++) { char c = str.at((str.size() - i) - 1); int nibble = chtohex(c); + if (nibble == (int)std::string::npos) + log_error("hex string has invalid char '%c' at position %d.\n", c, i); word.at(i * 4) = nibble & 0x1; if (i * 4 + 1 < length) word.at(i * 4 + 1) = nibble & 0x2; diff --git a/fpga_interchange/globals.cc b/fpga_interchange/globals.cc index 6efd1d89..eaff30e0 100644 --- a/fpga_interchange/globals.cc +++ b/fpga_interchange/globals.cc @@ -76,7 +76,7 @@ static int route_global_arc(Context *ctx, NetInfo *net, store_index<PortRef> usr while (!visit_queue.empty()) { WireId cursor = visit_queue.front(); visit_queue.pop(); - auto &curr_visit = visits.at(cursor); + auto curr_visit = visits.at(cursor); // We're now at least one layer deeper than a valid visit, any further exploration is futile if (startpoint != WireId() && curr_visit.total_hops > best_visit.total_hops) break; diff --git a/gowin/arch.cc b/gowin/arch.cc index e6ee8267..22874810 100644 --- a/gowin/arch.cc +++ b/gowin/arch.cc @@ -991,6 +991,14 @@ Arch::Arch(ArchArgs args) : args(args) int z = 0; bool dff = true; switch (static_cast<ConstIds>(bel->type_id)) { + case ID_GSR0: + snprintf(buf, 32, "R%dC%d_GSR0", row + 1, col + 1); + belname = id(buf); + addBel(belname, id_GSR, Loc(col, row, 0), false); + portname = IdString(pairLookup(bel->ports.get(), bel->num_ports, ID_GSRI)->src_id); + snprintf(buf, 32, "R%dC%d_%s", row + 1, col + 1, portname.c_str(this)); + addBelInput(belname, id_GSRI, id(buf)); + break; // fall through the ++ case ID_LUT7: z++; diff --git a/gowin/cells.cc b/gowin/cells.cc index d862458c..8e450b51 100644 --- a/gowin/cells.cc +++ b/gowin/cells.cc @@ -63,6 +63,8 @@ std::unique_ptr<CellInfo> create_generic_cell(Context *ctx, IdString type, std:: new_cell->addInput(id_I); new_cell->addInput(id_OEN); new_cell->addOutput(id_O); + } else if (type == id_GSR) { + new_cell->addInput(id_GSRI); } else { log_error("unable to create generic cell of type %s\n", type.c_str(ctx)); } diff --git a/gowin/constids.inc b/gowin/constids.inc index 3e72340a..d32a987d 100644 --- a/gowin/constids.inc +++ b/gowin/constids.inc @@ -739,6 +739,11 @@ X(IOBUF) X(TBUF) X(TLVDS_OBUF) +// global set/reset +X(GSR) +X(GSR0) +X(GSRI) + // primitive attributes X(INIT) X(FF_USED) diff --git a/gowin/pack.cc b/gowin/pack.cc index c17a20c7..24daee31 100644 --- a/gowin/pack.cc +++ b/gowin/pack.cc @@ -660,6 +660,41 @@ static void pack_constants(Context *ctx) } } +// Pack global set-reset +static void pack_gsr(Context *ctx) +{ + log_info("Packing GSR..\n"); + + bool user_gsr = false; + for (auto &cell : ctx->cells) { + CellInfo *ci = cell.second.get(); + if (ctx->verbose) + log_info("cell '%s' is of type '%s'\n", ctx->nameOf(ci), ci->type.c_str(ctx)); + if (ci->type == id_GSR) { + user_gsr = true; + break; + } + } + if (!user_gsr) { + // XXX + bool have_gsr_bel = false; + for (auto bi : ctx->bels) { + if (bi.second.type == id_GSR) { + have_gsr_bel = true; + break; + } + } + if (have_gsr_bel) { + // make default GSR + std::unique_ptr<CellInfo> gsr_cell = create_generic_cell(ctx, id_GSR, "GSR"); + gsr_cell->connectPort(id_GSRI, ctx->nets[ctx->id("$PACKER_VCC_NET")].get()); + ctx->cells[gsr_cell->name] = std::move(gsr_cell); + } else { + log_info("No GSR in the chip base\n"); + } + } +} + static bool is_nextpnr_iob(const Context *ctx, CellInfo *cell) { return cell->type == ctx->id("$nextpnr_ibuf") || cell->type == ctx->id("$nextpnr_obuf") || @@ -857,6 +892,7 @@ bool Arch::pack() try { log_break(); pack_constants(ctx); + pack_gsr(ctx); pack_io(ctx); pack_diff_io(ctx); pack_wideluts(ctx); |