Mark IdString and IdStringList single argument constructors explicit.
Single argument constructors will silently convert to that type. This is typically not the right thing to do. For example, the nexus and ice40 arch_pybindings.h files were incorrectly parsing bel name strings, etc. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
This commit is contained in:
parent
40d026e6fc
commit
c99fbde0eb
@ -135,8 +135,10 @@ void archcheck_locs(const Context *ctx)
|
|||||||
//
|
//
|
||||||
// This allows a fast way to check getPipsDownhill/getPipsUphill from getPips,
|
// This allows a fast way to check getPipsDownhill/getPipsUphill from getPips,
|
||||||
// without balloning memory usage.
|
// without balloning memory usage.
|
||||||
struct LruWireCacheMap {
|
struct LruWireCacheMap
|
||||||
LruWireCacheMap(const Context *ctx, size_t cache_size) : ctx(ctx), cache_size(cache_size) {
|
{
|
||||||
|
LruWireCacheMap(const Context *ctx, size_t cache_size) : ctx(ctx), cache_size(cache_size)
|
||||||
|
{
|
||||||
cache_hits = 0;
|
cache_hits = 0;
|
||||||
cache_misses = 0;
|
cache_misses = 0;
|
||||||
cache_evictions = 0;
|
cache_evictions = 0;
|
||||||
@ -159,7 +161,8 @@ struct LruWireCacheMap {
|
|||||||
std::unordered_map<PipId, WireId> pips_downhill;
|
std::unordered_map<PipId, WireId> pips_downhill;
|
||||||
std::unordered_map<PipId, WireId> pips_uphill;
|
std::unordered_map<PipId, WireId> pips_uphill;
|
||||||
|
|
||||||
void removeWireFromCache(WireId wire_to_remove) {
|
void removeWireFromCache(WireId wire_to_remove)
|
||||||
|
{
|
||||||
for (PipId pip : ctx->getPipsDownhill(wire_to_remove)) {
|
for (PipId pip : ctx->getPipsDownhill(wire_to_remove)) {
|
||||||
log_assert(pips_downhill.erase(pip) == 1);
|
log_assert(pips_downhill.erase(pip) == 1);
|
||||||
}
|
}
|
||||||
@ -169,7 +172,8 @@ struct LruWireCacheMap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void addWireToCache(WireId wire) {
|
void addWireToCache(WireId wire)
|
||||||
|
{
|
||||||
for (PipId pip : ctx->getPipsDownhill(wire)) {
|
for (PipId pip : ctx->getPipsDownhill(wire)) {
|
||||||
auto result = pips_downhill.emplace(pip, wire);
|
auto result = pips_downhill.emplace(pip, wire);
|
||||||
log_assert(result.second);
|
log_assert(result.second);
|
||||||
@ -181,12 +185,13 @@ struct LruWireCacheMap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void populateCache(WireId wire) {
|
void populateCache(WireId wire)
|
||||||
|
{
|
||||||
// Put this wire at the end of last_access_list.
|
// Put this wire at the end of last_access_list.
|
||||||
auto iter = last_access_list.emplace(last_access_list.end(), wire);
|
auto iter = last_access_list.emplace(last_access_list.end(), wire);
|
||||||
last_access_map.emplace(wire, iter);
|
last_access_map.emplace(wire, iter);
|
||||||
|
|
||||||
if(last_access_list.size() > cache_size) {
|
if (last_access_list.size() > cache_size) {
|
||||||
// Cache is full, remove front of last_access_list.
|
// Cache is full, remove front of last_access_list.
|
||||||
cache_evictions += 1;
|
cache_evictions += 1;
|
||||||
WireId wire_to_remove = last_access_list.front();
|
WireId wire_to_remove = last_access_list.front();
|
||||||
@ -202,9 +207,10 @@ struct LruWireCacheMap {
|
|||||||
// Determine if wire is in the cache. If wire is not in the cache,
|
// Determine if wire is in the cache. If wire is not in the cache,
|
||||||
// adds the wire to the cache, and potentially evicts the oldest wire if
|
// adds the wire to the cache, and potentially evicts the oldest wire if
|
||||||
// cache is now full.
|
// cache is now full.
|
||||||
void checkCache(WireId wire) {
|
void checkCache(WireId wire)
|
||||||
|
{
|
||||||
auto iter = last_access_map.find(wire);
|
auto iter = last_access_map.find(wire);
|
||||||
if(iter == last_access_map.end()) {
|
if (iter == last_access_map.end()) {
|
||||||
cache_misses += 1;
|
cache_misses += 1;
|
||||||
populateCache(wire);
|
populateCache(wire);
|
||||||
} else {
|
} else {
|
||||||
@ -215,18 +221,21 @@ struct LruWireCacheMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if pip is uphill of wire (e.g. pip in getPipsUphill(wire)).
|
// Returns true if pip is uphill of wire (e.g. pip in getPipsUphill(wire)).
|
||||||
bool isPipUphill(PipId pip, WireId wire) {
|
bool isPipUphill(PipId pip, WireId wire)
|
||||||
|
{
|
||||||
checkCache(wire);
|
checkCache(wire);
|
||||||
return pips_uphill.at(pip) == wire;
|
return pips_uphill.at(pip) == wire;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if pip is downhill of wire (e.g. pip in getPipsDownhill(wire)).
|
// Returns true if pip is downhill of wire (e.g. pip in getPipsDownhill(wire)).
|
||||||
bool isPipDownhill(PipId pip, WireId wire) {
|
bool isPipDownhill(PipId pip, WireId wire)
|
||||||
|
{
|
||||||
checkCache(wire);
|
checkCache(wire);
|
||||||
return pips_downhill.at(pip) == wire;
|
return pips_downhill.at(pip) == wire;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cache_info() const {
|
void cache_info() const
|
||||||
|
{
|
||||||
log_info("Cache hits: %zu\n", cache_hits);
|
log_info("Cache hits: %zu\n", cache_hits);
|
||||||
log_info("Cache misses: %zu\n", cache_misses);
|
log_info("Cache misses: %zu\n", cache_misses);
|
||||||
log_info("Cache evictions: %zu\n", cache_evictions);
|
log_info("Cache evictions: %zu\n", cache_evictions);
|
||||||
@ -285,7 +294,7 @@ void archcheck_conn(const Context *ctx)
|
|||||||
// gains by avoiding the full pip -> wire map, and still preserves a fast
|
// gains by avoiding the full pip -> wire map, and still preserves a fast
|
||||||
// pip -> wire, assuming that pips are returned from getPips with some
|
// pip -> wire, assuming that pips are returned from getPips with some
|
||||||
// chip locality.
|
// chip locality.
|
||||||
LruWireCacheMap pip_cache(ctx, /*cache_size=*/64*1024);
|
LruWireCacheMap pip_cache(ctx, /*cache_size=*/64 * 1024);
|
||||||
log_info("Checking all PIPs...\n");
|
log_info("Checking all PIPs...\n");
|
||||||
for (PipId pip : ctx->getPips()) {
|
for (PipId pip : ctx->getPips()) {
|
||||||
WireId src_wire = ctx->getPipSrcWire(pip);
|
WireId src_wire = ctx->getPipSrcWire(pip);
|
||||||
|
@ -805,9 +805,9 @@ void BaseCtx::attributesToArchInfo()
|
|||||||
std::string pip = strs[i * 3 + 1];
|
std::string pip = strs[i * 3 + 1];
|
||||||
PlaceStrength strength = (PlaceStrength)std::stoi(strs[i * 3 + 2]);
|
PlaceStrength strength = (PlaceStrength)std::stoi(strs[i * 3 + 2]);
|
||||||
if (pip.empty())
|
if (pip.empty())
|
||||||
getCtx()->bindWire(getCtx()->getWireByName(id(wire)), ni, strength);
|
getCtx()->bindWire(getCtx()->getWireByName(IdStringList::parse(getCtx(), wire)), ni, strength);
|
||||||
else
|
else
|
||||||
getCtx()->bindPip(getCtx()->getPipByName(id(pip)), ni, strength);
|
getCtx()->bindPip(getCtx()->getPipByName(IdStringList::parse(getCtx(), pip)), ni, strength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -110,7 +110,8 @@ struct IdString
|
|||||||
|
|
||||||
static void initialize_add(const BaseCtx *ctx, const char *s, int idx);
|
static void initialize_add(const BaseCtx *ctx, const char *s, int idx);
|
||||||
|
|
||||||
constexpr IdString(int index = 0) : index(index) {}
|
constexpr IdString() : index(0) {}
|
||||||
|
explicit constexpr IdString(int index) : index(index) {}
|
||||||
|
|
||||||
void set(const BaseCtx *ctx, const std::string &s);
|
void set(const BaseCtx *ctx, const std::string &s);
|
||||||
|
|
||||||
@ -229,9 +230,9 @@ struct IdStringList
|
|||||||
SSOArray<IdString, 4> ids;
|
SSOArray<IdString, 4> ids;
|
||||||
|
|
||||||
IdStringList(){};
|
IdStringList(){};
|
||||||
IdStringList(size_t n) : ids(n, IdString()){};
|
explicit IdStringList(size_t n) : ids(n, IdString()){};
|
||||||
IdStringList(IdString id) : ids(1, id){};
|
explicit IdStringList(IdString id) : ids(1, id){};
|
||||||
template <typename Tlist> IdStringList(const Tlist &list) : ids(list){};
|
template <typename Tlist> explicit IdStringList(const Tlist &list) : ids(list){};
|
||||||
|
|
||||||
static IdStringList parse(Context *ctx, const std::string &str);
|
static IdStringList parse(Context *ctx, const std::string &str);
|
||||||
void build_str(const Context *ctx, std::string &str) const;
|
void build_str(const Context *ctx, std::string &str) const;
|
||||||
|
@ -129,7 +129,7 @@ void Arch::addBelInput(IdStringList bel, IdString name, IdStringList wire)
|
|||||||
{
|
{
|
||||||
NPNR_ASSERT(bel_info(bel).pins.count(name) == 0);
|
NPNR_ASSERT(bel_info(bel).pins.count(name) == 0);
|
||||||
PinInfo &pi = bel_info(bel).pins[name];
|
PinInfo &pi = bel_info(bel).pins[name];
|
||||||
pi.name = name;
|
pi.name = IdStringList(name);
|
||||||
pi.wire = wire;
|
pi.wire = wire;
|
||||||
pi.type = PORT_IN;
|
pi.type = PORT_IN;
|
||||||
|
|
||||||
@ -141,7 +141,7 @@ void Arch::addBelOutput(IdStringList bel, IdString name, IdStringList wire)
|
|||||||
{
|
{
|
||||||
NPNR_ASSERT(bel_info(bel).pins.count(name) == 0);
|
NPNR_ASSERT(bel_info(bel).pins.count(name) == 0);
|
||||||
PinInfo &pi = bel_info(bel).pins[name];
|
PinInfo &pi = bel_info(bel).pins[name];
|
||||||
pi.name = name;
|
pi.name = IdStringList(name);
|
||||||
pi.wire = wire;
|
pi.wire = wire;
|
||||||
pi.type = PORT_OUT;
|
pi.type = PORT_OUT;
|
||||||
|
|
||||||
@ -153,7 +153,7 @@ void Arch::addBelInout(IdStringList bel, IdString name, IdStringList wire)
|
|||||||
{
|
{
|
||||||
NPNR_ASSERT(bel_info(bel).pins.count(name) == 0);
|
NPNR_ASSERT(bel_info(bel).pins.count(name) == 0);
|
||||||
PinInfo &pi = bel_info(bel).pins[name];
|
PinInfo &pi = bel_info(bel).pins[name];
|
||||||
pi.name = name;
|
pi.name = IdStringList(name);
|
||||||
pi.wire = wire;
|
pi.wire = wire;
|
||||||
pi.type = PORT_INOUT;
|
pi.type = PORT_INOUT;
|
||||||
|
|
||||||
@ -216,12 +216,9 @@ void Arch::setDelayScaling(double scale, double offset)
|
|||||||
args.delayOffset = offset;
|
args.delayOffset = offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Arch::addCellTimingClock(IdStringList cell, IdString port)
|
void Arch::addCellTimingClock(IdString cell, IdString port) { cellTiming[cell].portClasses[port] = TMG_CLOCK_INPUT; }
|
||||||
{
|
|
||||||
cellTiming[cell].portClasses[port] = TMG_CLOCK_INPUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Arch::addCellTimingDelay(IdStringList cell, IdString fromPort, IdString toPort, DelayInfo delay)
|
void Arch::addCellTimingDelay(IdString cell, IdString fromPort, IdString toPort, DelayInfo delay)
|
||||||
{
|
{
|
||||||
if (get_or_default(cellTiming[cell].portClasses, fromPort, TMG_IGNORE) == TMG_IGNORE)
|
if (get_or_default(cellTiming[cell].portClasses, fromPort, TMG_IGNORE) == TMG_IGNORE)
|
||||||
cellTiming[cell].portClasses[fromPort] = TMG_COMB_INPUT;
|
cellTiming[cell].portClasses[fromPort] = TMG_COMB_INPUT;
|
||||||
@ -230,7 +227,7 @@ void Arch::addCellTimingDelay(IdStringList cell, IdString fromPort, IdString toP
|
|||||||
cellTiming[cell].combDelays[CellDelayKey{fromPort, toPort}] = delay;
|
cellTiming[cell].combDelays[CellDelayKey{fromPort, toPort}] = delay;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Arch::addCellTimingSetupHold(IdStringList cell, IdString port, IdString clock, DelayInfo setup, DelayInfo hold)
|
void Arch::addCellTimingSetupHold(IdString cell, IdString port, IdString clock, DelayInfo setup, DelayInfo hold)
|
||||||
{
|
{
|
||||||
TimingClockingInfo ci;
|
TimingClockingInfo ci;
|
||||||
ci.clock_port = clock;
|
ci.clock_port = clock;
|
||||||
@ -241,7 +238,7 @@ void Arch::addCellTimingSetupHold(IdStringList cell, IdString port, IdString clo
|
|||||||
cellTiming[cell].portClasses[port] = TMG_REGISTER_INPUT;
|
cellTiming[cell].portClasses[port] = TMG_REGISTER_INPUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Arch::addCellTimingClockToOut(IdStringList cell, IdString port, IdString clock, DelayInfo clktoq)
|
void Arch::addCellTimingClockToOut(IdString cell, IdString port, IdString clock, DelayInfo clktoq)
|
||||||
{
|
{
|
||||||
TimingClockingInfo ci;
|
TimingClockingInfo ci;
|
||||||
ci.clock_port = clock;
|
ci.clock_port = clock;
|
||||||
@ -256,7 +253,7 @@ void Arch::addCellTimingClockToOut(IdStringList cell, IdString port, IdString cl
|
|||||||
Arch::Arch(ArchArgs args) : chipName("generic"), args(args)
|
Arch::Arch(ArchArgs args) : chipName("generic"), args(args)
|
||||||
{
|
{
|
||||||
// Dummy for empty decals
|
// Dummy for empty decals
|
||||||
decal_graphics[IdString()];
|
decal_graphics[DecalId()];
|
||||||
}
|
}
|
||||||
|
|
||||||
void IdString::initialize_arch(const BaseCtx *ctx) {}
|
void IdString::initialize_arch(const BaseCtx *ctx) {}
|
||||||
|
@ -141,7 +141,7 @@ struct Arch : BaseCtx
|
|||||||
std::vector<std::vector<int>> tileBelDimZ;
|
std::vector<std::vector<int>> tileBelDimZ;
|
||||||
std::vector<std::vector<int>> tilePipDimZ;
|
std::vector<std::vector<int>> tilePipDimZ;
|
||||||
|
|
||||||
std::unordered_map<IdStringList, CellTiming> cellTiming;
|
std::unordered_map<IdString, CellTiming> cellTiming;
|
||||||
|
|
||||||
void addWire(IdStringList name, IdString type, int x, int y);
|
void addWire(IdStringList name, IdString type, int x, int y);
|
||||||
void addPip(IdStringList name, IdString type, IdStringList srcWire, IdStringList dstWire, DelayInfo delay, Loc loc);
|
void addPip(IdStringList name, IdString type, IdStringList srcWire, IdStringList dstWire, DelayInfo delay, Loc loc);
|
||||||
@ -169,10 +169,10 @@ struct Arch : BaseCtx
|
|||||||
void setLutK(int K);
|
void setLutK(int K);
|
||||||
void setDelayScaling(double scale, double offset);
|
void setDelayScaling(double scale, double offset);
|
||||||
|
|
||||||
void addCellTimingClock(IdStringList cell, IdString port);
|
void addCellTimingClock(IdString cell, IdString port);
|
||||||
void addCellTimingDelay(IdStringList cell, IdString fromPort, IdString toPort, DelayInfo delay);
|
void addCellTimingDelay(IdString cell, IdString fromPort, IdString toPort, DelayInfo delay);
|
||||||
void addCellTimingSetupHold(IdStringList cell, IdString port, IdString clock, DelayInfo setup, DelayInfo hold);
|
void addCellTimingSetupHold(IdString cell, IdString port, IdString clock, DelayInfo setup, DelayInfo hold);
|
||||||
void addCellTimingClockToOut(IdStringList cell, IdString port, IdString clock, DelayInfo clktoq);
|
void addCellTimingClockToOut(IdString cell, IdString port, IdString clock, DelayInfo clktoq);
|
||||||
|
|
||||||
// ---------------------------------------------------------------
|
// ---------------------------------------------------------------
|
||||||
// Common Arch API. Every arch must provide the following methods.
|
// Common Arch API. Every arch must provide the following methods.
|
||||||
|
@ -212,17 +212,16 @@ void arch_wrap_python(py::module &m)
|
|||||||
pass_through<double>>::def_wrap(ctx_cls, "setDelayScaling", "scale"_a, "offset"_a);
|
pass_through<double>>::def_wrap(ctx_cls, "setDelayScaling", "scale"_a, "offset"_a);
|
||||||
|
|
||||||
fn_wrapper_2a_v<Context, decltype(&Context::addCellTimingClock), &Context::addCellTimingClock,
|
fn_wrapper_2a_v<Context, decltype(&Context::addCellTimingClock), &Context::addCellTimingClock,
|
||||||
conv_from_str<IdStringList>, conv_from_str<IdString>>::def_wrap(ctx_cls, "addCellTimingClock",
|
conv_from_str<IdString>, conv_from_str<IdString>>::def_wrap(ctx_cls, "addCellTimingClock", "cell"_a,
|
||||||
"cell"_a, "port"_a);
|
"port"_a);
|
||||||
fn_wrapper_4a_v<Context, decltype(&Context::addCellTimingDelay), &Context::addCellTimingDelay,
|
fn_wrapper_4a_v<Context, decltype(&Context::addCellTimingDelay), &Context::addCellTimingDelay,
|
||||||
conv_from_str<IdStringList>, conv_from_str<IdString>, conv_from_str<IdString>,
|
conv_from_str<IdString>, conv_from_str<IdString>, conv_from_str<IdString>,
|
||||||
pass_through<DelayInfo>>::def_wrap(ctx_cls, "addCellTimingDelay", "cell"_a, "fromPort"_a,
|
pass_through<DelayInfo>>::def_wrap(ctx_cls, "addCellTimingDelay", "cell"_a, "fromPort"_a,
|
||||||
"toPort"_a, "delay"_a);
|
"toPort"_a, "delay"_a);
|
||||||
fn_wrapper_5a_v<Context, decltype(&Context::addCellTimingSetupHold), &Context::addCellTimingSetupHold,
|
fn_wrapper_5a_v<Context, decltype(&Context::addCellTimingSetupHold), &Context::addCellTimingSetupHold,
|
||||||
conv_from_str<IdStringList>, conv_from_str<IdString>, conv_from_str<IdString>,
|
conv_from_str<IdString>, conv_from_str<IdString>, conv_from_str<IdString>, pass_through<DelayInfo>,
|
||||||
pass_through<DelayInfo>, pass_through<DelayInfo>>::def_wrap(ctx_cls, "addCellTimingSetupHold",
|
pass_through<DelayInfo>>::def_wrap(ctx_cls, "addCellTimingSetupHold", "cell"_a, "port"_a, "clock"_a,
|
||||||
"cell"_a, "port"_a, "clock"_a,
|
"setup"_a, "hold"_a);
|
||||||
"setup"_a, "hold"_a);
|
|
||||||
fn_wrapper_4a_v<Context, decltype(&Context::addCellTimingClockToOut), &Context::addCellTimingClockToOut,
|
fn_wrapper_4a_v<Context, decltype(&Context::addCellTimingClockToOut), &Context::addCellTimingClockToOut,
|
||||||
conv_from_str<IdString>, conv_from_str<IdString>, conv_from_str<IdString>,
|
conv_from_str<IdString>, conv_from_str<IdString>, conv_from_str<IdString>,
|
||||||
pass_through<DelayInfo>>::def_wrap(ctx_cls, "addCellTimingClockToOut", "cell"_a, "port"_a,
|
pass_through<DelayInfo>>::def_wrap(ctx_cls, "addCellTimingClockToOut", "cell"_a, "port"_a,
|
||||||
|
@ -459,9 +459,9 @@ DelayInfo Arch::getWireTypeDelay(IdString wire)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (wire.str(this).rfind("SPINE", 0) == 0) {
|
if (wire.str(this).rfind("SPINE", 0) == 0) {
|
||||||
glbsrc = ID_CENT_SPINE_PCLK;
|
glbsrc = IdString(ID_CENT_SPINE_PCLK);
|
||||||
} else if (wire.str(this).rfind("UNK", 0) == 0) {
|
} else if (wire.str(this).rfind("UNK", 0) == 0) {
|
||||||
glbsrc = ID_PIO_CENT_PCLK;
|
glbsrc = IdString(ID_PIO_CENT_PCLK);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -511,7 +511,7 @@ void Arch::read_cst(std::istream &in)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
std::string bel = IdString(belname->src_id).str(this);
|
std::string bel = IdString(belname->src_id).str(this);
|
||||||
it->second->attrs[ID_BEL] = bel;
|
it->second->attrs[IdString(ID_BEL)] = bel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -589,16 +589,16 @@ Arch::Arch(ArchArgs args) : args(args)
|
|||||||
const PairPOD pip = pips[p][j];
|
const PairPOD pip = pips[p][j];
|
||||||
int destrow = row;
|
int destrow = row;
|
||||||
int destcol = col;
|
int destcol = col;
|
||||||
IdString destid = pip.dest_id;
|
IdString destid(pip.dest_id);
|
||||||
IdString gdestname = wireToGlobal(destrow, destcol, db, destid);
|
IdString gdestname = wireToGlobal(destrow, destcol, db, destid);
|
||||||
if (wires.count(gdestname) == 0)
|
if (wires.count(gdestname) == 0)
|
||||||
addWire(gdestname, pip.dest_id, destcol, destrow);
|
addWire(gdestname, destid, destcol, destrow);
|
||||||
int srcrow = row;
|
int srcrow = row;
|
||||||
int srccol = col;
|
int srccol = col;
|
||||||
IdString srcid = pip.src_id;
|
IdString srcid(pip.src_id);
|
||||||
IdString gsrcname = wireToGlobal(srcrow, srccol, db, srcid);
|
IdString gsrcname = wireToGlobal(srcrow, srccol, db, srcid);
|
||||||
if (wires.count(gsrcname) == 0)
|
if (wires.count(gsrcname) == 0)
|
||||||
addWire(gsrcname, pip.src_id, srccol, srcrow);
|
addWire(gsrcname, srcid, srccol, srcrow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (unsigned int j = 0; j < tile->num_bels; j++) {
|
for (unsigned int j = 0; j < tile->num_bels; j++) {
|
||||||
@ -673,13 +673,13 @@ Arch::Arch(ArchArgs args) : args(args)
|
|||||||
snprintf(buf, 32, "R%dC%d_IOB%c", row + 1, col + 1, 'A' + z);
|
snprintf(buf, 32, "R%dC%d_IOB%c", row + 1, col + 1, 'A' + z);
|
||||||
belname = id(buf);
|
belname = id(buf);
|
||||||
addBel(belname, id_IOB, Loc(col, row, z), false);
|
addBel(belname, id_IOB, Loc(col, row, z), false);
|
||||||
portname = pairLookup(bel->ports.get(), bel->num_ports, ID_O)->src_id;
|
portname = IdString(pairLookup(bel->ports.get(), bel->num_ports, ID_O)->src_id);
|
||||||
snprintf(buf, 32, "R%dC%d_%s", row + 1, col + 1, portname.c_str(this));
|
snprintf(buf, 32, "R%dC%d_%s", row + 1, col + 1, portname.c_str(this));
|
||||||
addBelOutput(belname, id_O, id(buf));
|
addBelOutput(belname, id_O, id(buf));
|
||||||
portname = pairLookup(bel->ports.get(), bel->num_ports, ID_I)->src_id;
|
portname = IdString(pairLookup(bel->ports.get(), bel->num_ports, ID_I)->src_id);
|
||||||
snprintf(buf, 32, "R%dC%d_%s", row + 1, col + 1, portname.c_str(this));
|
snprintf(buf, 32, "R%dC%d_%s", row + 1, col + 1, portname.c_str(this));
|
||||||
addBelInput(belname, id_I, id(buf));
|
addBelInput(belname, id_I, id(buf));
|
||||||
portname = pairLookup(bel->ports.get(), bel->num_ports, ID_OE)->src_id;
|
portname = IdString(pairLookup(bel->ports.get(), bel->num_ports, ID_OE)->src_id);
|
||||||
snprintf(buf, 32, "R%dC%d_%s", row + 1, col + 1, portname.c_str(this));
|
snprintf(buf, 32, "R%dC%d_%s", row + 1, col + 1, portname.c_str(this));
|
||||||
addBelInput(belname, id_OEN, id(buf));
|
addBelInput(belname, id_OEN, id(buf));
|
||||||
break;
|
break;
|
||||||
@ -701,26 +701,25 @@ Arch::Arch(ArchArgs args) : args(args)
|
|||||||
const PairPOD pip = pips[p][j];
|
const PairPOD pip = pips[p][j];
|
||||||
int destrow = row;
|
int destrow = row;
|
||||||
int destcol = col;
|
int destcol = col;
|
||||||
IdString destid = pip.dest_id;
|
IdString destid(pip.dest_id);
|
||||||
IdString gdestname = wireToGlobal(destrow, destcol, db, destid);
|
IdString gdestname = wireToGlobal(destrow, destcol, db, destid);
|
||||||
int srcrow = row;
|
int srcrow = row;
|
||||||
int srccol = col;
|
int srccol = col;
|
||||||
IdString srcid = pip.src_id;
|
IdString srcid(pip.src_id);
|
||||||
IdString gsrcname = wireToGlobal(srcrow, srccol, db, srcid);
|
IdString gsrcname = wireToGlobal(srcrow, srccol, db, srcid);
|
||||||
|
|
||||||
snprintf(buf, 32, "R%dC%d_%s_%s", row + 1, col + 1, IdString(pip.src_id).c_str(this),
|
snprintf(buf, 32, "R%dC%d_%s_%s", row + 1, col + 1, srcid.c_str(this), destid.c_str(this));
|
||||||
IdString(pip.dest_id).c_str(this));
|
|
||||||
IdString pipname = id(buf);
|
IdString pipname = id(buf);
|
||||||
DelayInfo delay = getWireTypeDelay(pip.dest_id);
|
DelayInfo delay = getWireTypeDelay(destid);
|
||||||
// local alias
|
// local alias
|
||||||
auto local_alias = pairLookup(tile->aliases.get(), tile->num_aliases, srcid.index);
|
auto local_alias = pairLookup(tile->aliases.get(), tile->num_aliases, srcid.index);
|
||||||
// std::cout << "srcid " << srcid.str(this) << std::endl;
|
// std::cout << "srcid " << srcid.str(this) << std::endl;
|
||||||
if (local_alias != nullptr) {
|
if (local_alias != nullptr) {
|
||||||
srcid = local_alias->src_id;
|
srcid = IdString(local_alias->src_id);
|
||||||
gsrcname = wireToGlobal(srcrow, srccol, db, srcid);
|
gsrcname = wireToGlobal(srcrow, srccol, db, srcid);
|
||||||
}
|
}
|
||||||
// global alias
|
// global alias
|
||||||
srcid = pip.src_id;
|
srcid = IdString(pip.src_id);
|
||||||
GlobalAliasPOD alias;
|
GlobalAliasPOD alias;
|
||||||
alias.dest_col = srccol;
|
alias.dest_col = srccol;
|
||||||
alias.dest_row = srcrow;
|
alias.dest_row = srcrow;
|
||||||
@ -729,11 +728,11 @@ Arch::Arch(ArchArgs args) : args(args)
|
|||||||
if (alias_src != nullptr) {
|
if (alias_src != nullptr) {
|
||||||
srccol = alias_src->src_col;
|
srccol = alias_src->src_col;
|
||||||
srcrow = alias_src->src_row;
|
srcrow = alias_src->src_row;
|
||||||
srcid = alias_src->src_id;
|
srcid = IdString(alias_src->src_id);
|
||||||
gsrcname = wireToGlobal(srcrow, srccol, db, srcid);
|
gsrcname = wireToGlobal(srcrow, srccol, db, srcid);
|
||||||
// std::cout << buf << std::endl;
|
// std::cout << buf << std::endl;
|
||||||
}
|
}
|
||||||
addPip(pipname, pip.dest_id, gsrcname, gdestname, delay, Loc(col, row, j));
|
addPip(pipname, destid, gsrcname, gdestname, delay, Loc(col, row, j));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -911,7 +911,7 @@ void DesignWidget::prepareMenuProperty(const QPoint &pos)
|
|||||||
ElementType type = getElementTypeByName(selectedProperty->propertyId());
|
ElementType type = getElementTypeByName(selectedProperty->propertyId());
|
||||||
if (type == ElementType::NONE)
|
if (type == ElementType::NONE)
|
||||||
continue;
|
continue;
|
||||||
IdString value = ctx->id(selectedProperty->valueText().toStdString());
|
IdStringList value = IdStringList::parse(ctx, selectedProperty->valueText().toStdString());
|
||||||
auto node = getTreeByElementType(type)->nodeForId(value);
|
auto node = getTreeByElementType(type)->nodeForId(value);
|
||||||
if (!node)
|
if (!node)
|
||||||
continue;
|
continue;
|
||||||
@ -996,7 +996,9 @@ void DesignWidget::onItemDoubleClicked(QTreeWidgetItem *item, int column)
|
|||||||
ElementType type = getElementTypeByName(selectedProperty->propertyId());
|
ElementType type = getElementTypeByName(selectedProperty->propertyId());
|
||||||
if (type == ElementType::NONE)
|
if (type == ElementType::NONE)
|
||||||
return;
|
return;
|
||||||
auto it = getTreeByElementType(type)->nodeForId(ctx->id(selectedProperty->valueText().toStdString()));
|
|
||||||
|
IdStringList value = IdStringList::parse(ctx, selectedProperty->valueText().toStdString());
|
||||||
|
auto it = getTreeByElementType(type)->nodeForId(value);
|
||||||
if (it) {
|
if (it) {
|
||||||
int num = getIndexByElementType(type);
|
int num = getIndexByElementType(type);
|
||||||
clearAllSelectionModels();
|
clearAllSelectionModels();
|
||||||
@ -1049,8 +1051,8 @@ void DesignWidget::onHoverPropertyChanged(QtBrowserItem *item)
|
|||||||
QtProperty *selectedProperty = item->property();
|
QtProperty *selectedProperty = item->property();
|
||||||
ElementType type = getElementTypeByName(selectedProperty->propertyId());
|
ElementType type = getElementTypeByName(selectedProperty->propertyId());
|
||||||
if (type != ElementType::NONE) {
|
if (type != ElementType::NONE) {
|
||||||
IdString value = ctx->id(selectedProperty->valueText().toStdString());
|
IdStringList value = IdStringList::parse(ctx, selectedProperty->valueText().toStdString());
|
||||||
if (value != IdString()) {
|
if (value != IdStringList()) {
|
||||||
auto node = getTreeByElementType(type)->nodeForId(value);
|
auto node = getTreeByElementType(type)->nodeForId(value);
|
||||||
if (node) {
|
if (node) {
|
||||||
std::vector<DecalXY> decals = getDecals((*node)->type(), (*node)->id());
|
std::vector<DecalXY> decals = getDecals((*node)->type(), (*node)->id());
|
||||||
|
@ -564,7 +564,7 @@ IdStringList Arch::getGroupName(GroupId group) const
|
|||||||
suffix = "lc7_sw";
|
suffix = "lc7_sw";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return IdString();
|
return IdStringList();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::array<IdString, 3> ids{x_ids.at(group.x), y_ids.at(group.y), id(suffix)};
|
std::array<IdString, 3> ids{x_ids.at(group.x), y_ids.at(group.y), id(suffix)};
|
||||||
|
@ -269,7 +269,7 @@ struct BelPinIterator
|
|||||||
{
|
{
|
||||||
BelPin ret;
|
BelPin ret;
|
||||||
ret.bel.index = ptr->bel_index;
|
ret.bel.index = ptr->bel_index;
|
||||||
ret.pin = ptr->port;
|
ret.pin = IdString(ptr->port);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -30,7 +30,7 @@ namespace PythonConversion {
|
|||||||
|
|
||||||
template <> struct string_converter<BelId>
|
template <> struct string_converter<BelId>
|
||||||
{
|
{
|
||||||
BelId from_str(Context *ctx, std::string name) { return ctx->getBelByName(ctx->id(name)); }
|
BelId from_str(Context *ctx, std::string name) { return ctx->getBelByName(IdStringList::parse(ctx, name)); }
|
||||||
|
|
||||||
std::string to_str(Context *ctx, BelId id)
|
std::string to_str(Context *ctx, BelId id)
|
||||||
{
|
{
|
||||||
@ -42,7 +42,7 @@ template <> struct string_converter<BelId>
|
|||||||
|
|
||||||
template <> struct string_converter<WireId>
|
template <> struct string_converter<WireId>
|
||||||
{
|
{
|
||||||
WireId from_str(Context *ctx, std::string name) { return ctx->getWireByName(ctx->id(name)); }
|
WireId from_str(Context *ctx, std::string name) { return ctx->getWireByName(IdStringList::parse(ctx, name)); }
|
||||||
|
|
||||||
std::string to_str(Context *ctx, WireId id)
|
std::string to_str(Context *ctx, WireId id)
|
||||||
{
|
{
|
||||||
@ -54,7 +54,7 @@ template <> struct string_converter<WireId>
|
|||||||
|
|
||||||
template <> struct string_converter<const WireId>
|
template <> struct string_converter<const WireId>
|
||||||
{
|
{
|
||||||
WireId from_str(Context *ctx, std::string name) { return ctx->getWireByName(ctx->id(name)); }
|
WireId from_str(Context *ctx, std::string name) { return ctx->getWireByName(IdStringList::parse(ctx, name)); }
|
||||||
|
|
||||||
std::string to_str(Context *ctx, WireId id)
|
std::string to_str(Context *ctx, WireId id)
|
||||||
{
|
{
|
||||||
@ -66,7 +66,7 @@ template <> struct string_converter<const WireId>
|
|||||||
|
|
||||||
template <> struct string_converter<PipId>
|
template <> struct string_converter<PipId>
|
||||||
{
|
{
|
||||||
PipId from_str(Context *ctx, std::string name) { return ctx->getPipByName(ctx->id(name)); }
|
PipId from_str(Context *ctx, std::string name) { return ctx->getPipByName(IdStringList::parse(ctx, name)); }
|
||||||
|
|
||||||
std::string to_str(Context *ctx, PipId id)
|
std::string to_str(Context *ctx, PipId id)
|
||||||
{
|
{
|
||||||
|
@ -373,8 +373,8 @@ std::vector<std::pair<IdString, std::string>> Arch::getPipAttrs(PipId pip) const
|
|||||||
ret.emplace_back(id("GRID_X"), stringf("%d", pip.tile % chip_info->width));
|
ret.emplace_back(id("GRID_X"), stringf("%d", pip.tile % chip_info->width));
|
||||||
ret.emplace_back(id("GRID_Y"), stringf("%d", pip.tile / chip_info->width));
|
ret.emplace_back(id("GRID_Y"), stringf("%d", pip.tile / chip_info->width));
|
||||||
|
|
||||||
ret.emplace_back(id("FROM_TILE_WIRE"), nameOf(loc_data(pip).wires[pip_data(pip).from_wire].name));
|
ret.emplace_back(id("FROM_TILE_WIRE"), nameOf(IdString(loc_data(pip).wires[pip_data(pip).from_wire].name)));
|
||||||
ret.emplace_back(id("TO_TILE_WIRE"), nameOf(loc_data(pip).wires[pip_data(pip).to_wire].name));
|
ret.emplace_back(id("TO_TILE_WIRE"), nameOf(IdString(loc_data(pip).wires[pip_data(pip).to_wire].name)));
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -936,7 +936,7 @@ void Arch::lookup_cell_clock_out(int type_idx, IdString to_port, IdString &clock
|
|||||||
ct.prop_delays.get(), ct.prop_delays.size(), [](const CellPropDelayPOD &pd) { return pd.to_port; },
|
ct.prop_delays.get(), ct.prop_delays.size(), [](const CellPropDelayPOD &pd) { return pd.to_port; },
|
||||||
to_port.index);
|
to_port.index);
|
||||||
NPNR_ASSERT(dly_idx != -1);
|
NPNR_ASSERT(dly_idx != -1);
|
||||||
clock = ct.prop_delays[dly_idx].from_port;
|
clock = IdString(ct.prop_delays[dly_idx].from_port);
|
||||||
delay.min_delay = ct.prop_delays[dly_idx].min_delay;
|
delay.min_delay = ct.prop_delays[dly_idx].min_delay;
|
||||||
delay.max_delay = ct.prop_delays[dly_idx].max_delay;
|
delay.max_delay = ct.prop_delays[dly_idx].max_delay;
|
||||||
}
|
}
|
||||||
|
@ -1444,12 +1444,12 @@ struct Arch : BaseCtx
|
|||||||
IdString pip_src_wire_name(PipId pip) const
|
IdString pip_src_wire_name(PipId pip) const
|
||||||
{
|
{
|
||||||
int wire = pip_data(pip).from_wire;
|
int wire = pip_data(pip).from_wire;
|
||||||
return db->loctypes[chip_info->grid[pip.tile].loc_type].wires[wire].name;
|
return IdString(db->loctypes[chip_info->grid[pip.tile].loc_type].wires[wire].name);
|
||||||
}
|
}
|
||||||
IdString pip_dst_wire_name(PipId pip) const
|
IdString pip_dst_wire_name(PipId pip) const
|
||||||
{
|
{
|
||||||
int wire = pip_data(pip).to_wire;
|
int wire = pip_data(pip).to_wire;
|
||||||
return db->loctypes[chip_info->grid[pip.tile].loc_type].wires[wire].name;
|
return IdString(db->loctypes[chip_info->grid[pip.tile].loc_type].wires[wire].name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
|
@ -30,7 +30,7 @@ namespace PythonConversion {
|
|||||||
|
|
||||||
template <> struct string_converter<BelId>
|
template <> struct string_converter<BelId>
|
||||||
{
|
{
|
||||||
BelId from_str(Context *ctx, std::string name) { return ctx->getBelByName(ctx->id(name)); }
|
BelId from_str(Context *ctx, std::string name) { return ctx->getBelByName(IdStringList::parse(ctx, name)); }
|
||||||
|
|
||||||
std::string to_str(Context *ctx, BelId id)
|
std::string to_str(Context *ctx, BelId id)
|
||||||
{
|
{
|
||||||
@ -42,7 +42,7 @@ template <> struct string_converter<BelId>
|
|||||||
|
|
||||||
template <> struct string_converter<WireId>
|
template <> struct string_converter<WireId>
|
||||||
{
|
{
|
||||||
WireId from_str(Context *ctx, std::string name) { return ctx->getWireByName(ctx->id(name)); }
|
WireId from_str(Context *ctx, std::string name) { return ctx->getWireByName(IdStringList::parse(ctx, name)); }
|
||||||
|
|
||||||
std::string to_str(Context *ctx, WireId id)
|
std::string to_str(Context *ctx, WireId id)
|
||||||
{
|
{
|
||||||
@ -54,7 +54,7 @@ template <> struct string_converter<WireId>
|
|||||||
|
|
||||||
template <> struct string_converter<const WireId>
|
template <> struct string_converter<const WireId>
|
||||||
{
|
{
|
||||||
WireId from_str(Context *ctx, std::string name) { return ctx->getWireByName(ctx->id(name)); }
|
WireId from_str(Context *ctx, std::string name) { return ctx->getWireByName(IdStringList::parse(ctx, name)); }
|
||||||
|
|
||||||
std::string to_str(Context *ctx, WireId id)
|
std::string to_str(Context *ctx, WireId id)
|
||||||
{
|
{
|
||||||
@ -66,7 +66,7 @@ template <> struct string_converter<const WireId>
|
|||||||
|
|
||||||
template <> struct string_converter<PipId>
|
template <> struct string_converter<PipId>
|
||||||
{
|
{
|
||||||
PipId from_str(Context *ctx, std::string name) { return ctx->getPipByName(ctx->id(name)); }
|
PipId from_str(Context *ctx, std::string name) { return ctx->getPipByName(IdStringList::parse(ctx, name)); }
|
||||||
|
|
||||||
std::string to_str(Context *ctx, PipId id)
|
std::string to_str(Context *ctx, PipId id)
|
||||||
{
|
{
|
||||||
|
@ -144,7 +144,7 @@ struct NexusFasmWriter
|
|||||||
{
|
{
|
||||||
int r = loc / ctx->chip_info->width;
|
int r = loc / ctx->chip_info->width;
|
||||||
int c = loc % ctx->chip_info->width;
|
int c = loc % ctx->chip_info->width;
|
||||||
return stringf("%sR%dC%d__%s", ctx->nameOf(tile.prefix), r, c, ctx->nameOf(tile.tiletype));
|
return stringf("%sR%dC%d__%s", ctx->nameOf(IdString(tile.prefix)), r, c, ctx->nameOf(IdString(tile.tiletype)));
|
||||||
}
|
}
|
||||||
// Look up a tile by location index and tile type
|
// Look up a tile by location index and tile type
|
||||||
const PhysicalTileInfoPOD &tile_by_type_and_loc(int loc, IdString type)
|
const PhysicalTileInfoPOD &tile_by_type_and_loc(int loc, IdString type)
|
||||||
@ -180,7 +180,7 @@ struct NexusFasmWriter
|
|||||||
void push_tile(int loc, IdString tile_type) { push(tile_name(loc, tile_by_type_and_loc(loc, tile_type))); }
|
void push_tile(int loc, IdString tile_type) { push(tile_name(loc, tile_by_type_and_loc(loc, tile_type))); }
|
||||||
void push_tile(int loc) { push(tile_name(loc, tile_at_loc(loc))); }
|
void push_tile(int loc) { push(tile_name(loc, tile_at_loc(loc))); }
|
||||||
// Push a bel name onto the prefix stack
|
// Push a bel name onto the prefix stack
|
||||||
void push_belname(BelId bel) { push(ctx->nameOf(ctx->bel_data(bel).name)); }
|
void push_belname(BelId bel) { push(ctx->nameOf(IdString(ctx->bel_data(bel).name))); }
|
||||||
// Push the tile group name corresponding to a bel onto the prefix stack
|
// Push the tile group name corresponding to a bel onto the prefix stack
|
||||||
void push_belgroup(BelId bel)
|
void push_belgroup(BelId bel)
|
||||||
{
|
{
|
||||||
@ -189,14 +189,14 @@ struct NexusFasmWriter
|
|||||||
auto &bel_data = ctx->bel_data(bel);
|
auto &bel_data = ctx->bel_data(bel);
|
||||||
r += bel_data.rel_y;
|
r += bel_data.rel_y;
|
||||||
c += bel_data.rel_x;
|
c += bel_data.rel_x;
|
||||||
std::string s = stringf("R%dC%d_%s", r, c, ctx->nameOf(ctx->bel_data(bel).name));
|
std::string s = stringf("R%dC%d_%s", r, c, ctx->nameOf(IdString(ctx->bel_data(bel).name)));
|
||||||
push(s);
|
push(s);
|
||||||
}
|
}
|
||||||
// Push a bel's group and name
|
// Push a bel's group and name
|
||||||
void push_bel(BelId bel)
|
void push_bel(BelId bel)
|
||||||
{
|
{
|
||||||
push_belgroup(bel);
|
push_belgroup(bel);
|
||||||
fasm_ctx.back() += stringf(".%s", ctx->nameOf(ctx->bel_data(bel).name));
|
fasm_ctx.back() += stringf(".%s", ctx->nameOf(IdString(ctx->bel_data(bel).name)));
|
||||||
}
|
}
|
||||||
// Write out a pip in tile.dst.src format
|
// Write out a pip in tile.dst.src format
|
||||||
void write_pip(PipId pip)
|
void write_pip(PipId pip)
|
||||||
@ -204,7 +204,7 @@ struct NexusFasmWriter
|
|||||||
auto &pd = ctx->pip_data(pip);
|
auto &pd = ctx->pip_data(pip);
|
||||||
if (pd.flags & PIP_FIXED_CONN)
|
if (pd.flags & PIP_FIXED_CONN)
|
||||||
return;
|
return;
|
||||||
std::string tile = tile_name(pip.tile, tile_by_type_and_loc(pip.tile, pd.tile_type));
|
std::string tile = tile_name(pip.tile, tile_by_type_and_loc(pip.tile, IdString(pd.tile_type)));
|
||||||
std::string source_wire = escape_name(ctx->pip_src_wire_name(pip).str(ctx));
|
std::string source_wire = escape_name(ctx->pip_src_wire_name(pip).str(ctx));
|
||||||
std::string dest_wire = escape_name(ctx->pip_dst_wire_name(pip).str(ctx));
|
std::string dest_wire = escape_name(ctx->pip_dst_wire_name(pip).str(ctx));
|
||||||
out << stringf("%s.PIP.%s.%s", tile.c_str(), dest_wire.c_str(), source_wire.c_str()) << std::endl;
|
out << stringf("%s.PIP.%s.%s", tile.c_str(), dest_wire.c_str(), source_wire.c_str()) << std::endl;
|
||||||
@ -580,7 +580,7 @@ struct NexusFasmWriter
|
|||||||
write_enum(cell, "CLKMUX_FB");
|
write_enum(cell, "CLKMUX_FB");
|
||||||
write_cell_muxes(cell);
|
write_cell_muxes(cell);
|
||||||
pop();
|
pop();
|
||||||
push(stringf("IP_%s", ctx->nameOf(ctx->bel_data(bel).name)));
|
push(stringf("IP_%s", ctx->nameOf(IdString(ctx->bel_data(bel).name))));
|
||||||
for (auto param : sorted_cref(cell->params)) {
|
for (auto param : sorted_cref(cell->params)) {
|
||||||
const std::string &name = param.first.str(ctx);
|
const std::string &name = param.first.str(ctx);
|
||||||
if (is_mux_param(name) || name == "CLKMUX_FB" || name == "SEL_FBK")
|
if (is_mux_param(name) || name == "CLKMUX_FB" || name == "SEL_FBK")
|
||||||
|
@ -1283,7 +1283,7 @@ struct NexusPacker
|
|||||||
// Function to check if a wire is general routing; and therefore skipped for cascade purposes
|
// Function to check if a wire is general routing; and therefore skipped for cascade purposes
|
||||||
bool is_general_routing(WireId wire)
|
bool is_general_routing(WireId wire)
|
||||||
{
|
{
|
||||||
std::string name = ctx->nameOf(ctx->wire_data(wire).name);
|
std::string name = ctx->nameOf(IdString(ctx->wire_data(wire).name));
|
||||||
if (name.size() == 3 && (name.substr(0, 2) == "JF" || name.substr(0, 2) == "JQ"))
|
if (name.size() == 3 && (name.substr(0, 2) == "JF" || name.substr(0, 2) == "JQ"))
|
||||||
return true;
|
return true;
|
||||||
if (name.size() == 12 && (name.substr(0, 10) == "JCIBMUXOUT"))
|
if (name.size() == 12 && (name.substr(0, 10) == "JCIBMUXOUT"))
|
||||||
|
Loading…
Reference in New Issue
Block a user