refactor: Use IdString::in instead of || chains
Signed-off-by: gatecat <gatecat@ds0.me>
This commit is contained in:
parent
a20d21bd13
commit
c60fb94b6c
76
ecp5/arch.cc
76
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 {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
@ -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");
|
||||
|
@ -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"));
|
||||
}
|
||||
|
45
ecp5/gfx.cc
45
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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
41
ecp5/pack.cc
41
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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
|
@ -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) ||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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"));
|
||||
|
@ -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";
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user