aboutsummaryrefslogtreecommitdiffstats
path: root/gowin/arch.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gowin/arch.cc')
-rw-r--r--gowin/arch.cc31
1 files changed, 26 insertions, 5 deletions
diff --git a/gowin/arch.cc b/gowin/arch.cc
index 8c908b04..33f25405 100644
--- a/gowin/arch.cc
+++ b/gowin/arch.cc
@@ -698,17 +698,28 @@ template <class T, class C> const T *genericLookup(const T *first, int len, cons
}
}
+template <class T, class C> const T *timingLookup(const T *first, int len, const T val, C compare)
+{
+ for (int i = 0; i < len; ++i) {
+ auto res = &first[i];
+ if (!(compare(*res, val) || compare(val, *res))) {
+ return res;
+ }
+ }
+ return nullptr;
+}
+
DelayQuad delayLookup(const TimingPOD *first, int len, IdString name)
{
TimingPOD needle;
needle.name_id = name.index;
- const TimingPOD *timing = genericLookup(first, len, needle, timingCompare);
+ const TimingPOD *timing = timingLookup(first, len, needle, timingCompare);
DelayQuad delay;
if (timing != nullptr) {
- delay.fall.max_delay = std::max(timing->ff, timing->rf) / 1000;
- delay.fall.min_delay = std::min(timing->ff, timing->rf) / 1000;
- delay.rise.max_delay = std::max(timing->rr, timing->fr) / 1000;
- delay.rise.min_delay = std::min(timing->rr, timing->fr) / 1000;
+ delay.fall.max_delay = std::max(timing->ff, timing->rf) / 1000.;
+ delay.fall.min_delay = std::min(timing->ff, timing->rf) / 1000.;
+ delay.rise.max_delay = std::max(timing->rr, timing->fr) / 1000.;
+ delay.rise.min_delay = std::min(timing->rr, timing->fr) / 1000.;
} else {
delay = DelayQuad(0);
}
@@ -2005,6 +2016,16 @@ static bool is_PLL_T_FB_iob(const Context *ctx, const CellInfo *cell)
return is_spec_iob(ctx, cell, ctx->id("RPLL_T_FB"));
}
+bool Arch::is_GCLKT_iob(const CellInfo *cell)
+{
+ for (int i = 0; i < 6; ++i) {
+ if (is_spec_iob(getCtx(), cell, idf("GCLKT_%d", i))) {
+ return true;
+ }
+ }
+ return false;
+}
+
// If the PLL input can be connected using a direct wire, then do so,
// bypassing conventional routing.
void Arch::fix_pll_nets(Context *ctx)