diff --git a/cyclonev/arch.cc b/cyclonev/arch.cc index c4b21b4a..016b69b6 100644 --- a/cyclonev/arch.cc +++ b/cyclonev/arch.cc @@ -31,6 +31,35 @@ Arch::Arch(ArchArgs args) this->args = args; this->cyclonev = mistral::CycloneV::get_model(args.device); NPNR_ASSERT(this->cyclonev != nullptr); + + for (int x = 0; x < cyclonev->get_tile_sx(); x++) { + for (int y = 0; y < cyclonev->get_tile_sy(); y++) { + CycloneV::pos_t pos = cyclonev->xy2pos(x, y); + + for (CycloneV::block_type_t bel : cyclonev->pos_get_bels(pos)) { + switch (bel) { + case CycloneV::block_type_t::LAB: + /* + * nextpnr and mistral disagree on what a BEL is: mistral thinks an entire LAB + * is one BEL, but nextpnr wants something with more precision. + * + * One LAB contains 10 ALMs. + * One ALM contains 2 LUT outputs and 4 flop outputs. + */ + for (int z = 0; z < 60; z++) { + this->bel_list.push_back(BelId(pos, z)); + } + case CycloneV::block_type_t::GPIO: + // GPIO tiles contain 4 pins. + for (int z = 0; z < 4; z++) { + this->bel_list.push_back(BelId(pos, z)); + } + default: + continue; + } + } + } + } } int Arch::getTileBelDimZ(int x, int y) const @@ -106,43 +135,6 @@ void Arch::unbindBel(BelId bel) refreshUiBel(bel); } -std::vector Arch::getBels() const -{ - // This should probably be redesigned, but it's a hack. - std::vector bels{}; - - for (int x = 0; x < cyclonev->get_tile_sx(); x++) { - for (int y = 0; y < cyclonev->get_tile_sy(); y++) { - CycloneV::pos_t pos = cyclonev->xy2pos(x, y); - - for (CycloneV::block_type_t bel : cyclonev->pos_get_bels(pos)) { - switch (bel) { - case CycloneV::block_type_t::LAB: - /* - * nextpnr and mistral disagree on what a BEL is: mistral thinks an entire LAB - * is one BEL, but nextpnr wants something with more precision. - * - * One LAB contains 10 ALMs. - * One ALM contains 2 LUT outputs and 4 flop outputs. - */ - for (int z = 0; z < 60; z++) { - bels.push_back(BelId(pos, z)); - } - case CycloneV::block_type_t::GPIO: - // GPIO tiles contain 4 pins. - for (int z = 0; z < 4; z++) { - bels.push_back(BelId(pos, z)); - } - default: - continue; - } - } - } - } - - return bels; -} - std::vector Arch::getBelsByTile(int x, int y) const { // This should probably be redesigned, but it's a hack. @@ -150,8 +142,8 @@ std::vector Arch::getBelsByTile(int x, int y) const CycloneV::pos_t pos = cyclonev->xy2pos(x, y); - for (CycloneV::block_type_t bel : cyclonev->pos_get_bels(pos)) { - switch (bel) { + for (CycloneV::block_type_t cvbel : cyclonev->pos_get_bels(pos)) { + switch (cvbel) { case CycloneV::block_type_t::LAB: /* * nextpnr and mistral disagree on what a BEL is: mistral thinks an entire LAB @@ -178,10 +170,8 @@ std::vector Arch::getBelsByTile(int x, int y) const IdString Arch::getBelType(BelId bel) const { - CycloneV::pos_t pos = cyclonev->xy2pos(x, y); - - for (CycloneV::block_type_t bel : cyclonev->pos_get_bels(pos)) { - switch (bel) { + for (CycloneV::block_type_t cvbel : cyclonev->pos_get_bels(bel.pos)) { + switch (cvbel) { case CycloneV::block_type_t::LAB: /* * nextpnr and mistral disagree on what a BEL is: mistral thinks an entire LAB diff --git a/cyclonev/arch.h b/cyclonev/arch.h index 874e4f3e..01b548af 100644 --- a/cyclonev/arch.h +++ b/cyclonev/arch.h @@ -54,6 +54,7 @@ struct Arch : BaseCtx mistral::CycloneV* cyclonev; std::unordered_map bels; + std::vector bel_list; Arch(ArchArgs args); @@ -80,7 +81,7 @@ struct Arch : BaseCtx bool checkBelAvail(BelId bel) const { return bels.at(bel).bound_cell == nullptr; } CellInfo *getBoundBelCell(BelId bel) const { return bels.at(bel).bound_cell; } CellInfo *getConflictingBelCell(BelId bel) const { return nullptr; } // HACK - std::vector getBels() const; // arch.cc + const std::vector& Arch::getBels() const { return bel_list; } Loc getBelLocation(BelId bel) const { return Loc(CycloneV::pos2x(bel.pos), CycloneV::pos2y(bel.pos), bel.z); } BelId getBelByLocation(Loc loc) const { return BelId(CycloneV::xy2pos(loc.x, loc.y), loc.z); } std::vector getBelsByTile(int x, int y) const; // arch.cc