diff options
Diffstat (limited to 'ice40')
| -rw-r--r-- | ice40/arch.cc | 293 | ||||
| -rw-r--r-- | ice40/arch.h | 46 | ||||
| -rw-r--r-- | ice40/arch_pybindings.cc | 13 | ||||
| -rw-r--r-- | ice40/archdefs.h | 67 | ||||
| -rw-r--r-- | ice40/bitstream.cc | 5 | ||||
| -rw-r--r-- | ice40/chipdb.py | 41 | ||||
| -rw-r--r-- | ice40/family.cmake | 6 | ||||
| -rw-r--r-- | ice40/gfx.cc | 488 | ||||
| -rw-r--r-- | ice40/gfx.h | 474 | ||||
| -rw-r--r-- | ice40/main.cc | 166 | ||||
| -rw-r--r-- | ice40/pack.cc | 4 | ||||
| -rw-r--r-- | ice40/pack.h | 32 | 
12 files changed, 1427 insertions, 208 deletions
diff --git a/ice40/arch.cc b/ice40/arch.cc index 72f9c1f3..adc37dbd 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -19,9 +19,13 @@  #include <algorithm>  #include <cmath> +#include "gfx.h"  #include "log.h"  #include "nextpnr.h" +#include "placer1.h" +#include "router1.h"  #include "util.h" +  NEXTPNR_NAMESPACE_BEGIN  // ----------------------------------------------------------------------- @@ -365,6 +369,49 @@ std::string Arch::getBelPackagePin(BelId bel) const      }      return "";  } + +// ----------------------------------------------------------------------- + +GroupId Arch::getGroupByName(IdString name) const +{ +    for (auto g : getGroups()) +        if (getGroupName(g) == name) +            return g; +    return GroupId(); +} + +IdString Arch::getGroupName(GroupId group) const { return IdString(); } + +std::vector<GroupId> Arch::getGroups() const +{ +    std::vector<GroupId> ret; +    return ret; +} + +std::vector<BelId> Arch::getGroupBels(GroupId group) const +{ +    std::vector<BelId> ret; +    return ret; +} + +std::vector<WireId> Arch::getGroupWires(GroupId group) const +{ +    std::vector<WireId> ret; +    return ret; +} + +std::vector<PipId> Arch::getGroupPips(GroupId group) const +{ +    std::vector<PipId> ret; +    return ret; +} + +std::vector<GroupId> Arch::getGroupGroups(GroupId group) const +{ +    std::vector<GroupId> ret; +    return ret; +} +  // -----------------------------------------------------------------------  void Arch::estimatePosition(BelId bel, int &x, int &y, bool &gb) const @@ -398,100 +445,206 @@ delay_t Arch::estimateDelay(WireId src, WireId dst) const  // ----------------------------------------------------------------------- -std::vector<GraphicElement> Arch::getFrameGraphics() const +bool Arch::place() { return placer1(getCtx()); } + +bool Arch::route() { return router1(getCtx()); } + +// ----------------------------------------------------------------------- + +DecalXY Arch::getFrameDecal() const  { -    std::vector<GraphicElement> ret; +    DecalXY decalxy; +    decalxy.decal.type = DecalId::TYPE_FRAME; +    decalxy.decal.active = true; +    return decalxy; +} -    for (int x = 0; x <= chip_info->width; x++) -        for (int y = 0; y <= chip_info->height; y++) { -            GraphicElement el; -            el.type = GraphicElement::G_LINE; -            el.x1 = x - 0.05, el.x2 = x + 0.05, el.y1 = y, el.y2 = y, el.z = 0; -            ret.push_back(el); -            el.x1 = x, el.x2 = x, el.y1 = y - 0.05, el.y2 = y + 0.05, el.z = 0; -            ret.push_back(el); -        } +DecalXY Arch::getBelDecal(BelId bel) const +{ +    DecalXY decalxy; +    decalxy.decal.type = DecalId::TYPE_BEL; +    decalxy.decal.index = bel.index; +    decalxy.decal.active = bel_to_cell.at(bel.index) != IdString(); +    return decalxy; +} -    return ret; +DecalXY Arch::getWireDecal(WireId wire) const +{ +    DecalXY decalxy; +    decalxy.decal.type = DecalId::TYPE_WIRE; +    decalxy.decal.index = wire.index; +    decalxy.decal.active = wire_to_net.at(wire.index) != IdString(); +    return decalxy;  } -std::vector<GraphicElement> Arch::getBelGraphics(BelId bel) const +DecalXY Arch::getPipDecal(PipId pip) const +{ +    DecalXY decalxy; +    decalxy.decal.type = DecalId::TYPE_PIP; +    decalxy.decal.index = pip.index; +    decalxy.decal.active = pip_to_net.at(pip.index) != IdString(); +    return decalxy; +}; + +DecalXY Arch::getGroupDecal(GroupId group) const +{ +    DecalXY decalxy; +    decalxy.decal.type = DecalId::TYPE_GROUP; +    decalxy.decal.index = (group.type << 16) | (group.x << 8) | (group.y); +    decalxy.decal.active = true; +    return decalxy; +}; + +std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const  {      std::vector<GraphicElement> ret; -    auto bel_type = getBelType(bel); - -    if (bel_type == TYPE_ICESTORM_LC) { -        GraphicElement el; -        el.type = GraphicElement::G_BOX; -        el.x1 = chip_info->bel_data[bel.index].x + 0.1; -        el.x2 = chip_info->bel_data[bel.index].x + 0.9; -        el.y1 = chip_info->bel_data[bel.index].y + 0.10 + (chip_info->bel_data[bel.index].z) * (0.8 / 8); -        el.y2 = chip_info->bel_data[bel.index].y + 0.18 + (chip_info->bel_data[bel.index].z) * (0.8 / 8); -        el.z = 0; -        ret.push_back(el); +    if (decal.type == DecalId::TYPE_FRAME) { +        for (int x = 0; x <= chip_info->width; x++) +            for (int y = 0; y <= chip_info->height; y++) { +                GraphicElement el; +                el.type = GraphicElement::G_LINE; +                el.x1 = x - 0.05, el.x2 = x + 0.05, el.y1 = y, el.y2 = y, el.z = 0; +                ret.push_back(el); +                el.x1 = x, el.x2 = x, el.y1 = y - 0.05, el.y2 = y + 0.05, el.z = 0; +                ret.push_back(el); +            } +    } + +    if (decal.type == DecalId::TYPE_WIRE) { +        WireId wire; +        wire.index = decal.index; + +        int n = chip_info->wire_data[wire.index].num_segments; +        const WireSegmentPOD *p = chip_info->wire_data[wire.index].segments.get(); + +        GraphicElement::style_t style = decal.active ? GraphicElement::G_ACTIVE : GraphicElement::G_INACTIVE; + +        for (int i = 0; i < n; i++) +            gfxTileWire(ret, p[i].x, p[i].y, GfxTileWireId(p[i].index), style);      } -    if (bel_type == TYPE_SB_IO) { -        if (chip_info->bel_data[bel.index].x == 0 || chip_info->bel_data[bel.index].x == chip_info->width - 1) { +    if (decal.type == DecalId::TYPE_BEL) { +        BelId bel; +        bel.index = decal.index; + +        auto bel_type = getBelType(bel); + +        if (bel_type == TYPE_ICESTORM_LC) {              GraphicElement el;              el.type = GraphicElement::G_BOX; -            el.x1 = chip_info->bel_data[bel.index].x + 0.1; -            el.x2 = chip_info->bel_data[bel.index].x + 0.9; -            if (chip_info->bel_data[bel.index].z == 0) { -                el.y1 = chip_info->bel_data[bel.index].y + 0.10; -                el.y2 = chip_info->bel_data[bel.index].y + 0.45; -            } else { -                el.y1 = chip_info->bel_data[bel.index].y + 0.55; -                el.y2 = chip_info->bel_data[bel.index].y + 0.90; -            } +            el.style = decal.active ? GraphicElement::G_ACTIVE : GraphicElement::G_INACTIVE; +            el.x1 = chip_info->bel_data[bel.index].x + logic_cell_x1; +            el.x2 = chip_info->bel_data[bel.index].x + logic_cell_x2; +            el.y1 = chip_info->bel_data[bel.index].y + logic_cell_y1 + +                    (chip_info->bel_data[bel.index].z) * logic_cell_pitch; +            el.y2 = chip_info->bel_data[bel.index].y + logic_cell_y2 + +                    (chip_info->bel_data[bel.index].z) * logic_cell_pitch;              el.z = 0;              ret.push_back(el); -        } else { -            GraphicElement el; -            el.type = GraphicElement::G_BOX; +              if (chip_info->bel_data[bel.index].z == 0) { -                el.x1 = chip_info->bel_data[bel.index].x + 0.10; -                el.x2 = chip_info->bel_data[bel.index].x + 0.45; +                int tx = chip_info->bel_data[bel.index].x; +                int ty = chip_info->bel_data[bel.index].y; + +                // Main switchbox +                GraphicElement main_sw; +                main_sw.type = GraphicElement::G_BOX; +                main_sw.style = GraphicElement::G_FRAME; +                main_sw.x1 = tx + main_swbox_x1; +                main_sw.x2 = tx + main_swbox_x2; +                main_sw.y1 = ty + main_swbox_y1; +                main_sw.y2 = ty + main_swbox_y2; +                ret.push_back(main_sw); + +                // Local tracks to LUT input switchbox +                GraphicElement local_sw; +                local_sw.type = GraphicElement::G_BOX; +                local_sw.style = GraphicElement::G_FRAME; +                local_sw.x1 = tx + local_swbox_x1; +                local_sw.x2 = tx + local_swbox_x2; +                local_sw.y1 = ty + local_swbox_y1; +                local_sw.y2 = ty + local_swbox_y2; +                local_sw.z = 0; +                ret.push_back(local_sw); +            } +        } + +        if (bel_type == TYPE_SB_IO) { +            if (chip_info->bel_data[bel.index].x == 0 || chip_info->bel_data[bel.index].x == chip_info->width - 1) { +                GraphicElement el; +                el.type = GraphicElement::G_BOX; +                el.x1 = chip_info->bel_data[bel.index].x + 0.1; +                el.x2 = chip_info->bel_data[bel.index].x + 0.9; +                if (chip_info->bel_data[bel.index].z == 0) { +                    el.y1 = chip_info->bel_data[bel.index].y + 0.10; +                    el.y2 = chip_info->bel_data[bel.index].y + 0.45; +                } else { +                    el.y1 = chip_info->bel_data[bel.index].y + 0.55; +                    el.y2 = chip_info->bel_data[bel.index].y + 0.90; +                } +                el.z = 0; +                ret.push_back(el);              } else { -                el.x1 = chip_info->bel_data[bel.index].x + 0.55; -                el.x2 = chip_info->bel_data[bel.index].x + 0.90; +                GraphicElement el; +                el.type = GraphicElement::G_BOX; +                if (chip_info->bel_data[bel.index].z == 0) { +                    el.x1 = chip_info->bel_data[bel.index].x + 0.10; +                    el.x2 = chip_info->bel_data[bel.index].x + 0.45; +                } else { +                    el.x1 = chip_info->bel_data[bel.index].x + 0.55; +                    el.x2 = chip_info->bel_data[bel.index].x + 0.90; +                } +                el.y1 = chip_info->bel_data[bel.index].y + 0.1; +                el.y2 = chip_info->bel_data[bel.index].y + 0.9; +                el.z = 0; +                ret.push_back(el);              } -            el.y1 = chip_info->bel_data[bel.index].y + 0.1; -            el.y2 = chip_info->bel_data[bel.index].y + 0.9; -            el.z = 0; -            ret.push_back(el);          } -    } -    if (bel_type == TYPE_ICESTORM_RAM) { -        GraphicElement el; -        el.type = GraphicElement::G_BOX; -        el.x1 = chip_info->bel_data[bel.index].x + 0.1; -        el.x2 = chip_info->bel_data[bel.index].x + 0.9; -        el.y1 = chip_info->bel_data[bel.index].y + 0.1; -        el.y2 = chip_info->bel_data[bel.index].y + 1.9; -        el.z = 0; -        ret.push_back(el); +        if (bel_type == TYPE_ICESTORM_RAM) { +            for (int i = 0; i < 2; i++) +            { +                int tx = chip_info->bel_data[bel.index].x; +                int ty = chip_info->bel_data[bel.index].y + i; + +                GraphicElement el; +                el.type = GraphicElement::G_BOX; +                el.style = decal.active ? GraphicElement::G_ACTIVE : GraphicElement::G_INACTIVE; +                el.x1 = chip_info->bel_data[bel.index].x + logic_cell_x1; +                el.x2 = chip_info->bel_data[bel.index].x + logic_cell_x2; +                el.y1 = chip_info->bel_data[bel.index].y + logic_cell_y1; +                el.y2 = chip_info->bel_data[bel.index].y + logic_cell_y2 + 7*logic_cell_pitch; +                el.z = 0; +                ret.push_back(el); + +                // Main switchbox +                GraphicElement main_sw; +                main_sw.type = GraphicElement::G_BOX; +                main_sw.style = GraphicElement::G_FRAME; +                main_sw.x1 = tx + main_swbox_x1; +                main_sw.x2 = tx + main_swbox_x2; +                main_sw.y1 = ty + main_swbox_y1; +                main_sw.y2 = ty + main_swbox_y2; +                ret.push_back(main_sw); + +                // Local tracks to LUT input switchbox +                GraphicElement local_sw; +                local_sw.type = GraphicElement::G_BOX; +                local_sw.style = GraphicElement::G_FRAME; +                local_sw.x1 = tx + local_swbox_x1; +                local_sw.x2 = tx + local_swbox_x2; +                local_sw.y1 = ty + local_swbox_y1; +                local_sw.y2 = ty + local_swbox_y2; +                local_sw.z = 0; +                ret.push_back(local_sw); +            } +        }      }      return ret;  } -std::vector<GraphicElement> Arch::getWireGraphics(WireId wire) const -{ -    std::vector<GraphicElement> ret; -    // FIXME -    return ret; -} - -std::vector<GraphicElement> Arch::getPipGraphics(PipId pip) const -{ -    std::vector<GraphicElement> ret; -    // FIXME -    return ret; -}; -  // -----------------------------------------------------------------------  bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, delay_t &delay) const diff --git a/ice40/arch.h b/ice40/arch.h index 43aa0829..a02e0ced 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -70,6 +70,11 @@ NPNR_PACKED_STRUCT(struct PipInfoPOD {      int32_t switch_index;  }); +NPNR_PACKED_STRUCT(struct WireSegmentPOD { +    int8_t x, y; +    int16_t index; +}); +  NPNR_PACKED_STRUCT(struct WireInfoPOD {      RelPtr<char> name;      int32_t num_uphill, num_downhill; @@ -79,6 +84,9 @@ NPNR_PACKED_STRUCT(struct WireInfoPOD {      BelPortPOD bel_uphill;      RelPtr<BelPortPOD> bels_downhill; +    int32_t num_segments; +    RelPtr<WireSegmentPOD> segments; +      int8_t x, y;      WireType type;      int8_t padding_0; @@ -515,9 +523,6 @@ struct Arch : BaseCtx      // -------------------------------------------------      PipId getPipByName(IdString name) const; -    IdString getPipName(PipId pip) const; - -    uint32_t getPipChecksum(PipId pip) const { return pip.index; }      void bindPip(PipId pip, IdString net, PlaceStrength strength)      { @@ -577,6 +582,10 @@ struct Arch : BaseCtx          range.e.cursor = chip_info->num_pips;          return range;      } +     +    IdString getPipName(PipId pip) const; + +    uint32_t getPipChecksum(PipId pip) const { return pip.index; }      WireId getPipSrcWire(PipId pip) const      { @@ -634,6 +643,16 @@ struct Arch : BaseCtx      // ------------------------------------------------- +    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; + +    // ------------------------------------------------- +      void estimatePosition(BelId bel, int &x, int &y, bool &gb) const;      delay_t estimateDelay(WireId src, WireId dst) const;      delay_t getDelayEpsilon() const { return 20; } @@ -643,16 +662,19 @@ struct Arch : BaseCtx      // ------------------------------------------------- -    std::vector<GraphicElement> getFrameGraphics() const; -    std::vector<GraphicElement> getBelGraphics(BelId bel) const; -    std::vector<GraphicElement> getWireGraphics(WireId wire) const; -    std::vector<GraphicElement> getPipGraphics(PipId pip) const; +    bool pack(); +    bool place(); +    bool route(); + +    // ------------------------------------------------- + +    std::vector<GraphicElement> getDecalGraphics(DecalId decal) const; -    bool allGraphicsReload = false; -    bool frameGraphicsReload = false; -    std::unordered_set<BelId> belGraphicsReload; -    std::unordered_set<WireId> wireGraphicsReload; -    std::unordered_set<PipId> pipGraphicsReload; +    DecalXY getFrameDecal() const; +    DecalXY getBelDecal(BelId bel) const; +    DecalXY getWireDecal(WireId wire) const; +    DecalXY getPipDecal(PipId pip) const; +    DecalXY getGroupDecal(GroupId group) const;      // ------------------------------------------------- diff --git a/ice40/arch_pybindings.cc b/ice40/arch_pybindings.cc index 67a37983..fd5109b4 100644 --- a/ice40/arch_pybindings.cc +++ b/ice40/arch_pybindings.cc @@ -58,7 +58,10 @@ void arch_wrap_python()      auto arch_cls = class_<Arch, Arch *, bases<BaseCtx>, boost::noncopyable>("Arch", init<ArchArgs>());      auto ctx_cls = class_<Context, Context *, bases<Arch>, boost::noncopyable>("Context", no_init) -                           .def("checksum", &Context::checksum); +                           .def("checksum", &Context::checksum) +                           .def("pack", &Context::pack) +                           .def("place", &Context::place) +                           .def("route", &Context::route);      fn_wrapper_1a<Context, decltype(&Context::getBelType), &Context::getBelType, conv_to_str<BelType>,                    conv_from_str<BelId>>::def_wrap(ctx_cls, "getBelType"); @@ -75,7 +78,7 @@ void arch_wrap_python()      fn_wrapper_1a<Context, decltype(&Context::getConflictingBelCell), &Context::getConflictingBelCell,                    conv_to_str<IdString>, conv_from_str<BelId>>::def_wrap(ctx_cls, "getConflictingBelCell");      fn_wrapper_0a<Context, decltype(&Context::getBels), &Context::getBels, wrap_context<BelRange>>::def_wrap(ctx_cls, -                                                                                                           "getBels"); +                                                                                                             "getBels");      fn_wrapper_1a<Context, decltype(&Context::getBelsAtSameTile), &Context::getBelsAtSameTile, wrap_context<BelRange>,                    conv_from_str<BelId>>::def_wrap(ctx_cls, "getBelsAtSameTile"); @@ -139,15 +142,15 @@ void arch_wrap_python()      fn_wrapper_0a<Context, decltype(&Context::getChipName), &Context::getChipName, pass_through<std::string>>::def_wrap(              ctx_cls, "getChipName");      fn_wrapper_0a<Context, decltype(&Context::archId), &Context::archId, conv_to_str<IdString>>::def_wrap(ctx_cls, -                                                                                                        "archId"); +                                                                                                          "archId");      typedef std::unordered_map<IdString, std::unique_ptr<CellInfo>> CellMap;      typedef std::unordered_map<IdString, std::unique_ptr<NetInfo>> NetMap;      readonly_wrapper<Context, decltype(&Context::cells), &Context::cells, wrap_context<CellMap &>>::def_wrap(ctx_cls, -                                                                                                           "cells"); +                                                                                                             "cells");      readonly_wrapper<Context, decltype(&Context::nets), &Context::nets, wrap_context<NetMap &>>::def_wrap(ctx_cls, -                                                                                                        "nets"); +                                                                                                          "nets");      WRAP_RANGE(Bel, conv_to_str<BelId>);      WRAP_RANGE(Wire, conv_to_str<WireId>);      WRAP_RANGE(AllPip, conv_to_str<PipId>); diff --git a/ice40/archdefs.h b/ice40/archdefs.h index be2e406d..75df678a 100644 --- a/ice40/archdefs.h +++ b/ice40/archdefs.h @@ -21,6 +21,8 @@  #error Include "archdefs.h" via "nextpnr.h" only.  #endif +#include <boost/functional/hash.hpp> +  NEXTPNR_NAMESPACE_BEGIN  typedef int delay_t; @@ -107,6 +109,47 @@ struct PipId      bool operator!=(const PipId &other) const { return index != other.index; }  }; +struct GroupId +{ +    enum : int8_t +    { +        TYPE_NONE, +        TYPE_FRAME, +        TYPE_MAIN_SW, +        TYPE_LOCAL_SW, +        TYPE_LC0_SW, +        TYPE_LC1_SW, +        TYPE_LC2_SW, +        TYPE_LC3_SW, +        TYPE_LC4_SW, +        TYPE_LC5_SW, +        TYPE_LC6_SW, +        TYPE_LC7_SW +    } 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_FRAME, +        TYPE_BEL, +        TYPE_WIRE, +        TYPE_PIP, +        TYPE_GROUP +    } 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); } +}; +  NEXTPNR_NAMESPACE_END  namespace std { @@ -135,4 +178,28 @@ template <> struct hash<NEXTPNR_NAMESPACE_PREFIX BelType> : hash<int>  template <> struct hash<NEXTPNR_NAMESPACE_PREFIX PortPin> : hash<int>  {  }; + +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 diff --git a/ice40/bitstream.cc b/ice40/bitstream.cc index 98a7a0e4..a62c6c09 100644 --- a/ice40/bitstream.cc +++ b/ice40/bitstream.cc @@ -341,9 +341,8 @@ void write_asc(const Context *ctx, std::ostream &out)                              set_config(ti, config.at(y).at(x),                                         "Cascade.IPCON_LC0" + std::to_string(lc_idx) + "_inmux02_5", true);                          else -                            set_config(ti, config.at(y).at(x), -                                       "Cascade.MULT" + std::to_string(int(tile - TILE_DSP0)) + "_LC0" + -                                               std::to_string(lc_idx) + "_inmux02_5", +                            set_config(ti, config.at(y).at(x), "Cascade.MULT" + std::to_string(int(tile - TILE_DSP0)) + +                                                                       "_LC0" + std::to_string(lc_idx) + "_inmux02_5",                                         true);                      }                  } diff --git a/ice40/chipdb.py b/ice40/chipdb.py index 931c73d1..51fe169c 100644 --- a/ice40/chipdb.py +++ b/ice40/chipdb.py @@ -11,6 +11,7 @@ group.add_argument("-b", "--binary", action="store_true")  group.add_argument("-c", "--c_file", action="store_true")  parser.add_argument("filename", type=str, help="chipdb input filename")  parser.add_argument("-p", "--portspins", type=str, help="path to portpins.inc") +parser.add_argument("-g", "--gfxh", type=str, help="path to gfx.h")  args = parser.parse_args()  endianness = "le" @@ -54,6 +55,9 @@ beltypes = dict()  tiletypes = dict()  wiretypes = dict() +gfx_wire_ids = dict() +wire_segments = dict() +  with open(args.portspins) as f:      for line in f:          line = line.replace("(", " ") @@ -66,6 +70,20 @@ with open(args.portspins) as f:          idx = len(portpins) + 1          portpins[line[1]] = idx +with open(args.gfxh) as f: +    state = 0 +    for line in f: +        if state == 0 and line.startswith("enum GfxTileWireId"): +            state = 1 +        elif state == 1 and line.startswith("};"): +            state = 0 +        elif state == 1 and (line.startswith("{") or line.strip() == ""): +            pass +        elif state == 1: +            idx = len(gfx_wire_ids) +            name = line.strip().rstrip(",") +            gfx_wire_ids[name] = idx +  beltypes["ICESTORM_LC"] = 1  beltypes["ICESTORM_RAM"] = 2  beltypes["SB_IO"] = 3 @@ -371,6 +389,10 @@ with open(args.filename, "r") as f:              if mode[1] not in wire_xy:                  wire_xy[mode[1]] = list()              wire_xy[mode[1]].append((int(line[0]), int(line[1]))) +            if mode[1] not in wire_segments: +                wire_segments[mode[1]] = set() +            if ("TILE_WIRE_" + wname[2].upper().replace("/", "_")) in gfx_wire_ids: +                wire_segments[mode[1]].add((wname[0], wname[1], gfx_wire_ids["TILE_WIRE_" + wname[2].upper().replace("/", "_")]))              continue          if mode[0] in ("buffer", "routing"): @@ -712,7 +734,7 @@ class BinaryBlobAssembler:      def finalize(self):          assert not self.finalized -        for s, index in self.strings.items(): +        for s, index in sorted(self.strings.items()):              self.l("str%d" % index, "char")              for c in s:                  self.data.append(ord(c)) @@ -947,7 +969,7 @@ for wire in range(num_wires):      if wire in wire_downhill_belports:          num_bels_downhill = len(wire_downhill_belports[wire])          bba.l("wire%d_downbels" % wire, "BelPortPOD") -        for belport in wire_downhill_belports[wire]: +        for belport in sorted(wire_downhill_belports[wire]):              bba.u32(belport[0], "bel_index")              bba.u32(portpins[belport[1]], "port")      else: @@ -1040,7 +1062,7 @@ for t in range(num_tile_types):      tileinfo.append(ti)  bba.l("wire_data_%s" % dev_name, "WireInfoPOD") -for info in wireinfo: +for wire, info in enumerate(wireinfo):      bba.s(info["name"], "name")      bba.u32(info["num_uphill"], "num_uphill")      bba.u32(info["num_downhill"], "num_downhill") @@ -1050,11 +1072,24 @@ for info in wireinfo:      bba.u32(info["uphill_bel"], "bel_uphill.bel_index")      bba.u32(info["uphill_pin"], "bel_uphill.port")      bba.r(info["list_bels_downhill"], "bels_downhill") +    bba.u32(len(wire_segments[wire]), "num_segments") +    if len(wire_segments[wire]): +        bba.r("wire_segments_%d" % wire, "segments") +    else: +        bba.u32(0, "segments")      bba.u8(info["x"], "x")      bba.u8(info["y"], "y")      bba.u8(wiretypes[wire_type(info["name"])], "type")      bba.u8(0, "padding") +for wire in range(num_wires): +    if len(wire_segments[wire]): +        bba.l("wire_segments_%d" % wire, "WireSegmentPOD") +        for seg in sorted(wire_segments[wire]): +            bba.u8(seg[0], "x") +            bba.u8(seg[1], "y") +            bba.u16(seg[2], "index") +  bba.l("pip_data_%s" % dev_name, "PipInfoPOD")  for info in pipinfo:      bba.u32(info["src"], "src") diff --git a/ice40/family.cmake b/ice40/family.cmake index e6cefecb..9af06f82 100644 --- a/ice40/family.cmake +++ b/ice40/family.cmake @@ -21,8 +21,9 @@ if (MSVC)          set(DEV_TXT_DB ${ICEBOX_ROOT}/chipdb-${dev}.txt)          set(DEV_CC_DB ${CMAKE_CURRENT_SOURCE_DIR}/ice40/chipdbs/chipdb-${dev}.bin)          set(DEV_PORTS_INC ${CMAKE_CURRENT_SOURCE_DIR}/ice40/portpins.inc) +        set(DEV_GFXH ${CMAKE_CURRENT_SOURCE_DIR}/ice40/gfx.h)          add_custom_command(OUTPUT ${DEV_CC_DB} -                COMMAND ${PYTHON_EXECUTABLE} ${DB_PY} -b -p ${DEV_PORTS_INC} ${DEV_TXT_DB} > ${DEV_CC_DB} +                COMMAND ${PYTHON_EXECUTABLE} ${DB_PY} -b -p ${DEV_PORTS_INC} -g ${DEV_GFXH} ${DEV_TXT_DB} > ${DEV_CC_DB}                  DEPENDS ${DEV_TXT_DB} ${DB_PY}                  )          target_sources(ice40_chipdb PRIVATE ${DEV_CC_DB}) @@ -37,8 +38,9 @@ else()          set(DEV_TXT_DB ${ICEBOX_ROOT}/chipdb-${dev}.txt)          set(DEV_CC_DB ${CMAKE_CURRENT_SOURCE_DIR}/ice40/chipdbs/chipdb-${dev}.cc)          set(DEV_PORTS_INC ${CMAKE_CURRENT_SOURCE_DIR}/ice40/portpins.inc) +        set(DEV_GFXH ${CMAKE_CURRENT_SOURCE_DIR}/ice40/gfx.h)          add_custom_command(OUTPUT ${DEV_CC_DB} -                COMMAND ${PYTHON_EXECUTABLE} ${DB_PY} -c -p ${DEV_PORTS_INC} ${DEV_TXT_DB} > ${DEV_CC_DB}.new +                COMMAND ${PYTHON_EXECUTABLE} ${DB_PY} -c -p ${DEV_PORTS_INC} -g ${DEV_GFXH} ${DEV_TXT_DB} > ${DEV_CC_DB}.new                  COMMAND mv ${DEV_CC_DB}.new ${DEV_CC_DB}                  DEPENDS ${DEV_TXT_DB} ${DB_PY}                  ) diff --git a/ice40/gfx.cc b/ice40/gfx.cc new file mode 100644 index 00000000..19aaed13 --- /dev/null +++ b/ice40/gfx.cc @@ -0,0 +1,488 @@ +/* + *  nextpnr -- Next Generation Place and Route + * + *  Copyright (C) 2018  Clifford Wolf <clifford@symbioticeda.com> + * + *  Permission to use, copy, modify, and/or distribute this software for any + *  purpose with or without fee is hereby granted, provided that the above + *  copyright notice and this permission notice appear in all copies. + * + *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "gfx.h" + +NEXTPNR_NAMESPACE_BEGIN + +void gfxTileWire(std::vector<GraphicElement> &g, int x, int y, GfxTileWireId id, GraphicElement::style_t style) +{ +    GraphicElement el; +    el.type = GraphicElement::G_LINE; +    el.style = style; + +    // Horizontal Span-4 Wires + +    if (id >= TILE_WIRE_SP4_H_L_36 && id <= TILE_WIRE_SP4_H_L_47) { +        int idx = (id - TILE_WIRE_SP4_H_L_36) + 48; + +        float y1 = y + 1.0 - (0.03 + 0.0025 * (60 - (idx ^ 1))); +        float y2 = y + 1.0 - (0.03 + 0.0025 * (60 - idx)); + +        el.x1 = x; +        el.x2 = x + 0.01; +        el.y1 = y1; +        el.y2 = y1; +        g.push_back(el); + +        el.x1 = x + 0.01; +        el.x2 = x + 0.02; +        el.y1 = y1; +        el.y2 = y2; +        g.push_back(el); + +        el.x1 = x + 0.02; +        el.x2 = x + 0.9; +        el.y1 = y2; +        el.y2 = y2; +        g.push_back(el); + +        el.x1 = x + main_swbox_x1 + 0.0025 * (idx + 35); +        el.x2 = el.x1; +        el.y1 = y2; +        el.y2 = y + main_swbox_y2; +        g.push_back(el); +    } + +    if (id >= TILE_WIRE_SP4_H_R_0 && id <= TILE_WIRE_SP4_H_R_47) { +        int idx = id - TILE_WIRE_SP4_H_R_0; + +        float y1 = y + 1.0 - (0.03 + 0.0025 * (60 - idx)); +        float y2 = y + 1.0 - (0.03 + 0.0025 * (60 - (idx ^ 1))); +        float y3 = y + 1.0 - (0.03 + 0.0025 * (60 - (idx ^ 1) - 12)); + +        if (idx >= 12) { +            el.x1 = x; +            el.x2 = x + 0.01; +            el.y1 = y1; +            el.y2 = y1; +            g.push_back(el); + +            el.x1 = x + 0.01; +            el.x2 = x + 0.02; +            el.y1 = y1; +            el.y2 = y2; +            g.push_back(el); +        } + +        el.x1 = x + 0.02; +        el.x2 = x + 0.9; +        el.y1 = y2; +        el.y2 = y2; +        g.push_back(el); + +        el.x1 = x + 0.9; +        el.x2 = x + 1.0; +        el.y1 = y2; +        el.y2 = y3; +        g.push_back(el); + +        el.x1 = x + main_swbox_x1 + 0.0025 * ((idx ^ 1) + 35); +        el.x2 = el.x1; +        el.y1 = y2; +        el.y2 = y + main_swbox_y2; +        g.push_back(el); +    } + +    // Vertical Span-4 Wires + +    if (id >= TILE_WIRE_SP4_V_T_36 && id <= TILE_WIRE_SP4_V_T_47) { +        int idx = (id - TILE_WIRE_SP4_V_T_36) + 48; + +        float x1 = x + 0.03 + 0.0025 * (60 - (idx ^ 1)); +        float x2 = x + 0.03 + 0.0025 * (60 - idx); + +        el.y1 = y + 1.00; +        el.y2 = y + 0.99; +        el.x1 = x1; +        el.x2 = x1; +        g.push_back(el); + +        el.y1 = y + 0.99; +        el.y2 = y + 0.98; +        el.x1 = x1; +        el.x2 = x2; +        g.push_back(el); + +        el.y1 = y + 0.98; +        el.y2 = y + 0.10; +        el.x1 = x2; +        el.x2 = x2; +        g.push_back(el); + +        el.y1 = y + 1.0 - (0.03 + 0.0025 * (270 - idx)); +        el.y2 = el.y1; +        el.x1 = x2; +        el.x2 = x + main_swbox_x1; +        g.push_back(el); +    } + +    if (id >= TILE_WIRE_SP4_V_B_0 && id <= TILE_WIRE_SP4_V_B_47) { +        int idx = id - TILE_WIRE_SP4_V_B_0; + +        float x1 = x + 0.03 + 0.0025 * (60 - idx); +        float x2 = x + 0.03 + 0.0025 * (60 - (idx ^ 1)); +        float x3 = x + 0.03 + 0.0025 * (60 - (idx ^ 1) - 12); + +        if (idx >= 12) { +            el.y1 = y + 1.00; +            el.y2 = y + 0.99; +            el.x1 = x1; +            el.x2 = x1; +            g.push_back(el); + +            el.y1 = y + 0.99; +            el.y2 = y + 0.98; +            el.x1 = x1; +            el.x2 = x2; +            g.push_back(el); +        } + +        el.y1 = y + 0.98; +        el.y2 = y + 0.10; +        el.x1 = x2; +        el.x2 = x2; +        g.push_back(el); + +        el.y1 = y + 0.10; +        el.y2 = y; +        el.x1 = x2; +        el.x2 = x3; +        g.push_back(el); + +        el.y1 = y + 1.0 - (0.03 + 0.0025 * (145 - (idx ^ 1))); +        el.y2 = el.y1; +        el.x1 = x; +        el.x2 = x2; +        g.push_back(el); + +        el.y1 = y + 1.0 - (0.03 + 0.0025 * (270 - (idx ^ 1))); +        el.y2 = el.y1; +        el.x1 = x2; +        el.x2 = x + main_swbox_x1; +        g.push_back(el); +    } + +    // Horizontal Span-12 Wires + +    if (id >= TILE_WIRE_SP12_H_L_22 && id <= TILE_WIRE_SP12_H_L_23) { +        int idx = (id - TILE_WIRE_SP12_H_L_22) + 24; + +        float y1 = y + 1.0 - (0.03 + 0.0025 * (90 - (idx ^ 1))); +        float y2 = y + 1.0 - (0.03 + 0.0025 * (90 - idx)); + +        el.x1 = x; +        el.x2 = x + 0.01; +        el.y1 = y1; +        el.y2 = y1; +        g.push_back(el); + +        el.x1 = x + 0.01; +        el.x2 = x + 0.02; +        el.y1 = y1; +        el.y2 = y2; +        g.push_back(el); + +        el.x1 = x + 0.02; +        el.x2 = x + 0.98333; +        el.y1 = y2; +        el.y2 = y2; +        g.push_back(el); + +        el.x1 = x + main_swbox_x1 + 0.0025 * (idx + 5); +        el.x2 = el.x1; +        el.y1 = y2; +        el.y2 = y + main_swbox_y2; +        g.push_back(el); +    } + +    if (id >= TILE_WIRE_SP12_H_R_0 && id <= TILE_WIRE_SP12_H_R_23) { +        int idx = id - TILE_WIRE_SP12_H_R_0; + +        float y1 = y + 1.0 - (0.03 + 0.0025 * (90 - idx)); +        float y2 = y + 1.0 - (0.03 + 0.0025 * (90 - (idx ^ 1))); +        float y3 = y + 1.0 - (0.03 + 0.0025 * (90 - (idx ^ 1) - 2)); + +        if (idx >= 2) { +            el.x1 = x; +            el.x2 = x + 0.01; +            el.y1 = y1; +            el.y2 = y1; +            g.push_back(el); + +            el.x1 = x + 0.01; +            el.x2 = x + 0.02; +            el.y1 = y1; +            el.y2 = y2; +            g.push_back(el); +        } + +        el.x1 = x + 0.02; +        el.x2 = x + 0.98333; +        el.y1 = y2; +        el.y2 = y2; +        g.push_back(el); + +        el.x1 = x + 0.98333; +        el.x2 = x + 1.0; +        el.y1 = y2; +        el.y2 = y3; +        g.push_back(el); + +        el.x1 = x + main_swbox_x1 + 0.0025 * ((idx ^ 1) + 5); +        el.x2 = el.x1; +        el.y1 = y2; +        el.y2 = y + main_swbox_y2; +        g.push_back(el); +    } + +    // Vertical Right Span-4 + +    if (id >= TILE_WIRE_SP4_R_V_B_0 && id <= TILE_WIRE_SP4_R_V_B_47) { +        int idx = id - TILE_WIRE_SP4_R_V_B_0; + +        float y1 = y + 1.0 - (0.03 + 0.0025 * (145 - (idx ^ 1))); + +        el.y1 = y1; +        el.y2 = y1; +        el.x1 = x + main_swbox_x2; +        el.x2 = x + 1.0; +        g.push_back(el); +    } + +    // Vertical Span-12 Wires + +    if (id >= TILE_WIRE_SP12_V_T_22 && id <= TILE_WIRE_SP12_V_T_23) { +        int idx = (id - TILE_WIRE_SP12_V_T_22) + 24; + +        float x1 = x + 0.03 + 0.0025 * (90 - (idx ^ 1)); +        float x2 = x + 0.03 + 0.0025 * (90 - idx); + +        el.y1 = y + 1.00; +        el.y2 = y + 0.99; +        el.x1 = x1; +        el.x2 = x1; +        g.push_back(el); + +        el.y1 = y + 0.99; +        el.y2 = y + 0.98; +        el.x1 = x1; +        el.x2 = x2; +        g.push_back(el); + +        el.y1 = y + 0.98; +        el.y2 = y + 0.01667; +        el.x1 = x2; +        el.x2 = x2; +        g.push_back(el); + +        el.y1 = y + 1.0 - (0.03 + 0.0025 * (300 - idx)); +        el.y2 = el.y1; +        el.x1 = x2; +        el.x2 = x + main_swbox_x1; +        g.push_back(el); +    } + +    if (id >= TILE_WIRE_SP12_V_B_0 && id <= TILE_WIRE_SP12_V_B_23) { +        int idx = id - TILE_WIRE_SP12_V_B_0; + +        float x1 = x + 0.03 + 0.0025 * (90 - idx); +        float x2 = x + 0.03 + 0.0025 * (90 - (idx ^ 1)); +        float x3 = x + 0.03 + 0.0025 * (90 - (idx ^ 1) - 2); + +        if (idx >= 2) { +            el.y1 = y + 1.00; +            el.y2 = y + 0.99; +            el.x1 = x1; +            el.x2 = x1; +            g.push_back(el); + +            el.y1 = y + 0.99; +            el.y2 = y + 0.98; +            el.x1 = x1; +            el.x2 = x2; +            g.push_back(el); +        } + +        el.y1 = y + 0.98; +        el.y2 = y + 0.01667; +        el.x1 = x2; +        el.x2 = x2; +        g.push_back(el); + +        el.y1 = y + 0.01667; +        el.y2 = y; +        el.x1 = x2; +        el.x2 = x3; +        g.push_back(el); + +        el.y1 = y + 1.0 - (0.03 + 0.0025 * (300 - (idx ^ 1))); +        el.y2 = el.y1; +        el.x1 = x2; +        el.x2 = x + main_swbox_x1; +        g.push_back(el); +    } + +    // Global2Local + +    if (id >= TILE_WIRE_GLB2LOCAL_0 && id <= TILE_WIRE_GLB2LOCAL_3) { +        int idx = id - TILE_WIRE_GLB2LOCAL_0; +        el.x1 = x + main_swbox_x1 + 0.005 * (idx + 5); +        el.x2 = el.x1; +        el.y1 = y + main_swbox_y1; +        el.y2 = el.y1 - 0.02; +        g.push_back(el); +    } + +    // GlobalNets + +    if (id >= TILE_WIRE_GLB_NETWK_0 && id <= TILE_WIRE_GLB_NETWK_7) { +        int idx = id - TILE_WIRE_GLB_NETWK_0; +        el.x1 = x + main_swbox_x1 - 0.05; +        el.x2 = x + main_swbox_x1; +        el.y1 = y + main_swbox_y1 + 0.005 * (13 - idx); +        el.y2 = el.y1; +        g.push_back(el); +    } + +    // Neighbours + +    if (id >= TILE_WIRE_NEIGH_OP_BNL_0 && id <= TILE_WIRE_NEIGH_OP_TOP_7) { +        int idx = id - TILE_WIRE_NEIGH_OP_BNL_0; +        el.y1 = y + main_swbox_y2 - (0.0025 * (idx + 10) + 0.01 * (idx / 8)); +        el.y2 = el.y1; +        el.x1 = x + main_swbox_x1 - 0.05; +        el.x2 = x + main_swbox_x1; +        g.push_back(el); +    } + +    // Local Tracks + +    if (id >= TILE_WIRE_LOCAL_G0_0 && id <= TILE_WIRE_LOCAL_G3_7) { +        int idx = id - TILE_WIRE_LOCAL_G0_0; +        el.x1 = x + main_swbox_x2; +        el.x2 = x + local_swbox_x1; +        float yoff = y + (local_swbox_y1 + local_swbox_y2) / 2 - 0.005 * 16 - 0.075; +        el.y1 = yoff + 0.005 * idx + 0.05 * (idx / 8); +        el.y2 = el.y1; +        g.push_back(el); +    } + +    // LC Inputs + +    if (id >= TILE_WIRE_LUTFF_0_IN_0 && id <= TILE_WIRE_LUTFF_7_IN_3) { +        int idx = id - TILE_WIRE_LUTFF_0_IN_0; +        int z = idx / 4; +        int input = idx % 4; +        el.x1 = x + local_swbox_x2; +        el.x2 = x + logic_cell_x1; +        el.y1 = y + (logic_cell_y1 + logic_cell_y2) / 2 - 0.0075 + (0.005 * input) + z * logic_cell_pitch; +        el.y2 = el.y1; +        g.push_back(el); +    } + +    // LC Outputs + +    if (id >= TILE_WIRE_LUTFF_0_OUT && id <= TILE_WIRE_LUTFF_7_OUT) { +        int idx = id - TILE_WIRE_LUTFF_0_OUT; + +        float y1 = y + 1.0 - (0.03 + 0.0025 * (152 + idx)); + +        el.y1 = y1; +        el.y2 = y1; +        el.x1 = x + main_swbox_x2; +        el.x2 = x + 0.97 + 0.0025 * (7 - idx); +        g.push_back(el); + +        el.y1 = y1; +        el.y2 = y + (logic_cell_y1 + logic_cell_y2) / 2 + idx * logic_cell_pitch; +        el.x1 = el.x2; +        g.push_back(el); + +        el.y1 = el.y2; +        el.x1 = x + logic_cell_x2; +        g.push_back(el); +    } + +    // LC Control + +    if (id >= TILE_WIRE_LUTFF_GLOBAL_CEN && id <= TILE_WIRE_LUTFF_GLOBAL_S_R) { +        int idx = id - TILE_WIRE_LUTFF_GLOBAL_CEN; + +        el.x1 = x + main_swbox_x2 - 0.005 * (idx + 5); +        el.x2 = el.x1; +        el.y1 = y + main_swbox_y1; +        el.y2 = el.y1 - 0.005 * (idx + 2); +        g.push_back(el); + +        el.y1 = el.y2; +        el.x2 = x + logic_cell_x2 - 0.005 * (2 - idx + 5); +        g.push_back(el); + +        el.y2 = y + logic_cell_y1; +        el.x1 = el.x2; +        g.push_back(el); + +        for (int i = 0; i < 7; i++) { +            el.y1 = y + logic_cell_y2 + i * logic_cell_pitch; +            el.y2 = y + logic_cell_y1 + (i + 1) * logic_cell_pitch; +            g.push_back(el); +        } +    } + +    // LC Cascade + +    if (id >= TILE_WIRE_LUTFF_0_LOUT && id <= TILE_WIRE_LUTFF_6_LOUT) { +        int idx = id - TILE_WIRE_LUTFF_0_LOUT; +        el.x1 = x + logic_cell_x1 + 0.005 * 5; +        el.x2 = el.x1; +        el.y1 = y + logic_cell_y2 + idx * logic_cell_pitch; +        el.y2 = y + logic_cell_y1 + (idx + 1) * logic_cell_pitch; +        g.push_back(el); +    } + +    // Carry Chain + +    if (id >= TILE_WIRE_LUTFF_0_COUT && id <= TILE_WIRE_LUTFF_7_COUT) { +        int idx = id - TILE_WIRE_LUTFF_0_COUT; +        el.x1 = x + logic_cell_x1 + 0.005 * 3; +        el.x2 = el.x1; +        el.y1 = y + logic_cell_y2 + idx * logic_cell_pitch; +        el.y2 = y + (idx < 7 ? logic_cell_y1 + (idx + 1) * logic_cell_pitch : 1.0); +        g.push_back(el); +    } + +    if (id == TILE_WIRE_CARRY_IN) { +        el.x1 = x + logic_cell_x1 + 0.005 * 3; +        el.x2 = el.x1; +        el.y1 = y; +        el.y2 = y + 0.01; +        g.push_back(el); +    } + +    if (id == TILE_WIRE_CARRY_IN_MUX) { +        el.x1 = x + logic_cell_x1 + 0.005 * 3; +        el.x2 = el.x1; +        el.y1 = y + 0.02; +        el.y2 = y + logic_cell_y1; +        g.push_back(el); +    } +} + +NEXTPNR_NAMESPACE_END diff --git a/ice40/gfx.h b/ice40/gfx.h new file mode 100644 index 00000000..a65f7683 --- /dev/null +++ b/ice40/gfx.h @@ -0,0 +1,474 @@ +/* + *  nextpnr -- Next Generation Place and Route + * + *  Copyright (C) 2018  Clifford Wolf <clifford@symbioticeda.com> + * + *  Permission to use, copy, modify, and/or distribute this software for any + *  purpose with or without fee is hereby granted, provided that the above + *  copyright notice and this permission notice appear in all copies. + * + *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#ifndef GFX_H +#define GFX_H + +#include "nextpnr.h" + +NEXTPNR_NAMESPACE_BEGIN + +const float main_swbox_x1 = 0.35; +const float main_swbox_x2 = 0.60; +const float main_swbox_y1 = 0.05; +const float main_swbox_y2 = 0.73; + +const float local_swbox_x1 = 0.63; +const float local_swbox_x2 = 0.73; +const float local_swbox_y1 = 0.05; +const float local_swbox_y2 = 0.55; + +const float logic_cell_x1 = 0.76; +const float logic_cell_x2 = 0.95; +const float logic_cell_y1 = 0.05; +const float logic_cell_y2 = 0.10; +const float logic_cell_pitch = 0.0625; + +enum GfxTileWireId +{ +    TILE_WIRE_GLB2LOCAL_0, +    TILE_WIRE_GLB2LOCAL_1, +    TILE_WIRE_GLB2LOCAL_2, +    TILE_WIRE_GLB2LOCAL_3, + +    TILE_WIRE_GLB_NETWK_0, +    TILE_WIRE_GLB_NETWK_1, +    TILE_WIRE_GLB_NETWK_2, +    TILE_WIRE_GLB_NETWK_3, +    TILE_WIRE_GLB_NETWK_4, +    TILE_WIRE_GLB_NETWK_5, +    TILE_WIRE_GLB_NETWK_6, +    TILE_WIRE_GLB_NETWK_7, + +    TILE_WIRE_LOCAL_G0_0, +    TILE_WIRE_LOCAL_G0_1, +    TILE_WIRE_LOCAL_G0_2, +    TILE_WIRE_LOCAL_G0_3, +    TILE_WIRE_LOCAL_G0_4, +    TILE_WIRE_LOCAL_G0_5, +    TILE_WIRE_LOCAL_G0_6, +    TILE_WIRE_LOCAL_G0_7, + +    TILE_WIRE_LOCAL_G1_0, +    TILE_WIRE_LOCAL_G1_1, +    TILE_WIRE_LOCAL_G1_2, +    TILE_WIRE_LOCAL_G1_3, +    TILE_WIRE_LOCAL_G1_4, +    TILE_WIRE_LOCAL_G1_5, +    TILE_WIRE_LOCAL_G1_6, +    TILE_WIRE_LOCAL_G1_7, + +    TILE_WIRE_LOCAL_G2_0, +    TILE_WIRE_LOCAL_G2_1, +    TILE_WIRE_LOCAL_G2_2, +    TILE_WIRE_LOCAL_G2_3, +    TILE_WIRE_LOCAL_G2_4, +    TILE_WIRE_LOCAL_G2_5, +    TILE_WIRE_LOCAL_G2_6, +    TILE_WIRE_LOCAL_G2_7, + +    TILE_WIRE_LOCAL_G3_0, +    TILE_WIRE_LOCAL_G3_1, +    TILE_WIRE_LOCAL_G3_2, +    TILE_WIRE_LOCAL_G3_3, +    TILE_WIRE_LOCAL_G3_4, +    TILE_WIRE_LOCAL_G3_5, +    TILE_WIRE_LOCAL_G3_6, +    TILE_WIRE_LOCAL_G3_7, + +    TILE_WIRE_CARRY_IN, +    TILE_WIRE_CARRY_IN_MUX, + +    TILE_WIRE_LUTFF_0_IN_0, +    TILE_WIRE_LUTFF_0_IN_1, +    TILE_WIRE_LUTFF_0_IN_2, +    TILE_WIRE_LUTFF_0_IN_3, + +    TILE_WIRE_LUTFF_1_IN_0, +    TILE_WIRE_LUTFF_1_IN_1, +    TILE_WIRE_LUTFF_1_IN_2, +    TILE_WIRE_LUTFF_1_IN_3, + +    TILE_WIRE_LUTFF_2_IN_0, +    TILE_WIRE_LUTFF_2_IN_1, +    TILE_WIRE_LUTFF_2_IN_2, +    TILE_WIRE_LUTFF_2_IN_3, + +    TILE_WIRE_LUTFF_3_IN_0, +    TILE_WIRE_LUTFF_3_IN_1, +    TILE_WIRE_LUTFF_3_IN_2, +    TILE_WIRE_LUTFF_3_IN_3, + +    TILE_WIRE_LUTFF_4_IN_0, +    TILE_WIRE_LUTFF_4_IN_1, +    TILE_WIRE_LUTFF_4_IN_2, +    TILE_WIRE_LUTFF_4_IN_3, + +    TILE_WIRE_LUTFF_5_IN_0, +    TILE_WIRE_LUTFF_5_IN_1, +    TILE_WIRE_LUTFF_5_IN_2, +    TILE_WIRE_LUTFF_5_IN_3, + +    TILE_WIRE_LUTFF_6_IN_0, +    TILE_WIRE_LUTFF_6_IN_1, +    TILE_WIRE_LUTFF_6_IN_2, +    TILE_WIRE_LUTFF_6_IN_3, + +    TILE_WIRE_LUTFF_7_IN_0, +    TILE_WIRE_LUTFF_7_IN_1, +    TILE_WIRE_LUTFF_7_IN_2, +    TILE_WIRE_LUTFF_7_IN_3, + +    TILE_WIRE_LUTFF_0_LOUT, +    TILE_WIRE_LUTFF_1_LOUT, +    TILE_WIRE_LUTFF_2_LOUT, +    TILE_WIRE_LUTFF_3_LOUT, +    TILE_WIRE_LUTFF_4_LOUT, +    TILE_WIRE_LUTFF_5_LOUT, +    TILE_WIRE_LUTFF_6_LOUT, + +    TILE_WIRE_LUTFF_0_OUT, +    TILE_WIRE_LUTFF_1_OUT, +    TILE_WIRE_LUTFF_2_OUT, +    TILE_WIRE_LUTFF_3_OUT, +    TILE_WIRE_LUTFF_4_OUT, +    TILE_WIRE_LUTFF_5_OUT, +    TILE_WIRE_LUTFF_6_OUT, +    TILE_WIRE_LUTFF_7_OUT, + +    TILE_WIRE_LUTFF_0_COUT, +    TILE_WIRE_LUTFF_1_COUT, +    TILE_WIRE_LUTFF_2_COUT, +    TILE_WIRE_LUTFF_3_COUT, +    TILE_WIRE_LUTFF_4_COUT, +    TILE_WIRE_LUTFF_5_COUT, +    TILE_WIRE_LUTFF_6_COUT, +    TILE_WIRE_LUTFF_7_COUT, + +    TILE_WIRE_LUTFF_GLOBAL_CEN, +    TILE_WIRE_LUTFF_GLOBAL_CLK, +    TILE_WIRE_LUTFF_GLOBAL_S_R, + +    TILE_WIRE_NEIGH_OP_BNL_0, +    TILE_WIRE_NEIGH_OP_BNL_1, +    TILE_WIRE_NEIGH_OP_BNL_2, +    TILE_WIRE_NEIGH_OP_BNL_3, +    TILE_WIRE_NEIGH_OP_BNL_4, +    TILE_WIRE_NEIGH_OP_BNL_5, +    TILE_WIRE_NEIGH_OP_BNL_6, +    TILE_WIRE_NEIGH_OP_BNL_7, + +    TILE_WIRE_NEIGH_OP_BNR_0, +    TILE_WIRE_NEIGH_OP_BNR_1, +    TILE_WIRE_NEIGH_OP_BNR_2, +    TILE_WIRE_NEIGH_OP_BNR_3, +    TILE_WIRE_NEIGH_OP_BNR_4, +    TILE_WIRE_NEIGH_OP_BNR_5, +    TILE_WIRE_NEIGH_OP_BNR_6, +    TILE_WIRE_NEIGH_OP_BNR_7, + +    TILE_WIRE_NEIGH_OP_BOT_0, +    TILE_WIRE_NEIGH_OP_BOT_1, +    TILE_WIRE_NEIGH_OP_BOT_2, +    TILE_WIRE_NEIGH_OP_BOT_3, +    TILE_WIRE_NEIGH_OP_BOT_4, +    TILE_WIRE_NEIGH_OP_BOT_5, +    TILE_WIRE_NEIGH_OP_BOT_6, +    TILE_WIRE_NEIGH_OP_BOT_7, + +    TILE_WIRE_NEIGH_OP_LFT_0, +    TILE_WIRE_NEIGH_OP_LFT_1, +    TILE_WIRE_NEIGH_OP_LFT_2, +    TILE_WIRE_NEIGH_OP_LFT_3, +    TILE_WIRE_NEIGH_OP_LFT_4, +    TILE_WIRE_NEIGH_OP_LFT_5, +    TILE_WIRE_NEIGH_OP_LFT_6, +    TILE_WIRE_NEIGH_OP_LFT_7, + +    TILE_WIRE_NEIGH_OP_RGT_0, +    TILE_WIRE_NEIGH_OP_RGT_1, +    TILE_WIRE_NEIGH_OP_RGT_2, +    TILE_WIRE_NEIGH_OP_RGT_3, +    TILE_WIRE_NEIGH_OP_RGT_4, +    TILE_WIRE_NEIGH_OP_RGT_5, +    TILE_WIRE_NEIGH_OP_RGT_6, +    TILE_WIRE_NEIGH_OP_RGT_7, + +    TILE_WIRE_NEIGH_OP_TNL_0, +    TILE_WIRE_NEIGH_OP_TNL_1, +    TILE_WIRE_NEIGH_OP_TNL_2, +    TILE_WIRE_NEIGH_OP_TNL_3, +    TILE_WIRE_NEIGH_OP_TNL_4, +    TILE_WIRE_NEIGH_OP_TNL_5, +    TILE_WIRE_NEIGH_OP_TNL_6, +    TILE_WIRE_NEIGH_OP_TNL_7, + +    TILE_WIRE_NEIGH_OP_TNR_0, +    TILE_WIRE_NEIGH_OP_TNR_1, +    TILE_WIRE_NEIGH_OP_TNR_2, +    TILE_WIRE_NEIGH_OP_TNR_3, +    TILE_WIRE_NEIGH_OP_TNR_4, +    TILE_WIRE_NEIGH_OP_TNR_5, +    TILE_WIRE_NEIGH_OP_TNR_6, +    TILE_WIRE_NEIGH_OP_TNR_7, + +    TILE_WIRE_NEIGH_OP_TOP_0, +    TILE_WIRE_NEIGH_OP_TOP_1, +    TILE_WIRE_NEIGH_OP_TOP_2, +    TILE_WIRE_NEIGH_OP_TOP_3, +    TILE_WIRE_NEIGH_OP_TOP_4, +    TILE_WIRE_NEIGH_OP_TOP_5, +    TILE_WIRE_NEIGH_OP_TOP_6, +    TILE_WIRE_NEIGH_OP_TOP_7, + +    TILE_WIRE_SP4_V_B_0, +    TILE_WIRE_SP4_V_B_1, +    TILE_WIRE_SP4_V_B_2, +    TILE_WIRE_SP4_V_B_3, +    TILE_WIRE_SP4_V_B_4, +    TILE_WIRE_SP4_V_B_5, +    TILE_WIRE_SP4_V_B_6, +    TILE_WIRE_SP4_V_B_7, +    TILE_WIRE_SP4_V_B_8, +    TILE_WIRE_SP4_V_B_9, +    TILE_WIRE_SP4_V_B_10, +    TILE_WIRE_SP4_V_B_11, +    TILE_WIRE_SP4_V_B_12, +    TILE_WIRE_SP4_V_B_13, +    TILE_WIRE_SP4_V_B_14, +    TILE_WIRE_SP4_V_B_15, +    TILE_WIRE_SP4_V_B_16, +    TILE_WIRE_SP4_V_B_17, +    TILE_WIRE_SP4_V_B_18, +    TILE_WIRE_SP4_V_B_19, +    TILE_WIRE_SP4_V_B_20, +    TILE_WIRE_SP4_V_B_21, +    TILE_WIRE_SP4_V_B_22, +    TILE_WIRE_SP4_V_B_23, +    TILE_WIRE_SP4_V_B_24, +    TILE_WIRE_SP4_V_B_25, +    TILE_WIRE_SP4_V_B_26, +    TILE_WIRE_SP4_V_B_27, +    TILE_WIRE_SP4_V_B_28, +    TILE_WIRE_SP4_V_B_29, +    TILE_WIRE_SP4_V_B_30, +    TILE_WIRE_SP4_V_B_31, +    TILE_WIRE_SP4_V_B_32, +    TILE_WIRE_SP4_V_B_33, +    TILE_WIRE_SP4_V_B_34, +    TILE_WIRE_SP4_V_B_35, +    TILE_WIRE_SP4_V_B_36, +    TILE_WIRE_SP4_V_B_37, +    TILE_WIRE_SP4_V_B_38, +    TILE_WIRE_SP4_V_B_39, +    TILE_WIRE_SP4_V_B_40, +    TILE_WIRE_SP4_V_B_41, +    TILE_WIRE_SP4_V_B_42, +    TILE_WIRE_SP4_V_B_43, +    TILE_WIRE_SP4_V_B_44, +    TILE_WIRE_SP4_V_B_45, +    TILE_WIRE_SP4_V_B_46, +    TILE_WIRE_SP4_V_B_47, + +    TILE_WIRE_SP4_V_T_36, +    TILE_WIRE_SP4_V_T_37, +    TILE_WIRE_SP4_V_T_38, +    TILE_WIRE_SP4_V_T_39, +    TILE_WIRE_SP4_V_T_40, +    TILE_WIRE_SP4_V_T_41, +    TILE_WIRE_SP4_V_T_42, +    TILE_WIRE_SP4_V_T_43, +    TILE_WIRE_SP4_V_T_44, +    TILE_WIRE_SP4_V_T_45, +    TILE_WIRE_SP4_V_T_46, +    TILE_WIRE_SP4_V_T_47, + +    TILE_WIRE_SP4_R_V_B_0, +    TILE_WIRE_SP4_R_V_B_1, +    TILE_WIRE_SP4_R_V_B_2, +    TILE_WIRE_SP4_R_V_B_3, +    TILE_WIRE_SP4_R_V_B_4, +    TILE_WIRE_SP4_R_V_B_5, +    TILE_WIRE_SP4_R_V_B_6, +    TILE_WIRE_SP4_R_V_B_7, +    TILE_WIRE_SP4_R_V_B_8, +    TILE_WIRE_SP4_R_V_B_9, +    TILE_WIRE_SP4_R_V_B_10, +    TILE_WIRE_SP4_R_V_B_11, +    TILE_WIRE_SP4_R_V_B_12, +    TILE_WIRE_SP4_R_V_B_13, +    TILE_WIRE_SP4_R_V_B_14, +    TILE_WIRE_SP4_R_V_B_15, +    TILE_WIRE_SP4_R_V_B_16, +    TILE_WIRE_SP4_R_V_B_17, +    TILE_WIRE_SP4_R_V_B_18, +    TILE_WIRE_SP4_R_V_B_19, +    TILE_WIRE_SP4_R_V_B_20, +    TILE_WIRE_SP4_R_V_B_21, +    TILE_WIRE_SP4_R_V_B_22, +    TILE_WIRE_SP4_R_V_B_23, +    TILE_WIRE_SP4_R_V_B_24, +    TILE_WIRE_SP4_R_V_B_25, +    TILE_WIRE_SP4_R_V_B_26, +    TILE_WIRE_SP4_R_V_B_27, +    TILE_WIRE_SP4_R_V_B_28, +    TILE_WIRE_SP4_R_V_B_29, +    TILE_WIRE_SP4_R_V_B_30, +    TILE_WIRE_SP4_R_V_B_31, +    TILE_WIRE_SP4_R_V_B_32, +    TILE_WIRE_SP4_R_V_B_33, +    TILE_WIRE_SP4_R_V_B_34, +    TILE_WIRE_SP4_R_V_B_35, +    TILE_WIRE_SP4_R_V_B_36, +    TILE_WIRE_SP4_R_V_B_37, +    TILE_WIRE_SP4_R_V_B_38, +    TILE_WIRE_SP4_R_V_B_39, +    TILE_WIRE_SP4_R_V_B_40, +    TILE_WIRE_SP4_R_V_B_41, +    TILE_WIRE_SP4_R_V_B_42, +    TILE_WIRE_SP4_R_V_B_43, +    TILE_WIRE_SP4_R_V_B_44, +    TILE_WIRE_SP4_R_V_B_45, +    TILE_WIRE_SP4_R_V_B_46, +    TILE_WIRE_SP4_R_V_B_47, + +    TILE_WIRE_SP4_H_L_36, +    TILE_WIRE_SP4_H_L_37, +    TILE_WIRE_SP4_H_L_38, +    TILE_WIRE_SP4_H_L_39, +    TILE_WIRE_SP4_H_L_40, +    TILE_WIRE_SP4_H_L_41, +    TILE_WIRE_SP4_H_L_42, +    TILE_WIRE_SP4_H_L_43, +    TILE_WIRE_SP4_H_L_44, +    TILE_WIRE_SP4_H_L_45, +    TILE_WIRE_SP4_H_L_46, +    TILE_WIRE_SP4_H_L_47, + +    TILE_WIRE_SP4_H_R_0, +    TILE_WIRE_SP4_H_R_1, +    TILE_WIRE_SP4_H_R_2, +    TILE_WIRE_SP4_H_R_3, +    TILE_WIRE_SP4_H_R_4, +    TILE_WIRE_SP4_H_R_5, +    TILE_WIRE_SP4_H_R_6, +    TILE_WIRE_SP4_H_R_7, +    TILE_WIRE_SP4_H_R_8, +    TILE_WIRE_SP4_H_R_9, +    TILE_WIRE_SP4_H_R_10, +    TILE_WIRE_SP4_H_R_11, +    TILE_WIRE_SP4_H_R_12, +    TILE_WIRE_SP4_H_R_13, +    TILE_WIRE_SP4_H_R_14, +    TILE_WIRE_SP4_H_R_15, +    TILE_WIRE_SP4_H_R_16, +    TILE_WIRE_SP4_H_R_17, +    TILE_WIRE_SP4_H_R_18, +    TILE_WIRE_SP4_H_R_19, +    TILE_WIRE_SP4_H_R_20, +    TILE_WIRE_SP4_H_R_21, +    TILE_WIRE_SP4_H_R_22, +    TILE_WIRE_SP4_H_R_23, +    TILE_WIRE_SP4_H_R_24, +    TILE_WIRE_SP4_H_R_25, +    TILE_WIRE_SP4_H_R_26, +    TILE_WIRE_SP4_H_R_27, +    TILE_WIRE_SP4_H_R_28, +    TILE_WIRE_SP4_H_R_29, +    TILE_WIRE_SP4_H_R_30, +    TILE_WIRE_SP4_H_R_31, +    TILE_WIRE_SP4_H_R_32, +    TILE_WIRE_SP4_H_R_33, +    TILE_WIRE_SP4_H_R_34, +    TILE_WIRE_SP4_H_R_35, +    TILE_WIRE_SP4_H_R_36, +    TILE_WIRE_SP4_H_R_37, +    TILE_WIRE_SP4_H_R_38, +    TILE_WIRE_SP4_H_R_39, +    TILE_WIRE_SP4_H_R_40, +    TILE_WIRE_SP4_H_R_41, +    TILE_WIRE_SP4_H_R_42, +    TILE_WIRE_SP4_H_R_43, +    TILE_WIRE_SP4_H_R_44, +    TILE_WIRE_SP4_H_R_45, +    TILE_WIRE_SP4_H_R_46, +    TILE_WIRE_SP4_H_R_47, + +    TILE_WIRE_SP12_V_B_0, +    TILE_WIRE_SP12_V_B_1, +    TILE_WIRE_SP12_V_B_2, +    TILE_WIRE_SP12_V_B_3, +    TILE_WIRE_SP12_V_B_4, +    TILE_WIRE_SP12_V_B_5, +    TILE_WIRE_SP12_V_B_6, +    TILE_WIRE_SP12_V_B_7, +    TILE_WIRE_SP12_V_B_8, +    TILE_WIRE_SP12_V_B_9, +    TILE_WIRE_SP12_V_B_10, +    TILE_WIRE_SP12_V_B_11, +    TILE_WIRE_SP12_V_B_12, +    TILE_WIRE_SP12_V_B_13, +    TILE_WIRE_SP12_V_B_14, +    TILE_WIRE_SP12_V_B_15, +    TILE_WIRE_SP12_V_B_16, +    TILE_WIRE_SP12_V_B_17, +    TILE_WIRE_SP12_V_B_18, +    TILE_WIRE_SP12_V_B_19, +    TILE_WIRE_SP12_V_B_20, +    TILE_WIRE_SP12_V_B_21, +    TILE_WIRE_SP12_V_B_22, +    TILE_WIRE_SP12_V_B_23, + +    TILE_WIRE_SP12_V_T_22, +    TILE_WIRE_SP12_V_T_23, + +    TILE_WIRE_SP12_H_R_0, +    TILE_WIRE_SP12_H_R_1, +    TILE_WIRE_SP12_H_R_2, +    TILE_WIRE_SP12_H_R_3, +    TILE_WIRE_SP12_H_R_4, +    TILE_WIRE_SP12_H_R_5, +    TILE_WIRE_SP12_H_R_6, +    TILE_WIRE_SP12_H_R_7, +    TILE_WIRE_SP12_H_R_8, +    TILE_WIRE_SP12_H_R_9, +    TILE_WIRE_SP12_H_R_10, +    TILE_WIRE_SP12_H_R_11, +    TILE_WIRE_SP12_H_R_12, +    TILE_WIRE_SP12_H_R_13, +    TILE_WIRE_SP12_H_R_14, +    TILE_WIRE_SP12_H_R_15, +    TILE_WIRE_SP12_H_R_16, +    TILE_WIRE_SP12_H_R_17, +    TILE_WIRE_SP12_H_R_18, +    TILE_WIRE_SP12_H_R_19, +    TILE_WIRE_SP12_H_R_20, +    TILE_WIRE_SP12_H_R_21, +    TILE_WIRE_SP12_H_R_22, +    TILE_WIRE_SP12_H_R_23, + +    TILE_WIRE_SP12_H_L_22, +    TILE_WIRE_SP12_H_L_23 +}; + +void gfxTileWire(std::vector<GraphicElement> &g, int x, int y, GfxTileWireId id, GraphicElement::style_t style); + +NEXTPNR_NAMESPACE_END + +#endif // GFX_H diff --git a/ice40/main.cc b/ice40/main.cc index 87a32ded..e77bdd34 100644 --- a/ice40/main.cc +++ b/ice40/main.cc @@ -39,30 +39,30 @@  #include "jsonparse.h"  #include "log.h"  #include "nextpnr.h" -#include "pack.h"  #include "pcf.h"  #include "place_legaliser.h" -#include "place_sa.h" -#include "route.h"  #include "timing.h"  #include "version.h"  USING_NEXTPNR_NAMESPACE -void svg_dump_el(const GraphicElement &el) +void svg_dump_decal(const Context *ctx, const DecalXY &decal)  { -    float scale = 10.0, offset = 10.0; -    std::string style = "stroke=\"black\" stroke-width=\"0.1\" fill=\"none\""; - -    if (el.type == GraphicElement::G_BOX) { -        std::cout << "<rect x=\"" << (offset + scale * el.x1) << "\" y=\"" << (offset + scale * el.y1) << "\" height=\"" -                  << (scale * (el.y2 - el.y1)) << "\" width=\"" << (scale * (el.x2 - el.x1)) << "\" " << style -                  << "/>\n"; -    } +    const float scale = 10.0, offset = 10.0; +    const std::string style = "stroke=\"black\" stroke-width=\"0.1\" fill=\"none\""; + +    for (auto &el : ctx->getDecalGraphics(decal.decal)) { +        if (el.type == GraphicElement::G_BOX) { +            std::cout << "<rect x=\"" << (offset + scale * (decal.x + el.x1)) << "\" y=\"" +                      << (offset + scale * (decal.y + el.y1)) << "\" height=\"" << (scale * (el.y2 - el.y1)) +                      << "\" width=\"" << (scale * (el.x2 - el.x1)) << "\" " << style << "/>\n"; +        } -    if (el.type == GraphicElement::G_LINE) { -        std::cout << "<line x1=\"" << (offset + scale * el.x1) << "\" y1=\"" << (offset + scale * el.y1) << "\" x2=\"" -                  << (offset + scale * el.x2) << "\" y2=\"" << (offset + scale * el.y2) << "\" " << style << "/>\n"; +        if (el.type == GraphicElement::G_LINE) { +            std::cout << "<line x1=\"" << (offset + scale * (decal.x + el.x1)) << "\" y1=\"" +                      << (offset + scale * (decal.y + el.y1)) << "\" x2=\"" << (offset + scale * (decal.x + el.x2)) +                      << "\" y2=\"" << (offset + scale * (decal.y + el.y2)) << "\" " << style << "/>\n"; +        }      }  } @@ -98,12 +98,16 @@ int main(int argc, char *argv[])          options.add_options()("seed", po::value<int>(), "seed value for random number generator");          options.add_options()("version,V", "show version");          options.add_options()("tmfuzz", "run path delay estimate fuzzer"); +#ifdef ICE40_HX1K_ONLY +        options.add_options()("hx1k", "set device type to iCE40HX1K"); +#else          options.add_options()("lp384", "set device type to iCE40LP384");          options.add_options()("lp1k", "set device type to iCE40LP1K");          options.add_options()("lp8k", "set device type to iCE40LP8K");          options.add_options()("hx1k", "set device type to iCE40HX1K");          options.add_options()("hx8k", "set device type to iCE40HX8K");          options.add_options()("up5k", "set device type to iCE40UP5K"); +#endif          options.add_options()("freq", po::value<double>(), "set target frequency for design in MHz");          options.add_options()("no-tmdriv", "disable timing-driven placement");          options.add_options()("package", po::value<std::string>(), "set device package"); @@ -267,112 +271,126 @@ int main(int argc, char *argv[])              return 1;          } -        Context ctx(chipArgs); +        std::unique_ptr<Context> ctx = std::unique_ptr<Context>(new Context(chipArgs));          if (vm.count("verbose")) { -            ctx.verbose = true; +            ctx->verbose = true;          }          if (vm.count("debug")) { -            ctx.verbose = true; -            ctx.debug = true; +            ctx->verbose = true; +            ctx->debug = true;          }          if (vm.count("force")) { -            ctx.force = true; +            ctx->force = true;          }          if (vm.count("seed")) { -            ctx.rngseed(vm["seed"].as<int>()); +            ctx->rngseed(vm["seed"].as<int>());          }          if (vm.count("svg")) {              std::cout << "<svg xmlns=\"http://www.w3.org/2000/svg\" "                           "xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n"; -            for (auto bel : ctx.getBels()) { -                std::cout << "<!-- " << ctx.getBelName(bel).str(&ctx) << " -->\n"; -                for (auto &el : ctx.getBelGraphics(bel)) -                    svg_dump_el(el); +            for (auto bel : ctx->getBels()) { +                std::cout << "<!-- " << ctx->getBelName(bel).str(ctx.get()) << " -->\n"; +                svg_dump_decal(ctx.get(), ctx->getBelDecal(bel));              }              std::cout << "<!-- Frame -->\n"; -            for (auto &el : ctx.getFrameGraphics()) -                svg_dump_el(el); +            svg_dump_decal(ctx.get(), ctx->getFrameDecal());              std::cout << "</svg>\n";          }          if (vm.count("tmfuzz")) {              std::vector<WireId> src_wires, dst_wires; -            /*for (auto w : ctx.getWires()) +            /*for (auto w : ctx->getWires())                  src_wires.push_back(w);*/ -            for (auto b : ctx.getBels()) { -                if (ctx.getBelType(b) == TYPE_ICESTORM_LC) { -                    src_wires.push_back(ctx.getWireBelPin(b, PIN_O)); +            for (auto b : ctx->getBels()) { +                if (ctx->getBelType(b) == TYPE_ICESTORM_LC) { +                    src_wires.push_back(ctx->getWireBelPin(b, PIN_O));                  } -                if (ctx.getBelType(b) == TYPE_SB_IO) { -                    src_wires.push_back(ctx.getWireBelPin(b, PIN_D_IN_0)); +                if (ctx->getBelType(b) == TYPE_SB_IO) { +                    src_wires.push_back(ctx->getWireBelPin(b, PIN_D_IN_0));                  }              } -            for (auto b : ctx.getBels()) { -                if (ctx.getBelType(b) == TYPE_ICESTORM_LC) { -                    dst_wires.push_back(ctx.getWireBelPin(b, PIN_I0)); -                    dst_wires.push_back(ctx.getWireBelPin(b, PIN_I1)); -                    dst_wires.push_back(ctx.getWireBelPin(b, PIN_I2)); -                    dst_wires.push_back(ctx.getWireBelPin(b, PIN_I3)); -                    dst_wires.push_back(ctx.getWireBelPin(b, PIN_CEN)); -                    dst_wires.push_back(ctx.getWireBelPin(b, PIN_CIN)); +            for (auto b : ctx->getBels()) { +                if (ctx->getBelType(b) == TYPE_ICESTORM_LC) { +                    dst_wires.push_back(ctx->getWireBelPin(b, PIN_I0)); +                    dst_wires.push_back(ctx->getWireBelPin(b, PIN_I1)); +                    dst_wires.push_back(ctx->getWireBelPin(b, PIN_I2)); +                    dst_wires.push_back(ctx->getWireBelPin(b, PIN_I3)); +                    dst_wires.push_back(ctx->getWireBelPin(b, PIN_CEN)); +                    dst_wires.push_back(ctx->getWireBelPin(b, PIN_CIN));                  } -                if (ctx.getBelType(b) == TYPE_SB_IO) { -                    dst_wires.push_back(ctx.getWireBelPin(b, PIN_D_OUT_0)); -                    dst_wires.push_back(ctx.getWireBelPin(b, PIN_OUTPUT_ENABLE)); +                if (ctx->getBelType(b) == TYPE_SB_IO) { +                    dst_wires.push_back(ctx->getWireBelPin(b, PIN_D_OUT_0)); +                    dst_wires.push_back(ctx->getWireBelPin(b, PIN_OUTPUT_ENABLE));                  }              } -            ctx.shuffle(src_wires); -            ctx.shuffle(dst_wires); +            ctx->shuffle(src_wires); +            ctx->shuffle(dst_wires);              for (int i = 0; i < int(src_wires.size()) && i < int(dst_wires.size()); i++) {                  delay_t actual_delay;                  WireId src = src_wires[i], dst = dst_wires[i]; -                if (!get_actual_route_delay(&ctx, src, dst, actual_delay)) +                if (!ctx->getActualRouteDelay(src, dst, actual_delay))                      continue; -                printf("%s %s %.3f %.3f %d %d %d %d %d %d\n", ctx.getWireName(src).c_str(&ctx), -                       ctx.getWireName(dst).c_str(&ctx), ctx.getDelayNS(actual_delay), -                       ctx.getDelayNS(ctx.estimateDelay(src, dst)), ctx.chip_info->wire_data[src.index].x, -                       ctx.chip_info->wire_data[src.index].y, ctx.chip_info->wire_data[src.index].type, -                       ctx.chip_info->wire_data[dst.index].x, ctx.chip_info->wire_data[dst.index].y, -                       ctx.chip_info->wire_data[dst.index].type); +                printf("%s %s %.3f %.3f %d %d %d %d %d %d\n", ctx->getWireName(src).c_str(ctx.get()), +                       ctx->getWireName(dst).c_str(ctx.get()), ctx->getDelayNS(actual_delay), +                       ctx->getDelayNS(ctx->estimateDelay(src, dst)), ctx->chip_info->wire_data[src.index].x, +                       ctx->chip_info->wire_data[src.index].y, ctx->chip_info->wire_data[src.index].type, +                       ctx->chip_info->wire_data[dst.index].x, ctx->chip_info->wire_data[dst.index].y, +                       ctx->chip_info->wire_data[dst.index].type);              }          } +        if (vm.count("freq")) +            ctx->target_freq = vm["freq"].as<double>() * 1e6; +        ctx->timing_driven = true; +        if (vm.count("no-tmdriv")) +            ctx->timing_driven = false; +#ifndef NO_GUI +        if (vm.count("gui")) { +            Application a(argc, argv); +            MainWindow w(std::move(ctx), chipArgs); +            if (vm.count("json")) { +                std::string filename = vm["json"].as<std::string>(); +                std::string pcf = ""; +                if (vm.count("pcf")) +                    pcf = vm["pcf"].as<std::string>(); +                w.load_json(filename, pcf); +            } +            w.show(); + +            return a.exec(); +        } +#endif          if (vm.count("json")) {              std::string filename = vm["json"].as<std::string>();              std::ifstream f(filename); -            if (!parse_json_file(f, filename, &ctx)) +            if (!parse_json_file(f, filename, ctx.get()))                  log_error("Loading design failed.\n");              if (vm.count("pcf")) {                  std::ifstream pcf(vm["pcf"].as<std::string>()); -                if (!apply_pcf(&ctx, pcf)) +                if (!apply_pcf(ctx.get(), pcf))                      log_error("Loading PCF failed.\n");              } -            if (!pack_design(&ctx) && !ctx.force) +            if (!ctx->pack() && !ctx->force)                  log_error("Packing design failed.\n"); -            if (vm.count("freq")) -                ctx.target_freq = vm["freq"].as<double>() * 1e6; -            assign_budget(&ctx); -            ctx.check(); -            print_utilisation(&ctx); -            ctx.timing_driven = true; -            if (vm.count("no-tmdriv")) -                ctx.timing_driven = false; +            assign_budget(ctx.get()); +            ctx->check(); +            print_utilisation(ctx.get());              if (!vm.count("pack-only")) { -                if (!place_design_sa(&ctx) && !ctx.force) +                if (!ctx->place() && !ctx->force)                      log_error("Placing design failed.\n"); -                ctx.check(); -                if (!route_design(&ctx) && !ctx.force) +                ctx->check(); +                if (!ctx->route() && !ctx->force)                      log_error("Routing design failed.\n");              }          } @@ -380,13 +398,13 @@ int main(int argc, char *argv[])          if (vm.count("asc")) {              std::string filename = vm["asc"].as<std::string>();              std::ofstream f(filename); -            write_asc(&ctx, f); +            write_asc(ctx.get(), f);          }  #ifndef NO_PYTHON          if (vm.count("run")) {              init_python(argv[0], true); -            python_export_global("ctx", ctx); +            python_export_global("ctx", *ctx.get());              std::vector<std::string> files = vm["run"].as<std::vector<std::string>>();              for (auto filename : files) @@ -395,16 +413,6 @@ int main(int argc, char *argv[])              deinit_python();          }  #endif - -#ifndef NO_GUI -        if (vm.count("gui")) { -            Application a(argc, argv); -            MainWindow w; -            w.show(); - -            rc = a.exec(); -        } -#endif          return rc;      } catch (log_execution_error_exception) {  #if defined(_MSC_VER) diff --git a/ice40/pack.cc b/ice40/pack.cc index d1be4a29..76a52be0 100644 --- a/ice40/pack.cc +++ b/ice40/pack.cc @@ -18,7 +18,6 @@   *   */ -#include "pack.h"  #include <algorithm>  #include <iterator>  #include <unordered_set> @@ -577,8 +576,9 @@ static void pack_special(Context *ctx)  }  // Main pack function -bool pack_design(Context *ctx) +bool Arch::pack()  { +    Context *ctx = getCtx();      try {          log_break();          pack_constants(ctx); diff --git a/ice40/pack.h b/ice40/pack.h deleted file mode 100644 index cdebdd79..00000000 --- a/ice40/pack.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - *  nextpnr -- Next Generation Place and Route - * - *  Copyright (C) 2018  Clifford Wolf <clifford@symbioticeda.com> - *  Copyright (C) 2018  David Shah <david@symbioticeda.com> - * - *  Permission to use, copy, modify, and/or distribute this software for any - *  purpose with or without fee is hereby granted, provided that the above - *  copyright notice and this permission notice appear in all copies. - * - *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ - -#ifndef PACK_H -#define PACK_H - -#include "nextpnr.h" - -NEXTPNR_NAMESPACE_BEGIN - -bool pack_design(Context *ctx); - -NEXTPNR_NAMESPACE_END - -#endif // ROUTE_H  | 
