diff options
-rw-r--r-- | cyclonev/arch.cc | 96 | ||||
-rw-r--r-- | cyclonev/arch.h | 40 | ||||
-rw-r--r-- | cyclonev/archdefs.h | 5 |
3 files changed, 118 insertions, 23 deletions
diff --git a/cyclonev/arch.cc b/cyclonev/arch.cc index ac19b7d2..c4b21b4a 100644 --- a/cyclonev/arch.cc +++ b/cyclonev/arch.cc @@ -106,6 +106,100 @@ void Arch::unbindBel(BelId bel) refreshUiBel(bel); } -bool Arch::checkBelAvail(BelId bel) const { return bels.at(bel).bound_cell == nullptr; } +std::vector<BelId> Arch::getBels() const +{ + // This should probably be redesigned, but it's a hack. + std::vector<BelId> 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<BelId> Arch::getBelsByTile(int x, int y) const +{ + // This should probably be redesigned, but it's a hack. + std::vector<BelId> bels{}; + + 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; +} + +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) { + 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. + */ + return IdString(this, "LAB"); + case CycloneV::block_type_t::GPIO: + // GPIO tiles contain 4 pins. + return IdString(this, "GPIO"); + default: + continue; + } + } + + return IdString(); +} NEXTPNR_NAMESPACE_END
\ No newline at end of file diff --git a/cyclonev/arch.h b/cyclonev/arch.h index cd5905cd..874e4f3e 100644 --- a/cyclonev/arch.h +++ b/cyclonev/arch.h @@ -30,6 +30,13 @@ struct ArchArgs std::string device; }; +struct PinInfo +{ + IdString name; + WireId wire; + PortType type; +}; + struct BelInfo { IdString name, type; @@ -41,19 +48,12 @@ struct BelInfo bool gb; }; -struct PinInfo -{ - IdString name; - WireId wire; - PortType type; -}; - struct Arch : BaseCtx { ArchArgs args; mistral::CycloneV* cyclonev; - std::unordered_map<IdString, BelInfo> bels; + std::unordered_map<BelId, BelInfo> bels; Arch(ArchArgs args); @@ -75,18 +75,18 @@ struct Arch : BaseCtx BelId getBelByName(IdString name) const; // arch.cc IdString getBelName(BelId bel) const; // arch.cc uint32_t getBelChecksum(BelId bel) const { return (bel.pos << 16) | bel.z; } - void bindBel(BelId bel, CellInfo *cell, PlaceStrength strength); - void unbindBel(BelId bel); - bool checkBelAvail(BelId bel) const; - CellInfo *getBoundBelCell(BelId bel) const; - CellInfo *getConflictingBelCell(BelId bel) const; - const std::vector<BelId> &getBels() const; - Loc getBelLocation(BelId bel) const; - BelId getBelByLocation(Loc loc) const; - const std::vector<BelId> &getBelsByTile(int x, int y) const; - bool getBelGlobalBuf(BelId bel) const; - IdString getBelType(BelId bel) const; - std::vector<std::pair<IdString, std::string>> getBelAttrs(BelId bel) const; + void bindBel(BelId bel, CellInfo *cell, PlaceStrength strength); // arch.cc + void unbindBel(BelId bel); // arch.cc + 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<BelId> getBels() const; // arch.cc + 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<BelId> getBelsByTile(int x, int y) const; // arch.cc + bool getBelGlobalBuf(BelId bel) const { return false; } // HACK + IdString getBelType(BelId bel) const; // arch.cc + std::vector<std::pair<IdString, std::string>> getBelAttrs(BelId bel) const { return std::vector<std::pair<IdString, std::string>>{}; } // HACK WireId getBelPinWire(BelId bel, IdString pin) const; PortType getBelPinType(BelId bel, IdString pin) const; std::vector<IdString> getBelPins(BelId bel) const; diff --git a/cyclonev/archdefs.h b/cyclonev/archdefs.h index c522a83f..de04b4c7 100644 --- a/cyclonev/archdefs.h +++ b/cyclonev/archdefs.h @@ -52,6 +52,9 @@ struct DelayInfo struct BelId { + BelId() = default; + BelId(CycloneV::pos_t _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; uint16_t z = 0; @@ -106,8 +109,6 @@ struct DecalId struct ArchNetInfo { - bool is_global = false; - bool is_reset = false, is_enable = false; }; struct ArchCellInfo |