diff --git a/mistral/arch.cc b/mistral/arch.cc index cb2016bd..6e12bcf6 100644 --- a/mistral/arch.cc +++ b/mistral/arch.cc @@ -46,7 +46,7 @@ void IdString::initialize_arch(const BaseCtx *ctx) CycloneV::rnode_coords Arch::find_rnode(CycloneV::block_type_t bt, int x, int y, CycloneV::port_type_t port, int bi, int pi) const { - auto pn1 = CycloneV::pnode(bt, x, y, port, bi, pi); + auto pn1 = CycloneV::pnode_coords{bt, x, y, port, bi, pi}; auto rn1 = cyclonev->pnode_to_rnode(pn1); if (rn1) return rn1; @@ -63,7 +63,7 @@ CycloneV::rnode_coords Arch::find_rnode(CycloneV::block_type_t bt, int x, int y, return rn2; } - return 0; + return CycloneV::rnode_coords{}; } WireId Arch::get_port(CycloneV::block_type_t bt, int x, int y, int bi, CycloneV::port_type_t port, int pi) const @@ -72,7 +72,7 @@ WireId Arch::get_port(CycloneV::block_type_t bt, int x, int y, int bi, CycloneV: if (rn) return WireId(rn); - log_error("Trying to connect unknown node %s\n", CycloneV::pn2s(CycloneV::pnode(bt, x, y, port, bi, pi)).c_str()); + log_error("Trying to connect unknown node %s\n", CycloneV::pnode_coords{bt, x, y, port, bi, pi}.to_string().c_str()); } bool Arch::has_port(CycloneV::block_type_t bt, int x, int y, int bi, CycloneV::port_type_t port, int pi) const @@ -103,33 +103,33 @@ Arch::Arch(ArchArgs args) bels_by_tile.resize(cyclonev->get_tile_sx() * cyclonev->get_tile_sy()); for (auto lab_pos : cyclonev->lab_get_pos()) - create_lab(CycloneV::pos2x(lab_pos), CycloneV::pos2y(lab_pos), /*is_mlab=*/false); + create_lab(lab_pos.x(), lab_pos.y(), /*is_mlab=*/false); for (auto mlab_pos : cyclonev->mlab_get_pos()) - create_lab(CycloneV::pos2x(mlab_pos), CycloneV::pos2y(mlab_pos), /*is_mlab=*/true); + create_lab(mlab_pos.x(), mlab_pos.y(), /*is_mlab=*/true); for (auto gpio_pos : cyclonev->gpio_get_pos()) - create_gpio(CycloneV::pos2x(gpio_pos), CycloneV::pos2y(gpio_pos)); + create_gpio(gpio_pos.x(), gpio_pos.y()); for (auto cmuxh_pos : cyclonev->cmuxh_get_pos()) - create_clkbuf(CycloneV::pos2x(cmuxh_pos), CycloneV::pos2y(cmuxh_pos)); + create_clkbuf(cmuxh_pos.x(), cmuxh_pos.y()); - create_control(CycloneV::pos2x(cyclonev->ctrl_get_pos()[0]), CycloneV::pos2y(cyclonev->ctrl_get_pos()[0])); + create_control(cyclonev->ctrl_get_pos()[0].x(), cyclonev->ctrl_get_pos()[0].y()); auto hps_pos = cyclonev->hps_get_pos(); if (!hps_pos.empty()) { - create_hps_mpu_general_purpose(CycloneV::pos2x(hps_pos[CycloneV::I_HPS_MPU_GENERAL_PURPOSE]), - CycloneV::pos2y(hps_pos[CycloneV::I_HPS_MPU_GENERAL_PURPOSE])); + create_hps_mpu_general_purpose(hps_pos[CycloneV::I_HPS_MPU_GENERAL_PURPOSE].x(), + hps_pos[CycloneV::I_HPS_MPU_GENERAL_PURPOSE].y()); } for (auto m10k_pos : cyclonev->m10k_get_pos()) - create_m10k(CycloneV::pos2x(m10k_pos), CycloneV::pos2y(m10k_pos)); + create_m10k(m10k_pos.x(), m10k_pos.y()); // This import takes about 5s, perhaps long term we can speed it up, e.g. defer to Mistral more... log_info("Initialising routing graph...\n"); int pip_count = 0; for (const auto &rnode : cyclonev->rnodes()) { - WireId dst_wire(rnode.id()); + WireId dst_wire(rnode.rc()); for (const auto &src : rnode.sources()) { WireId src_wire(src); wires[dst_wire].wires_uphill.push_back(src_wire); @@ -158,7 +158,7 @@ BelId Arch::getBelByName(IdStringList name) const int y = id2int.at(name[2]); int z = id2int.at(name[3]); - bel.pos = CycloneV::xy2pos(x, y); + bel.pos = CycloneV::xycoords{x, y}; bel.z = z; NPNR_ASSERT(name[0] == getBelType(bel)); @@ -168,8 +168,8 @@ BelId Arch::getBelByName(IdStringList name) const IdStringList Arch::getBelName(BelId bel) const { - int x = CycloneV::pos2x(bel.pos); - int y = CycloneV::pos2y(bel.pos); + int x = bel.pos.x(); + int y = bel.pos.y(); int z = bel.z & 0xFF; std::array ids{ @@ -215,7 +215,7 @@ WireId Arch::getWireByName(IdStringList name) const int x = id2int.at(name[1]); int y = id2int.at(name[2]); int z = id2int.at(name[3]); - return WireId(CycloneV::rnode(ty, x, y, z)); + return WireId(CycloneV::rnode_coords{ty, x, y, z}); } IdStringList Arch::getWireName(WireId wire) const @@ -224,17 +224,17 @@ IdStringList Arch::getWireName(WireId wire) const // non-mistral wires std::array ids{ id_WIRE, - int2id.at(CycloneV::rn2x(wire.node)), - int2id.at(CycloneV::rn2y(wire.node)), + int2id.at(wire.node.x()), + int2id.at(wire.node.y()), wires.at(wire).name_override, }; return IdStringList(ids); } else { std::array ids{ - rn_t2id.at(CycloneV::rn2t(wire.node)), - int2id.at(CycloneV::rn2x(wire.node)), - int2id.at(CycloneV::rn2y(wire.node)), - int2id.at(CycloneV::rn2z(wire.node)), + rn_t2id.at(wire.node.t()), + int2id.at(wire.node.x()), + int2id.at(wire.node.y()), + int2id.at(wire.node.z()), }; return IdStringList(ids); } @@ -260,7 +260,7 @@ std::vector Arch::getBelsByTile(int x, int y) const std::vector bels; if (x >= 0 && x < cyclonev->get_tile_sx() && y >= 0 && y < cyclonev->get_tile_sy()) { for (size_t i = 0; i < bels_by_tile.at(pos2idx(x, y)).size(); i++) - bels.push_back(BelId(CycloneV::xy2pos(x, y), i)); + bels.push_back(BelId(CycloneV::xycoords{x, y}, i)); } return bels; @@ -320,7 +320,7 @@ BelId Arch::bel_by_block_idx(int x, int y, IdString type, int block_index) const for (size_t i = 0; i < bels.size(); i++) { auto &bel_data = bels.at(i); if (bel_data.type == type && bel_data.block_index == block_index) - return BelId(CycloneV::xy2pos(x, y), i); + return BelId(CycloneV::xycoords{x, y}, i); } return BelId(); } @@ -328,7 +328,7 @@ BelId Arch::bel_by_block_idx(int x, int y, IdString type, int block_index) const BelId Arch::add_bel(int x, int y, IdString name, IdString type) { auto &bels = bels_by_tile.at(pos2idx(x, y)); - BelId id = BelId(CycloneV::xy2pos(x, y), bels.size()); + BelId id = BelId(CycloneV::xycoords{x, y}, bels.size()); all_bels.push_back(id); bels.emplace_back(); auto &bel = bels.back(); @@ -356,7 +356,7 @@ WireId Arch::add_wire(int x, int y, IdString name, uint64_t flags) // Determine a unique ID for the wire int z = 0; WireId id; - while (wires.count(id = WireId(CycloneV::rnode(CycloneV::rnode_type_t((z >> 10) + 128), x, y, (z & 0x3FF))))) + while (wires.count(id = WireId(CycloneV::rnode_coords{CycloneV::rnode_type_t((z >> 10) + 128), x, y, (z & 0x3FF)}))) z++; wires[id].name_override = name; wires[id].flags = flags; @@ -438,10 +438,10 @@ void Arch::assignArchInfo() BoundingBox Arch::getRouteBoundingBox(WireId src, WireId dst) const { BoundingBox bounds; - int src_x = CycloneV::rn2x(src.node); - int src_y = CycloneV::rn2y(src.node); - int dst_x = CycloneV::rn2x(dst.node); - int dst_y = CycloneV::rn2y(dst.node); + int src_x = src.node.x(); + int src_y = src.node.y(); + int dst_x = dst.node.x(); + int dst_y = dst.node.y(); bounds.x0 = std::min(src_x, dst_x); bounds.y0 = std::min(src_y, dst_y); bounds.x1 = std::max(src_x, dst_x); diff --git a/mistral/arch.h b/mistral/arch.h index d99cefb8..30f14537 100644 --- a/mistral/arch.h +++ b/mistral/arch.h @@ -311,7 +311,7 @@ struct Arch : BaseArch std::vector getBelsByTile(int x, int y) const override; Loc getBelLocation(BelId bel) const override { - return Loc(CycloneV::pos2x(bel.pos), CycloneV::pos2y(bel.pos), bel.z); + return Loc(bel.pos.x(), bel.pos.y(), bel.z); } BelId getBelByLocation(Loc loc) const override { @@ -322,7 +322,7 @@ struct Arch : BaseArch auto &bels = bels_by_tile.at(pos2idx(loc.x, loc.y)); if (loc.z < 0 || loc.z >= int(bels.size())) return BelId(); - return BelId(CycloneV::xy2pos(loc.x, loc.y), loc.z); + return BelId(CycloneV::xycoords(loc.x, loc.y), loc.z); } IdString getBelType(BelId bel) const override; // arch.cc WireId getBelPinWire(BelId bel, IdString pin) const override @@ -380,7 +380,7 @@ struct Arch : BaseArch PipId getPipByName(IdStringList name) const override; AllPipRange getPips() const override { return AllPipRange(wires); } - Loc getPipLocation(PipId pip) const override { return Loc(CycloneV::rn2x(pip.dst), CycloneV::rn2y(pip.dst), 0); } + Loc getPipLocation(PipId pip) const override { return Loc(pip.dst.x(), pip.dst.y(), 0); } IdStringList getPipName(PipId pip) const override; WireId getPipSrcWire(PipId pip) const override { return WireId(pip.src); }; WireId getPipDstWire(PipId pip) const override { return WireId(pip.dst); }; @@ -545,7 +545,7 @@ struct Arch : BaseArch return y * cyclonev->get_tile_sx() + x; } - size_t pos2idx(CycloneV::pos_t pos) const { return pos2idx(CycloneV::pos2x(pos), CycloneV::pos2y(pos)); } + size_t pos2idx(CycloneV::xycoords pos) const { return pos2idx(pos.x(), pos.y()); } BelInfo &bel_data(BelId bel) { return bels_by_tile.at(pos2idx(bel.pos)).at(bel.z); } const BelInfo &bel_data(BelId bel) const { return bels_by_tile.at(pos2idx(bel.pos)).at(bel.z); } diff --git a/mistral/archdefs.h b/mistral/archdefs.h index ca88e3f3..97d95bc8 100644 --- a/mistral/archdefs.h +++ b/mistral/archdefs.h @@ -76,19 +76,19 @@ struct DelayInfo struct BelId { BelId() = default; - BelId(CycloneV::pos_t _pos, uint16_t _z) : pos{_pos}, z{_z} {} + BelId(CycloneV::xycoords _pos, uint16_t _z) : pos{_pos}, z{_z} {} - // pos_t is used for X/Y, nextpnr-cyclonev uses its own Z coordinate system. - CycloneV::pos_t pos = 0; + // xycoords is used for X/Y, nextpnr-cyclonev uses its own Z coordinate system. + CycloneV::xycoords pos{}; uint16_t z = 0; bool operator==(const BelId &other) const { return pos == other.pos && z == other.z; } bool operator!=(const BelId &other) const { return pos != other.pos || z != other.z; } bool operator<(const BelId &other) const { return pos < other.pos || (pos == other.pos && z < other.z); } - unsigned int hash() const { return mkhash(pos, z); } + unsigned int hash() const { return mkhash(pos.v, z); } }; -static constexpr auto invalid_rnode = std::numeric_limits::max(); +static constexpr auto invalid_rnode = CycloneV::rnode_coords{}; struct WireId { @@ -100,7 +100,7 @@ struct WireId bool is_nextpnr_created() const { NPNR_ASSERT(node != invalid_rnode); - return unsigned(CycloneV::rn2t(node)) >= 128; + return unsigned(node.t()) >= 128; } bool operator==(const WireId &other) const { return node == other.node; } diff --git a/mistral/bitstream.cc b/mistral/bitstream.cc index d2d72d8d..f9369669 100644 --- a/mistral/bitstream.cc +++ b/mistral/bitstream.cc @@ -32,13 +32,13 @@ struct MistralBitgen using rnode_coords = CycloneV::rnode_coords; using pnode_coords = CycloneV::pnode_coords; - using pos_t = CycloneV::pos_t; + using xycoords = CycloneV::xycoords; using block_type_t = CycloneV::block_type_t; using port_type_t = CycloneV::port_type_t; - rnode_coords find_rnode(block_type_t bt, pos_t pos, port_type_t port, int bi = -1, int pi = -1) const + rnode_coords find_rnode(block_type_t bt, xycoords pos, port_type_t port, int bi = -1, int pi = -1) const { - auto pn1 = CycloneV::pnode(bt, pos, port, bi, pi); + auto pn1 = CycloneV::pnode_coords{bt, pos, port, bi, pi}; auto rn1 = cv->pnode_to_rnode(pn1); if (rn1) return rn1; @@ -55,7 +55,7 @@ struct MistralBitgen return rn2; } - return 0; + return CycloneV::rnode_coords{}; } void options() @@ -88,7 +88,7 @@ struct MistralBitgen void write_io_cell(CellInfo *ci, int x, int y, int bi) { bool is_output = (ci->type == id_MISTRAL_OB || (ci->type == id_MISTRAL_IO && ci->getPort(id_OE) != nullptr)); - auto pos = CycloneV::xy2pos(x, y); + auto pos = CycloneV::xycoords{x, y}; // TODO: configurable pull, IO standard, etc cv->bmux_b_set(CycloneV::GPIO, pos, CycloneV::USE_WEAK_PULLUP, bi, false); if (is_output) { @@ -96,12 +96,12 @@ struct MistralBitgen cv->bmux_m_set(CycloneV::GPIO, pos, CycloneV::IOCSR_STD, bi, CycloneV::DIS); // Output gpios must also bypass things in the associated dqs - auto dqs = cv->p2p_to(CycloneV::pnode(CycloneV::GPIO, pos, CycloneV::PNONE, bi, -1)); + auto dqs = cv->p2p_to(CycloneV::pnode_coords{CycloneV::GPIO, pos, CycloneV::PNONE, bi, -1}); if (dqs) { - cv->bmux_m_set(CycloneV::DQS16, CycloneV::pn2p(dqs), CycloneV::INPUT_REG4_SEL, CycloneV::pn2bi(dqs), + cv->bmux_m_set(CycloneV::DQS16, dqs.p(), CycloneV::INPUT_REG4_SEL, dqs.bi(), CycloneV::SEL_LOCKED_DPA); - cv->bmux_r_set(CycloneV::DQS16, CycloneV::pn2p(dqs), CycloneV::RB_T9_SEL_EREG_CFF_DELAY, - CycloneV::pn2bi(dqs), 0x1f); + cv->bmux_r_set(CycloneV::DQS16, dqs.p(), CycloneV::RB_T9_SEL_EREG_CFF_DELAY, + dqs.bi(), 0x1f); } } // There seem to be two mirrored OEIN inversion bits for constant OE for inputs/outputs. This might be to @@ -114,14 +114,14 @@ struct MistralBitgen void write_clkbuf_cell(CellInfo *ci, int x, int y, int bi) { (void)ci; // currently unused - auto pos = CycloneV::xy2pos(x, y); + auto pos = CycloneV::xycoords{x, y}; cv->bmux_r_set(CycloneV::CMUXHG, pos, CycloneV::INPUT_SEL, bi, 0x1b); // hardcode to general routing cv->bmux_m_set(CycloneV::CMUXHG, pos, CycloneV::TESTSYN_ENOUT_SELECT, bi, CycloneV::PRE_SYNENB); } void write_m10k_cell(CellInfo *ci, int x, int y, int bi) { - auto pos = CycloneV::xy2pos(x, y); + auto pos = CycloneV::xycoords{x, y}; // Notes: // DATA_FLOW_THRU is probably transparent reads. @@ -240,8 +240,8 @@ struct MistralBitgen const std::array mux_port{CycloneV::FFT0, CycloneV::FFT1, CycloneV::FFT1L, CycloneV::FFB0, CycloneV::FFB1, CycloneV::FFB1L}; for (int i = 0; i < 6; i++) { - if (ctx->wires_connected(alm_data.comb_out[i / 3], ctx->get_port(block_type, CycloneV::pos2x(pos), - CycloneV::pos2y(pos), alm, mux_port[i]))) + if (ctx->wires_connected(alm_data.comb_out[i / 3], ctx->get_port(block_type, pos.x(), + pos.y(), alm, mux_port[i]))) cv->bmux_m_set(block_type, pos, mux_settings[i], alm, CycloneV::NLUT); } @@ -358,7 +358,7 @@ struct MistralBitgen for (int i = 0; i < 3; i++) { // Check for fabric->clock routing if (ctx->wires_connected( - ctx->get_port(block_type, CycloneV::pos2x(pos), CycloneV::pos2y(pos), -1, CycloneV::DATAIN, 0), + ctx->get_port(block_type, pos.x(), pos.y(), -1, CycloneV::DATAIN, 0), lab_data.clk_wires[i])) cv->bmux_m_set(block_type, pos, CycloneV::CLKA_SEL, 0, CycloneV::DIN0); } diff --git a/mistral/delay.cc b/mistral/delay.cc index e7c8918b..1cf054be 100644 --- a/mistral/delay.cc +++ b/mistral/delay.cc @@ -251,7 +251,7 @@ DelayQuad Arch::getPipDelay(PipId pip) const return DelayQuad{20}; // This is guesswork based on average of (interconnect delay / number of pips) - auto src_type = CycloneV::rn2t(src.node); + auto src_type = src.node.t(); switch (src_type) { case CycloneV::rnode_type_t::SCLK: @@ -342,7 +342,7 @@ bool Arch::getArcDelayOverride(const NetInfo *net_info, const PortRef &sink, Del continue; if (dst.is_nextpnr_created()) - dst.node = 0; + dst.node = CycloneV::rnode_coords{}; auto mode = cyclonev->rnode_timing_get_mode(src.node); NPNR_ASSERT(mode != mistral::CycloneV::RTM_UNSUPPORTED); @@ -419,10 +419,10 @@ delay_t Arch::predictDelay(BelId src_bel, IdString src_pin, BelId dst_bel, IdStr delay_t Arch::estimateDelay(WireId src, WireId dst) const { - int x0 = CycloneV::rn2x(src.node); - int y0 = CycloneV::rn2y(src.node); - int x1 = CycloneV::rn2x(dst.node); - int y1 = CycloneV::rn2y(dst.node); + int x0 = src.node.x(); + int y0 = src.node.y(); + int x1 = dst.node.x(); + int y1 = dst.node.y(); int x_diff = std::abs(x1 - x0); int y_diff = std::abs(y1 - y0); return 75 * x_diff + 200 * y_diff; diff --git a/mistral/globals.cc b/mistral/globals.cc index cb00b635..d85b89a9 100644 --- a/mistral/globals.cc +++ b/mistral/globals.cc @@ -71,7 +71,7 @@ struct MistralGlobalRouter // When routing globals; we allow global->local for some tricky cases but never local->local bool global_pip_filter(PipId pip) const { - auto src_type = CycloneV::rn2t(pip.src); + auto src_type = pip.src.t(); return src_type != CycloneV::H14 && src_type != CycloneV::H6 && src_type != CycloneV::H3 && src_type != CycloneV::V12 && src_type != CycloneV::V2 && src_type != CycloneV::V4 && src_type != CycloneV::WM; diff --git a/mistral/io.cc b/mistral/io.cc index 6690fc16..63ff8359 100644 --- a/mistral/io.cc +++ b/mistral/io.cc @@ -56,8 +56,8 @@ bool Arch::is_io_cell(IdString cell_type) const BelId Arch::get_io_pin_bel(const CycloneV::pin_info_t *pin) const { auto pad = pin->pad; - CycloneV::pos_t pos = (pad & 0x3FFF); - return bel_by_block_idx(CycloneV::pos2x(pos), CycloneV::pos2y(pos), id_MISTRAL_IO, (pad >> 14)); + CycloneV::xycoords pos = CycloneV::xycoords{pad & 0x3FFF}; + return bel_by_block_idx(pos.x(), pos.y(), id_MISTRAL_IO, (pad >> 14)); } NEXTPNR_NAMESPACE_END diff --git a/mistral/lab.cc b/mistral/lab.cc index 692197fd..97cf02d4 100644 --- a/mistral/lab.cc +++ b/mistral/lab.cc @@ -1081,7 +1081,7 @@ uint64_t Arch::compute_lut_mask(uint32_t lab, uint8_t alm) #if 1 if (getCtx()->debug) { auto pos = alm_data.lut_bels[0].pos; - log("ALM %03d.%03d.%d\n", CycloneV::pos2x(pos), CycloneV::pos2y(pos), alm); + log("ALM %03d.%03d.%d\n", pos.x(), pos.y(), alm); for (int i = 0; i < 2; i++) { log(" LUT%d: ", i); if (luts[i]) {