aboutsummaryrefslogtreecommitdiffstats
path: root/cyclonev
diff options
context:
space:
mode:
authorgatecat <gatecat@ds0.me>2021-04-30 18:40:24 +0100
committergatecat <gatecat@ds0.me>2021-05-15 14:54:33 +0100
commit0533818ceead805b9afc749d3a23e571e4a21543 (patch)
treea60b9bc96eafea8760536db360094c8bd98a4f81 /cyclonev
parent9f2cbe1762387ec38d358fb4c885740de89b5656 (diff)
downloadnextpnr-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.cc78
-rw-r--r--cyclonev/arch.h214
-rw-r--r--cyclonev/archdefs.h68
-rw-r--r--cyclonev/family.cmake5
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()