clangformat
This commit is contained in:
parent
d80b63cc55
commit
aa7f7d6a97
@ -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) {
|
||||||
|
@ -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>
|
||||||
|
@ -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);
|
||||||
@ -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();
|
||||||
@ -742,7 +734,8 @@ void FPGAViewWidget::mouseMoveEvent(QMouseEvent *event)
|
|||||||
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
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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) {
|
||||||
|
@ -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);
|
||||||
|
157
xc7/arch.cc
157
xc7/arch.cc
@ -32,10 +32,16 @@
|
|||||||
|
|
||||||
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);
|
||||||
|
|
||||||
@ -57,8 +63,7 @@ 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;
|
||||||
@ -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,25 +100,27 @@ 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;
|
||||||
|
|
||||||
@ -128,10 +136,10 @@ std::vector<Tilewire> TorcInfo::construct_wire_to_tilewire(const Segments& segme
|
|||||||
const auto ¤tSegment = segments.getTilewireSegment(currentTilewire);
|
const auto ¤tSegment = 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);
|
||||||
@ -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());
|
||||||
@ -240,9 +262,11 @@ 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());
|
||||||
@ -253,14 +277,12 @@ std::vector<Arc> TorcInfo::construct_pip_to_arc(const std::vector<Tilewire>& wir
|
|||||||
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)
|
||||||
@ -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,7 +451,8 @@ 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);
|
||||||
|
|
||||||
@ -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;
|
||||||
@ -947,14 +982,12 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, Id
|
|||||||
}
|
}
|
||||||
// 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;
|
||||||
|
69
xc7/arch.h
69
xc7/arch.h
@ -41,15 +41,13 @@ namespace std {
|
|||||||
{
|
{
|
||||||
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>
|
||||||
@ -62,7 +60,7 @@ namespace std {
|
|||||||
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();
|
||||||
}
|
}
|
||||||
@ -323,14 +323,20 @@ struct TorcInfo {
|
|||||||
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
|
||||||
@ -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);
|
||||||
@ -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;
|
||||||
@ -665,10 +681,7 @@ 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
|
||||||
{
|
{
|
||||||
|
@ -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
|
|
||||||
|
@ -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)
|
||||||
|
@ -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();
|
||||||
|
10
xc7/pack.cc
10
xc7/pack.cc
@ -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.
|
||||||
|
@ -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());
|
||||||
|
87
xc7/xdl.cc
87
xc7/xdl.cc
@ -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"
|
||||||
@ -43,19 +43,35 @@ void write_xdl(const Context *ctx, std::ostream &out)
|
|||||||
|
|
||||||
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);
|
||||||
@ -69,8 +85,7 @@ void write_xdl(const Context *ctx, std::ostream &out)
|
|||||||
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,12 +95,18 @@ 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");
|
||||||
|
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")];
|
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) {
|
||||||
@ -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) {
|
||||||
@ -219,16 +241,17 @@ void write_xdl(const Context *ctx, std::ostream &out)
|
|||||||
|
|
||||||
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
|
||||||
|
Loading…
Reference in New Issue
Block a user