diff options
author | Eddie Hung <eddie.hung+gitlab@gmail.com> | 2018-07-15 19:22:57 +0000 |
---|---|---|
committer | Eddie Hung <eddie.hung+gitlab@gmail.com> | 2018-07-15 19:22:57 +0000 |
commit | 0bae7f5606b15591a23fb63da1c5ff6f93b40747 (patch) | |
tree | 7b0760fa1e5c837f9b43cf1c97fa9f55973a169b /ice40 | |
parent | 1457a6453c11af34a73460868833a9462e987854 (diff) | |
parent | 21bf78dae9ef95e65b549c60061bce9790b1b611 (diff) | |
download | nextpnr-0bae7f5606b15591a23fb63da1c5ff6f93b40747.tar.gz nextpnr-0bae7f5606b15591a23fb63da1c5ff6f93b40747.tar.bz2 nextpnr-0bae7f5606b15591a23fb63da1c5ff6f93b40747.zip |
Merge branch 'master' into 'master'
Master
See merge request eddiehung/nextpnr!1
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 |