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; | 
