timing: Working on a timing constraint API
Signed-off-by: David Shah <davey1576@gmail.com>
This commit is contained in:
parent
7bd542ecbe
commit
83b1c43630
103
common/nextpnr.h
103
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
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user