aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/log.cc2
-rw-r--r--gui/designwidget.cc8
-rw-r--r--ice40/cells.cc2
-rw-r--r--ice40/pack.cc42
4 files changed, 46 insertions, 8 deletions
diff --git a/common/log.cc b/common/log.cc
index e30449ad..3ae553e9 100644
--- a/common/log.cc
+++ b/common/log.cc
@@ -195,7 +195,6 @@ void log_info(const char *format, ...)
void log_warning(const char *format, ...)
{
- if (log_quiet_warnings) return;
va_list ap;
va_start(ap, format);
logv_warning(format, ap);
@@ -204,7 +203,6 @@ void log_warning(const char *format, ...)
void log_warning_noprefix(const char *format, ...)
{
- if (log_quiet_warnings) return;
va_list ap;
va_start(ap, format);
logv_warning_noprefix(format, ap);
diff --git a/gui/designwidget.cc b/gui/designwidget.cc
index c49df085..34f151a8 100644
--- a/gui/designwidget.cc
+++ b/gui/designwidget.cc
@@ -827,7 +827,9 @@ void DesignWidget::onHoverIndexChanged(QModelIndex index)
if (index.isValid()) {
TreeModel::Item *item = treeModel->nodeFromIndex(index);
if (item->type() != ElementType::NONE) {
- Q_EMIT hover(getDecals(item->type(), item->id()).at(0));
+ std::vector<DecalXY> decals = getDecals(item->type(), item->id());
+ if (decals.size()>0)
+ Q_EMIT hover(decals.at(0));
return;
}
}
@@ -844,7 +846,9 @@ void DesignWidget::onHoverPropertyChanged(QtBrowserItem *item)
if (value!=IdString()) {
auto node = treeModel->nodeForIdType(type, value);
if (node) {
- Q_EMIT hover(getDecals((*node)->type(), (*node)->id()).at(0));
+ std::vector<DecalXY> decals = getDecals((*node)->type(), (*node)->id());
+ if (decals.size()>0)
+ Q_EMIT hover(decals.at(0));
return;
}
}
diff --git a/ice40/cells.cc b/ice40/cells.cc
index 70b89631..886dae2a 100644
--- a/ice40/cells.cc
+++ b/ice40/cells.cc
@@ -243,6 +243,8 @@ std::unique_ptr<CellInfo> create_ice_cell(Context *ctx, IdString type, std::stri
add_port(ctx, new_cell.get(), "LOCK", PORT_OUT);
add_port(ctx, new_cell.get(), "PLLOUT_A", PORT_OUT);
add_port(ctx, new_cell.get(), "PLLOUT_B", PORT_OUT);
+ add_port(ctx, new_cell.get(), "PLLOUTGLOBALA", PORT_OUT);
+ add_port(ctx, new_cell.get(), "PLLOUTGLOBALB", PORT_OUT);
} else {
log_error("unable to create iCE40 cell of type %s", type.c_str(ctx));
}
diff --git a/ice40/pack.cc b/ice40/pack.cc
index feca8a77..07c003d1 100644
--- a/ice40/pack.cc
+++ b/ice40/pack.cc
@@ -159,7 +159,7 @@ static void pack_carries(Context *ctx)
exhausted_cells.find(usr.cell->name) == exhausted_cells.end()) {
// This clause stops us double-packing cells
i0_matches.insert(usr.cell->name);
- if (!i1_net) {
+ if (!i1_net && !usr.cell->ports.at(ctx->id("I2")).net) {
// I1 is don't care when disconnected, duplicate I0
i1_matches.insert(usr.cell->name);
}
@@ -174,7 +174,7 @@ static void pack_carries(Context *ctx)
exhausted_cells.find(usr.cell->name) == exhausted_cells.end()) {
// This clause stops us double-packing cells
i1_matches.insert(usr.cell->name);
- if (!i0_net) {
+ if (!i0_net && !usr.cell->ports.at(ctx->id("I1")).net) {
// I0 is don't care when disconnected, duplicate I1
i0_matches.insert(usr.cell->name);
}
@@ -717,6 +717,30 @@ 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);
@@ -730,10 +754,20 @@ static void pack_special(Context *ctx)
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("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());
if (pi.name == ctx->id("PACKAGEPIN")) {
if (!is_pad) {
- log_error("PLL '%s' has a PACKAGEPIN but is not a PAD PLL", ci->name.c_str(ctx));
+ log_error("PLL '%s' has a PACKAGEPIN but is not a PAD PLL\n", ci->name.c_str(ctx));
} else {
// We drop this port and instead place the PLL adequately below.
pad_packagepin_net = port.second.net;
@@ -743,7 +777,7 @@ static void pack_special(Context *ctx)
}
if (pi.name == ctx->id("REFERENCECLK")) {
if (!is_core)
- log_error("PLL '%s' has a REFERENCECLK but is not a CORE PLL", ci->name.c_str(ctx));
+ log_error("PLL '%s' has a REFERENCECLK but is not a CORE PLL\n", ci->name.c_str(ctx));
}
if (packed->ports.count(ctx->id(newname)) == 0) {