aboutsummaryrefslogtreecommitdiffstats
path: root/ice40/pack.cc
diff options
context:
space:
mode:
authorSylvain Munaut <tnt@246tNt.com>2018-11-16 02:03:25 +0100
committerSylvain Munaut <tnt@246tNt.com>2018-11-19 18:20:20 +0100
commitd8e4c21d96bfca7da60d0c445a1fdba48f46e9e1 (patch)
treefff58a215b70b7746f5793f2e23de82194133f29 /ice40/pack.cc
parentbc9f2da470b96c4e2f65324a0da1ffe099b5e586 (diff)
downloadnextpnr-d8e4c21d96bfca7da60d0c445a1fdba48f46e9e1.tar.gz
nextpnr-d8e4c21d96bfca7da60d0c445a1fdba48f46e9e1.tar.bz2
nextpnr-d8e4c21d96bfca7da60d0c445a1fdba48f46e9e1.zip
ice40: Add support for PLL global outputs via PADIN
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
Diffstat (limited to 'ice40/pack.cc')
-rw-r--r--ice40/pack.cc63
1 files changed, 23 insertions, 40 deletions
diff --git a/ice40/pack.cc b/ice40/pack.cc
index cae6ab8c..ca67baab 100644
--- a/ice40/pack.cc
+++ b/ice40/pack.cc
@@ -790,32 +790,6 @@ static void pack_special(Context *ctx)
NetInfo *pad_packagepin_net = nullptr;
- int pllout_a_used = 0;
- int pllout_b_used = 0;
- for (auto port : ci->ports) {
- PortInfo &pi = port.second;
- if (pi.name == ctx->id("PLLOUTCOREA"))
- pllout_a_used++;
- if (pi.name == ctx->id("PLLOUTCOREB"))
- pllout_b_used++;
- if (pi.name == ctx->id("PLLOUTCORE"))
- pllout_a_used++;
- if (pi.name == ctx->id("PLLOUTGLOBALA"))
- pllout_a_used++;
- if (pi.name == ctx->id("PLLOUTGLOBALB"))
- pllout_b_used++;
- if (pi.name == ctx->id("PLLOUTGLOBAL"))
- pllout_a_used++;
- }
-
- if (pllout_a_used > 1)
- log_error("PLL '%s' is using multiple ports mapping to PLLOUT_A output of the PLL\n",
- ci->name.c_str(ctx));
-
- if (pllout_b_used > 1)
- log_error("PLL '%s' is using multiple ports mapping to PLLOUT_B output of the PLL\n",
- ci->name.c_str(ctx));
-
for (auto port : ci->ports) {
PortInfo &pi = port.second;
std::string newname = pi.name.str(ctx);
@@ -823,24 +797,15 @@ static void pack_special(Context *ctx)
if (bpos != std::string::npos) {
newname = newname.substr(0, bpos) + "_" + newname.substr(bpos + 1, (newname.size() - bpos) - 2);
}
- if (pi.name == ctx->id("PLLOUTCOREA"))
+
+ if (pi.name == ctx->id("PLLOUTCOREA") || pi.name == ctx->id("PLLOUTCORE"))
newname = "PLLOUT_A";
if (pi.name == ctx->id("PLLOUTCOREB"))
newname = "PLLOUT_B";
- if (pi.name == ctx->id("PLLOUTCORE"))
- newname = "PLLOUT_A";
- if (pi.name == ctx->id("PLLOUTGLOBALA"))
- newname = "PLLOUT_A";
+ if (pi.name == ctx->id("PLLOUTGLOBALA") || pi.name == ctx->id("PLLOUTGLOBALA"))
+ newname = "PLLOUT_A_GLOBAL";
if (pi.name == ctx->id("PLLOUTGLOBALB"))
- newname = "PLLOUT_B";
- if (pi.name == ctx->id("PLLOUTGLOBAL"))
- newname = "PLLOUT_A";
-
- if (pi.name == ctx->id("PLLOUTGLOBALA") || pi.name == ctx->id("PLLOUTGLOBALB") ||
- pi.name == ctx->id("PLLOUTGLOBAL"))
- log_warning("PLL '%s' is using port %s but implementation does not actually "
- "use the global clock output of the PLL\n",
- ci->name.c_str(ctx), pi.name.str(ctx).c_str());
+ newname = "PLLOUT_B_GLOBAL";
if (pi.name == ctx->id("PACKAGEPIN")) {
if (!is_pad) {
@@ -1011,6 +976,24 @@ static void pack_special(Context *ctx)
}
}
+ // Handle the global buffer connections
+ for (auto port : packed->ports) {
+ PortInfo &pi = port.second;
+ bool is_b_port;
+
+ if (pi.name == ctx->id("PLLOUT_A_GLOBAL"))
+ is_b_port = false;
+ else if (pi.name == ctx->id("PLLOUT_B_GLOBAL"))
+ is_b_port = true;
+ else
+ continue;
+
+ std::unique_ptr<CellInfo> gb =
+ create_padin_gbuf(ctx, packed.get(), pi.name,
+ "$gbuf_" + ci->name.str(ctx) + "_pllout_" + (is_b_port ? "b" : "a"));
+ new_cells.push_back(std::move(gb));
+ }
+
new_cells.push_back(std::move(packed));
}
}