diff options
author | David Shah <davey1576@gmail.com> | 2018-10-24 18:10:19 +0100 |
---|---|---|
committer | David Shah <dave@ds0.me> | 2018-11-12 14:03:58 +0000 |
commit | 83b1c436303ad152cf78a517979d8ab7e24eadf6 (patch) | |
tree | e3c2756501304eaaf390557ec07b1f57127696c1 | |
parent | 7bd542ecbeb5d2ea0cf3b381b56bfc4ff18498fb (diff) | |
download | nextpnr-83b1c436303ad152cf78a517979d8ab7e24eadf6.tar.gz nextpnr-83b1c436303ad152cf78a517979d8ab7e24eadf6.tar.bz2 nextpnr-83b1c436303ad152cf78a517979d8ab7e24eadf6.zip |
timing: Working on a timing constraint API
Signed-off-by: David Shah <davey1576@gmail.com>
-rw-r--r-- | common/nextpnr.h | 103 | ||||
-rw-r--r-- | common/timing.cc | 3 |
2 files changed, 105 insertions, 1 deletions
diff --git a/common/nextpnr.h b/common/nextpnr.h index 59ae0323..909d49a1 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -194,6 +194,14 @@ struct Loc bool operator!=(const Loc &other) const { return (x != other.x) || (y != other.y) || (z == other.z); } }; +struct TimingConstrObjectId +{ + int32_t index = -1; + + bool operator==(const TimingConstrObjectId &other) const { return index == other.index; } + bool operator!=(const TimingConstrObjectId &other) const { return index != other.index; } +}; + NEXTPNR_NAMESPACE_END namespace std { @@ -208,6 +216,15 @@ template <> struct hash<NEXTPNR_NAMESPACE_PREFIX Loc> return seed; } }; + +template <> struct hash<NEXTPNR_NAMESPACE_PREFIX TimingConstrObjectId> +{ + std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX TimingConstrObjectId &obj) const noexcept + { + return hash<int>()(obj.index); + } +}; + } // namespace std #include "archdefs.h" @@ -266,6 +283,8 @@ struct PipMap PlaceStrength strength = STRENGTH_NONE; }; +struct ClockConstraint; + struct NetInfo : ArchNetInfo { IdString name; @@ -278,6 +297,8 @@ struct NetInfo : ArchNetInfo // wire -> uphill_pip std::unordered_map<WireId, PipMap> wires; + ClockConstraint *clkconstr = nullptr; + Region *region = nullptr; }; @@ -293,6 +314,7 @@ struct PortInfo IdString name; NetInfo *net; PortType type; + TimingConstrObjectId tmg_id; }; struct CellInfo : ArchCellInfo @@ -320,6 +342,7 @@ struct CellInfo : ArchCellInfo // parent.[xyz] := 0 when (constr_parent == nullptr) Region *region = nullptr; + TimingConstrObjectId tmg_id; }; enum TimingPortClass @@ -335,6 +358,60 @@ enum TimingPortClass TMG_IGNORE, // Asynchronous to all clocks, "don't care", and should be ignored (false path) for analysis }; +struct TimingClockingInfo +{ + IdString clock_port; // Port name of clock domain + enum + { + RISING, + FALLING + } edge; + DelayInfo setup, hold; // Input timing checks + DelayInfo clockToQ; // Output clock-to-Q time +}; + +struct ClockConstraint +{ + DelayInfo high; + DelayInfo low; + DelayInfo period; + + TimingConstrObjectId domain_tmg_id; +}; + +struct TimingConstraintObject +{ + TimingConstrObjectId id; + enum + { + ANYTHING, + CLOCK_DOMAIN, + NET, + CELL, + CELL_PORT + } type; + IdString entity; // Name of clock net; net or cell + IdString port; // Name of port on a cell +}; + +struct TimingConstraint +{ + IdString name; + + enum + { + FALSE_PATH, + MIN_DELAY, + MAX_DELAY, + MULTICYCLE, + } type; + + delay_t value; + + std::unordered_set<TimingConstrObjectId> from; + std::unordered_set<TimingConstrObjectId> to; +}; + struct DeterministicRNG { uint64_t rngstate; @@ -431,6 +508,11 @@ struct BaseCtx idstring_idx_to_str = new std::vector<const std::string *>; IdString::initialize_add(this, "", 0); IdString::initialize_arch(this); + + TimingConstraintObject wildcard; + wildcard.id.index = 0; + wildcard.type = TimingConstraintObject::ANYTHING; + constraintObjects.push_back(wildcard); } ~BaseCtx() @@ -514,6 +596,27 @@ struct BaseCtx void refreshUiPip(PipId pip) { pipUiReload.insert(pip); } void refreshUiGroup(GroupId group) { groupUiReload.insert(group); } + + // -------------------------------------------------------------- + + // Timing Constraint API + + // constraint name -> constraint + std::unordered_map<IdString, std::unique_ptr<TimingConstraint>> constraints; + // object ID -> object + std::vector<TimingConstraintObject> constraintObjects; + // object ID -> constraint + std::unordered_multimap<TimingConstrObjectId, TimingConstraint *> constrsFrom; + std::unordered_multimap<TimingConstrObjectId, TimingConstraint *> constrsTo; + + TimingConstrObjectId timingWildcardObject(); + TimingConstrObjectId timingClockDomainObject(NetInfo *clockDomain); + TimingConstrObjectId timingNetObject(NetInfo *net); + TimingConstrObjectId timingCellObject(CellInfo *cell); + TimingConstrObjectId timingPortObject(CellInfo *cell, IdString port); + + void addConstraint(std::unique_ptr<TimingConstraint> constr); + void removeConstraint(IdString constrName); }; NEXTPNR_NAMESPACE_END diff --git a/common/timing.cc b/common/timing.cc index 2769cd65..196168ab 100644 --- a/common/timing.cc +++ b/common/timing.cc @@ -215,7 +215,8 @@ struct Timing for (auto net : boost::adaptors::reverse(topographical_order)) { auto &nd = net_data.at(net); // Ignore false startpoints - if (nd.false_startpoint) continue; + if (nd.false_startpoint) + continue; const delay_t net_length_plus_one = nd.max_path_length + 1; auto &net_min_remaining_budget = nd.min_remaining_budget; for (auto &usr : net->users) { |