933 lines
38 KiB
C++
933 lines
38 KiB
C++
![]() |
/*
|
||
|
* nextpnr -- Next Generation Place and Route
|
||
|
*
|
||
|
* Copyright (C) 2018 Claire Xenia Wolf <claire@yosyshq.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 <boost/algorithm/string.hpp>
|
||
|
#include <iostream>
|
||
|
|
||
|
#include "gfx.h"
|
||
|
|
||
|
NEXTPNR_NAMESPACE_BEGIN
|
||
|
|
||
|
const int PIP_SRC_DST_LEN = 20;
|
||
|
|
||
|
static void get_pip_xy(CruSide side, float &off, float &x, float &y)
|
||
|
{
|
||
|
switch (side) {
|
||
|
case Top:
|
||
|
x = off;
|
||
|
y = cru_y + cru_h;
|
||
|
break;
|
||
|
case Bottom:
|
||
|
x = off;
|
||
|
y = cru_y;
|
||
|
break;
|
||
|
case Left:
|
||
|
x = cru_x;
|
||
|
y = off;
|
||
|
break;
|
||
|
case Right:
|
||
|
x = cru_x + cru_w;
|
||
|
y = off;
|
||
|
break;
|
||
|
case Center:
|
||
|
x = cru_x + cru_w / 2.f;
|
||
|
y = off;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void gfxSetPipDefaultDecal(Arch *arch, PipInfo &pip)
|
||
|
{
|
||
|
DecalXY active, inactive;
|
||
|
std::vector<std::string> split_res;
|
||
|
IdString src_loc_id, dst_loc_id;
|
||
|
char buf[PIP_SRC_DST_LEN];
|
||
|
|
||
|
active.x = inactive.x = pip.loc.x;
|
||
|
active.y = inactive.y = arch->gridDimY - 1. - pip.loc.y;
|
||
|
boost::split(split_res, pip.name.str(arch), [](char c) { return c == '_'; });
|
||
|
src_loc_id = arch->id(split_res.at(1));
|
||
|
dst_loc_id = arch->id(split_res.at(2));
|
||
|
snprintf(buf, PIP_SRC_DST_LEN, "%s_%s_active", src_loc_id.c_str(arch), dst_loc_id.c_str(arch));
|
||
|
IdString active_id = arch->id(buf);
|
||
|
active.decal = active_id;
|
||
|
snprintf(buf, PIP_SRC_DST_LEN, "%s_%s_inactive", src_loc_id.c_str(arch), dst_loc_id.c_str(arch));
|
||
|
IdString inactive_id = arch->id(buf);
|
||
|
inactive.decal = inactive_id;
|
||
|
// create if absent
|
||
|
if (arch->decal_graphics.count(active_id) == 0) {
|
||
|
// clock?
|
||
|
if (dst_loc_id == id_GT00 || dst_loc_id == id_GT10) {
|
||
|
WireInfo &wi = arch->wire_info(pip.srcWire);
|
||
|
if (wi.type.str(arch).substr(0, 3) != "UNK") {
|
||
|
// create pip
|
||
|
GraphicElement el;
|
||
|
el.type = GraphicElement::TYPE_LOCAL_LINE;
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
if (dst_loc_id == id_GT00) {
|
||
|
el.x1 = WIRE_X(CLK_GT00_X);
|
||
|
} else {
|
||
|
el.x1 = WIRE_X(CLK_GT10_X);
|
||
|
}
|
||
|
el.x2 = el.x1 + spine_pip_off;
|
||
|
el.y2 = spineY.at(arch->wire_info(pip.srcWire).type);
|
||
|
el.y1 = el.y2 - spine_pip_off;
|
||
|
arch->addDecalGraphic(active_id, el);
|
||
|
el.style = GraphicElement::STYLE_INACTIVE;
|
||
|
arch->addDecalGraphic(inactive_id, el);
|
||
|
}
|
||
|
} else {
|
||
|
// XXX
|
||
|
if (pipPoint.count(src_loc_id) == 0 || pipPoint.count(dst_loc_id) == 0) {
|
||
|
// std::cout << "*R" << pip.loc.y + 1 << "C" << pip.loc.x + 1 << " no " << pip.name.str(arch) << " " <<
|
||
|
// buf << std::endl;
|
||
|
} else {
|
||
|
GraphicElement el;
|
||
|
el.type = GraphicElement::TYPE_LOCAL_ARROW;
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
CruSide srcSide = pipPoint.at(src_loc_id).first;
|
||
|
float srcOff = pipPoint.at(src_loc_id).second;
|
||
|
CruSide dstSide = pipPoint.at(dst_loc_id).first;
|
||
|
float dstOff = pipPoint.at(dst_loc_id).second;
|
||
|
if (srcSide != dstSide) {
|
||
|
get_pip_xy(srcSide, srcOff, el.x1, el.y1);
|
||
|
get_pip_xy(dstSide, dstOff, el.x2, el.y2);
|
||
|
arch->addDecalGraphic(active_id, el);
|
||
|
el.style = GraphicElement::STYLE_HIDDEN;
|
||
|
arch->addDecalGraphic(inactive_id, el);
|
||
|
} else {
|
||
|
get_pip_xy(srcSide, srcOff, el.x1, el.y1);
|
||
|
float dst_x = 0, dst_y = 0, m_x = 0, m_y = 0;
|
||
|
get_pip_xy(dstSide, dstOff, dst_x, dst_y);
|
||
|
switch (dstSide) {
|
||
|
case Top:
|
||
|
m_x = el.x1 + (dst_x - el.x1) / 2.f;
|
||
|
m_y = dst_y - std::max(cru_h * 0.1f, std::min(cru_h * 0.4f, std::abs(el.x1 - dst_x)));
|
||
|
break;
|
||
|
case Bottom:
|
||
|
m_x = el.x1 + (dst_x - el.x1) / 2.f;
|
||
|
m_y = dst_y + std::max(cru_h * 0.1f, std::min(cru_h * 0.4f, std::abs(el.x1 - dst_x)));
|
||
|
break;
|
||
|
case Right:
|
||
|
m_x = dst_x - std::max(cru_w * 0.1f, std::min(cru_w * 0.4f, std::abs(el.y1 - dst_y)));
|
||
|
m_y = el.y1 + (dst_y - el.y1) / 2.f;
|
||
|
break;
|
||
|
case Left:
|
||
|
m_x = dst_x + std::max(cru_w * 0.1f, std::min(cru_w * 0.4f, std::abs(el.y1 - dst_y)));
|
||
|
m_y = el.y1 + (dst_y - el.y1) / 2.f;
|
||
|
break;
|
||
|
default: // unreachable
|
||
|
break;
|
||
|
}
|
||
|
el.x2 = m_x;
|
||
|
el.y2 = m_y;
|
||
|
arch->addDecalGraphic(active_id, el);
|
||
|
el.style = GraphicElement::STYLE_HIDDEN;
|
||
|
arch->addDecalGraphic(inactive_id, el);
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
el.x1 = m_x;
|
||
|
el.y1 = m_y;
|
||
|
el.x2 = dst_x;
|
||
|
el.y2 = dst_y;
|
||
|
arch->addDecalGraphic(active_id, el);
|
||
|
el.style = GraphicElement::STYLE_HIDDEN;
|
||
|
arch->addDecalGraphic(inactive_id, el);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
arch->setPipDecal(pip.name, active, inactive);
|
||
|
}
|
||
|
|
||
|
const int WIRE_ID_LEN = 30;
|
||
|
|
||
|
void gfxSetWireDefaultDecal(Arch *arch, WireInfo &wire)
|
||
|
{
|
||
|
DecalXY active, inactive;
|
||
|
IdString active_id, inactive_id;
|
||
|
GraphicElement el;
|
||
|
std::vector<std::string> split_res;
|
||
|
char buf[WIRE_ID_LEN];
|
||
|
|
||
|
if (std::find(decalless_wires.begin(), decalless_wires.end(), wire.name) != decalless_wires.end()) {
|
||
|
arch->setWireDecal(wire.type, DecalXY(), DecalXY());
|
||
|
return;
|
||
|
}
|
||
|
// local to cell
|
||
|
if (arch->haveBelType(wire.x, wire.y, id_SLICE) && sliceLocalWires.count(wire.type) != 0) {
|
||
|
snprintf(buf, sizeof(buf), "%s_active", wire.type.c_str(arch));
|
||
|
active_id = arch->id(buf);
|
||
|
active.decal = active_id;
|
||
|
snprintf(buf, sizeof(buf), "%s_inactive", wire.type.c_str(arch));
|
||
|
inactive_id = arch->id(buf);
|
||
|
inactive.decal = inactive_id;
|
||
|
active.x = inactive.x = wire.x;
|
||
|
active.y = inactive.y = arch->gridDimY - 1. - wire.y;
|
||
|
|
||
|
// create if absent
|
||
|
if (arch->decal_graphics.count(active_id) == 0) {
|
||
|
el.type = GraphicElement::TYPE_LOCAL_LINE;
|
||
|
for (auto seg : sliceLocalWires.at(wire.type)) {
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
el.x1 = std::get<0>(seg);
|
||
|
el.y1 = std::get<1>(seg);
|
||
|
el.x2 = std::get<2>(seg);
|
||
|
el.y2 = std::get<3>(seg);
|
||
|
arch->addDecalGraphic(active_id, el);
|
||
|
el.style = GraphicElement::STYLE_INACTIVE;
|
||
|
arch->addDecalGraphic(inactive_id, el);
|
||
|
}
|
||
|
}
|
||
|
arch->setWireDecal(wire.name, active, inactive);
|
||
|
return;
|
||
|
}
|
||
|
// spines
|
||
|
if (spineY.count(wire.type) != 0) {
|
||
|
snprintf(buf, sizeof(buf), "%s_active", wire.type.c_str(arch));
|
||
|
active_id = arch->id(buf);
|
||
|
active.decal = active_id;
|
||
|
snprintf(buf, sizeof(buf), "%s_inactive", wire.type.c_str(arch));
|
||
|
inactive_id = arch->id(buf);
|
||
|
inactive.decal = inactive_id;
|
||
|
active.x = inactive.x = 0.;
|
||
|
active.y = inactive.y = 0.;
|
||
|
|
||
|
// update clock spines cache
|
||
|
arch->updateClockSpinesCache(wire.type, wire.name);
|
||
|
|
||
|
if (arch->decal_graphics.count(active_id) == 0) {
|
||
|
el.type = GraphicElement::TYPE_LINE;
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
el.x1 = 0.2; // cell's x will be added later in fixClockSpineDecals
|
||
|
el.x2 = 0.7; // cell's x will be added later in fixClockSpineDecals
|
||
|
el.y1 = spineY.at(wire.type) + arch->gridDimY - 1.; // cell's y will be added later in fixClockSpineDecals
|
||
|
el.y2 = el.y1;
|
||
|
arch->addDecalGraphic(active_id, el);
|
||
|
el.style = GraphicElement::STYLE_HIDDEN;
|
||
|
arch->addDecalGraphic(inactive_id, el);
|
||
|
}
|
||
|
arch->setWireDecal(wire.name, active, inactive);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// global simple wires like IMUX
|
||
|
if (globalSimpleWires.count(wire.type) != 0) {
|
||
|
snprintf(buf, sizeof(buf), "%s_active", wire.name.c_str(arch));
|
||
|
active_id = arch->id(buf);
|
||
|
active.decal = active_id;
|
||
|
snprintf(buf, sizeof(buf), "%s_inactive", wire.name.c_str(arch));
|
||
|
inactive_id = arch->id(buf);
|
||
|
inactive.decal = inactive_id;
|
||
|
active.x = inactive.x = 0;
|
||
|
active.y = inactive.y = 0;
|
||
|
|
||
|
// create if absent
|
||
|
if (arch->decal_graphics.count(active_id) == 0) {
|
||
|
el.type = GraphicElement::TYPE_LINE;
|
||
|
for (auto seg : globalSimpleWires.at(wire.type)) {
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
el.x1 = std::get<0>(seg) + wire.x;
|
||
|
el.y1 = std::get<1>(seg) + arch->gridDimY - 1. - wire.y;
|
||
|
el.x2 = std::get<2>(seg) + wire.x;
|
||
|
el.y2 = std::get<3>(seg) + arch->gridDimY - 1. - wire.y;
|
||
|
arch->addDecalGraphic(active_id, el);
|
||
|
el.style = GraphicElement::STYLE_INACTIVE;
|
||
|
arch->addDecalGraphic(inactive_id, el);
|
||
|
}
|
||
|
}
|
||
|
arch->setWireDecal(wire.name, active, inactive);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// global
|
||
|
boost::split(split_res, wire.name.str(arch), [](char c) { return c == '_'; });
|
||
|
if (split_res.size() >= 2) {
|
||
|
IdString wire_id = arch->id(split_res.at(1));
|
||
|
// wrap
|
||
|
if ((wire.y == (arch->gridDimY - 1) && split_res.at(1).at(0) == 'S') ||
|
||
|
(wire.y == 0 && split_res.at(1).at(0) == 'N')) {
|
||
|
wire_id = arch->id(split_res.at(1) + "_loop0");
|
||
|
}
|
||
|
if ((wire.x == (arch->gridDimX - 1) && split_res.at(1).at(0) == 'E') ||
|
||
|
(wire.x == 0 && split_res.at(1).at(0) == 'W')) {
|
||
|
wire_id = arch->id(split_res.at(1) + "_loop0");
|
||
|
}
|
||
|
// SN wires
|
||
|
if (split_res.at(1).substr(0, 2) == "SN") {
|
||
|
if (wire.y == 0) {
|
||
|
wire_id = arch->id(split_res.at(1) + "_loop_n");
|
||
|
} else {
|
||
|
if (wire.y == (arch->gridDimY - 1)) {
|
||
|
wire_id = arch->id(split_res.at(1) + "_loop_s");
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
// wrap 2 hop
|
||
|
if ((wire.y == (arch->gridDimY - 2) && split_res.at(1).substr(0, 2) == "S2") ||
|
||
|
(wire.y == 1 && split_res.at(1).substr(0, 2) == "N2")) {
|
||
|
wire_id = arch->id(split_res.at(1) + "_loop1");
|
||
|
}
|
||
|
// wrap 4 hop
|
||
|
if (split_res.at(1).substr(0, 2) == "S8" || split_res.at(1).substr(0, 2) == "N8") {
|
||
|
char loop_buf[5 + 2];
|
||
|
if (split_res.at(1).substr(0, 2) == "N8") {
|
||
|
if (wire.y < 8) {
|
||
|
snprintf(loop_buf, sizeof(loop_buf), "_loop%1u", wire.y);
|
||
|
wire_id = arch->id(split_res.at(1) + loop_buf);
|
||
|
}
|
||
|
} else {
|
||
|
if (arch->gridDimY - 1 - wire.y < 8) {
|
||
|
snprintf(loop_buf, sizeof(loop_buf), "_loop%1u", arch->gridDimY - 1 - wire.y);
|
||
|
wire_id = arch->id(split_res.at(1) + loop_buf);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
// EW wires
|
||
|
if (split_res.at(1).substr(0, 2) == "EW") {
|
||
|
if (wire.x == 0) {
|
||
|
wire_id = arch->id(split_res.at(1) + "_loop_w");
|
||
|
} else {
|
||
|
if (wire.x == (arch->gridDimX - 1)) {
|
||
|
wire_id = arch->id(split_res.at(1) + "_loop_e");
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
// wrap 2 hop
|
||
|
if ((wire.x == (arch->gridDimX - 2) && split_res.at(1).substr(0, 2) == "E2") ||
|
||
|
(wire.x == 1 && split_res.at(1).substr(0, 2) == "W2")) {
|
||
|
wire_id = arch->id(split_res.at(1) + "_loop1");
|
||
|
}
|
||
|
// wrap 4 hop
|
||
|
if (split_res.at(1).substr(0, 2) == "E8" || split_res.at(1).substr(0, 2) == "W8") {
|
||
|
char loop_buf[5 + 2];
|
||
|
if (split_res.at(1).substr(0, 2) == "W8") {
|
||
|
if (wire.x < 8) {
|
||
|
snprintf(loop_buf, sizeof(loop_buf), "_loop%1u", wire.x);
|
||
|
wire_id = arch->id(split_res.at(1) + loop_buf);
|
||
|
}
|
||
|
} else {
|
||
|
if (arch->gridDimX - 1 - wire.x < 8) {
|
||
|
snprintf(loop_buf, sizeof(loop_buf), "_loop%1u", arch->gridDimX - 1 - wire.x);
|
||
|
wire_id = arch->id(split_res.at(1) + loop_buf);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
// really create decal
|
||
|
if (globalWires.count(wire_id) != 0) {
|
||
|
snprintf(buf, sizeof(buf), "%s_active", wire.name.c_str(arch));
|
||
|
active_id = arch->id(buf);
|
||
|
active.decal = active_id;
|
||
|
snprintf(buf, sizeof(buf), "%s_inactive", wire.name.c_str(arch));
|
||
|
inactive_id = arch->id(buf);
|
||
|
inactive.decal = inactive_id;
|
||
|
active.x = inactive.x = 0;
|
||
|
active.y = inactive.y = 0;
|
||
|
|
||
|
// create if absent
|
||
|
if (arch->decal_graphics.count(active_id) == 0) {
|
||
|
el.type = GraphicElement::TYPE_LINE;
|
||
|
for (auto seg : globalWires.at(wire_id)) {
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
el.x1 = std::get<0>(seg) + wire.x;
|
||
|
el.y1 = std::get<1>(seg) + arch->gridDimY - 1. - wire.y;
|
||
|
el.x2 = std::get<2>(seg) + wire.x;
|
||
|
el.y2 = std::get<3>(seg) + arch->gridDimY - 1. - wire.y;
|
||
|
arch->addDecalGraphic(active_id, el);
|
||
|
el.style = GraphicElement::STYLE_INACTIVE;
|
||
|
arch->addDecalGraphic(inactive_id, el);
|
||
|
}
|
||
|
}
|
||
|
arch->setWireDecal(wire.name, active, inactive);
|
||
|
return;
|
||
|
}
|
||
|
// clock branches
|
||
|
// # of rows is unknown so generate wire ids at runtime
|
||
|
if (split_res.at(1).substr(0, 3) == "GBO") {
|
||
|
snprintf(buf, sizeof(buf), "%s_active", wire.name.c_str(arch));
|
||
|
active_id = arch->id(buf);
|
||
|
active.decal = active_id;
|
||
|
inactive_id = IdString();
|
||
|
inactive.decal = inactive_id;
|
||
|
active.x = inactive.x = 0;
|
||
|
active.y = inactive.y = 0;
|
||
|
|
||
|
float pip_x = PIP_X(id_GBO0);
|
||
|
float line_y = WIRE_Y(CLK_GBO0_Y) + arch->gridDimY - 1. - wire.y;
|
||
|
float line_0 = WIRE_Y(0) + arch->gridDimY - 1. - wire.y;
|
||
|
if (split_res.at(1).at(3) == '1') {
|
||
|
pip_x = PIP_X(id_GBO1);
|
||
|
line_y = WIRE_Y(CLK_GBO1_Y) + arch->gridDimY - 1. - wire.y;
|
||
|
}
|
||
|
|
||
|
// create if absent
|
||
|
if (arch->decal_graphics.count(active_id) == 0) {
|
||
|
el.type = GraphicElement::TYPE_LINE;
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
el.x1 = wire.x + pip_x;
|
||
|
el.y1 = line_y;
|
||
|
el.x2 = el.x1;
|
||
|
el.y2 = line_0;
|
||
|
arch->addDecalGraphic(active_id, el);
|
||
|
el.style = GraphicElement::STYLE_HIDDEN;
|
||
|
arch->addDecalGraphic(inactive_id, el);
|
||
|
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
el.x1 = pip_x;
|
||
|
el.y1 = line_y;
|
||
|
el.x2 = pip_x + arch->gridDimX - 1.;
|
||
|
el.y2 = el.y1;
|
||
|
arch->addDecalGraphic(active_id, el);
|
||
|
el.style = GraphicElement::STYLE_HIDDEN;
|
||
|
arch->addDecalGraphic(inactive_id, el);
|
||
|
}
|
||
|
arch->setWireDecal(wire.name, active, inactive);
|
||
|
return;
|
||
|
} else {
|
||
|
if (split_res.at(1).substr(0, 2) == "GT") {
|
||
|
snprintf(buf, sizeof(buf), "%s_active", wire.name.c_str(arch));
|
||
|
active_id = arch->id(buf);
|
||
|
active.decal = active_id;
|
||
|
// snprintf(buf, sizeof(buf), "%s_inactive", wire.name.c_str(arch));
|
||
|
// inactive_id = arch->id(buf);
|
||
|
inactive_id = IdString();
|
||
|
inactive.decal = inactive_id;
|
||
|
active.x = inactive.x = 0;
|
||
|
active.y = inactive.y = 0;
|
||
|
|
||
|
float pip_y = PIP_Y(id_GT00);
|
||
|
float line_x = WIRE_X(CLK_GT00_X) + wire.x;
|
||
|
float line_0 = WIRE_X(0) + wire.x;
|
||
|
if (split_res.at(1).at(2) == '1') {
|
||
|
pip_y = PIP_Y(id_GT10);
|
||
|
line_x = WIRE_X(CLK_GT10_X) + wire.x;
|
||
|
}
|
||
|
|
||
|
// create if absent
|
||
|
if (arch->decal_graphics.count(active_id) == 0) {
|
||
|
el.type = GraphicElement::TYPE_LINE;
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
el.x1 = line_x;
|
||
|
el.y1 = pip_y + arch->gridDimY - 1.;
|
||
|
el.x2 = el.x1;
|
||
|
el.y2 = pip_y;
|
||
|
arch->addDecalGraphic(active_id, el);
|
||
|
el.style = GraphicElement::STYLE_HIDDEN;
|
||
|
arch->addDecalGraphic(inactive_id, el);
|
||
|
|
||
|
for (int i = 0; i <= arch->gridDimY - 1; ++i) {
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
el.x1 = line_x;
|
||
|
el.y1 = pip_y + arch->gridDimY - 1. - i;
|
||
|
el.x2 = line_0;
|
||
|
el.y2 = el.y1;
|
||
|
arch->addDecalGraphic(active_id, el);
|
||
|
el.style = GraphicElement::STYLE_HIDDEN;
|
||
|
arch->addDecalGraphic(inactive_id, el);
|
||
|
}
|
||
|
}
|
||
|
arch->setWireDecal(wire.name, active, inactive);
|
||
|
return;
|
||
|
} else {
|
||
|
if (split_res.at(1).substr(0, 2) == "GB") {
|
||
|
snprintf(buf, sizeof(buf), "%s_active", wire.name.c_str(arch));
|
||
|
active_id = arch->id(buf);
|
||
|
active.decal = active_id;
|
||
|
snprintf(buf, sizeof(buf), "%s_inactive", wire.name.c_str(arch));
|
||
|
inactive_id = arch->id(buf);
|
||
|
inactive.decal = inactive_id;
|
||
|
active.x = inactive.x = 0;
|
||
|
active.y = inactive.y = 0;
|
||
|
|
||
|
float line_y = WIRE_Y(CLK_GBO0_Y) + arch->gridDimY - 1. - wire.y;
|
||
|
float line_0 = WIRE_Y(0) + arch->gridDimY - 1. - wire.y;
|
||
|
float pip_x = PIP_X(arch->id(split_res.at(1)));
|
||
|
if (split_res.at(1).at(2) >= '4') {
|
||
|
line_y = WIRE_Y(CLK_GBO1_Y) + arch->gridDimY - 1. - wire.y;
|
||
|
}
|
||
|
|
||
|
// create if absent
|
||
|
if (arch->decal_graphics.count(active_id) == 0) {
|
||
|
el.type = GraphicElement::TYPE_LINE;
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
el.x1 = wire.x + pip_x;
|
||
|
el.y1 = line_y;
|
||
|
el.x2 = el.x1;
|
||
|
el.y2 = line_0;
|
||
|
arch->addDecalGraphic(active_id, el);
|
||
|
el.style = GraphicElement::STYLE_INACTIVE;
|
||
|
arch->addDecalGraphic(inactive_id, el);
|
||
|
}
|
||
|
arch->setWireDecal(wire.name, active, inactive);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
// std::cout << wire.name.str(arch) << ":" << wire.type.str(arch) << " R" << wire.y + 1 << "C" << wire.x + 1 <<
|
||
|
// std::endl;
|
||
|
}
|
||
|
|
||
|
void gfxCreateBelDecals(Arch *arch)
|
||
|
{
|
||
|
GraphicElement el;
|
||
|
// LUTs
|
||
|
el.type = GraphicElement::TYPE_BOX;
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
el.x1 = lut_x;
|
||
|
el.x2 = el.x1 + lut_w;
|
||
|
el.y1 = 0.;
|
||
|
el.y2 = el.y1 + lut_h;
|
||
|
arch->addDecalGraphic(id_DECAL_LUT_ACTIVE, el);
|
||
|
arch->addDecalGraphic(id_DECAL_LUTDFF_ACTIVE, el);
|
||
|
arch->addDecalGraphic(id_DECAL_LUT_UNUSED_DFF_ACTIVE, el);
|
||
|
arch->addDecalGraphic(id_DECAL_ALU_ACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_INACTIVE;
|
||
|
arch->addDecalGraphic(id_DECAL_LUT_INACTIVE, el);
|
||
|
arch->addDecalGraphic(id_DECAL_LUTDFF_INACTIVE, el);
|
||
|
el.x1 = dff_x;
|
||
|
el.x2 = el.x1 + dff_w;
|
||
|
el.y1 = 0.;
|
||
|
el.y2 = el.y1 + lut_h;
|
||
|
arch->addDecalGraphic(id_DECAL_LUTDFF_INACTIVE, el);
|
||
|
arch->addDecalGraphic(id_DECAL_LUT_UNUSED_DFF_ACTIVE, el);
|
||
|
arch->addDecalGraphic(id_DECAL_ALU_ACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
arch->addDecalGraphic(id_DECAL_LUTDFF_ACTIVE, el);
|
||
|
el.type = GraphicElement::TYPE_LOCAL_LINE;
|
||
|
el.x1 = lut_x + 0.33f * lut_w;
|
||
|
el.x2 = el.x1 + 0.33f * lut_w;
|
||
|
el.y1 = 0.66f * lut_h;
|
||
|
el.y2 = el.y1;
|
||
|
arch->addDecalGraphic(id_DECAL_ALU_ACTIVE, el);
|
||
|
el.y1 = 0.3f * lut_h;
|
||
|
el.y2 = el.y1;
|
||
|
arch->addDecalGraphic(id_DECAL_ALU_ACTIVE, el);
|
||
|
el.x1 = lut_x + 0.5f * lut_w;
|
||
|
el.x2 = el.x1;
|
||
|
el.y1 = 0.5f * lut_h;
|
||
|
el.y2 = el.y1 + 0.33f * lut_h;
|
||
|
arch->addDecalGraphic(id_DECAL_ALU_ACTIVE, el);
|
||
|
|
||
|
// LUT group
|
||
|
el.type = GraphicElement::TYPE_BOX;
|
||
|
el.style = GraphicElement::STYLE_FRAME;
|
||
|
el.x1 = grp_lut_x;
|
||
|
el.x2 = el.x1 + grp_lut_w;
|
||
|
el.y1 = 0.;
|
||
|
el.y2 = el.y1 + grp_lut_h;
|
||
|
arch->addDecalGraphic(id_DECAL_GRP_LUT, el);
|
||
|
|
||
|
// CRU group
|
||
|
el.type = GraphicElement::TYPE_BOX;
|
||
|
el.style = GraphicElement::STYLE_FRAME;
|
||
|
el.x1 = cru_x;
|
||
|
el.x2 = el.x1 + cru_w;
|
||
|
el.y1 = cru_y;
|
||
|
el.y2 = el.y1 + cru_h;
|
||
|
arch->addDecalGraphic(id_DECAL_CRU, el);
|
||
|
|
||
|
// Mux with upper 1 input
|
||
|
el.type = GraphicElement::TYPE_LINE;
|
||
|
el.style = GraphicElement::STYLE_INACTIVE;
|
||
|
el.x1 = 0.;
|
||
|
el.x2 = mux_w;
|
||
|
el.y1 = 0.;
|
||
|
el.y2 = mux_f;
|
||
|
arch->addDecalGraphic(id_DECAL_MUXUPPER_INACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
arch->addDecalGraphic(id_DECAL_MUXUPPER_ACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_INACTIVE;
|
||
|
el.x1 = el.x2;
|
||
|
el.y1 = el.y2;
|
||
|
el.y2 = mux_h - mux_f;
|
||
|
arch->addDecalGraphic(id_DECAL_MUXUPPER_INACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
arch->addDecalGraphic(id_DECAL_MUXUPPER_ACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_INACTIVE;
|
||
|
el.x2 = 0.;
|
||
|
el.y1 = el.y2;
|
||
|
el.y2 = mux_h;
|
||
|
arch->addDecalGraphic(id_DECAL_MUXUPPER_INACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
arch->addDecalGraphic(id_DECAL_MUXUPPER_ACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_INACTIVE;
|
||
|
el.x1 = el.x2;
|
||
|
el.y1 = mux_h;
|
||
|
el.y2 = 0.;
|
||
|
arch->addDecalGraphic(id_DECAL_MUXUPPER_INACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
arch->addDecalGraphic(id_DECAL_MUXUPPER_ACTIVE, el);
|
||
|
// 1
|
||
|
el.style = GraphicElement::STYLE_INACTIVE;
|
||
|
el.x1 = 0.0038;
|
||
|
el.x2 = 0.0118;
|
||
|
el.y1 = el.y2 = 0.0598;
|
||
|
arch->addDecalGraphic(id_DECAL_MUXUPPER_INACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
arch->addDecalGraphic(id_DECAL_MUXUPPER_ACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_INACTIVE;
|
||
|
el.x1 = (el.x1 + el.x2) / 2.;
|
||
|
el.x2 = el.x1;
|
||
|
el.y2 = 0.0808;
|
||
|
arch->addDecalGraphic(id_DECAL_MUXUPPER_INACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
arch->addDecalGraphic(id_DECAL_MUXUPPER_ACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_INACTIVE;
|
||
|
el.x2 = 0.0038;
|
||
|
el.y1 = el.y2;
|
||
|
el.y2 = 0.0797;
|
||
|
arch->addDecalGraphic(id_DECAL_MUXUPPER_INACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
arch->addDecalGraphic(id_DECAL_MUXUPPER_ACTIVE, el);
|
||
|
|
||
|
// Mux with lower 1 input
|
||
|
el.type = GraphicElement::TYPE_LINE;
|
||
|
el.style = GraphicElement::STYLE_INACTIVE;
|
||
|
el.x1 = 0.;
|
||
|
el.x2 = mux_w;
|
||
|
el.y1 = 0.;
|
||
|
el.y2 = mux_f;
|
||
|
arch->addDecalGraphic(id_DECAL_MUXLOWER_INACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
arch->addDecalGraphic(id_DECAL_MUXLOWER_ACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_INACTIVE;
|
||
|
el.x1 = el.x2;
|
||
|
el.y1 = el.y2;
|
||
|
el.y2 = mux_h - mux_f;
|
||
|
arch->addDecalGraphic(id_DECAL_MUXLOWER_INACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
arch->addDecalGraphic(id_DECAL_MUXLOWER_ACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_INACTIVE;
|
||
|
el.x2 = 0.;
|
||
|
el.y1 = el.y2;
|
||
|
el.y2 = mux_h;
|
||
|
arch->addDecalGraphic(id_DECAL_MUXLOWER_INACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
arch->addDecalGraphic(id_DECAL_MUXLOWER_ACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_INACTIVE;
|
||
|
el.x1 = el.x2;
|
||
|
el.y1 = mux_h;
|
||
|
el.y2 = 0.;
|
||
|
arch->addDecalGraphic(id_DECAL_MUXLOWER_INACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
arch->addDecalGraphic(id_DECAL_MUXLOWER_ACTIVE, el);
|
||
|
// 1
|
||
|
el.style = GraphicElement::STYLE_INACTIVE;
|
||
|
el.x1 = 0.0038;
|
||
|
el.x2 = 0.0118;
|
||
|
el.y1 = el.y2 = 0.0140;
|
||
|
arch->addDecalGraphic(id_DECAL_MUXLOWER_INACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
arch->addDecalGraphic(id_DECAL_MUXLOWER_ACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_INACTIVE;
|
||
|
el.x1 = (el.x1 + el.x2) / 2.;
|
||
|
el.x2 = el.x1;
|
||
|
el.y2 = 0.0352;
|
||
|
arch->addDecalGraphic(id_DECAL_MUXLOWER_INACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
arch->addDecalGraphic(id_DECAL_MUXLOWER_ACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_INACTIVE;
|
||
|
el.x2 = 0.0038;
|
||
|
el.y1 = el.y2;
|
||
|
el.y2 = 0.0341;
|
||
|
arch->addDecalGraphic(id_DECAL_MUXLOWER_INACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
arch->addDecalGraphic(id_DECAL_MUXLOWER_ACTIVE, el);
|
||
|
|
||
|
// IOB
|
||
|
el.type = GraphicElement::TYPE_LINE;
|
||
|
el.style = GraphicElement::STYLE_INACTIVE;
|
||
|
el.x1 = 0.;
|
||
|
el.x2 = io_w;
|
||
|
el.y1 = 0.;
|
||
|
el.y2 = el.y1;
|
||
|
arch->addDecalGraphic(id_DECAL_IOB_INACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
arch->addDecalGraphic(id_DECAL_IOB_ACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_INACTIVE;
|
||
|
el.x1 = el.x2;
|
||
|
el.y2 = io_h;
|
||
|
arch->addDecalGraphic(id_DECAL_IOB_INACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
arch->addDecalGraphic(id_DECAL_IOB_ACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_INACTIVE;
|
||
|
el.x1 = 0.;
|
||
|
el.y1 = el.y2;
|
||
|
arch->addDecalGraphic(id_DECAL_IOB_INACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
arch->addDecalGraphic(id_DECAL_IOB_ACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_INACTIVE;
|
||
|
el.x2 = el.x1;
|
||
|
el.y2 = 0.;
|
||
|
arch->addDecalGraphic(id_DECAL_IOB_INACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
arch->addDecalGraphic(id_DECAL_IOB_ACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_INACTIVE;
|
||
|
el.x1 = io_w;
|
||
|
el.x2 = io_w * 1.3f;
|
||
|
el.y2 = el.y1 = io_h / 2.f;
|
||
|
arch->addDecalGraphic(id_DECAL_IOB_INACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
arch->addDecalGraphic(id_DECAL_IOB_ACTIVE, el);
|
||
|
|
||
|
// IOBS
|
||
|
el.type = GraphicElement::TYPE_LINE;
|
||
|
el.style = GraphicElement::STYLE_INACTIVE;
|
||
|
el.x1 = 0.;
|
||
|
el.x2 = ios_w;
|
||
|
el.y1 = 0.;
|
||
|
el.y2 = el.y1;
|
||
|
arch->addDecalGraphic(id_DECAL_IOBS_INACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
arch->addDecalGraphic(id_DECAL_IOBS_ACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_INACTIVE;
|
||
|
el.x1 = el.x2;
|
||
|
el.y2 = ios_h;
|
||
|
arch->addDecalGraphic(id_DECAL_IOBS_INACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
arch->addDecalGraphic(id_DECAL_IOBS_ACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_INACTIVE;
|
||
|
el.x1 = 0.;
|
||
|
el.y1 = el.y2;
|
||
|
arch->addDecalGraphic(id_DECAL_IOBS_INACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
arch->addDecalGraphic(id_DECAL_IOBS_ACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_INACTIVE;
|
||
|
el.x2 = el.x1;
|
||
|
el.y2 = 0.;
|
||
|
arch->addDecalGraphic(id_DECAL_IOBS_INACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
arch->addDecalGraphic(id_DECAL_IOBS_ACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_INACTIVE;
|
||
|
el.x1 = ios_w;
|
||
|
el.x2 = ios_w * 1.3f;
|
||
|
el.y2 = el.y1 = ios_h / 2.f;
|
||
|
arch->addDecalGraphic(id_DECAL_IOBS_INACTIVE, el);
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
arch->addDecalGraphic(id_DECAL_IOBS_ACTIVE, el);
|
||
|
}
|
||
|
|
||
|
void gfxSetBelDefaultDecal(Arch *arch, BelInfo &bel)
|
||
|
{
|
||
|
DecalXY active, inactive;
|
||
|
switch (bel.type.hash()) {
|
||
|
case ID_SLICE:
|
||
|
active.x = inactive.x = bel.x;
|
||
|
active.y = inactive.y = arch->gridDimY - 1. - bel.y + lut_y[bel.z];
|
||
|
if (bel.z < 6) {
|
||
|
active.decal = id_DECAL_LUTDFF_ACTIVE;
|
||
|
inactive.decal = id_DECAL_LUTDFF_INACTIVE;
|
||
|
} else {
|
||
|
active.decal = id_DECAL_LUT_ACTIVE;
|
||
|
inactive.decal = id_DECAL_LUT_INACTIVE;
|
||
|
}
|
||
|
arch->setBelDecal(bel.name, active, inactive);
|
||
|
break;
|
||
|
case ID_GW_MUX2_LUT5:
|
||
|
active.x = inactive.x = bel.x + mux2lut5_x;
|
||
|
active.y = inactive.y = arch->gridDimY - 1. - bel.y + mux2lut5_y[(bel.z - arch->mux_0_z) >> 1];
|
||
|
active.decal = id_DECAL_MUXUPPER_ACTIVE;
|
||
|
inactive.decal = id_DECAL_MUXUPPER_INACTIVE;
|
||
|
arch->setBelDecal(bel.name, active, inactive);
|
||
|
break;
|
||
|
case ID_GW_MUX2_LUT6:
|
||
|
active.x = inactive.x = bel.x + mux2lut6_x;
|
||
|
active.y = inactive.y = arch->gridDimY - 1. - bel.y + mux2lut6_y[(bel.z - arch->mux_0_z) / 5];
|
||
|
active.decal = id_DECAL_MUXLOWER_ACTIVE;
|
||
|
inactive.decal = id_DECAL_MUXLOWER_INACTIVE;
|
||
|
arch->setBelDecal(bel.name, active, inactive);
|
||
|
break;
|
||
|
case ID_GW_MUX2_LUT7:
|
||
|
active.x = inactive.x = bel.x + mux2lut7_x;
|
||
|
active.y = inactive.y = arch->gridDimY - 1. - bel.y + mux2lut7_y;
|
||
|
active.decal = id_DECAL_MUXLOWER_ACTIVE;
|
||
|
inactive.decal = id_DECAL_MUXLOWER_INACTIVE;
|
||
|
arch->setBelDecal(bel.name, active, inactive);
|
||
|
break;
|
||
|
case ID_GW_MUX2_LUT8:
|
||
|
active.x = inactive.x = bel.x + mux2lut8_x;
|
||
|
active.y = inactive.y = arch->gridDimY - 1. - bel.y + mux2lut8_y;
|
||
|
active.decal = id_DECAL_MUXUPPER_ACTIVE;
|
||
|
inactive.decal = id_DECAL_MUXUPPER_INACTIVE;
|
||
|
arch->setBelDecal(bel.name, active, inactive);
|
||
|
break;
|
||
|
case ID_IOB:
|
||
|
active.x = inactive.x = bel.x + io_x;
|
||
|
active.y = inactive.y = arch->gridDimY - 1. - bel.y + io_y + bel.z * (2 * io_gap + io_h);
|
||
|
active.decal = id_DECAL_IOB_ACTIVE;
|
||
|
inactive.decal = id_DECAL_IOB_INACTIVE;
|
||
|
arch->setBelDecal(bel.name, active, inactive);
|
||
|
gfxSetIOBWireDecals(arch, bel);
|
||
|
break;
|
||
|
case ID_IOBS:
|
||
|
active.x = inactive.x = bel.x + ios_x + (ios_w + ios_gap_x) * (bel.z % 3);
|
||
|
active.y = inactive.y = arch->gridDimY - 1. - bel.y + ios_y + (ios_h + ios_gap_y) * (bel.z / 3);
|
||
|
active.decal = id_DECAL_IOBS_ACTIVE;
|
||
|
inactive.decal = id_DECAL_IOBS_INACTIVE;
|
||
|
arch->setBelDecal(bel.name, active, inactive);
|
||
|
gfxSetIOBSWireDecals(arch, bel);
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void gfxSetIOBWireDecals(Arch *arch, BelInfo &bel)
|
||
|
{
|
||
|
DecalXY active, inactive;
|
||
|
GraphicElement el;
|
||
|
char buf[20];
|
||
|
|
||
|
// set decals for I, O and OE input wires
|
||
|
for (auto pi : bel.pins) {
|
||
|
WireInfo &wi = arch->wire_info(pi.second.wire);
|
||
|
// decal name: wire_port_z_active|inactive
|
||
|
snprintf(buf, sizeof(buf), "%s_%s_%u_active", wi.type.c_str(arch), pi.first.c_str(arch), bel.z);
|
||
|
IdString active_id = arch->id(buf);
|
||
|
active.decal = active_id;
|
||
|
snprintf(buf, sizeof(buf), "%s_%s_%u_inactive", wi.type.c_str(arch), pi.first.c_str(arch), bel.z);
|
||
|
IdString inactive_id = arch->id(buf);
|
||
|
inactive.decal = inactive_id;
|
||
|
active.x = inactive.x = bel.x;
|
||
|
active.y = inactive.y = arch->gridDimY - 1. - bel.y;
|
||
|
if (arch->decal_graphics.count(active_id) == 0) {
|
||
|
el.type = GraphicElement::TYPE_LOCAL_LINE;
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
el.x1 = cru_x + cru_w;
|
||
|
el.y1 = pipPoint.at(wi.type).second;
|
||
|
el.x2 = io_x;
|
||
|
el.y2 = portPoint.at(pi.first) + io_y + bel.z * (2 * io_gap + io_h);
|
||
|
arch->addDecalGraphic(active_id, el);
|
||
|
el.style = GraphicElement::STYLE_INACTIVE;
|
||
|
arch->addDecalGraphic(inactive_id, el);
|
||
|
for (auto seg : portSign.at(pi.first)) {
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
el.x1 = std::get<0>(seg) + io_x;
|
||
|
el.y1 = std::get<1>(seg) + io_y + bel.z * (2 * io_gap + io_h);
|
||
|
el.x2 = std::get<2>(seg) + io_x;
|
||
|
el.y2 = std::get<3>(seg) + io_y + bel.z * (2 * io_gap + io_h);
|
||
|
arch->addDecalGraphic(active_id, el);
|
||
|
el.style = GraphicElement::STYLE_INACTIVE;
|
||
|
arch->addDecalGraphic(inactive_id, el);
|
||
|
}
|
||
|
}
|
||
|
arch->setWireDecal(wi.name, active, inactive);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void gfxSetIOBSWireDecals(Arch *arch, BelInfo &bel)
|
||
|
{
|
||
|
DecalXY active, inactive;
|
||
|
GraphicElement el;
|
||
|
char buf[20];
|
||
|
|
||
|
// set decals for I, O and OE input wires
|
||
|
for (auto pi : bel.pins) {
|
||
|
WireInfo &wi = arch->wire_info(pi.second.wire);
|
||
|
// decal name: ios_wire_port_z_active|inactive
|
||
|
snprintf(buf, sizeof(buf), "ios_%s_%s_%u_active", wi.type.c_str(arch), pi.first.c_str(arch), bel.z);
|
||
|
IdString active_id = arch->id(buf);
|
||
|
active.decal = active_id;
|
||
|
snprintf(buf, sizeof(buf), "ios_%s_%s_%u_inactive", wi.type.c_str(arch), pi.first.c_str(arch), bel.z);
|
||
|
IdString inactive_id = arch->id(buf);
|
||
|
inactive.decal = inactive_id;
|
||
|
active.x = inactive.x = bel.x;
|
||
|
active.y = inactive.y = arch->gridDimY - 1. - bel.y;
|
||
|
if (arch->decal_graphics.count(active_id) == 0) {
|
||
|
// leftmost wires
|
||
|
el.type = GraphicElement::TYPE_LOCAL_LINE;
|
||
|
if (bel.z % 3 == 0) {
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
el.x1 = cru_x + cru_w;
|
||
|
el.y1 = pipPoint.at(wi.type).second;
|
||
|
el.x2 = ios_x;
|
||
|
el.y2 = ios_scl * portPoint.at(pi.first) + ios_y + (ios_h + ios_gap_y) * (bel.z / 3);
|
||
|
arch->addDecalGraphic(active_id, el);
|
||
|
el.style = GraphicElement::STYLE_INACTIVE;
|
||
|
arch->addDecalGraphic(inactive_id, el);
|
||
|
} else {
|
||
|
float col = (bel.z % 3) - 1;
|
||
|
float rel_port = portPoint.at(pi.first) / io_h;
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
el.x1 = cru_x + cru_w;
|
||
|
el.y1 = pipPoint.at(wi.type).second;
|
||
|
el.x2 = ios_x * (0.97 - 0.02 * col);
|
||
|
el.y2 = (rel_port + col) * 0.5 * ios_gap_y + ios_y + ios_h + (ios_h + ios_gap_y) * (bel.z / 3);
|
||
|
arch->addDecalGraphic(active_id, el);
|
||
|
el.style = GraphicElement::STYLE_INACTIVE;
|
||
|
arch->addDecalGraphic(inactive_id, el);
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
el.x1 = ios_x + (ios_w + ios_gap_x) * (col + 1) - ios_gap_x + ios_w * 0.3 +
|
||
|
rel_port * (ios_gap_x - 0.3 * ios_w);
|
||
|
el.y1 = el.y2;
|
||
|
arch->addDecalGraphic(active_id, el);
|
||
|
el.style = GraphicElement::STYLE_INACTIVE;
|
||
|
arch->addDecalGraphic(inactive_id, el);
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
el.x2 = el.x1;
|
||
|
el.y2 = ios_scl * portPoint.at(pi.first) + ios_y + (ios_h + ios_gap_y) * (bel.z / 3);
|
||
|
arch->addDecalGraphic(active_id, el);
|
||
|
el.style = GraphicElement::STYLE_INACTIVE;
|
||
|
arch->addDecalGraphic(inactive_id, el);
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
el.x1 = ios_x + (ios_w + ios_gap_x) * (col + 1);
|
||
|
el.y1 = el.y2;
|
||
|
arch->addDecalGraphic(active_id, el);
|
||
|
el.style = GraphicElement::STYLE_INACTIVE;
|
||
|
arch->addDecalGraphic(inactive_id, el);
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
}
|
||
|
// signs
|
||
|
for (auto seg : portSign.at(pi.first)) {
|
||
|
el.style = GraphicElement::STYLE_ACTIVE;
|
||
|
el.x1 = ios_scl * std::get<0>(seg) + ios_x + (ios_w + ios_gap_x) * (bel.z % 3);
|
||
|
el.y1 = ios_scl * std::get<1>(seg) + ios_y + (ios_h + ios_gap_y) * (bel.z / 3);
|
||
|
el.x2 = ios_scl * std::get<2>(seg) + ios_x + (ios_w + ios_gap_x) * (bel.z % 3);
|
||
|
el.y2 = ios_scl * std::get<3>(seg) + ios_y + (ios_h + ios_gap_y) * (bel.z / 3);
|
||
|
arch->addDecalGraphic(active_id, el);
|
||
|
el.style = GraphicElement::STYLE_INACTIVE;
|
||
|
arch->addDecalGraphic(inactive_id, el);
|
||
|
}
|
||
|
}
|
||
|
arch->setWireDecal(wi.name, active, inactive);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
DecalXY gfxGetLutGroupDecalXY(int x, int y, int z)
|
||
|
{
|
||
|
DecalXY decalxy;
|
||
|
decalxy.decal = id_DECAL_GRP_LUT;
|
||
|
decalxy.x = x;
|
||
|
decalxy.y = y + grp_lut_y[z];
|
||
|
return decalxy;
|
||
|
}
|
||
|
|
||
|
DecalXY gfxGetCruGroupDecalXY(int x, int y)
|
||
|
{
|
||
|
DecalXY decalxy;
|
||
|
decalxy.decal = id_DECAL_CRU;
|
||
|
decalxy.x = x;
|
||
|
decalxy.y = y;
|
||
|
return decalxy;
|
||
|
}
|
||
|
|
||
|
NEXTPNR_NAMESPACE_END
|