aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgatecat <gatecat@ds0.me>2021-05-02 20:40:27 +0100
committergatecat <gatecat@ds0.me>2021-05-15 14:54:33 +0100
commitc671961c188ef57637fcecae4decf55fecc30491 (patch)
treec221fbe8d6dc37dae1f1d6eb26fff15f28581631
parentb1d3eb07c3998e8ce71f770eb56d4fe96b60c785 (diff)
downloadnextpnr-c671961c188ef57637fcecae4decf55fecc30491.tar.gz
nextpnr-c671961c188ef57637fcecae4decf55fecc30491.tar.bz2
nextpnr-c671961c188ef57637fcecae4decf55fecc30491.zip
cyclonev: Outline functions for creating bels/wires/pips
Signed-off-by: gatecat <gatecat@ds0.me>
-rw-r--r--cyclonev/arch.cc60
-rw-r--r--cyclonev/arch.h47
2 files changed, 104 insertions, 3 deletions
diff --git a/cyclonev/arch.cc b/cyclonev/arch.cc
index 10b7a71b..64444695 100644
--- a/cyclonev/arch.cc
+++ b/cyclonev/arch.cc
@@ -261,6 +261,66 @@ bool Arch::pack() { return true; }
bool Arch::place() { return true; }
bool Arch::route() { return true; }
+BelId Arch::add_bel(int x, int y, IdString name, IdString type, IdString bucket)
+{
+ // TODO: nothing else is using this BelId system yet...
+ // TODO (tomorrow?): we probably want a belsByTile type arrangement, similar for wires and pips, for better spacial
+ // locality
+ int z = 0;
+ BelId id;
+ // Determine a unique z-coordinate
+ while (bels.count(id = BelId(CycloneV::xy2pos(x, y), z)))
+ z++;
+ auto &bel = bels[id];
+ bel.name = name;
+ bel.type = type;
+ bel.bucket = bucket;
+ return id;
+}
+
+WireId Arch::add_wire(int x, int y, IdString name, uint64_t flags)
+{
+ std::array<IdString, 4> ids{
+ id_WIRE,
+ int2id.at(x),
+ int2id.at(y),
+ name,
+ };
+ IdStringList full_name(ids);
+ auto existing = npnr_wirebyname.find(full_name);
+ if (existing != npnr_wirebyname.end()) {
+ // Already exists, don't create anything
+ return existing->second;
+ } else {
+ // 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)))))
+ z++;
+ wires[id].name_override = name;
+ wires[id].flags = flags;
+ return id;
+ }
+}
+
+PipId Arch::add_pip(WireId src, WireId dst)
+{
+ wires[src].wires_downhill.push_back(dst);
+ wires[dst].wires_uphill.push_back(src);
+ return PipId(src.node, dst.node);
+}
+
+void Arch::add_bel_pin(BelId bel, IdString pin, PortType dir, WireId wire)
+{
+ bels[bel].pins[pin].dir = dir;
+ bels[bel].pins[pin].wire = wire;
+
+ BelPin bel_pin;
+ bel_pin.bel = bel;
+ bel_pin.pin = pin;
+ wires[wire].bel_pins.push_back(bel_pin);
+}
+
#ifdef WITH_HEAP
const std::string Arch::defaultPlacer = "heap";
#else
diff --git a/cyclonev/arch.h b/cyclonev/arch.h
index ce21a63c..1f545134 100644
--- a/cyclonev/arch.h
+++ b/cyclonev/arch.h
@@ -37,16 +37,45 @@ struct ArchArgs
std::string mistral_root;
};
+// These structures are used for fast ALM validity checking
+struct ALMInfo
+{
+ // Pointers to bels
+ std::array<BelId, 2> lut_bels;
+ std::array<BelId, 4> ff_bels;
+ // TODO: ALM configuration (L5/L6 mode, LUT input permutation, etc)
+};
+
+struct LABInfo
+{
+ std::array<ALMInfo, 10> alms;
+ // TODO: LAB configuration (control set etc)
+};
+
struct PinInfo
{
- IdString name;
WireId wire;
- PortType type;
+ PortType dir;
};
struct BelInfo
{
- // TODO
+ IdString name;
+ IdString type;
+ IdString bucket;
+ int z;
+ std::unordered_map<IdString, PinInfo> pins;
+ // Info for different kinds of bels
+ union
+ {
+ // This enables fast lookup of the associated ALM, etc
+ struct
+ {
+ uint32_t lab; // index into the list of LABs
+ uint8_t alm; // ALM index inside LAB
+ uint8_t idx; // LUT or FF index inside ALM
+ } labData;
+ };
};
// We maintain our own wire data based on mistral's. This gets us the bidirectional linking that nextpnr needs,
@@ -273,6 +302,18 @@ struct Arch : BaseArch<ArchRanges>
bool route() override;
// -------------------------------------------------
+ // Functions for device setup
+
+ BelId add_bel(int x, int y, IdString name, IdString type, IdString bucket);
+ WireId add_wire(int x, int y, IdString name, uint64_t flags = 0);
+ PipId add_pip(WireId src, WireId dst);
+
+ void add_bel_pin(BelId bel, IdString pin, PortType dir, WireId wire);
+
+ void create_lab(int x, int y);
+ void create_gpio(int x, int y);
+
+ // -------------------------------------------------
static const std::string defaultPlacer;
static const std::vector<std::string> availablePlacers;