aboutsummaryrefslogtreecommitdiffstats
path: root/ecp5
diff options
context:
space:
mode:
authorDavid Shah <dave@ds0.me>2020-05-18 09:38:41 +0100
committerGitHub <noreply@github.com>2020-05-18 09:38:41 +0100
commit2d406f3e275beda8b70b4c7d4d5e43433dd3c43c (patch)
treea95e996ab39cf3447710ce93161e97419591854b /ecp5
parentddf546c2cc8a99da320921f9b49a01b865ee04c9 (diff)
parent163dee1e1ad90091cbb2742190a07aa87fa83d7f (diff)
downloadnextpnr-2d406f3e275beda8b70b4c7d4d5e43433dd3c43c.tar.gz
nextpnr-2d406f3e275beda8b70b4c7d4d5e43433dd3c43c.tar.bz2
nextpnr-2d406f3e275beda8b70b4c7d4d5e43433dd3c43c.zip
Merge pull request #440 from YosysHQ/lattice-fixes
Fixes for the Lattice SERDES eye demo designs
Diffstat (limited to 'ecp5')
-rw-r--r--ecp5/globals.cc13
-rw-r--r--ecp5/lpf.cc3
-rw-r--r--ecp5/pack.cc12
3 files changed, 28 insertions, 0 deletions
diff --git a/ecp5/globals.cc b/ecp5/globals.cc
index 65b1710f..550af615 100644
--- a/ecp5/globals.cc
+++ b/ecp5/globals.cc
@@ -63,11 +63,20 @@ class Ecp5GlobalRouter
return false;
}
+ bool is_logic_port(const PortRef &user)
+ {
+ if (user.cell->type == id_TRELLIS_SLICE && user.port != id_CLK && user.port != id_WCK)
+ return true;
+ return false;
+ }
+
std::vector<NetInfo *> get_clocks()
{
std::unordered_map<IdString, int> clockCount;
for (auto &net : ctx->nets) {
NetInfo *ni = net.second.get();
+ if (ni->name == ctx->id("$PACKER_GND_NET") || ni->name == ctx->id("$PACKER_VCC_NET"))
+ continue;
clockCount[ni->name] = 0;
for (const auto &user : ni->users) {
if (is_clock_port(user)) {
@@ -160,6 +169,8 @@ class Ecp5GlobalRouter
if (ctx->checkWireAvail(next)) {
for (auto pip : ctx->getPipsUphill(next)) {
WireId src = ctx->getPipSrcWire(pip);
+ if (backtrace.count(src))
+ continue;
backtrace[src] = pip;
upstream.push(src);
}
@@ -412,6 +423,8 @@ class Ecp5GlobalRouter
keep_users.push_back(user);
} else if (net->driver.cell->type == id_EXTREFB && user.cell->type == id_DCUA) {
keep_users.push_back(user);
+ } else if (is_logic_port(user)) {
+ keep_users.push_back(user);
} else {
glbnet->users.push_back(user);
user.cell->ports.at(user.port).net = glbnet.get();
diff --git a/ecp5/lpf.cc b/ecp5/lpf.cc
index e626cc54..e740b737 100644
--- a/ecp5/lpf.cc
+++ b/ecp5/lpf.cc
@@ -48,6 +48,9 @@ bool Arch::applyLPF(std::string filename, std::istream &in)
size_t cstart = line.find('#');
if (cstart != std::string::npos)
line = line.substr(0, cstart);
+ cstart = line.find("//");
+ if (cstart != std::string::npos)
+ line = line.substr(0, cstart);
if (isempty(line))
continue;
linebuf += line;
diff --git a/ecp5/pack.cc b/ecp5/pack.cc
index 55b2c791..fb8a95e9 100644
--- a/ecp5/pack.cc
+++ b/ecp5/pack.cc
@@ -1617,6 +1617,18 @@ class Ecp5Packer
for (auto pin : ctx->getBelPins(exemplar_bel))
if (ctx->getBelPinType(exemplar_bel, pin) == PORT_IN)
autocreate_empty_port(ci, pin);
+ // Disconnect these ports if connected to constant to prevent routing failure
+ for (auto ndport : {id_D_TXBIT_CLKP_FROM_ND, id_D_TXBIT_CLKN_FROM_ND, id_D_SYNC_ND,
+ id_D_TXPLL_LOL_FROM_ND, id_CH0_HDINN, id_CH0_HDINP, id_CH1_HDINN, id_CH1_HDINP}) {
+ const NetInfo *net = get_net_or_empty(ci, ndport);
+ if (net == nullptr || net->driver.cell == nullptr)
+ continue;
+ IdString ct = net->driver.cell->type;
+ if (ct == ctx->id("GND") || ct == ctx->id("VCC")) {
+ disconnect_port(ctx, ci, ndport);
+ ci->ports.erase(ndport);
+ }
+ }
}
}
for (auto cell : sorted(ctx->cells)) {