diff --git a/common/nextpnr.h b/common/nextpnr.h index 37e193b9..0b41ff81 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -155,6 +155,12 @@ NEXTPNR_NAMESPACE_END NEXTPNR_NAMESPACE_BEGIN +struct DecalXY +{ + DecalId decal; + float x = 0, y = 0; +}; + struct BelPin { BelId bel; @@ -273,6 +279,60 @@ struct Context : Arch // -------------------------------------------------------------- + std::vector getFrameGraphics() const __attribute__ ((deprecated)) { + std::vector ret; + DecalXY decalxy = getFrameDecal(); + ret = getDecalGraphics(decalxy.decal); + for (auto &it : ret) { + it.x1 += decalxy.x; + it.x2 += decalxy.x; + it.y1 += decalxy.y; + it.y2 += decalxy.y; + } + return ret; + } + + std::vector getBelGraphics(BelId bel) const __attribute__ ((deprecated)) { + std::vector ret; + DecalXY decalxy = getBelDecal(bel); + ret = getDecalGraphics(decalxy.decal); + for (auto &it : ret) { + it.x1 += decalxy.x; + it.x2 += decalxy.x; + it.y1 += decalxy.y; + it.y2 += decalxy.y; + } + return ret; + } + + std::vector getWireGraphics(WireId wire) const __attribute__ ((deprecated)) { + std::vector ret; + DecalXY decalxy = getWireDecal(wire); + ret = getDecalGraphics(decalxy.decal); + for (auto &it : ret) { + it.x1 += decalxy.x; + it.x2 += decalxy.x; + it.y1 += decalxy.y; + it.y2 += decalxy.y; + } + return ret; + } + + std::vector getPipGraphics(PipId pip) const __attribute__ ((deprecated)) { + std::vector ret; + DecalXY decalxy = getPipDecal(pip); + ret = getDecalGraphics(decalxy.decal); + for (auto &it : ret) { + it.x1 += decalxy.x; + it.x2 += decalxy.x; + it.y1 += decalxy.y; + it.y2 += decalxy.y; + } + return ret; + } + + // -------------------------------------------------------------- + uint64_t rngstate = 0x3141592653589793; uint64_t rng64() diff --git a/generic/arch.cc b/generic/arch.cc index 8f897604..b3854401 100644 --- a/generic/arch.cc +++ b/generic/arch.cc @@ -107,27 +107,32 @@ void Arch::addBelInout(IdString bel, IdString name, IdString wire) wires.at(wire).downhill_bel_pins.push_back(BelPin{bel, name}); } -void Arch::addFrameGraphic(const GraphicElement &graphic) +void Arch::addDecalGraphic(DecalId decal, const GraphicElement &graphic) { - frame_graphics.push_back(graphic); + decal_graphics[decal].push_back(graphic); +} + +void Arch::setFrameDecal(DecalXY decalxy) +{ + frame_decalxy = decalxy; frameGraphicsReload = true; } -void Arch::addWireGraphic(WireId wire, const GraphicElement &graphic) +void Arch::setWireDecal(WireId wire, DecalXY decalxy) { - wires.at(wire).graphics.push_back(graphic); + wires.at(wire).decalxy = decalxy; wireGraphicsReload.insert(wire); } -void Arch::addPipGraphic(PipId pip, const GraphicElement &graphic) +void Arch::setPipDecal(PipId pip, DecalXY decalxy) { - pips.at(pip).graphics.push_back(graphic); + pips.at(pip).decalxy = decalxy; pipGraphicsReload.insert(pip); } -void Arch::addBelGraphic(BelId bel, const GraphicElement &graphic) +void Arch::setBelDecal(BelId bel, DecalXY decalxy) { - bels.at(bel).graphics.push_back(graphic); + bels.at(bel).decalxy = decalxy; belGraphicsReload.insert(bel); } @@ -310,13 +315,15 @@ delay_t Arch::estimateDelay(WireId src, WireId dst) const // --------------------------------------------------------------- -const std::vector &Arch::getFrameGraphics() const { return frame_graphics; } +const std::vector &Arch::getDecalGraphics(DecalId decal) const { return decal_graphics.at(decal); } -const std::vector &Arch::getBelGraphics(BelId bel) const { return bels.at(bel).graphics; } +DecalXY Arch::getFrameDecal() const { return frame_decalxy; } -const std::vector &Arch::getWireGraphics(WireId wire) const { return wires.at(wire).graphics; } +DecalXY Arch::getBelDecal(BelId bel) const { return bels.at(bel).decalxy; } -const std::vector &Arch::getPipGraphics(PipId pip) const { return pips.at(pip).graphics; } +DecalXY Arch::getWireDecal(WireId wire) const { return wires.at(wire).decalxy; } + +DecalXY Arch::getPipDecal(PipId pip) const { return pips.at(pip).decalxy; } // --------------------------------------------------------------- diff --git a/generic/arch.h b/generic/arch.h index e739cfab..dafbfec3 100644 --- a/generic/arch.h +++ b/generic/arch.h @@ -34,16 +34,16 @@ struct PipInfo IdString name, bound_net; WireId srcWire, dstWire; DelayInfo delay; - std::vector graphics; + DecalXY decalxy; }; struct WireInfo { IdString name, bound_net; - std::vector graphics; std::vector downhill, uphill, aliases; BelPin uphill_bel_pin; std::vector downhill_bel_pins; + DecalXY decalxy; int grid_x, grid_y; }; @@ -58,7 +58,7 @@ struct BelInfo { IdString name, type, bound_cell; std::unordered_map pins; - std::vector graphics; + DecalXY decalxy; int grid_x, grid_y; bool gb; }; @@ -74,7 +74,9 @@ struct Arch : BaseCtx std::vector bel_ids, wire_ids, pip_ids; std::unordered_map> bel_ids_by_type; - std::vector frame_graphics; + std::unordered_map> decal_graphics; + DecalXY frame_decalxy; + float grid_distance_to_delay; void addWire(IdString name, int x, int y); @@ -86,10 +88,11 @@ struct Arch : BaseCtx void addBelOutput(IdString bel, IdString name, IdString wire); void addBelInout(IdString bel, IdString name, IdString wire); - void addFrameGraphic(const GraphicElement &graphic); - void addWireGraphic(WireId wire, const GraphicElement &graphic); - void addPipGraphic(PipId pip, const GraphicElement &graphic); - void addBelGraphic(BelId bel, const GraphicElement &graphic); + void addDecalGraphic(DecalId decal, const GraphicElement &graphic); + void setFrameDecal(DecalXY decalxy); + void setWireDecal(WireId wire, DecalXY decalxy); + void setPipDecal(PipId pip, DecalXY decalxy); + void setBelDecal(BelId bel, DecalXY decalxy); // --------------------------------------------------------------- // Common Arch API. Every arch must provide the following methods. @@ -155,10 +158,11 @@ struct Arch : BaseCtx float getDelayNS(delay_t v) const { return v; } uint32_t getDelayChecksum(delay_t v) const { return 0; } - const std::vector &getFrameGraphics() const; - const std::vector &getBelGraphics(BelId bel) const; - const std::vector &getWireGraphics(WireId wire) const; - const std::vector &getPipGraphics(PipId pip) const; + const std::vector &getDecalGraphics(DecalId decal) const; + DecalXY getFrameDecal() const; + DecalXY getBelDecal(BelId bel) const; + DecalXY getWireDecal(WireId wire) const; + DecalXY getPipDecal(PipId pip) const; bool allGraphicsReload = false; bool frameGraphicsReload = false; diff --git a/generic/archdefs.h b/generic/archdefs.h index 9e8462e0..8e6dcb2f 100644 --- a/generic/archdefs.h +++ b/generic/archdefs.h @@ -49,5 +49,6 @@ typedef IdString PortPin; typedef IdString BelId; typedef IdString WireId; typedef IdString PipId; +typedef IdString DecalId; NEXTPNR_NAMESPACE_END diff --git a/gui/fpgaviewwidget.cc b/gui/fpgaviewwidget.cc index ae0b9240..49ec4529 100644 --- a/gui/fpgaviewwidget.cc +++ b/gui/fpgaviewwidget.cc @@ -363,6 +363,26 @@ void FPGAViewWidget::paintGL() lineShader_.draw(bels, matrix); } + // Draw Wires. + auto wires = LineShaderData(0.0005f, QColor("#b000ba")); + if (ctx_) { + for (auto wire : ctx_->getWires()) { + for (auto &el : ctx_->getWireGraphics(wire)) + drawElement(wires, el); + } + lineShader_.draw(wires, matrix); + } + + // Draw Pips. + auto pips = LineShaderData(0.0005f, QColor("#b000ba")); + if (ctx_) { + for (auto wire : ctx_->getPips()) { + for (auto &el : ctx_->getPipGraphics(wire)) + drawElement(pips, el); + } + lineShader_.draw(pips, matrix); + } + // Draw Frame Graphics. auto frames = LineShaderData(0.002f, QColor("#0066ba")); if (ctx_) { diff --git a/ice40/arch.cc b/ice40/arch.cc index 0b82914a..a25c3d87 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -400,128 +400,143 @@ delay_t Arch::estimateDelay(WireId src, WireId dst) const // ----------------------------------------------------------------------- -std::vector Arch::getFrameGraphics() const +DecalXY Arch::getFrameDecal() const { - std::vector ret; - - 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); - } - - return ret; + DecalXY decalxy; + decalxy.decal.type = 'f'; + return decalxy; } -std::vector Arch::getBelGraphics(BelId bel) const +DecalXY Arch::getBelDecal(BelId bel) const +{ + DecalXY decalxy; + decalxy.decal.type = 'b'; + decalxy.decal.z = bel.index; + return decalxy; +} + +DecalXY Arch::getWireDecal(WireId wire) const +{ + DecalXY decalxy; + return decalxy; +} + +DecalXY Arch::getPipDecal(PipId pip) const +{ + DecalXY decalxy; + return decalxy; +}; + +std::vector Arch::getDecalGraphics(DecalId decal) const { std::vector 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 + 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); - - if (chip_info->bel_data[bel.index].z == 0) { - 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.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.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); - - // All the wires - for (int i = TILE_WIRE_GLB2LOCAL_0; i <= TILE_WIRE_SP12_H_L_23; i++) - gfxTileWire(ret, tx, ty, GfxTileWireId(i)); - } + if (decal.type == 'f') + { + 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 (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 == 'b') + { + BelId bel; + bel.index = decal.z; + + 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 + 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); + + if (chip_info->bel_data[bel.index].z == 0) { + 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.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.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); + + // All the wires + for (int i = TILE_WIRE_GLB2LOCAL_0; i <= TILE_WIRE_SP12_H_L_23; i++) + gfxTileWire(ret, tx, ty, GfxTileWireId(i)); + } + } + + 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 { + 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); + } + } + + 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; - 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 { - 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.y2 = chip_info->bel_data[bel.index].y + 1.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); - } - return ret; } -std::vector Arch::getWireGraphics(WireId wire) const -{ - std::vector ret; - // FIXME - return ret; -} - -std::vector Arch::getPipGraphics(PipId pip) const -{ - std::vector 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..03685152 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -643,10 +643,12 @@ struct Arch : BaseCtx // ------------------------------------------------- - std::vector getFrameGraphics() const; - std::vector getBelGraphics(BelId bel) const; - std::vector getWireGraphics(WireId wire) const; - std::vector getPipGraphics(PipId pip) const; + std::vector getDecalGraphics(DecalId decal) const; + + DecalXY getFrameDecal() const; + DecalXY getBelDecal(BelId bel) const; + DecalXY getWireDecal(WireId wire) const; + DecalXY getPipDecal(PipId pip) const; bool allGraphicsReload = false; bool frameGraphicsReload = false; diff --git a/ice40/archdefs.h b/ice40/archdefs.h index be2e406d..061e9b44 100644 --- a/ice40/archdefs.h +++ b/ice40/archdefs.h @@ -21,6 +21,8 @@ #error Include "archdefs.h" via "nextpnr.h" only. #endif +#include + NEXTPNR_NAMESPACE_BEGIN typedef int delay_t; @@ -107,6 +109,13 @@ struct PipId bool operator!=(const PipId &other) const { return index != other.index; } }; +struct DecalId +{ + char type = 0; // Bel/Wire/Pip/Frame (b/w/p/f) + uint8_t x = 0, y = 0; + uint32_t z = 0; +}; + NEXTPNR_NAMESPACE_END namespace std { @@ -135,4 +144,17 @@ template <> struct hash : hash template <> struct hash : hash { }; + +template <> struct hash +{ + std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX DecalId &decal) const noexcept { + std::size_t seed = 0; + boost::hash_combine(seed, hash()(decal.type)); + boost::hash_combine(seed, hash()(decal.x)); + boost::hash_combine(seed, hash()(decal.y)); + boost::hash_combine(seed, hash()(decal.z)); + return seed; + } +}; + } // namespace std