gatemate: improve --help and error messages (#1639)

* gatemate: improve mode arg error message

* gatemate: fix initial capitals and periods in log_*() messages

* gatemate: replace operation -> performance for mode in help and log_*()

This is the term used both in the datasheet and the primitive library PDF.
This commit is contained in:
mrcmry 2026-02-25 09:39:05 +01:00 committed by GitHub
parent a60fdbb9a2
commit 0c970d6891
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 67 additions and 64 deletions

View File

@ -245,10 +245,10 @@ struct BitstreamBackend
NPNR_ASSERT(!(all_correct && all_inverted) && "net doesn't drive any ports?");
if (!all_correct && !all_inverted) {
log_warning("multiplier net '%s' has inconsistent inversion\n", net->name.c_str(ctx));
log_warning("Multiplier net '%s' has inconsistent inversion.\n", net->name.c_str(ctx));
auto driver_loc = ctx->getBelLocation(net->driver.cell->bel);
log_warning("net is driven from (%d, %d)\n", driver_loc.x, driver_loc.y);
log_warning("Net is driven from (%d, %d)\n", driver_loc.x, driver_loc.y);
log_warning(" these ports are not inverted:\n");
for (PortRef user : net->users) {
@ -274,7 +274,7 @@ struct BitstreamBackend
} else if (all_inverted) {
params[id_INIT_L10] = Property(~driver_l10 & 0b1111, 4);
if (ctx->debug)
log_info("multiplier net '%s': fixed inversion\n", net->name.c_str(ctx));
log_info("Multiplier net '%s': fixed inversion.\n", net->name.c_str(ctx));
}
}
@ -481,7 +481,7 @@ struct BitstreamBackend
case id_CFG_CTRL.index:
break;
default:
log_error("Unhandled cell %s of type %s\n", cell.second.get()->name.c_str(ctx),
log_error("Unhandled cell %s of type %s.\n", cell.second.get()->name.c_str(ctx),
cell.second->type.c_str(ctx));
}
}
@ -521,7 +521,7 @@ void GateMateImpl::write_bitstream(const std::string &device, const std::string
{
std::ofstream out(filename);
if (!out)
log_error("failed to open file %s for writing (%s)\n", filename.c_str(), strerror(errno));
log_error("Failed to open file '%s' for writing (%s).\n", filename.c_str(), strerror(errno));
BitstreamBackend be(ctx, this, device, out);
be.write_bitstream();

View File

@ -51,7 +51,7 @@ struct GateMateCCFReader
{
if (str.at(0) == '"') {
if (str.back() != '"') {
log_error("expected '\"' at end of string '%s' (on line %d).\n", str.c_str(), lineno);
log_error("Expected '\"' at end of string '%s' (on line %d).\n", str.c_str(), lineno);
}
return str.substr(1, str.size() - 2);
} else {
@ -70,8 +70,8 @@ struct GateMateCCFReader
if (expr.size() != 2) {
if (name == "LOC" || name == "DRIVE" || name == "DELAY_IBF" || name == "DELAY_OBF" || name == "DIE")
log_error("Parameter must be in form NAME=VALUE (on line %d)\n", lineno);
log_warning("Parameter '%s' missing value, defaulting to '1' (on line %d)\n", name.c_str(), lineno);
log_error("Parameter must be in form NAME=VALUE (on line %d).\n", lineno);
log_warning("Parameter '%s' missing value, defaulting to '1' (on line %d).\n", name.c_str(), lineno);
expr.push_back("1");
}
@ -199,13 +199,13 @@ struct GateMateCCFReader
boost::algorithm::to_lower(type);
if (type == "default_gpio") {
if (words.size() != 1)
log_error("line with default_GPIO should not contain only parameters (in line %d).\n", lineno);
log_error("Line with default_GPIO should not contain only parameters (in line %d).\n", lineno);
params.erase(params.begin());
parse_params(params, true, &defaults);
} else if (type == "net" || type == "pin_in" || type == "pin_out" || type == "pin_inout") {
if (words.size() < 3 || words.size() > 5)
log_error("pin definition line not properly formed (in line %d).\n", lineno);
log_error("Pin definition line not properly formed (in line %d).\n", lineno);
std::string pin_name = strip_quotes(words.at(1));
// put back other words and use them as parameters
@ -223,7 +223,7 @@ struct GateMateCCFReader
} else
log_warning("Pad with name '%s' not found in netlist.\n", pin_name.c_str());
} else {
log_error("unknown type '%s' in line %d.\n", type.c_str(), lineno);
log_error("Unknown type '%s' in line %d.\n", type.c_str(), lineno);
}
linebuf = linebuf.substr(pos + 1);
@ -231,7 +231,7 @@ struct GateMateCCFReader
}
}
if (!isempty(linebuf))
log_error("unexpected end of CCF file\n");
log_error("Unexpected end of CCF file.\n");
int max_num = 0;
uarch->preferred_die = 0;
for (int i = 0; i < uarch->dies; i++) {
@ -247,7 +247,7 @@ void GateMateImpl::parse_ccf(const std::string &filename)
{
std::ifstream in(filename);
if (!in)
log_error("failed to open CCF file '%s'\n", filename.c_str());
log_error("Failed to open CCF file '%s'.\n", filename.c_str());
GateMateCCFReader reader(ctx, this, in);
reader.run();
}

View File

@ -143,7 +143,7 @@ CellInfo *GateMatePacker::create_cell_ptr(IdString type, IdString name)
add_port(id_USR_PLL_LOCKED_STDY, PORT_OUT);
add_port(id_USR_LOCKED_STDY_RST, PORT_IN);
} else {
log_error("Trying to create unknown cell type %s\n", type.c_str(ctx));
log_error("Trying to create unknown cell type %s.\n", type.c_str(ctx));
}
return cell;
}

View File

@ -58,7 +58,7 @@ void TileConfig::add_word(const std::string &name, const std::vector<bool> &valu
} else {
auto val = added.at(name);
if (val != value)
log_error("Trying to add value to already assigned word %s for %s\n", name.c_str(), c ? c : "");
log_error("Trying to add value to already assigned word %s for %s.\n", name.c_str(), c ? c : "");
}
}

View File

@ -326,7 +326,7 @@ TimingPortClass GateMateImpl::getPortTimingClass(const CellInfo *cell, IdString
}
NPNR_ASSERT_FALSE_STR("no timing type for RAM port '" + port.str(ctx) + "'");
} else {
log_error("cell type '%s' is unsupported (instantiated as '%s')\n", cell->type.c_str(ctx),
log_error("Cell type '%s' is unsupported (instantiated as '%s').\n", cell->type.c_str(ctx),
cell->name.c_str(ctx));
}
}
@ -516,7 +516,7 @@ TimingClockingInfo GateMateImpl::getPortClockingInfo(const CellInfo *cell, IdStr
break;
}
} else {
log_error("Unknown clock signal for %s\n", name.c_str());
log_error("Unknown clock signal for %s.\n", name.c_str());
}
}

View File

@ -39,7 +39,7 @@ po::options_description GateMateImpl::getUArchOptions()
specific.add_options()("out", po::value<std::string>(), "textual configuration bitstream output file");
specific.add_options()("ccf", po::value<std::string>(), "name of constraints file");
specific.add_options()("allow-unconstrained", "allow unconstrained IOs");
specific.add_options()("fpga_mode", po::value<std::string>(), "operation mode (1:lowpower, 2:economy, 3:speed)");
specific.add_options()("fpga_mode", po::value<std::string>(), "performance mode (1:lowpower, 2:economy, 3:speed)");
specific.add_options()("time_mode", po::value<std::string>(), "timing mode (1:best, 2:typical, 3:worst)");
specific.add_options()("strategy", po::value<std::string>(),
"multi-die clock placement strategy (mirror, full or clk1)");
@ -61,7 +61,7 @@ static int parse_mode(const std::string &val, const std::map<std::string, int> &
if (it != map.end())
return it->second;
}
log_error("%s\n", error_msg);
log_error("Invalid mode='%s', %s", val.c_str(), error_msg);
}
void GateMateImpl::init_database(Arch *arch)
@ -79,10 +79,10 @@ void GateMateImpl::init_database(Arch *arch)
if (args.options.count("fpga_mode"))
fpga_mode = parse_mode(args.options["fpga_mode"].as<std::string>(), fpga_map,
"operation mode valid values are {1:lowpower, 2:economy, 3:speed}");
"performance valid values are {1:lowpower, 2:economy, 3:speed}.\n");
if (args.options.count("time_mode"))
timing_mode = parse_mode(args.options["time_mode"].as<std::string>(), timing_map,
"timing mode valid values are {1:best, 2:typical, 3:worst}");
"timing valid values are {1:best, 2:typical, 3:worst}.\n");
std::string speed_grade = "";
switch (timing_mode) {
@ -96,10 +96,10 @@ void GateMateImpl::init_database(Arch *arch)
speed_grade = "worst_";
break;
}
log_info("Using timing mode '%s'\n", timing_mode == 1 ? "BEST"
: timing_mode == 2 ? "TYPICAL"
: timing_mode == 3 ? "WORST"
: "");
log_info("Using timing mode '%s'.\n", timing_mode == 1 ? "BEST"
: timing_mode == 2 ? "TYPICAL"
: timing_mode == 3 ? "WORST"
: "");
switch (fpga_mode) {
case 1:
@ -111,10 +111,10 @@ void GateMateImpl::init_database(Arch *arch)
default:
speed_grade += "spd";
}
log_info("Using operation mode '%s'\n", fpga_mode == 1 ? "LOWPOWER"
: fpga_mode == 2 ? "ECONOMY"
: fpga_mode == 3 ? "SPEED"
: "");
log_info("Using performance mode '%s'.\n", fpga_mode == 1 ? "LOWPOWER"
: fpga_mode == 2 ? "ECONOMY"
: fpga_mode == 3 ? "SPEED"
: "");
arch->set_speed_grade(speed_grade);
use_cp_for_clk = args.options.count("clk-cp") == 1;
use_cp_for_cpe = args.options.count("no-cpe-cp") == 0;

View File

@ -103,10 +103,10 @@ void GateMatePacker::copy_constraint(const NetInfo *in_net, NetInfo *out_net)
if (!in_net || !out_net)
return;
if (ctx->debug)
log_info("copy clock period constraint on net '%s' from net '%s'\n", out_net->name.c_str(ctx),
log_info("Copy clock period constraint on net '%s' from net '%s'\n", out_net->name.c_str(ctx),
in_net->name.c_str(ctx));
if (out_net->clkconstr.get() != nullptr)
log_warning("found multiple clock constraints on net '%s'\n", out_net->name.c_str(ctx));
log_warning("Found multiple clock constraints on net '%s'\n", out_net->name.c_str(ctx));
if (in_net->clkconstr) {
out_net->clkconstr = std::unique_ptr<ClockConstraint>(new ClockConstraint());
out_net->clkconstr->low = in_net->clkconstr->low;
@ -574,15 +574,16 @@ void GateMateImpl::pack()
std::string val = args.options["strategy"].as<std::string>();
if (val == "mirror") {
strategy = MultiDieStrategy::CLOCK_MIRROR;
log_info("Multidie mode: CLOCK MIRROR\n");
log_info("Multidie mode: CLOCK MIRROR.\n");
} else if (val == "clk1") {
strategy = MultiDieStrategy::REUSE_CLK1;
log_info("Multidie mode: REUSE CLK1\n");
log_info("Multidie mode: REUSE CLK1.\n");
} else if (val == "full") {
strategy = MultiDieStrategy::FULL_USE;
log_info("Multidie mode: FULL USE\n");
log_info("Multidie mode: FULL USE.\n");
} else {
log_error("Unknown value for 'strategy' option. Allowed values are 'mirror', 'full' and 'clk1'.\n");
log_error("Unknown value='%s' for 'strategy' option. Allowed values are 'mirror', 'full' and 'clk1'.\n",
val.c_str());
}
} else {
strategy = MultiDieStrategy::CLOCK_MIRROR;

View File

@ -79,6 +79,7 @@ void GateMatePacker::sort_bufg(unsigned max_num)
flush_cells();
}
// clang-format off
static int glb_mux_mapping[] = {
// CLK0_0 CLK90_0 CLK180_0 CLK270_0 CLK0_1 CLK0_2 CLK0_3
4, 5, 6, 7, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, // GLBOUT 0
@ -89,6 +90,7 @@ static int glb_mux_mapping[] = {
// CLK270_0 CLK270_1 CLK270_2 CLK0_3 CLK90_3 CLK180_3 CLK270_3
0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 4, 5, 6, 7, // GLBOUT 3
};
// clang-format on
void GateMatePacker::pack_bufg()
{
@ -144,7 +146,7 @@ void GateMatePacker::pack_bufg()
}
} while (std::next_permutation(indexes.begin(), indexes.end()));
if (!valid)
log_error("Unable to place PLLs and BUFGs\n");
log_error("Unable to place PLLs and BUFGs.\n");
for (unsigned i = 0; i < max_plls; ++i) {
@ -317,7 +319,7 @@ void GateMatePacker::pll_out(CellInfo *cell, IdString origPort, Loc fixed)
}
if (bufg) {
if (net->users.entries() != 1) {
log_error("not handled BUFG\n");
log_error("Not handled BUFG.\n");
}
} else {
move_ram_i_fixed(cell, origPort, fixed);
@ -475,8 +477,8 @@ void GateMatePacker::pack_pll()
}
if (perf_md != uarch->fpga_mode)
log_warning("PLL '%s' operational mode is '%s' but FPGA operational mode is '%s'.\n",
ci.name.c_str(ctx), fpga_mode_to_str(perf_md), fpga_mode_to_str(uarch->fpga_mode));
log_warning("PLL '%s' PERF_MD mode is '%s' but FPGA performance mode is '%s'.\n", ci.name.c_str(ctx),
fpga_mode_to_str(perf_md), fpga_mode_to_str(uarch->fpga_mode));
double ref_clk = double_or_default(ci.params, id_REF_CLK, 0.0);
if (ref_clk <= 0 || ref_clk > 125)
@ -487,11 +489,11 @@ void GateMatePacker::pack_pll()
log_error("OUT_CLK parameter is out of range (0,%.2lf] for '%s'.\n", max_freq, ci.name.c_str(ctx));
if ((ci_const < 1) || (ci_const > 31)) {
log_warning("CI const out of range. Set to default CI = 2 for '%s'\n", ci.name.c_str(ctx));
log_warning("CI const out of range. Set to default CI = 2 for '%s'.\n", ci.name.c_str(ctx));
ci_const = 2;
}
if ((cp_const < 1) || (cp_const > 31)) {
log_warning("CP const out of range. Set to default CP = 4 for '%s'\n", ci.name.c_str(ctx));
log_warning("CP const out of range. Set to default CP = 4 for '%s'.\n", ci.name.c_str(ctx));
cp_const = 4;
}
// PLL_cfg_val_800_1400 PLL values from 11.08.2021
@ -537,7 +539,7 @@ void GateMatePacker::pack_pll()
ci.params[ctx->id("CFG_A_M2")] = Property(val.M2, 10);
ci.params[ctx->id("CFG_A_PDIV1_SEL")] = Property(val.PDIV1 == 2 ? 1 : 0, 1);
} else {
log_error("Unable to configure PLL %s\n", ci.name.c_str(ctx));
log_error("Unable to configure PLL %s.\n", ci.name.c_str(ctx));
}
// Remove all not propagated parameters
ci.unsetParam(id_PERF_MD);
@ -666,15 +668,15 @@ void GateMatePacker::rewire_ram_o(CellInfo *first, IdString port, CellInfo *seco
net = net->driver.cell->getPort(id_IN1);
break;
default:
log_error("Unsupported config, rewire from '%s' port '%s'\n", first->name.c_str(ctx), port.c_str(ctx));
log_error("Unsupported config, rewire from '%s' port '%s'.\n", first->name.c_str(ctx), port.c_str(ctx));
break;
}
second->connectPort(port, net);
} else {
log_error("Missing cell, rewire from '%s' port '%s'\n", first->name.c_str(ctx), port.c_str(ctx));
log_error("Missing cell, rewire from '%s' port '%s'.\n", first->name.c_str(ctx), port.c_str(ctx));
}
} else {
log_error("Missing cell, rewire from '%s' port '%s'\n", first->name.c_str(ctx), port.c_str(ctx));
log_error("Missing cell, rewire from '%s' port '%s'.\n", first->name.c_str(ctx), port.c_str(ctx));
}
}

View File

@ -170,7 +170,7 @@ void GateMatePacker::override_region(CellInfo *first, CellInfo *second)
{
if (first->region) {
if (second->region && second->region->name != first->region->name) {
log_warning("Unable to place cell '%s' in '%s' region\n", first->name.c_str(ctx),
log_warning("Unable to place cell '%s' in '%s' region.\n", first->name.c_str(ctx),
first->region->name.c_str(ctx));
}
} else {
@ -747,7 +747,7 @@ void GateMatePacker::remove_constants()
ctx->unbindBel(bel);
ctx->cells.erase(fnd_cell);
ctx->nets.erase(fnd_net);
log_info(" Removed unused VCC cell\n");
log_info(" Removed unused VCC cell.\n");
}
}
fnd_cell = ctx->cells.find(ctx->id("$PACKER_GND_DRV"));
@ -759,7 +759,7 @@ void GateMatePacker::remove_constants()
ctx->unbindBel(bel);
ctx->cells.erase(fnd_cell);
ctx->nets.erase(fnd_net);
log_info(" Removed unused GND cell\n");
log_info(" Removed unused GND cell.\n");
}
}
}

View File

@ -37,7 +37,7 @@ void GateMatePacker::pack_io()
// Trim nextpnr IOBs - assume IO buffer insertion has been done in synthesis
for (auto &port : ctx->ports) {
if (!ctx->cells.count(port.first))
log_error("Port '%s' doesn't seem to have a corresponding top level IO\n", ctx->nameOf(port.first));
log_error("Port '%s' doesn't seem to have a corresponding top level IO.\n", ctx->nameOf(port.first));
CellInfo *ci = ctx->cells.at(port.first).get();
PortRef top_port;
@ -51,7 +51,7 @@ void GateMatePacker::pack_io()
if (o == nullptr)
;
else if (o->users.entries() > 1)
log_error("Top level pin '%s' has multiple input buffers\n", ctx->nameOf(port.first));
log_error("Top level pin '%s' has multiple input buffers.\n", ctx->nameOf(port.first));
else if (o->users.entries() == 1)
top_port = *o->users.begin();
}
@ -61,15 +61,15 @@ void GateMatePacker::pack_io()
NetInfo *i = ci->getPort(id_I);
if (i != nullptr && i->driver.cell != nullptr) {
if (top_port.cell != nullptr)
log_error("Top level pin '%s' has multiple input/output buffers\n", ctx->nameOf(port.first));
log_error("Top level pin '%s' has multiple input/output buffers.\n", ctx->nameOf(port.first));
top_port = i->driver;
}
// Edge case of a bidirectional buffer driving an output pin
if (i->users.entries() > 2) {
log_error("Top level pin '%s' has illegal buffer configuration\n", ctx->nameOf(port.first));
log_error("Top level pin '%s' has illegal buffer configuration.\n", ctx->nameOf(port.first));
} else if (i->users.entries() == 2) {
if (top_port.cell != nullptr)
log_error("Top level pin '%s' has illegal buffer configuration\n", ctx->nameOf(port.first));
log_error("Top level pin '%s' has illegal buffer configuration.\n", ctx->nameOf(port.first));
for (auto &usr : i->users) {
if (usr.cell->type == ctx->id("$nextpnr_obuf") || usr.cell->type == ctx->id("$nextpnr_iobuf"))
continue;
@ -79,7 +79,7 @@ void GateMatePacker::pack_io()
}
}
if (!is_npnr_iob)
log_error("Port '%s' doesn't seem to have a corresponding top level IO (internal cell type mismatch)\n",
log_error("Port '%s' doesn't seem to have a corresponding top level IO (internal cell type mismatch).\n",
ctx->nameOf(port.first));
if (top_port.cell == nullptr) {
@ -129,7 +129,7 @@ void GateMatePacker::pack_io()
if (ci.params.count(id_LOC)) {
std::string new_loc = str_or_default(ci.params, id_LOC, "UNPLACED");
if (loc != "UNPLACED" && loc != new_loc)
log_warning("Overriding location of cell '%s' from '%s' with '%s'\n", ctx->nameOf(&ci), loc.c_str(),
log_warning("Overriding location of cell '%s' from '%s' with '%s'.\n", ctx->nameOf(&ci), loc.c_str(),
new_loc.c_str());
loc = new_loc;
}
@ -329,12 +329,12 @@ void GateMatePacker::pack_io()
bel = ctx->get_package_pin_bel(ctx->id(loc));
}
if (bel == BelId())
log_error("Unable to constrain IO '%s', device does not have a pin named '%s'\n", ci.name.c_str(ctx),
log_error("Unable to constrain IO '%s', device does not have a pin named '%s'.\n", ci.name.c_str(ctx),
loc.c_str());
log_info(" Constraining '%s' to pad '%s'%s.\n", ci.name.c_str(ctx), loc.c_str(),
get_die_name(uarch->dies, uarch->tile_extra_data(bel.tile)->die).c_str());
if (!ctx->checkBelAvail(bel)) {
log_error("Can't place %s at %s because it's already taken by %s\n", ctx->nameOf(&ci), ctx->nameOfBel(bel),
log_error("Can't place %s at %s because it's already taken by %s.\n", ctx->nameOf(&ci), ctx->nameOfBel(bel),
ctx->nameOf(ctx->getBoundBelCell(bel)));
}

View File

@ -208,18 +208,18 @@ PllCfgRecord GateMatePacker::get_pll_settings(double f_ref, double f_core, int m
double f_core_par = f_core;
if (f_ref > 50)
log_warning("The PLL input frequency is outside the specified frequency (max 50 MHz ) range\n");
log_warning("The PLL input frequency is outside the specified frequency (max 50 MHz) range.\n");
if (pdiv0_mux && feedback) {
double res;
if (modf(f_core / f_ref, &res) != 0)
log_warning("In this PLL mode f_core can only be greater and multiple of f_ref\n");
log_warning("In this PLL mode f_core can only be greater and multiple of f_ref.\n");
}
if (pdiv0_mux) {
if (f_core > max_input_freq / 4) {
f_core = max_input_freq / 4;
log_warning("Frequency out of range; PLL max output frequency for mode: %d: %.5f MHz\n", mode,
log_warning("Frequency out of range; PLL max output frequency for mode: %d: %.5f MHz.\n", mode,
max_input_freq / 4);
}
}

View File

@ -204,7 +204,7 @@ void GateMateImpl::route_clock()
ctx->nameOfWire(src), pip_plane(uh));
ctx->bindPip(uh, clk_net, is_glb_clk ? STRENGTH_LOCKED : STRENGTH_WEAK);
} else {
log_error("Can't bind pip %s because wire %s is already bound\n", ctx->nameOfPip(uh),
log_error("Can't bind pip %s because wire %s is already bound.\n", ctx->nameOfPip(uh),
ctx->nameOfWire(src));
}
if (src == src_wire)
@ -214,7 +214,7 @@ void GateMateImpl::route_clock()
}
}
auto rend = std::chrono::high_resolution_clock::now();
log_info("Clock router time %.02fs\n", std::chrono::duration<float>(rend - rstart).count());
log_info("Clock router time %.02fs.\n", std::chrono::duration<float>(rend - rstart).count());
}
NEXTPNR_NAMESPACE_END

View File

@ -48,7 +48,7 @@ void find_and_bind_downhill_pip(Context *ctx, WireId from, WireId to, NetInfo *n
return;
}
}
log_error("Couldn't find pip from %s to %s\n", ctx->nameOfWire(from), ctx->nameOfWire(to));
log_error("Couldn't find pip from %s to %s.\n", ctx->nameOfWire(from), ctx->nameOfWire(to));
}
void route_mult_diag(Context *ctx, NetInfo *net, Loc loc, WireId last_wire, int plane)

View File

@ -196,7 +196,7 @@ CellInfo *GateMateTest::create_cell_ptr(IdString type, std::string name)
break;
default:
log_error("Trying to create unknown cell type %s\n", type.c_str(ctx));
log_error("Trying to create unknown cell type %s.\n", type.c_str(ctx));
break;
}
return cell;