clangformat

This commit is contained in:
Eddie Hung 2018-11-03 15:18:26 -07:00
parent d80b63cc55
commit aa7f7d6a97
21 changed files with 764 additions and 706 deletions

View File

@ -212,7 +212,8 @@ struct Timing
for (auto net : boost::adaptors::reverse(topographical_order)) { for (auto net : boost::adaptors::reverse(topographical_order)) {
auto &nd = net_data.at(net); auto &nd = net_data.at(net);
// Ignore false startpoints // 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; const delay_t net_length_plus_one = nd.max_path_length + 1;
auto &net_min_remaining_budget = nd.min_remaining_budget; auto &net_min_remaining_budget = nd.min_remaining_budget;
for (auto &usr : net->users) { for (auto &usr : net->users) {

View File

@ -18,9 +18,9 @@
*/ */
#include "mainwindow.h" #include "mainwindow.h"
#include <fstream>
#include "bitstream.h" #include "bitstream.h"
#include "log.h" #include "log.h"
#include <fstream>
#include <QFileDialog> #include <QFileDialog>
#include <QInputDialog> #include <QInputDialog>

View File

@ -107,9 +107,8 @@ void FPGAViewWidget::initializeGL()
} }
initializeOpenGLFunctions(); initializeOpenGLFunctions();
QtImGui::initialize(this); QtImGui::initialize(this);
glClearColor(colors_.background.red() / 255, colors_.background.green() / 255, glClearColor(colors_.background.red() / 255, colors_.background.green() / 255, colors_.background.blue() / 255,
colors_.background.blue() / 255, 0.0); 0.0);
{ {
QMutexLocker locker(&rendererDataLock_); QMutexLocker locker(&rendererDataLock_);
@ -321,30 +320,22 @@ void FPGAViewWidget::paintGL()
} }
// Render the grid. // Render the grid.
lineShader_.draw(GraphicElement::STYLE_GRID, colors_.grid, thick1Px, lineShader_.draw(GraphicElement::STYLE_GRID, colors_.grid, thick1Px, matrix);
matrix);
// Render Arch graphics. // Render Arch graphics.
lineShader_.draw(GraphicElement::STYLE_FRAME, colors_.frame, thick11Px, lineShader_.draw(GraphicElement::STYLE_FRAME, colors_.frame, thick11Px, matrix);
matrix); lineShader_.draw(GraphicElement::STYLE_HIDDEN, colors_.hidden, thick11Px, matrix);
lineShader_.draw(GraphicElement::STYLE_HIDDEN, colors_.hidden, thick11Px, lineShader_.draw(GraphicElement::STYLE_INACTIVE, colors_.inactive, thick11Px, matrix);
matrix); lineShader_.draw(GraphicElement::STYLE_ACTIVE, colors_.active, thick11Px, matrix);
lineShader_.draw(GraphicElement::STYLE_INACTIVE, colors_.inactive,
thick11Px, matrix);
lineShader_.draw(GraphicElement::STYLE_ACTIVE, colors_.active, thick11Px,
matrix);
// Draw highlighted items. // Draw highlighted items.
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
GraphicElement::style_t style = (GraphicElement::style_t)( GraphicElement::style_t style = (GraphicElement::style_t)(GraphicElement::STYLE_HIGHLIGHTED0 + i);
GraphicElement::STYLE_HIGHLIGHTED0 + i);
lineShader_.draw(style, colors_.highlight[i], thick11Px, matrix); lineShader_.draw(style, colors_.highlight[i], thick11Px, matrix);
} }
lineShader_.draw(GraphicElement::STYLE_SELECTED, colors_.selected, lineShader_.draw(GraphicElement::STYLE_SELECTED, colors_.selected, thick11Px, matrix);
thick11Px, matrix); lineShader_.draw(GraphicElement::STYLE_HOVER, colors_.hovered, thick2Px, matrix);
lineShader_.draw(GraphicElement::STYLE_HOVER, colors_.hovered,
thick2Px, matrix);
// Flags from pipeline. // Flags from pipeline.
PassthroughFlags flags = rendererData_->flags; PassthroughFlags flags = rendererData_->flags;
@ -364,8 +355,7 @@ void FPGAViewWidget::paintGL()
} }
QtImGui::newFrame(); QtImGui::newFrame();
QMutexLocker lock(&rendererArgsLock_); 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::SetNextWindowPos(ImVec2(rendererArgs_->x, rendererArgs_->y));
ImGui::BeginTooltip(); ImGui::BeginTooltip();
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f); ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
@ -465,7 +455,7 @@ void FPGAViewWidget::renderLines(void)
int last_render[GraphicElement::STYLE_HIGHLIGHTED0]; int last_render[GraphicElement::STYLE_HIGHLIGHTED0];
{ {
QMutexLocker locker(&rendererDataLock_); QMutexLocker locker(&rendererDataLock_);
for(int i =0; i<GraphicElement::STYLE_HIGHLIGHTED0; i++) for (int i = 0; i < GraphicElement::STYLE_HIGHLIGHTED0; i++)
last_render[i] = rendererData_->gfxByStyle[(enum GraphicElement::style_t)i].last_render; last_render[i] = rendererData_->gfxByStyle[(enum GraphicElement::style_t)i].last_render;
} }
@ -534,7 +524,7 @@ void FPGAViewWidget::renderLines(void)
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
data->gfxHighlighted[i] = rendererData_->gfxHighlighted[i]; data->gfxHighlighted[i] = rendererData_->gfxHighlighted[i];
} }
for(int i =0; i<GraphicElement::STYLE_HIGHLIGHTED0; i++) for (int i = 0; i < GraphicElement::STYLE_HIGHLIGHTED0; i++)
data->gfxByStyle[(enum GraphicElement::style_t)i].last_render = ++last_render[i]; data->gfxByStyle[(enum GraphicElement::style_t)i].last_render = ++last_render[i];
rendererData_ = std::move(data); rendererData_ = std::move(data);
} }
@ -655,7 +645,8 @@ boost::optional<FPGAViewWidget::PickedElement> FPGAViewWidget::pickElement(float
void FPGAViewWidget::mousePressEvent(QMouseEvent *event) void FPGAViewWidget::mousePressEvent(QMouseEvent *event)
{ {
ImGuiIO &io = ImGui::GetIO(); ImGuiIO &io = ImGui::GetIO();
if (io.WantCaptureMouse) return; if (io.WantCaptureMouse)
return;
if (event->buttons() & Qt::RightButton || event->buttons() & Qt::MidButton) { if (event->buttons() & Qt::RightButton || event->buttons() & Qt::MidButton) {
lastDragPos_ = event->pos(); lastDragPos_ = event->pos();
@ -691,7 +682,8 @@ void FPGAViewWidget::mousePressEvent(QMouseEvent *event)
void FPGAViewWidget::mouseMoveEvent(QMouseEvent *event) void FPGAViewWidget::mouseMoveEvent(QMouseEvent *event)
{ {
ImGuiIO &io = ImGui::GetIO(); ImGuiIO &io = ImGui::GetIO();
if (io.WantCaptureMouse) return; if (io.WantCaptureMouse)
return;
if (event->buttons() & Qt::RightButton || event->buttons() & Qt::MidButton) { if (event->buttons() & Qt::RightButton || event->buttons() & Qt::MidButton) {
const int dx = event->x() - lastDragPos_.x(); const int dx = event->x() - lastDragPos_.x();
@ -728,21 +720,22 @@ void FPGAViewWidget::mouseMoveEvent(QMouseEvent *event)
if (closest.type == ElementType::BEL) { if (closest.type == ElementType::BEL) {
rendererArgs_->hintText = std::string("BEL\n") + ctx_->getBelName(closest.bel).c_str(ctx_); rendererArgs_->hintText = std::string("BEL\n") + ctx_->getBelName(closest.bel).c_str(ctx_);
CellInfo *cell = ctx_->getBoundBelCell(closest.bel); CellInfo *cell = ctx_->getBoundBelCell(closest.bel);
if (cell!=nullptr) if (cell != nullptr)
rendererArgs_->hintText += std::string("\nCELL\n") +ctx_->nameOf(cell); rendererArgs_->hintText += std::string("\nCELL\n") + ctx_->nameOf(cell);
} else if (closest.type == ElementType::WIRE) { } else if (closest.type == ElementType::WIRE) {
rendererArgs_->hintText = std::string("WIRE\n") + ctx_->getWireName(closest.wire).c_str(ctx_); rendererArgs_->hintText = std::string("WIRE\n") + ctx_->getWireName(closest.wire).c_str(ctx_);
NetInfo *net = ctx_->getBoundWireNet(closest.wire); NetInfo *net = ctx_->getBoundWireNet(closest.wire);
if (net!=nullptr) if (net != nullptr)
rendererArgs_->hintText += std::string("\nNET\n") +ctx_->nameOf(net); rendererArgs_->hintText += std::string("\nNET\n") + ctx_->nameOf(net);
} else if (closest.type == ElementType::PIP) { } else if (closest.type == ElementType::PIP) {
rendererArgs_->hintText = std::string("PIP\n") + ctx_->getPipName(closest.pip).c_str(ctx_); rendererArgs_->hintText = std::string("PIP\n") + ctx_->getPipName(closest.pip).c_str(ctx_);
NetInfo *net = ctx_->getBoundPipNet(closest.pip); NetInfo *net = ctx_->getBoundPipNet(closest.pip);
if (net!=nullptr) if (net != nullptr)
rendererArgs_->hintText += std::string("\nNET\n") +ctx_->nameOf(net); rendererArgs_->hintText += std::string("\nNET\n") + ctx_->nameOf(net);
} else if (closest.type == ElementType::GROUP) { } else if (closest.type == ElementType::GROUP) {
rendererArgs_->hintText = std::string("GROUP\n") + ctx_->getGroupName(closest.group).c_str(ctx_); rendererArgs_->hintText = std::string("GROUP\n") + ctx_->getGroupName(closest.group).c_str(ctx_);
} else rendererArgs_->hintText = ""; } else
rendererArgs_->hintText = "";
pokeRenderer(); pokeRenderer();
} }
@ -793,7 +786,8 @@ QVector4D FPGAViewWidget::mouseToWorldDimensions(float x, float y)
void FPGAViewWidget::wheelEvent(QWheelEvent *event) void FPGAViewWidget::wheelEvent(QWheelEvent *event)
{ {
ImGuiIO &io = ImGui::GetIO(); ImGuiIO &io = ImGui::GetIO();
if (io.WantCaptureMouse) return; if (io.WantCaptureMouse)
return;
QPoint degree = event->angleDelta() / 8; QPoint degree = event->angleDelta() / 8;
@ -876,23 +870,17 @@ void FPGAViewWidget::leaveEvent(QEvent *event)
void FPGAViewWidget::update_vbos() void FPGAViewWidget::update_vbos()
{ {
for (int style = GraphicElement::STYLE_FRAME; style for (int style = GraphicElement::STYLE_FRAME; style < GraphicElement::STYLE_HIGHLIGHTED0; style++) {
< GraphicElement::STYLE_HIGHLIGHTED0; lineShader_.update_vbos((enum GraphicElement::style_t)(style), rendererData_->gfxByStyle[style]);
style++) {
lineShader_.update_vbos((enum GraphicElement::style_t)(style),
rendererData_->gfxByStyle[style]);
} }
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
GraphicElement::style_t style = (GraphicElement::style_t)( GraphicElement::style_t style = (GraphicElement::style_t)(GraphicElement::STYLE_HIGHLIGHTED0 + i);
GraphicElement::STYLE_HIGHLIGHTED0 + i);
lineShader_.update_vbos(style, rendererData_->gfxHighlighted[i]); lineShader_.update_vbos(style, rendererData_->gfxHighlighted[i]);
} }
lineShader_.update_vbos(GraphicElement::STYLE_SELECTED, lineShader_.update_vbos(GraphicElement::STYLE_SELECTED, rendererData_->gfxSelected);
rendererData_->gfxSelected); lineShader_.update_vbos(GraphicElement::STYLE_HOVER, rendererData_->gfxHovered);
lineShader_.update_vbos(GraphicElement::STYLE_HOVER,
rendererData_->gfxHovered);
} }
NEXTPNR_NAMESPACE_END NEXTPNR_NAMESPACE_END

View File

@ -271,7 +271,7 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions
// Hint text // Hint text
std::string hintText; std::string hintText;
// cursor pos // cursor pos
int x,y; int x, y;
}; };
std::unique_ptr<RendererArgs> rendererArgs_; std::unique_ptr<RendererArgs> rendererArgs_;
QMutex rendererArgsLock_; QMutex rendererArgsLock_;

View File

@ -206,8 +206,7 @@ bool LineShader::compile(void)
return true; return true;
} }
void LineShader::update_vbos(enum GraphicElement::style_t style, void LineShader::update_vbos(enum GraphicElement::style_t style, const LineShaderData &line)
const LineShaderData &line)
{ {
if (buffers_[style].last_vbo_update == line.last_render) if (buffers_[style].last_vbo_update == line.last_render)
return; 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()); buffers_[style].index.allocate(&line.indices[0], sizeof(GLuint) * line.indices.size());
} }
void LineShader::draw(enum GraphicElement::style_t style, const QColor &color, void LineShader::draw(enum GraphicElement::style_t style, const QColor &color, float thickness,
float thickness, const QMatrix4x4 &projection) const QMatrix4x4 &projection)
{ {
auto gl = QOpenGLContext::currentContext()->functions(); auto gl = QOpenGLContext::currentContext()->functions();
if (buffers_[style].indices == 0) if (buffers_[style].indices == 0)

View File

@ -20,12 +20,12 @@
#ifndef LINESHADER_H #ifndef LINESHADER_H
#define LINESHADER_H #define LINESHADER_H
#include <array>
#include <QOpenGLBuffer> #include <QOpenGLBuffer>
#include <QOpenGLFunctions> #include <QOpenGLFunctions>
#include <QOpenGLShaderProgram> #include <QOpenGLShaderProgram>
#include <QOpenGLVertexArrayObject> #include <QOpenGLVertexArrayObject>
#include <QOpenGLWidget> #include <QOpenGLWidget>
#include <array>
#include "log.h" #include "log.h"
#include "nextpnr.h" #include "nextpnr.h"
@ -169,9 +169,7 @@ class LineShader
} uniforms_; } uniforms_;
public: public:
LineShader(QObject *parent) : parent_(parent), program_(nullptr) LineShader(QObject *parent) : parent_(parent), program_(nullptr) {}
{
}
static constexpr const char *vertexShaderSource_ = static constexpr const char *vertexShaderSource_ =
"#version 110\n" "#version 110\n"
@ -194,12 +192,10 @@ class LineShader
// Must be called on initialization. // Must be called on initialization.
bool compile(void); bool compile(void);
void update_vbos(enum GraphicElement::style_t style, void update_vbos(enum GraphicElement::style_t style, const LineShaderData &line);
const LineShaderData &line);
// Render a LineShaderData with a given M/V/P transformation. // Render a LineShaderData with a given M/V/P transformation.
void draw(enum GraphicElement::style_t style, const QColor &color, void draw(enum GraphicElement::style_t style, const QColor &color, float thickness, const QMatrix4x4 &projection);
float thickness, const QMatrix4x4 &projection);
}; };
NEXTPNR_NAMESPACE_END NEXTPNR_NAMESPACE_END

View File

@ -872,16 +872,13 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, Id
if (cell->lcInfo.dffEnable) { if (cell->lcInfo.dffEnable) {
clockPort = id_CLK; clockPort = id_CLK;
return TMG_REGISTER_OUTPUT; return TMG_REGISTER_OUTPUT;
} } else
else
return TMG_COMB_OUTPUT; return TMG_COMB_OUTPUT;
} } else {
else {
if (cell->lcInfo.dffEnable) { if (cell->lcInfo.dffEnable) {
clockPort = id_CLK; clockPort = id_CLK;
return TMG_REGISTER_INPUT; return TMG_REGISTER_INPUT;
} } else
else
return TMG_COMB_INPUT; return TMG_COMB_INPUT;
} }
} else if (cell->type == id_ICESTORM_RAM) { } else if (cell->type == id_ICESTORM_RAM) {

View File

@ -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) 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::string glb_name = net->name.str(ctx) + std::string("_$glb_") + (is_reset ? "sr" : (is_cen ? "ce" : "clk"));
std::unique_ptr<CellInfo> gb = create_ice_cell(ctx, ctx->id("SB_GB"), "$gbuf_" + glb_name); std::unique_ptr<CellInfo> gb = create_ice_cell(ctx, ctx->id("SB_GB"), "$gbuf_" + glb_name);

View File

@ -32,19 +32,25 @@
NEXTPNR_NAMESPACE_BEGIN NEXTPNR_NAMESPACE_BEGIN
std::unique_ptr<const TorcInfo> torc_info; std::unique_ptr<const TorcInfo> torc_info;
TorcInfo::TorcInfo(Arch *ctx, const std::string &inDeviceName, const std::string &inPackageName) 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); 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(); const auto &tw = arc.getSinkTilewire();
pip_to_dst_wire.push_back(tilewire_to_wire(tw)); pip_to_dst_wire.push_back(tilewire_to_wire(tw));
} }
} }
std::vector<SiteIndex> TorcInfo::construct_bel_to_site_index(Arch* ctx, const Sites &sites) std::vector<SiteIndex> TorcInfo::construct_bel_to_site_index(Arch *ctx, const Sites &sites)
{ {
std::vector<SiteIndex> bel_to_site_index; std::vector<SiteIndex> bel_to_site_index;
bel_to_site_index.reserve(sites.getSiteCount()); bel_to_site_index.reserve(sites.getSiteCount());
@ -57,13 +63,12 @@ std::vector<SiteIndex> 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); 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); bel_to_site_index.push_back(i);
} }
return bel_to_site_index; return bel_to_site_index;
} }
std::vector<IdString> TorcInfo::construct_site_index_to_type(Arch* ctx, const Sites &sites) std::vector<IdString> TorcInfo::construct_site_index_to_type(Arch *ctx, const Sites &sites)
{ {
std::vector<IdString> site_index_to_type; std::vector<IdString> site_index_to_type;
site_index_to_type.resize(sites.getSiteCount()); site_index_to_type.resize(sites.getSiteCount());
@ -80,7 +85,8 @@ std::vector<IdString> TorcInfo::construct_site_index_to_type(Arch* ctx, const Si
} }
return site_index_to_type; return site_index_to_type;
} }
std::vector<Loc> TorcInfo::construct_bel_to_loc(const Sites &sites, const Tiles &tiles, const int num_bels, const std::vector<IdString> &site_index_to_type) std::vector<Loc> TorcInfo::construct_bel_to_loc(const Sites &sites, const Tiles &tiles, const int num_bels,
const std::vector<IdString> &site_index_to_type)
{ {
std::vector<Loc> bel_to_loc; std::vector<Loc> bel_to_loc;
bel_to_loc.resize(num_bels); bel_to_loc.resize(num_bels);
@ -94,44 +100,46 @@ std::vector<Loc> TorcInfo::construct_bel_to_loc(const Sites &sites, const Tiles
if (site_index_to_type[i] == id_SLICE_LUT6) { if (site_index_to_type[i] == id_SLICE_LUT6) {
const auto site_name = site.getName(); const auto site_name = site.getName();
const auto site_name_back = site_name.back(); 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, 0);
bel_to_loc[bel_index++] = Loc(x, y, 1); 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, 2);
bel_to_loc[bel_index++] = Loc(x, y, 3); 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, 4);
bel_to_loc[bel_index++] = Loc(x, y, 5); 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, 6);
bel_to_loc[bel_index++] = Loc(x, y, 7); bel_to_loc[bel_index++] = Loc(x, y, 7);
} }
} } else
else
bel_to_loc[bel_index++] = Loc(x, y, 0); bel_to_loc[bel_index++] = Loc(x, y, 0);
} }
return bel_to_loc; return bel_to_loc;
} }
std::vector<Tilewire> TorcInfo::construct_wire_to_tilewire(const Segments& segments, const Tiles& tiles, std::unordered_map<Segments::SegmentReference,int>& segment_to_wire, std::unordered_map<Tilewire,int>& trivial_to_wire) std::vector<Tilewire>
TorcInfo::construct_wire_to_tilewire(const Segments &segments, const Tiles &tiles,
std::unordered_map<Segments::SegmentReference, int> &segment_to_wire,
std::unordered_map<Tilewire, int> &trivial_to_wire)
{ {
std::vector<Tilewire> wire_to_tilewire; std::vector<Tilewire> wire_to_tilewire;
Tilewire currentTilewire; 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 // iterate over every wire in the tile
const auto& tileInfo = tiles.getTileInfo(tileIndex); const auto &tileInfo = tiles.getTileInfo(tileIndex);
auto tileTypeIndex = tileInfo.getTypeIndex(); auto tileTypeIndex = tileInfo.getTypeIndex();
auto wireCount = tiles.getWireCount(tileTypeIndex); auto wireCount = tiles.getWireCount(tileTypeIndex);
currentTilewire.setTileIndex(tileIndex); currentTilewire.setTileIndex(tileIndex);
for(WireIndex wireIndex(0); wireIndex < wireCount; wireIndex++) { for (WireIndex wireIndex(0); wireIndex < wireCount; wireIndex++) {
currentTilewire.setWireIndex(wireIndex); currentTilewire.setWireIndex(wireIndex);
const auto& currentSegment = segments.getTilewireSegment(currentTilewire); const auto &currentSegment = segments.getTilewireSegment(currentTilewire);
if (!currentSegment.isTrivial()) { if (!currentSegment.isTrivial()) {
if (currentSegment.getAnchorTileIndex() != tileIndex) continue; if (currentSegment.getAnchorTileIndex() != tileIndex)
continue;
segment_to_wire.emplace(currentSegment, wire_to_tilewire.size()); segment_to_wire.emplace(currentSegment, wire_to_tilewire.size());
} } else
else
trivial_to_wire.emplace(currentTilewire, wire_to_tilewire.size()); trivial_to_wire.emplace(currentTilewire, wire_to_tilewire.size());
wire_to_tilewire.push_back(currentTilewire); wire_to_tilewire.push_back(currentTilewire);
@ -141,7 +149,7 @@ std::vector<Tilewire> TorcInfo::construct_wire_to_tilewire(const Segments& segme
wire_to_tilewire.shrink_to_fit(); wire_to_tilewire.shrink_to_fit();
return wire_to_tilewire; return wire_to_tilewire;
} }
std::vector<DelayInfo> TorcInfo::construct_wire_to_delay(const std::vector<Tilewire>& wire_to_tilewire, const DDB &ddb) std::vector<DelayInfo> TorcInfo::construct_wire_to_delay(const std::vector<Tilewire> &wire_to_tilewire, const DDB &ddb)
{ {
std::vector<DelayInfo> wire_to_delay; std::vector<DelayInfo> wire_to_delay;
wire_to_delay.reserve(wire_to_tilewire.size()); wire_to_delay.reserve(wire_to_tilewire.size());
@ -155,32 +163,40 @@ std::vector<DelayInfo> TorcInfo::construct_wire_to_delay(const std::vector<Tilew
boost::cmatch what; boost::cmatch what;
ExtendedWireInfo ewi(ddb); ExtendedWireInfo ewi(ddb);
for (const auto &tw : wire_to_tilewire) for (const auto &tw : wire_to_tilewire) {
{
ewi.set(tw); ewi.set(tw);
DelayInfo d; DelayInfo d;
if (boost::regex_match(ewi.mWireName, what, re_124)) { if (boost::regex_match(ewi.mWireName, what, re_124)) {
switch (what.str(2)[0]) { switch (what.str(2)[0]) {
case '1': d.delay = 150; break; case '1':
case '2': d.delay = 170; break; d.delay = 150;
case '4': d.delay = 210; break; break;
case '6': d.delay = 210; break; case '2':
default: throw; 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]); std::string l(what[2]);
if (l == "H") d.delay = 360; if (l == "H")
else if (l == "VB") d.delay = 300; d.delay = 360;
else if (l == "V") d.delay = 350; else if (l == "VB")
else throw; d.delay = 300;
} else if (l == "V")
else if (boost::regex_match(ewi.mWireName, what, re_BYP)) { d.delay = 350;
else
throw;
} else if (boost::regex_match(ewi.mWireName, what, re_BYP)) {
d.delay = 190; d.delay = 190;
} } else if (boost::regex_match(ewi.mWireName, what, re_BYP_B)) {
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_FAN)) {
d.delay = 190; d.delay = 190;
} }
wire_to_delay.emplace_back(std::move(d)); wire_to_delay.emplace_back(std::move(d));
@ -188,7 +204,9 @@ std::vector<DelayInfo> TorcInfo::construct_wire_to_delay(const std::vector<Tilew
return wire_to_delay; return wire_to_delay;
} }
std::vector<Arc> TorcInfo::construct_pip_to_arc(const std::vector<Tilewire>& wire_to_tilewire, const DDB& ddb, std::vector<std::vector<int>> &wire_to_pips_uphill, std::vector<std::vector<int>> &wire_to_pips_downhill) std::vector<Arc> TorcInfo::construct_pip_to_arc(const std::vector<Tilewire> &wire_to_tilewire, const DDB &ddb,
std::vector<std::vector<int>> &wire_to_pips_uphill,
std::vector<std::vector<int>> &wire_to_pips_downhill)
{ {
const auto &tiles = ddb.getTiles(); const auto &tiles = ddb.getTiles();
@ -201,14 +219,18 @@ std::vector<Arc> TorcInfo::construct_pip_to_arc(const std::vector<Tilewire>& wir
ExtendedWireInfo ewi(ddb); ExtendedWireInfo ewi(ddb);
for (auto i = 0u; i < wire_to_tilewire.size(); ++i) { for (auto i = 0u; i < wire_to_tilewire.size(); ++i) {
const auto &tw = wire_to_tilewire[i]; const auto &tw = wire_to_tilewire[i];
if (tw.isUndefined()) continue; if (tw.isUndefined())
continue;
arcs.clear(); arcs.clear();
const auto& tileInfo = tiles.getTileInfo(tw.getTileIndex()); const auto &tileInfo = tiles.getTileInfo(tw.getTileIndex());
const auto tileTypeName = tiles.getTileTypeName(tileInfo.getTypeIndex()); 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&>(ddb).expandSegmentSinks(tw, arcs, DDB::eExpandDirectionNone, false /* inUseTied */, true /*inUseRegular */, true /* inUseIrregular */, !clb /* inUseRoutethrough */); const_cast<DDB &>(ddb).expandSegmentSinks(tw, arcs, DDB::eExpandDirectionNone, false /* inUseTied */,
true /*inUseRegular */, true /* inUseIrregular */,
!clb /* inUseRoutethrough */);
auto index = pip_to_arc.size(); auto index = pip_to_arc.size();
pip_to_arc.insert(pip_to_arc.end(), arcs.begin(), arcs.end()); pip_to_arc.insert(pip_to_arc.end(), arcs.begin(), arcs.end());
@ -219,7 +241,7 @@ std::vector<Arc> TorcInfo::construct_pip_to_arc(const std::vector<Tilewire>& wir
auto &pips = wire_to_pips_downhill[i]; auto &pips = wire_to_pips_downhill[i];
pips.reserve(arcs.size()); pips.reserve(arcs.size());
const bool clk_tile = boost::starts_with(tileTypeName, "CMT") || boost::starts_with(tileTypeName, "CLK"); 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 // Disable BUFG I0 -> O routethrough
if (clk_tile) { if (clk_tile) {
ewi.set(a.getSourceTilewire()); ewi.set(a.getSourceTilewire());
@ -240,27 +262,27 @@ std::vector<Arc> TorcInfo::construct_pip_to_arc(const std::vector<Tilewire>& wir
wire_to_pips_uphill.resize(wire_to_tilewire.size()); wire_to_pips_uphill.resize(wire_to_tilewire.size());
for (auto i = 0u; i < wire_to_tilewire.size(); ++i) { for (auto i = 0u; i < wire_to_tilewire.size(); ++i) {
const auto &tw = wire_to_tilewire[i]; const auto &tw = wire_to_tilewire[i];
if (tw.isUndefined()) continue; if (tw.isUndefined())
continue;
arcs.clear(); arcs.clear();
//const_cast<DDB&>(ddb).expandSegmentSources(tw, arcs, DDB::eExpandDirectionNone, false /* inUseTied */, true /*inUseRegular */, true /* inUseIrregular */, false /* inUseRoutethrough */); // const_cast<DDB&>(ddb).expandSegmentSources(tw, arcs, DDB::eExpandDirectionNone, false /* inUseTied */, true
// /*inUseRegular */, true /* inUseIrregular */, false /* inUseRoutethrough */);
auto &pips = wire_to_pips_uphill[i]; auto &pips = wire_to_pips_uphill[i];
pips.reserve(arcs.size()); pips.reserve(arcs.size());
for (const auto& a : arcs) for (const auto &a : arcs)
pips.push_back(arc_to_pip.at(a)); pips.push_back(arc_to_pip.at(a));
} }
return pip_to_arc; return pip_to_arc;
} }
std::vector<int> std::vector<int> construct_pip_to_dst_wire(const std::vector<Arc> &pip_to_arc)
construct_pip_to_dst_wire(const std::vector<Arc>& pip_to_arc)
{ {
std::vector<int> pip_to_wire; std::vector<int> pip_to_wire;
return pip_to_wire; return pip_to_wire;
} }
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
void IdString::initialize_arch(const BaseCtx *ctx) void IdString::initialize_arch(const BaseCtx *ctx)
@ -281,21 +303,21 @@ Arch::Arch(ArchArgs args) : args(args)
log_error("Unsupported XC7 chip type.\n"); log_error("Unsupported XC7 chip type.\n");
} }
// package_info = nullptr; // package_info = nullptr;
// for (int i = 0; i < chip_info->num_packages; i++) { // for (int i = 0; i < chip_info->num_packages; i++) {
// if (chip_info->packages_data[i].name.get() == args.package) { // if (chip_info->packages_data[i].name.get() == args.package) {
// package_info = &(chip_info->packages_data[i]); // package_info = &(chip_info->packages_data[i]);
// break; // break;
// } // }
// } // }
// if (package_info == nullptr) // if (package_info == nullptr)
// log_error("Unsupported package '%s'.\n", args.package.c_str()); // 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); bel_to_cell.resize(torc_info->num_bels);
wire_to_net.resize(torc_info->num_wires); wire_to_net.resize(torc_info->num_wires);
pip_to_net.resize(torc_info->num_pips); 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 // 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') { if (pin_name[0] == 'I' || pin_name[0] == 'O') {
switch (torc_info->bel_to_loc[bel.index].z) { switch (torc_info->bel_to_loc[bel.index].z) {
case 0: case 4: pin_name[0] = 'A'; break; case 0:
case 1: case 5: pin_name[0] = 'B'; break; case 4:
case 2: case 6: pin_name[0] = 'C'; break; pin_name[0] = 'A';
case 3: case 7: pin_name[0] = 'D'; break; break;
default: throw; 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); auto &tw = site.getPinTilewire(pin_name);
if (tw.isUndefined()) 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); ret.index = torc_info->tilewire_to_wire(tw);
// NPNR_ASSERT(bel != BelId()); // NPNR_ASSERT(bel != BelId());
// //
// int num_bel_wires = chip_info->bel_data[bel.index].num_bel_wires; // 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(); // const BelWirePOD *bel_wires = chip_info->bel_data[bel.index].bel_wires.get();
// //
// if (num_bel_wires < 7) { // if (num_bel_wires < 7) {
// for (int i = 0; i < num_bel_wires; i++) { // for (int i = 0; i < num_bel_wires; i++) {
// if (bel_wires[i].port == pin.index) { // if (bel_wires[i].port == pin.index) {
// ret.index = bel_wires[i].wire_index; // ret.index = bel_wires[i].wire_index;
// break; // break;
// } // }
// } // }
// } else { // } else {
// int b = 0, e = num_bel_wires - 1; // int b = 0, e = num_bel_wires - 1;
// while (b <= e) { // while (b <= e) {
// int i = (b + e) / 2; // int i = (b + e) / 2;
// if (bel_wires[i].port == pin.index) { // if (bel_wires[i].port == pin.index) {
// ret.index = bel_wires[i].wire_index; // ret.index = bel_wires[i].wire_index;
// break; // break;
// } // }
// if (bel_wires[i].port > pin.index) // if (bel_wires[i].port > pin.index)
// e = i - 1; // e = i - 1;
// else // else
// b = i + 1; // b = i + 1;
// } // }
// } // }
return ret; return ret;
} }
@ -476,8 +512,8 @@ WireId Arch::getWireByName(IdString name) const
wire_by_name[id(chip_info->wire_data[i].name.get())] = i; wire_by_name[id(chip_info->wire_data[i].name.get())] = i;
} }
//auto it = wire_by_name.find(name); // auto it = wire_by_name.find(name);
//if (it != wire_by_name.end()) // if (it != wire_by_name.end())
// ret.index = it->second; // ret.index = it->second;
return ret; return ret;
@ -486,38 +522,38 @@ WireId Arch::getWireByName(IdString name) const
IdString Arch::getWireType(WireId wire) const IdString Arch::getWireType(WireId wire) const
{ {
NPNR_ASSERT(wire != WireId()); NPNR_ASSERT(wire != WireId());
// switch (chip_info->wire_data[wire.index].type) { // switch (chip_info->wire_data[wire.index].type) {
// case WireInfoPOD::WIRE_TYPE_NONE: // case WireInfoPOD::WIRE_TYPE_NONE:
// return IdString(); // return IdString();
// case WireInfoPOD::WIRE_TYPE_GLB2LOCAL: // case WireInfoPOD::WIRE_TYPE_GLB2LOCAL:
// return id("GLB2LOCAL"); // return id("GLB2LOCAL");
// case WireInfoPOD::WIRE_TYPE_GLB_NETWK: // case WireInfoPOD::WIRE_TYPE_GLB_NETWK:
// return id("GLB_NETWK"); // return id("GLB_NETWK");
// case WireInfoPOD::WIRE_TYPE_LOCAL: // case WireInfoPOD::WIRE_TYPE_LOCAL:
// return id("LOCAL"); // return id("LOCAL");
// case WireInfoPOD::WIRE_TYPE_LUTFF_IN: // case WireInfoPOD::WIRE_TYPE_LUTFF_IN:
// return id("LUTFF_IN"); // return id("LUTFF_IN");
// case WireInfoPOD::WIRE_TYPE_LUTFF_IN_LUT: // case WireInfoPOD::WIRE_TYPE_LUTFF_IN_LUT:
// return id("LUTFF_IN_LUT"); // return id("LUTFF_IN_LUT");
// case WireInfoPOD::WIRE_TYPE_LUTFF_LOUT: // case WireInfoPOD::WIRE_TYPE_LUTFF_LOUT:
// return id("LUTFF_LOUT"); // return id("LUTFF_LOUT");
// case WireInfoPOD::WIRE_TYPE_LUTFF_OUT: // case WireInfoPOD::WIRE_TYPE_LUTFF_OUT:
// return id("LUTFF_OUT"); // return id("LUTFF_OUT");
// case WireInfoPOD::WIRE_TYPE_LUTFF_COUT: // case WireInfoPOD::WIRE_TYPE_LUTFF_COUT:
// return id("LUTFF_COUT"); // return id("LUTFF_COUT");
// case WireInfoPOD::WIRE_TYPE_LUTFF_GLOBAL: // case WireInfoPOD::WIRE_TYPE_LUTFF_GLOBAL:
// return id("LUTFF_GLOBAL"); // return id("LUTFF_GLOBAL");
// case WireInfoPOD::WIRE_TYPE_CARRY_IN_MUX: // case WireInfoPOD::WIRE_TYPE_CARRY_IN_MUX:
// return id("CARRY_IN_MUX"); // return id("CARRY_IN_MUX");
// case WireInfoPOD::WIRE_TYPE_SP4_V: // case WireInfoPOD::WIRE_TYPE_SP4_V:
// return id("SP4_V"); // return id("SP4_V");
// case WireInfoPOD::WIRE_TYPE_SP4_H: // case WireInfoPOD::WIRE_TYPE_SP4_H:
// return id("SP4_H"); // return id("SP4_H");
// case WireInfoPOD::WIRE_TYPE_SP12_V: // case WireInfoPOD::WIRE_TYPE_SP12_V:
// return id("SP12_V"); // return id("SP12_V");
// case WireInfoPOD::WIRE_TYPE_SP12_H: // case WireInfoPOD::WIRE_TYPE_SP12_H:
// return id("SP12_H"); // return id("SP12_H");
// } // }
return IdString(); return IdString();
} }
@ -566,23 +602,23 @@ IdString Arch::getPipName(PipId pip) const
BelId Arch::getPackagePinBel(const std::string &pin) const BelId Arch::getPackagePinBel(const std::string &pin) const
{ {
// for (int i = 0; i < package_info->num_pins; i++) { // for (int i = 0; i < package_info->num_pins; i++) {
// if (package_info->pins[i].name.get() == pin) { // if (package_info->pins[i].name.get() == pin) {
// BelId id; // BelId id;
// id.index = package_info->pins[i].bel_index; // id.index = package_info->pins[i].bel_index;
// return id; // return id;
// } // }
// } // }
return BelId(); return BelId();
} }
std::string Arch::getBelPackagePin(BelId bel) const std::string Arch::getBelPackagePin(BelId bel) const
{ {
// for (int i = 0; i < package_info->num_pins; i++) { // for (int i = 0; i < package_info->num_pins; i++) {
// if (package_info->pins[i].bel_index == bel.index) { // if (package_info->pins[i].bel_index == bel.index) {
// return std::string(package_info->pins[i].name.get()); // return std::string(package_info->pins[i].name.get());
// } // }
// } // }
return ""; return "";
} }
@ -719,16 +755,18 @@ std::vector<GroupId> Arch::getGroupGroups(GroupId group) const
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const { return false; }
{
return false;
}
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
bool Arch::place() { return placer1(getCtx(), Placer1Cfg(getCtx())); } 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<GraphicElement> Arch::getDecalGraphics(DecalId decal) const
bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) 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) if (fromPort.index >= id_I1.index && fromPort.index <= id_I6.index)
return toPort == id_O || toPort == id_OQ; return toPort == id_O || toPort == id_OQ;
} } else if (cell->type == id_BUFGCTRL) {
else if (cell->type == id_BUFGCTRL)
{
return true; return true;
} }
return false; return false;
@ -946,15 +981,13 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, Id
return TMG_COMB_INPUT; return TMG_COMB_INPUT;
} }
// TODO // TODO
//if (port == id_OMUX) // if (port == id_OMUX)
} } else if (cell->type == id_IOB33) {
else if (cell->type == id_IOB33) {
if (port == id_I) if (port == id_I)
return TMG_STARTPOINT; return TMG_STARTPOINT;
else if (port == id_O) else if (port == id_O)
return TMG_ENDPOINT; return TMG_ENDPOINT;
} } else if (cell->type == id_BUFGCTRL) {
else if (cell->type == id_BUFGCTRL) {
if (port == id_O) if (port == id_O)
return TMG_COMB_OUTPUT; return TMG_COMB_OUTPUT;
return TMG_COMB_INPUT; return TMG_COMB_INPUT;

View File

@ -27,8 +27,8 @@ using namespace torc::architecture;
using namespace torc::architecture::xilinx; using namespace torc::architecture::xilinx;
namespace std { namespace std {
template <> struct hash<Segments::SegmentReference> template <> struct hash<Segments::SegmentReference>
{ {
size_t operator()(const Segments::SegmentReference &s) const size_t operator()(const Segments::SegmentReference &s) const
{ {
size_t seed = 0; size_t seed = 0;
@ -36,24 +36,22 @@ namespace std {
boost::hash_combine(seed, hash<unsigned>()(s.getAnchorTileIndex())); boost::hash_combine(seed, hash<unsigned>()(s.getAnchorTileIndex()));
return seed; return seed;
} }
}; };
template <> struct equal_to<Segments::SegmentReference> template <> struct equal_to<Segments::SegmentReference>
{ {
bool operator()(const Segments::SegmentReference &lhs, const Segments::SegmentReference &rhs) const 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<Tilewire> template <> struct hash<Tilewire>
{ {
size_t operator()(const Tilewire& t) const size_t operator()(const Tilewire &t) const { return hash_value(t); }
{ };
return hash_value(t);
}
};
template <> struct hash<Arc> template <> struct hash<Arc>
{ {
size_t operator()(const Arc &a) const size_t operator()(const Arc &a) const
{ {
size_t seed = 0; size_t seed = 0;
@ -61,8 +59,8 @@ namespace std {
boost::hash_combine(seed, hash_value(a.getSinkTilewire())); boost::hash_combine(seed, hash_value(a.getSinkTilewire()));
return seed; return seed;
} }
}; };
} } // namespace std
NEXTPNR_NAMESPACE_BEGIN NEXTPNR_NAMESPACE_BEGIN
@ -270,21 +268,23 @@ NPNR_PACKED_STRUCT(struct ChipInfoPOD {
RelPtr<CellTimingPOD> cell_timing; RelPtr<CellTimingPOD> cell_timing;
}); });
struct Arch; struct Arch;
struct TorcInfo { struct TorcInfo
{
TorcInfo(Arch *ctx, const std::string &inDeviceName, const std::string &inPackageName); TorcInfo(Arch *ctx, const std::string &inDeviceName, const std::string &inPackageName);
std::unique_ptr<const DDB> ddb; std::unique_ptr<const DDB> ddb;
const Sites &sites; const Sites &sites;
const Tiles &tiles; const Tiles &tiles;
const Segments &segments; 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]; auto si = bel_to_site_index[index];
const auto &site = sites.getSite(si); const auto &site = sites.getSite(si);
return tiles.getTileInfo(site.getTileIndex()); 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]; auto si = bel_to_site_index[index];
return sites.getSite(si).getName(); return sites.getSite(si).getName();
} }
@ -309,8 +309,8 @@ struct TorcInfo {
const int num_bels; const int num_bels;
const std::vector<IdString> site_index_to_type; const std::vector<IdString> site_index_to_type;
const std::vector<Loc> bel_to_loc; const std::vector<Loc> bel_to_loc;
std::unordered_map<Segments::SegmentReference,int> segment_to_wire; std::unordered_map<Segments::SegmentReference, int> segment_to_wire;
std::unordered_map<Tilewire,int> trivial_to_wire; std::unordered_map<Tilewire, int> trivial_to_wire;
const std::vector<Tilewire> wire_to_tilewire; const std::vector<Tilewire> wire_to_tilewire;
const int num_wires; const int num_wires;
const std::vector<DelayInfo> wire_to_delay; const std::vector<DelayInfo> wire_to_delay;
@ -320,17 +320,23 @@ struct TorcInfo {
const int num_pips; const int num_pips;
std::vector<int> pip_to_dst_wire; std::vector<int> pip_to_dst_wire;
private: private:
static std::vector<SiteIndex> construct_bel_to_site_index(Arch *ctx, const Sites &sites); static std::vector<SiteIndex> construct_bel_to_site_index(Arch *ctx, const Sites &sites);
static std::vector<IdString> construct_site_index_to_type(Arch *ctx, const Sites &sites); static std::vector<IdString> construct_site_index_to_type(Arch *ctx, const Sites &sites);
static std::vector<Loc> construct_bel_to_loc(const Sites &sites, const Tiles &tiles, const int num_bels, const std::vector<IdString> &site_index_to_type); static std::vector<Loc> construct_bel_to_loc(const Sites &sites, const Tiles &tiles, const int num_bels,
static std::vector<Tilewire> construct_wire_to_tilewire(const Segments &segments, const Tiles &tiles, std::unordered_map<Segments::SegmentReference,int>& segment_to_wire, std::unordered_map<Tilewire,int>& trivial_to_wire); const std::vector<IdString> &site_index_to_type);
static std::vector<DelayInfo> construct_wire_to_delay(const std::vector<Tilewire>& wire_to_tilewire, const DDB &ddb); static std::vector<Tilewire>
static std::vector<Arc> construct_pip_to_arc(const std::vector<Tilewire>& wire_to_tilewire, const DDB& ddb, std::vector<std::vector<int>> &wire_to_pips_uphill, std::vector<std::vector<int>> &wire_to_pips_downhill); construct_wire_to_tilewire(const Segments &segments, const Tiles &tiles,
std::unordered_map<Segments::SegmentReference, int> &segment_to_wire,
std::unordered_map<Tilewire, int> &trivial_to_wire);
static std::vector<DelayInfo> construct_wire_to_delay(const std::vector<Tilewire> &wire_to_tilewire,
const DDB &ddb);
static std::vector<Arc> construct_pip_to_arc(const std::vector<Tilewire> &wire_to_tilewire, const DDB &ddb,
std::vector<std::vector<int>> &wire_to_pips_uphill,
std::vector<std::vector<int>> &wire_to_pips_downhill);
}; };
extern std::unique_ptr<const TorcInfo> torc_info; extern std::unique_ptr<const TorcInfo> torc_info;
/************************ End of chipdb section. ************************/ /************************ End of chipdb section. ************************/
struct BelIterator struct BelIterator
@ -486,11 +492,11 @@ struct Arch : BaseCtx
mutable std::unordered_map<IdString, int> pip_by_name; mutable std::unordered_map<IdString, int> pip_by_name;
mutable std::unordered_map<Loc, BelId> bel_by_loc; mutable std::unordered_map<Loc, BelId> bel_by_loc;
//std::vector<bool> bel_carry; // std::vector<bool> bel_carry;
std::vector<CellInfo *> bel_to_cell; std::vector<CellInfo *> bel_to_cell;
std::vector<NetInfo *> wire_to_net; std::vector<NetInfo *> wire_to_net;
std::vector<NetInfo *> pip_to_net; std::vector<NetInfo *> pip_to_net;
//std::vector<NetInfo *> switches_locked; // std::vector<NetInfo *> switches_locked;
ArchArgs args; ArchArgs args;
Arch(ArchArgs args); Arch(ArchArgs args);
@ -521,11 +527,24 @@ struct Arch : BaseCtx
name.reserve(name.size() + 2); name.reserve(name.size() + 2);
name += "_"; name += "_";
switch (torc_info->bel_to_loc[bel.index].z) { switch (torc_info->bel_to_loc[bel.index].z) {
case 0: case 4: name += 'A'; break; case 0:
case 1: case 5: name += 'B'; break; case 4:
case 2: case 6: name += 'C'; break; name += 'A';
case 3: case 7: name += 'D'; break; break;
default: throw; 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); return id(name);
@ -539,7 +558,7 @@ struct Arch : BaseCtx
NPNR_ASSERT(bel_to_cell[bel.index] == nullptr); NPNR_ASSERT(bel_to_cell[bel.index] == nullptr);
bel_to_cell[bel.index] = cell; 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->bel = bel;
cell->belStrength = strength; cell->belStrength = strength;
refreshUiBel(bel); refreshUiBel(bel);
@ -552,7 +571,7 @@ struct Arch : BaseCtx
bel_to_cell[bel.index]->bel = BelId(); bel_to_cell[bel.index]->bel = BelId();
bel_to_cell[bel.index]->belStrength = STRENGTH_NONE; bel_to_cell[bel.index]->belStrength = STRENGTH_NONE;
bel_to_cell[bel.index] = nullptr; bel_to_cell[bel.index] = nullptr;
//bel_carry[bel.index] = false; // bel_carry[bel.index] = false;
refreshUiBel(bel); refreshUiBel(bel);
} }
@ -582,10 +601,7 @@ struct Arch : BaseCtx
return range; return range;
} }
Loc getBelLocation(BelId bel) const Loc getBelLocation(BelId bel) const { return torc_info->bel_to_loc[bel.index]; }
{
return torc_info->bel_to_loc[bel.index];
}
BelId getBelByLocation(Loc loc) const; BelId getBelByLocation(Loc loc) const;
BelRange getBelsByTile(int x, int y) const; BelRange getBelsByTile(int x, int y) const;
@ -639,7 +655,7 @@ struct Arch : BaseCtx
auto pip = it->second.pip; auto pip = it->second.pip;
if (pip != PipId()) { if (pip != PipId()) {
pip_to_net[pip.index] = nullptr; 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); net_wires.erase(it);
@ -665,17 +681,14 @@ struct Arch : BaseCtx
return wire_to_net[wire.index]; return wire_to_net[wire.index];
} }
DelayInfo getWireDelay(WireId wire) const DelayInfo getWireDelay(WireId wire) const { return torc_info->wire_to_delay[wire.index]; }
{
return torc_info->wire_to_delay[wire.index];
}
BelPinRange getWireBelPins(WireId wire) const BelPinRange getWireBelPins(WireId wire) const
{ {
BelPinRange range; BelPinRange range;
//NPNR_ASSERT(wire != WireId()); // NPNR_ASSERT(wire != WireId());
//range.b.ptr = chip_info->wire_data[wire.index].bel_pins.get(); // 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; // range.e.ptr = range.b.ptr + chip_info->wire_data[wire.index].num_bel_pins;
throw; throw;
return range; return range;
} }
@ -696,10 +709,10 @@ struct Arch : BaseCtx
{ {
NPNR_ASSERT(pip != PipId()); NPNR_ASSERT(pip != PipId());
NPNR_ASSERT(pip_to_net[pip.index] == nullptr); 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; 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); WireId dst = getPipDstWire(pip);
NPNR_ASSERT(wire_to_net[dst.index] == nullptr); NPNR_ASSERT(wire_to_net[dst.index] == nullptr);
@ -714,7 +727,7 @@ struct Arch : BaseCtx
{ {
NPNR_ASSERT(pip != PipId()); NPNR_ASSERT(pip != PipId());
NPNR_ASSERT(pip_to_net[pip.index] != nullptr); 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); WireId dst = getPipDstWire(pip);
NPNR_ASSERT(wire_to_net[dst.index] != nullptr); 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]->wires.erase(dst);
pip_to_net[pip.index] = nullptr; 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); refreshUiPip(pip);
refreshUiWire(dst); refreshUiWire(dst);
} }
@ -730,25 +743,25 @@ struct Arch : BaseCtx
bool checkPipAvail(PipId pip) const bool checkPipAvail(PipId pip) const
{ {
NPNR_ASSERT(pip != PipId()); NPNR_ASSERT(pip != PipId());
//auto &pi = chip_info->pip_data[pip.index]; // auto &pi = chip_info->pip_data[pip.index];
//auto &si = chip_info->bits_info->switches[pi.switch_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; // return false;
//if (pi.flags & PipInfoPOD::FLAG_ROUTETHRU) { // if (pi.flags & PipInfoPOD::FLAG_ROUTETHRU) {
// NPNR_ASSERT(si.bel >= 0); // NPNR_ASSERT(si.bel >= 0);
// if (bel_to_cell[si.bel] != nullptr) // if (bel_to_cell[si.bel] != nullptr)
// return false; // return false;
//} //}
//if (pi.flags & PipInfoPOD::FLAG_NOCARRY) { // if (pi.flags & PipInfoPOD::FLAG_NOCARRY) {
// NPNR_ASSERT(si.bel >= 0); // NPNR_ASSERT(si.bel >= 0);
// if (bel_carry[si.bel]) // if (bel_carry[si.bel])
// return false; // return false;
//} //}
//return true; // return true;
return pip_to_net[pip.index] == nullptr; return pip_to_net[pip.index] == nullptr;
} }
@ -761,7 +774,7 @@ struct Arch : BaseCtx
NetInfo *getConflictingPipNet(PipId pip) const NetInfo *getConflictingPipNet(PipId pip) const
{ {
NPNR_ASSERT(pip != PipId()); 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]; return pip_to_net[pip.index];
} }
@ -816,9 +829,9 @@ struct Arch : BaseCtx
{ {
DelayInfo delay; DelayInfo delay;
NPNR_ASSERT(pip != PipId()); NPNR_ASSERT(pip != PipId());
//if (fast_part) // if (fast_part)
// delay.delay = chip_info->pip_data[pip.index].fast_delay; // delay.delay = chip_info->pip_data[pip.index].fast_delay;
//else // else
// delay.delay = chip_info->pip_data[pip.index].slow_delay; // delay.delay = chip_info->pip_data[pip.index].slow_delay;
return delay; return delay;
} }
@ -915,7 +928,7 @@ struct Arch : BaseCtx
bool isBelLocationValid(BelId bel) const; bool isBelLocationValid(BelId bel) const;
// Helper function for above // 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 // Assign architecure-specific arguments to nets and cells, which must be
@ -939,6 +952,6 @@ struct Arch : BaseCtx
float placer_constraintWeight = 10; float placer_constraintWeight = 10;
}; };
//void ice40DelayFuzzerMain(Context *ctx); // void ice40DelayFuzzerMain(Context *ctx);
NEXTPNR_NAMESPACE_END NEXTPNR_NAMESPACE_END

View File

@ -27,38 +27,38 @@
NEXTPNR_NAMESPACE_BEGIN 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; // bool dffs_exist = false, dffs_neg = false;
// const NetInfo *cen = nullptr, *clk = nullptr, *sr = nullptr; // const NetInfo *cen = nullptr, *clk = nullptr, *sr = nullptr;
// //
// for (auto cell : boost::make_iterator_range(it, it+size)) { // for (auto cell : boost::make_iterator_range(it, it+size)) {
// NPNR_ASSERT(cell->belType == id_ICESTORM_LC); // NPNR_ASSERT(cell->belType == id_ICESTORM_LC);
// if (cell->lcInfo.dffEnable) { // if (cell->lcInfo.dffEnable) {
// if (!dffs_exist) { // if (!dffs_exist) {
// dffs_exist = true; // dffs_exist = true;
// cen = cell->lcInfo.cen; // cen = cell->lcInfo.cen;
// clk = cell->lcInfo.clk; // clk = cell->lcInfo.clk;
// sr = cell->lcInfo.sr; // sr = cell->lcInfo.sr;
// //
// if (cell->lcInfo.negClk) { // if (cell->lcInfo.negClk) {
// dffs_neg = true; // dffs_neg = true;
// } // }
// } else { // } else {
// if (cen != cell->lcInfo.cen) // if (cen != cell->lcInfo.cen)
// return false; // return false;
// if (clk != cell->lcInfo.clk) // if (clk != cell->lcInfo.clk)
// return false; // return false;
// if (sr != cell->lcInfo.sr) // if (sr != cell->lcInfo.sr)
// return false; // return false;
// if (dffs_neg != cell->lcInfo.negClk) // if (dffs_neg != cell->lcInfo.negClk)
// return false; // return false;
// } // }
// } // }
// locals_count += cell->lcInfo.inputCount; // locals_count += cell->lcInfo.inputCount;
// } // }
// //
// return locals_count <= 32; // return locals_count <= 32;
return true; return true;
} }
@ -85,70 +85,70 @@ bool Arch::isBelLocationValid(BelId bel) const
bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const
{ {
// if (cell->type == id_ICESTORM_LC) { // if (cell->type == id_ICESTORM_LC) {
// NPNR_ASSERT(getBelType(bel) == id_ICESTORM_LC); // NPNR_ASSERT(getBelType(bel) == id_ICESTORM_LC);
// //
// std::array<const CellInfo *, 8> bel_cells; // std::array<const CellInfo *, 8> bel_cells;
// size_t num_cells = 0; // size_t num_cells = 0;
// //
// Loc bel_loc = getBelLocation(bel); // Loc bel_loc = getBelLocation(bel);
// for (auto bel_other : getBelsByTile(bel_loc.x, bel_loc.y)) { // for (auto bel_other : getBelsByTile(bel_loc.x, bel_loc.y)) {
// CellInfo *ci_other = getBoundBelCell(bel_other); // CellInfo *ci_other = getBoundBelCell(bel_other);
// if (ci_other != nullptr && bel_other != bel) // if (ci_other != nullptr && bel_other != bel)
// bel_cells[num_cells++] = ci_other; // bel_cells[num_cells++] = ci_other;
// } // }
// //
// bel_cells[num_cells++] = cell; // bel_cells[num_cells++] = cell;
// return logicCellsCompatible(bel_cells.data(), num_cells); // return logicCellsCompatible(bel_cells.data(), num_cells);
// } else if (cell->type == id_SB_IO) { // } else if (cell->type == id_SB_IO) {
// // Do not allow placement of input SB_IOs on blocks where there a PLL is outputting to. // // 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 // // Find shared PLL by looking for driving bel siblings from D_IN_0
// // that are a PLL clock output. // // that are a PLL clock output.
// auto wire = getBelPinWire(bel, id_D_IN_0); // auto wire = getBelPinWire(bel, id_D_IN_0);
// IdString pll_bel_pin; // IdString pll_bel_pin;
// BelId pll_bel; // BelId pll_bel;
// for (auto pin : getWireBelPins(wire)) { // for (auto pin : getWireBelPins(wire)) {
// if (pin.pin == id_PLLOUT_A || pin.pin == id_PLLOUT_B) { // if (pin.pin == id_PLLOUT_A || pin.pin == id_PLLOUT_B) {
// pll_bel = pin.bel; // pll_bel = pin.bel;
// pll_bel_pin = pin.pin; // pll_bel_pin = pin.pin;
// break; // break;
// } // }
// } // }
// // Is there a PLL that shares this IO buffer? // // Is there a PLL that shares this IO buffer?
// if (pll_bel.index != -1) { // if (pll_bel.index != -1) {
// auto pll_cell = getBoundBelCell(pll_bel); // auto pll_cell = getBoundBelCell(pll_bel);
// // Is a PLL placed in this PLL bel? // // Is a PLL placed in this PLL bel?
// if (pll_cell != nullptr) { // if (pll_cell != nullptr) {
// // Is the shared port driving a net? // // Is the shared port driving a net?
// auto pi = pll_cell->ports[pll_bel_pin]; // auto pi = pll_cell->ports[pll_bel_pin];
// if (pi.net != nullptr) { // if (pi.net != nullptr) {
// // Are we perhaps a PAD INPUT Bel that can be placed here? // // Are we perhaps a PAD INPUT Bel that can be placed here?
// if (pll_cell->attrs[id("BEL_PAD_INPUT")] == getBelName(bel).str(this)) { // if (pll_cell->attrs[id("BEL_PAD_INPUT")] == getBelName(bel).str(this)) {
// return true; // return true;
// } // }
// return false; // return false;
// } // }
// } // }
// } // }
// return getBelPackagePin(bel) != ""; // return getBelPackagePin(bel) != "";
// } else if (cell->type == id_SB_GB) { // } else if (cell->type == id_SB_GB) {
// NPNR_ASSERT(cell->ports.at(id_GLOBAL_BUFFER_OUTPUT).net != nullptr); // NPNR_ASSERT(cell->ports.at(id_GLOBAL_BUFFER_OUTPUT).net != nullptr);
// const NetInfo *net = cell->ports.at(id_GLOBAL_BUFFER_OUTPUT).net; // const NetInfo *net = cell->ports.at(id_GLOBAL_BUFFER_OUTPUT).net;
// IdString glb_net = getWireName(getBelPinWire(bel, id_GLOBAL_BUFFER_OUTPUT)); // IdString glb_net = getWireName(getBelPinWire(bel, id_GLOBAL_BUFFER_OUTPUT));
// int glb_id = std::stoi(std::string("") + glb_net.str(this).back()); // int glb_id = std::stoi(std::string("") + glb_net.str(this).back());
// if (net->is_reset && net->is_enable) // if (net->is_reset && net->is_enable)
// return false; // return false;
// else if (net->is_reset) // else if (net->is_reset)
// return (glb_id % 2) == 0; // return (glb_id % 2) == 0;
// else if (net->is_enable) // else if (net->is_enable)
// return (glb_id % 2) == 1; // return (glb_id % 2) == 1;
// else // else
// return true; // return true;
// } else { // } else {
// // TODO: IO cell clock checks // // TODO: IO cell clock checks
return true; return true;
// } // }
} }
NEXTPNR_NAMESPACE_END NEXTPNR_NAMESPACE_END

View File

@ -1,6 +1,6 @@
set_io led1 99 COMP "led1" LOCATE = SITE "M14" LEVEL 1;
set_io led2 98 COMP "led2" LOCATE = SITE "M15" LEVEL 1;
set_io led3 97 COMP "led3" LOCATE = SITE "G14" LEVEL 1;
set_io led4 96 COMP "led4" LOCATE = SITE "D18" LEVEL 1;
set_io led5 95 COMP "clki" LOCATE = SITE "L16" LEVEL 1;
set_io clki 21

View File

@ -76,180 +76,180 @@ std::unique_ptr<CellInfo> create_xc7_cell(Context *ctx, IdString type, std::stri
new_cell->params[ctx->id("NEG_TRIGGER")] = "0"; new_cell->params[ctx->id("NEG_TRIGGER")] = "0";
new_cell->params[ctx->id("IOSTANDARD")] = "SB_LVCMOS"; new_cell->params[ctx->id("IOSTANDARD")] = "SB_LVCMOS";
// add_port(ctx, new_cell.get(), "PACKAGE_PIN", PORT_INOUT); // 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(), "LATCH_INPUT_VALUE", PORT_IN);
// add_port(ctx, new_cell.get(), "CLOCK_ENABLE", 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(), "INPUT_CLK", PORT_IN);
// add_port(ctx, new_cell.get(), "OUTPUT_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(), "OUTPUT_ENABLE", PORT_IN);
// add_port(ctx, new_cell.get(), "D_OUT_0", 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_OUT_1", PORT_IN);
// //
// add_port(ctx, new_cell.get(), "D_IN_0", PORT_OUT); // 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(), "D_IN_1", PORT_OUT);
add_port(ctx, new_cell.get(), "I", PORT_OUT); add_port(ctx, new_cell.get(), "I", PORT_OUT);
add_port(ctx, new_cell.get(), "O", PORT_IN); add_port(ctx, new_cell.get(), "O", PORT_IN);
// } else if (type == ctx->id("ICESTORM_RAM")) { // } else if (type == ctx->id("ICESTORM_RAM")) {
// new_cell->params[ctx->id("NEG_CLK_W")] = "0"; // new_cell->params[ctx->id("NEG_CLK_W")] = "0";
// new_cell->params[ctx->id("NEG_CLK_R")] = "0"; // new_cell->params[ctx->id("NEG_CLK_R")] = "0";
// new_cell->params[ctx->id("WRITE_MODE")] = "0"; // new_cell->params[ctx->id("WRITE_MODE")] = "0";
// new_cell->params[ctx->id("READ_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(), "RCLK", PORT_IN);
// add_port(ctx, new_cell.get(), "RCLKE", 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(), "RE", PORT_IN);
// //
// add_port(ctx, new_cell.get(), "WCLK", 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(), "WCLKE", PORT_IN);
// add_port(ctx, new_cell.get(), "WE", PORT_IN); // add_port(ctx, new_cell.get(), "WE", PORT_IN);
// //
// for (int i = 0; i < 16; i++) { // 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(), "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(), "MASK_" + std::to_string(i), PORT_IN);
// add_port(ctx, new_cell.get(), "RDATA_" + std::to_string(i), PORT_OUT); // add_port(ctx, new_cell.get(), "RDATA_" + std::to_string(i), PORT_OUT);
// } // }
// //
// for (int i = 0; i < 11; i++) { // 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(), "RADDR_" + std::to_string(i), PORT_IN);
// add_port(ctx, new_cell.get(), "WADDR_" + 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")) { // } else if (type == ctx->id("ICESTORM_LFOSC")) {
// add_port(ctx, new_cell.get(), "CLKLFEN", PORT_IN); // add_port(ctx, new_cell.get(), "CLKLFEN", PORT_IN);
// add_port(ctx, new_cell.get(), "CLKLFPU", 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", PORT_OUT);
// add_port(ctx, new_cell.get(), "CLKLF_FABRIC", PORT_OUT); // add_port(ctx, new_cell.get(), "CLKLF_FABRIC", PORT_OUT);
// } else if (type == ctx->id("ICESTORM_HFOSC")) { // } else if (type == ctx->id("ICESTORM_HFOSC")) {
// new_cell->params[ctx->id("CLKHF_DIV")] = "0b00"; // new_cell->params[ctx->id("CLKHF_DIV")] = "0b00";
// new_cell->params[ctx->id("TRIM_EN")] = "0b0"; // new_cell->params[ctx->id("TRIM_EN")] = "0b0";
// //
// add_port(ctx, new_cell.get(), "CLKHFEN", PORT_IN); // add_port(ctx, new_cell.get(), "CLKHFEN", PORT_IN);
// add_port(ctx, new_cell.get(), "CLKHFPU", 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", PORT_OUT);
// add_port(ctx, new_cell.get(), "CLKHF_FABRIC", PORT_OUT); // add_port(ctx, new_cell.get(), "CLKHF_FABRIC", PORT_OUT);
// for (int i = 0; i < 10; i++) // for (int i = 0; i < 10; i++)
// add_port(ctx, new_cell.get(), "TRIM" + std::to_string(i), PORT_IN); // add_port(ctx, new_cell.get(), "TRIM" + std::to_string(i), PORT_IN);
} else if (type == id_BUFGCTRL) { } else if (type == id_BUFGCTRL) {
add_port(ctx, new_cell.get(), "I0", PORT_IN); add_port(ctx, new_cell.get(), "I0", PORT_IN);
add_port(ctx, new_cell.get(), "O", PORT_OUT); add_port(ctx, new_cell.get(), "O", PORT_OUT);
// } else if (type == ctx->id("ICESTORM_SPRAM")) { // } else if (type == ctx->id("ICESTORM_SPRAM")) {
// add_port(ctx, new_cell.get(), "WREN", PORT_IN); // add_port(ctx, new_cell.get(), "WREN", PORT_IN);
// add_port(ctx, new_cell.get(), "CHIPSELECT", 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(), "CLOCK", PORT_IN);
// add_port(ctx, new_cell.get(), "STANDBY", 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(), "SLEEP", PORT_IN);
// add_port(ctx, new_cell.get(), "POWEROFF", PORT_IN); // add_port(ctx, new_cell.get(), "POWEROFF", PORT_IN);
// //
// for (int i = 0; i < 16; i++) { // 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(), "DATAIN_" + std::to_string(i), PORT_IN);
// add_port(ctx, new_cell.get(), "DATAOUT_" + std::to_string(i), PORT_OUT); // add_port(ctx, new_cell.get(), "DATAOUT_" + std::to_string(i), PORT_OUT);
// } // }
// for (int i = 0; i < 14; i++) { // for (int i = 0; i < 14; i++) {
// add_port(ctx, new_cell.get(), "ADDRESS_" + std::to_string(i), PORT_IN); // add_port(ctx, new_cell.get(), "ADDRESS_" + std::to_string(i), PORT_IN);
// } // }
// for (int i = 0; i < 4; i++) { // for (int i = 0; i < 4; i++) {
// add_port(ctx, new_cell.get(), "MASKWREN_" + std::to_string(i), PORT_IN); // add_port(ctx, new_cell.get(), "MASKWREN_" + std::to_string(i), PORT_IN);
// } // }
// } else if (type == ctx->id("ICESTORM_DSP")) { // } else if (type == ctx->id("ICESTORM_DSP")) {
// new_cell->params[ctx->id("NEG_TRIGGER")] = "0"; // new_cell->params[ctx->id("NEG_TRIGGER")] = "0";
// //
// new_cell->params[ctx->id("C_REG")] = "0"; // new_cell->params[ctx->id("C_REG")] = "0";
// new_cell->params[ctx->id("A_REG")] = "0"; // new_cell->params[ctx->id("A_REG")] = "0";
// new_cell->params[ctx->id("B_REG")] = "0"; // new_cell->params[ctx->id("B_REG")] = "0";
// new_cell->params[ctx->id("D_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("TOP_8x8_MULT_REG")] = "0";
// new_cell->params[ctx->id("BOT_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_REG1")] = "0";
// new_cell->params[ctx->id("PIPELINE_16x16_MULT_REG2")] = "0"; // new_cell->params[ctx->id("PIPELINE_16x16_MULT_REG2")] = "0";
// //
// new_cell->params[ctx->id("TOPOUTPUT_SELECT")] = "0"; // new_cell->params[ctx->id("TOPOUTPUT_SELECT")] = "0";
// new_cell->params[ctx->id("TOPADDSUB_LOWERINPUT")] = "0"; // new_cell->params[ctx->id("TOPADDSUB_LOWERINPUT")] = "0";
// new_cell->params[ctx->id("TOPADDSUB_UPPERINPUT")] = "0"; // new_cell->params[ctx->id("TOPADDSUB_UPPERINPUT")] = "0";
// new_cell->params[ctx->id("TOPADDSUB_CARRYSELECT")] = "0"; // new_cell->params[ctx->id("TOPADDSUB_CARRYSELECT")] = "0";
// //
// new_cell->params[ctx->id("BOTOUTPUT_SELECT")] = "0"; // new_cell->params[ctx->id("BOTOUTPUT_SELECT")] = "0";
// new_cell->params[ctx->id("BOTADDSUB_LOWERINPUT")] = "0"; // new_cell->params[ctx->id("BOTADDSUB_LOWERINPUT")] = "0";
// new_cell->params[ctx->id("BOTADDSUB_UPPERINPUT")] = "0"; // new_cell->params[ctx->id("BOTADDSUB_UPPERINPUT")] = "0";
// new_cell->params[ctx->id("BOTADDSUB_CARRYSELECT")] = "0"; // new_cell->params[ctx->id("BOTADDSUB_CARRYSELECT")] = "0";
// //
// new_cell->params[ctx->id("MODE_8x8")] = "0"; // new_cell->params[ctx->id("MODE_8x8")] = "0";
// new_cell->params[ctx->id("A_SIGNED")] = "0"; // new_cell->params[ctx->id("A_SIGNED")] = "0";
// new_cell->params[ctx->id("B_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(), "CLK", PORT_IN);
// add_port(ctx, new_cell.get(), "CE", PORT_IN); // add_port(ctx, new_cell.get(), "CE", PORT_IN);
// for (int i = 0; i < 16; i++) { // 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(), "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(), "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(), "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(), "D_" + std::to_string(i), PORT_IN);
// } // }
// add_port(ctx, new_cell.get(), "AHOLD", 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(), "BHOLD", PORT_IN);
// add_port(ctx, new_cell.get(), "CHOLD", 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(), "DHOLD", PORT_IN);
// //
// add_port(ctx, new_cell.get(), "IRSTTOP", 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(), "IRSTBOT", PORT_IN);
// add_port(ctx, new_cell.get(), "ORSTTOP", 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(), "ORSTBOT", PORT_IN);
// //
// add_port(ctx, new_cell.get(), "OLOADTOP", 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(), "OLOADBOT", PORT_IN);
// //
// add_port(ctx, new_cell.get(), "ADDSUBTOP", 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(), "ADDSUBBOT", PORT_IN);
// //
// add_port(ctx, new_cell.get(), "OHOLDTOP", 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(), "OHOLDBOT", PORT_IN);
// //
// add_port(ctx, new_cell.get(), "CI", 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(), "ACCUMCI", PORT_IN);
// add_port(ctx, new_cell.get(), "SIGNEXTIN", PORT_IN); // add_port(ctx, new_cell.get(), "SIGNEXTIN", PORT_IN);
// //
// for (int i = 0; i < 32; i++) { // 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(), "O_" + std::to_string(i), PORT_OUT);
// } // }
// //
// add_port(ctx, new_cell.get(), "CO", 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(), "ACCUMCO", PORT_OUT);
// add_port(ctx, new_cell.get(), "SIGNEXTOUT", PORT_OUT); // add_port(ctx, new_cell.get(), "SIGNEXTOUT", PORT_OUT);
// //
// } else if (type == ctx->id("ICESTORM_PLL")) { // } else if (type == ctx->id("ICESTORM_PLL")) {
// new_cell->params[ctx->id("DELAY_ADJMODE_FB")] = "0"; // new_cell->params[ctx->id("DELAY_ADJMODE_FB")] = "0";
// new_cell->params[ctx->id("DELAY_ADJMODE_REL")] = "0"; // new_cell->params[ctx->id("DELAY_ADJMODE_REL")] = "0";
// //
// new_cell->params[ctx->id("DIVF")] = "0"; // new_cell->params[ctx->id("DIVF")] = "0";
// new_cell->params[ctx->id("DIVQ")] = "0"; // new_cell->params[ctx->id("DIVQ")] = "0";
// new_cell->params[ctx->id("DIVR")] = "0"; // new_cell->params[ctx->id("DIVR")] = "0";
// //
// new_cell->params[ctx->id("FDA_FEEDBACK")] = "0"; // new_cell->params[ctx->id("FDA_FEEDBACK")] = "0";
// new_cell->params[ctx->id("FDA_RELATIVE")] = "0"; // new_cell->params[ctx->id("FDA_RELATIVE")] = "0";
// new_cell->params[ctx->id("FEEDBACK_PATH")] = "0"; // new_cell->params[ctx->id("FEEDBACK_PATH")] = "0";
// new_cell->params[ctx->id("FILTER_RANGE")] = "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_A")] = "0";
// new_cell->params[ctx->id("PLLOUT_SELECT_B")] = "0"; // new_cell->params[ctx->id("PLLOUT_SELECT_B")] = "0";
// //
// new_cell->params[ctx->id("PLLTYPE")] = "0"; // new_cell->params[ctx->id("PLLTYPE")] = "0";
// new_cell->params[ctx->id("SHIFTREG_DIVMODE")] = "0"; // new_cell->params[ctx->id("SHIFTREG_DIVMODE")] = "0";
// new_cell->params[ctx->id("TEST_MODE")] = "0"; // new_cell->params[ctx->id("TEST_MODE")] = "0";
// //
// add_port(ctx, new_cell.get(), "BYPASS", PORT_IN); // add_port(ctx, new_cell.get(), "BYPASS", PORT_IN);
// add_port(ctx, new_cell.get(), "DYNAMICDELAY", 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(), "EXTFEEDBACK", PORT_IN);
// add_port(ctx, new_cell.get(), "LATCHINPUTVALUE", 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(), "REFERENCECLK", PORT_IN);
// add_port(ctx, new_cell.get(), "RESETB", 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(), "SCLK", PORT_IN);
// add_port(ctx, new_cell.get(), "SDI", 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(), "SDI", PORT_OUT);
// //
// add_port(ctx, new_cell.get(), "LOCK", 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_A", PORT_OUT);
// add_port(ctx, new_cell.get(), "PLLOUT_B", PORT_OUT); // add_port(ctx, new_cell.get(), "PLLOUT_B", PORT_OUT);
} else { } else {
log_error("unable to create XC7 cell of type %s\n", type.c_str(ctx)); log_error("unable to create XC7 cell of type %s\n", type.c_str(ctx));
} }

View File

@ -30,7 +30,11 @@ NEXTPNR_NAMESPACE_BEGIN
std::unique_ptr<CellInfo> create_xc7_cell(Context *ctx, IdString type, std::string name = ""); std::unique_ptr<CellInfo> create_xc7_cell(Context *ctx, IdString type, std::string name = "");
// Return true if a cell is a LUT // 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 // Return true if a cell is a flipflop
inline bool is_ff(const BaseCtx *ctx, const CellInfo *cell) inline bool is_ff(const BaseCtx *ctx, const CellInfo *cell)

View File

@ -97,7 +97,8 @@ class ChainConstrainer
} }
tile.push_back(cell); tile.push_back(cell);
chains.back().cells.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) { if (split_chain) {
CellInfo *passout = make_carry_pass_out(cell->ports.at(ctx->id("COUT"))); CellInfo *passout = make_carry_pass_out(cell->ports.at(ctx->id("COUT")));
tile.pop_back(); tile.pop_back();

View File

@ -27,75 +27,75 @@ NEXTPNR_NAMESPACE_BEGIN
void ice40DelayFuzzerMain(Context *ctx) void ice40DelayFuzzerMain(Context *ctx)
{ {
// std::vector<WireId> srcWires, dstWires; // std::vector<WireId> srcWires, dstWires;
// //
// for (int i = 0; i < ctx->chip_info->num_wires; i++) { // for (int i = 0; i < ctx->chip_info->num_wires; i++) {
// WireId wire; // WireId wire;
// wire.index = i; // wire.index = i;
// //
// switch (ctx->chip_info->wire_data[i].type) { // switch (ctx->chip_info->wire_data[i].type) {
// case WireInfoPOD::WIRE_TYPE_LUTFF_OUT: // case WireInfoPOD::WIRE_TYPE_LUTFF_OUT:
// srcWires.push_back(wire); // srcWires.push_back(wire);
// break; // break;
// //
// case WireInfoPOD::WIRE_TYPE_LUTFF_IN_LUT: // case WireInfoPOD::WIRE_TYPE_LUTFF_IN_LUT:
// dstWires.push_back(wire); // dstWires.push_back(wire);
// break; // break;
// //
// default: // default:
// break; // break;
// } // }
// } // }
// //
// ctx->shuffle(srcWires); // ctx->shuffle(srcWires);
// ctx->shuffle(dstWires); // ctx->shuffle(dstWires);
// //
// int index = 0; // int index = 0;
// int cnt = 0; // int cnt = 0;
// //
// while (cnt < NUM_FUZZ_ROUTES) { // while (cnt < NUM_FUZZ_ROUTES) {
// if (index >= int(srcWires.size()) || index >= int(dstWires.size())) { // if (index >= int(srcWires.size()) || index >= int(dstWires.size())) {
// index = 0; // index = 0;
// ctx->shuffle(srcWires); // ctx->shuffle(srcWires);
// ctx->shuffle(dstWires); // ctx->shuffle(dstWires);
// } // }
// //
// WireId src = srcWires[index]; // WireId src = srcWires[index];
// WireId dst = dstWires[index++]; // WireId dst = dstWires[index++];
// std::unordered_map<WireId, PipId> route; // std::unordered_map<WireId, PipId> route;
// //
//#if NUM_FUZZ_ROUTES <= 1000 //#if NUM_FUZZ_ROUTES <= 1000
// if (!ctx->getActualRouteDelay(src, dst, nullptr, &route, false)) // if (!ctx->getActualRouteDelay(src, dst, nullptr, &route, false))
// continue; // continue;
//#else //#else
// if (!ctx->getActualRouteDelay(src, dst, nullptr, &route, true)) // if (!ctx->getActualRouteDelay(src, dst, nullptr, &route, true))
// continue; // continue;
//#endif //#endif
// //
// WireId cursor = dst; // WireId cursor = dst;
// delay_t delay = 0; // delay_t delay = 0;
// //
// while (1) { // while (1) {
// delay += ctx->getWireDelay(cursor).maxDelay(); // delay += ctx->getWireDelay(cursor).maxDelay();
// //
// printf("%s %d %d %s %s %d %d\n", cursor == dst ? "dst" : "src", // 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), // 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), // ctx->getWireType(cursor).c_str(ctx), ctx->getWireName(cursor).c_str(ctx), int(delay),
// int(ctx->estimateDelay(cursor, dst))); // int(ctx->estimateDelay(cursor, dst)));
// //
// if (cursor == src) // if (cursor == src)
// break; // break;
// //
// PipId pip = route.at(cursor); // PipId pip = route.at(cursor);
// delay += ctx->getPipDelay(pip).maxDelay(); // delay += ctx->getPipDelay(pip).maxDelay();
// cursor = ctx->getPipSrcWire(pip); // cursor = ctx->getPipSrcWire(pip);
// } // }
// //
// cnt++; // cnt++;
// //
// if (cnt % 100 == 0) // if (cnt % 100 == 0)
// fprintf(stderr, "Fuzzed %d arcs.\n", cnt); // fprintf(stderr, "Fuzzed %d arcs.\n", cnt);
// } // }
} }
delay_t Arch::estimateDelay(WireId src, WireId dst) const delay_t Arch::estimateDelay(WireId src, WireId dst) const

View File

@ -52,18 +52,18 @@ po::options_description Xc7CommandHandler::getArchOptions()
{ {
po::options_description specific("Architecture specific options"); po::options_description specific("Architecture specific options");
specific.add_options()("xc7z020", "set device type to xc7z020"); specific.add_options()("xc7z020", "set device type to xc7z020");
// specific.add_options()("package", po::value<std::string>(), "set device package"); // specific.add_options()("package", po::value<std::string>(), "set device package");
specific.add_options()("pcf", po::value<std::string>(), "PCF constraints file to ingest"); specific.add_options()("pcf", po::value<std::string>(), "PCF constraints file to ingest");
specific.add_options()("xdl", po::value<std::string>(), "XDL file to write"); specific.add_options()("xdl", po::value<std::string>(), "XDL file to write");
// specific.add_options()("tmfuzz", "run path delay estimate fuzzer"); // specific.add_options()("tmfuzz", "run path delay estimate fuzzer");
return specific; return specific;
} }
void Xc7CommandHandler::validate() void Xc7CommandHandler::validate()
{ {
conflicting_options(vm, "read", "json"); conflicting_options(vm, "read", "json");
// if ((vm.count("lp384") + vm.count("lp1k") + vm.count("lp8k") + vm.count("hx1k") + vm.count("hx8k") + // if ((vm.count("lp384") + vm.count("lp1k") + vm.count("lp8k") + vm.count("hx1k") + vm.count("hx8k") +
// vm.count("up5k")) > 1) // vm.count("up5k")) > 1)
// log_error("Only one device type can be set\n"); // log_error("Only one device type can be set\n");
} }
void Xc7CommandHandler::customAfterLoad(Context *ctx) void Xc7CommandHandler::customAfterLoad(Context *ctx)
@ -86,8 +86,8 @@ void Xc7CommandHandler::customBitstream(Context *ctx)
void Xc7CommandHandler::setupArchContext(Context *ctx) void Xc7CommandHandler::setupArchContext(Context *ctx)
{ {
// if (vm.count("tmfuzz")) // if (vm.count("tmfuzz"))
// ice40DelayFuzzerMain(ctx); // ice40DelayFuzzerMain(ctx);
} }
std::unique_ptr<Context> Xc7CommandHandler::createContext() std::unique_ptr<Context> Xc7CommandHandler::createContext()

View File

@ -96,8 +96,7 @@ static void pack_nonlut_ffs(Context *ctx)
for (auto cell : sorted(ctx->cells)) { for (auto cell : sorted(ctx->cells)) {
CellInfo *ci = cell.second; CellInfo *ci = cell.second;
if (is_ff(ctx, ci)) { if (is_ff(ctx, ci)) {
std::unique_ptr<CellInfo> packed = std::unique_ptr<CellInfo> packed = create_xc7_cell(ctx, ctx->id("XC7_LC"), ci->name.str(ctx) + "_DFFLC");
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())); std::copy(ci->attrs.begin(), ci->attrs.end(), std::inserter(packed->attrs, packed->attrs.begin()));
if (ctx->verbose) if (ctx->verbose)
log_info("packed cell %s into %s\n", ci->name.c_str(ctx), packed->name.c_str(ctx)); 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 { } else {
// Create a IOBUF buffer // Create a IOBUF buffer
std::unique_ptr<CellInfo> ice_cell = std::unique_ptr<CellInfo> ice_cell = create_xc7_cell(ctx, ctx->id("IOBUF"), ci->name.str(ctx) + "$iob");
create_xc7_cell(ctx, ctx->id("IOBUF"), ci->name.str(ctx) + "$iob");
nxio_to_sb(ctx, ci, ice_cell.get()); nxio_to_sb(ctx, ci, ice_cell.get());
new_cells.push_back(std::move(ice_cell)); new_cells.push_back(std::move(ice_cell));
sb = new_cells.back().get(); sb = new_cells.back().get();
@ -582,8 +580,8 @@ static std::unique_ptr<CellInfo> spliceLUT(Context *ctx, CellInfo *ci, IdString
NPNR_ASSERT(port.net != nullptr); NPNR_ASSERT(port.net != nullptr);
// Create pass-through LUT. // Create pass-through LUT.
std::unique_ptr<CellInfo> pt = create_xc7_cell(ctx, ctx->id("XC7_LC"), std::unique_ptr<CellInfo> pt =
ci->name.str(ctx) + "$nextpnr_" + portId.str(ctx) + "_lut_through"); 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 pt->params[ctx->id("INIT")] = "65280"; // output is always I3
// Create LUT output net. // 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 // Now, constrain all LUTs on the output of the signal to be at
// the correct Bel relative to the PLL Bel. // the correct Bel relative to the PLL Bel.
//int x = ctx->chip_info->wire_data[pll_out_wire.index].x; // 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 y = ctx->chip_info->wire_data[pll_out_wire.index].y;
//int z = 0; // int z = 0;
//for (const auto &user : port.net->users) { // for (const auto &user : port.net->users) {
// NPNR_ASSERT(user.cell != nullptr); // NPNR_ASSERT(user.cell != nullptr);
// NPNR_ASSERT(user.cell->type == ctx->id("XC7_LC")); // NPNR_ASSERT(user.cell->type == ctx->id("XC7_LC"));
@ -888,7 +886,7 @@ bool Arch::pack()
log_break(); log_break();
pack_constants(ctx); pack_constants(ctx);
// TODO // TODO
//promote_globals(ctx); // promote_globals(ctx);
pack_io(ctx); pack_io(ctx);
pack_lut_lutffs(ctx); pack_lut_lutffs(ctx);
pack_nonlut_ffs(ctx); pack_nonlut_ffs(ctx);

View File

@ -22,6 +22,8 @@
#include <sstream> #include <sstream>
#include "log.h" #include "log.h"
#include <boost/algorithm/string.hpp>
NEXTPNR_NAMESPACE_BEGIN NEXTPNR_NAMESPACE_BEGIN
// Read a w // Read a w
@ -45,12 +47,14 @@ bool apply_pcf(Context *ctx, std::string filename, std::istream &in)
if (words.size() == 0) if (words.size() == 0)
continue; continue;
std::string cmd = words.at(0); std::string cmd = words.at(0);
if (cmd == "set_io") { if (cmd == "COMP") {
size_t args_end = 1; size_t args_end = 1;
while (args_end < words.size() && words.at(args_end).at(0) == '-') while (args_end < words.size() && words.at(args_end).at(0) == '-')
args_end++; args_end++;
std::string cell = words.at(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)); auto fnd_cell = ctx->cells.find(ctx->id(cell));
if (fnd_cell == ctx->cells.end()) { if (fnd_cell == ctx->cells.end()) {
log_warning("unmatched pcf constraint %s\n", cell.c_str()); log_warning("unmatched pcf constraint %s\n", cell.c_str());

View File

@ -18,12 +18,12 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
*/ */
#include "nextpnr.h"
#include "xdl.h" #include "xdl.h"
#include <cctype> #include <cctype>
#include <vector> #include <vector>
#include "cells.h" #include "cells.h"
#include "log.h" #include "log.h"
#include "nextpnr.h"
#include "util.h" #include "util.h"
#include "torc/Physical.hpp" #include "torc/Physical.hpp"
@ -37,25 +37,41 @@ void write_xdl(const Context *ctx, std::ostream &out)
XdlExporter exporter(out); XdlExporter exporter(out);
auto designPtr = Factory::newDesignPtr("name", torc_info->ddb->getDeviceName(), ctx->args.package, "-1", ""); auto designPtr = Factory::newDesignPtr("name", torc_info->ddb->getDeviceName(), ctx->args.package, "-1", "");
std::unordered_map<int32_t,InstanceSharedPtr> site_to_instance; std::unordered_map<int32_t, InstanceSharedPtr> site_to_instance;
std::vector<std::pair<std::string,std::string>> lut_inputs; std::vector<std::pair<std::string, std::string>> lut_inputs;
lut_inputs.reserve(6); lut_inputs.reserve(6);
auto bel_to_lut = [](const BelId bel) { auto bel_to_lut = [](const BelId bel) {
switch (torc_info->bel_to_loc[bel.index].z) { switch (torc_info->bel_to_loc[bel.index].z) {
case 0: case 4: return "A"; break; case 0:
case 1: case 5: return "B"; break; case 4:
case 2: case 6: return "C"; break; return "A";
case 3: case 7: return "D"; break; break;
default: throw; 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) { for (const auto &cell : ctx->cells) {
const char* type; const char *type;
if (cell.second->type == id_SLICE_LUT6) type = "SLICEL"; if (cell.second->type == id_SLICE_LUT6)
else if (cell.second->type == id_IOB33 || cell.second->type == id_BUFGCTRL) type = cell.second->type.c_str(ctx); type = "SLICEL";
else log_error("Unsupported cell type '%s'.\n", cell.second->type.c_str(ctx)); 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 site_index = torc_info->bel_to_site_index[cell.second->bel.index];
auto ret = site_to_instance.emplace(site_index, nullptr); auto ret = site_to_instance.emplace(site_index, nullptr);
@ -66,11 +82,10 @@ void write_xdl(const Context *ctx, std::ostream &out)
assert(b); assert(b);
ret.first->second = instPtr; 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->setTile(tile_info.getName());
instPtr->setSite(torc_info->bel_to_name(cell.second->bel.index)); instPtr->setSite(torc_info->bel_to_name(cell.second->bel.index));
} } else
else
instPtr = ret.first->second; instPtr = ret.first->second;
if (cell.second->type == id_SLICE_LUT6) { if (cell.second->type == id_SLICE_LUT6) {
@ -80,13 +95,19 @@ void write_xdl(const Context *ctx, std::ostream &out)
setting = lut + "6LUT"; setting = lut + "6LUT";
value = "#LUT:O6="; value = "#LUT:O6=";
lut_inputs.clear(); 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_I1))
if (get_net_or_empty(cell.second.get(), id_I2)) lut_inputs.emplace_back("A2", "~A2"); lut_inputs.emplace_back("A1", "~A1");
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_I2))
if (get_net_or_empty(cell.second.get(), id_I4)) lut_inputs.emplace_back("A4", "~A4"); lut_inputs.emplace_back("A2", "~A2");
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_I3))
if (get_net_or_empty(cell.second.get(), id_I6)) lut_inputs.emplace_back("A6", "~A6"); lut_inputs.emplace_back("A3", "~A3");
const auto& init = cell.second->params[ctx->id("INIT")]; 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 // Assume from Yosys that INIT masks of less than 32 bits are output as uint32_t
if (lut_inputs.size() < 6) { if (lut_inputs.size() < 6) {
auto init_as_uint = boost::lexical_cast<uint32_t>(init); auto init_as_uint = boost::lexical_cast<uint32_t>(init);
@ -96,8 +117,10 @@ void write_xdl(const Context *ctx, std::ostream &out)
else { else {
unsigned n = 0; unsigned n = 0;
for (unsigned o = 0; o < (1u << lut_inputs.size()); ++o) { for (unsigned o = 0; o < (1u << lut_inputs.size()); ++o) {
if ((init_as_uint >> o) & 0x1) continue; if ((init_as_uint >> o) & 0x1)
if (n++ > 0) value += "+"; continue;
if (n++ > 0)
value += "+";
value += "("; value += "(";
value += (o & 1) ? lut_inputs[0].first : lut_inputs[0].second; value += (o & 1) ? lut_inputs[0].first : lut_inputs[0].second;
for (unsigned i = 1; i < lut_inputs.size(); ++i) { 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())); NPNR_ASSERT(init.size() == (1u << lut_inputs.size()));
unsigned n = 0; unsigned n = 0;
for (unsigned i = 0; i < (1u << lut_inputs.size()); ++i) { for (unsigned i = 0; i < (1u << lut_inputs.size()); ++i) {
if (init[i] == '0') continue; if (init[i] == '0')
if (n++ > 0) value += "+"; continue;
if (n++ > 0)
value += "+";
value += "("; value += "(";
value += (i & 1) ? lut_inputs[0].first : lut_inputs[0].second; value += (i & 1) ? lut_inputs[0].first : lut_inputs[0].second;
for (unsigned j = 1; j < lut_inputs.size(); ++j) { 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("CEUSEDMUX", "", "IN");
instPtr->setConfig("SYNC_ATTR", "", "ASYNC"); 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)) { if (get_net_or_empty(cell.second.get(), id_I)) {
instPtr->setConfig("IUSED", "", "0"); instPtr->setConfig("IUSED", "", "0");
instPtr->setConfig("IBUF_LOW_PWR", "", "TRUE"); instPtr->setConfig("IBUF_LOW_PWR", "", "TRUE");
instPtr->setConfig("ISTANDARD", "", "LVCMOS33"); instPtr->setConfig("ISTANDARD", "", "LVCMOS33");
} } else {
else {
instPtr->setConfig("OUSED", "", "0"); instPtr->setConfig("OUSED", "", "0");
instPtr->setConfig("OSTANDARD", "", "LVCMOS33"); instPtr->setConfig("OSTANDARD", "", "LVCMOS33");
instPtr->setConfig("DRIVE", "", "12"); instPtr->setConfig("DRIVE", "", "12");
instPtr->setConfig("SLEW", "", "SLOW"); 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")); auto it = cell.second->params.find(ctx->id("PRESELECT_I0"));
instPtr->setConfig("PRESELECT_I0", "", it != cell.second->params.end() ? it->second : "TRUE"); instPtr->setConfig("PRESELECT_I0", "", it != cell.second->params.end() ? it->second : "TRUE");
instPtr->setConfig("CE0INV", "", "CE0_B"); instPtr->setConfig("CE0INV", "", "CE0_B");
instPtr->setConfig("S0INV", "", "S0_B"); instPtr->setConfig("S0INV", "", "S0_B");
} } else
else log_error("Unsupported cell type '%s'.\n", cell.second->type.c_str(ctx)); log_error("Unsupported cell type '%s'.\n", cell.second->type.c_str(ctx));
} }
for (const auto &net : ctx->nets) { for (const auto &net : ctx->nets) {
@ -217,18 +239,19 @@ void write_xdl(const Context *ctx, std::ostream &out)
auto b = designPtr->addNet(netPtr); auto b = designPtr->addNet(netPtr);
assert(b); assert(b);
for (const auto& i : net.second->wires) { for (const auto &i : net.second->wires) {
const auto& pip_map = i.second; const auto &pip_map = i.second;
if (pip_map.pip == PipId()) continue; if (pip_map.pip == PipId())
continue;
ExtendedWireInfo ewi_src(*torc_info->ddb, torc_info->pip_to_arc[pip_map.pip.index].getSourceTilewire()); 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()); 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); netPtr->addPip(p);
} }
} }
exporter(designPtr); exporter(designPtr);
} }
NEXTPNR_NAMESPACE_END NEXTPNR_NAMESPACE_END