diff options
author | gatecat <gatecat@ds0.me> | 2021-05-02 20:40:27 +0100 |
---|---|---|
committer | gatecat <gatecat@ds0.me> | 2021-05-15 14:54:33 +0100 |
commit | c671961c188ef57637fcecae4decf55fecc30491 (patch) | |
tree | c221fbe8d6dc37dae1f1d6eb26fff15f28581631 | |
parent | b1d3eb07c3998e8ce71f770eb56d4fe96b60c785 (diff) | |
download | nextpnr-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.cc | 60 | ||||
-rw-r--r-- | cyclonev/arch.h | 47 |
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; |