commit
fe4f98f26f
27
ecp5/arch.cc
27
ecp5/arch.cc
@ -651,6 +651,16 @@ TimingPortClass Arch::getPortTimingClass(const CellInfo *cell, IdString port, in
|
|||||||
return TMG_IGNORE; // FIXME
|
return TMG_IGNORE; // FIXME
|
||||||
} else if (cell->type == id_EHXPLLL) {
|
} else if (cell->type == id_EHXPLLL) {
|
||||||
return TMG_IGNORE;
|
return TMG_IGNORE;
|
||||||
|
} else if (cell->type == id_DCUA || cell->type == id_EXTREFB || cell->type == id_PCSCLKDIV) {
|
||||||
|
if (port == id_CH0_FF_TXI_CLK || port == id_CH0_FF_RXI_CLK || port == id_CH1_FF_TXI_CLK ||
|
||||||
|
port == id_CH1_FF_RXI_CLK)
|
||||||
|
return TMG_CLOCK_INPUT;
|
||||||
|
std::string prefix = port.str(this).substr(0, 9);
|
||||||
|
if (prefix == "CH0_FF_TX" || prefix == "CH0_FF_RX" || prefix == "CH1_FF_TX" || prefix == "CH1_FF_RX") {
|
||||||
|
clockInfoCount = 1;
|
||||||
|
return (cell->ports.at(port).type == PORT_OUT) ? TMG_REGISTER_OUTPUT : TMG_REGISTER_INPUT;
|
||||||
|
}
|
||||||
|
return TMG_IGNORE;
|
||||||
} else {
|
} else {
|
||||||
NPNR_ASSERT_FALSE_STR("no timing data for cell type '" + cell->type.str(this) + "'");
|
NPNR_ASSERT_FALSE_STR("no timing data for cell type '" + cell->type.str(this) + "'");
|
||||||
}
|
}
|
||||||
@ -706,6 +716,23 @@ TimingClockingInfo Arch::getPortClockingInfo(const CellInfo *cell, IdString port
|
|||||||
info.setup.delay = 100;
|
info.setup.delay = 100;
|
||||||
info.hold.delay = 0;
|
info.hold.delay = 0;
|
||||||
}
|
}
|
||||||
|
} else if (cell->type == id_DCUA) {
|
||||||
|
std::string prefix = port.str(this).substr(0, 9);
|
||||||
|
info.edge = RISING_EDGE;
|
||||||
|
if (prefix == "CH0_FF_TX")
|
||||||
|
info.clock_port = id_CH0_FF_TXI_CLK;
|
||||||
|
else if (prefix == "CH0_FF_RX")
|
||||||
|
info.clock_port = id_CH0_FF_RXI_CLK;
|
||||||
|
else if (prefix == "CH1_FF_TX")
|
||||||
|
info.clock_port = id_CH1_FF_TXI_CLK;
|
||||||
|
else if (prefix == "CH1_FF_RX")
|
||||||
|
info.clock_port = id_CH1_FF_RXI_CLK;
|
||||||
|
if (cell->ports.at(port).type == PORT_OUT) {
|
||||||
|
info.clockToQ.delay = 660;
|
||||||
|
} else {
|
||||||
|
info.setup.delay = 1000;
|
||||||
|
info.hold.delay = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
@ -101,6 +101,8 @@ bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const
|
|||||||
|
|
||||||
bel_cells.push_back(cell);
|
bel_cells.push_back(cell);
|
||||||
return slicesCompatible(bel_cells);
|
return slicesCompatible(bel_cells);
|
||||||
|
} else if (cell->type == id_DCUA || cell->type == id_EXTREFB || cell->type == id_PCSCLKDIV) {
|
||||||
|
return args.type != ArchArgs::LFE5U_25F && args.type != ArchArgs::LFE5U_45F && args.type != ArchArgs::LFE5U_85F;
|
||||||
} else {
|
} else {
|
||||||
// other checks
|
// other checks
|
||||||
return true;
|
return true;
|
||||||
|
@ -87,7 +87,10 @@ struct BelId
|
|||||||
|
|
||||||
bool operator==(const BelId &other) const { return index == other.index && location == other.location; }
|
bool operator==(const BelId &other) const { return index == other.index && location == other.location; }
|
||||||
bool operator!=(const BelId &other) const { return index != other.index || location != other.location; }
|
bool operator!=(const BelId &other) const { return index != other.index || location != other.location; }
|
||||||
bool operator<(const BelId &other) const { return location == other.location ? index < other.index : location < other.location; }
|
bool operator<(const BelId &other) const
|
||||||
|
{
|
||||||
|
return location == other.location ? index < other.index : location < other.location;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WireId
|
struct WireId
|
||||||
@ -97,7 +100,10 @@ struct WireId
|
|||||||
|
|
||||||
bool operator==(const WireId &other) const { return index == other.index && location == other.location; }
|
bool operator==(const WireId &other) const { return index == other.index && location == other.location; }
|
||||||
bool operator!=(const WireId &other) const { return index != other.index || location != other.location; }
|
bool operator!=(const WireId &other) const { return index != other.index || location != other.location; }
|
||||||
bool operator<(const WireId &other) const { return location == other.location ? index < other.index : location < other.location; }
|
bool operator<(const WireId &other) const
|
||||||
|
{
|
||||||
|
return location == other.location ? index < other.index : location < other.location;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PipId
|
struct PipId
|
||||||
@ -107,7 +113,10 @@ struct PipId
|
|||||||
|
|
||||||
bool operator==(const PipId &other) const { return index == other.index && location == other.location; }
|
bool operator==(const PipId &other) const { return index == other.index && location == other.location; }
|
||||||
bool operator!=(const PipId &other) const { return index != other.index || location != other.location; }
|
bool operator!=(const PipId &other) const { return index != other.index || location != other.location; }
|
||||||
bool operator<(const PipId &other) const { return location == other.location ? index < other.index : location < other.location; }
|
bool operator<(const PipId &other) const
|
||||||
|
{
|
||||||
|
return location == other.location ? index < other.index : location < other.location;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GroupId
|
struct GroupId
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
#include <queue>
|
#include <queue>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
#include <streambuf>
|
#include <streambuf>
|
||||||
|
#include <boost/algorithm/string/predicate.hpp>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
@ -379,6 +379,16 @@ std::vector<std::string> get_dsp_tiles(Context *ctx, BelId bel)
|
|||||||
return tiles;
|
return tiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the list of tiles corresponding to a DCU
|
||||||
|
std::vector<std::string> get_dcu_tiles(Context *ctx, BelId bel)
|
||||||
|
{
|
||||||
|
std::vector<std::string> tiles;
|
||||||
|
Loc loc = ctx->getBelLocation(bel);
|
||||||
|
for (int i = 0; i < 9; i++)
|
||||||
|
tiles.push_back(ctx->getTileByTypeAndLocation(loc.y, loc.x + i, "DCU" + std::to_string(i)));
|
||||||
|
return tiles;
|
||||||
|
}
|
||||||
|
|
||||||
// Get the list of tiles corresponding to a PLL
|
// Get the list of tiles corresponding to a PLL
|
||||||
std::vector<std::string> get_pll_tiles(Context *ctx, BelId bel)
|
std::vector<std::string> get_pll_tiles(Context *ctx, BelId bel)
|
||||||
{
|
{
|
||||||
@ -408,28 +418,25 @@ std::vector<std::string> get_pll_tiles(Context *ctx, BelId bel)
|
|||||||
void fix_tile_names(Context *ctx, ChipConfig &cc)
|
void fix_tile_names(Context *ctx, ChipConfig &cc)
|
||||||
{
|
{
|
||||||
// Remove the V prefix/suffix on certain tiles if device is a SERDES variant
|
// Remove the V prefix/suffix on certain tiles if device is a SERDES variant
|
||||||
if (ctx->args.type == ArchArgs::LFE5UM_25F || ctx->args.type == ArchArgs::LFE5UM_45F ||
|
if (ctx->args.type == ArchArgs::LFE5U_25F || ctx->args.type == ArchArgs::LFE5U_45F ||
|
||||||
ctx->args.type == ArchArgs::LFE5UM_85F || ctx->args.type == ArchArgs::LFE5UM5G_25F ||
|
ctx->args.type == ArchArgs::LFE5U_85F) {
|
||||||
ctx->args.type == ArchArgs::LFE5UM5G_45F || ctx->args.type == ArchArgs::LFE5UM5G_85F) {
|
|
||||||
std::map<std::string, std::string> tiletype_xform;
|
std::map<std::string, std::string> tiletype_xform;
|
||||||
for (const auto &tile : cc.tiles) {
|
for (const auto &tile : cc.tiles) {
|
||||||
std::string newname = tile.first;
|
std::string newname = tile.first;
|
||||||
auto vcib = tile.first.find("VCIB");
|
auto cibdcu = tile.first.find("CIB_DCU");
|
||||||
if (vcib != std::string::npos) {
|
if (cibdcu != std::string::npos) {
|
||||||
// Remove the V
|
// Add the V
|
||||||
newname.erase(vcib, 1);
|
if (newname.at(cibdcu - 1) != 'V')
|
||||||
|
newname.insert(cibdcu, 1, 'V');
|
||||||
tiletype_xform[tile.first] = newname;
|
tiletype_xform[tile.first] = newname;
|
||||||
} else if (tile.first.back() == 'V') {
|
} else if (boost::ends_with(tile.first, "BMID_0H")) {
|
||||||
// BMID_0V or BMID_2V
|
newname.back() = 'V';
|
||||||
if (tile.first.at(tile.first.size() - 2) == '0') {
|
|
||||||
newname.at(tile.first.size() - 1) = 'H';
|
|
||||||
tiletype_xform[tile.first] = newname;
|
tiletype_xform[tile.first] = newname;
|
||||||
} else if (tile.first.at(tile.first.size() - 2) == '2') {
|
} else if (boost::ends_with(tile.first, "BMID_2")) {
|
||||||
newname.pop_back();
|
newname.push_back('V');
|
||||||
tiletype_xform[tile.first] = newname;
|
tiletype_xform[tile.first] = newname;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// Apply the name changes
|
// Apply the name changes
|
||||||
for (auto xform : tiletype_xform) {
|
for (auto xform : tiletype_xform) {
|
||||||
cc.tiles[xform.second] = cc.tiles.at(xform.first);
|
cc.tiles[xform.second] = cc.tiles.at(xform.first);
|
||||||
@ -456,6 +463,20 @@ void tieoff_dsp_ports(Context *ctx, ChipConfig &cc, CellInfo *ci)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tieoff_dcu_ports(Context *ctx, ChipConfig &cc, CellInfo *ci)
|
||||||
|
{
|
||||||
|
for (auto port : ci->ports) {
|
||||||
|
if (port.second.net == nullptr && port.second.type == PORT_IN) {
|
||||||
|
if (port.first.str(ctx).find("CLK") != std::string::npos ||
|
||||||
|
port.first.str(ctx).find("HDIN") != std::string::npos ||
|
||||||
|
port.first.str(ctx).find("HDOUT") != std::string::npos)
|
||||||
|
continue;
|
||||||
|
bool value = bool_or_default(ci->params, ctx->id(port.first.str(ctx) + "MUX"), false);
|
||||||
|
tie_cib_signal(ctx, cc, ctx->getBelPinWire(ci->bel, port.first), value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void set_pip(Context *ctx, ChipConfig &cc, PipId pip)
|
static void set_pip(Context *ctx, ChipConfig &cc, PipId pip)
|
||||||
{
|
{
|
||||||
std::string tile = ctx->getPipTilename(pip);
|
std::string tile = ctx->getPipTilename(pip);
|
||||||
@ -464,6 +485,46 @@ static void set_pip(Context *ctx, ChipConfig &cc, PipId pip)
|
|||||||
cc.tiles[tile].add_arc(sink, source);
|
cc.tiles[tile].add_arc(sink, source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::vector<bool> parse_config_str(std::string str, int length)
|
||||||
|
{
|
||||||
|
// For DCU config which might be bin, hex or dec using prefices accordingly
|
||||||
|
std::string base = str.substr(0, 2);
|
||||||
|
std::vector<bool> word;
|
||||||
|
word.resize(length, false);
|
||||||
|
if (base == "0b") {
|
||||||
|
for (int i = 0; i < int(str.length()) - 2; i++) {
|
||||||
|
char c = str.at((str.size() - 1) - i);
|
||||||
|
NPNR_ASSERT(c == '0' || c == '1');
|
||||||
|
word.at(i) = (c == '1');
|
||||||
|
}
|
||||||
|
} else if (base == "0x") {
|
||||||
|
for (int i = 0; i < int(str.length()) - 2; i++) {
|
||||||
|
char c = str.at((str.size() - i) - 1);
|
||||||
|
int nibble = chtohex(c);
|
||||||
|
word.at(i * 4) = nibble & 0x1;
|
||||||
|
if (i * 4 + 1 < length)
|
||||||
|
word.at(i * 4 + 1) = nibble & 0x2;
|
||||||
|
if (i * 4 + 2 < length)
|
||||||
|
word.at(i * 4 + 2) = nibble & 0x4;
|
||||||
|
if (i * 4 + 3 < length)
|
||||||
|
word.at(i * 4 + 3) = nibble & 0x8;
|
||||||
|
}
|
||||||
|
} else if (base == "0d") {
|
||||||
|
NPNR_ASSERT(length < 64);
|
||||||
|
unsigned long long value = std::stoull(str.substr(2));
|
||||||
|
for (int i = 0; i < length; i++)
|
||||||
|
if (value & (1 << i))
|
||||||
|
word.at(i) = true;
|
||||||
|
} else {
|
||||||
|
NPNR_ASSERT(length < 64);
|
||||||
|
unsigned long long value = std::stoull(str);
|
||||||
|
for (int i = 0; i < length; i++)
|
||||||
|
if (value & (1 << i))
|
||||||
|
word.at(i) = true;
|
||||||
|
}
|
||||||
|
return word;
|
||||||
|
}
|
||||||
|
|
||||||
void write_bitstream(Context *ctx, std::string base_config_file, std::string text_config_file)
|
void write_bitstream(Context *ctx, std::string base_config_file, std::string text_config_file)
|
||||||
{
|
{
|
||||||
ChipConfig cc;
|
ChipConfig cc;
|
||||||
@ -481,6 +542,23 @@ void write_bitstream(Context *ctx, std::string base_config_file, std::string tex
|
|||||||
// TODO: .bit metadata
|
// TODO: .bit metadata
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clear out DCU tieoffs in base config if DCU used
|
||||||
|
for (auto &cell : ctx->cells) {
|
||||||
|
CellInfo *ci = cell.second.get();
|
||||||
|
if (ci->type == id_DCUA) {
|
||||||
|
Loc loc = ctx->getBelLocation(ci->bel);
|
||||||
|
for (int i = 0; i < 12; i++) {
|
||||||
|
auto tiles = ctx->getTilesAtLocation(loc.y - 1, loc.x + i);
|
||||||
|
for (const auto &tile : tiles) {
|
||||||
|
auto cc_tile = cc.tiles.find(tile.first);
|
||||||
|
if (cc_tile != cc.tiles.end()) {
|
||||||
|
cc_tile->second.cenums.clear();
|
||||||
|
cc_tile->second.cunknowns.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
// Add all set, configurable pips to the config
|
// Add all set, configurable pips to the config
|
||||||
for (auto pip : ctx->getPips()) {
|
for (auto pip : ctx->getPips()) {
|
||||||
if (ctx->getBoundPipNet(pip) != nullptr) {
|
if (ctx->getBoundPipNet(pip) != nullptr) {
|
||||||
@ -1000,6 +1078,28 @@ void write_bitstream(Context *ctx, std::string base_config_file, std::string tex
|
|||||||
int_to_bitvector(int_or_default(ci->attrs, ctx->id("MFG_ENABLE_FILTEROPAMP"), 0), 1));
|
int_to_bitvector(int_or_default(ci->attrs, ctx->id("MFG_ENABLE_FILTEROPAMP"), 0), 1));
|
||||||
|
|
||||||
cc.tilegroups.push_back(tg);
|
cc.tilegroups.push_back(tg);
|
||||||
|
} else if (ci->type == id_DCUA) {
|
||||||
|
TileGroup tg;
|
||||||
|
tg.tiles = get_dcu_tiles(ctx, ci->bel);
|
||||||
|
tg.config.add_enum("DCU.MODE", "DCUA");
|
||||||
|
#include "dcu_bitstream.h"
|
||||||
|
cc.tilegroups.push_back(tg);
|
||||||
|
tieoff_dcu_ports(ctx, cc, ci);
|
||||||
|
} else if (ci->type == id_EXTREFB) {
|
||||||
|
TileGroup tg;
|
||||||
|
tg.tiles = get_dcu_tiles(ctx, ci->bel);
|
||||||
|
tg.config.add_word("EXTREF.REFCK_DCBIAS_EN",
|
||||||
|
parse_config_str(str_or_default(ci->params, ctx->id("REFCK_DCBIAS_EN"), "0"), 1));
|
||||||
|
tg.config.add_word("EXTREF.REFCK_RTERM",
|
||||||
|
parse_config_str(str_or_default(ci->params, ctx->id("REFCK_RTERM"), "0"), 1));
|
||||||
|
tg.config.add_word("EXTREF.REFCK_PWDNB",
|
||||||
|
parse_config_str(str_or_default(ci->params, ctx->id("REFCK_PWDNB"), "0"), 1));
|
||||||
|
cc.tilegroups.push_back(tg);
|
||||||
|
} else if (ci->type == id_PCSCLKDIV) {
|
||||||
|
Loc loc = ctx->getBelLocation(ci->bel);
|
||||||
|
std::string tname = ctx->getTileByTypeAndLocation(loc.y + 1, loc.x, "BMID_0H");
|
||||||
|
cc.tiles[tname].add_enum("PCSCLKDIV" + std::to_string(loc.z),
|
||||||
|
str_or_default(ci->params, ctx->id("GSR"), "ENABLED"));
|
||||||
} else {
|
} else {
|
||||||
NPNR_ASSERT_FALSE("unsupported cell type");
|
NPNR_ASSERT_FALSE("unsupported cell type");
|
||||||
}
|
}
|
||||||
|
@ -810,3 +810,310 @@ X(LOCK)
|
|||||||
X(INTLOCK)
|
X(INTLOCK)
|
||||||
X(REFCLK)
|
X(REFCLK)
|
||||||
X(CLKINTFB)
|
X(CLKINTFB)
|
||||||
|
|
||||||
|
|
||||||
|
X(EXTREFB)
|
||||||
|
X(REFCLKP)
|
||||||
|
X(REFCLKN)
|
||||||
|
X(REFCLKO)
|
||||||
|
|
||||||
|
X(DCUA)
|
||||||
|
X(CH0_HDINP)
|
||||||
|
X(CH1_HDINP)
|
||||||
|
X(CH0_HDINN)
|
||||||
|
X(CH1_HDINN)
|
||||||
|
X(D_TXBIT_CLKP_FROM_ND)
|
||||||
|
X(D_TXBIT_CLKN_FROM_ND)
|
||||||
|
X(D_SYNC_ND)
|
||||||
|
X(D_TXPLL_LOL_FROM_ND)
|
||||||
|
X(CH0_RX_REFCLK)
|
||||||
|
X(CH1_RX_REFCLK)
|
||||||
|
X(CH0_FF_RXI_CLK)
|
||||||
|
X(CH1_FF_RXI_CLK)
|
||||||
|
X(CH0_FF_TXI_CLK)
|
||||||
|
X(CH1_FF_TXI_CLK)
|
||||||
|
X(CH0_FF_EBRD_CLK)
|
||||||
|
X(CH1_FF_EBRD_CLK)
|
||||||
|
X(CH0_FF_TX_D_0)
|
||||||
|
X(CH1_FF_TX_D_0)
|
||||||
|
X(CH0_FF_TX_D_1)
|
||||||
|
X(CH1_FF_TX_D_1)
|
||||||
|
X(CH0_FF_TX_D_2)
|
||||||
|
X(CH1_FF_TX_D_2)
|
||||||
|
X(CH0_FF_TX_D_3)
|
||||||
|
X(CH1_FF_TX_D_3)
|
||||||
|
X(CH0_FF_TX_D_4)
|
||||||
|
X(CH1_FF_TX_D_4)
|
||||||
|
X(CH0_FF_TX_D_5)
|
||||||
|
X(CH1_FF_TX_D_5)
|
||||||
|
X(CH0_FF_TX_D_6)
|
||||||
|
X(CH1_FF_TX_D_6)
|
||||||
|
X(CH0_FF_TX_D_7)
|
||||||
|
X(CH1_FF_TX_D_7)
|
||||||
|
X(CH0_FF_TX_D_8)
|
||||||
|
X(CH1_FF_TX_D_8)
|
||||||
|
X(CH0_FF_TX_D_9)
|
||||||
|
X(CH1_FF_TX_D_9)
|
||||||
|
X(CH0_FF_TX_D_10)
|
||||||
|
X(CH1_FF_TX_D_10)
|
||||||
|
X(CH0_FF_TX_D_11)
|
||||||
|
X(CH1_FF_TX_D_11)
|
||||||
|
X(CH0_FF_TX_D_12)
|
||||||
|
X(CH1_FF_TX_D_12)
|
||||||
|
X(CH0_FF_TX_D_13)
|
||||||
|
X(CH1_FF_TX_D_13)
|
||||||
|
X(CH0_FF_TX_D_14)
|
||||||
|
X(CH1_FF_TX_D_14)
|
||||||
|
X(CH0_FF_TX_D_15)
|
||||||
|
X(CH1_FF_TX_D_15)
|
||||||
|
X(CH0_FF_TX_D_16)
|
||||||
|
X(CH1_FF_TX_D_16)
|
||||||
|
X(CH0_FF_TX_D_17)
|
||||||
|
X(CH1_FF_TX_D_17)
|
||||||
|
X(CH0_FF_TX_D_18)
|
||||||
|
X(CH1_FF_TX_D_18)
|
||||||
|
X(CH0_FF_TX_D_19)
|
||||||
|
X(CH1_FF_TX_D_19)
|
||||||
|
X(CH0_FF_TX_D_20)
|
||||||
|
X(CH1_FF_TX_D_20)
|
||||||
|
X(CH0_FF_TX_D_21)
|
||||||
|
X(CH1_FF_TX_D_21)
|
||||||
|
X(CH0_FF_TX_D_22)
|
||||||
|
X(CH1_FF_TX_D_22)
|
||||||
|
X(CH0_FF_TX_D_23)
|
||||||
|
X(CH1_FF_TX_D_23)
|
||||||
|
X(CH0_FFC_EI_EN)
|
||||||
|
X(CH1_FFC_EI_EN)
|
||||||
|
X(CH0_FFC_PCIE_DET_EN)
|
||||||
|
X(CH1_FFC_PCIE_DET_EN)
|
||||||
|
X(CH0_FFC_PCIE_CT)
|
||||||
|
X(CH1_FFC_PCIE_CT)
|
||||||
|
X(CH0_FFC_SB_INV_RX)
|
||||||
|
X(CH1_FFC_SB_INV_RX)
|
||||||
|
X(CH0_FFC_ENABLE_CGALIGN)
|
||||||
|
X(CH1_FFC_ENABLE_CGALIGN)
|
||||||
|
X(CH0_FFC_SIGNAL_DETECT)
|
||||||
|
X(CH1_FFC_SIGNAL_DETECT)
|
||||||
|
X(CH0_FFC_FB_LOOPBACK)
|
||||||
|
X(CH1_FFC_FB_LOOPBACK)
|
||||||
|
X(CH0_FFC_SB_PFIFO_LP)
|
||||||
|
X(CH1_FFC_SB_PFIFO_LP)
|
||||||
|
X(CH0_FFC_PFIFO_CLR)
|
||||||
|
X(CH1_FFC_PFIFO_CLR)
|
||||||
|
X(CH0_FFC_RATE_MODE_RX)
|
||||||
|
X(CH1_FFC_RATE_MODE_RX)
|
||||||
|
X(CH0_FFC_RATE_MODE_TX)
|
||||||
|
X(CH1_FFC_RATE_MODE_TX)
|
||||||
|
X(CH0_FFC_DIV11_MODE_RX)
|
||||||
|
X(CH1_FFC_DIV11_MODE_RX)
|
||||||
|
X(CH0_FFC_RX_GEAR_MODE)
|
||||||
|
X(CH1_FFC_RX_GEAR_MODE)
|
||||||
|
X(CH0_FFC_TX_GEAR_MODE)
|
||||||
|
X(CH1_FFC_TX_GEAR_MODE)
|
||||||
|
X(CH0_FFC_DIV11_MODE_TX)
|
||||||
|
X(CH1_FFC_DIV11_MODE_TX)
|
||||||
|
X(CH0_FFC_LDR_CORE2TX_EN)
|
||||||
|
X(CH1_FFC_LDR_CORE2TX_EN)
|
||||||
|
X(CH0_FFC_LANE_TX_RST)
|
||||||
|
X(CH1_FFC_LANE_TX_RST)
|
||||||
|
X(CH0_FFC_LANE_RX_RST)
|
||||||
|
X(CH1_FFC_LANE_RX_RST)
|
||||||
|
X(CH0_FFC_RRST)
|
||||||
|
X(CH1_FFC_RRST)
|
||||||
|
X(CH0_FFC_TXPWDNB)
|
||||||
|
X(CH1_FFC_TXPWDNB)
|
||||||
|
X(CH0_FFC_RXPWDNB)
|
||||||
|
X(CH1_FFC_RXPWDNB)
|
||||||
|
X(CH0_LDR_CORE2TX)
|
||||||
|
X(CH1_LDR_CORE2TX)
|
||||||
|
X(D_SCIWDATA0)
|
||||||
|
X(D_SCIWDATA1)
|
||||||
|
X(D_SCIWDATA2)
|
||||||
|
X(D_SCIWDATA3)
|
||||||
|
X(D_SCIWDATA4)
|
||||||
|
X(D_SCIWDATA5)
|
||||||
|
X(D_SCIWDATA6)
|
||||||
|
X(D_SCIWDATA7)
|
||||||
|
X(D_SCIADDR0)
|
||||||
|
X(D_SCIADDR1)
|
||||||
|
X(D_SCIADDR2)
|
||||||
|
X(D_SCIADDR3)
|
||||||
|
X(D_SCIADDR4)
|
||||||
|
X(D_SCIADDR5)
|
||||||
|
X(D_SCIENAUX)
|
||||||
|
X(D_SCISELAUX)
|
||||||
|
X(CH0_SCIEN)
|
||||||
|
X(CH1_SCIEN)
|
||||||
|
X(CH0_SCISEL)
|
||||||
|
X(CH1_SCISEL)
|
||||||
|
X(D_SCIRD)
|
||||||
|
X(D_SCIWSTN)
|
||||||
|
X(D_CYAWSTN)
|
||||||
|
X(D_FFC_SYNC_TOGGLE)
|
||||||
|
X(D_FFC_DUAL_RST)
|
||||||
|
X(D_FFC_MACRO_RST)
|
||||||
|
X(D_FFC_MACROPDB)
|
||||||
|
X(D_FFC_TRST)
|
||||||
|
X(CH0_FFC_CDR_EN_BITSLIP)
|
||||||
|
X(CH1_FFC_CDR_EN_BITSLIP)
|
||||||
|
X(D_SCAN_ENABLE)
|
||||||
|
X(D_SCAN_IN_0)
|
||||||
|
X(D_SCAN_IN_1)
|
||||||
|
X(D_SCAN_IN_2)
|
||||||
|
X(D_SCAN_IN_3)
|
||||||
|
X(D_SCAN_IN_4)
|
||||||
|
X(D_SCAN_IN_5)
|
||||||
|
X(D_SCAN_IN_6)
|
||||||
|
X(D_SCAN_IN_7)
|
||||||
|
X(D_SCAN_MODE)
|
||||||
|
X(D_SCAN_RESET)
|
||||||
|
X(D_CIN0)
|
||||||
|
X(D_CIN1)
|
||||||
|
X(D_CIN2)
|
||||||
|
X(D_CIN3)
|
||||||
|
X(D_CIN4)
|
||||||
|
X(D_CIN5)
|
||||||
|
X(D_CIN6)
|
||||||
|
X(D_CIN7)
|
||||||
|
X(D_CIN8)
|
||||||
|
X(D_CIN9)
|
||||||
|
X(D_CIN10)
|
||||||
|
X(D_CIN11)
|
||||||
|
X(CH0_HDOUTP)
|
||||||
|
X(CH1_HDOUTP)
|
||||||
|
X(CH0_HDOUTN)
|
||||||
|
X(CH1_HDOUTN)
|
||||||
|
X(D_TXBIT_CLKP_TO_ND)
|
||||||
|
X(D_TXBIT_CLKN_TO_ND)
|
||||||
|
X(D_SYNC_PULSE2ND)
|
||||||
|
X(D_TXPLL_LOL_TO_ND)
|
||||||
|
X(CH0_FF_RX_F_CLK)
|
||||||
|
X(CH1_FF_RX_F_CLK)
|
||||||
|
X(CH0_FF_RX_H_CLK)
|
||||||
|
X(CH1_FF_RX_H_CLK)
|
||||||
|
X(CH0_FF_TX_F_CLK)
|
||||||
|
X(CH1_FF_TX_F_CLK)
|
||||||
|
X(CH0_FF_TX_H_CLK)
|
||||||
|
X(CH1_FF_TX_H_CLK)
|
||||||
|
X(CH0_FF_RX_PCLK)
|
||||||
|
X(CH1_FF_RX_PCLK)
|
||||||
|
X(CH0_FF_TX_PCLK)
|
||||||
|
X(CH1_FF_TX_PCLK)
|
||||||
|
X(CH0_FF_RX_D_0)
|
||||||
|
X(CH1_FF_RX_D_0)
|
||||||
|
X(CH0_FF_RX_D_1)
|
||||||
|
X(CH1_FF_RX_D_1)
|
||||||
|
X(CH0_FF_RX_D_2)
|
||||||
|
X(CH1_FF_RX_D_2)
|
||||||
|
X(CH0_FF_RX_D_3)
|
||||||
|
X(CH1_FF_RX_D_3)
|
||||||
|
X(CH0_FF_RX_D_4)
|
||||||
|
X(CH1_FF_RX_D_4)
|
||||||
|
X(CH0_FF_RX_D_5)
|
||||||
|
X(CH1_FF_RX_D_5)
|
||||||
|
X(CH0_FF_RX_D_6)
|
||||||
|
X(CH1_FF_RX_D_6)
|
||||||
|
X(CH0_FF_RX_D_7)
|
||||||
|
X(CH1_FF_RX_D_7)
|
||||||
|
X(CH0_FF_RX_D_8)
|
||||||
|
X(CH1_FF_RX_D_8)
|
||||||
|
X(CH0_FF_RX_D_9)
|
||||||
|
X(CH1_FF_RX_D_9)
|
||||||
|
X(CH0_FF_RX_D_10)
|
||||||
|
X(CH1_FF_RX_D_10)
|
||||||
|
X(CH0_FF_RX_D_11)
|
||||||
|
X(CH1_FF_RX_D_11)
|
||||||
|
X(CH0_FF_RX_D_12)
|
||||||
|
X(CH1_FF_RX_D_12)
|
||||||
|
X(CH0_FF_RX_D_13)
|
||||||
|
X(CH1_FF_RX_D_13)
|
||||||
|
X(CH0_FF_RX_D_14)
|
||||||
|
X(CH1_FF_RX_D_14)
|
||||||
|
X(CH0_FF_RX_D_15)
|
||||||
|
X(CH1_FF_RX_D_15)
|
||||||
|
X(CH0_FF_RX_D_16)
|
||||||
|
X(CH1_FF_RX_D_16)
|
||||||
|
X(CH0_FF_RX_D_17)
|
||||||
|
X(CH1_FF_RX_D_17)
|
||||||
|
X(CH0_FF_RX_D_18)
|
||||||
|
X(CH1_FF_RX_D_18)
|
||||||
|
X(CH0_FF_RX_D_19)
|
||||||
|
X(CH1_FF_RX_D_19)
|
||||||
|
X(CH0_FF_RX_D_20)
|
||||||
|
X(CH1_FF_RX_D_20)
|
||||||
|
X(CH0_FF_RX_D_21)
|
||||||
|
X(CH1_FF_RX_D_21)
|
||||||
|
X(CH0_FF_RX_D_22)
|
||||||
|
X(CH1_FF_RX_D_22)
|
||||||
|
X(CH0_FF_RX_D_23)
|
||||||
|
X(CH1_FF_RX_D_23)
|
||||||
|
X(CH0_FFS_PCIE_DONE)
|
||||||
|
X(CH1_FFS_PCIE_DONE)
|
||||||
|
X(CH0_FFS_PCIE_CON)
|
||||||
|
X(CH1_FFS_PCIE_CON)
|
||||||
|
X(CH0_FFS_RLOS)
|
||||||
|
X(CH1_FFS_RLOS)
|
||||||
|
X(CH0_FFS_LS_SYNC_STATUS)
|
||||||
|
X(CH1_FFS_LS_SYNC_STATUS)
|
||||||
|
X(CH0_FFS_CC_UNDERRUN)
|
||||||
|
X(CH1_FFS_CC_UNDERRUN)
|
||||||
|
X(CH0_FFS_CC_OVERRUN)
|
||||||
|
X(CH1_FFS_CC_OVERRUN)
|
||||||
|
X(CH0_FFS_RXFBFIFO_ERROR)
|
||||||
|
X(CH1_FFS_RXFBFIFO_ERROR)
|
||||||
|
X(CH0_FFS_TXFBFIFO_ERROR)
|
||||||
|
X(CH1_FFS_TXFBFIFO_ERROR)
|
||||||
|
X(CH0_FFS_RLOL)
|
||||||
|
X(CH1_FFS_RLOL)
|
||||||
|
X(CH0_FFS_SKP_ADDED)
|
||||||
|
X(CH1_FFS_SKP_ADDED)
|
||||||
|
X(CH0_FFS_SKP_DELETED)
|
||||||
|
X(CH1_FFS_SKP_DELETED)
|
||||||
|
X(CH0_LDR_RX2CORE)
|
||||||
|
X(CH1_LDR_RX2CORE)
|
||||||
|
X(D_SCIRDATA0)
|
||||||
|
X(D_SCIRDATA1)
|
||||||
|
X(D_SCIRDATA2)
|
||||||
|
X(D_SCIRDATA3)
|
||||||
|
X(D_SCIRDATA4)
|
||||||
|
X(D_SCIRDATA5)
|
||||||
|
X(D_SCIRDATA6)
|
||||||
|
X(D_SCIRDATA7)
|
||||||
|
X(D_SCIINT)
|
||||||
|
X(D_SCAN_OUT_0)
|
||||||
|
X(D_SCAN_OUT_1)
|
||||||
|
X(D_SCAN_OUT_2)
|
||||||
|
X(D_SCAN_OUT_3)
|
||||||
|
X(D_SCAN_OUT_4)
|
||||||
|
X(D_SCAN_OUT_5)
|
||||||
|
X(D_SCAN_OUT_6)
|
||||||
|
X(D_SCAN_OUT_7)
|
||||||
|
X(D_COUT0)
|
||||||
|
X(D_COUT1)
|
||||||
|
X(D_COUT2)
|
||||||
|
X(D_COUT3)
|
||||||
|
X(D_COUT4)
|
||||||
|
X(D_COUT5)
|
||||||
|
X(D_COUT6)
|
||||||
|
X(D_COUT7)
|
||||||
|
X(D_COUT8)
|
||||||
|
X(D_COUT9)
|
||||||
|
X(D_COUT10)
|
||||||
|
X(D_COUT11)
|
||||||
|
X(D_COUT12)
|
||||||
|
X(D_COUT13)
|
||||||
|
X(D_COUT14)
|
||||||
|
X(D_COUT15)
|
||||||
|
X(D_COUT16)
|
||||||
|
X(D_COUT17)
|
||||||
|
X(D_COUT18)
|
||||||
|
X(D_COUT19)
|
||||||
|
X(D_REFCLKI)
|
||||||
|
X(D_FFS_PLOL)
|
||||||
|
|
||||||
|
X(PCSCLKDIV)
|
||||||
|
X(SEL2)
|
||||||
|
X(SEL1)
|
||||||
|
X(SEL0)
|
||||||
|
X(CDIV1)
|
||||||
|
X(CDIVX)
|
254
ecp5/dcu_bitstream.h
Normal file
254
ecp5/dcu_bitstream.h
Normal file
@ -0,0 +1,254 @@
|
|||||||
|
tg.config.add_word("DCU.CH0_AUTO_CALIB_EN", parse_config_str(str_or_default(ci->params, ctx->id("CH0_AUTO_CALIB_EN"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_AUTO_FACQ_EN", parse_config_str(str_or_default(ci->params, ctx->id("CH0_AUTO_FACQ_EN"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_BAND_THRESHOLD", parse_config_str(str_or_default(ci->params, ctx->id("CH0_BAND_THRESHOLD"), "0"), 6));
|
||||||
|
tg.config.add_word("DCU.CH0_CALIB_CK_MODE", parse_config_str(str_or_default(ci->params, ctx->id("CH0_CALIB_CK_MODE"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_CC_MATCH_1", parse_config_str(str_or_default(ci->params, ctx->id("CH0_CC_MATCH_1"), "0"), 10));
|
||||||
|
tg.config.add_word("DCU.CH0_CC_MATCH_2", parse_config_str(str_or_default(ci->params, ctx->id("CH0_CC_MATCH_2"), "0"), 10));
|
||||||
|
tg.config.add_word("DCU.CH0_CC_MATCH_3", parse_config_str(str_or_default(ci->params, ctx->id("CH0_CC_MATCH_3"), "0"), 10));
|
||||||
|
tg.config.add_word("DCU.CH0_CC_MATCH_4", parse_config_str(str_or_default(ci->params, ctx->id("CH0_CC_MATCH_4"), "0"), 10));
|
||||||
|
tg.config.add_word("DCU.CH0_CDR_CNT4SEL", parse_config_str(str_or_default(ci->params, ctx->id("CH0_CDR_CNT4SEL"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH0_CDR_CNT8SEL", parse_config_str(str_or_default(ci->params, ctx->id("CH0_CDR_CNT8SEL"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH0_CTC_BYPASS", parse_config_str(str_or_default(ci->params, ctx->id("CH0_CTC_BYPASS"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_DCOATDCFG", parse_config_str(str_or_default(ci->params, ctx->id("CH0_DCOATDCFG"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH0_DCOATDDLY", parse_config_str(str_or_default(ci->params, ctx->id("CH0_DCOATDDLY"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH0_DCOBYPSATD", parse_config_str(str_or_default(ci->params, ctx->id("CH0_DCOBYPSATD"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_DCOCALDIV", parse_config_str(str_or_default(ci->params, ctx->id("CH0_DCOCALDIV"), "0"), 3));
|
||||||
|
tg.config.add_word("DCU.CH0_DCOCTLGI", parse_config_str(str_or_default(ci->params, ctx->id("CH0_DCOCTLGI"), "0"), 3));
|
||||||
|
tg.config.add_word("DCU.CH0_DCODISBDAVOID", parse_config_str(str_or_default(ci->params, ctx->id("CH0_DCODISBDAVOID"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_DCOFLTDAC", parse_config_str(str_or_default(ci->params, ctx->id("CH0_DCOFLTDAC"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH0_DCOFTNRG", parse_config_str(str_or_default(ci->params, ctx->id("CH0_DCOFTNRG"), "0"), 3));
|
||||||
|
tg.config.add_word("DCU.CH0_DCOIOSTUNE", parse_config_str(str_or_default(ci->params, ctx->id("CH0_DCOIOSTUNE"), "0"), 3));
|
||||||
|
tg.config.add_word("DCU.CH0_DCOITUNE", parse_config_str(str_or_default(ci->params, ctx->id("CH0_DCOITUNE"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH0_DCOITUNE4LSB", parse_config_str(str_or_default(ci->params, ctx->id("CH0_DCOITUNE4LSB"), "0"), 3));
|
||||||
|
tg.config.add_word("DCU.CH0_DCOIUPDNX2", parse_config_str(str_or_default(ci->params, ctx->id("CH0_DCOIUPDNX2"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_DCONUOFLSB", parse_config_str(str_or_default(ci->params, ctx->id("CH0_DCONUOFLSB"), "0"), 3));
|
||||||
|
tg.config.add_word("DCU.CH0_DCOSCALEI", parse_config_str(str_or_default(ci->params, ctx->id("CH0_DCOSCALEI"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH0_DCOSTARTVAL", parse_config_str(str_or_default(ci->params, ctx->id("CH0_DCOSTARTVAL"), "0"), 3));
|
||||||
|
tg.config.add_word("DCU.CH0_DCOSTEP", parse_config_str(str_or_default(ci->params, ctx->id("CH0_DCOSTEP"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH0_DEC_BYPASS", parse_config_str(str_or_default(ci->params, ctx->id("CH0_DEC_BYPASS"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_ENABLE_CG_ALIGN", parse_config_str(str_or_default(ci->params, ctx->id("CH0_ENABLE_CG_ALIGN"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_ENC_BYPASS", parse_config_str(str_or_default(ci->params, ctx->id("CH0_ENC_BYPASS"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_FF_RX_F_CLK_DIS", parse_config_str(str_or_default(ci->params, ctx->id("CH0_FF_RX_F_CLK_DIS"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_FF_RX_H_CLK_EN", parse_config_str(str_or_default(ci->params, ctx->id("CH0_FF_RX_H_CLK_EN"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_FF_TX_F_CLK_DIS", parse_config_str(str_or_default(ci->params, ctx->id("CH0_FF_TX_F_CLK_DIS"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_FF_TX_H_CLK_EN", parse_config_str(str_or_default(ci->params, ctx->id("CH0_FF_TX_H_CLK_EN"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_GE_AN_ENABLE", parse_config_str(str_or_default(ci->params, ctx->id("CH0_GE_AN_ENABLE"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_INVERT_RX", parse_config_str(str_or_default(ci->params, ctx->id("CH0_INVERT_RX"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_INVERT_TX", parse_config_str(str_or_default(ci->params, ctx->id("CH0_INVERT_TX"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_LDR_CORE2TX_SEL", parse_config_str(str_or_default(ci->params, ctx->id("CH0_LDR_CORE2TX_SEL"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_LDR_RX2CORE_SEL", parse_config_str(str_or_default(ci->params, ctx->id("CH0_LDR_RX2CORE_SEL"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_LEQ_OFFSET_SEL", parse_config_str(str_or_default(ci->params, ctx->id("CH0_LEQ_OFFSET_SEL"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_LEQ_OFFSET_TRIM", parse_config_str(str_or_default(ci->params, ctx->id("CH0_LEQ_OFFSET_TRIM"), "0"), 3));
|
||||||
|
tg.config.add_word("DCU.CH0_LSM_DISABLE", parse_config_str(str_or_default(ci->params, ctx->id("CH0_LSM_DISABLE"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_MATCH_2_ENABLE", parse_config_str(str_or_default(ci->params, ctx->id("CH0_MATCH_2_ENABLE"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_MATCH_4_ENABLE", parse_config_str(str_or_default(ci->params, ctx->id("CH0_MATCH_4_ENABLE"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_MIN_IPG_CNT", parse_config_str(str_or_default(ci->params, ctx->id("CH0_MIN_IPG_CNT"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH0_PCIE_EI_EN", parse_config_str(str_or_default(ci->params, ctx->id("CH0_PCIE_EI_EN"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_PCIE_MODE", parse_config_str(str_or_default(ci->params, ctx->id("CH0_PCIE_MODE"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_PCS_DET_TIME_SEL", parse_config_str(str_or_default(ci->params, ctx->id("CH0_PCS_DET_TIME_SEL"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH0_PDEN_SEL", parse_config_str(str_or_default(ci->params, ctx->id("CH0_PDEN_SEL"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_PRBS_ENABLE", parse_config_str(str_or_default(ci->params, ctx->id("CH0_PRBS_ENABLE"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_PRBS_LOCK", parse_config_str(str_or_default(ci->params, ctx->id("CH0_PRBS_LOCK"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_PRBS_SELECTION", parse_config_str(str_or_default(ci->params, ctx->id("CH0_PRBS_SELECTION"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_RATE_MODE_RX", parse_config_str(str_or_default(ci->params, ctx->id("CH0_RATE_MODE_RX"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_RATE_MODE_TX", parse_config_str(str_or_default(ci->params, ctx->id("CH0_RATE_MODE_TX"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_RCV_DCC_EN", parse_config_str(str_or_default(ci->params, ctx->id("CH0_RCV_DCC_EN"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_REG_BAND_OFFSET", parse_config_str(str_or_default(ci->params, ctx->id("CH0_REG_BAND_OFFSET"), "0"), 4));
|
||||||
|
tg.config.add_word("DCU.CH0_REG_BAND_SEL", parse_config_str(str_or_default(ci->params, ctx->id("CH0_REG_BAND_SEL"), "0"), 6));
|
||||||
|
tg.config.add_word("DCU.CH0_REG_IDAC_EN", parse_config_str(str_or_default(ci->params, ctx->id("CH0_REG_IDAC_EN"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_REG_IDAC_SEL", parse_config_str(str_or_default(ci->params, ctx->id("CH0_REG_IDAC_SEL"), "0"), 10));
|
||||||
|
tg.config.add_word("DCU.CH0_REQ_EN", parse_config_str(str_or_default(ci->params, ctx->id("CH0_REQ_EN"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_REQ_LVL_SET", parse_config_str(str_or_default(ci->params, ctx->id("CH0_REQ_LVL_SET"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH0_RIO_MODE", parse_config_str(str_or_default(ci->params, ctx->id("CH0_RIO_MODE"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_RLOS_SEL", parse_config_str(str_or_default(ci->params, ctx->id("CH0_RLOS_SEL"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_RPWDNB", parse_config_str(str_or_default(ci->params, ctx->id("CH0_RPWDNB"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_RTERM_RX", parse_config_str(str_or_default(ci->params, ctx->id("CH0_RTERM_RX"), "0"), 5));
|
||||||
|
tg.config.add_word("DCU.CH0_RTERM_TX", parse_config_str(str_or_default(ci->params, ctx->id("CH0_RTERM_TX"), "0"), 5));
|
||||||
|
tg.config.add_word("DCU.CH0_RXIN_CM", parse_config_str(str_or_default(ci->params, ctx->id("CH0_RXIN_CM"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH0_RXTERM_CM", parse_config_str(str_or_default(ci->params, ctx->id("CH0_RXTERM_CM"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH0_RX_DCO_CK_DIV", parse_config_str(str_or_default(ci->params, ctx->id("CH0_RX_DCO_CK_DIV"), "0"), 3));
|
||||||
|
tg.config.add_word("DCU.CH0_RX_DIV11_SEL", parse_config_str(str_or_default(ci->params, ctx->id("CH0_RX_DIV11_SEL"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_RX_GEAR_BYPASS", parse_config_str(str_or_default(ci->params, ctx->id("CH0_RX_GEAR_BYPASS"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_RX_GEAR_MODE", parse_config_str(str_or_default(ci->params, ctx->id("CH0_RX_GEAR_MODE"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_RX_LOS_CEQ", parse_config_str(str_or_default(ci->params, ctx->id("CH0_RX_LOS_CEQ"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH0_RX_LOS_EN", parse_config_str(str_or_default(ci->params, ctx->id("CH0_RX_LOS_EN"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_RX_LOS_HYST_EN", parse_config_str(str_or_default(ci->params, ctx->id("CH0_RX_LOS_HYST_EN"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_RX_LOS_LVL", parse_config_str(str_or_default(ci->params, ctx->id("CH0_RX_LOS_LVL"), "0"), 3));
|
||||||
|
tg.config.add_word("DCU.CH0_RX_RATE_SEL", parse_config_str(str_or_default(ci->params, ctx->id("CH0_RX_RATE_SEL"), "0"), 4));
|
||||||
|
tg.config.add_word("DCU.CH0_RX_SB_BYPASS", parse_config_str(str_or_default(ci->params, ctx->id("CH0_RX_SB_BYPASS"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_SB_BYPASS", parse_config_str(str_or_default(ci->params, ctx->id("CH0_SB_BYPASS"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_SEL_SD_RX_CLK", parse_config_str(str_or_default(ci->params, ctx->id("CH0_SEL_SD_RX_CLK"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_TDRV_DAT_SEL", parse_config_str(str_or_default(ci->params, ctx->id("CH0_TDRV_DAT_SEL"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH0_TDRV_POST_EN", parse_config_str(str_or_default(ci->params, ctx->id("CH0_TDRV_POST_EN"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_TDRV_PRE_EN", parse_config_str(str_or_default(ci->params, ctx->id("CH0_TDRV_PRE_EN"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_TDRV_SLICE0_CUR", parse_config_str(str_or_default(ci->params, ctx->id("CH0_TDRV_SLICE0_CUR"), "0"), 3));
|
||||||
|
tg.config.add_word("DCU.CH0_TDRV_SLICE0_SEL", parse_config_str(str_or_default(ci->params, ctx->id("CH0_TDRV_SLICE0_SEL"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH0_TDRV_SLICE1_CUR", parse_config_str(str_or_default(ci->params, ctx->id("CH0_TDRV_SLICE1_CUR"), "0"), 3));
|
||||||
|
tg.config.add_word("DCU.CH0_TDRV_SLICE1_SEL", parse_config_str(str_or_default(ci->params, ctx->id("CH0_TDRV_SLICE1_SEL"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH0_TDRV_SLICE2_CUR", parse_config_str(str_or_default(ci->params, ctx->id("CH0_TDRV_SLICE2_CUR"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH0_TDRV_SLICE2_SEL", parse_config_str(str_or_default(ci->params, ctx->id("CH0_TDRV_SLICE2_SEL"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH0_TDRV_SLICE3_CUR", parse_config_str(str_or_default(ci->params, ctx->id("CH0_TDRV_SLICE3_CUR"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH0_TDRV_SLICE3_SEL", parse_config_str(str_or_default(ci->params, ctx->id("CH0_TDRV_SLICE3_SEL"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH0_TDRV_SLICE4_CUR", parse_config_str(str_or_default(ci->params, ctx->id("CH0_TDRV_SLICE4_CUR"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH0_TDRV_SLICE4_SEL", parse_config_str(str_or_default(ci->params, ctx->id("CH0_TDRV_SLICE4_SEL"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH0_TDRV_SLICE5_CUR", parse_config_str(str_or_default(ci->params, ctx->id("CH0_TDRV_SLICE5_CUR"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH0_TDRV_SLICE5_SEL", parse_config_str(str_or_default(ci->params, ctx->id("CH0_TDRV_SLICE5_SEL"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH0_TPWDNB", parse_config_str(str_or_default(ci->params, ctx->id("CH0_TPWDNB"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_TX_CM_SEL", parse_config_str(str_or_default(ci->params, ctx->id("CH0_TX_CM_SEL"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH0_TX_DIV11_SEL", parse_config_str(str_or_default(ci->params, ctx->id("CH0_TX_DIV11_SEL"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_TX_GEAR_BYPASS", parse_config_str(str_or_default(ci->params, ctx->id("CH0_TX_GEAR_BYPASS"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_TX_GEAR_MODE", parse_config_str(str_or_default(ci->params, ctx->id("CH0_TX_GEAR_MODE"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_TX_POST_SIGN", parse_config_str(str_or_default(ci->params, ctx->id("CH0_TX_POST_SIGN"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_TX_PRE_SIGN", parse_config_str(str_or_default(ci->params, ctx->id("CH0_TX_PRE_SIGN"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_UC_MODE", parse_config_str(str_or_default(ci->params, ctx->id("CH0_UC_MODE"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_UDF_COMMA_A", parse_config_str(str_or_default(ci->params, ctx->id("CH0_UDF_COMMA_A"), "0"), 10));
|
||||||
|
tg.config.add_word("DCU.CH0_UDF_COMMA_B", parse_config_str(str_or_default(ci->params, ctx->id("CH0_UDF_COMMA_B"), "0"), 10));
|
||||||
|
tg.config.add_word("DCU.CH0_UDF_COMMA_MASK", parse_config_str(str_or_default(ci->params, ctx->id("CH0_UDF_COMMA_MASK"), "0"), 10));
|
||||||
|
tg.config.add_word("DCU.CH0_WA_BYPASS", parse_config_str(str_or_default(ci->params, ctx->id("CH0_WA_BYPASS"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH0_WA_MODE", parse_config_str(str_or_default(ci->params, ctx->id("CH0_WA_MODE"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_AUTO_CALIB_EN", parse_config_str(str_or_default(ci->params, ctx->id("CH1_AUTO_CALIB_EN"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_AUTO_FACQ_EN", parse_config_str(str_or_default(ci->params, ctx->id("CH1_AUTO_FACQ_EN"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_BAND_THRESHOLD", parse_config_str(str_or_default(ci->params, ctx->id("CH1_BAND_THRESHOLD"), "0"), 6));
|
||||||
|
tg.config.add_word("DCU.CH1_CALIB_CK_MODE", parse_config_str(str_or_default(ci->params, ctx->id("CH1_CALIB_CK_MODE"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_CC_MATCH_1", parse_config_str(str_or_default(ci->params, ctx->id("CH1_CC_MATCH_1"), "0"), 10));
|
||||||
|
tg.config.add_word("DCU.CH1_CC_MATCH_2", parse_config_str(str_or_default(ci->params, ctx->id("CH1_CC_MATCH_2"), "0"), 10));
|
||||||
|
tg.config.add_word("DCU.CH1_CC_MATCH_3", parse_config_str(str_or_default(ci->params, ctx->id("CH1_CC_MATCH_3"), "0"), 10));
|
||||||
|
tg.config.add_word("DCU.CH1_CC_MATCH_4", parse_config_str(str_or_default(ci->params, ctx->id("CH1_CC_MATCH_4"), "0"), 10));
|
||||||
|
tg.config.add_word("DCU.CH1_CDR_CNT4SEL", parse_config_str(str_or_default(ci->params, ctx->id("CH1_CDR_CNT4SEL"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH1_CDR_CNT8SEL", parse_config_str(str_or_default(ci->params, ctx->id("CH1_CDR_CNT8SEL"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH1_CTC_BYPASS", parse_config_str(str_or_default(ci->params, ctx->id("CH1_CTC_BYPASS"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_DCOATDCFG", parse_config_str(str_or_default(ci->params, ctx->id("CH1_DCOATDCFG"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH1_DCOATDDLY", parse_config_str(str_or_default(ci->params, ctx->id("CH1_DCOATDDLY"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH1_DCOBYPSATD", parse_config_str(str_or_default(ci->params, ctx->id("CH1_DCOBYPSATD"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_DCOCALDIV", parse_config_str(str_or_default(ci->params, ctx->id("CH1_DCOCALDIV"), "0"), 3));
|
||||||
|
tg.config.add_word("DCU.CH1_DCOCTLGI", parse_config_str(str_or_default(ci->params, ctx->id("CH1_DCOCTLGI"), "0"), 3));
|
||||||
|
tg.config.add_word("DCU.CH1_DCODISBDAVOID", parse_config_str(str_or_default(ci->params, ctx->id("CH1_DCODISBDAVOID"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_DCOFLTDAC", parse_config_str(str_or_default(ci->params, ctx->id("CH1_DCOFLTDAC"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH1_DCOFTNRG", parse_config_str(str_or_default(ci->params, ctx->id("CH1_DCOFTNRG"), "0"), 3));
|
||||||
|
tg.config.add_word("DCU.CH1_DCOIOSTUNE", parse_config_str(str_or_default(ci->params, ctx->id("CH1_DCOIOSTUNE"), "0"), 3));
|
||||||
|
tg.config.add_word("DCU.CH1_DCOITUNE", parse_config_str(str_or_default(ci->params, ctx->id("CH1_DCOITUNE"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH1_DCOITUNE4LSB", parse_config_str(str_or_default(ci->params, ctx->id("CH1_DCOITUNE4LSB"), "0"), 3));
|
||||||
|
tg.config.add_word("DCU.CH1_DCOIUPDNX2", parse_config_str(str_or_default(ci->params, ctx->id("CH1_DCOIUPDNX2"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_DCONUOFLSB", parse_config_str(str_or_default(ci->params, ctx->id("CH1_DCONUOFLSB"), "0"), 3));
|
||||||
|
tg.config.add_word("DCU.CH1_DCOSCALEI", parse_config_str(str_or_default(ci->params, ctx->id("CH1_DCOSCALEI"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH1_DCOSTARTVAL", parse_config_str(str_or_default(ci->params, ctx->id("CH1_DCOSTARTVAL"), "0"), 3));
|
||||||
|
tg.config.add_word("DCU.CH1_DCOSTEP", parse_config_str(str_or_default(ci->params, ctx->id("CH1_DCOSTEP"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH1_DEC_BYPASS", parse_config_str(str_or_default(ci->params, ctx->id("CH1_DEC_BYPASS"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_ENABLE_CG_ALIGN", parse_config_str(str_or_default(ci->params, ctx->id("CH1_ENABLE_CG_ALIGN"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_ENC_BYPASS", parse_config_str(str_or_default(ci->params, ctx->id("CH1_ENC_BYPASS"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_FF_RX_F_CLK_DIS", parse_config_str(str_or_default(ci->params, ctx->id("CH1_FF_RX_F_CLK_DIS"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_FF_RX_H_CLK_EN", parse_config_str(str_or_default(ci->params, ctx->id("CH1_FF_RX_H_CLK_EN"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_FF_TX_F_CLK_DIS", parse_config_str(str_or_default(ci->params, ctx->id("CH1_FF_TX_F_CLK_DIS"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_FF_TX_H_CLK_EN", parse_config_str(str_or_default(ci->params, ctx->id("CH1_FF_TX_H_CLK_EN"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_GE_AN_ENABLE", parse_config_str(str_or_default(ci->params, ctx->id("CH1_GE_AN_ENABLE"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_INVERT_RX", parse_config_str(str_or_default(ci->params, ctx->id("CH1_INVERT_RX"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_INVERT_TX", parse_config_str(str_or_default(ci->params, ctx->id("CH1_INVERT_TX"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_LDR_CORE2TX_SEL", parse_config_str(str_or_default(ci->params, ctx->id("CH1_LDR_CORE2TX_SEL"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_LDR_RX2CORE_SEL", parse_config_str(str_or_default(ci->params, ctx->id("CH1_LDR_RX2CORE_SEL"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_LEQ_OFFSET_SEL", parse_config_str(str_or_default(ci->params, ctx->id("CH1_LEQ_OFFSET_SEL"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_LEQ_OFFSET_TRIM", parse_config_str(str_or_default(ci->params, ctx->id("CH1_LEQ_OFFSET_TRIM"), "0"), 3));
|
||||||
|
tg.config.add_word("DCU.CH1_LSM_DISABLE", parse_config_str(str_or_default(ci->params, ctx->id("CH1_LSM_DISABLE"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_MATCH_2_ENABLE", parse_config_str(str_or_default(ci->params, ctx->id("CH1_MATCH_2_ENABLE"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_MATCH_4_ENABLE", parse_config_str(str_or_default(ci->params, ctx->id("CH1_MATCH_4_ENABLE"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_MIN_IPG_CNT", parse_config_str(str_or_default(ci->params, ctx->id("CH1_MIN_IPG_CNT"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH1_PCIE_EI_EN", parse_config_str(str_or_default(ci->params, ctx->id("CH1_PCIE_EI_EN"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_PCIE_MODE", parse_config_str(str_or_default(ci->params, ctx->id("CH1_PCIE_MODE"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_PCS_DET_TIME_SEL", parse_config_str(str_or_default(ci->params, ctx->id("CH1_PCS_DET_TIME_SEL"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH1_PDEN_SEL", parse_config_str(str_or_default(ci->params, ctx->id("CH1_PDEN_SEL"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_PRBS_ENABLE", parse_config_str(str_or_default(ci->params, ctx->id("CH1_PRBS_ENABLE"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_PRBS_LOCK", parse_config_str(str_or_default(ci->params, ctx->id("CH1_PRBS_LOCK"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_PRBS_SELECTION", parse_config_str(str_or_default(ci->params, ctx->id("CH1_PRBS_SELECTION"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_RATE_MODE_RX", parse_config_str(str_or_default(ci->params, ctx->id("CH1_RATE_MODE_RX"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_RATE_MODE_TX", parse_config_str(str_or_default(ci->params, ctx->id("CH1_RATE_MODE_TX"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_RCV_DCC_EN", parse_config_str(str_or_default(ci->params, ctx->id("CH1_RCV_DCC_EN"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_REG_BAND_OFFSET", parse_config_str(str_or_default(ci->params, ctx->id("CH1_REG_BAND_OFFSET"), "0"), 4));
|
||||||
|
tg.config.add_word("DCU.CH1_REG_BAND_SEL", parse_config_str(str_or_default(ci->params, ctx->id("CH1_REG_BAND_SEL"), "0"), 6));
|
||||||
|
tg.config.add_word("DCU.CH1_REG_IDAC_EN", parse_config_str(str_or_default(ci->params, ctx->id("CH1_REG_IDAC_EN"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_REG_IDAC_SEL", parse_config_str(str_or_default(ci->params, ctx->id("CH1_REG_IDAC_SEL"), "0"), 10));
|
||||||
|
tg.config.add_word("DCU.CH1_REQ_EN", parse_config_str(str_or_default(ci->params, ctx->id("CH1_REQ_EN"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_REQ_LVL_SET", parse_config_str(str_or_default(ci->params, ctx->id("CH1_REQ_LVL_SET"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH1_RIO_MODE", parse_config_str(str_or_default(ci->params, ctx->id("CH1_RIO_MODE"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_RLOS_SEL", parse_config_str(str_or_default(ci->params, ctx->id("CH1_RLOS_SEL"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_RPWDNB", parse_config_str(str_or_default(ci->params, ctx->id("CH1_RPWDNB"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_RTERM_RX", parse_config_str(str_or_default(ci->params, ctx->id("CH1_RTERM_RX"), "0"), 5));
|
||||||
|
tg.config.add_word("DCU.CH1_RTERM_TX", parse_config_str(str_or_default(ci->params, ctx->id("CH1_RTERM_TX"), "0"), 5));
|
||||||
|
tg.config.add_word("DCU.CH1_RXIN_CM", parse_config_str(str_or_default(ci->params, ctx->id("CH1_RXIN_CM"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH1_RXTERM_CM", parse_config_str(str_or_default(ci->params, ctx->id("CH1_RXTERM_CM"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH1_RX_DCO_CK_DIV", parse_config_str(str_or_default(ci->params, ctx->id("CH1_RX_DCO_CK_DIV"), "0"), 3));
|
||||||
|
tg.config.add_word("DCU.CH1_RX_DIV11_SEL", parse_config_str(str_or_default(ci->params, ctx->id("CH1_RX_DIV11_SEL"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_RX_GEAR_BYPASS", parse_config_str(str_or_default(ci->params, ctx->id("CH1_RX_GEAR_BYPASS"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_RX_GEAR_MODE", parse_config_str(str_or_default(ci->params, ctx->id("CH1_RX_GEAR_MODE"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_RX_LOS_CEQ", parse_config_str(str_or_default(ci->params, ctx->id("CH1_RX_LOS_CEQ"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH1_RX_LOS_EN", parse_config_str(str_or_default(ci->params, ctx->id("CH1_RX_LOS_EN"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_RX_LOS_HYST_EN", parse_config_str(str_or_default(ci->params, ctx->id("CH1_RX_LOS_HYST_EN"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_RX_LOS_LVL", parse_config_str(str_or_default(ci->params, ctx->id("CH1_RX_LOS_LVL"), "0"), 3));
|
||||||
|
tg.config.add_word("DCU.CH1_RX_RATE_SEL", parse_config_str(str_or_default(ci->params, ctx->id("CH1_RX_RATE_SEL"), "0"), 4));
|
||||||
|
tg.config.add_word("DCU.CH1_RX_SB_BYPASS", parse_config_str(str_or_default(ci->params, ctx->id("CH1_RX_SB_BYPASS"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_SB_BYPASS", parse_config_str(str_or_default(ci->params, ctx->id("CH1_SB_BYPASS"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_SEL_SD_RX_CLK", parse_config_str(str_or_default(ci->params, ctx->id("CH1_SEL_SD_RX_CLK"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_TDRV_DAT_SEL", parse_config_str(str_or_default(ci->params, ctx->id("CH1_TDRV_DAT_SEL"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH1_TDRV_POST_EN", parse_config_str(str_or_default(ci->params, ctx->id("CH1_TDRV_POST_EN"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_TDRV_PRE_EN", parse_config_str(str_or_default(ci->params, ctx->id("CH1_TDRV_PRE_EN"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_TDRV_SLICE0_CUR", parse_config_str(str_or_default(ci->params, ctx->id("CH1_TDRV_SLICE0_CUR"), "0"), 3));
|
||||||
|
tg.config.add_word("DCU.CH1_TDRV_SLICE0_SEL", parse_config_str(str_or_default(ci->params, ctx->id("CH1_TDRV_SLICE0_SEL"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH1_TDRV_SLICE1_CUR", parse_config_str(str_or_default(ci->params, ctx->id("CH1_TDRV_SLICE1_CUR"), "0"), 3));
|
||||||
|
tg.config.add_word("DCU.CH1_TDRV_SLICE1_SEL", parse_config_str(str_or_default(ci->params, ctx->id("CH1_TDRV_SLICE1_SEL"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH1_TDRV_SLICE2_CUR", parse_config_str(str_or_default(ci->params, ctx->id("CH1_TDRV_SLICE2_CUR"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH1_TDRV_SLICE2_SEL", parse_config_str(str_or_default(ci->params, ctx->id("CH1_TDRV_SLICE2_SEL"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH1_TDRV_SLICE3_CUR", parse_config_str(str_or_default(ci->params, ctx->id("CH1_TDRV_SLICE3_CUR"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH1_TDRV_SLICE3_SEL", parse_config_str(str_or_default(ci->params, ctx->id("CH1_TDRV_SLICE3_SEL"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH1_TDRV_SLICE4_CUR", parse_config_str(str_or_default(ci->params, ctx->id("CH1_TDRV_SLICE4_CUR"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH1_TDRV_SLICE4_SEL", parse_config_str(str_or_default(ci->params, ctx->id("CH1_TDRV_SLICE4_SEL"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH1_TDRV_SLICE5_CUR", parse_config_str(str_or_default(ci->params, ctx->id("CH1_TDRV_SLICE5_CUR"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH1_TDRV_SLICE5_SEL", parse_config_str(str_or_default(ci->params, ctx->id("CH1_TDRV_SLICE5_SEL"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH1_TPWDNB", parse_config_str(str_or_default(ci->params, ctx->id("CH1_TPWDNB"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_TX_CM_SEL", parse_config_str(str_or_default(ci->params, ctx->id("CH1_TX_CM_SEL"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.CH1_TX_DIV11_SEL", parse_config_str(str_or_default(ci->params, ctx->id("CH1_TX_DIV11_SEL"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_TX_GEAR_BYPASS", parse_config_str(str_or_default(ci->params, ctx->id("CH1_TX_GEAR_BYPASS"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_TX_GEAR_MODE", parse_config_str(str_or_default(ci->params, ctx->id("CH1_TX_GEAR_MODE"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_TX_POST_SIGN", parse_config_str(str_or_default(ci->params, ctx->id("CH1_TX_POST_SIGN"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_TX_PRE_SIGN", parse_config_str(str_or_default(ci->params, ctx->id("CH1_TX_PRE_SIGN"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_UC_MODE", parse_config_str(str_or_default(ci->params, ctx->id("CH1_UC_MODE"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_UDF_COMMA_A", parse_config_str(str_or_default(ci->params, ctx->id("CH1_UDF_COMMA_A"), "0"), 10));
|
||||||
|
tg.config.add_word("DCU.CH1_UDF_COMMA_B", parse_config_str(str_or_default(ci->params, ctx->id("CH1_UDF_COMMA_B"), "0"), 10));
|
||||||
|
tg.config.add_word("DCU.CH1_UDF_COMMA_MASK", parse_config_str(str_or_default(ci->params, ctx->id("CH1_UDF_COMMA_MASK"), "0"), 10));
|
||||||
|
tg.config.add_word("DCU.CH1_WA_BYPASS", parse_config_str(str_or_default(ci->params, ctx->id("CH1_WA_BYPASS"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.CH1_WA_MODE", parse_config_str(str_or_default(ci->params, ctx->id("CH1_WA_MODE"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.D_BITCLK_FROM_ND_EN", parse_config_str(str_or_default(ci->params, ctx->id("D_BITCLK_FROM_ND_EN"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.D_BITCLK_LOCAL_EN", parse_config_str(str_or_default(ci->params, ctx->id("D_BITCLK_LOCAL_EN"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.D_BITCLK_ND_EN", parse_config_str(str_or_default(ci->params, ctx->id("D_BITCLK_ND_EN"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.D_BUS8BIT_SEL", parse_config_str(str_or_default(ci->params, ctx->id("D_BUS8BIT_SEL"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.D_CDR_LOL_SET", parse_config_str(str_or_default(ci->params, ctx->id("D_CDR_LOL_SET"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.D_CMUSETBIASI", parse_config_str(str_or_default(ci->params, ctx->id("D_CMUSETBIASI"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.D_CMUSETI4CPP", parse_config_str(str_or_default(ci->params, ctx->id("D_CMUSETI4CPP"), "0"), 4));
|
||||||
|
tg.config.add_word("DCU.D_CMUSETI4CPZ", parse_config_str(str_or_default(ci->params, ctx->id("D_CMUSETI4CPZ"), "0"), 4));
|
||||||
|
tg.config.add_word("DCU.D_CMUSETI4VCO", parse_config_str(str_or_default(ci->params, ctx->id("D_CMUSETI4VCO"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.D_CMUSETICP4P", parse_config_str(str_or_default(ci->params, ctx->id("D_CMUSETICP4P"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.D_CMUSETICP4Z", parse_config_str(str_or_default(ci->params, ctx->id("D_CMUSETICP4Z"), "0"), 3));
|
||||||
|
tg.config.add_word("DCU.D_CMUSETINITVCT", parse_config_str(str_or_default(ci->params, ctx->id("D_CMUSETINITVCT"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.D_CMUSETISCL4VCO", parse_config_str(str_or_default(ci->params, ctx->id("D_CMUSETISCL4VCO"), "0"), 3));
|
||||||
|
tg.config.add_word("DCU.D_CMUSETP1GM", parse_config_str(str_or_default(ci->params, ctx->id("D_CMUSETP1GM"), "0"), 3));
|
||||||
|
tg.config.add_word("DCU.D_CMUSETP2AGM", parse_config_str(str_or_default(ci->params, ctx->id("D_CMUSETP2AGM"), "0"), 3));
|
||||||
|
tg.config.add_word("DCU.D_CMUSETZGM", parse_config_str(str_or_default(ci->params, ctx->id("D_CMUSETZGM"), "0"), 3));
|
||||||
|
tg.config.add_word("DCU.D_DCO_CALIB_TIME_SEL", parse_config_str(str_or_default(ci->params, ctx->id("D_DCO_CALIB_TIME_SEL"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.D_HIGH_MARK", parse_config_str(str_or_default(ci->params, ctx->id("D_HIGH_MARK"), "0"), 4));
|
||||||
|
tg.config.add_word("DCU.D_IB_PWDNB", parse_config_str(str_or_default(ci->params, ctx->id("D_IB_PWDNB"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.D_ISETLOS", parse_config_str(str_or_default(ci->params, ctx->id("D_ISETLOS"), "0"), 8));
|
||||||
|
tg.config.add_word("DCU.D_LOW_MARK", parse_config_str(str_or_default(ci->params, ctx->id("D_LOW_MARK"), "0"), 4));
|
||||||
|
tg.config.add_word("DCU.D_MACROPDB", parse_config_str(str_or_default(ci->params, ctx->id("D_MACROPDB"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.D_PD_ISET", parse_config_str(str_or_default(ci->params, ctx->id("D_PD_ISET"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.D_PLL_LOL_SET", parse_config_str(str_or_default(ci->params, ctx->id("D_PLL_LOL_SET"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.D_REFCK_MODE", parse_config_str(str_or_default(ci->params, ctx->id("D_REFCK_MODE"), "0"), 3));
|
||||||
|
tg.config.add_word("DCU.D_REQ_ISET", parse_config_str(str_or_default(ci->params, ctx->id("D_REQ_ISET"), "0"), 3));
|
||||||
|
tg.config.add_word("DCU.D_RG_EN", parse_config_str(str_or_default(ci->params, ctx->id("D_RG_EN"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.D_RG_SET", parse_config_str(str_or_default(ci->params, ctx->id("D_RG_SET"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.D_SETICONST_AUX", parse_config_str(str_or_default(ci->params, ctx->id("D_SETICONST_AUX"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.D_SETICONST_CH", parse_config_str(str_or_default(ci->params, ctx->id("D_SETICONST_CH"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.D_SETIRPOLY_AUX", parse_config_str(str_or_default(ci->params, ctx->id("D_SETIRPOLY_AUX"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.D_SETIRPOLY_CH", parse_config_str(str_or_default(ci->params, ctx->id("D_SETIRPOLY_CH"), "0"), 2));
|
||||||
|
tg.config.add_word("DCU.D_SETPLLRC", parse_config_str(str_or_default(ci->params, ctx->id("D_SETPLLRC"), "0"), 6));
|
||||||
|
tg.config.add_word("DCU.D_SYNC_LOCAL_EN", parse_config_str(str_or_default(ci->params, ctx->id("D_SYNC_LOCAL_EN"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.D_SYNC_ND_EN", parse_config_str(str_or_default(ci->params, ctx->id("D_SYNC_ND_EN"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.D_TXPLL_PWDNB", parse_config_str(str_or_default(ci->params, ctx->id("D_TXPLL_PWDNB"), "0"), 1));
|
||||||
|
tg.config.add_word("DCU.D_TX_VCO_CK_DIV", parse_config_str(str_or_default(ci->params, ctx->id("D_TX_VCO_CK_DIV"), "0"), 3));
|
||||||
|
tg.config.add_word("DCU.D_XGE_MODE", parse_config_str(str_or_default(ci->params, ctx->id("D_XGE_MODE"), "0"), 1));
|
@ -55,6 +55,9 @@ class Ecp5GlobalRouter
|
|||||||
{
|
{
|
||||||
if (user.cell->type == id_TRELLIS_SLICE && (user.port == id_CLK || user.port == id_WCK))
|
if (user.cell->type == id_TRELLIS_SLICE && (user.port == id_CLK || user.port == id_WCK))
|
||||||
return true;
|
return true;
|
||||||
|
if (user.cell->type == id_DCUA && (user.port == id_CH0_FF_RXI_CLK || user.port == id_CH1_FF_RXI_CLK ||
|
||||||
|
user.port == id_CH0_FF_TXI_CLK || user.port == id_CH1_FF_TXI_CLK))
|
||||||
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,8 +68,11 @@ class Ecp5GlobalRouter
|
|||||||
NetInfo *ni = net.second.get();
|
NetInfo *ni = net.second.get();
|
||||||
clockCount[ni->name] = 0;
|
clockCount[ni->name] = 0;
|
||||||
for (const auto &user : ni->users) {
|
for (const auto &user : ni->users) {
|
||||||
if (is_clock_port(user))
|
if (is_clock_port(user)) {
|
||||||
clockCount[ni->name]++;
|
clockCount[ni->name]++;
|
||||||
|
if (user.cell->type == id_DCUA)
|
||||||
|
clockCount[ni->name] += 100;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// log_info("clkcount %s: %d\n", ni->name.c_str(ctx),clockCount[ni->name]);
|
// log_info("clkcount %s: %d\n", ni->name.c_str(ctx),clockCount[ni->name]);
|
||||||
}
|
}
|
||||||
@ -290,6 +296,10 @@ class Ecp5GlobalRouter
|
|||||||
float tns;
|
float tns;
|
||||||
return get_net_metric(ctx, clki, MetricType::WIRELENGTH, tns);
|
return get_net_metric(ctx, clki, MetricType::WIRELENGTH, tns);
|
||||||
} else {
|
} else {
|
||||||
|
// Check for dedicated routing
|
||||||
|
if (has_short_route(ctx->getBelPinWire(drv_bel, drv.port), ctx->getBelPinWire(dcc->bel, id_CLKI))) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
// Driver is locked
|
// Driver is locked
|
||||||
Loc dcc_loc = ctx->getBelLocation(dcc->bel);
|
Loc dcc_loc = ctx->getBelLocation(dcc->bel);
|
||||||
Loc drv_loc = ctx->getBelLocation(drv_bel);
|
Loc drv_loc = ctx->getBelLocation(drv_bel);
|
||||||
@ -297,6 +307,46 @@ class Ecp5GlobalRouter
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return true if a short (<5) route exists between two wires
|
||||||
|
bool has_short_route(WireId src, WireId dst, int thresh = 5)
|
||||||
|
{
|
||||||
|
std::queue<WireId> visit;
|
||||||
|
std::unordered_map<WireId, PipId> backtrace;
|
||||||
|
visit.push(src);
|
||||||
|
WireId cursor;
|
||||||
|
while (true) {
|
||||||
|
|
||||||
|
if (visit.empty() || visit.size() > 1000) {
|
||||||
|
// log_info ("dist %s -> %s = inf\n", ctx->getWireName(src).c_str(ctx),
|
||||||
|
// ctx->getWireName(dst).c_str(ctx));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
cursor = visit.front();
|
||||||
|
visit.pop();
|
||||||
|
|
||||||
|
if (cursor == dst)
|
||||||
|
break;
|
||||||
|
for (auto dh : ctx->getPipsDownhill(cursor)) {
|
||||||
|
WireId pipDst = ctx->getPipDstWire(dh);
|
||||||
|
if (backtrace.count(pipDst))
|
||||||
|
continue;
|
||||||
|
backtrace[pipDst] = dh;
|
||||||
|
visit.push(pipDst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int length = 0;
|
||||||
|
while (true) {
|
||||||
|
auto fnd = backtrace.find(cursor);
|
||||||
|
if (fnd == backtrace.end())
|
||||||
|
break;
|
||||||
|
cursor = ctx->getPipSrcWire(fnd->second);
|
||||||
|
length++;
|
||||||
|
}
|
||||||
|
// log_info ("dist %s -> %s = %d\n", ctx->getWireName(src).c_str(ctx), ctx->getWireName(dst).c_str(ctx),
|
||||||
|
// length);
|
||||||
|
return length < thresh;
|
||||||
|
}
|
||||||
|
|
||||||
// Attempt to place a DCC
|
// Attempt to place a DCC
|
||||||
void place_dcc(CellInfo *dcc)
|
void place_dcc(CellInfo *dcc)
|
||||||
{
|
{
|
||||||
@ -335,6 +385,8 @@ class Ecp5GlobalRouter
|
|||||||
for (auto user : net->users) {
|
for (auto user : net->users) {
|
||||||
if (user.port == id_CLKFB) {
|
if (user.port == id_CLKFB) {
|
||||||
keep_users.push_back(user);
|
keep_users.push_back(user);
|
||||||
|
} else if (net->driver.cell->type == id_EXTREFB && user.cell->type == id_DCUA) {
|
||||||
|
keep_users.push_back(user);
|
||||||
} else {
|
} else {
|
||||||
glbnet->users.push_back(user);
|
glbnet->users.push_back(user);
|
||||||
user.cell->ports.at(user.port).net = glbnet.get();
|
user.cell->ports.at(user.port).net = glbnet.get();
|
||||||
|
142
ecp5/pack.cc
142
ecp5/pack.cc
@ -235,6 +235,46 @@ class Ecp5Packer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return true if an port is a top level port that provides its own IOBUF
|
||||||
|
bool is_top_port(PortRef &port)
|
||||||
|
{
|
||||||
|
if (port.cell == nullptr)
|
||||||
|
return false;
|
||||||
|
if (port.cell->type == id_DCUA) {
|
||||||
|
return port.port == id_CH0_HDINP || port.port == id_CH0_HDINN || port.port == id_CH0_HDOUTP ||
|
||||||
|
port.port == id_CH0_HDOUTN || port.port == id_CH1_HDINP || port.port == id_CH1_HDINN ||
|
||||||
|
port.port == id_CH1_HDOUTP || port.port == id_CH1_HDOUTN;
|
||||||
|
} else if (port.cell->type == id_EXTREFB) {
|
||||||
|
return port.port == id_REFCLKP || port.port == id_REFCLKN;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return true if a net only drives a top port
|
||||||
|
bool drives_top_port(NetInfo *net, PortRef &tp)
|
||||||
|
{
|
||||||
|
if (net == nullptr)
|
||||||
|
return false;
|
||||||
|
for (auto user : net->users) {
|
||||||
|
if (is_top_port(user)) {
|
||||||
|
if (net->users.size() > 1)
|
||||||
|
log_error(" port %s.%s must be connected to (and only to) a top level pin\n",
|
||||||
|
user.cell->name.c_str(ctx), user.port.c_str(ctx));
|
||||||
|
tp = user;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (net->driver.cell != nullptr && is_top_port(net->driver)) {
|
||||||
|
if (net->users.size() > 1)
|
||||||
|
log_error(" port %s.%s must be connected to (and only to) a top level pin\n",
|
||||||
|
net->driver.cell->name.c_str(ctx), net->driver.port.c_str(ctx));
|
||||||
|
tp = net->driver;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Simple "packer" to remove nextpnr IOBUFs, this assumes IOBUFs are manually instantiated
|
// Simple "packer" to remove nextpnr IOBUFs, this assumes IOBUFs are manually instantiated
|
||||||
void pack_io()
|
void pack_io()
|
||||||
{
|
{
|
||||||
@ -244,10 +284,14 @@ class Ecp5Packer
|
|||||||
CellInfo *ci = cell.second;
|
CellInfo *ci = cell.second;
|
||||||
if (is_nextpnr_iob(ctx, ci)) {
|
if (is_nextpnr_iob(ctx, ci)) {
|
||||||
CellInfo *trio = nullptr;
|
CellInfo *trio = nullptr;
|
||||||
|
NetInfo *ionet = nullptr;
|
||||||
|
PortRef tp;
|
||||||
if (ci->type == ctx->id("$nextpnr_ibuf") || ci->type == ctx->id("$nextpnr_iobuf")) {
|
if (ci->type == ctx->id("$nextpnr_ibuf") || ci->type == ctx->id("$nextpnr_iobuf")) {
|
||||||
trio = net_only_drives(ctx, ci->ports.at(ctx->id("O")).net, is_trellis_io, ctx->id("B"), true, ci);
|
ionet = ci->ports.at(ctx->id("O")).net;
|
||||||
|
trio = net_only_drives(ctx, ionet, is_trellis_io, ctx->id("B"), true, ci);
|
||||||
|
|
||||||
} else if (ci->type == ctx->id("$nextpnr_obuf")) {
|
} else if (ci->type == ctx->id("$nextpnr_obuf")) {
|
||||||
|
ionet = ci->ports.at(ctx->id("I")).net;
|
||||||
trio = net_only_drives(ctx, ci->ports.at(ctx->id("I")).net, is_trellis_io, ctx->id("B"), true, ci);
|
trio = net_only_drives(ctx, ci->ports.at(ctx->id("I")).net, is_trellis_io, ctx->id("B"), true, ci);
|
||||||
}
|
}
|
||||||
if (trio != nullptr) {
|
if (trio != nullptr) {
|
||||||
@ -266,6 +310,19 @@ class Ecp5Packer
|
|||||||
ctx->nets.erase(net2->name);
|
ctx->nets.erase(net2->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (drives_top_port(ionet, tp)) {
|
||||||
|
log_info("%s feeds %s %s.%s, removing %s %s.\n", ci->name.c_str(ctx), tp.cell->type.c_str(ctx),
|
||||||
|
tp.cell->name.c_str(ctx), tp.port.c_str(ctx), ci->type.c_str(ctx), ci->name.c_str(ctx));
|
||||||
|
if (ionet != nullptr) {
|
||||||
|
ctx->nets.erase(ionet->name);
|
||||||
|
tp.cell->ports.at(tp.port).net = nullptr;
|
||||||
|
}
|
||||||
|
if (ci->type == ctx->id("$nextpnr_iobuf")) {
|
||||||
|
NetInfo *net2 = ci->ports.at(ctx->id("I")).net;
|
||||||
|
if (net2 != nullptr) {
|
||||||
|
ctx->nets.erase(net2->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Create a TRELLIS_IO buffer
|
// Create a TRELLIS_IO buffer
|
||||||
std::unique_ptr<CellInfo> tr_cell =
|
std::unique_ptr<CellInfo> tr_cell =
|
||||||
@ -276,6 +333,7 @@ class Ecp5Packer
|
|||||||
}
|
}
|
||||||
|
|
||||||
packed_cells.insert(ci->name);
|
packed_cells.insert(ci->name);
|
||||||
|
if (trio != nullptr) {
|
||||||
for (const auto &attr : ci->attrs)
|
for (const auto &attr : ci->attrs)
|
||||||
trio->attrs[attr.first] = attr.second;
|
trio->attrs[attr.first] = attr.second;
|
||||||
|
|
||||||
@ -294,6 +352,7 @@ class Ecp5Packer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
flush_cells();
|
flush_cells();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1033,12 +1092,93 @@ class Ecp5Packer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// "Pack" DCUs
|
||||||
|
void pack_dcus()
|
||||||
|
{
|
||||||
|
for (auto cell : sorted(ctx->cells)) {
|
||||||
|
CellInfo *ci = cell.second;
|
||||||
|
if (ci->type == id_DCUA) {
|
||||||
|
if (ci->attrs.count(ctx->id("LOC"))) {
|
||||||
|
std::string loc = ci->attrs.at(ctx->id("LOC"));
|
||||||
|
if (loc == "DCU0" &&
|
||||||
|
(ctx->args.type == ArchArgs::LFE5UM_25F || ctx->args.type == ArchArgs::LFE5UM5G_25F))
|
||||||
|
ci->attrs[ctx->id("BEL")] = "X42/Y50/DCU";
|
||||||
|
else if (loc == "DCU0" &&
|
||||||
|
(ctx->args.type == ArchArgs::LFE5UM_45F || ctx->args.type == ArchArgs::LFE5UM5G_45F))
|
||||||
|
ci->attrs[ctx->id("BEL")] = "X42/Y71/DCU";
|
||||||
|
else if (loc == "DCU1" &&
|
||||||
|
(ctx->args.type == ArchArgs::LFE5UM_45F || ctx->args.type == ArchArgs::LFE5UM5G_45F))
|
||||||
|
ci->attrs[ctx->id("BEL")] = "X69/Y71/DCU";
|
||||||
|
else if (loc == "DCU0" &&
|
||||||
|
(ctx->args.type == ArchArgs::LFE5UM_85F || ctx->args.type == ArchArgs::LFE5UM5G_85F))
|
||||||
|
ci->attrs[ctx->id("BEL")] = "X46/Y95/DCU";
|
||||||
|
else if (loc == "DCU1" &&
|
||||||
|
(ctx->args.type == ArchArgs::LFE5UM_85F || ctx->args.type == ArchArgs::LFE5UM5G_85F))
|
||||||
|
ci->attrs[ctx->id("BEL")] = "X71/Y95/DCU";
|
||||||
|
else
|
||||||
|
log_error("no DCU location '%s' in device '%s'\n", loc.c_str(), ctx->getChipName().c_str());
|
||||||
|
}
|
||||||
|
if (!ci->attrs.count(ctx->id("BEL")))
|
||||||
|
log_error("DCU must be constrained to a Bel!\n");
|
||||||
|
// Empty port auto-creation to generate correct tie-downs
|
||||||
|
BelId exemplar_bel;
|
||||||
|
for (auto bel : ctx->getBels()) {
|
||||||
|
if (ctx->getBelType(bel) == id_DCUA) {
|
||||||
|
exemplar_bel = bel;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NPNR_ASSERT(exemplar_bel != BelId());
|
||||||
|
for (auto pin : ctx->getBelPins(exemplar_bel))
|
||||||
|
if (ctx->getBelPinType(exemplar_bel, pin) == PORT_IN)
|
||||||
|
autocreate_empty_port(ci, pin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (auto cell : sorted(ctx->cells)) {
|
||||||
|
CellInfo *ci = cell.second;
|
||||||
|
if (ci->type == id_EXTREFB) {
|
||||||
|
const NetInfo *refo = net_or_nullptr(ci, id_REFCLKO);
|
||||||
|
CellInfo *dcu = nullptr;
|
||||||
|
if (refo == nullptr)
|
||||||
|
log_error("EXTREFB REFCLKO must not be unconnected\n");
|
||||||
|
for (auto user : refo->users) {
|
||||||
|
if (user.cell->type != id_DCUA)
|
||||||
|
continue;
|
||||||
|
if (dcu != nullptr && dcu != user.cell)
|
||||||
|
log_error("EXTREFB REFCLKO must only drive a single DCUA\n");
|
||||||
|
dcu = user.cell;
|
||||||
|
}
|
||||||
|
if (!dcu->attrs.count(ctx->id("BEL")))
|
||||||
|
log_error("DCU must be constrained to a Bel!\n");
|
||||||
|
std::string bel = dcu->attrs.at(ctx->id("BEL"));
|
||||||
|
NPNR_ASSERT(bel.substr(bel.length() - 3) == "DCU");
|
||||||
|
bel.replace(bel.length() - 3, 3, "EXTREF");
|
||||||
|
ci->attrs[ctx->id("BEL")] = bel;
|
||||||
|
} else if (ci->type == id_PCSCLKDIV) {
|
||||||
|
const NetInfo *clki = net_or_nullptr(ci, id_CLKI);
|
||||||
|
if (clki != nullptr && clki->driver.cell != nullptr && clki->driver.cell->type == id_DCUA) {
|
||||||
|
CellInfo *dcu = clki->driver.cell;
|
||||||
|
if (!dcu->attrs.count(ctx->id("BEL")))
|
||||||
|
log_error("DCU must be constrained to a Bel!\n");
|
||||||
|
BelId bel = ctx->getBelByName(ctx->id(dcu->attrs.at(ctx->id("BEL"))));
|
||||||
|
if (bel == BelId())
|
||||||
|
log_error("Invalid DCU bel '%s'\n", dcu->attrs.at(ctx->id("BEL")).c_str());
|
||||||
|
Loc loc = ctx->getBelLocation(bel);
|
||||||
|
// DCU0 -> CLKDIV z=0; DCU1 -> CLKDIV z=1
|
||||||
|
ci->constr_abs_z = true;
|
||||||
|
ci->constr_z = (loc.x >= 69) ? 1 : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void pack()
|
void pack()
|
||||||
{
|
{
|
||||||
pack_io();
|
pack_io();
|
||||||
pack_ebr();
|
pack_ebr();
|
||||||
pack_dsps();
|
pack_dsps();
|
||||||
|
pack_dcus();
|
||||||
pack_constants();
|
pack_constants();
|
||||||
pack_dram();
|
pack_dram();
|
||||||
pack_carries();
|
pack_carries();
|
||||||
|
@ -200,9 +200,14 @@ def write_database(dev_name, chip, ddrg, endianness):
|
|||||||
write_loc(arc.sinkWire.rel, "dst")
|
write_loc(arc.sinkWire.rel, "dst")
|
||||||
bba.u32(arc.srcWire.id, "src_idx")
|
bba.u32(arc.srcWire.id, "src_idx")
|
||||||
bba.u32(arc.sinkWire.id, "dst_idx")
|
bba.u32(arc.sinkWire.id, "dst_idx")
|
||||||
bba.u32(get_pip_delay(get_wire_name(idx, arc.srcWire.rel, arc.srcWire.id), get_wire_name(idx, arc.sinkWire.rel, arc.sinkWire.id)), "delay") # TODO:delay
|
src_name = get_wire_name(idx, arc.srcWire.rel, arc.srcWire.id)
|
||||||
|
snk_name = get_wire_name(idx, arc.sinkWire.rel, arc.sinkWire.id)
|
||||||
|
bba.u32(get_pip_delay(src_name, snk_name), "delay") # TODO:delay
|
||||||
bba.u16(get_tiletype_index(ddrg.to_str(arc.tiletype)), "tile_type")
|
bba.u16(get_tiletype_index(ddrg.to_str(arc.tiletype)), "tile_type")
|
||||||
bba.u8(int(arc.cls), "pip_type")
|
cls = arc.cls
|
||||||
|
if cls == 1 and "PCS" in snk_name or "DCU" in snk_name or "DCU" in src_name:
|
||||||
|
cls = 2
|
||||||
|
bba.u8(cls, "pip_type")
|
||||||
bba.u8(0, "padding")
|
bba.u8(0, "padding")
|
||||||
if len(loctype.wires) > 0:
|
if len(loctype.wires) > 0:
|
||||||
for wire_idx in range(len(loctype.wires)):
|
for wire_idx in range(len(loctype.wires)):
|
||||||
@ -340,7 +345,7 @@ def write_database(dev_name, chip, ddrg, endianness):
|
|||||||
bba.pop()
|
bba.pop()
|
||||||
return bba
|
return bba
|
||||||
|
|
||||||
dev_names = {"25k": "LFE5U-25F", "45k": "LFE5U-45F", "85k": "LFE5U-85F"}
|
dev_names = {"25k": "LFE5UM5G-25F", "45k": "LFE5UM5G-45F", "85k": "LFE5UM5G-85F"}
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
global max_row, max_col
|
global max_row, max_col
|
||||||
|
Loading…
Reference in New Issue
Block a user