aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/arch_api.h1
-rw-r--r--common/arch_pybindings_shared.h2
-rw-r--r--common/base_arch.h5
-rw-r--r--common/router2.cc20
-rw-r--r--docs/archapi.md7
-rw-r--r--fpga_interchange/arch.cc4
-rw-r--r--fpga_interchange/arch.h2
-rw-r--r--fpga_interchange/examples/devices/xc7a35t/test_data.yaml4
-rw-r--r--generic/arch.cc6
-rw-r--r--generic/arch.h1
-rw-r--r--python/check_arch_api.py4
11 files changed, 40 insertions, 16 deletions
diff --git a/common/arch_api.h b/common/arch_api.h
index 83872b7d..7ed81434 100644
--- a/common/arch_api.h
+++ b/common/arch_api.h
@@ -93,6 +93,7 @@ template <typename R> struct ArchAPI : BaseCtx
virtual void bindPip(PipId pip, NetInfo *net, PlaceStrength strength) = 0;
virtual void unbindPip(PipId pip) = 0;
virtual bool checkPipAvail(PipId pip) const = 0;
+ virtual bool checkPipAvailForNet(PipId pip, NetInfo *net) const = 0;
virtual NetInfo *getBoundPipNet(PipId pip) const = 0;
virtual WireId getConflictingPipWire(PipId pip) const = 0;
virtual NetInfo *getConflictingPipNet(PipId pip) const = 0;
diff --git a/common/arch_pybindings_shared.h b/common/arch_pybindings_shared.h
index 81469df3..ef355a54 100644
--- a/common/arch_pybindings_shared.h
+++ b/common/arch_pybindings_shared.h
@@ -60,6 +60,8 @@ fn_wrapper_0a<Context, decltype(&Context::getBels), &Context::getBels, wrap_cont
fn_wrapper_2a<Context, decltype(&Context::getBelPinWire), &Context::getBelPinWire, conv_to_str<WireId>,
conv_from_str<BelId>, conv_from_str<IdString>>::def_wrap(ctx_cls, "getBelPinWire");
+fn_wrapper_2a<Context, decltype(&Context::getBelPinType), &Context::getBelPinType, pass_through<PortType>,
+ conv_from_str<BelId>, conv_from_str<IdString>>::def_wrap(ctx_cls, "getBelPinType");
fn_wrapper_1a<Context, decltype(&Context::getWireBelPins), &Context::getWireBelPins, wrap_context<BelPinRange>,
conv_from_str<WireId>>::def_wrap(ctx_cls, "getWireBelPins");
diff --git a/common/base_arch.h b/common/base_arch.h
index 84629977..d4efe9ce 100644
--- a/common/base_arch.h
+++ b/common/base_arch.h
@@ -243,6 +243,11 @@ template <typename R> struct BaseArch : ArchAPI<R>
p2n_entry = nullptr;
}
virtual bool checkPipAvail(PipId pip) const override { return getBoundPipNet(pip) == nullptr; }
+ virtual bool checkPipAvailForNet(PipId pip, NetInfo *net) const override
+ {
+ NetInfo *bound_net = getBoundPipNet(pip);
+ return bound_net == nullptr || bound_net == net;
+ }
virtual NetInfo *getBoundPipNet(PipId pip) const override
{
auto fnd = base_pip2net.find(pip);
diff --git a/common/router2.cc b/common/router2.cc
index 002a05a3..a233cdc5 100644
--- a/common/router2.cc
+++ b/common/router2.cc
@@ -588,7 +588,7 @@ struct Router2
bool did_something = false;
for (auto uh : ctx->getPipsUphill(flat_wires[cursor].w)) {
did_something = true;
- if (!ctx->checkPipAvail(uh) && ctx->getBoundPipNet(uh) != net)
+ if (!ctx->checkPipAvailForNet(uh, net))
continue;
if (cpip != PipId() && cpip != uh)
continue; // don't allow multiple pips driving a wire with a net
@@ -675,18 +675,12 @@ struct Router2
#else
if (is_bb && !hit_test_pip(ad.bb, ctx->getPipLocation(dh)))
continue;
- if (!ctx->checkPipAvail(dh)) {
- NetInfo *bound_net = ctx->getBoundPipNet(dh);
- if (bound_net != net) {
- if (bound_net != nullptr) {
- ROUTE_LOG_DBG("Skipping pip %s because it is bound to net '%s' not net '%s'\n",
- ctx->nameOfPip(dh), bound_net->name.c_str(ctx), net->name.c_str(ctx));
- } else {
- ROUTE_LOG_DBG("Skipping pip %s because it is reported not available\n", ctx->nameOfPip(dh));
- }
-
- continue;
- }
+ if (!ctx->checkPipAvailForNet(dh, net)) {
+ ROUTE_LOG_DBG("Skipping pip %s because it is bound to net '%s' not net '%s'\n", ctx->nameOfPip(dh),
+ ctx->getBoundPipNet(dh) != nullptr ? ctx->getBoundPipNet(dh)->name.c_str(ctx)
+ : "<not a net>",
+ net->name.c_str(ctx));
+ continue;
}
#endif
// Evaluate score of next wire
diff --git a/docs/archapi.md b/docs/archapi.md
index 3131ae64..d164e61c 100644
--- a/docs/archapi.md
+++ b/docs/archapi.md
@@ -398,6 +398,13 @@ pip to a net.
*BaseArch default: returns `getBoundPipNet(pip) == nullptr`*
+### bool checkPipAvailForNet(PipId pip, NetInfo *net) const
+
+Returns true if the given pip is available to be bound to a net, or if the
+pip is already bound to that net.
+
+*BaseArch default: returns `getBoundPipNet(pip) == nullptr || getBoundPipNet(pip) == net`*
+
### NetInfo \*getBoundPipNet(PipId pip) const
Return the net this pip is bound to.
diff --git a/fpga_interchange/arch.cc b/fpga_interchange/arch.cc
index 96169cf2..a3a8a166 100644
--- a/fpga_interchange/arch.cc
+++ b/fpga_interchange/arch.cc
@@ -1617,7 +1617,7 @@ void Arch::bindWire(WireId wire, NetInfo *net, PlaceStrength strength)
refreshUiWire(wire);
}
-bool Arch::check_pip_avail_for_net(PipId pip, NetInfo *net) const
+bool Arch::checkPipAvailForNet(PipId pip, NetInfo *net) const
{
NPNR_ASSERT(pip != PipId());
auto pip_iter = pip_to_net.find(pip);
@@ -1755,7 +1755,7 @@ bool Arch::check_pip_avail_for_net(PipId pip, NetInfo *net) const
return true;
}
-bool Arch::checkPipAvail(PipId pip) const { return check_pip_avail_for_net(pip, nullptr); }
+bool Arch::checkPipAvail(PipId pip) const { return checkPipAvailForNet(pip, nullptr); }
// Instance constraint templates.
template void Arch::ArchConstraints::bindBel(Arch::ArchConstraints::TagState *, const Arch::ConstraintRange);
diff --git a/fpga_interchange/arch.h b/fpga_interchange/arch.h
index 005bbb41..217e3508 100644
--- a/fpga_interchange/arch.h
+++ b/fpga_interchange/arch.h
@@ -537,7 +537,7 @@ struct Arch : ArchAPI<ArchRanges>
void unbindPip(PipId pip) final;
bool checkPipAvail(PipId pip) const final;
- bool check_pip_avail_for_net(PipId pip, NetInfo *) const;
+ bool checkPipAvailForNet(PipId pip, NetInfo *net) const final;
NetInfo *getBoundPipNet(PipId pip) const final
{
diff --git a/fpga_interchange/examples/devices/xc7a35t/test_data.yaml b/fpga_interchange/examples/devices/xc7a35t/test_data.yaml
index 268d180a..88c6feda 100644
--- a/fpga_interchange/examples/devices/xc7a35t/test_data.yaml
+++ b/fpga_interchange/examples/devices/xc7a35t/test_data.yaml
@@ -34,3 +34,7 @@ bel_pin_test:
- bel: $CONSTANTS_X0Y0.$CONSTANTS/VCC
pin: P
wire: $CONSTANTS_X0Y0.$CONSTANTS/$VCC_SOURCE
+ - bel: SLICE_X1Y19.SLICEL/SRUSEDGND
+ pin: "0"
+ wire: SLICE_X1Y19.SLICEL/SRUSEDGND_HARD0
+ type: PORT_OUT
diff --git a/generic/arch.cc b/generic/arch.cc
index 1f9531c7..a683e34e 100644
--- a/generic/arch.cc
+++ b/generic/arch.cc
@@ -450,6 +450,12 @@ void Arch::unbindPip(PipId pip)
bool Arch::checkPipAvail(PipId pip) const { return pips.at(pip).bound_net == nullptr; }
+bool Arch::checkPipAvailForNet(PipId pip, NetInfo *net) const
+{
+ NetInfo *bound_net = pips.at(pip).bound_net;
+ return bound_net == nullptr || bound_net == net;
+}
+
NetInfo *Arch::getBoundPipNet(PipId pip) const { return pips.at(pip).bound_net; }
NetInfo *Arch::getConflictingPipNet(PipId pip) const { return pips.at(pip).bound_net; }
diff --git a/generic/arch.h b/generic/arch.h
index 1d37b2fd..92260ce0 100644
--- a/generic/arch.h
+++ b/generic/arch.h
@@ -279,6 +279,7 @@ struct Arch : ArchAPI<ArchRanges>
void bindPip(PipId pip, NetInfo *net, PlaceStrength strength) override;
void unbindPip(PipId pip) override;
bool checkPipAvail(PipId pip) const override;
+ bool checkPipAvailForNet(PipId pip, NetInfo *net) const override;
NetInfo *getBoundPipNet(PipId pip) const override;
WireId getConflictingPipWire(PipId pip) const override;
NetInfo *getConflictingPipNet(PipId pip) const override;
diff --git a/python/check_arch_api.py b/python/check_arch_api.py
index 166f1fd3..4c21d223 100644
--- a/python/check_arch_api.py
+++ b/python/check_arch_api.py
@@ -78,6 +78,10 @@ def check_arch_api(ctx):
wire_name = ctx.getBelPinWire(bel_pin_test['bel'], bel_pin_test['pin'])
assert bel_pin_test['wire'] == wire_name, (bel_pin_test['wire'], wire_name)
+ if 'type' in bel_pin_test:
+ pin_type = ctx.getBelPinType(bel_pin_test['bel'], bel_pin_test['pin'])
+ assert bel_pin_test['type'] == pin_type.name, (bel_pin_test['type'], pin_type)
+
bel_pins_tested += 1
print('Tested {} pips and {} bel pins'.format(pips_tested, bel_pins_tested))