diff options
author | gatecat <gatecat@ds0.me> | 2021-04-30 18:40:24 +0100 |
---|---|---|
committer | gatecat <gatecat@ds0.me> | 2021-05-15 14:54:33 +0100 |
commit | 0533818ceead805b9afc749d3a23e571e4a21543 (patch) | |
tree | a60b9bc96eafea8760536db360094c8bd98a4f81 /cyclonev | |
parent | 9f2cbe1762387ec38d358fb4c885740de89b5656 (diff) | |
download | nextpnr-0533818ceead805b9afc749d3a23e571e4a21543.tar.gz nextpnr-0533818ceead805b9afc749d3a23e571e4a21543.tar.bz2 nextpnr-0533818ceead805b9afc749d3a23e571e4a21543.zip |
cyclonev: Update in line with nextpnr changes
Signed-off-by: gatecat <gatecat@ds0.me>
Diffstat (limited to 'cyclonev')
-rw-r--r-- | cyclonev/arch.cc | 78 | ||||
-rw-r--r-- | cyclonev/arch.h | 214 | ||||
-rw-r--r-- | cyclonev/archdefs.h | 68 | ||||
-rw-r--r-- | cyclonev/family.cmake | 5 |
4 files changed, 127 insertions, 238 deletions
diff --git a/cyclonev/arch.cc b/cyclonev/arch.cc index 016b69b6..3f728b91 100644 --- a/cyclonev/arch.cc +++ b/cyclonev/arch.cc @@ -20,7 +20,7 @@ #include "nextpnr.h" -#include "mistral/lib/cyclonev.h" +#include "cyclonev.h" NEXTPNR_NAMESPACE_BEGIN @@ -40,20 +40,22 @@ Arch::Arch(ArchArgs args) 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. - */ + * 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)); } + break; 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)); } + break; default: continue; } @@ -70,12 +72,12 @@ int Arch::getTileBelDimZ(int x, int y) const 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. - */ + * 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 60; case CycloneV::block_type_t::GPIO: // GPIO tiles contain 4 pins. @@ -89,13 +91,13 @@ int Arch::getTileBelDimZ(int x, int y) const return 0; } -BelId Arch::getBelByName(IdString name) const +BelId Arch::getBelByName(IdStringList name) const { char bel_type_str[80] = {0}; int x = 0, y = 0, z = 0; BelId bel; - sscanf(name.c_str(this), "%25s.%d.%d.%d", bel_type_str, &x, &y, &z); + sscanf(name[0].c_str(this), "%25s.%d.%d.%d", bel_type_str, &x, &y, &z); auto bel_type = cyclonev->block_type_lookup(std::string{bel_type_str}); @@ -105,7 +107,7 @@ BelId Arch::getBelByName(IdString name) const return bel; } -IdString Arch::getBelName(BelId bel) const +IdStringList Arch::getBelName(BelId bel) const { char bel_str[80] = {0}; @@ -116,23 +118,7 @@ IdString Arch::getBelName(BelId bel) const snprintf(bel_str, 80, "%s.%03d.%03d.%03d", cyclonev->block_type_names[bel_type], x, y, z); - return id(bel_str); -} - -void Arch::bindBel(BelId bel, CellInfo *cell, PlaceStrength strength) -{ - bels.at(bel).bound_cell = cell; - cell->bel = bel; - cell->belStrength = strength; - refreshUiBel(bel); -} - -void Arch::unbindBel(BelId bel) -{ - bels.at(bel).bound_cell->bel = BelId(); - bels.at(bel).bound_cell->belStrength = STRENGTH_NONE; - bels.at(bel).bound_cell = nullptr; - refreshUiBel(bel); + return IdStringList(id(bel_str)); } std::vector<BelId> Arch::getBelsByTile(int x, int y) const @@ -146,20 +132,22 @@ std::vector<BelId> Arch::getBelsByTile(int x, int y) const switch (cvbel) { 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. - */ + * 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)); } + break; case CycloneV::block_type_t::GPIO: // GPIO tiles contain 4 pins. for (int z = 0; z < 4; z++) { bels.push_back(BelId(pos, z)); } + break; default: continue; } @@ -174,12 +162,12 @@ IdString Arch::getBelType(BelId bel) const switch (cvbel) { 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. - */ + * 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. diff --git a/cyclonev/arch.h b/cyclonev/arch.h index 01b548af..84ab72f2 100644 --- a/cyclonev/arch.h +++ b/cyclonev/arch.h @@ -17,11 +17,17 @@ * */ -#ifndef NEXTPNR_H -#error Include "arch.h" via "nextpnr.h" only. -#endif +#ifndef MISTRAL_ARCH_H +#define MISTRAL_ARCH_H -#include "mistral/lib/cyclonev.h" +#include <set> +#include <sstream> + +#include "base_arch.h" +#include "nextpnr_types.h" +#include "relptr.h" + +#include "cyclonev.h" NEXTPNR_NAMESPACE_BEGIN @@ -48,173 +54,95 @@ struct BelInfo bool gb; }; -struct Arch : BaseCtx +struct ArchRanges : BaseArchRanges +{ + using ArchArgsT = ArchArgs; + // Bels + using AllBelsRangeT = const std::vector<BelId> &; + using TileBelsRangeT = std::vector<BelId>; + using BelPinsRangeT = std::vector<IdString>; + // Wires + using AllWiresRangeT = const std::vector<WireId> &; + using DownhillPipRangeT = const std::vector<PipId> &; + using UphillPipRangeT = const std::vector<PipId> &; + using WireBelPinRangeT = std::vector<BelPin>; + // Pips + using AllPipsRangeT = const std::vector<PipId> &; +}; + +struct Arch : BaseArch<ArchRanges> { ArchArgs args; - mistral::CycloneV* cyclonev; + mistral::CycloneV *cyclonev; std::unordered_map<BelId, BelInfo> bels; std::vector<BelId> bel_list; Arch(ArchArgs args); - std::string getChipName() const { return std::string{"TODO: getChipName"}; } - - IdString archId() const { return id("cyclonev"); } - ArchArgs archArgs() const { return args; } - IdString archArgsToId(ArchArgs args) const { return id("TODO: archArgsToId"); } - + std::string getChipName() const override { return std::string{"TODO: getChipName"}; } // ------------------------------------------------- - int getGridDimX() const { return cyclonev->get_tile_sx(); } - int getGridDimY() const { return cyclonev->get_tile_sy(); } - int getTileBelDimZ(int x, int y) const; // arch.cc - int getTilePipDimZ(int x, int y) const { return 1; } + int getGridDimX() const override { return cyclonev->get_tile_sx(); } + int getGridDimY() const override { return cyclonev->get_tile_sy(); } + int getTileBelDimZ(int x, int y) const override; // arch.cc // ------------------------------------------------- - 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); // 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 - const std::vector<BelId>& 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<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; - bool isBelLocked(BelId bel) const; + BelId getBelByName(IdStringList name) const override; // arch.cc + IdStringList getBelName(BelId bel) const override; // arch.cc + const std::vector<BelId> &getBels() const override { return bel_list; } + std::vector<BelId> 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); + } + BelId getBelByLocation(Loc loc) const override { return BelId(CycloneV::xy2pos(loc.x, loc.y), loc.z); } + IdString getBelType(BelId bel) const override; // arch.cc + WireId getBelPinWire(BelId bel, IdString pin) const override; + PortType getBelPinType(BelId bel, IdString pin) const override; + std::vector<IdString> getBelPins(BelId bel) const override; // ------------------------------------------------- - WireId getWireByName(IdString name) const; - IdString getWireName(WireId wire) const; - IdString getWireType(WireId wire) const; - std::vector<std::pair<IdString, std::string>> getWireAttrs(WireId wire) const; - uint32_t getWireChecksum(WireId wire) const; - void bindWire(WireId wire, NetInfo *net, PlaceStrength strength); - void unbindWire(WireId wire); - bool checkWireAvail(WireId wire) const; - NetInfo *getBoundWireNet(WireId wire) const; - WireId getConflictingWireWire(WireId wire) const; - NetInfo *getConflictingWireNet(WireId wire) const; - DelayInfo getWireDelay(WireId wire) const; - const std::vector<BelPin> &getWireBelPins(WireId wire) const; - const std::vector<WireId> &getWires() const; + WireId getWireByName(IdStringList name) const override; + IdStringList getWireName(WireId wire) const override; + DelayQuad getWireDelay(WireId wire) const; + std::vector<BelPin> getWireBelPins(WireId wire) const override; + const std::vector<WireId> &getWires() const override; // ------------------------------------------------- - PipId getPipByName(IdString name) const; - void bindPip(PipId pip, NetInfo *net, PlaceStrength strength); - void unbindPip(PipId pip); - bool checkPipAvail(PipId pip) const; - NetInfo *getBoundPipNet(PipId pip) const; - WireId getConflictingPipWire(PipId pip) const; - NetInfo *getConflictingPipNet(PipId pip) const; - const std::vector<PipId> &getPips() const; - Loc getPipLocation(PipId pip) const; - IdString getPipName(PipId pip) const; - IdString getPipType(PipId pip) const; - std::vector<std::pair<IdString, std::string>> getPipAttrs(PipId pip) const; - uint32_t getPipChecksum(PipId pip) const; - WireId getPipSrcWire(PipId pip) const; - WireId getPipDstWire(PipId pip) const; - DelayInfo getPipDelay(PipId pip) const; - const std::vector<PipId> &getPipsDownhill(WireId wire) const; - const std::vector<PipId> &getPipsUphill(WireId wire) const; - const std::vector<PipId> &getWireAliases(WireId wire) const; - BelId getPackagePinBel(const std::string &pin) const; - std::string getBelPackagePin(BelId bel) const; + PipId getPipByName(IdStringList name) const override; + const std::vector<PipId> &getPips() const override; + Loc getPipLocation(PipId pip) const override; + IdStringList getPipName(PipId pip) const override; + WireId getPipSrcWire(PipId pip) const override; + WireId getPipDstWire(PipId pip) const override; + DelayQuad getPipDelay(PipId pip) const override; + const std::vector<PipId> &getPipsDownhill(WireId wire) const override; + const std::vector<PipId> &getPipsUphill(WireId wire) const override; // ------------------------------------------------- - GroupId getGroupByName(IdString name) const; - IdString getGroupName(GroupId group) const; - std::vector<GroupId> getGroups() const; - std::vector<BelId> getGroupBels(GroupId group) const; - std::vector<WireId> getGroupWires(GroupId group) const; - std::vector<PipId> getGroupPips(GroupId group) const; - std::vector<GroupId> getGroupGroups(GroupId group) const; + delay_t estimateDelay(WireId src, WireId dst) const override; + delay_t predictDelay(const NetInfo *net_info, const PortRef &sink) const override; + delay_t getDelayEpsilon() const override; + delay_t getRipupDelayPenalty() const override; + float getDelayNS(delay_t v) const override; + delay_t getDelayFromNS(float ns) const override; + uint32_t getDelayChecksum(delay_t v) const override; - // ------------------------------------------------- - - delay_t estimateDelay(WireId src, WireId dst) const; - delay_t predictDelay(const NetInfo *net_info, const PortRef &sink) const; - delay_t getDelayEpsilon() const; - delay_t getRipupDelayPenalty() const; - float getDelayNS(delay_t v) const; - DelayInfo getDelayFromNS(float ns) const; - uint32_t getDelayChecksum(delay_t v) const; - bool getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const; - - ArcBounds getRouteBoundingBox(WireId src, WireId dst) const; + ArcBounds getRouteBoundingBox(WireId src, WireId dst) const override; // ------------------------------------------------- - bool pack(); - bool place(); - bool route(); - - // ------------------------------------------------- - - std::vector<GraphicElement> getDecalGraphics(DecalId decal) const; - - DecalXY getBelDecal(BelId bel) const; - DecalXY getWireDecal(WireId wire) const; - DecalXY getPipDecal(PipId pip) const; - DecalXY getGroupDecal(GroupId group) const; + bool pack() override; + bool place() override; + bool route() override; // ------------------------------------------------- - // Get the delay through a cell from one port to another, returning false - // if no path exists. This only considers combinational delays, as required by the Arch API - bool getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const; - // getCellDelayInternal is similar to the above, but without false path checks and including clock to out delays - // for internal arch use only - bool getCellDelayInternal(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const; - // Get the port class, also setting clockInfoCount to the number of TimingClockingInfos associated with a port - TimingPortClass getPortTimingClass(const CellInfo *cell, IdString port, int &clockInfoCount) const; - // Get the TimingClockingInfo of a port - TimingClockingInfo getPortClockingInfo(const CellInfo *cell, IdString port, int index) const; - // Return true if a port is a net - bool isGlobalNet(const NetInfo *net) const; - - // ------------------------------------------------- - - // Perform placement validity checks, returning false on failure (all - // implemented in arch_place.cc) - - // Whether or not a given cell can be placed at a given Bel - // This is not intended for Bel type checks, but finer-grained constraints - // such as conflicting set/reset signals, etc - bool isValidBelForCell(CellInfo *cell, BelId bel) const; - - // Return true whether all Bels at a given location are valid - bool isBelLocationValid(BelId bel) const; - - // Helper function for above - bool logicCellsCompatible(const CellInfo **it, const size_t size) const; - - // ------------------------------------------------- - // Assign architecure-specific arguments to nets and cells, which must be - // called between packing or further - // netlist modifications, and validity checks - void assignArchInfo(); - void assignCellInfo(CellInfo *cell); - - // ------------------------------------------------- - BelPin getIOBSharingPLLPin(BelId pll, IdString pll_pin) const; - - int getDrivenGlobalNetwork(BelId bel) const; - static const std::string defaultPlacer; static const std::vector<std::string> availablePlacers; static const std::string defaultRouter; @@ -222,3 +150,5 @@ struct Arch : BaseCtx }; NEXTPNR_NAMESPACE_END + +#endif
\ No newline at end of file diff --git a/cyclonev/archdefs.h b/cyclonev/archdefs.h index de04b4c7..d8fd3160 100644 --- a/cyclonev/archdefs.h +++ b/cyclonev/archdefs.h @@ -17,11 +17,15 @@ * */ -#ifndef NEXTPNR_H -#error Include "archdefs.h" via "nextpnr.h" only. -#endif +#ifndef MISTRAL_ARCHDEFS_H +#define MISTRAL_ARCHDEFS_H -#include "mistral/lib/cyclonev.h" +#include <boost/functional/hash.hpp> + +#include "cyclonev.h" + +#include "idstring.h" +#include "nextpnr_namespaces.h" NEXTPNR_NAMESPACE_BEGIN @@ -82,30 +86,9 @@ struct PipId bool operator<(const PipId &other) const { return index < other.index; } }; -struct GroupId -{ - enum : int8_t - { - TYPE_NONE - } type = TYPE_NONE; - int8_t x = 0, y = 0; - - bool operator==(const GroupId &other) const { return (type == other.type) && (x == other.x) && (y == other.y); } - bool operator!=(const GroupId &other) const { return (type != other.type) || (x != other.x) || (y == other.y); } -}; - -struct DecalId -{ - enum : int8_t - { - TYPE_NONE, - } type = TYPE_NONE; - int32_t index = -1; - bool active = false; - - bool operator==(const DecalId &other) const { return (type == other.type) && (index == other.index); } - bool operator!=(const DecalId &other) const { return (type != other.type) || (index != other.index); } -}; +typedef IdString DecalId; +typedef IdString GroupId; +typedef IdString BelBucketId; struct ArchNetInfo { @@ -120,7 +103,10 @@ NEXTPNR_NAMESPACE_END namespace std { template <> struct hash<NEXTPNR_NAMESPACE_PREFIX BelId> { - std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX BelId &bel) const noexcept { return hash<uint32_t>()((static_cast<uint32_t>(bel.pos) << 16) | bel.z); } + std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX BelId &bel) const noexcept + { + return hash<uint32_t>()((static_cast<uint32_t>(bel.pos) << 16) | bel.z); + } }; template <> struct hash<NEXTPNR_NAMESPACE_PREFIX WireId> @@ -136,26 +122,6 @@ template <> struct hash<NEXTPNR_NAMESPACE_PREFIX PipId> std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX PipId &pip) const noexcept { return hash<int>()(pip.index); } }; -template <> struct hash<NEXTPNR_NAMESPACE_PREFIX GroupId> -{ - std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX GroupId &group) const noexcept - { - std::size_t seed = 0; - boost::hash_combine(seed, hash<int>()(group.type)); - boost::hash_combine(seed, hash<int>()(group.x)); - boost::hash_combine(seed, hash<int>()(group.y)); - return seed; - } -}; - -template <> struct hash<NEXTPNR_NAMESPACE_PREFIX DecalId> -{ - std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX DecalId &decal) const noexcept - { - std::size_t seed = 0; - boost::hash_combine(seed, hash<int>()(decal.type)); - boost::hash_combine(seed, hash<int>()(decal.index)); - return seed; - } -}; } // namespace std + +#endif
\ No newline at end of file diff --git a/cyclonev/family.cmake b/cyclonev/family.cmake index e69de29b..9d1fb9bf 100644 --- a/cyclonev/family.cmake +++ b/cyclonev/family.cmake @@ -0,0 +1,5 @@ +set(MISTRAL_ROOT "" CACHE STRING "Mistral install path") + +foreach(family_target ${family_targets}) + target_include_directories(${family_target} PRIVATE ${MISTRAL_ROOT}/lib) +endforeach() |