aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ecp5/arch.cc76
-rw-r--r--ecp5/arch.h2
-rw-r--r--ecp5/arch_place.cc5
-rw-r--r--ecp5/bitstream.cc13
-rw-r--r--ecp5/cells.cc2
-rw-r--r--ecp5/cells.h6
-rw-r--r--ecp5/gfx.cc45
-rw-r--r--ecp5/globals.cc22
-rw-r--r--ecp5/pack.cc41
-rw-r--r--gowin/cells.cc5
-rw-r--r--gowin/gfx.cc2
-rw-r--r--gowin/globals.cc3
-rw-r--r--ice40/arch.cc36
-rw-r--r--ice40/arch_place.cc2
-rw-r--r--ice40/bitstream.cc3
-rw-r--r--ice40/cells.cc8
-rw-r--r--ice40/cells.h20
-rw-r--r--ice40/pack.cc8
-rw-r--r--mistral/globals.cc5
-rw-r--r--nexus/arch.cc37
-rw-r--r--nexus/arch.h2
-rw-r--r--nexus/fasm.cc7
-rw-r--r--nexus/global.cc2
-rw-r--r--nexus/pack.cc4
24 files changed, 153 insertions, 203 deletions
diff --git a/ecp5/arch.cc b/ecp5/arch.cc
index 0b763612..f031c904 100644
--- a/ecp5/arch.cc
+++ b/ecp5/arch.cc
@@ -557,8 +557,7 @@ ArcBounds Arch::getRouteBoundingBox(WireId src, WireId dst) const
delay_t Arch::predictDelay(BelId src_bel, IdString src_pin, BelId dst_bel, IdString dst_pin) const
{
- if ((src_pin == id_FCO && dst_pin == id_FCI) || dst_pin == id_FXA || dst_pin == id_FXB ||
- (src_pin == id_F && dst_pin == id_DI))
+ if ((src_pin == id_FCO && dst_pin == id_FCI) || dst_pin.in(id_FXA, id_FXB) || (src_pin == id_F && dst_pin == id_DI))
return 0;
auto driver_loc = getBelLocation(src_bel);
auto sink_loc = getBelLocation(dst_bel);
@@ -588,7 +587,7 @@ bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay
if (net_info->driver.port == id_FCO && sink.port == id_FCI) {
budget = 0;
return true;
- } else if (sink.port == id_FXA || sink.port == id_FXB) {
+ } else if (sink.port.in(id_FXA, id_FXB)) {
budget = 0;
return true;
} else {
@@ -819,8 +818,7 @@ bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort
IdString tmg_type = has_carry ? (((cell->constr_z >> Arch::lc_idx_shift) % 2) ? id_TRELLIS_COMB_CARRY1
: id_TRELLIS_COMB_CARRY0)
: id_TRELLIS_COMB;
- if (fromPort == id_A || fromPort == id_B || fromPort == id_C || fromPort == id_D || fromPort == id_M ||
- fromPort == id_F1 || fromPort == id_FXA || fromPort == id_FXB || fromPort == id_FCI)
+ if (fromPort.in(id_A, id_B, id_C, id_D, id_M, id_F1, id_FXA, id_FXB, id_FCI))
return get_delay_from_tmg_db(tmg_type, fromPort, toPort, delay);
else
return false;
@@ -842,7 +840,7 @@ bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort
}
return false;
} else if (cell->type == id_DCSC) {
- if ((fromPort == id_CLK0 || fromPort == id_CLK1) && toPort == id_DCSOUT) {
+ if ((fromPort.in(id_CLK0, id_CLK1)) && toPort == id_DCSOUT) {
delay = DelayQuad(0);
return true;
}
@@ -858,7 +856,7 @@ bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort
return get_delay_from_tmg_db(cell->multInfo.timing_id, id(std::string("") + fn.front()), id_P, delay);
}
return false;
- } else if (cell->type == id_IOLOGIC || cell->type == id_SIOLOGIC) {
+ } else if (cell->type.in(id_IOLOGIC, id_SIOLOGIC)) {
return false;
} else {
return false;
@@ -872,18 +870,16 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, in
if (cell->type == id_TRELLIS_COMB) {
if (port == id_WCK)
return TMG_CLOCK_INPUT;
- if (port == id_A || port == id_B || port == id_C || port == id_D || port == id_FCI || port == id_FXA ||
- port == id_FXB || port == id_F1)
+ if (port.in(id_A, id_B, id_C, id_D, id_FCI, id_FXA, id_FXB, id_F1))
return TMG_COMB_INPUT;
if (port == id_F && disconnected(id_A) && disconnected(id_B) && disconnected(id_C) && disconnected(id_D) &&
disconnected(id_FCI))
return TMG_IGNORE; // LUT with no inputs is a constant
- if (port == id_F || port == id_FCO || port == id_OFX)
+ if (port.in(id_F, id_FCO, id_OFX))
return TMG_COMB_OUTPUT;
if (port == id_M)
return TMG_COMB_INPUT;
- if (port == id_WD || port == id_WAD0 || port == id_WAD1 || port == id_WAD2 || port == id_WAD3 ||
- port == id_WRE) {
+ if (port.in(id_WD, id_WAD0, id_WAD1, id_WAD2, id_WAD3, id_WRE)) {
clockInfoCount = 1;
return TMG_REGISTER_INPUT;
}
@@ -892,7 +888,7 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, in
bool using_m = (cell->ffInfo.flags & ArchCellInfo::FF_M_USED);
if (port == id_CLK)
return TMG_CLOCK_INPUT;
- if (port == id_DI || (using_m && (port == id_M)) || port == id_CE || port == id_LSR) {
+ if (port == id_DI || (using_m && (port == id_M)) || port.in(id_CE, id_LSR)) {
clockInfoCount = 1;
return TMG_REGISTER_INPUT;
}
@@ -902,15 +898,13 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, in
}
return TMG_IGNORE;
} else if (cell->type == id_TRELLIS_RAMW) {
- if (port == id_A0 || port == id_A1 || port == id_B0 || port == id_B1 || port == id_C0 || port == id_C1 ||
- port == id_D0 || port == id_D1)
+ if (port.in(id_A0, id_A1, id_B0, id_B1, id_C0, id_C1, id_D0, id_D1))
return TMG_COMB_INPUT;
- if (port == id_WDO0 || port == id_WDO1 || port == id_WDO2 || port == id_WDO3 || port == id_WADO0 ||
- port == id_WADO1 || port == id_WADO2 || port == id_WADO3)
+ if (port.in(id_WDO0, id_WDO1, id_WDO2, id_WDO3, id_WADO0, id_WADO1, id_WADO2, id_WADO3))
return TMG_COMB_OUTPUT;
return TMG_IGNORE;
} else if (cell->type == id_TRELLIS_IO) {
- if (port == id_T || port == id_I)
+ if (port.in(id_T, id_I))
return TMG_ENDPOINT;
if (port == id_O)
return TMG_STARTPOINT;
@@ -922,13 +916,13 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, in
return TMG_COMB_OUTPUT;
return TMG_IGNORE;
} else if (cell->type == id_DCSC) {
- if (port == id_CLK0 || port == id_CLK1)
+ if (port.in(id_CLK0, id_CLK1))
return TMG_COMB_INPUT;
if (port == id_DCSOUT)
return TMG_COMB_OUTPUT;
return TMG_IGNORE;
} else if (cell->type == id_DP16KD) {
- if (port == id_CLKA || port == id_CLKB)
+ if (port.in(id_CLKA, id_CLKB))
return TMG_CLOCK_INPUT;
std::string port_name = port.str(this);
for (auto c : boost::adaptors::reverse(port_name)) {
@@ -942,10 +936,9 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, in
}
NPNR_ASSERT_FALSE_STR("no timing type for RAM port '" + port.str(this) + "'");
} else if (cell->type == id_MULT18X18D) {
- if (port == id_CLK0 || port == id_CLK1 || port == id_CLK2 || port == id_CLK3)
+ if (port.in(id_CLK0, id_CLK1, id_CLK2, id_CLK3))
return TMG_CLOCK_INPUT;
- if (port == id_CE0 || port == id_CE1 || port == id_CE2 || port == id_CE3 || port == id_RST0 ||
- port == id_RST1 || port == id_RST2 || port == id_RST3 || port == id_SIGNEDA || port == id_SIGNEDB) {
+ if (port.in(id_CE0, id_CE1, id_CE2, id_CE3, id_RST0, id_RST1, id_RST2, id_RST3, id_SIGNEDA, id_SIGNEDB)) {
if (cell->multInfo.is_clocked) {
clockInfoCount = 1;
return TMG_REGISTER_INPUT;
@@ -977,9 +970,8 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, in
return TMG_IGNORE; // FIXME
} else if (cell->type == id_EHXPLLL) {
return TMG_IGNORE;
- } else if (cell->type == id_DCUA || cell->type == id_EXTREFB || cell->type == id_PCSCLKDIV) {
- if (port == id_CH0_FF_TXI_CLK || port == id_CH0_FF_RXI_CLK || port == id_CH1_FF_TXI_CLK ||
- port == id_CH1_FF_RXI_CLK)
+ } else if (cell->type.in(id_DCUA, id_EXTREFB, id_PCSCLKDIV)) {
+ if (port.in(id_CH0_FF_TXI_CLK, id_CH0_FF_RXI_CLK, id_CH1_FF_TXI_CLK, id_CH1_FF_RXI_CLK))
return TMG_CLOCK_INPUT;
std::string prefix = port.str(this).substr(0, 9);
if (prefix == "CH0_FF_TX" || prefix == "CH0_FF_RX" || prefix == "CH1_FF_TX" || prefix == "CH1_FF_RX") {
@@ -987,18 +979,16 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, in
return (cell->ports.at(port).type == PORT_OUT) ? TMG_REGISTER_OUTPUT : TMG_REGISTER_INPUT;
}
return TMG_IGNORE;
- } else if (cell->type == id_IOLOGIC || cell->type == id_SIOLOGIC) {
- if (port == id_CLK || port == id_ECLK) {
+ } else if (cell->type.in(id_IOLOGIC, id_SIOLOGIC)) {
+ if (port.in(id_CLK, id_ECLK)) {
return TMG_CLOCK_INPUT;
- } else if (port == id_IOLDO || port == id_IOLDOI || port == id_IOLDOD || port == id_IOLTO || port == id_PADDI ||
- port == id_DQSR90 || port == id_DQSW || port == id_DQSW270) {
+ } else if (port.in(id_IOLDO, id_IOLDOI, id_IOLDOD, id_IOLTO, id_PADDI, id_DQSR90, id_DQSW, id_DQSW270)) {
return TMG_IGNORE;
} else {
clockInfoCount = 1;
return (cell->ports.at(port).type == PORT_OUT) ? TMG_REGISTER_OUTPUT : TMG_REGISTER_INPUT;
}
- } else if (cell->type == id_DTR || cell->type == id_USRMCLK || cell->type == id_SEDGA || cell->type == id_GSR ||
- cell->type == id_JTAGG) {
+ } else if (cell->type.in(id_DTR, id_USRMCLK, id_SEDGA, id_GSR, id_JTAGG)) {
return (cell->ports.at(port).type == PORT_OUT) ? TMG_STARTPOINT : TMG_ENDPOINT;
} else if (cell->type == id_OSCG) {
if (port == id_OSC)
@@ -1008,22 +998,22 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, in
} else if (cell->type == id_CLKDIVF) {
if (port == id_CLKI)
return TMG_CLOCK_INPUT;
- else if (port == id_RST || port == id_ALIGNWD)
+ else if (port.in(id_RST, id_ALIGNWD))
return TMG_ENDPOINT;
else if (port == id_CDIVX)
return TMG_GEN_CLOCK;
else
NPNR_ASSERT_FALSE("bad clkdiv port");
} else if (cell->type == id_DQSBUFM) {
- if (port == id_READ0 || port == id_READ1) {
+ if (port.in(id_READ0, id_READ1)) {
clockInfoCount = 1;
return TMG_REGISTER_INPUT;
} else if (port == id_DATAVALID) {
clockInfoCount = 1;
return TMG_REGISTER_OUTPUT;
- } else if (port == id_SCLK || port == id_ECLK || port == id_DQSI) {
+ } else if (port.in(id_SCLK, id_ECLK, id_DQSI)) {
return TMG_CLOCK_INPUT;
- } else if (port == id_DQSR90 || port == id_DQSW || port == id_DQSW270) {
+ } else if (port.in(id_DQSR90, id_DQSW, id_DQSW270)) {
return TMG_GEN_CLOCK;
}
return (cell->ports.at(port).type == PORT_OUT) ? TMG_STARTPOINT : TMG_ENDPOINT;
@@ -1054,8 +1044,7 @@ TimingClockingInfo Arch::getPortClockingInfo(const CellInfo *cell, IdString port
info.hold = DelayPair(0);
info.clockToQ = DelayQuad(0);
if (cell->type == id_TRELLIS_COMB) {
- if (port == id_WD || port == id_WAD0 || port == id_WAD1 || port == id_WAD2 || port == id_WAD3 ||
- port == id_WRE) {
+ if (port.in(id_WD, id_WAD0, id_WAD1, id_WAD2, id_WAD3, id_WRE)) {
if (port == id_WD)
port = id_WD0;
info.edge = (cell->combInfo.flags & ArchCellInfo::COMB_RAM_WCKINV) ? FALLING_EDGE : RISING_EDGE;
@@ -1064,7 +1053,7 @@ TimingClockingInfo Arch::getPortClockingInfo(const CellInfo *cell, IdString port
}
} else if (cell->type == id_TRELLIS_FF) {
bool using_m = (cell->ffInfo.flags & ArchCellInfo::FF_M_USED);
- if (port == id_DI || port == id_CE || port == id_LSR || (using_m && port == id_M)) {
+ if (port.in(id_DI, id_CE, id_LSR) || (using_m && port == id_M)) {
if (port == id_DI)
port = id_DI0;
if (port == id_M)
@@ -1098,9 +1087,8 @@ TimingClockingInfo Arch::getPortClockingInfo(const CellInfo *cell, IdString port
if (cell->ramInfo.is_pdp) {
bool is_output = cell->ports.at(port).type == PORT_OUT;
// In PDP mode, all read signals are in CLKB domain and write signals in CLKA domain
- if (is_output || port == id_OCEB || port == id_CEB || port == id_ADB5 || port == id_ADB6 ||
- port == id_ADB7 || port == id_ADB8 || port == id_ADB9 || port == id_ADB10 || port == id_ADB11 ||
- port == id_ADB12 || port == id_ADB13)
+ if (is_output || port.in(id_OCEB, id_CEB, id_ADB5, id_ADB6, id_ADB7, id_ADB8, id_ADB9, id_ADB10, id_ADB11,
+ id_ADB12, id_ADB13))
info.clock_port = id_CLKB;
else
info.clock_port = id_CLKA;
@@ -1133,7 +1121,7 @@ TimingClockingInfo Arch::getPortClockingInfo(const CellInfo *cell, IdString port
info.setup = DelayPair(getDelayFromNS(1));
info.hold = DelayPair(getDelayFromNS(0));
}
- } else if (cell->type == id_IOLOGIC || cell->type == id_SIOLOGIC) {
+ } else if (cell->type.in(id_IOLOGIC, id_SIOLOGIC)) {
info.clock_port = id_CLK;
info.edge = RISING_EDGE;
if (cell->ports.at(port).type == PORT_OUT) {
@@ -1147,7 +1135,7 @@ TimingClockingInfo Arch::getPortClockingInfo(const CellInfo *cell, IdString port
info.edge = RISING_EDGE;
if (port == id_DATAVALID) {
info.clockToQ = DelayQuad(getDelayFromNS(0.2));
- } else if (port == id_READ0 || port == id_READ1) {
+ } else if (port.in(id_READ0, id_READ1)) {
info.setup = DelayPair(getDelayFromNS(0.5));
info.hold = DelayPair(getDelayFromNS(-0.4));
} else {
diff --git a/ecp5/arch.h b/ecp5/arch.h
index 3d95fc9b..12f043b7 100644
--- a/ecp5/arch.h
+++ b/ecp5/arch.h
@@ -565,7 +565,7 @@ struct Arch : BaseArch<ArchRanges>
void update_bel(BelId bel, CellInfo *old_cell, CellInfo *new_cell)
{
CellInfo *act_cell = (old_cell == nullptr) ? new_cell : old_cell;
- if (act_cell->type == id_TRELLIS_FF || act_cell->type == id_TRELLIS_COMB || act_cell->type == id_TRELLIS_RAMW) {
+ if (act_cell->type.in(id_TRELLIS_FF, id_TRELLIS_COMB, id_TRELLIS_RAMW)) {
LogicTileStatus *lts = tile_status.at(tile_index(bel)).lts;
NPNR_ASSERT(lts != nullptr);
int z = loc_info(bel)->bel_data[bel.index].z;
diff --git a/ecp5/arch_place.cc b/ecp5/arch_place.cc
index afe9aca0..fed9c055 100644
--- a/ecp5/arch_place.cc
+++ b/ecp5/arch_place.cc
@@ -187,7 +187,7 @@ bool Arch::isBelLocationValid(BelId bel) const
CellInfo *cell = getBoundBelCell(bel);
if (cell == nullptr) {
return true;
- } else if (cell->type == id_DCUA || cell->type == id_EXTREFB || cell->type == id_PCSCLKDIV) {
+ } else if (cell->type.in(id_DCUA, id_EXTREFB, id_PCSCLKDIV)) {
return args.type != ArchArgs::LFE5U_25F && args.type != ArchArgs::LFE5U_45F &&
args.type != ArchArgs::LFE5U_85F;
} else {
@@ -203,8 +203,7 @@ void Arch::setup_wire_locations()
CellInfo *ci = cell.second.get();
if (ci->bel == BelId())
continue;
- if (ci->type == id_MULT18X18D || ci->type == id_DCUA || ci->type == id_DDRDLL || ci->type == id_DQSBUFM ||
- ci->type == id_EHXPLLL) {
+ if (ci->type.in(id_MULT18X18D, id_DCUA, id_DDRDLL, id_DQSBUFM, id_EHXPLLL)) {
for (auto &port : ci->ports) {
if (port.second.net == nullptr)
continue;
diff --git a/ecp5/bitstream.cc b/ecp5/bitstream.cc
index 3c01fe71..37883bda 100644
--- a/ecp5/bitstream.cc
+++ b/ecp5/bitstream.cc
@@ -1110,25 +1110,22 @@ void write_bitstream(Context *ctx, std::string base_config_file, std::string tex
// Tie signals as appropriate
for (auto port : ci->ports) {
- if (ci->ramInfo.is_pdp && (port.first == id_WEA || port.first == id_WEB || port.first == id_ADA4))
+ if (ci->ramInfo.is_pdp && (port.first.in(id_WEA, id_WEB, id_ADA4)))
continue;
if (port.second.net == nullptr && port.second.type == PORT_IN) {
- if (port.first == id_CLKA || port.first == id_CLKB || port.first == id_WEA ||
- port.first == id_WEB || port.first == id_RSTA || port.first == id_RSTB) {
+ if (port.first.in(id_CLKA, id_CLKB, id_WEA, id_WEB, id_RSTA, id_RSTB)) {
// CIB clock or LSR. Tie to "1" (also 0 in prjtrellis db?) in CIB
// If MUX doesn't exist, set to INV to emulate default 0
tie_cib_signal(ctx, cc, ctx->getBelPinWire(ci->bel, port.first), true);
if (!ci->params.count(ctx->id(port.first.str(ctx) + "MUX")))
ci->params[ctx->id(port.first.str(ctx) + "MUX")] = std::string("INV");
- } else if (port.first == id_CEA || port.first == id_CEB || port.first == id_OCEA ||
- port.first == id_OCEB) {
+ } else if (port.first.in(id_CEA, id_CEB, id_OCEA, id_OCEB)) {
// CIB CE. Tie to "1" in CIB
// If MUX doesn't exist, set to passthru to emulate default 1
tie_cib_signal(ctx, cc, ctx->getBelPinWire(ci->bel, port.first), true);
if (!ci->params.count(ctx->id(port.first.str(ctx) + "MUX")))
ci->params[ctx->id(port.first.str(ctx) + "MUX")] = port.first.str(ctx);
- } else if (port.first == id_CSA0 || port.first == id_CSA1 || port.first == id_CSA2 ||
- port.first == id_CSB0 || port.first == id_CSB1 || port.first == id_CSB2) {
+ } else if (port.first.in(id_CSA0, id_CSA1, id_CSA2, id_CSB0, id_CSB1, id_CSB2)) {
// CIB CE. Tie to "1" in CIB.
// If MUX doesn't exist, set to INV to emulate default 0
tie_cib_signal(ctx, cc, ctx->getBelPinWire(ci->bel, port.first), true);
@@ -1392,7 +1389,7 @@ void write_bitstream(Context *ctx, std::string base_config_file, std::string tex
int_to_bitvector(int_or_default(ci->attrs, id_MFG_ENABLE_FILTEROPAMP, 0), 1));
cc.tilegroups.push_back(tg);
- } else if (ci->type == id_IOLOGIC || ci->type == id_SIOLOGIC) {
+ } else if (ci->type.in(id_IOLOGIC, id_SIOLOGIC)) {
Loc pio_loc = ctx->getBelLocation(ci->bel);
pio_loc.z -= ci->type == id_SIOLOGIC ? 2 : 4;
std::string pic_tile = get_pic_tile(ctx, ctx->getBelByLocation(pio_loc));
diff --git a/ecp5/cells.cc b/ecp5/cells.cc
index 99f672a6..23d4b855 100644
--- a/ecp5/cells.cc
+++ b/ecp5/cells.cc
@@ -133,7 +133,7 @@ std::unique_ptr<CellInfo> create_ecp5_cell(Context *ctx, IdString type, std::str
new_cell->addInput(id_CLKI);
new_cell->addOutput(id_CLKO);
new_cell->addInput(id_CE);
- } else if (type == id_IOLOGIC || type == id_SIOLOGIC) {
+ } else if (type.in(id_IOLOGIC, id_SIOLOGIC)) {
new_cell->params[id_MODE] = std::string("NONE");
new_cell->params[id_GSR] = std::string("DISABLED");
new_cell->params[id_CLKIMUX] = std::string("CLK");
diff --git a/ecp5/cells.h b/ecp5/cells.h
index 185b19ce..c79bf8cd 100644
--- a/ecp5/cells.h
+++ b/ecp5/cells.h
@@ -47,15 +47,13 @@ inline bool is_l6mux(const BaseCtx *ctx, const CellInfo *cell) { return cell->ty
inline bool is_iologic_input_cell(const BaseCtx *ctx, const CellInfo *cell)
{
- return cell->type == id_IDDRX1F || cell->type == id_IDDRX2F || cell->type == id_IDDR71B ||
- cell->type == id_IDDRX2DQA ||
+ return cell->type.in(id_IDDRX1F, id_IDDRX2F, id_IDDR71B, id_IDDRX2DQA) ||
(cell->type == id_TRELLIS_FF && bool_or_default(cell->attrs, id_syn_useioff) &&
(str_or_default(cell->attrs, id_ioff_dir, "") != "output"));
}
inline bool is_iologic_output_cell(const BaseCtx *ctx, const CellInfo *cell)
{
- return cell->type == id_ODDRX1F || cell->type == id_ODDRX2F || cell->type == id_ODDR71B ||
- cell->type == id_ODDRX2DQA || cell->type == id_ODDRX2DQSB || cell->type == id_OSHX2A ||
+ return cell->type.in(id_ODDRX1F, id_ODDRX2F, id_ODDR71B, id_ODDRX2DQA, id_ODDRX2DQSB, id_OSHX2A) ||
(cell->type == id_TRELLIS_FF && bool_or_default(cell->attrs, id_syn_useioff) &&
(str_or_default(cell->attrs, id_ioff_dir, "") != "input"));
}
diff --git a/ecp5/gfx.cc b/ecp5/gfx.cc
index fe206de0..b1f3d4dd 100644
--- a/ecp5/gfx.cc
+++ b/ecp5/gfx.cc
@@ -84,8 +84,7 @@ void gfxTileBel(std::vector<GraphicElement> &g, int x, int y, int z, int w, int
3 * slice_pitch - 0.0007f;
el.y2 = el.y1 + wire_distance * 5;
g.push_back(el);
- } else if (bel_type == id_TRELLIS_IO || bel_type == id_IOLOGIC || bel_type == id_SIOLOGIC ||
- bel_type == id_DQSBUFM) {
+ } else if (bel_type.in(id_TRELLIS_IO, id_IOLOGIC, id_SIOLOGIC, id_DQSBUFM)) {
bool top_bottom = (y == 0 || y == (h - 1));
if (top_bottom) {
el.x1 = x + io_cell_h_x1 + (z + 2) * io_cell_gap;
@@ -115,7 +114,7 @@ void gfxTileBel(std::vector<GraphicElement> &g, int x, int y, int z, int w, int
el.x2 = x + switchbox_x1 + (z)*0.025 + 0.020;
el.y2 = y + 0.18;
g.push_back(el);
- } else if (bel_type == id_DP16KD || bel_type == id_MULT18X18D || bel_type == id_ALU54B) {
+ } else if (bel_type.in(id_DP16KD, id_MULT18X18D, id_ALU54B)) {
el.x1 = x + slice_x1;
el.x2 = x + slice_x2_wide;
el.y1 = y + slice_y1 - 1 * slice_pitch;
@@ -133,8 +132,7 @@ void gfxTileBel(std::vector<GraphicElement> &g, int x, int y, int z, int w, int
el.y1 = y + slice_y2;
el.y2 = y + 0.25;
g.push_back(el);
- } else if (bel_type == id_EXTREFB || bel_type == id_PCSCLKDIV || bel_type == id_DTR || bel_type == id_USRMCLK ||
- bel_type == id_SEDGA || bel_type == id_GSR || bel_type == id_JTAGG || bel_type == id_OSCG) {
+ } else if (bel_type.in(id_EXTREFB, id_PCSCLKDIV, id_DTR, id_USRMCLK, id_SEDGA, id_GSR, id_JTAGG, id_OSCG)) {
el.x1 = x + slice_x1;
el.x2 = x + slice_x2_wide;
el.y1 = y + slice_y1 + (z)*slice_pitch;
@@ -146,8 +144,7 @@ void gfxTileBel(std::vector<GraphicElement> &g, int x, int y, int z, int w, int
el.y1 = y + dll_cell_y1;
el.y2 = y + dll_cell_y2;
g.push_back(el);
- } else if (bel_type == id_DLLDELD || bel_type == id_CLKDIVF || bel_type == id_ECLKSYNCB ||
- bel_type == id_TRELLIS_ECLKBUF || bel_type == id_ECLKBRIDGECS) {
+ } else if (bel_type.in(id_DLLDELD, id_CLKDIVF, id_ECLKSYNCB, id_TRELLIS_ECLKBUF, id_ECLKBRIDGECS)) {
el.x1 = x + 0.1 + z * 0.05;
el.x2 = x + 0.14 + z * 0.05;
el.y1 = y + 0.475;
@@ -1455,15 +1452,13 @@ void gfxTilePip(std::vector<GraphicElement> &g, int x, int y, int w, int h, Wire
dst_id - TILE_WIRE_JCE0);
}
- if ((src_type == id_WIRE_TYPE_H02 || src_type == id_WIRE_TYPE_V00 || src_type == id_WIRE_TYPE_V01 ||
- src_type == id_WIRE_TYPE_V02) &&
+ if ((src_type.in(id_WIRE_TYPE_H02, id_WIRE_TYPE_V00, id_WIRE_TYPE_V01, id_WIRE_TYPE_V02)) &&
dst_type == id_WIRE_TYPE_NONE &&
((dst_id >= TILE_WIRE_FCO && dst_id <= TILE_WIRE_FCI) ||
(dst_id >= TILE_WIRE_JCE0 && dst_id <= TILE_WIRE_JQ7))) {
straightLine(g, el, x, y, w, h, src, src_type, src_id, dst, dst_type, dst_id);
}
- if ((dst_type == id_WIRE_TYPE_H02 || dst_type == id_WIRE_TYPE_V00 || dst_type == id_WIRE_TYPE_V01 ||
- dst_type == id_WIRE_TYPE_V02) &&
+ if ((dst_type.in(id_WIRE_TYPE_H02, id_WIRE_TYPE_V00, id_WIRE_TYPE_V01, id_WIRE_TYPE_V02)) &&
src_type == id_WIRE_TYPE_NONE &&
((src_id >= TILE_WIRE_FCO && src_id <= TILE_WIRE_FCI) ||
(src_id >= TILE_WIRE_JCE0 && src_id <= TILE_WIRE_JQ7))) {
@@ -1480,33 +1475,27 @@ void gfxTilePip(std::vector<GraphicElement> &g, int x, int y, int w, int h, Wire
}
if (src_type == id_WIRE_TYPE_NONE &&
- (dst_type == id_WIRE_TYPE_PLL || dst_type == id_WIRE_TYPE_GSR || dst_type == id_WIRE_TYPE_JTAG ||
- dst_type == id_WIRE_TYPE_OSC || dst_type == id_WIRE_TYPE_SED || dst_type == id_WIRE_TYPE_DTR ||
- dst_type == id_WIRE_TYPE_EXTREF || dst_type == id_WIRE_TYPE_DCU || dst_type == id_WIRE_TYPE_PCSCLKDIV ||
- dst_type == id_WIRE_TYPE_DDRDLL || dst_type == id_WIRE_TYPE_CCLK || dst_type == id_WIRE_TYPE_DQS ||
- dst_type == id_WIRE_TYPE_IOLOGIC || dst_type == id_WIRE_TYPE_SIOLOGIC || dst_type == id_WIRE_TYPE_EBR ||
- dst_type == id_WIRE_TYPE_MULT18 || dst_type == id_WIRE_TYPE_ALU54) &&
+ (dst_type.in(id_WIRE_TYPE_PLL, id_WIRE_TYPE_GSR, id_WIRE_TYPE_JTAG, id_WIRE_TYPE_OSC, id_WIRE_TYPE_SED,
+ id_WIRE_TYPE_DTR, id_WIRE_TYPE_EXTREF, id_WIRE_TYPE_DCU, id_WIRE_TYPE_PCSCLKDIV,
+ id_WIRE_TYPE_DDRDLL, id_WIRE_TYPE_CCLK, id_WIRE_TYPE_DQS, id_WIRE_TYPE_IOLOGIC,
+ id_WIRE_TYPE_SIOLOGIC, id_WIRE_TYPE_EBR, id_WIRE_TYPE_MULT18, id_WIRE_TYPE_ALU54)) &&
(src_id >= TILE_WIRE_JCE0 && src_id <= TILE_WIRE_JQ7)) {
straightLine(g, el, x, y, w, h, src, src_type, src_id, dst, dst_type, dst_id);
}
if (dst_type == id_WIRE_TYPE_NONE &&
- (src_type == id_WIRE_TYPE_PLL || src_type == id_WIRE_TYPE_GSR || src_type == id_WIRE_TYPE_JTAG ||
- src_type == id_WIRE_TYPE_OSC || src_type == id_WIRE_TYPE_SED || src_type == id_WIRE_TYPE_DTR ||
- src_type == id_WIRE_TYPE_EXTREF || src_type == id_WIRE_TYPE_DCU || src_type == id_WIRE_TYPE_PCSCLKDIV ||
- src_type == id_WIRE_TYPE_DDRDLL || src_type == id_WIRE_TYPE_CCLK || src_type == id_WIRE_TYPE_DQS ||
- src_type == id_WIRE_TYPE_IOLOGIC || src_type == id_WIRE_TYPE_SIOLOGIC || src_type == id_WIRE_TYPE_EBR ||
- src_type == id_WIRE_TYPE_MULT18 || src_type == id_WIRE_TYPE_ALU54) &&
+ (src_type.in(id_WIRE_TYPE_PLL, id_WIRE_TYPE_GSR, id_WIRE_TYPE_JTAG, id_WIRE_TYPE_OSC, id_WIRE_TYPE_SED,
+ id_WIRE_TYPE_DTR, id_WIRE_TYPE_EXTREF, id_WIRE_TYPE_DCU, id_WIRE_TYPE_PCSCLKDIV,
+ id_WIRE_TYPE_DDRDLL, id_WIRE_TYPE_CCLK, id_WIRE_TYPE_DQS, id_WIRE_TYPE_IOLOGIC,
+ id_WIRE_TYPE_SIOLOGIC, id_WIRE_TYPE_EBR, id_WIRE_TYPE_MULT18, id_WIRE_TYPE_ALU54)) &&
(dst_id >= TILE_WIRE_JCE0 && dst_id <= TILE_WIRE_JQ7)) {
straightLine(g, el, x, y, w, h, src, src_type, src_id, dst, dst_type, dst_id);
}
- if (src_type == id_WIRE_TYPE_NONE &&
- (dst_type == id_WIRE_TYPE_IOLOGIC || dst_type == id_WIRE_TYPE_SIOLOGIC || dst_type == id_WIRE_TYPE_PIO) &&
+ if (src_type == id_WIRE_TYPE_NONE && (dst_type.in(id_WIRE_TYPE_IOLOGIC, id_WIRE_TYPE_SIOLOGIC, id_WIRE_TYPE_PIO)) &&
(src_id >= TILE_WIRE_JDIA && src_id <= TILE_WIRE_ECLKD)) {
straightLine(g, el, x, y, w, h, src, src_type, src_id, dst, dst_type, dst_id);
}
- if (dst_type == id_WIRE_TYPE_NONE &&
- (src_type == id_WIRE_TYPE_IOLOGIC || src_type == id_WIRE_TYPE_SIOLOGIC || src_type == id_WIRE_TYPE_PIO) &&
+ if (dst_type == id_WIRE_TYPE_NONE && (src_type.in(id_WIRE_TYPE_IOLOGIC, id_WIRE_TYPE_SIOLOGIC, id_WIRE_TYPE_PIO)) &&
(dst_id >= TILE_WIRE_JDIA && dst_id <= TILE_WIRE_ECLKD)) {
straightLine(g, el, x, y, w, h, src, src_type, src_id, dst, dst_type, dst_id);
}
@@ -1526,7 +1515,7 @@ void gfxTilePip(std::vector<GraphicElement> &g, int x, int y, int w, int h, Wire
(dst_id >= TILE_WIRE_CLK0 && dst_id <= TILE_WIRE_FCI))) {
straightLine(g, el, x, y, w, h, src, src_type, src_id, dst, dst_type, dst_id);
}
- if ((dst_type == id_WIRE_TYPE_H01 || dst_type == id_WIRE_TYPE_V01) && src_type == id_WIRE_TYPE_G_HPBX) {
+ if ((dst_type.in(id_WIRE_TYPE_H01, id_WIRE_TYPE_V01)) && src_type == id_WIRE_TYPE_G_HPBX) {
straightLine(g, el, x, y, w, h, src, src_type, src_id, dst, dst_type, dst_id);
}
}
diff --git a/ecp5/globals.cc b/ecp5/globals.cc
index 7123705a..6c7ffba0 100644
--- a/ecp5/globals.cc
+++ b/ecp5/globals.cc
@@ -57,10 +57,10 @@ class Ecp5GlobalRouter
return true;
if (user.cell->type == id_TRELLIS_COMB && user.port == id_WCK)
return true;
- if (user.cell->type == id_DCUA && (user.port == id_CH0_FF_RXI_CLK || user.port == id_CH1_FF_RXI_CLK ||
- user.port == id_CH0_FF_TXI_CLK || user.port == id_CH1_FF_TXI_CLK))
+ if (user.cell->type == id_DCUA &&
+ (user.port.in(id_CH0_FF_RXI_CLK, id_CH1_FF_RXI_CLK, id_CH0_FF_TXI_CLK, id_CH1_FF_TXI_CLK)))
return true;
- if ((user.cell->type == id_IOLOGIC || user.cell->type == id_SIOLOGIC) && (user.port == id_CLK))
+ if ((user.cell->type.in(id_IOLOGIC, id_SIOLOGIC)) && (user.port == id_CLK))
return true;
return false;
}
@@ -88,7 +88,7 @@ class Ecp5GlobalRouter
clockCount[ni->name]++;
if (user.cell->type == id_DCUA)
clockCount[ni->name] += 100;
- if (user.cell->type == id_IOLOGIC || user.cell->type == id_SIOLOGIC)
+ if (user.cell->type.in(id_IOLOGIC, id_SIOLOGIC))
clockCount[ni->name] += 10;
}
}
@@ -282,7 +282,7 @@ class Ecp5GlobalRouter
bool route_onto_global(NetInfo *net, int network)
{
WireId glb_src;
- NPNR_ASSERT(net->driver.cell->type == id_DCCA || net->driver.cell->type == id_DCSC);
+ NPNR_ASSERT(net->driver.cell->type.in(id_DCCA, id_DCSC));
glb_src = ctx->getNetinfoSourceWire(net);
for (int quad = QUAD_UL; quad < QUAD_LR + 1; quad++) {
WireId glb_dst = get_global_wire(GlobalQuadrant(quad), network);
@@ -454,7 +454,7 @@ class Ecp5GlobalRouter
{
NetInfo *glbptr = nullptr;
CellInfo *dccptr = nullptr;
- if (net->driver.cell != nullptr && (net->driver.cell->type == id_DCCA || net->driver.cell->type == id_DCSC)) {
+ if (net->driver.cell != nullptr && (net->driver.cell->type.in(id_DCCA, id_DCSC))) {
// Already have a DCC (such as clock gating)
glbptr = net;
dccptr = net->driver.cell;
@@ -502,7 +502,7 @@ class Ecp5GlobalRouter
int global_route_priority(const PortRef &load)
{
- if (load.port == id_WCK || load.port == id_WRE)
+ if (load.port.in(id_WCK, id_WRE))
return 90;
return 99;
}
@@ -555,7 +555,7 @@ class Ecp5GlobalRouter
dict<int, NetInfo *> clocks;
for (auto &cell : ctx->cells) {
CellInfo *ci = cell.second.get();
- if (ci->type == id_DCCA || ci->type == id_DCSC) {
+ if (ci->type.in(id_DCCA, id_DCSC)) {
NetInfo *clock = ci->ports.at((ci->type == id_DCSC) ? id_DCSOUT : id_CLKO).net;
NPNR_ASSERT(clock != nullptr);
bool drives_fabric = false;
@@ -591,7 +591,7 @@ class Ecp5GlobalRouter
return global_route_priority(*a.first) < global_route_priority(*b.first);
});
for (const auto &user : toroute) {
- if (user.first->cell->type == id_DCSC && (user.first->port == id_CLK0 || user.first->port == id_CLK1)) {
+ if (user.first->cell->type == id_DCSC && (user.first->port.in(id_CLK0, id_CLK1))) {
// Special case, skips most of the typical global network
NetInfo *net = clocks.at(user.second);
simple_router(net, ctx->getNetinfoSourceWire(net), ctx->getNetinfoSinkWire(net, *(user.first), 0));
@@ -606,9 +606,9 @@ class Ecp5GlobalRouter
// Try and use dedicated paths if possible
for (auto &cell : ctx->cells) {
CellInfo *ci = cell.second.get();
- if (ci->type == id_ECLKSYNCB || ci->type == id_TRELLIS_ECLKBUF || ci->type == id_ECLKBRIDGECS) {
+ if (ci->type.in(id_ECLKSYNCB, id_TRELLIS_ECLKBUF, id_ECLKBRIDGECS)) {
std::vector<IdString> pins;
- if (ci->type == id_ECLKSYNCB || ci->type == id_TRELLIS_ECLKBUF) {
+ if (ci->type.in(id_ECLKSYNCB, id_TRELLIS_ECLKBUF)) {
pins.push_back(id_ECLKI);
} else {
pins.push_back(id_CLK0);
diff --git a/ecp5/pack.cc b/ecp5/pack.cc
index 4cd33dee..4c8ceee8 100644
--- a/ecp5/pack.cc
+++ b/ecp5/pack.cc
@@ -266,11 +266,10 @@ class Ecp5Packer
if (port.cell == nullptr)
return false;
if (port.cell->type == id_DCUA) {
- return port.port == id_CH0_HDINP || port.port == id_CH0_HDINN || port.port == id_CH0_HDOUTP ||
- port.port == id_CH0_HDOUTN || port.port == id_CH1_HDINP || port.port == id_CH1_HDINN ||
- port.port == id_CH1_HDOUTP || port.port == id_CH1_HDOUTN;
+ return port.port.in(id_CH0_HDINP, id_CH0_HDINN, id_CH0_HDOUTP, id_CH0_HDOUTN, id_CH1_HDINP, id_CH1_HDINN,
+ id_CH1_HDOUTP, id_CH1_HDOUTN);
} else if (port.cell->type == id_EXTREFB) {
- return port.port == id_REFCLKP || port.port == id_REFCLKN;
+ return port.port.in(id_REFCLKP, id_REFCLKN);
} else {
return false;
}
@@ -905,13 +904,11 @@ class Ecp5Packer
uc->params[id_CEMUX] = std::string(constval ? "1" : "0");
uc->ports[user.port].net = nullptr;
} else if (is_carry(ctx, uc)) {
- if (constval &&
- (user.port == id_A0 || user.port == id_A1 || user.port == id_B0 || user.port == id_B1 ||
- user.port == id_C0 || user.port == id_C1 || user.port == id_D0 || user.port == id_D1)) {
+ if (constval && (user.port.in(id_A0, id_A1, id_B0, id_B1, id_C0, id_C1, id_D0, id_D1))) {
// Input tied high, nothing special to do (bitstream gen will auto-enable tie-high)
uc->ports[user.port].net = nullptr;
} else if (!constval) {
- if (user.port == id_A0 || user.port == id_A1 || user.port == id_B0 || user.port == id_B1) {
+ if (user.port.in(id_A0, id_A1, id_B0, id_B1)) {
// These inputs can be switched to tie-high without consequence
set_ccu2c_input_constant(uc, user.port, constval);
} else if (user.port == id_C0 && is_ccu2c_port_high(uc, id_D0)) {
@@ -940,10 +937,8 @@ class Ecp5Packer
(constval && str_or_default(uc->params, id_LSRMUX, "LSR") == "INV"))) {
uc->ports[user.port].net = nullptr;
} else if (uc->type == id_DP16KD) {
- if (user.port == id_CLKA || user.port == id_CLKB || user.port == id_RSTA || user.port == id_RSTB ||
- user.port == id_WEA || user.port == id_WEB || user.port == id_CEA || user.port == id_CEB ||
- user.port == id_OCEA || user.port == id_OCEB || user.port == id_CSA0 || user.port == id_CSA1 ||
- user.port == id_CSA2 || user.port == id_CSB0 || user.port == id_CSB1 || user.port == id_CSB2) {
+ if (user.port.in(id_CLKA, id_CLKB, id_RSTA, id_RSTB, id_WEA, id_WEB, id_CEA, id_CEB, id_OCEA,
+ id_OCEB, id_CSA0, id_CSA1, id_CSA2, id_CSB0, id_CSB1, id_CSB2)) {
// Connect to CIB CLK, LSR or CE. Default state is 1
uc->params[ctx->id(user.port.str(ctx) + "MUX")] = constval ? user.port.str(ctx) : "INV";
} else {
@@ -951,7 +946,7 @@ class Ecp5Packer
uc->params[ctx->id(user.port.str(ctx) + "MUX")] = std::string(constval ? "1" : "0");
}
uc->ports[user.port].net = nullptr;
- } else if (uc->type == id_ALU54B || uc->type == id_MULT18X18D) {
+ } else if (uc->type.in(id_ALU54B, id_MULT18X18D)) {
if (user.port.str(ctx).substr(0, 3) == "CLK" || user.port.str(ctx).substr(0, 2) == "CE" ||
user.port.str(ctx).substr(0, 3) == "RST" || user.port.str(ctx).substr(0, 3) == "SRO" ||
user.port.str(ctx).substr(0, 3) == "SRI" || user.port.str(ctx).substr(0, 2) == "RO" ||
@@ -1350,7 +1345,7 @@ class Ecp5Packer
if (net == nullptr || net->driver.cell == nullptr)
continue;
IdString ct = net->driver.cell->type;
- if (ct == id_GND || ct == id_VCC) {
+ if (ct.in(id_GND, id_VCC)) {
ci->disconnectPort(ndport);
ci->ports.erase(ndport);
}
@@ -1442,7 +1437,7 @@ class Ecp5Packer
ci->renamePort(id_USRMCLKI, id_PADDO);
ci->renamePort(id_USRMCLKTS, id_PADDT);
ci->renamePort(id_USRMCLKO, id_PADDI);
- } else if (ci->type == id_GSR || ci->type == id_SGSR) {
+ } else if (ci->type.in(id_GSR, id_SGSR)) {
ci->params[id_MODE] = std::string("ACTIVE_LOW");
ci->params[id_SYNCMODE] = ci->type == id_SGSR ? std::string("SYNC") : std::string("ASYNC");
ci->type = id_GSR;
@@ -1894,7 +1889,7 @@ class Ecp5Packer
for (auto &cell : ctx->cells) {
CellInfo *ci = cell.second.get();
- if (ci->type == id_DELAYF || ci->type == id_DELAYG) {
+ if (ci->type.in(id_DELAYF, id_DELAYG)) {
CellInfo *i_pio = net_driven_by(ctx, ci->ports.at(id_A).net, is_trellis_io, id_O);
CellInfo *o_pio = net_only_drives(ctx, ci->ports.at(id_Z).net, is_trellis_io, id_I, true);
CellInfo *iol = nullptr;
@@ -2021,7 +2016,7 @@ class Ecp5Packer
ci->movePortTo(id_D1, iol, id_TXDATA1);
iol->params[id_GSR] = str_or_default(ci->params, id_GSR, "DISABLED");
packed_cells.insert(cell.first);
- } else if (ci->type == id_ODDRX2F || ci->type == id_ODDR71B) {
+ } else if (ci->type.in(id_ODDRX2F, id_ODDR71B)) {
CellInfo *pio = net_only_drives(ctx, ci->ports.at(id_Q).net, is_trellis_io, id_I, true);
if (pio == nullptr)
log_error("%s '%s' Q output must be connected only to a top level output\n", ci->type.c_str(ctx),
@@ -2061,7 +2056,7 @@ class Ecp5Packer
iol->params[id_GSR] = str_or_default(ci->params, id_GSR, "DISABLED");
pio->params[id_DATAMUX_ODDR] = std::string("IOLDO");
packed_cells.insert(cell.first);
- } else if (ci->type == id_IDDRX2F || ci->type == id_IDDR71B) {
+ } else if (ci->type.in(id_IDDRX2F, id_IDDR71B)) {
CellInfo *pio = net_driven_by(ctx, ci->ports.at(id_D).net, is_trellis_io, id_O);
if (pio == nullptr || ci->ports.at(id_D).net->users.entries() > 1)
log_error("%s '%s' D input must be connected only to a top level input\n", ci->type.c_str(ctx),
@@ -2121,7 +2116,7 @@ class Ecp5Packer
iol->params[ctx->id("MODDRX.MODE")] = std::string("MOSHX2");
pio->params[id_DATAMUX_MDDR] = std::string("IOLDO");
packed_cells.insert(cell.first);
- } else if (ci->type == id_ODDRX2DQA || ci->type == id_ODDRX2DQSB) {
+ } else if (ci->type.in(id_ODDRX2DQA, id_ODDRX2DQSB)) {
CellInfo *pio = net_only_drives(ctx, ci->ports.at(id_Q).net, is_trellis_io, id_I, true);
if (pio == nullptr)
log_error("%s '%s' Q output must be connected only to a top level output\n", ci->type.c_str(ctx),
@@ -2183,7 +2178,7 @@ class Ecp5Packer
process_dqs_port(ci, pio, iol, id_WRPNTR1);
process_dqs_port(ci, pio, iol, id_WRPNTR0);
packed_cells.insert(cell.first);
- } else if (ci->type == id_TSHX2DQA || ci->type == id_TSHX2DQSA) {
+ } else if (ci->type.in(id_TSHX2DQA, id_TSHX2DQSA)) {
CellInfo *pio = net_only_drives(ctx, ci->ports.at(id_Q).net, is_trellis_io, id_T, true);
if (pio == nullptr)
log_error("%s '%s' Q output must be connected only to a top level tristate\n", ci->type.c_str(ctx),
@@ -2388,7 +2383,7 @@ class Ecp5Packer
// Promote/route edge clocks
for (auto &cell : ctx->cells) {
CellInfo *ci = cell.second.get();
- if (ci->type == id_IOLOGIC || ci->type == id_DQSBUFM) {
+ if (ci->type.in(id_IOLOGIC, id_DQSBUFM)) {
if (!ci->ports.count(id_ECLK) || ci->ports.at(id_ECLK).net == nullptr)
continue;
BelId bel = ctx->getBelByNameStr(str_or_default(ci->attrs, id_BEL));
@@ -2669,7 +2664,7 @@ class Ecp5Packer
pool<IdString> changed_cells;
for (auto net : changed_nets) {
for (auto &user : ctx->nets.at(net)->users)
- if (user.port == id_CLKI || user.port == id_ECLKI || user.port == id_CLK0 || user.port == id_CLK1)
+ if (user.port.in(id_CLKI, id_ECLKI, id_CLK0, id_CLK1))
changed_cells.insert(user.cell->name);
auto &drv = ctx->nets.at(net)->driver;
if (iter == 1 && drv.cell != nullptr && drv.port == id_OSC)
@@ -2688,7 +2683,7 @@ class Ecp5Packer
else
log_error("Unsupported divider ratio '%s' on CLKDIVF '%s'\n", div.c_str(), ci->name.c_str(ctx));
copy_constraint(ci, id_CLKI, id_CDIVX, ratio);
- } else if (ci->type == id_ECLKSYNCB || ci->type == id_TRELLIS_ECLKBUF) {
+ } else if (ci->type.in(id_ECLKSYNCB, id_TRELLIS_ECLKBUF)) {
copy_constraint(ci, id_ECLKI, id_ECLKO, 1);
} else if (ci->type == id_ECLKBRIDGECS) {
copy_constraint(ci, id_CLK0, id_ECSOUT, 1);
diff --git a/gowin/cells.cc b/gowin/cells.cc
index 0c027d38..fc5e7388 100644
--- a/gowin/cells.cc
+++ b/gowin/cells.cc
@@ -56,13 +56,12 @@ std::unique_ptr<CellInfo> create_generic_cell(Context *ctx, IdString type, std::
new_cell->addInput(id_CLK);
new_cell->addInput(id_CE);
new_cell->addInput(id_LSR);
- } else if (type == id_MUX2_LUT5 || type == id_MUX2_LUT6 || type == id_MUX2_LUT7 || type == id_MUX2_LUT7 ||
- type == id_MUX2_LUT8) {
+ } else if (type.in(id_MUX2_LUT5, id_MUX2_LUT6, id_MUX2_LUT7, id_MUX2_LUT7, id_MUX2_LUT8)) {
new_cell->addInput(id_I0);
new_cell->addInput(id_I1);
new_cell->addInput(id_SEL);
new_cell->addOutput(id_OF);
- } else if (type == id_IOB || type == id_IOBS) {
+ } else if (type.in(id_IOB, id_IOBS)) {
new_cell->params[id_INPUT_USED] = 0;
new_cell->params[id_OUTPUT_USED] = 0;
new_cell->params[id_ENABLE_USED] = 0;
diff --git a/gowin/gfx.cc b/gowin/gfx.cc
index 9c9bc3fc..048ae62e 100644
--- a/gowin/gfx.cc
+++ b/gowin/gfx.cc
@@ -4969,7 +4969,7 @@ void gfxSetPipDefaultDecal(Arch *arch, PipInfo &pip)
// create if absent
if (arch->decal_graphics.count(active_id) == 0) {
// clock?
- if (dst_loc_id == id_GT00 || dst_loc_id == id_GT10) {
+ if (dst_loc_id.in(id_GT00, id_GT10)) {
WireInfo &wi = arch->wire_info(pip.srcWire);
if (wi.type.str(arch).substr(0, 3) != "UNK") {
// create pip
diff --git a/gowin/globals.cc b/gowin/globals.cc
index 1794dd4c..21ee722a 100644
--- a/gowin/globals.cc
+++ b/gowin/globals.cc
@@ -32,8 +32,7 @@ NEXTPNR_NAMESPACE_BEGIN
bool GowinGlobalRouter::is_clock_port(PortRef const &user)
{
- if ((user.cell->type == id_SLICE || user.cell->type == id_ODDR || user.cell->type == id_ODDRC) &&
- user.port == id_CLK) {
+ if ((user.cell->type.in(id_SLICE, id_ODDR, id_ODDRC)) && user.port == id_CLK) {
return true;
}
return false;
diff --git a/ice40/arch.cc b/ice40/arch.cc
index 905b8d61..c9c99d3a 100644
--- a/ice40/arch.cc
+++ b/ice40/arch.cc
@@ -643,7 +643,7 @@ bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay
{
const auto &driver = net_info->driver;
if (driver.port == id_COUT) {
- NPNR_ASSERT(sink.port == id_CIN || sink.port == id_I3);
+ NPNR_ASSERT(sink.port.in(id_CIN, id_I3));
NPNR_ASSERT(driver.cell->constr_abs_z);
bool cin = sink.port == id_CIN;
bool same_y = driver.cell->constr_z < 7;
@@ -904,7 +904,7 @@ std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const
ret.push_back(el);
}
- if (bel_type == id_ICESTORM_PLL || bel_type == id_SB_WARMBOOT) {
+ if (bel_type.in(id_ICESTORM_PLL, id_SB_WARMBOOT)) {
GraphicElement el;
el.type = GraphicElement::TYPE_BOX;
el.style = decal.active ? GraphicElement::STYLE_ACTIVE : GraphicElement::STYLE_INACTIVE;
@@ -937,7 +937,7 @@ bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort
if (fromPort == id_I3 && ((cell->lcInfo.lutInputMask & 0x8U) == 0))
return false;
}
- } else if (cell->type == id_ICESTORM_RAM || cell->type == id_ICESTORM_SPRAM) {
+ } else if (cell->type.in(id_ICESTORM_RAM, id_ICESTORM_SPRAM)) {
return false;
}
return get_cell_delay_internal(cell, fromPort, toPort, delay);
@@ -971,7 +971,7 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, in
return TMG_CLOCK_INPUT;
if (port == id_CIN)
return TMG_COMB_INPUT;
- if (port == id_COUT || port == id_LO)
+ if (port.in(id_COUT, id_LO))
return TMG_COMB_OUTPUT;
if (port == id_O) {
// LCs with no inputs are constant drivers
@@ -991,7 +991,7 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, in
}
} else if (cell->type == id_ICESTORM_RAM) {
- if (port == id_RCLK || port == id_WCLK)
+ if (port.in(id_RCLK, id_WCLK))
return TMG_CLOCK_INPUT;
clockInfoCount = 1;
@@ -1000,8 +1000,8 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, in
return TMG_REGISTER_OUTPUT;
else
return TMG_REGISTER_INPUT;
- } else if (cell->type == id_ICESTORM_DSP || cell->type == id_ICESTORM_SPRAM) {
- if (port == id_CLK || port == id_CLOCK)
+ } else if (cell->type.in(id_ICESTORM_DSP, id_ICESTORM_SPRAM)) {
+ if (port.in(id_CLK, id_CLOCK))
return TMG_CLOCK_INPUT;
else {
clockInfoCount = 1;
@@ -1011,7 +1011,7 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, in
return TMG_REGISTER_INPUT;
}
} else if (cell->type == id_SB_IO) {
- if (port == id_INPUT_CLK || port == id_OUTPUT_CLK)
+ if (port.in(id_INPUT_CLK, id_OUTPUT_CLK))
return TMG_CLOCK_INPUT;
if (port == id_CLOCK_ENABLE) {
clockInfoCount = 2;
@@ -1023,7 +1023,7 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, in
} else if (port == id_D_IN_0) {
return TMG_STARTPOINT;
}
- if (port == id_D_OUT_0 || port == id_D_OUT_1) {
+ if (port.in(id_D_OUT_0, id_D_OUT_1)) {
if ((cell->ioInfo.pintype & 0xC) == 0x8) {
return TMG_ENDPOINT;
} else {
@@ -1041,7 +1041,7 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, in
return TMG_IGNORE;
} else if (cell->type == id_ICESTORM_PLL) {
- if (port == id_PLLOUT_A || port == id_PLLOUT_B || port == id_PLLOUT_A_GLOBAL || port == id_PLLOUT_B_GLOBAL)
+ if (port.in(id_PLLOUT_A, id_PLLOUT_B, id_PLLOUT_A_GLOBAL, id_PLLOUT_B_GLOBAL))
return TMG_GEN_CLOCK;
return TMG_IGNORE;
} else if (cell->type == id_ICESTORM_LFOSC) {
@@ -1063,18 +1063,18 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, in
return TMG_IGNORE;
return TMG_ENDPOINT;
} else if (cell->type == id_SB_RGB_DRV) {
- if (port == id_RGB0 || port == id_RGB1 || port == id_RGB2 || port == id_RGBPU)
+ if (port.in(id_RGB0, id_RGB1, id_RGB2, id_RGBPU))
return TMG_IGNORE;
return TMG_ENDPOINT;
} else if (cell->type == id_SB_RGBA_DRV) {
- if (port == id_RGB0 || port == id_RGB1 || port == id_RGB2)
+ if (port.in(id_RGB0, id_RGB1, id_RGB2))
return TMG_IGNORE;
return TMG_ENDPOINT;
} else if (cell->type == id_SB_LEDDA_IP) {
- if (port == id_CLK || port == id_CLOCK)
+ if (port.in(id_CLK, id_CLOCK))
return TMG_CLOCK_INPUT;
return TMG_IGNORE;
- } else if (cell->type == id_SB_I2C || cell->type == id_SB_SPI) {
+ } else if (cell->type.in(id_SB_I2C, id_SB_SPI)) {
if (port == id_SBCLKI)
return TMG_CLOCK_INPUT;
@@ -1098,7 +1098,7 @@ TimingClockingInfo Arch::getPortClockingInfo(const CellInfo *cell, IdString port
bool has_clktoq = get_cell_delay_internal(cell, id_CLK, id_O, info.clockToQ);
NPNR_ASSERT(has_clktoq);
} else {
- if (port == id_I0 || port == id_I1 || port == id_I2 || port == id_I3) {
+ if (port.in(id_I0, id_I1, id_I2, id_I3)) {
DelayQuad dlut;
bool has_ld = get_cell_delay_internal(cell, port, id_O, dlut);
NPNR_ASSERT(has_ld);
@@ -1146,7 +1146,7 @@ TimingClockingInfo Arch::getPortClockingInfo(const CellInfo *cell, IdString port
info.edge = cell->ioInfo.negtrig ? FALLING_EDGE : RISING_EDGE;
info.setup = DelayPair(io_setup);
info.hold = DelayPair(0);
- } else if (port == id_D_OUT_0 || port == id_OUTPUT_ENABLE) {
+ } else if (port.in(id_D_OUT_0, id_OUTPUT_ENABLE)) {
info.clock_port = id_OUTPUT_CLK;
info.edge = cell->ioInfo.negtrig ? FALLING_EDGE : RISING_EDGE;
info.setup = DelayPair(io_setup);
@@ -1167,7 +1167,7 @@ TimingClockingInfo Arch::getPortClockingInfo(const CellInfo *cell, IdString port
} else {
NPNR_ASSERT_FALSE("no clock data for IO cell port");
}
- } else if (cell->type == id_ICESTORM_DSP || cell->type == id_ICESTORM_SPRAM) {
+ } else if (cell->type.in(id_ICESTORM_DSP, id_ICESTORM_SPRAM)) {
info.clock_port = cell->type == id_ICESTORM_SPRAM ? id_CLOCK : id_CLK;
info.edge = RISING_EDGE;
if (cell->ports.at(port).type == PORT_OUT) {
@@ -1178,7 +1178,7 @@ TimingClockingInfo Arch::getPortClockingInfo(const CellInfo *cell, IdString port
info.setup = DelayPair(100);
info.hold = DelayPair(0);
}
- } else if (cell->type == id_SB_I2C || cell->type == id_SB_SPI) {
+ } else if (cell->type.in(id_SB_I2C, id_SB_SPI)) {
info.clock_port = id_SBCLKI;
info.edge = RISING_EDGE;
if (cell->ports.at(port).type == PORT_OUT) {
diff --git a/ice40/arch_place.cc b/ice40/arch_place.cc
index 67ddf777..5c3fa3c5 100644
--- a/ice40/arch_place.cc
+++ b/ice40/arch_place.cc
@@ -105,7 +105,7 @@ bool Arch::isBelLocationValid(BelId bel) const
// that are a PLL clock output.
auto wire = getBelPinWire(bel, id_D_IN_0);
for (auto pin : getWireBelPins(wire)) {
- if (pin.pin == id_PLLOUT_A || pin.pin == id_PLLOUT_B) {
+ if (pin.pin.in(id_PLLOUT_A, id_PLLOUT_B)) {
// Is there a PLL there ?
const CellInfo *pll_cell = getBoundBelCell(pin.bel);
if (pll_cell == nullptr)
diff --git a/ice40/bitstream.cc b/ice40/bitstream.cc
index 48fbc132..3e50c065 100644
--- a/ice40/bitstream.cc
+++ b/ice40/bitstream.cc
@@ -640,8 +640,7 @@ void write_asc(const Context *ctx, std::ostream &out)
{"CURRENT_MODE", 1}, {"RGB0_CURRENT", 6}, {"RGB1_CURRENT", 6}, {"RGB2_CURRENT", 6}};
configure_extra_cell(config, ctx, cell.second.get(), rgba_params, true, std::string("IpConfig."));
set_ec_cbit(config, ctx, get_ec_config(ctx->chip_info, cell.second->bel), "RGBA_DRV_EN", true, "IpConfig.");
- } else if (cell.second->type == id_SB_WARMBOOT || cell.second->type == id_ICESTORM_LFOSC ||
- cell.second->type == id_SB_LEDDA_IP) {
+ } else if (cell.second->type.in(id_SB_WARMBOOT, id_ICESTORM_LFOSC, id_SB_LEDDA_IP)) {
// No config needed
} else if (cell.second->type == id_SB_I2C) {
bool sda_in_dly = !cell.second->attrs.count(id_SDA_INPUT_DELAYED) ||
diff --git a/ice40/cells.cc b/ice40/cells.cc
index 9166b41b..fc24caaf 100644
--- a/ice40/cells.cc
+++ b/ice40/cells.cc
@@ -502,13 +502,13 @@ bool is_clock_port(const BaseCtx *ctx, const PortRef &port)
if (port.cell->type == id_ICESTORM_LC)
return port.port == id_CLK;
if (is_ram(ctx, port.cell) || port.cell->type == id_ICESTORM_RAM)
- return port.port == id_RCLK || port.port == id_WCLK || port.port == id_RCLKN || port.port == id_WCLKN;
+ return port.port.in(id_RCLK, id_WCLK, id_RCLKN, id_WCLKN);
if (is_sb_mac16(ctx, port.cell) || port.cell->type == id_ICESTORM_DSP)
return port.port == id_CLK;
if (is_sb_spram(ctx, port.cell) || port.cell->type == id_ICESTORM_SPRAM)
return port.port == id_CLOCK;
if (is_sb_io(ctx, port.cell))
- return port.port == id_INPUT_CLK || port.port == id_OUTPUT_CLK;
+ return port.port.in(id_INPUT_CLK, id_OUTPUT_CLK);
return false;
}
@@ -517,11 +517,11 @@ bool is_reset_port(const BaseCtx *ctx, const PortRef &port)
if (port.cell == nullptr)
return false;
if (is_ff(ctx, port.cell))
- return port.port == id_R || port.port == id_S;
+ return port.port.in(id_R, id_S);
if (port.cell->type == id_ICESTORM_LC)
return port.port == id_SR;
if (is_sb_mac16(ctx, port.cell) || port.cell->type == id_ICESTORM_DSP)
- return port.port == id_IRSTTOP || port.port == id_IRSTBOT || port.port == id_ORSTTOP || port.port == id_ORSTBOT;
+ return port.port.in(id_IRSTTOP, id_IRSTBOT, id_ORSTTOP, id_ORSTBOT);
return false;
}
diff --git a/ice40/cells.h b/ice40/cells.h
index 724500d6..8aed649d 100644
--- a/ice40/cells.h
+++ b/ice40/cells.h
@@ -35,13 +35,9 @@ inline bool is_lut(const BaseCtx *ctx, const CellInfo *cell) { return cell->type
// Return true if a cell is a flipflop
inline bool is_ff(const BaseCtx *ctx, const CellInfo *cell)
{
- return cell->type == id_SB_DFF || cell->type == id_SB_DFFE || cell->type == id_SB_DFFSR ||
- cell->type == id_SB_DFFR || cell->type == id_SB_DFFSS || cell->type == id_SB_DFFS ||
- cell->type == id_SB_DFFESR || cell->type == id_SB_DFFER || cell->type == id_SB_DFFESS ||
- cell->type == id_SB_DFFES || cell->type == id_SB_DFFN || cell->type == id_SB_DFFNE ||
- cell->type == id_SB_DFFNSR || cell->type == id_SB_DFFNR || cell->type == id_SB_DFFNSS ||
- cell->type == id_SB_DFFNS || cell->type == id_SB_DFFNESR || cell->type == id_SB_DFFNER ||
- cell->type == id_SB_DFFNESS || cell->type == id_SB_DFFNES;
+ return cell->type.in(id_SB_DFF, id_SB_DFFE, id_SB_DFFSR, id_SB_DFFR, id_SB_DFFSS, id_SB_DFFS, id_SB_DFFESR,
+ id_SB_DFFER, id_SB_DFFESS, id_SB_DFFES, id_SB_DFFN, id_SB_DFFNE, id_SB_DFFNSR, id_SB_DFFNR,
+ id_SB_DFFNSS, id_SB_DFFNS, id_SB_DFFNESR, id_SB_DFFNER, id_SB_DFFNESS, id_SB_DFFNES);
}
inline bool is_carry(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == id_SB_CARRY; }
@@ -60,8 +56,7 @@ inline bool is_gbuf(const BaseCtx *ctx, const CellInfo *cell) { return cell->typ
// Return true if a cell is a RAM
inline bool is_ram(const BaseCtx *ctx, const CellInfo *cell)
{
- return cell->type == id_SB_RAM40_4K || cell->type == id_SB_RAM40_4KNR || cell->type == id_SB_RAM40_4KNW ||
- cell->type == id_SB_RAM40_4KNRNW;
+ return cell->type.in(id_SB_RAM40_4K, id_SB_RAM40_4KNR, id_SB_RAM40_4KNW, id_SB_RAM40_4KNRNW);
}
inline bool is_sb_lfosc(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == id_SB_LFOSC; }
@@ -86,13 +81,12 @@ inline bool is_sb_spi(const BaseCtx *ctx, const CellInfo *cell) { return cell->t
inline bool is_sb_pll40(const BaseCtx *ctx, const CellInfo *cell)
{
- return cell->type == id_SB_PLL40_PAD || cell->type == id_SB_PLL40_2_PAD || cell->type == id_SB_PLL40_2F_PAD ||
- cell->type == id_SB_PLL40_CORE || cell->type == id_SB_PLL40_2F_CORE;
+ return cell->type.in(id_SB_PLL40_PAD, id_SB_PLL40_2_PAD, id_SB_PLL40_2F_PAD, id_SB_PLL40_CORE, id_SB_PLL40_2F_CORE);
}
inline bool is_sb_pll40_pad(const BaseCtx *ctx, const CellInfo *cell)
{
- return cell->type == id_SB_PLL40_PAD || cell->type == id_SB_PLL40_2_PAD || cell->type == id_SB_PLL40_2F_PAD ||
+ return cell->type.in(id_SB_PLL40_PAD, id_SB_PLL40_2_PAD, id_SB_PLL40_2F_PAD) ||
(cell->type == id_ICESTORM_PLL && (cell->attrs.at(id_TYPE).as_string() == "SB_PLL40_PAD" ||
cell->attrs.at(id_TYPE).as_string() == "SB_PLL40_2_PAD" ||
cell->attrs.at(id_TYPE).as_string() == "SB_PLL40_2F_PAD"));
@@ -100,7 +94,7 @@ inline bool is_sb_pll40_pad(const BaseCtx *ctx, const CellInfo *cell)
inline bool is_sb_pll40_dual(const BaseCtx *ctx, const CellInfo *cell)
{
- return cell->type == id_SB_PLL40_2_PAD || cell->type == id_SB_PLL40_2F_PAD || cell->type == id_SB_PLL40_2F_CORE ||
+ return cell->type.in(id_SB_PLL40_2_PAD, id_SB_PLL40_2F_PAD, id_SB_PLL40_2F_CORE) ||
(cell->type == id_ICESTORM_PLL && (cell->attrs.at(id_TYPE).as_string() == "SB_PLL40_2_PAD" ||
cell->attrs.at(id_TYPE).as_string() == "SB_PLL40_2F_PAD" ||
cell->attrs.at(id_TYPE).as_string() == "SB_PLL40_2F_CORE"));
diff --git a/ice40/pack.cc b/ice40/pack.cc
index 9eff053e..c9811721 100644
--- a/ice40/pack.cc
+++ b/ice40/pack.cc
@@ -345,8 +345,8 @@ static void pack_ram(Context *ctx)
packed->attrs[attr.first] = attr.second;
for (auto param : ci->params)
packed->params[param.first] = param.second;
- packed->params[id_NEG_CLK_W] = Property(ci->type == id_SB_RAM40_4KNW || ci->type == id_SB_RAM40_4KNRNW, 1);
- packed->params[id_NEG_CLK_R] = Property(ci->type == id_SB_RAM40_4KNR || ci->type == id_SB_RAM40_4KNRNW, 1);
+ packed->params[id_NEG_CLK_W] = Property(ci->type.in(id_SB_RAM40_4KNW, id_SB_RAM40_4KNRNW), 1);
+ packed->params[id_NEG_CLK_R] = Property(ci->type.in(id_SB_RAM40_4KNR, id_SB_RAM40_4KNRNW), 1);
packed->type = id_ICESTORM_RAM;
for (auto port : ci->ports) {
PortInfo &pi = port.second;
@@ -1468,11 +1468,11 @@ void pack_plls(Context *ctx)
newname = newname.substr(0, bpos) + "_" + newname.substr(bpos + 1, (newname.size() - bpos) - 2);
}
- if (pi.name == id_PLLOUTCOREA || pi.name == id_PLLOUTCORE)
+ if (pi.name.in(id_PLLOUTCOREA, id_PLLOUTCORE))
newname = "PLLOUT_A";
if (pi.name == id_PLLOUTCOREB)
newname = "PLLOUT_B";
- if (pi.name == id_PLLOUTGLOBALA || pi.name == id_PLLOUTGLOBAL)
+ if (pi.name.in(id_PLLOUTGLOBALA, id_PLLOUTGLOBAL))
newname = "PLLOUT_A_GLOBAL";
if (pi.name == id_PLLOUTGLOBALB)
newname = "PLLOUT_B_GLOBAL";
diff --git a/mistral/globals.cc b/mistral/globals.cc
index 6af8920d..bdd835a7 100644
--- a/mistral/globals.cc
+++ b/mistral/globals.cc
@@ -38,10 +38,7 @@ void Arch::create_clkbuf(int x, int y)
}
}
-bool Arch::is_clkbuf_cell(IdString cell_type) const
-{
- return cell_type == id_MISTRAL_CLKENA || cell_type == id_MISTRAL_CLKBUF;
-}
+bool Arch::is_clkbuf_cell(IdString cell_type) const { return cell_type.in(id_MISTRAL_CLKENA, id_MISTRAL_CLKBUF); }
void Arch::create_hps_mpu_general_purpose(int x, int y)
{
diff --git a/nexus/arch.cc b/nexus/arch.cc
index 4a956fae..c2d3b6e4 100644
--- a/nexus/arch.cc
+++ b/nexus/arch.cc
@@ -479,7 +479,7 @@ bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort
}
return result;
} else {
- if (toPort == id_F || toPort == id_OFX)
+ if (toPort.in(id_F, id_OFX))
return lookup_cell_delay(cell->tmg_index, fromPort, toPort, delay);
}
} else if (is_dsp_cell(cell)) {
@@ -487,7 +487,7 @@ bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort
return false; // don't include delays that are actually clock-to-out here
return lookup_cell_delay(cell->tmg_index, lookup_port(fromPort), lookup_port(toPort), delay);
} else if (cell->type == id_DCS) {
- if (fromPort == id_SELFORCE || fromPort == id_SEL) {
+ if (fromPort.in(id_SELFORCE, id_SEL)) {
return false;
}
int index = get_cell_timing_idx(id_DCS, id_DCS);
@@ -505,10 +505,9 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, in
};
clockInfoCount = 0;
if (cell->type == id_OXIDE_COMB) {
- if (port == id_A || port == id_B || port == id_C || port == id_D || port == id_SEL || port == id_F1 ||
- port == id_FCI || port == id_WDI)
+ if (port.in(id_A, id_B, id_C, id_D, id_SEL, id_F1, id_FCI, id_WDI))
return TMG_COMB_INPUT;
- if (port == id_F || port == id_OFX || port == id_FCO) {
+ if (port.in(id_F, id_OFX, id_FCO)) {
if (disconnected(id_A) && disconnected(id_B) && disconnected(id_C) && disconnected(id_D) &&
disconnected(id_FCI) && disconnected(id_SEL) && disconnected(id_WDI))
return TMG_IGNORE;
@@ -528,18 +527,17 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, in
} else if (cell->type == id_RAMW) {
if (port == id_CLK)
return TMG_CLOCK_INPUT;
- else if (port == id_WDO0 || port == id_WDO1 || port == id_WDO2 || port == id_WDO3) {
+ else if (port.in(id_WDO0, id_WDO1, id_WDO2, id_WDO3)) {
clockInfoCount = 1;
return TMG_REGISTER_OUTPUT;
- } else if (port == id_A0 || port == id_A1 || port == id_B0 || port == id_B1 || port == id_C0 || port == id_C1 ||
- port == id_D0 || port == id_D1) {
+ } else if (port.in(id_A0, id_A1, id_B0, id_B1, id_C0, id_C1, id_D0, id_D1)) {
clockInfoCount = 1;
return TMG_REGISTER_INPUT;
}
} else if (cell->type == id_OXIDE_EBR) {
- if (port == id_DWS0 || port == id_DWS1 || port == id_DWS2 || port == id_DWS3 || port == id_DWS4)
+ if (port.in(id_DWS0, id_DWS1, id_DWS2, id_DWS3, id_DWS4))
return TMG_IGNORE;
- if (port == id_CLKA || port == id_CLKB)
+ if (port.in(id_CLKA, id_CLKB))
return TMG_CLOCK_INPUT;
clockInfoCount = 1;
return (cell->ports.at(port).type == PORT_IN) ? TMG_REGISTER_INPUT : TMG_REGISTER_OUTPUT;
@@ -551,9 +549,9 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, in
return TMG_CLOCK_INPUT;
clockInfoCount = 1;
return (cell->ports.at(port).type == PORT_IN) ? TMG_REGISTER_INPUT : TMG_REGISTER_OUTPUT;
- } else if (cell->type == id_MULT18_CORE || cell->type == id_MULT18X36_CORE || cell->type == id_MULT36_CORE) {
+ } else if (cell->type.in(id_MULT18_CORE, id_MULT18X36_CORE, id_MULT36_CORE)) {
return (cell->ports.at(port).type == PORT_IN) ? TMG_COMB_INPUT : TMG_COMB_OUTPUT;
- } else if (cell->type == id_PREADD9_CORE || cell->type == id_REG18_CORE || cell->type == id_MULT9_CORE) {
+ } else if (cell->type.in(id_PREADD9_CORE, id_REG18_CORE, id_MULT9_CORE)) {
if (port == id_CLK)
return TMG_CLOCK_INPUT;
auto type = lookup_port_type(cell->tmg_index, lookup_port(port), cell->ports.at(port).type, id_CLK);
@@ -571,7 +569,7 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, in
// FIXME: Making inputs TMG_CLOCK_INPUT and the output TMG_CLOCK_GEN
// yielded in error in the timing analyzer. For now keep those as
// regular combinational ports.
- if (port == id_CLK0 || port == id_CLK1)
+ if (port.in(id_CLK0, id_CLK1))
return TMG_COMB_INPUT;
else if (port == id_DCSOUT) {
return TMG_COMB_OUTPUT;
@@ -598,7 +596,7 @@ TimingClockingInfo Arch::getPortClockingInfo(const CellInfo *cell, IdString port
} else if (cell->type == id_RAMW) {
info.edge = (cell->ffInfo.ctrlset.clkmux == ID_INV) ? FALLING_EDGE : RISING_EDGE;
info.clock_port = id_CLK;
- if (port == id_WDO0 || port == id_WDO1 || port == id_WDO2 || port == id_WDO3)
+ if (port.in(id_WDO0, id_WDO1, id_WDO2, id_WDO3))
NPNR_ASSERT(lookup_cell_delay(cell->tmg_index, id_CLK, port, info.clockToQ));
else
lookup_cell_setuphold(cell->tmg_index, port, id_CLK, info.setup, info.hold);
@@ -618,7 +616,7 @@ TimingClockingInfo Arch::getPortClockingInfo(const CellInfo *cell, IdString port
NPNR_ASSERT(lookup_cell_delay(cell->tmg_index, id_CLK, lookup_port(port), info.clockToQ));
}
info.edge = (get_cell_pinmux(cell, info.clock_port) == PINMUX_INV) ? FALLING_EDGE : RISING_EDGE;
- } else if (cell->type == id_PREADD9_CORE || cell->type == id_REG18_CORE || cell->type == id_MULT9_CORE) {
+ } else if (cell->type.in(id_PREADD9_CORE, id_REG18_CORE, id_MULT9_CORE)) {
info.clock_port = id_CLK;
if (cell->ports.at(port).type == PORT_IN) {
lookup_cell_setuphold(cell->tmg_index, lookup_port(port), id_CLK, info.setup, info.hold);
@@ -737,9 +735,8 @@ void Arch::pre_routing()
{
for (auto &cell : cells) {
CellInfo *ci = cell.second.get();
- if (ci->type == id_MULT9_CORE || ci->type == id_PREADD9_CORE || ci->type == id_MULT18_CORE ||
- ci->type == id_MULT18X36_CORE || ci->type == id_MULT36_CORE || ci->type == id_REG18_CORE ||
- ci->type == id_ACC54_CORE) {
+ if (ci->type.in(id_MULT9_CORE, id_PREADD9_CORE, id_MULT18_CORE, id_MULT18X36_CORE, id_MULT36_CORE,
+ id_REG18_CORE, id_ACC54_CORE)) {
for (auto &port : ci->ports) {
WireId wire = getBelPinWire(ci->bel, port.first);
if (wire != WireId())
@@ -953,8 +950,8 @@ int db_binary_search(const Tres *list, int count, Tgetter key_getter, Tkey key)
bool Arch::is_dsp_cell(const CellInfo *cell) const
{
- return cell->type == id_MULT18_CORE || cell->type == id_MULT18X36_CORE || cell->type == id_MULT36_CORE ||
- cell->type == id_PREADD9_CORE || cell->type == id_REG18_CORE || cell->type == id_MULT9_CORE;
+ return cell->type.in(id_MULT18_CORE, id_MULT18X36_CORE, id_MULT36_CORE, id_PREADD9_CORE, id_REG18_CORE,
+ id_MULT9_CORE);
}
int Arch::get_cell_timing_idx(IdString cell_type, IdString cell_variant) const
diff --git a/nexus/arch.h b/nexus/arch.h
index d713afcf..4a28dfb7 100644
--- a/nexus/arch.h
+++ b/nexus/arch.h
@@ -1072,7 +1072,7 @@ struct Arch : BaseArch<ArchRanges>
bool getBelGlobalBuf(BelId bel) const override
{
IdString type = getBelType(bel);
- return type == id_DCC || type == id_VCC_DRV;
+ return type.in(id_DCC, id_VCC_DRV);
}
IdString getBelType(BelId bel) const override
diff --git a/nexus/fasm.cc b/nexus/fasm.cc
index 48a3d259..81208c0f 100644
--- a/nexus/fasm.cc
+++ b/nexus/fasm.cc
@@ -1079,9 +1079,8 @@ struct NexusFasmWriter
write_osc(ci);
else if (ci->type == id_OXIDE_EBR)
write_bram(ci);
- else if (ci->type == id_MULT9_CORE || ci->type == id_PREADD9_CORE || ci->type == id_MULT18_CORE ||
- ci->type == id_MULT18X36_CORE || ci->type == id_MULT36_CORE || ci->type == id_REG18_CORE ||
- ci->type == id_ACC54_CORE)
+ else if (ci->type.in(id_MULT9_CORE, id_PREADD9_CORE, id_MULT18_CORE, id_MULT18X36_CORE, id_MULT36_CORE,
+ id_REG18_CORE, id_ACC54_CORE))
write_dsp(ci);
else if (ci->type == id_PLL_CORE)
write_pll(ci);
@@ -1089,7 +1088,7 @@ struct NexusFasmWriter
write_lram(ci);
else if (ci->type == id_DPHY_CORE)
write_dphy(ci);
- else if (ci->type == id_IOLOGIC || ci->type == id_SIOLOGIC)
+ else if (ci->type.in(id_IOLOGIC, id_SIOLOGIC))
write_iol(ci);
else if (ci->type == id_DCC)
write_dcc(ci);
diff --git a/nexus/global.cc b/nexus/global.cc
index 37629f64..0792715d 100644
--- a/nexus/global.cc
+++ b/nexus/global.cc
@@ -193,7 +193,7 @@ struct NexusGlobalRouter
CellInfo *drv = ni->driver.cell;
if (drv == nullptr)
continue;
- if (drv->type == id_DCC || drv->type == id_DCS) {
+ if (drv->type.in(id_DCC, id_DCS)) {
route_clk_net(ni);
continue;
}
diff --git a/nexus/pack.cc b/nexus/pack.cc
index e727364d..3d293f69 100644
--- a/nexus/pack.cc
+++ b/nexus/pack.cc
@@ -1981,11 +1981,11 @@ struct NexusPacker
pool<IdString> changed_cells;
for (auto net : changed_nets) {
for (auto &user : ctx->nets.at(net)->users)
- if (user.port == id_CLKI || user.port == id_REFCK)
+ if (user.port.in(id_CLKI, id_REFCK))
changed_cells.insert(user.cell->name);
auto &drv = ctx->nets.at(net)->driver;
if (iter == 1 && drv.cell != nullptr) {
- if (drv.cell->type == id_OSC_CORE && (drv.port == id_HFCLKOUT || drv.port == id_LFCLKOUT))
+ if (drv.cell->type == id_OSC_CORE && (drv.port.in(id_HFCLKOUT, id_LFCLKOUT)))
changed_cells.insert(drv.cell->name);
if (drv.cell->type == id_DCC && drv.port == id_CLKO)
changed_cells.insert(drv.cell->name);