aboutsummaryrefslogtreecommitdiffstats
path: root/common/exclusive_state_groups.impl.h
diff options
context:
space:
mode:
Diffstat (limited to 'common/exclusive_state_groups.impl.h')
-rw-r--r--common/exclusive_state_groups.impl.h96
1 files changed, 96 insertions, 0 deletions
diff --git a/common/exclusive_state_groups.impl.h b/common/exclusive_state_groups.impl.h
new file mode 100644
index 00000000..864e16c6
--- /dev/null
+++ b/common/exclusive_state_groups.impl.h
@@ -0,0 +1,96 @@
+/*
+ * nextpnr -- Next Generation Place and Route
+ *
+ * Copyright (C) 2021 The SymbiFlow Authors.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#pragma once
+
+#include "nextpnr.h"
+
+// This header must be included after "nextpnr.h", otherwise circular header
+// import insanity occurs.
+#ifndef NEXTPNR_H_COMPLETE
+#error This header cannot be used until after "nextpnr.h" is included
+#endif
+
+#include "log.h"
+
+NEXTPNR_NAMESPACE_BEGIN
+
+template <size_t StateCount, typename StateType, typename CountType>
+void ExclusiveStateGroup<StateCount, StateType, CountType>::print_debug(const Context *ctx, IdString object,
+ const Definition &definition) const
+{
+ if (state == kNoSelected) {
+ NPNR_ASSERT(selected_states.count() == 0);
+ log_info("%s.%s is currently unselected\n", object.c_str(ctx), definition.prefix.c_str(ctx));
+ } else if (state >= 0) {
+ log_info("%s.%s = %s, count = %d\n", object.c_str(ctx), definition.prefix.c_str(ctx),
+ definition.states[state].c_str(ctx), count[state]);
+ } else {
+ NPNR_ASSERT(state == kOverConstrained);
+ log_info("%s.%s is currently overconstrained, states selected:\n", object.c_str(ctx),
+ definition.prefix.c_str(ctx));
+ for (size_t i = 0; i < definition.states.size(); ++i) {
+ if (selected_states[i]) {
+ log_info(" - %s, count = %d\n", definition.states[i].c_str(ctx), count[i]);
+ }
+ }
+ }
+}
+
+template <size_t StateCount, typename StateType, typename CountType>
+void ExclusiveStateGroup<StateCount, StateType, CountType>::explain_implies(const Context *ctx, IdString object,
+ IdString cell, const Definition &definition,
+ BelId bel, int32_t next_state) const
+{
+ if (check_implies(next_state)) {
+ log_info("Placing cell %s at bel %s does not violate %s.%s\n", cell.c_str(ctx), ctx->nameOfBel(bel),
+ object.c_str(ctx), definition.prefix.c_str(ctx));
+ } else {
+ NPNR_ASSERT(next_state < definition.states.size());
+ log_info("Placing cell %s at bel %s does violates %s.%s.\n", cell.c_str(ctx), ctx->nameOfBel(bel),
+ object.c_str(ctx), definition.prefix.c_str(ctx));
+ print_debug(ctx, object, definition);
+ }
+}
+
+template <size_t StateCount, typename StateType, typename CountType>
+template <typename StateRange>
+void ExclusiveStateGroup<StateCount, StateType, CountType>::explain_requires(const Context *ctx, IdString object,
+ IdString cell,
+ const Definition &definition, BelId bel,
+ const StateRange state_range) const
+{
+ if (requires(state_range)) {
+ log_info("Placing cell %s at bel %s does not violate %s.%s\n", cell.c_str(ctx), ctx->nameOfBel(bel),
+ object.c_str(ctx), definition.prefix.c_str(ctx));
+ } else {
+ log_info("Placing cell %s at bel %s does violates %s.%s, because current state is %s, constraint requires one "
+ "of:\n",
+ cell.c_str(ctx), ctx->nameOfBel(bel), object.c_str(ctx), definition.prefix.c_str(ctx),
+ definition.states[state].c_str(ctx));
+
+ for (const auto required_state : state_range) {
+ NPNR_ASSERT(required_state < definition.states.size());
+ log_info(" - %s\n", definition.states[required_state].c_str(ctx));
+ }
+ print_debug(ctx, object, definition);
+ }
+}
+
+NEXTPNR_NAMESPACE_END