diff --git a/common/timing.cc b/common/timing.cc index d1a85779..81ce7b73 100644 --- a/common/timing.cc +++ b/common/timing.cc @@ -212,7 +212,8 @@ struct Timing for (auto net : boost::adaptors::reverse(topographical_order)) { auto &nd = net_data.at(net); // Ignore false startpoints - if (nd.false_startpoint) continue; + if (nd.false_startpoint) + continue; const delay_t net_length_plus_one = nd.max_path_length + 1; auto &net_min_remaining_budget = nd.min_remaining_budget; for (auto &usr : net->users) { diff --git a/gui/ecp5/mainwindow.cc b/gui/ecp5/mainwindow.cc index fe2f9e57..c6c7bc97 100644 --- a/gui/ecp5/mainwindow.cc +++ b/gui/ecp5/mainwindow.cc @@ -18,9 +18,9 @@ */ #include "mainwindow.h" +#include #include "bitstream.h" #include "log.h" -#include #include #include @@ -150,7 +150,7 @@ void MainWindow::open_lpf() { QString fileName = QFileDialog::getOpenFileName(this, QString("Open LPF"), QString(), QString("*.lpf")); if (!fileName.isEmpty()) { - std::ifstream in(fileName.toStdString()); + std::ifstream in(fileName.toStdString()); if (ctx->applyLPF(fileName.toStdString(), in)) { log("Loading LPF successful.\n"); actionPack->setEnabled(true); @@ -158,7 +158,7 @@ void MainWindow::open_lpf() } else { actionLoadLPF->setEnabled(true); log("Loading LPF failed.\n"); - } + } } } diff --git a/gui/fpgaviewwidget.cc b/gui/fpgaviewwidget.cc index 24fbc35d..e6f68d22 100644 --- a/gui/fpgaviewwidget.cc +++ b/gui/fpgaviewwidget.cc @@ -107,9 +107,8 @@ void FPGAViewWidget::initializeGL() } initializeOpenGLFunctions(); QtImGui::initialize(this); - glClearColor(colors_.background.red() / 255, colors_.background.green() / 255, - colors_.background.blue() / 255, 0.0); - + glClearColor(colors_.background.red() / 255, colors_.background.green() / 255, colors_.background.blue() / 255, + 0.0); { QMutexLocker locker(&rendererDataLock_); @@ -321,30 +320,22 @@ void FPGAViewWidget::paintGL() } // Render the grid. - lineShader_.draw(GraphicElement::STYLE_GRID, colors_.grid, thick1Px, - matrix); + lineShader_.draw(GraphicElement::STYLE_GRID, colors_.grid, thick1Px, matrix); // Render Arch graphics. - lineShader_.draw(GraphicElement::STYLE_FRAME, colors_.frame, thick11Px, - matrix); - lineShader_.draw(GraphicElement::STYLE_HIDDEN, colors_.hidden, thick11Px, - matrix); - lineShader_.draw(GraphicElement::STYLE_INACTIVE, colors_.inactive, - thick11Px, matrix); - lineShader_.draw(GraphicElement::STYLE_ACTIVE, colors_.active, thick11Px, - matrix); + lineShader_.draw(GraphicElement::STYLE_FRAME, colors_.frame, thick11Px, matrix); + lineShader_.draw(GraphicElement::STYLE_HIDDEN, colors_.hidden, thick11Px, matrix); + lineShader_.draw(GraphicElement::STYLE_INACTIVE, colors_.inactive, thick11Px, matrix); + lineShader_.draw(GraphicElement::STYLE_ACTIVE, colors_.active, thick11Px, matrix); // Draw highlighted items. for (int i = 0; i < 8; i++) { - GraphicElement::style_t style = (GraphicElement::style_t)( - GraphicElement::STYLE_HIGHLIGHTED0 + i); + GraphicElement::style_t style = (GraphicElement::style_t)(GraphicElement::STYLE_HIGHLIGHTED0 + i); lineShader_.draw(style, colors_.highlight[i], thick11Px, matrix); } - lineShader_.draw(GraphicElement::STYLE_SELECTED, colors_.selected, - thick11Px, matrix); - lineShader_.draw(GraphicElement::STYLE_HOVER, colors_.hovered, - thick2Px, matrix); + lineShader_.draw(GraphicElement::STYLE_SELECTED, colors_.selected, thick11Px, matrix); + lineShader_.draw(GraphicElement::STYLE_HOVER, colors_.hovered, thick2Px, matrix); // Flags from pipeline. PassthroughFlags flags = rendererData_->flags; @@ -364,8 +355,7 @@ void FPGAViewWidget::paintGL() } QtImGui::newFrame(); QMutexLocker lock(&rendererArgsLock_); - if (!(rendererArgs_->hoveredDecal == DecalXY()) && rendererArgs_->hintText.size() > 0) - { + if (!(rendererArgs_->hoveredDecal == DecalXY()) && rendererArgs_->hintText.size() > 0) { ImGui::SetNextWindowPos(ImVec2(rendererArgs_->x, rendererArgs_->y)); ImGui::BeginTooltip(); ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f); @@ -373,7 +363,7 @@ void FPGAViewWidget::paintGL() ImGui::PopTextWrapPos(); ImGui::EndTooltip(); } - ImGui::Render(); + ImGui::Render(); } void FPGAViewWidget::pokeRenderer(void) { renderRunner_->poke(); } @@ -465,10 +455,10 @@ void FPGAViewWidget::renderLines(void) int last_render[GraphicElement::STYLE_HIGHLIGHTED0]; { QMutexLocker locker(&rendererDataLock_); - for(int i =0; igfxByStyle[(enum GraphicElement::style_t)i].last_render; } - + auto data = std::unique_ptr(new FPGAViewWidget::RendererData); // Reset bounding box. data->bbGlobal.clear(); @@ -534,7 +524,7 @@ void FPGAViewWidget::renderLines(void) for (int i = 0; i < 8; i++) data->gfxHighlighted[i] = rendererData_->gfxHighlighted[i]; } - for(int i =0; igfxByStyle[(enum GraphicElement::style_t)i].last_render = ++last_render[i]; rendererData_ = std::move(data); } @@ -545,7 +535,7 @@ void FPGAViewWidget::renderLines(void) // Whether the currently being hovered decal is also selected. bool hoveringSelected = false; - // Render selected. + // Render selected. rendererData_->bbSelected.clear(); rendererData_->gfxSelected.clear(); for (auto &decal : selectedDecals) { @@ -655,7 +645,8 @@ boost::optional FPGAViewWidget::pickElement(float void FPGAViewWidget::mousePressEvent(QMouseEvent *event) { ImGuiIO &io = ImGui::GetIO(); - if (io.WantCaptureMouse) return; + if (io.WantCaptureMouse) + return; if (event->buttons() & Qt::RightButton || event->buttons() & Qt::MidButton) { lastDragPos_ = event->pos(); @@ -691,7 +682,8 @@ void FPGAViewWidget::mousePressEvent(QMouseEvent *event) void FPGAViewWidget::mouseMoveEvent(QMouseEvent *event) { ImGuiIO &io = ImGui::GetIO(); - if (io.WantCaptureMouse) return; + if (io.WantCaptureMouse) + return; if (event->buttons() & Qt::RightButton || event->buttons() & Qt::MidButton) { const int dx = event->x() - lastDragPos_.x(); @@ -728,22 +720,23 @@ void FPGAViewWidget::mouseMoveEvent(QMouseEvent *event) if (closest.type == ElementType::BEL) { rendererArgs_->hintText = std::string("BEL\n") + ctx_->getBelName(closest.bel).c_str(ctx_); CellInfo *cell = ctx_->getBoundBelCell(closest.bel); - if (cell!=nullptr) - rendererArgs_->hintText += std::string("\nCELL\n") +ctx_->nameOf(cell); + if (cell != nullptr) + rendererArgs_->hintText += std::string("\nCELL\n") + ctx_->nameOf(cell); } else if (closest.type == ElementType::WIRE) { rendererArgs_->hintText = std::string("WIRE\n") + ctx_->getWireName(closest.wire).c_str(ctx_); NetInfo *net = ctx_->getBoundWireNet(closest.wire); - if (net!=nullptr) - rendererArgs_->hintText += std::string("\nNET\n") +ctx_->nameOf(net); + if (net != nullptr) + rendererArgs_->hintText += std::string("\nNET\n") + ctx_->nameOf(net); } else if (closest.type == ElementType::PIP) { rendererArgs_->hintText = std::string("PIP\n") + ctx_->getPipName(closest.pip).c_str(ctx_); NetInfo *net = ctx_->getBoundPipNet(closest.pip); - if (net!=nullptr) - rendererArgs_->hintText += std::string("\nNET\n") +ctx_->nameOf(net); + if (net != nullptr) + rendererArgs_->hintText += std::string("\nNET\n") + ctx_->nameOf(net); } else if (closest.type == ElementType::GROUP) { rendererArgs_->hintText = std::string("GROUP\n") + ctx_->getGroupName(closest.group).c_str(ctx_); - } else rendererArgs_->hintText = ""; - + } else + rendererArgs_->hintText = ""; + pokeRenderer(); } update(); @@ -793,8 +786,9 @@ QVector4D FPGAViewWidget::mouseToWorldDimensions(float x, float y) void FPGAViewWidget::wheelEvent(QWheelEvent *event) { ImGuiIO &io = ImGui::GetIO(); - if (io.WantCaptureMouse) return; - + if (io.WantCaptureMouse) + return; + QPoint degree = event->angleDelta() / 8; if (!degree.isNull()) @@ -876,23 +870,17 @@ void FPGAViewWidget::leaveEvent(QEvent *event) void FPGAViewWidget::update_vbos() { - for (int style = GraphicElement::STYLE_FRAME; style - < GraphicElement::STYLE_HIGHLIGHTED0; - style++) { - lineShader_.update_vbos((enum GraphicElement::style_t)(style), - rendererData_->gfxByStyle[style]); + for (int style = GraphicElement::STYLE_FRAME; style < GraphicElement::STYLE_HIGHLIGHTED0; style++) { + lineShader_.update_vbos((enum GraphicElement::style_t)(style), rendererData_->gfxByStyle[style]); } for (int i = 0; i < 8; i++) { - GraphicElement::style_t style = (GraphicElement::style_t)( - GraphicElement::STYLE_HIGHLIGHTED0 + i); + GraphicElement::style_t style = (GraphicElement::style_t)(GraphicElement::STYLE_HIGHLIGHTED0 + i); lineShader_.update_vbos(style, rendererData_->gfxHighlighted[i]); } - lineShader_.update_vbos(GraphicElement::STYLE_SELECTED, - rendererData_->gfxSelected); - lineShader_.update_vbos(GraphicElement::STYLE_HOVER, - rendererData_->gfxHovered); + lineShader_.update_vbos(GraphicElement::STYLE_SELECTED, rendererData_->gfxSelected); + lineShader_.update_vbos(GraphicElement::STYLE_HOVER, rendererData_->gfxHovered); } NEXTPNR_NAMESPACE_END diff --git a/gui/fpgaviewwidget.h b/gui/fpgaviewwidget.h index e76e6f32..a4830898 100644 --- a/gui/fpgaviewwidget.h +++ b/gui/fpgaviewwidget.h @@ -127,7 +127,7 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions private: const float zoomNear_ = 0.1f; // do not zoom closer than this - float zoomFar_ = 10.0f; // do not zoom further than this + float zoomFar_ = 10.0f; // do not zoom further than this const float zoomLvl1_ = 1.0f; const float zoomLvl2_ = 5.0f; @@ -271,7 +271,7 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions // Hint text std::string hintText; // cursor pos - int x,y; + int x, y; }; std::unique_ptr rendererArgs_; QMutex rendererArgsLock_; diff --git a/gui/lineshader.cc b/gui/lineshader.cc index fc726df5..eded1689 100644 --- a/gui/lineshader.cc +++ b/gui/lineshader.cc @@ -206,8 +206,7 @@ bool LineShader::compile(void) return true; } -void LineShader::update_vbos(enum GraphicElement::style_t style, - const LineShaderData &line) +void LineShader::update_vbos(enum GraphicElement::style_t style, const LineShaderData &line) { if (buffers_[style].last_vbo_update == line.last_render) return; @@ -230,8 +229,8 @@ void LineShader::update_vbos(enum GraphicElement::style_t style, buffers_[style].index.allocate(&line.indices[0], sizeof(GLuint) * line.indices.size()); } -void LineShader::draw(enum GraphicElement::style_t style, const QColor &color, - float thickness, const QMatrix4x4 &projection) +void LineShader::draw(enum GraphicElement::style_t style, const QColor &color, float thickness, + const QMatrix4x4 &projection) { auto gl = QOpenGLContext::currentContext()->functions(); if (buffers_[style].indices == 0) diff --git a/gui/lineshader.h b/gui/lineshader.h index eb0f9e09..98042051 100644 --- a/gui/lineshader.h +++ b/gui/lineshader.h @@ -20,12 +20,12 @@ #ifndef LINESHADER_H #define LINESHADER_H -#include #include #include #include #include #include +#include #include "log.h" #include "nextpnr.h" @@ -169,9 +169,7 @@ class LineShader } uniforms_; public: - LineShader(QObject *parent) : parent_(parent), program_(nullptr) - { - } + LineShader(QObject *parent) : parent_(parent), program_(nullptr) {} static constexpr const char *vertexShaderSource_ = "#version 110\n" @@ -194,12 +192,10 @@ class LineShader // Must be called on initialization. bool compile(void); - void update_vbos(enum GraphicElement::style_t style, - const LineShaderData &line); + void update_vbos(enum GraphicElement::style_t style, const LineShaderData &line); // Render a LineShaderData with a given M/V/P transformation. - void draw(enum GraphicElement::style_t style, const QColor &color, - float thickness, const QMatrix4x4 &projection); + void draw(enum GraphicElement::style_t style, const QColor &color, float thickness, const QMatrix4x4 &projection); }; NEXTPNR_NAMESPACE_END diff --git a/ice40/arch.cc b/ice40/arch.cc index eb26ae5a..d940e773 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -872,16 +872,13 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, Id if (cell->lcInfo.dffEnable) { clockPort = id_CLK; return TMG_REGISTER_OUTPUT; - } - else + } else return TMG_COMB_OUTPUT; - } - else { + } else { if (cell->lcInfo.dffEnable) { clockPort = id_CLK; return TMG_REGISTER_INPUT; - } - else + } else return TMG_COMB_INPUT; } } else if (cell->type == id_ICESTORM_RAM) { diff --git a/ice40/gfx.cc b/ice40/gfx.cc index c41c424b..7ef43663 100644 --- a/ice40/gfx.cc +++ b/ice40/gfx.cc @@ -972,11 +972,11 @@ void gfxTilePip(std::vector &g, int x, int y, GfxTileWireId src, return; } - if (getWireXY_local(src, x1, y1) && getWireXY_local(dst, x2, y2)) { + if (getWireXY_local(src, x1, y1) && getWireXY_local(dst, x2, y2)) { pipGfx(g, x, y, x1, y1, x2, y2, local_swbox_x1, local_swbox_y1, local_swbox_x2, local_swbox_y2, style); return; } - + if (TILE_WIRE_LUTFF_0_IN_0_LUT <= src && src <= TILE_WIRE_LUTFF_7_IN_3_LUT && TILE_WIRE_LUTFF_0_OUT <= dst && dst <= TILE_WIRE_LUTFF_7_OUT) { int lut_idx = (src - TILE_WIRE_LUTFF_0_IN_0_LUT) / 4; diff --git a/ice40/pack.cc b/ice40/pack.cc index edd12f92..b9360b74 100644 --- a/ice40/pack.cc +++ b/ice40/pack.cc @@ -462,7 +462,8 @@ static bool is_logic_port(BaseCtx *ctx, const PortRef &port) static void insert_global(Context *ctx, NetInfo *net, bool is_reset, bool is_cen, bool is_logic) { - log_info("promoting %s%s%s%s\n", net->name.c_str(ctx), is_reset ? " [reset]" : "", is_cen ? " [cen]" : "", is_logic ? " [logic]" : ""); + log_info("promoting %s%s%s%s\n", net->name.c_str(ctx), is_reset ? " [reset]" : "", is_cen ? " [cen]" : "", + is_logic ? " [logic]" : ""); std::string glb_name = net->name.str(ctx) + std::string("_$glb_") + (is_reset ? "sr" : (is_cen ? "ce" : "clk")); std::unique_ptr gb = create_ice_cell(ctx, ctx->id("SB_GB"), "$gbuf_" + glb_name); diff --git a/xc7/arch.cc b/xc7/arch.cc index 9cc635ea..18f5b64e 100644 --- a/xc7/arch.cc +++ b/xc7/arch.cc @@ -32,19 +32,25 @@ NEXTPNR_NAMESPACE_BEGIN - std::unique_ptr torc_info; TorcInfo::TorcInfo(Arch *ctx, const std::string &inDeviceName, const std::string &inPackageName) - : ddb(new DDB(inDeviceName, inPackageName)), sites(ddb->getSites()), tiles(ddb->getTiles()), segments(ddb->getSegments()), bel_to_site_index(construct_bel_to_site_index(ctx, sites)), num_bels(bel_to_site_index.size()), site_index_to_type(construct_site_index_to_type(ctx, sites)), bel_to_loc(construct_bel_to_loc(sites, tiles, num_bels, site_index_to_type)), wire_to_tilewire(construct_wire_to_tilewire(segments, tiles, segment_to_wire, trivial_to_wire)), num_wires(wire_to_tilewire.size()), wire_to_delay(construct_wire_to_delay(wire_to_tilewire, *ddb)), pip_to_arc(construct_pip_to_arc(wire_to_tilewire, *ddb, wire_to_pips_uphill, wire_to_pips_downhill)), num_pips(pip_to_arc.size()) + : ddb(new DDB(inDeviceName, inPackageName)), sites(ddb->getSites()), tiles(ddb->getTiles()), + segments(ddb->getSegments()), bel_to_site_index(construct_bel_to_site_index(ctx, sites)), + num_bels(bel_to_site_index.size()), site_index_to_type(construct_site_index_to_type(ctx, sites)), + bel_to_loc(construct_bel_to_loc(sites, tiles, num_bels, site_index_to_type)), + wire_to_tilewire(construct_wire_to_tilewire(segments, tiles, segment_to_wire, trivial_to_wire)), + num_wires(wire_to_tilewire.size()), wire_to_delay(construct_wire_to_delay(wire_to_tilewire, *ddb)), + pip_to_arc(construct_pip_to_arc(wire_to_tilewire, *ddb, wire_to_pips_uphill, wire_to_pips_downhill)), + num_pips(pip_to_arc.size()) { pip_to_dst_wire.reserve(num_pips); - for (const auto& arc : pip_to_arc) { + for (const auto &arc : pip_to_arc) { const auto &tw = arc.getSinkTilewire(); pip_to_dst_wire.push_back(tilewire_to_wire(tw)); } } -std::vector TorcInfo::construct_bel_to_site_index(Arch* ctx, const Sites &sites) +std::vector TorcInfo::construct_bel_to_site_index(Arch *ctx, const Sites &sites) { std::vector bel_to_site_index; bel_to_site_index.reserve(sites.getSiteCount()); @@ -57,13 +63,12 @@ std::vector TorcInfo::construct_bel_to_site_index(Arch* ctx, const Si bel_to_site_index.push_back(i); bel_to_site_index.push_back(i); bel_to_site_index.push_back(i); - } - else + } else bel_to_site_index.push_back(i); } return bel_to_site_index; } -std::vector TorcInfo::construct_site_index_to_type(Arch* ctx, const Sites &sites) +std::vector TorcInfo::construct_site_index_to_type(Arch *ctx, const Sites &sites) { std::vector site_index_to_type; site_index_to_type.resize(sites.getSiteCount()); @@ -80,7 +85,8 @@ std::vector TorcInfo::construct_site_index_to_type(Arch* ctx, const Si } return site_index_to_type; } -std::vector TorcInfo::construct_bel_to_loc(const Sites &sites, const Tiles &tiles, const int num_bels, const std::vector &site_index_to_type) +std::vector TorcInfo::construct_bel_to_loc(const Sites &sites, const Tiles &tiles, const int num_bels, + const std::vector &site_index_to_type) { std::vector bel_to_loc; bel_to_loc.resize(num_bels); @@ -94,44 +100,46 @@ std::vector TorcInfo::construct_bel_to_loc(const Sites &sites, const Tiles if (site_index_to_type[i] == id_SLICE_LUT6) { const auto site_name = site.getName(); const auto site_name_back = site_name.back(); - if (site_name_back == '0' || site_name_back == '2' || site_name_back == '4' || site_name_back == '6' || site_name_back == '8') { + if (site_name_back == '0' || site_name_back == '2' || site_name_back == '4' || site_name_back == '6' || + site_name_back == '8') { bel_to_loc[bel_index++] = Loc(x, y, 0); bel_to_loc[bel_index++] = Loc(x, y, 1); bel_to_loc[bel_index++] = Loc(x, y, 2); bel_to_loc[bel_index++] = Loc(x, y, 3); - } - else { + } else { bel_to_loc[bel_index++] = Loc(x, y, 4); bel_to_loc[bel_index++] = Loc(x, y, 5); bel_to_loc[bel_index++] = Loc(x, y, 6); bel_to_loc[bel_index++] = Loc(x, y, 7); } - } - else + } else bel_to_loc[bel_index++] = Loc(x, y, 0); } return bel_to_loc; } -std::vector TorcInfo::construct_wire_to_tilewire(const Segments& segments, const Tiles& tiles, std::unordered_map& segment_to_wire, std::unordered_map& trivial_to_wire) +std::vector +TorcInfo::construct_wire_to_tilewire(const Segments &segments, const Tiles &tiles, + std::unordered_map &segment_to_wire, + std::unordered_map &trivial_to_wire) { std::vector wire_to_tilewire; Tilewire currentTilewire; - for(TileIndex tileIndex(0); tileIndex < tiles.getTileCount(); tileIndex++) { + for (TileIndex tileIndex(0); tileIndex < tiles.getTileCount(); tileIndex++) { // iterate over every wire in the tile - const auto& tileInfo = tiles.getTileInfo(tileIndex); + const auto &tileInfo = tiles.getTileInfo(tileIndex); auto tileTypeIndex = tileInfo.getTypeIndex(); auto wireCount = tiles.getWireCount(tileTypeIndex); currentTilewire.setTileIndex(tileIndex); - for(WireIndex wireIndex(0); wireIndex < wireCount; wireIndex++) { + for (WireIndex wireIndex(0); wireIndex < wireCount; wireIndex++) { currentTilewire.setWireIndex(wireIndex); - const auto& currentSegment = segments.getTilewireSegment(currentTilewire); + const auto ¤tSegment = segments.getTilewireSegment(currentTilewire); if (!currentSegment.isTrivial()) { - if (currentSegment.getAnchorTileIndex() != tileIndex) continue; + if (currentSegment.getAnchorTileIndex() != tileIndex) + continue; segment_to_wire.emplace(currentSegment, wire_to_tilewire.size()); - } - else + } else trivial_to_wire.emplace(currentTilewire, wire_to_tilewire.size()); wire_to_tilewire.push_back(currentTilewire); @@ -141,46 +149,54 @@ std::vector TorcInfo::construct_wire_to_tilewire(const Segments& segme wire_to_tilewire.shrink_to_fit(); return wire_to_tilewire; } -std::vector TorcInfo::construct_wire_to_delay(const std::vector& wire_to_tilewire, const DDB &ddb) +std::vector TorcInfo::construct_wire_to_delay(const std::vector &wire_to_tilewire, const DDB &ddb) { std::vector wire_to_delay; wire_to_delay.reserve(wire_to_tilewire.size()); - const boost::regex re_124 = boost::regex("(.+_)?[NESW][NESWLR](\\d)((BEG(_[NS])?)|(END(_[NS])?)|[A-E])?\\d(_\\d)?"); - const boost::regex re_L = boost::regex("(.+_)?L(H|V|VB)(_L)?\\d+(_\\d)?"); - const boost::regex re_BYP = boost::regex("BYP(_ALT)?\\d"); - const boost::regex re_BYP_B = boost::regex("BYP_[BL]\\d"); + const boost::regex re_124 = boost::regex("(.+_)?[NESW][NESWLR](\\d)((BEG(_[NS])?)|(END(_[NS])?)|[A-E])?\\d(_\\d)?"); + const boost::regex re_L = boost::regex("(.+_)?L(H|V|VB)(_L)?\\d+(_\\d)?"); + const boost::regex re_BYP = boost::regex("BYP(_ALT)?\\d"); + const boost::regex re_BYP_B = boost::regex("BYP_[BL]\\d"); const boost::regex re_BOUNCE_NS = boost::regex("(BYP|FAN)_BOUNCE_[NS]3_\\d"); - const boost::regex re_FAN = boost::regex("FAN(_ALT)?\\d"); + const boost::regex re_FAN = boost::regex("FAN(_ALT)?\\d"); boost::cmatch what; ExtendedWireInfo ewi(ddb); - for (const auto &tw : wire_to_tilewire) - { + for (const auto &tw : wire_to_tilewire) { ewi.set(tw); DelayInfo d; if (boost::regex_match(ewi.mWireName, what, re_124)) { switch (what.str(2)[0]) { - case '1': d.delay = 150; break; - case '2': d.delay = 170; break; - case '4': d.delay = 210; break; - case '6': d.delay = 210; break; - default: throw; + case '1': + d.delay = 150; + break; + case '2': + d.delay = 170; + break; + case '4': + d.delay = 210; + break; + case '6': + d.delay = 210; + break; + default: + throw; } - } - else if (boost::regex_match(ewi.mWireName, what, re_L)) { + } else if (boost::regex_match(ewi.mWireName, what, re_L)) { std::string l(what[2]); - if (l == "H") d.delay = 360; - else if (l == "VB") d.delay = 300; - else if (l == "V") d.delay = 350; - else throw; - } - else if (boost::regex_match(ewi.mWireName, what, re_BYP)) { + if (l == "H") + d.delay = 360; + else if (l == "VB") + d.delay = 300; + else if (l == "V") + d.delay = 350; + else + throw; + } else if (boost::regex_match(ewi.mWireName, what, re_BYP)) { d.delay = 190; - } - else if (boost::regex_match(ewi.mWireName, what, re_BYP_B)) { - } - else if (boost::regex_match(ewi.mWireName, what, re_FAN)) { + } else if (boost::regex_match(ewi.mWireName, what, re_BYP_B)) { + } else if (boost::regex_match(ewi.mWireName, what, re_FAN)) { d.delay = 190; } wire_to_delay.emplace_back(std::move(d)); @@ -188,7 +204,9 @@ std::vector TorcInfo::construct_wire_to_delay(const std::vector TorcInfo::construct_pip_to_arc(const std::vector& wire_to_tilewire, const DDB& ddb, std::vector> &wire_to_pips_uphill, std::vector> &wire_to_pips_downhill) +std::vector TorcInfo::construct_pip_to_arc(const std::vector &wire_to_tilewire, const DDB &ddb, + std::vector> &wire_to_pips_uphill, + std::vector> &wire_to_pips_downhill) { const auto &tiles = ddb.getTiles(); @@ -201,14 +219,18 @@ std::vector TorcInfo::construct_pip_to_arc(const std::vector& wir ExtendedWireInfo ewi(ddb); for (auto i = 0u; i < wire_to_tilewire.size(); ++i) { const auto &tw = wire_to_tilewire[i]; - if (tw.isUndefined()) continue; + if (tw.isUndefined()) + continue; arcs.clear(); - const auto& tileInfo = tiles.getTileInfo(tw.getTileIndex()); + const auto &tileInfo = tiles.getTileInfo(tw.getTileIndex()); const auto tileTypeName = tiles.getTileTypeName(tileInfo.getTypeIndex()); - const bool clb = boost::starts_with(tileTypeName, "CLB"); // Disable all CLB route-throughs (i.e. LUT in->out, LUT A->AMUX, for now) + const bool clb = boost::starts_with( + tileTypeName, "CLB"); // Disable all CLB route-throughs (i.e. LUT in->out, LUT A->AMUX, for now) - const_cast(ddb).expandSegmentSinks(tw, arcs, DDB::eExpandDirectionNone, false /* inUseTied */, true /*inUseRegular */, true /* inUseIrregular */, !clb /* inUseRoutethrough */); + const_cast(ddb).expandSegmentSinks(tw, arcs, DDB::eExpandDirectionNone, false /* inUseTied */, + true /*inUseRegular */, true /* inUseIrregular */, + !clb /* inUseRoutethrough */); auto index = pip_to_arc.size(); pip_to_arc.insert(pip_to_arc.end(), arcs.begin(), arcs.end()); @@ -219,7 +241,7 @@ std::vector TorcInfo::construct_pip_to_arc(const std::vector& wir auto &pips = wire_to_pips_downhill[i]; pips.reserve(arcs.size()); const bool clk_tile = boost::starts_with(tileTypeName, "CMT") || boost::starts_with(tileTypeName, "CLK"); - for (const auto& a : arcs) { + for (const auto &a : arcs) { // Disable BUFG I0 -> O routethrough if (clk_tile) { ewi.set(a.getSourceTilewire()); @@ -240,27 +262,27 @@ std::vector TorcInfo::construct_pip_to_arc(const std::vector& wir wire_to_pips_uphill.resize(wire_to_tilewire.size()); for (auto i = 0u; i < wire_to_tilewire.size(); ++i) { const auto &tw = wire_to_tilewire[i]; - if (tw.isUndefined()) continue; + if (tw.isUndefined()) + continue; arcs.clear(); - //const_cast(ddb).expandSegmentSources(tw, arcs, DDB::eExpandDirectionNone, false /* inUseTied */, true /*inUseRegular */, true /* inUseIrregular */, false /* inUseRoutethrough */); + // const_cast(ddb).expandSegmentSources(tw, arcs, DDB::eExpandDirectionNone, false /* inUseTied */, true + // /*inUseRegular */, true /* inUseIrregular */, false /* inUseRoutethrough */); auto &pips = wire_to_pips_uphill[i]; pips.reserve(arcs.size()); - for (const auto& a : arcs) + for (const auto &a : arcs) pips.push_back(arc_to_pip.at(a)); } return pip_to_arc; } -std::vector -construct_pip_to_dst_wire(const std::vector& pip_to_arc) +std::vector construct_pip_to_dst_wire(const std::vector &pip_to_arc) { std::vector pip_to_wire; return pip_to_wire; } - // ----------------------------------------------------------------------- void IdString::initialize_arch(const BaseCtx *ctx) @@ -281,21 +303,21 @@ Arch::Arch(ArchArgs args) : args(args) log_error("Unsupported XC7 chip type.\n"); } -// package_info = nullptr; -// for (int i = 0; i < chip_info->num_packages; i++) { -// if (chip_info->packages_data[i].name.get() == args.package) { -// package_info = &(chip_info->packages_data[i]); -// break; -// } -// } -// if (package_info == nullptr) -// log_error("Unsupported package '%s'.\n", args.package.c_str()); + // package_info = nullptr; + // for (int i = 0; i < chip_info->num_packages; i++) { + // if (chip_info->packages_data[i].name.get() == args.package) { + // package_info = &(chip_info->packages_data[i]); + // break; + // } + // } + // if (package_info == nullptr) + // log_error("Unsupported package '%s'.\n", args.package.c_str()); - //bel_carry.resize(chip_info->num_bels); + // bel_carry.resize(chip_info->num_bels); bel_to_cell.resize(torc_info->num_bels); wire_to_net.resize(torc_info->num_wires); pip_to_net.resize(torc_info->num_pips); - //switches_locked.resize(chip_info->num_switches); + // switches_locked.resize(chip_info->num_switches); } // ----------------------------------------------------------------------- @@ -403,11 +425,24 @@ WireId Arch::getBelPinWire(BelId bel, IdString pin) const // For all LUT based inputs and outputs (I1-I6,O,OQ,OMUX) then change the I/O into the LUT if (pin_name[0] == 'I' || pin_name[0] == 'O') { switch (torc_info->bel_to_loc[bel.index].z) { - case 0: case 4: pin_name[0] = 'A'; break; - case 1: case 5: pin_name[0] = 'B'; break; - case 2: case 6: pin_name[0] = 'C'; break; - case 3: case 7: pin_name[0] = 'D'; break; - default: throw; + case 0: + case 4: + pin_name[0] = 'A'; + break; + case 1: + case 5: + pin_name[0] = 'B'; + break; + case 2: + case 6: + pin_name[0] = 'C'; + break; + case 3: + case 7: + pin_name[0] = 'D'; + break; + default: + throw; } } } @@ -416,36 +451,37 @@ WireId Arch::getBelPinWire(BelId bel, IdString pin) const auto &tw = site.getPinTilewire(pin_name); if (tw.isUndefined()) - log_error("no wire found for site '%s' pin '%s' \n", torc_info->bel_to_name(bel.index).c_str(), pin_name.c_str()); + log_error("no wire found for site '%s' pin '%s' \n", torc_info->bel_to_name(bel.index).c_str(), + pin_name.c_str()); ret.index = torc_info->tilewire_to_wire(tw); -// NPNR_ASSERT(bel != BelId()); -// -// int num_bel_wires = chip_info->bel_data[bel.index].num_bel_wires; -// const BelWirePOD *bel_wires = chip_info->bel_data[bel.index].bel_wires.get(); -// -// if (num_bel_wires < 7) { -// for (int i = 0; i < num_bel_wires; i++) { -// if (bel_wires[i].port == pin.index) { -// ret.index = bel_wires[i].wire_index; -// break; -// } -// } -// } else { -// int b = 0, e = num_bel_wires - 1; -// while (b <= e) { -// int i = (b + e) / 2; -// if (bel_wires[i].port == pin.index) { -// ret.index = bel_wires[i].wire_index; -// break; -// } -// if (bel_wires[i].port > pin.index) -// e = i - 1; -// else -// b = i + 1; -// } -// } + // NPNR_ASSERT(bel != BelId()); + // + // int num_bel_wires = chip_info->bel_data[bel.index].num_bel_wires; + // const BelWirePOD *bel_wires = chip_info->bel_data[bel.index].bel_wires.get(); + // + // if (num_bel_wires < 7) { + // for (int i = 0; i < num_bel_wires; i++) { + // if (bel_wires[i].port == pin.index) { + // ret.index = bel_wires[i].wire_index; + // break; + // } + // } + // } else { + // int b = 0, e = num_bel_wires - 1; + // while (b <= e) { + // int i = (b + e) / 2; + // if (bel_wires[i].port == pin.index) { + // ret.index = bel_wires[i].wire_index; + // break; + // } + // if (bel_wires[i].port > pin.index) + // e = i - 1; + // else + // b = i + 1; + // } + // } return ret; } @@ -476,8 +512,8 @@ WireId Arch::getWireByName(IdString name) const wire_by_name[id(chip_info->wire_data[i].name.get())] = i; } - //auto it = wire_by_name.find(name); - //if (it != wire_by_name.end()) + // auto it = wire_by_name.find(name); + // if (it != wire_by_name.end()) // ret.index = it->second; return ret; @@ -486,38 +522,38 @@ WireId Arch::getWireByName(IdString name) const IdString Arch::getWireType(WireId wire) const { NPNR_ASSERT(wire != WireId()); -// switch (chip_info->wire_data[wire.index].type) { -// case WireInfoPOD::WIRE_TYPE_NONE: -// return IdString(); -// case WireInfoPOD::WIRE_TYPE_GLB2LOCAL: -// return id("GLB2LOCAL"); -// case WireInfoPOD::WIRE_TYPE_GLB_NETWK: -// return id("GLB_NETWK"); -// case WireInfoPOD::WIRE_TYPE_LOCAL: -// return id("LOCAL"); -// case WireInfoPOD::WIRE_TYPE_LUTFF_IN: -// return id("LUTFF_IN"); -// case WireInfoPOD::WIRE_TYPE_LUTFF_IN_LUT: -// return id("LUTFF_IN_LUT"); -// case WireInfoPOD::WIRE_TYPE_LUTFF_LOUT: -// return id("LUTFF_LOUT"); -// case WireInfoPOD::WIRE_TYPE_LUTFF_OUT: -// return id("LUTFF_OUT"); -// case WireInfoPOD::WIRE_TYPE_LUTFF_COUT: -// return id("LUTFF_COUT"); -// case WireInfoPOD::WIRE_TYPE_LUTFF_GLOBAL: -// return id("LUTFF_GLOBAL"); -// case WireInfoPOD::WIRE_TYPE_CARRY_IN_MUX: -// return id("CARRY_IN_MUX"); -// case WireInfoPOD::WIRE_TYPE_SP4_V: -// return id("SP4_V"); -// case WireInfoPOD::WIRE_TYPE_SP4_H: -// return id("SP4_H"); -// case WireInfoPOD::WIRE_TYPE_SP12_V: -// return id("SP12_V"); -// case WireInfoPOD::WIRE_TYPE_SP12_H: -// return id("SP12_H"); -// } + // switch (chip_info->wire_data[wire.index].type) { + // case WireInfoPOD::WIRE_TYPE_NONE: + // return IdString(); + // case WireInfoPOD::WIRE_TYPE_GLB2LOCAL: + // return id("GLB2LOCAL"); + // case WireInfoPOD::WIRE_TYPE_GLB_NETWK: + // return id("GLB_NETWK"); + // case WireInfoPOD::WIRE_TYPE_LOCAL: + // return id("LOCAL"); + // case WireInfoPOD::WIRE_TYPE_LUTFF_IN: + // return id("LUTFF_IN"); + // case WireInfoPOD::WIRE_TYPE_LUTFF_IN_LUT: + // return id("LUTFF_IN_LUT"); + // case WireInfoPOD::WIRE_TYPE_LUTFF_LOUT: + // return id("LUTFF_LOUT"); + // case WireInfoPOD::WIRE_TYPE_LUTFF_OUT: + // return id("LUTFF_OUT"); + // case WireInfoPOD::WIRE_TYPE_LUTFF_COUT: + // return id("LUTFF_COUT"); + // case WireInfoPOD::WIRE_TYPE_LUTFF_GLOBAL: + // return id("LUTFF_GLOBAL"); + // case WireInfoPOD::WIRE_TYPE_CARRY_IN_MUX: + // return id("CARRY_IN_MUX"); + // case WireInfoPOD::WIRE_TYPE_SP4_V: + // return id("SP4_V"); + // case WireInfoPOD::WIRE_TYPE_SP4_H: + // return id("SP4_H"); + // case WireInfoPOD::WIRE_TYPE_SP12_V: + // return id("SP12_V"); + // case WireInfoPOD::WIRE_TYPE_SP12_H: + // return id("SP12_H"); + // } return IdString(); } @@ -566,23 +602,23 @@ IdString Arch::getPipName(PipId pip) const BelId Arch::getPackagePinBel(const std::string &pin) const { -// for (int i = 0; i < package_info->num_pins; i++) { -// if (package_info->pins[i].name.get() == pin) { -// BelId id; -// id.index = package_info->pins[i].bel_index; -// return id; -// } -// } + // for (int i = 0; i < package_info->num_pins; i++) { + // if (package_info->pins[i].name.get() == pin) { + // BelId id; + // id.index = package_info->pins[i].bel_index; + // return id; + // } + // } return BelId(); } std::string Arch::getBelPackagePin(BelId bel) const { -// for (int i = 0; i < package_info->num_pins; i++) { -// if (package_info->pins[i].bel_index == bel.index) { -// return std::string(package_info->pins[i].name.get()); -// } -// } + // for (int i = 0; i < package_info->num_pins; i++) { + // if (package_info->pins[i].bel_index == bel.index) { + // return std::string(package_info->pins[i].name.get()); + // } + // } return ""; } @@ -719,16 +755,18 @@ std::vector Arch::getGroupGroups(GroupId group) const // ----------------------------------------------------------------------- -bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const -{ - return false; -} +bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const { return false; } // ----------------------------------------------------------------------- bool Arch::place() { return placer1(getCtx(), Placer1Cfg(getCtx())); } -bool Arch::route() { getCtx()->debug = true; getCtx()->verbose = true; return router1(getCtx(), Router1Cfg(getCtx())); } +bool Arch::route() +{ + getCtx()->debug = true; + getCtx()->verbose = true; + return router1(getCtx(), Router1Cfg(getCtx())); +} // ----------------------------------------------------------------------- @@ -909,13 +947,10 @@ std::vector Arch::getDecalGraphics(DecalId decal) const bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const { - if (cell->type == id_SLICE_LUT6) - { + if (cell->type == id_SLICE_LUT6) { if (fromPort.index >= id_I1.index && fromPort.index <= id_I6.index) return toPort == id_O || toPort == id_OQ; - } - else if (cell->type == id_BUFGCTRL) - { + } else if (cell->type == id_BUFGCTRL) { return true; } return false; @@ -946,15 +981,13 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, Id return TMG_COMB_INPUT; } // TODO - //if (port == id_OMUX) - } - else if (cell->type == id_IOB33) { + // if (port == id_OMUX) + } else if (cell->type == id_IOB33) { if (port == id_I) return TMG_STARTPOINT; else if (port == id_O) return TMG_ENDPOINT; - } - else if (cell->type == id_BUFGCTRL) { + } else if (cell->type == id_BUFGCTRL) { if (port == id_O) return TMG_COMB_OUTPUT; return TMG_COMB_INPUT; diff --git a/xc7/arch.h b/xc7/arch.h index a179139e..b5721552 100644 --- a/xc7/arch.h +++ b/xc7/arch.h @@ -27,8 +27,8 @@ using namespace torc::architecture; using namespace torc::architecture::xilinx; namespace std { - template <> struct hash - { +template <> struct hash +{ size_t operator()(const Segments::SegmentReference &s) const { size_t seed = 0; @@ -36,24 +36,22 @@ namespace std { boost::hash_combine(seed, hash()(s.getAnchorTileIndex())); return seed; } - }; - template <> struct equal_to - { +}; +template <> struct equal_to +{ bool operator()(const Segments::SegmentReference &lhs, const Segments::SegmentReference &rhs) const { - return lhs.getAnchorTileIndex() == rhs.getAnchorTileIndex() && lhs.getCompactSegmentIndex() == rhs.getCompactSegmentIndex(); + return lhs.getAnchorTileIndex() == rhs.getAnchorTileIndex() && + lhs.getCompactSegmentIndex() == rhs.getCompactSegmentIndex(); } - }; - template <> struct hash - { - size_t operator()(const Tilewire& t) const - { - return hash_value(t); - } - }; +}; +template <> struct hash +{ + size_t operator()(const Tilewire &t) const { return hash_value(t); } +}; - template <> struct hash - { +template <> struct hash +{ size_t operator()(const Arc &a) const { size_t seed = 0; @@ -61,8 +59,8 @@ namespace std { boost::hash_combine(seed, hash_value(a.getSinkTilewire())); return seed; } - }; -} +}; +} // namespace std NEXTPNR_NAMESPACE_BEGIN @@ -270,21 +268,23 @@ NPNR_PACKED_STRUCT(struct ChipInfoPOD { RelPtr cell_timing; }); - struct Arch; -struct TorcInfo { +struct TorcInfo +{ TorcInfo(Arch *ctx, const std::string &inDeviceName, const std::string &inPackageName); std::unique_ptr ddb; const Sites &sites; const Tiles &tiles; const Segments &segments; - const TileInfo& bel_to_tile_info(int32_t index) const { + const TileInfo &bel_to_tile_info(int32_t index) const + { auto si = bel_to_site_index[index]; const auto &site = sites.getSite(si); return tiles.getTileInfo(site.getTileIndex()); } - const std::string& bel_to_name(int32_t index) const { + const std::string &bel_to_name(int32_t index) const + { auto si = bel_to_site_index[index]; return sites.getSite(si).getName(); } @@ -309,8 +309,8 @@ struct TorcInfo { const int num_bels; const std::vector site_index_to_type; const std::vector bel_to_loc; - std::unordered_map segment_to_wire; - std::unordered_map trivial_to_wire; + std::unordered_map segment_to_wire; + std::unordered_map trivial_to_wire; const std::vector wire_to_tilewire; const int num_wires; const std::vector wire_to_delay; @@ -320,17 +320,23 @@ struct TorcInfo { const int num_pips; std::vector pip_to_dst_wire; -private: + private: static std::vector construct_bel_to_site_index(Arch *ctx, const Sites &sites); static std::vector construct_site_index_to_type(Arch *ctx, const Sites &sites); - static std::vector construct_bel_to_loc(const Sites &sites, const Tiles &tiles, const int num_bels, const std::vector &site_index_to_type); - static std::vector construct_wire_to_tilewire(const Segments &segments, const Tiles &tiles, std::unordered_map& segment_to_wire, std::unordered_map& trivial_to_wire); - static std::vector construct_wire_to_delay(const std::vector& wire_to_tilewire, const DDB &ddb); - static std::vector construct_pip_to_arc(const std::vector& wire_to_tilewire, const DDB& ddb, std::vector> &wire_to_pips_uphill, std::vector> &wire_to_pips_downhill); + static std::vector construct_bel_to_loc(const Sites &sites, const Tiles &tiles, const int num_bels, + const std::vector &site_index_to_type); + static std::vector + construct_wire_to_tilewire(const Segments &segments, const Tiles &tiles, + std::unordered_map &segment_to_wire, + std::unordered_map &trivial_to_wire); + static std::vector construct_wire_to_delay(const std::vector &wire_to_tilewire, + const DDB &ddb); + static std::vector construct_pip_to_arc(const std::vector &wire_to_tilewire, const DDB &ddb, + std::vector> &wire_to_pips_uphill, + std::vector> &wire_to_pips_downhill); }; extern std::unique_ptr torc_info; - /************************ End of chipdb section. ************************/ struct BelIterator @@ -486,11 +492,11 @@ struct Arch : BaseCtx mutable std::unordered_map pip_by_name; mutable std::unordered_map bel_by_loc; - //std::vector bel_carry; + // std::vector bel_carry; std::vector bel_to_cell; std::vector wire_to_net; std::vector pip_to_net; - //std::vector switches_locked; + // std::vector switches_locked; ArchArgs args; Arch(ArchArgs args); @@ -521,11 +527,24 @@ struct Arch : BaseCtx name.reserve(name.size() + 2); name += "_"; switch (torc_info->bel_to_loc[bel.index].z) { - case 0: case 4: name += 'A'; break; - case 1: case 5: name += 'B'; break; - case 2: case 6: name += 'C'; break; - case 3: case 7: name += 'D'; break; - default: throw; + case 0: + case 4: + name += 'A'; + break; + case 1: + case 5: + name += 'B'; + break; + case 2: + case 6: + name += 'C'; + break; + case 3: + case 7: + name += 'D'; + break; + default: + throw; } } return id(name); @@ -539,7 +558,7 @@ struct Arch : BaseCtx NPNR_ASSERT(bel_to_cell[bel.index] == nullptr); bel_to_cell[bel.index] = cell; - //bel_carry[bel.index] = (cell->type == id_ICESTORM_LC && cell->lcInfo.carryEnable); + // bel_carry[bel.index] = (cell->type == id_ICESTORM_LC && cell->lcInfo.carryEnable); cell->bel = bel; cell->belStrength = strength; refreshUiBel(bel); @@ -552,7 +571,7 @@ struct Arch : BaseCtx bel_to_cell[bel.index]->bel = BelId(); bel_to_cell[bel.index]->belStrength = STRENGTH_NONE; bel_to_cell[bel.index] = nullptr; - //bel_carry[bel.index] = false; + // bel_carry[bel.index] = false; refreshUiBel(bel); } @@ -582,10 +601,7 @@ struct Arch : BaseCtx return range; } - Loc getBelLocation(BelId bel) const - { - return torc_info->bel_to_loc[bel.index]; - } + Loc getBelLocation(BelId bel) const { return torc_info->bel_to_loc[bel.index]; } BelId getBelByLocation(Loc loc) const; BelRange getBelsByTile(int x, int y) const; @@ -639,7 +655,7 @@ struct Arch : BaseCtx auto pip = it->second.pip; if (pip != PipId()) { pip_to_net[pip.index] = nullptr; - //switches_locked[chip_info->pip_data[pip.index].switch_index] = nullptr; + // switches_locked[chip_info->pip_data[pip.index].switch_index] = nullptr; } net_wires.erase(it); @@ -665,17 +681,14 @@ struct Arch : BaseCtx return wire_to_net[wire.index]; } - DelayInfo getWireDelay(WireId wire) const - { - return torc_info->wire_to_delay[wire.index]; - } + DelayInfo getWireDelay(WireId wire) const { return torc_info->wire_to_delay[wire.index]; } BelPinRange getWireBelPins(WireId wire) const { BelPinRange range; - //NPNR_ASSERT(wire != WireId()); - //range.b.ptr = chip_info->wire_data[wire.index].bel_pins.get(); - //range.e.ptr = range.b.ptr + chip_info->wire_data[wire.index].num_bel_pins; + // NPNR_ASSERT(wire != WireId()); + // range.b.ptr = chip_info->wire_data[wire.index].bel_pins.get(); + // range.e.ptr = range.b.ptr + chip_info->wire_data[wire.index].num_bel_pins; throw; return range; } @@ -696,10 +709,10 @@ struct Arch : BaseCtx { NPNR_ASSERT(pip != PipId()); NPNR_ASSERT(pip_to_net[pip.index] == nullptr); - //NPNR_ASSERT(switches_locked[chip_info->pip_data[pip.index].switch_index] == nullptr); + // NPNR_ASSERT(switches_locked[chip_info->pip_data[pip.index].switch_index] == nullptr); pip_to_net[pip.index] = net; - //switches_locked[chip_info->pip_data[pip.index].switch_index] = net; + // switches_locked[chip_info->pip_data[pip.index].switch_index] = net; WireId dst = getPipDstWire(pip); NPNR_ASSERT(wire_to_net[dst.index] == nullptr); @@ -714,7 +727,7 @@ struct Arch : BaseCtx { NPNR_ASSERT(pip != PipId()); NPNR_ASSERT(pip_to_net[pip.index] != nullptr); - //NPNR_ASSERT(switches_locked[chip_info->pip_data[pip.index].switch_index] != nullptr); + // NPNR_ASSERT(switches_locked[chip_info->pip_data[pip.index].switch_index] != nullptr); WireId dst = getPipDstWire(pip); NPNR_ASSERT(wire_to_net[dst.index] != nullptr); @@ -722,7 +735,7 @@ struct Arch : BaseCtx pip_to_net[pip.index]->wires.erase(dst); pip_to_net[pip.index] = nullptr; - //switches_locked[chip_info->pip_data[pip.index].switch_index] = nullptr; + // switches_locked[chip_info->pip_data[pip.index].switch_index] = nullptr; refreshUiPip(pip); refreshUiWire(dst); } @@ -730,25 +743,25 @@ struct Arch : BaseCtx bool checkPipAvail(PipId pip) const { NPNR_ASSERT(pip != PipId()); - //auto &pi = chip_info->pip_data[pip.index]; - //auto &si = chip_info->bits_info->switches[pi.switch_index]; + // auto &pi = chip_info->pip_data[pip.index]; + // auto &si = chip_info->bits_info->switches[pi.switch_index]; - //if (switches_locked[pi.switch_index] != nullptr) + // if (switches_locked[pi.switch_index] != nullptr) // return false; - //if (pi.flags & PipInfoPOD::FLAG_ROUTETHRU) { + // if (pi.flags & PipInfoPOD::FLAG_ROUTETHRU) { // NPNR_ASSERT(si.bel >= 0); // if (bel_to_cell[si.bel] != nullptr) // return false; //} - //if (pi.flags & PipInfoPOD::FLAG_NOCARRY) { + // if (pi.flags & PipInfoPOD::FLAG_NOCARRY) { // NPNR_ASSERT(si.bel >= 0); // if (bel_carry[si.bel]) // return false; //} - //return true; + // return true; return pip_to_net[pip.index] == nullptr; } @@ -761,7 +774,7 @@ struct Arch : BaseCtx NetInfo *getConflictingPipNet(PipId pip) const { NPNR_ASSERT(pip != PipId()); - //return switches_locked[chip_info->pip_data[pip.index].switch_index]; + // return switches_locked[chip_info->pip_data[pip.index].switch_index]; return pip_to_net[pip.index]; } @@ -780,7 +793,7 @@ struct Arch : BaseCtx const auto &tile_info = torc_info->tiles.getTileInfo(tw.getTileIndex()); Loc loc; - loc.x = tile_info.getCol(); + loc.x = tile_info.getCol(); loc.y = tile_info.getRow(); loc.z = 0; return loc; @@ -816,9 +829,9 @@ struct Arch : BaseCtx { DelayInfo delay; NPNR_ASSERT(pip != PipId()); - //if (fast_part) + // if (fast_part) // delay.delay = chip_info->pip_data[pip.index].fast_delay; - //else + // else // delay.delay = chip_info->pip_data[pip.index].slow_delay; return delay; } @@ -915,7 +928,7 @@ struct Arch : BaseCtx bool isBelLocationValid(BelId bel) const; // Helper function for above - bool logicCellsCompatible(const CellInfo** it, const size_t size) const; + bool logicCellsCompatible(const CellInfo **it, const size_t size) const; // ------------------------------------------------- // Assign architecure-specific arguments to nets and cells, which must be @@ -939,6 +952,6 @@ struct Arch : BaseCtx float placer_constraintWeight = 10; }; -//void ice40DelayFuzzerMain(Context *ctx); +// void ice40DelayFuzzerMain(Context *ctx); NEXTPNR_NAMESPACE_END diff --git a/xc7/arch_place.cc b/xc7/arch_place.cc index 463e8312..fd09006e 100644 --- a/xc7/arch_place.cc +++ b/xc7/arch_place.cc @@ -27,38 +27,38 @@ NEXTPNR_NAMESPACE_BEGIN -bool Arch::logicCellsCompatible(const CellInfo** it, const size_t size) const +bool Arch::logicCellsCompatible(const CellInfo **it, const size_t size) const { -// bool dffs_exist = false, dffs_neg = false; -// const NetInfo *cen = nullptr, *clk = nullptr, *sr = nullptr; -// -// for (auto cell : boost::make_iterator_range(it, it+size)) { -// NPNR_ASSERT(cell->belType == id_ICESTORM_LC); -// if (cell->lcInfo.dffEnable) { -// if (!dffs_exist) { -// dffs_exist = true; -// cen = cell->lcInfo.cen; -// clk = cell->lcInfo.clk; -// sr = cell->lcInfo.sr; -// -// if (cell->lcInfo.negClk) { -// dffs_neg = true; -// } -// } else { -// if (cen != cell->lcInfo.cen) -// return false; -// if (clk != cell->lcInfo.clk) -// return false; -// if (sr != cell->lcInfo.sr) -// return false; -// if (dffs_neg != cell->lcInfo.negClk) -// return false; -// } -// } -// locals_count += cell->lcInfo.inputCount; -// } -// -// return locals_count <= 32; + // bool dffs_exist = false, dffs_neg = false; + // const NetInfo *cen = nullptr, *clk = nullptr, *sr = nullptr; + // + // for (auto cell : boost::make_iterator_range(it, it+size)) { + // NPNR_ASSERT(cell->belType == id_ICESTORM_LC); + // if (cell->lcInfo.dffEnable) { + // if (!dffs_exist) { + // dffs_exist = true; + // cen = cell->lcInfo.cen; + // clk = cell->lcInfo.clk; + // sr = cell->lcInfo.sr; + // + // if (cell->lcInfo.negClk) { + // dffs_neg = true; + // } + // } else { + // if (cen != cell->lcInfo.cen) + // return false; + // if (clk != cell->lcInfo.clk) + // return false; + // if (sr != cell->lcInfo.sr) + // return false; + // if (dffs_neg != cell->lcInfo.negClk) + // return false; + // } + // } + // locals_count += cell->lcInfo.inputCount; + // } + // + // return locals_count <= 32; return true; } @@ -85,70 +85,70 @@ bool Arch::isBelLocationValid(BelId bel) const bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const { -// if (cell->type == id_ICESTORM_LC) { -// NPNR_ASSERT(getBelType(bel) == id_ICESTORM_LC); -// -// std::array bel_cells; -// size_t num_cells = 0; -// -// Loc bel_loc = getBelLocation(bel); -// for (auto bel_other : getBelsByTile(bel_loc.x, bel_loc.y)) { -// CellInfo *ci_other = getBoundBelCell(bel_other); -// if (ci_other != nullptr && bel_other != bel) -// bel_cells[num_cells++] = ci_other; -// } -// -// bel_cells[num_cells++] = cell; -// return logicCellsCompatible(bel_cells.data(), num_cells); -// } else if (cell->type == id_SB_IO) { -// // Do not allow placement of input SB_IOs on blocks where there a PLL is outputting to. -// -// // Find shared PLL by looking for driving bel siblings from D_IN_0 -// // that are a PLL clock output. -// auto wire = getBelPinWire(bel, id_D_IN_0); -// IdString pll_bel_pin; -// BelId pll_bel; -// for (auto pin : getWireBelPins(wire)) { -// if (pin.pin == id_PLLOUT_A || pin.pin == id_PLLOUT_B) { -// pll_bel = pin.bel; -// pll_bel_pin = pin.pin; -// break; -// } -// } -// // Is there a PLL that shares this IO buffer? -// if (pll_bel.index != -1) { -// auto pll_cell = getBoundBelCell(pll_bel); -// // Is a PLL placed in this PLL bel? -// if (pll_cell != nullptr) { -// // Is the shared port driving a net? -// auto pi = pll_cell->ports[pll_bel_pin]; -// if (pi.net != nullptr) { -// // Are we perhaps a PAD INPUT Bel that can be placed here? -// if (pll_cell->attrs[id("BEL_PAD_INPUT")] == getBelName(bel).str(this)) { -// return true; -// } -// return false; -// } -// } -// } -// return getBelPackagePin(bel) != ""; -// } else if (cell->type == id_SB_GB) { -// NPNR_ASSERT(cell->ports.at(id_GLOBAL_BUFFER_OUTPUT).net != nullptr); -// const NetInfo *net = cell->ports.at(id_GLOBAL_BUFFER_OUTPUT).net; -// IdString glb_net = getWireName(getBelPinWire(bel, id_GLOBAL_BUFFER_OUTPUT)); -// int glb_id = std::stoi(std::string("") + glb_net.str(this).back()); -// if (net->is_reset && net->is_enable) -// return false; -// else if (net->is_reset) -// return (glb_id % 2) == 0; -// else if (net->is_enable) -// return (glb_id % 2) == 1; -// else -// return true; -// } else { -// // TODO: IO cell clock checks - return true; -// } + // if (cell->type == id_ICESTORM_LC) { + // NPNR_ASSERT(getBelType(bel) == id_ICESTORM_LC); + // + // std::array bel_cells; + // size_t num_cells = 0; + // + // Loc bel_loc = getBelLocation(bel); + // for (auto bel_other : getBelsByTile(bel_loc.x, bel_loc.y)) { + // CellInfo *ci_other = getBoundBelCell(bel_other); + // if (ci_other != nullptr && bel_other != bel) + // bel_cells[num_cells++] = ci_other; + // } + // + // bel_cells[num_cells++] = cell; + // return logicCellsCompatible(bel_cells.data(), num_cells); + // } else if (cell->type == id_SB_IO) { + // // Do not allow placement of input SB_IOs on blocks where there a PLL is outputting to. + // + // // Find shared PLL by looking for driving bel siblings from D_IN_0 + // // that are a PLL clock output. + // auto wire = getBelPinWire(bel, id_D_IN_0); + // IdString pll_bel_pin; + // BelId pll_bel; + // for (auto pin : getWireBelPins(wire)) { + // if (pin.pin == id_PLLOUT_A || pin.pin == id_PLLOUT_B) { + // pll_bel = pin.bel; + // pll_bel_pin = pin.pin; + // break; + // } + // } + // // Is there a PLL that shares this IO buffer? + // if (pll_bel.index != -1) { + // auto pll_cell = getBoundBelCell(pll_bel); + // // Is a PLL placed in this PLL bel? + // if (pll_cell != nullptr) { + // // Is the shared port driving a net? + // auto pi = pll_cell->ports[pll_bel_pin]; + // if (pi.net != nullptr) { + // // Are we perhaps a PAD INPUT Bel that can be placed here? + // if (pll_cell->attrs[id("BEL_PAD_INPUT")] == getBelName(bel).str(this)) { + // return true; + // } + // return false; + // } + // } + // } + // return getBelPackagePin(bel) != ""; + // } else if (cell->type == id_SB_GB) { + // NPNR_ASSERT(cell->ports.at(id_GLOBAL_BUFFER_OUTPUT).net != nullptr); + // const NetInfo *net = cell->ports.at(id_GLOBAL_BUFFER_OUTPUT).net; + // IdString glb_net = getWireName(getBelPinWire(bel, id_GLOBAL_BUFFER_OUTPUT)); + // int glb_id = std::stoi(std::string("") + glb_net.str(this).back()); + // if (net->is_reset && net->is_enable) + // return false; + // else if (net->is_reset) + // return (glb_id % 2) == 0; + // else if (net->is_enable) + // return (glb_id % 2) == 1; + // else + // return true; + // } else { + // // TODO: IO cell clock checks + return true; + // } } NEXTPNR_NAMESPACE_END diff --git a/xc7/blinky.pcf b/xc7/blinky.pcf index 141dfcc8..98bd5071 100644 --- a/xc7/blinky.pcf +++ b/xc7/blinky.pcf @@ -1,6 +1,6 @@ -set_io led1 99 -set_io led2 98 -set_io led3 97 -set_io led4 96 -set_io led5 95 -set_io clki 21 +COMP "led1" LOCATE = SITE "M14" LEVEL 1; +COMP "led2" LOCATE = SITE "M15" LEVEL 1; +COMP "led3" LOCATE = SITE "G14" LEVEL 1; +COMP "led4" LOCATE = SITE "D18" LEVEL 1; +COMP "clki" LOCATE = SITE "L16" LEVEL 1; + diff --git a/xc7/cells.cc b/xc7/cells.cc index 01109b96..e1588516 100644 --- a/xc7/cells.cc +++ b/xc7/cells.cc @@ -76,180 +76,180 @@ std::unique_ptr create_xc7_cell(Context *ctx, IdString type, std::stri new_cell->params[ctx->id("NEG_TRIGGER")] = "0"; new_cell->params[ctx->id("IOSTANDARD")] = "SB_LVCMOS"; -// add_port(ctx, new_cell.get(), "PACKAGE_PIN", PORT_INOUT); -// -// add_port(ctx, new_cell.get(), "LATCH_INPUT_VALUE", PORT_IN); -// add_port(ctx, new_cell.get(), "CLOCK_ENABLE", PORT_IN); -// add_port(ctx, new_cell.get(), "INPUT_CLK", PORT_IN); -// add_port(ctx, new_cell.get(), "OUTPUT_CLK", PORT_IN); -// -// add_port(ctx, new_cell.get(), "OUTPUT_ENABLE", PORT_IN); -// add_port(ctx, new_cell.get(), "D_OUT_0", PORT_IN); -// add_port(ctx, new_cell.get(), "D_OUT_1", PORT_IN); -// -// add_port(ctx, new_cell.get(), "D_IN_0", PORT_OUT); -// add_port(ctx, new_cell.get(), "D_IN_1", PORT_OUT); + // add_port(ctx, new_cell.get(), "PACKAGE_PIN", PORT_INOUT); + // + // add_port(ctx, new_cell.get(), "LATCH_INPUT_VALUE", PORT_IN); + // add_port(ctx, new_cell.get(), "CLOCK_ENABLE", PORT_IN); + // add_port(ctx, new_cell.get(), "INPUT_CLK", PORT_IN); + // add_port(ctx, new_cell.get(), "OUTPUT_CLK", PORT_IN); + // + // add_port(ctx, new_cell.get(), "OUTPUT_ENABLE", PORT_IN); + // add_port(ctx, new_cell.get(), "D_OUT_0", PORT_IN); + // add_port(ctx, new_cell.get(), "D_OUT_1", PORT_IN); + // + // add_port(ctx, new_cell.get(), "D_IN_0", PORT_OUT); + // add_port(ctx, new_cell.get(), "D_IN_1", PORT_OUT); add_port(ctx, new_cell.get(), "I", PORT_OUT); add_port(ctx, new_cell.get(), "O", PORT_IN); -// } else if (type == ctx->id("ICESTORM_RAM")) { -// new_cell->params[ctx->id("NEG_CLK_W")] = "0"; -// new_cell->params[ctx->id("NEG_CLK_R")] = "0"; -// new_cell->params[ctx->id("WRITE_MODE")] = "0"; -// new_cell->params[ctx->id("READ_MODE")] = "0"; -// -// add_port(ctx, new_cell.get(), "RCLK", PORT_IN); -// add_port(ctx, new_cell.get(), "RCLKE", PORT_IN); -// add_port(ctx, new_cell.get(), "RE", PORT_IN); -// -// add_port(ctx, new_cell.get(), "WCLK", PORT_IN); -// add_port(ctx, new_cell.get(), "WCLKE", PORT_IN); -// add_port(ctx, new_cell.get(), "WE", PORT_IN); -// -// for (int i = 0; i < 16; i++) { -// add_port(ctx, new_cell.get(), "WDATA_" + std::to_string(i), PORT_IN); -// add_port(ctx, new_cell.get(), "MASK_" + std::to_string(i), PORT_IN); -// add_port(ctx, new_cell.get(), "RDATA_" + std::to_string(i), PORT_OUT); -// } -// -// for (int i = 0; i < 11; i++) { -// add_port(ctx, new_cell.get(), "RADDR_" + std::to_string(i), PORT_IN); -// add_port(ctx, new_cell.get(), "WADDR_" + std::to_string(i), PORT_IN); -// } -// } else if (type == ctx->id("ICESTORM_LFOSC")) { -// add_port(ctx, new_cell.get(), "CLKLFEN", PORT_IN); -// add_port(ctx, new_cell.get(), "CLKLFPU", PORT_IN); -// add_port(ctx, new_cell.get(), "CLKLF", PORT_OUT); -// add_port(ctx, new_cell.get(), "CLKLF_FABRIC", PORT_OUT); -// } else if (type == ctx->id("ICESTORM_HFOSC")) { -// new_cell->params[ctx->id("CLKHF_DIV")] = "0b00"; -// new_cell->params[ctx->id("TRIM_EN")] = "0b0"; -// -// add_port(ctx, new_cell.get(), "CLKHFEN", PORT_IN); -// add_port(ctx, new_cell.get(), "CLKHFPU", PORT_IN); -// add_port(ctx, new_cell.get(), "CLKHF", PORT_OUT); -// add_port(ctx, new_cell.get(), "CLKHF_FABRIC", PORT_OUT); -// for (int i = 0; i < 10; i++) -// add_port(ctx, new_cell.get(), "TRIM" + std::to_string(i), PORT_IN); + // } else if (type == ctx->id("ICESTORM_RAM")) { + // new_cell->params[ctx->id("NEG_CLK_W")] = "0"; + // new_cell->params[ctx->id("NEG_CLK_R")] = "0"; + // new_cell->params[ctx->id("WRITE_MODE")] = "0"; + // new_cell->params[ctx->id("READ_MODE")] = "0"; + // + // add_port(ctx, new_cell.get(), "RCLK", PORT_IN); + // add_port(ctx, new_cell.get(), "RCLKE", PORT_IN); + // add_port(ctx, new_cell.get(), "RE", PORT_IN); + // + // add_port(ctx, new_cell.get(), "WCLK", PORT_IN); + // add_port(ctx, new_cell.get(), "WCLKE", PORT_IN); + // add_port(ctx, new_cell.get(), "WE", PORT_IN); + // + // for (int i = 0; i < 16; i++) { + // add_port(ctx, new_cell.get(), "WDATA_" + std::to_string(i), PORT_IN); + // add_port(ctx, new_cell.get(), "MASK_" + std::to_string(i), PORT_IN); + // add_port(ctx, new_cell.get(), "RDATA_" + std::to_string(i), PORT_OUT); + // } + // + // for (int i = 0; i < 11; i++) { + // add_port(ctx, new_cell.get(), "RADDR_" + std::to_string(i), PORT_IN); + // add_port(ctx, new_cell.get(), "WADDR_" + std::to_string(i), PORT_IN); + // } + // } else if (type == ctx->id("ICESTORM_LFOSC")) { + // add_port(ctx, new_cell.get(), "CLKLFEN", PORT_IN); + // add_port(ctx, new_cell.get(), "CLKLFPU", PORT_IN); + // add_port(ctx, new_cell.get(), "CLKLF", PORT_OUT); + // add_port(ctx, new_cell.get(), "CLKLF_FABRIC", PORT_OUT); + // } else if (type == ctx->id("ICESTORM_HFOSC")) { + // new_cell->params[ctx->id("CLKHF_DIV")] = "0b00"; + // new_cell->params[ctx->id("TRIM_EN")] = "0b0"; + // + // add_port(ctx, new_cell.get(), "CLKHFEN", PORT_IN); + // add_port(ctx, new_cell.get(), "CLKHFPU", PORT_IN); + // add_port(ctx, new_cell.get(), "CLKHF", PORT_OUT); + // add_port(ctx, new_cell.get(), "CLKHF_FABRIC", PORT_OUT); + // for (int i = 0; i < 10; i++) + // add_port(ctx, new_cell.get(), "TRIM" + std::to_string(i), PORT_IN); } else if (type == id_BUFGCTRL) { add_port(ctx, new_cell.get(), "I0", PORT_IN); add_port(ctx, new_cell.get(), "O", PORT_OUT); -// } else if (type == ctx->id("ICESTORM_SPRAM")) { -// add_port(ctx, new_cell.get(), "WREN", PORT_IN); -// add_port(ctx, new_cell.get(), "CHIPSELECT", PORT_IN); -// add_port(ctx, new_cell.get(), "CLOCK", PORT_IN); -// add_port(ctx, new_cell.get(), "STANDBY", PORT_IN); -// add_port(ctx, new_cell.get(), "SLEEP", PORT_IN); -// add_port(ctx, new_cell.get(), "POWEROFF", PORT_IN); -// -// for (int i = 0; i < 16; i++) { -// add_port(ctx, new_cell.get(), "DATAIN_" + std::to_string(i), PORT_IN); -// add_port(ctx, new_cell.get(), "DATAOUT_" + std::to_string(i), PORT_OUT); -// } -// for (int i = 0; i < 14; i++) { -// add_port(ctx, new_cell.get(), "ADDRESS_" + std::to_string(i), PORT_IN); -// } -// for (int i = 0; i < 4; i++) { -// add_port(ctx, new_cell.get(), "MASKWREN_" + std::to_string(i), PORT_IN); -// } -// } else if (type == ctx->id("ICESTORM_DSP")) { -// new_cell->params[ctx->id("NEG_TRIGGER")] = "0"; -// -// new_cell->params[ctx->id("C_REG")] = "0"; -// new_cell->params[ctx->id("A_REG")] = "0"; -// new_cell->params[ctx->id("B_REG")] = "0"; -// new_cell->params[ctx->id("D_REG")] = "0"; -// new_cell->params[ctx->id("TOP_8x8_MULT_REG")] = "0"; -// new_cell->params[ctx->id("BOT_8x8_MULT_REG")] = "0"; -// new_cell->params[ctx->id("PIPELINE_16x16_MULT_REG1")] = "0"; -// new_cell->params[ctx->id("PIPELINE_16x16_MULT_REG2")] = "0"; -// -// new_cell->params[ctx->id("TOPOUTPUT_SELECT")] = "0"; -// new_cell->params[ctx->id("TOPADDSUB_LOWERINPUT")] = "0"; -// new_cell->params[ctx->id("TOPADDSUB_UPPERINPUT")] = "0"; -// new_cell->params[ctx->id("TOPADDSUB_CARRYSELECT")] = "0"; -// -// new_cell->params[ctx->id("BOTOUTPUT_SELECT")] = "0"; -// new_cell->params[ctx->id("BOTADDSUB_LOWERINPUT")] = "0"; -// new_cell->params[ctx->id("BOTADDSUB_UPPERINPUT")] = "0"; -// new_cell->params[ctx->id("BOTADDSUB_CARRYSELECT")] = "0"; -// -// new_cell->params[ctx->id("MODE_8x8")] = "0"; -// new_cell->params[ctx->id("A_SIGNED")] = "0"; -// new_cell->params[ctx->id("B_SIGNED")] = "0"; -// -// add_port(ctx, new_cell.get(), "CLK", PORT_IN); -// add_port(ctx, new_cell.get(), "CE", PORT_IN); -// for (int i = 0; i < 16; i++) { -// add_port(ctx, new_cell.get(), "C_" + std::to_string(i), PORT_IN); -// add_port(ctx, new_cell.get(), "A_" + std::to_string(i), PORT_IN); -// add_port(ctx, new_cell.get(), "B_" + std::to_string(i), PORT_IN); -// add_port(ctx, new_cell.get(), "D_" + std::to_string(i), PORT_IN); -// } -// add_port(ctx, new_cell.get(), "AHOLD", PORT_IN); -// add_port(ctx, new_cell.get(), "BHOLD", PORT_IN); -// add_port(ctx, new_cell.get(), "CHOLD", PORT_IN); -// add_port(ctx, new_cell.get(), "DHOLD", PORT_IN); -// -// add_port(ctx, new_cell.get(), "IRSTTOP", PORT_IN); -// add_port(ctx, new_cell.get(), "IRSTBOT", PORT_IN); -// add_port(ctx, new_cell.get(), "ORSTTOP", PORT_IN); -// add_port(ctx, new_cell.get(), "ORSTBOT", PORT_IN); -// -// add_port(ctx, new_cell.get(), "OLOADTOP", PORT_IN); -// add_port(ctx, new_cell.get(), "OLOADBOT", PORT_IN); -// -// add_port(ctx, new_cell.get(), "ADDSUBTOP", PORT_IN); -// add_port(ctx, new_cell.get(), "ADDSUBBOT", PORT_IN); -// -// add_port(ctx, new_cell.get(), "OHOLDTOP", PORT_IN); -// add_port(ctx, new_cell.get(), "OHOLDBOT", PORT_IN); -// -// add_port(ctx, new_cell.get(), "CI", PORT_IN); -// add_port(ctx, new_cell.get(), "ACCUMCI", PORT_IN); -// add_port(ctx, new_cell.get(), "SIGNEXTIN", PORT_IN); -// -// for (int i = 0; i < 32; i++) { -// add_port(ctx, new_cell.get(), "O_" + std::to_string(i), PORT_OUT); -// } -// -// add_port(ctx, new_cell.get(), "CO", PORT_OUT); -// add_port(ctx, new_cell.get(), "ACCUMCO", PORT_OUT); -// add_port(ctx, new_cell.get(), "SIGNEXTOUT", PORT_OUT); -// -// } else if (type == ctx->id("ICESTORM_PLL")) { -// new_cell->params[ctx->id("DELAY_ADJMODE_FB")] = "0"; -// new_cell->params[ctx->id("DELAY_ADJMODE_REL")] = "0"; -// -// new_cell->params[ctx->id("DIVF")] = "0"; -// new_cell->params[ctx->id("DIVQ")] = "0"; -// new_cell->params[ctx->id("DIVR")] = "0"; -// -// new_cell->params[ctx->id("FDA_FEEDBACK")] = "0"; -// new_cell->params[ctx->id("FDA_RELATIVE")] = "0"; -// new_cell->params[ctx->id("FEEDBACK_PATH")] = "0"; -// new_cell->params[ctx->id("FILTER_RANGE")] = "0"; -// -// new_cell->params[ctx->id("PLLOUT_SELECT_A")] = "0"; -// new_cell->params[ctx->id("PLLOUT_SELECT_B")] = "0"; -// -// new_cell->params[ctx->id("PLLTYPE")] = "0"; -// new_cell->params[ctx->id("SHIFTREG_DIVMODE")] = "0"; -// new_cell->params[ctx->id("TEST_MODE")] = "0"; -// -// add_port(ctx, new_cell.get(), "BYPASS", PORT_IN); -// add_port(ctx, new_cell.get(), "DYNAMICDELAY", PORT_IN); -// add_port(ctx, new_cell.get(), "EXTFEEDBACK", PORT_IN); -// add_port(ctx, new_cell.get(), "LATCHINPUTVALUE", PORT_IN); -// add_port(ctx, new_cell.get(), "REFERENCECLK", PORT_IN); -// add_port(ctx, new_cell.get(), "RESETB", PORT_IN); -// -// add_port(ctx, new_cell.get(), "SCLK", PORT_IN); -// add_port(ctx, new_cell.get(), "SDI", PORT_IN); -// add_port(ctx, new_cell.get(), "SDI", PORT_OUT); -// -// add_port(ctx, new_cell.get(), "LOCK", PORT_OUT); -// add_port(ctx, new_cell.get(), "PLLOUT_A", PORT_OUT); -// add_port(ctx, new_cell.get(), "PLLOUT_B", PORT_OUT); + // } else if (type == ctx->id("ICESTORM_SPRAM")) { + // add_port(ctx, new_cell.get(), "WREN", PORT_IN); + // add_port(ctx, new_cell.get(), "CHIPSELECT", PORT_IN); + // add_port(ctx, new_cell.get(), "CLOCK", PORT_IN); + // add_port(ctx, new_cell.get(), "STANDBY", PORT_IN); + // add_port(ctx, new_cell.get(), "SLEEP", PORT_IN); + // add_port(ctx, new_cell.get(), "POWEROFF", PORT_IN); + // + // for (int i = 0; i < 16; i++) { + // add_port(ctx, new_cell.get(), "DATAIN_" + std::to_string(i), PORT_IN); + // add_port(ctx, new_cell.get(), "DATAOUT_" + std::to_string(i), PORT_OUT); + // } + // for (int i = 0; i < 14; i++) { + // add_port(ctx, new_cell.get(), "ADDRESS_" + std::to_string(i), PORT_IN); + // } + // for (int i = 0; i < 4; i++) { + // add_port(ctx, new_cell.get(), "MASKWREN_" + std::to_string(i), PORT_IN); + // } + // } else if (type == ctx->id("ICESTORM_DSP")) { + // new_cell->params[ctx->id("NEG_TRIGGER")] = "0"; + // + // new_cell->params[ctx->id("C_REG")] = "0"; + // new_cell->params[ctx->id("A_REG")] = "0"; + // new_cell->params[ctx->id("B_REG")] = "0"; + // new_cell->params[ctx->id("D_REG")] = "0"; + // new_cell->params[ctx->id("TOP_8x8_MULT_REG")] = "0"; + // new_cell->params[ctx->id("BOT_8x8_MULT_REG")] = "0"; + // new_cell->params[ctx->id("PIPELINE_16x16_MULT_REG1")] = "0"; + // new_cell->params[ctx->id("PIPELINE_16x16_MULT_REG2")] = "0"; + // + // new_cell->params[ctx->id("TOPOUTPUT_SELECT")] = "0"; + // new_cell->params[ctx->id("TOPADDSUB_LOWERINPUT")] = "0"; + // new_cell->params[ctx->id("TOPADDSUB_UPPERINPUT")] = "0"; + // new_cell->params[ctx->id("TOPADDSUB_CARRYSELECT")] = "0"; + // + // new_cell->params[ctx->id("BOTOUTPUT_SELECT")] = "0"; + // new_cell->params[ctx->id("BOTADDSUB_LOWERINPUT")] = "0"; + // new_cell->params[ctx->id("BOTADDSUB_UPPERINPUT")] = "0"; + // new_cell->params[ctx->id("BOTADDSUB_CARRYSELECT")] = "0"; + // + // new_cell->params[ctx->id("MODE_8x8")] = "0"; + // new_cell->params[ctx->id("A_SIGNED")] = "0"; + // new_cell->params[ctx->id("B_SIGNED")] = "0"; + // + // add_port(ctx, new_cell.get(), "CLK", PORT_IN); + // add_port(ctx, new_cell.get(), "CE", PORT_IN); + // for (int i = 0; i < 16; i++) { + // add_port(ctx, new_cell.get(), "C_" + std::to_string(i), PORT_IN); + // add_port(ctx, new_cell.get(), "A_" + std::to_string(i), PORT_IN); + // add_port(ctx, new_cell.get(), "B_" + std::to_string(i), PORT_IN); + // add_port(ctx, new_cell.get(), "D_" + std::to_string(i), PORT_IN); + // } + // add_port(ctx, new_cell.get(), "AHOLD", PORT_IN); + // add_port(ctx, new_cell.get(), "BHOLD", PORT_IN); + // add_port(ctx, new_cell.get(), "CHOLD", PORT_IN); + // add_port(ctx, new_cell.get(), "DHOLD", PORT_IN); + // + // add_port(ctx, new_cell.get(), "IRSTTOP", PORT_IN); + // add_port(ctx, new_cell.get(), "IRSTBOT", PORT_IN); + // add_port(ctx, new_cell.get(), "ORSTTOP", PORT_IN); + // add_port(ctx, new_cell.get(), "ORSTBOT", PORT_IN); + // + // add_port(ctx, new_cell.get(), "OLOADTOP", PORT_IN); + // add_port(ctx, new_cell.get(), "OLOADBOT", PORT_IN); + // + // add_port(ctx, new_cell.get(), "ADDSUBTOP", PORT_IN); + // add_port(ctx, new_cell.get(), "ADDSUBBOT", PORT_IN); + // + // add_port(ctx, new_cell.get(), "OHOLDTOP", PORT_IN); + // add_port(ctx, new_cell.get(), "OHOLDBOT", PORT_IN); + // + // add_port(ctx, new_cell.get(), "CI", PORT_IN); + // add_port(ctx, new_cell.get(), "ACCUMCI", PORT_IN); + // add_port(ctx, new_cell.get(), "SIGNEXTIN", PORT_IN); + // + // for (int i = 0; i < 32; i++) { + // add_port(ctx, new_cell.get(), "O_" + std::to_string(i), PORT_OUT); + // } + // + // add_port(ctx, new_cell.get(), "CO", PORT_OUT); + // add_port(ctx, new_cell.get(), "ACCUMCO", PORT_OUT); + // add_port(ctx, new_cell.get(), "SIGNEXTOUT", PORT_OUT); + // + // } else if (type == ctx->id("ICESTORM_PLL")) { + // new_cell->params[ctx->id("DELAY_ADJMODE_FB")] = "0"; + // new_cell->params[ctx->id("DELAY_ADJMODE_REL")] = "0"; + // + // new_cell->params[ctx->id("DIVF")] = "0"; + // new_cell->params[ctx->id("DIVQ")] = "0"; + // new_cell->params[ctx->id("DIVR")] = "0"; + // + // new_cell->params[ctx->id("FDA_FEEDBACK")] = "0"; + // new_cell->params[ctx->id("FDA_RELATIVE")] = "0"; + // new_cell->params[ctx->id("FEEDBACK_PATH")] = "0"; + // new_cell->params[ctx->id("FILTER_RANGE")] = "0"; + // + // new_cell->params[ctx->id("PLLOUT_SELECT_A")] = "0"; + // new_cell->params[ctx->id("PLLOUT_SELECT_B")] = "0"; + // + // new_cell->params[ctx->id("PLLTYPE")] = "0"; + // new_cell->params[ctx->id("SHIFTREG_DIVMODE")] = "0"; + // new_cell->params[ctx->id("TEST_MODE")] = "0"; + // + // add_port(ctx, new_cell.get(), "BYPASS", PORT_IN); + // add_port(ctx, new_cell.get(), "DYNAMICDELAY", PORT_IN); + // add_port(ctx, new_cell.get(), "EXTFEEDBACK", PORT_IN); + // add_port(ctx, new_cell.get(), "LATCHINPUTVALUE", PORT_IN); + // add_port(ctx, new_cell.get(), "REFERENCECLK", PORT_IN); + // add_port(ctx, new_cell.get(), "RESETB", PORT_IN); + // + // add_port(ctx, new_cell.get(), "SCLK", PORT_IN); + // add_port(ctx, new_cell.get(), "SDI", PORT_IN); + // add_port(ctx, new_cell.get(), "SDI", PORT_OUT); + // + // add_port(ctx, new_cell.get(), "LOCK", PORT_OUT); + // add_port(ctx, new_cell.get(), "PLLOUT_A", PORT_OUT); + // add_port(ctx, new_cell.get(), "PLLOUT_B", PORT_OUT); } else { log_error("unable to create XC7 cell of type %s\n", type.c_str(ctx)); } diff --git a/xc7/cells.h b/xc7/cells.h index de323b36..c5956eb8 100644 --- a/xc7/cells.h +++ b/xc7/cells.h @@ -30,7 +30,11 @@ NEXTPNR_NAMESPACE_BEGIN std::unique_ptr create_xc7_cell(Context *ctx, IdString type, std::string name = ""); // Return true if a cell is a LUT -inline bool is_lut(const BaseCtx *ctx, const CellInfo *cell) { return cell->type == id_LUT1 || cell->type == id_LUT2 || cell->type == id_LUT3 || cell->type == id_LUT4 || cell->type == id_LUT5 || cell->type == id_LUT6; } +inline bool is_lut(const BaseCtx *ctx, const CellInfo *cell) +{ + return cell->type == id_LUT1 || cell->type == id_LUT2 || cell->type == id_LUT3 || cell->type == id_LUT4 || + cell->type == id_LUT5 || cell->type == id_LUT6; +} // Return true if a cell is a flipflop inline bool is_ff(const BaseCtx *ctx, const CellInfo *cell) diff --git a/xc7/chains.cc b/xc7/chains.cc index 407b72ff..be1d6762 100644 --- a/xc7/chains.cc +++ b/xc7/chains.cc @@ -97,7 +97,8 @@ class ChainConstrainer } tile.push_back(cell); chains.back().cells.push_back(cell); - bool split_chain = (!ctx->logicCellsCompatible(tile.data(), tile.size())) || (int(chains.back().cells.size()) > max_length); + bool split_chain = (!ctx->logicCellsCompatible(tile.data(), tile.size())) || + (int(chains.back().cells.size()) > max_length); if (split_chain) { CellInfo *passout = make_carry_pass_out(cell->ports.at(ctx->id("COUT"))); tile.pop_back(); diff --git a/xc7/delay.cc b/xc7/delay.cc index 0c420694..fe14a5ce 100644 --- a/xc7/delay.cc +++ b/xc7/delay.cc @@ -27,75 +27,75 @@ NEXTPNR_NAMESPACE_BEGIN void ice40DelayFuzzerMain(Context *ctx) { -// std::vector srcWires, dstWires; -// -// for (int i = 0; i < ctx->chip_info->num_wires; i++) { -// WireId wire; -// wire.index = i; -// -// switch (ctx->chip_info->wire_data[i].type) { -// case WireInfoPOD::WIRE_TYPE_LUTFF_OUT: -// srcWires.push_back(wire); -// break; -// -// case WireInfoPOD::WIRE_TYPE_LUTFF_IN_LUT: -// dstWires.push_back(wire); -// break; -// -// default: -// break; -// } -// } -// -// ctx->shuffle(srcWires); -// ctx->shuffle(dstWires); -// -// int index = 0; -// int cnt = 0; -// -// while (cnt < NUM_FUZZ_ROUTES) { -// if (index >= int(srcWires.size()) || index >= int(dstWires.size())) { -// index = 0; -// ctx->shuffle(srcWires); -// ctx->shuffle(dstWires); -// } -// -// WireId src = srcWires[index]; -// WireId dst = dstWires[index++]; -// std::unordered_map route; -// -//#if NUM_FUZZ_ROUTES <= 1000 -// if (!ctx->getActualRouteDelay(src, dst, nullptr, &route, false)) -// continue; -//#else -// if (!ctx->getActualRouteDelay(src, dst, nullptr, &route, true)) -// continue; -//#endif -// -// WireId cursor = dst; -// delay_t delay = 0; -// -// while (1) { -// delay += ctx->getWireDelay(cursor).maxDelay(); -// -// printf("%s %d %d %s %s %d %d\n", cursor == dst ? "dst" : "src", -// int(ctx->chip_info->wire_data[cursor.index].x), int(ctx->chip_info->wire_data[cursor.index].y), -// ctx->getWireType(cursor).c_str(ctx), ctx->getWireName(cursor).c_str(ctx), int(delay), -// int(ctx->estimateDelay(cursor, dst))); -// -// if (cursor == src) -// break; -// -// PipId pip = route.at(cursor); -// delay += ctx->getPipDelay(pip).maxDelay(); -// cursor = ctx->getPipSrcWire(pip); -// } -// -// cnt++; -// -// if (cnt % 100 == 0) -// fprintf(stderr, "Fuzzed %d arcs.\n", cnt); -// } + // std::vector srcWires, dstWires; + // + // for (int i = 0; i < ctx->chip_info->num_wires; i++) { + // WireId wire; + // wire.index = i; + // + // switch (ctx->chip_info->wire_data[i].type) { + // case WireInfoPOD::WIRE_TYPE_LUTFF_OUT: + // srcWires.push_back(wire); + // break; + // + // case WireInfoPOD::WIRE_TYPE_LUTFF_IN_LUT: + // dstWires.push_back(wire); + // break; + // + // default: + // break; + // } + // } + // + // ctx->shuffle(srcWires); + // ctx->shuffle(dstWires); + // + // int index = 0; + // int cnt = 0; + // + // while (cnt < NUM_FUZZ_ROUTES) { + // if (index >= int(srcWires.size()) || index >= int(dstWires.size())) { + // index = 0; + // ctx->shuffle(srcWires); + // ctx->shuffle(dstWires); + // } + // + // WireId src = srcWires[index]; + // WireId dst = dstWires[index++]; + // std::unordered_map route; + // + //#if NUM_FUZZ_ROUTES <= 1000 + // if (!ctx->getActualRouteDelay(src, dst, nullptr, &route, false)) + // continue; + //#else + // if (!ctx->getActualRouteDelay(src, dst, nullptr, &route, true)) + // continue; + //#endif + // + // WireId cursor = dst; + // delay_t delay = 0; + // + // while (1) { + // delay += ctx->getWireDelay(cursor).maxDelay(); + // + // printf("%s %d %d %s %s %d %d\n", cursor == dst ? "dst" : "src", + // int(ctx->chip_info->wire_data[cursor.index].x), int(ctx->chip_info->wire_data[cursor.index].y), + // ctx->getWireType(cursor).c_str(ctx), ctx->getWireName(cursor).c_str(ctx), int(delay), + // int(ctx->estimateDelay(cursor, dst))); + // + // if (cursor == src) + // break; + // + // PipId pip = route.at(cursor); + // delay += ctx->getPipDelay(pip).maxDelay(); + // cursor = ctx->getPipSrcWire(pip); + // } + // + // cnt++; + // + // if (cnt % 100 == 0) + // fprintf(stderr, "Fuzzed %d arcs.\n", cnt); + // } } delay_t Arch::estimateDelay(WireId src, WireId dst) const diff --git a/xc7/main.cc b/xc7/main.cc index c24ce488..65fabff4 100644 --- a/xc7/main.cc +++ b/xc7/main.cc @@ -52,18 +52,18 @@ po::options_description Xc7CommandHandler::getArchOptions() { po::options_description specific("Architecture specific options"); specific.add_options()("xc7z020", "set device type to xc7z020"); -// specific.add_options()("package", po::value(), "set device package"); + // specific.add_options()("package", po::value(), "set device package"); specific.add_options()("pcf", po::value(), "PCF constraints file to ingest"); specific.add_options()("xdl", po::value(), "XDL file to write"); -// specific.add_options()("tmfuzz", "run path delay estimate fuzzer"); + // specific.add_options()("tmfuzz", "run path delay estimate fuzzer"); return specific; } void Xc7CommandHandler::validate() { conflicting_options(vm, "read", "json"); -// if ((vm.count("lp384") + vm.count("lp1k") + vm.count("lp8k") + vm.count("hx1k") + vm.count("hx8k") + -// vm.count("up5k")) > 1) -// log_error("Only one device type can be set\n"); + // if ((vm.count("lp384") + vm.count("lp1k") + vm.count("lp8k") + vm.count("hx1k") + vm.count("hx8k") + + // vm.count("up5k")) > 1) + // log_error("Only one device type can be set\n"); } void Xc7CommandHandler::customAfterLoad(Context *ctx) @@ -86,8 +86,8 @@ void Xc7CommandHandler::customBitstream(Context *ctx) void Xc7CommandHandler::setupArchContext(Context *ctx) { -// if (vm.count("tmfuzz")) -// ice40DelayFuzzerMain(ctx); + // if (vm.count("tmfuzz")) + // ice40DelayFuzzerMain(ctx); } std::unique_ptr Xc7CommandHandler::createContext() diff --git a/xc7/pack.cc b/xc7/pack.cc index 05404fdb..7d7eb34d 100644 --- a/xc7/pack.cc +++ b/xc7/pack.cc @@ -96,8 +96,7 @@ static void pack_nonlut_ffs(Context *ctx) for (auto cell : sorted(ctx->cells)) { CellInfo *ci = cell.second; if (is_ff(ctx, ci)) { - std::unique_ptr packed = - create_xc7_cell(ctx, ctx->id("XC7_LC"), ci->name.str(ctx) + "_DFFLC"); + std::unique_ptr packed = create_xc7_cell(ctx, ctx->id("XC7_LC"), ci->name.str(ctx) + "_DFFLC"); std::copy(ci->attrs.begin(), ci->attrs.end(), std::inserter(packed->attrs, packed->attrs.begin())); if (ctx->verbose) log_info("packed cell %s into %s\n", ci->name.c_str(ctx), packed->name.c_str(ctx)); @@ -422,8 +421,7 @@ static void pack_io(Context *ctx) } } else { // Create a IOBUF buffer - std::unique_ptr ice_cell = - create_xc7_cell(ctx, ctx->id("IOBUF"), ci->name.str(ctx) + "$iob"); + std::unique_ptr ice_cell = create_xc7_cell(ctx, ctx->id("IOBUF"), ci->name.str(ctx) + "$iob"); nxio_to_sb(ctx, ci, ice_cell.get()); new_cells.push_back(std::move(ice_cell)); sb = new_cells.back().get(); @@ -582,8 +580,8 @@ static std::unique_ptr spliceLUT(Context *ctx, CellInfo *ci, IdString NPNR_ASSERT(port.net != nullptr); // Create pass-through LUT. - std::unique_ptr pt = create_xc7_cell(ctx, ctx->id("XC7_LC"), - ci->name.str(ctx) + "$nextpnr_" + portId.str(ctx) + "_lut_through"); + std::unique_ptr pt = + create_xc7_cell(ctx, ctx->id("XC7_LC"), ci->name.str(ctx) + "$nextpnr_" + portId.str(ctx) + "_lut_through"); pt->params[ctx->id("INIT")] = "65280"; // output is always I3 // Create LUT output net. @@ -851,10 +849,10 @@ static void pack_special(Context *ctx) // Now, constrain all LUTs on the output of the signal to be at // the correct Bel relative to the PLL Bel. - //int x = ctx->chip_info->wire_data[pll_out_wire.index].x; - //int y = ctx->chip_info->wire_data[pll_out_wire.index].y; - //int z = 0; - //for (const auto &user : port.net->users) { + // int x = ctx->chip_info->wire_data[pll_out_wire.index].x; + // int y = ctx->chip_info->wire_data[pll_out_wire.index].y; + // int z = 0; + // for (const auto &user : port.net->users) { // NPNR_ASSERT(user.cell != nullptr); // NPNR_ASSERT(user.cell->type == ctx->id("XC7_LC")); @@ -888,7 +886,7 @@ bool Arch::pack() log_break(); pack_constants(ctx); // TODO - //promote_globals(ctx); + // promote_globals(ctx); pack_io(ctx); pack_lut_lutffs(ctx); pack_nonlut_ffs(ctx); diff --git a/xc7/pcf.cc b/xc7/pcf.cc index d9fc4e68..7327b252 100644 --- a/xc7/pcf.cc +++ b/xc7/pcf.cc @@ -22,6 +22,8 @@ #include #include "log.h" +#include + NEXTPNR_NAMESPACE_BEGIN // Read a w @@ -45,12 +47,14 @@ bool apply_pcf(Context *ctx, std::string filename, std::istream &in) if (words.size() == 0) continue; std::string cmd = words.at(0); - if (cmd == "set_io") { + if (cmd == "COMP") { size_t args_end = 1; while (args_end < words.size() && words.at(args_end).at(0) == '-') args_end++; std::string cell = words.at(args_end); - std::string pin = words.at(args_end + 1); + boost::trim_if(cell, boost::is_any_of("\"")); + std::string pin = words.at(args_end + 4); + boost::trim_if(pin, boost::is_any_of("\"")); auto fnd_cell = ctx->cells.find(ctx->id(cell)); if (fnd_cell == ctx->cells.end()) { log_warning("unmatched pcf constraint %s\n", cell.c_str()); diff --git a/xc7/xdl.cc b/xc7/xdl.cc index 21a1ccf5..1bee3029 100644 --- a/xc7/xdl.cc +++ b/xc7/xdl.cc @@ -18,12 +18,12 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ -#include "nextpnr.h" #include "xdl.h" #include #include #include "cells.h" #include "log.h" +#include "nextpnr.h" #include "util.h" #include "torc/Physical.hpp" @@ -37,25 +37,41 @@ void write_xdl(const Context *ctx, std::ostream &out) XdlExporter exporter(out); auto designPtr = Factory::newDesignPtr("name", torc_info->ddb->getDeviceName(), ctx->args.package, "-1", ""); - std::unordered_map site_to_instance; - std::vector> lut_inputs; + std::unordered_map site_to_instance; + std::vector> lut_inputs; lut_inputs.reserve(6); auto bel_to_lut = [](const BelId bel) { switch (torc_info->bel_to_loc[bel.index].z) { - case 0: case 4: return "A"; break; - case 1: case 5: return "B"; break; - case 2: case 6: return "C"; break; - case 3: case 7: return "D"; break; - default: throw; + case 0: + case 4: + return "A"; + break; + case 1: + case 5: + return "B"; + break; + case 2: + case 6: + return "C"; + break; + case 3: + case 7: + return "D"; + break; + default: + throw; } }; - for (const auto& cell : ctx->cells) { - const char* type; - if (cell.second->type == id_SLICE_LUT6) type = "SLICEL"; - else if (cell.second->type == id_IOB33 || cell.second->type == id_BUFGCTRL) type = cell.second->type.c_str(ctx); - else log_error("Unsupported cell type '%s'.\n", cell.second->type.c_str(ctx)); + for (const auto &cell : ctx->cells) { + const char *type; + if (cell.second->type == id_SLICE_LUT6) + type = "SLICEL"; + else if (cell.second->type == id_IOB33 || cell.second->type == id_BUFGCTRL) + type = cell.second->type.c_str(ctx); + else + log_error("Unsupported cell type '%s'.\n", cell.second->type.c_str(ctx)); auto site_index = torc_info->bel_to_site_index[cell.second->bel.index]; auto ret = site_to_instance.emplace(site_index, nullptr); @@ -66,11 +82,10 @@ void write_xdl(const Context *ctx, std::ostream &out) assert(b); ret.first->second = instPtr; - const auto& tile_info = torc_info->bel_to_tile_info(cell.second->bel.index); + const auto &tile_info = torc_info->bel_to_tile_info(cell.second->bel.index); instPtr->setTile(tile_info.getName()); instPtr->setSite(torc_info->bel_to_name(cell.second->bel.index)); - } - else + } else instPtr = ret.first->second; if (cell.second->type == id_SLICE_LUT6) { @@ -80,13 +95,19 @@ void write_xdl(const Context *ctx, std::ostream &out) setting = lut + "6LUT"; value = "#LUT:O6="; lut_inputs.clear(); - if (get_net_or_empty(cell.second.get(), id_I1)) lut_inputs.emplace_back("A1", "~A1"); - if (get_net_or_empty(cell.second.get(), id_I2)) lut_inputs.emplace_back("A2", "~A2"); - if (get_net_or_empty(cell.second.get(), id_I3)) lut_inputs.emplace_back("A3", "~A3"); - if (get_net_or_empty(cell.second.get(), id_I4)) lut_inputs.emplace_back("A4", "~A4"); - if (get_net_or_empty(cell.second.get(), id_I5)) lut_inputs.emplace_back("A5", "~A5"); - if (get_net_or_empty(cell.second.get(), id_I6)) lut_inputs.emplace_back("A6", "~A6"); - const auto& init = cell.second->params[ctx->id("INIT")]; + if (get_net_or_empty(cell.second.get(), id_I1)) + lut_inputs.emplace_back("A1", "~A1"); + if (get_net_or_empty(cell.second.get(), id_I2)) + lut_inputs.emplace_back("A2", "~A2"); + if (get_net_or_empty(cell.second.get(), id_I3)) + lut_inputs.emplace_back("A3", "~A3"); + if (get_net_or_empty(cell.second.get(), id_I4)) + lut_inputs.emplace_back("A4", "~A4"); + if (get_net_or_empty(cell.second.get(), id_I5)) + lut_inputs.emplace_back("A5", "~A5"); + if (get_net_or_empty(cell.second.get(), id_I6)) + lut_inputs.emplace_back("A6", "~A6"); + const auto &init = cell.second->params[ctx->id("INIT")]; // Assume from Yosys that INIT masks of less than 32 bits are output as uint32_t if (lut_inputs.size() < 6) { auto init_as_uint = boost::lexical_cast(init); @@ -96,8 +117,10 @@ void write_xdl(const Context *ctx, std::ostream &out) else { unsigned n = 0; for (unsigned o = 0; o < (1u << lut_inputs.size()); ++o) { - if ((init_as_uint >> o) & 0x1) continue; - if (n++ > 0) value += "+"; + if ((init_as_uint >> o) & 0x1) + continue; + if (n++ > 0) + value += "+"; value += "("; value += (o & 1) ? lut_inputs[0].first : lut_inputs[0].second; for (unsigned i = 1; i < lut_inputs.size(); ++i) { @@ -113,8 +136,10 @@ void write_xdl(const Context *ctx, std::ostream &out) NPNR_ASSERT(init.size() == (1u << lut_inputs.size())); unsigned n = 0; for (unsigned i = 0; i < (1u << lut_inputs.size()); ++i) { - if (init[i] == '0') continue; - if (n++ > 0) value += "+"; + if (init[i] == '0') + continue; + if (n++ > 0) + value += "+"; value += "("; value += (i & 1) ? lut_inputs[0].first : lut_inputs[0].second; for (unsigned j = 1; j < lut_inputs.size(); ++j) { @@ -159,28 +184,25 @@ void write_xdl(const Context *ctx, std::ostream &out) instPtr->setConfig("CEUSEDMUX", "", "IN"); instPtr->setConfig("SYNC_ATTR", "", "ASYNC"); } - } - else if (cell.second->type == id_IOB33) { + } else if (cell.second->type == id_IOB33) { if (get_net_or_empty(cell.second.get(), id_I)) { instPtr->setConfig("IUSED", "", "0"); instPtr->setConfig("IBUF_LOW_PWR", "", "TRUE"); instPtr->setConfig("ISTANDARD", "", "LVCMOS33"); - } - else { + } else { instPtr->setConfig("OUSED", "", "0"); instPtr->setConfig("OSTANDARD", "", "LVCMOS33"); instPtr->setConfig("DRIVE", "", "12"); instPtr->setConfig("SLEW", "", "SLOW"); } - } - else if (cell.second->type == id_BUFGCTRL) { + } else if (cell.second->type == id_BUFGCTRL) { auto it = cell.second->params.find(ctx->id("PRESELECT_I0")); instPtr->setConfig("PRESELECT_I0", "", it != cell.second->params.end() ? it->second : "TRUE"); instPtr->setConfig("CE0INV", "", "CE0_B"); instPtr->setConfig("S0INV", "", "S0_B"); - } - else log_error("Unsupported cell type '%s'.\n", cell.second->type.c_str(ctx)); + } else + log_error("Unsupported cell type '%s'.\n", cell.second->type.c_str(ctx)); } for (const auto &net : ctx->nets) { @@ -217,18 +239,19 @@ void write_xdl(const Context *ctx, std::ostream &out) auto b = designPtr->addNet(netPtr); assert(b); - for (const auto& i : net.second->wires) { - const auto& pip_map = i.second; - if (pip_map.pip == PipId()) continue; + for (const auto &i : net.second->wires) { + const auto &pip_map = i.second; + if (pip_map.pip == PipId()) + continue; ExtendedWireInfo ewi_src(*torc_info->ddb, torc_info->pip_to_arc[pip_map.pip.index].getSourceTilewire()); ExtendedWireInfo ewi_dst(*torc_info->ddb, torc_info->pip_to_arc[pip_map.pip.index].getSinkTilewire()); - auto p = Factory::newPip(ewi_src.mTileName, ewi_src.mWireName, ewi_dst.mWireName, ePipUnidirectionalBuffered); + auto p = Factory::newPip(ewi_src.mTileName, ewi_src.mWireName, ewi_dst.mWireName, + ePipUnidirectionalBuffered); netPtr->addPip(p); } } exporter(designPtr); - } NEXTPNR_NAMESPACE_END