aboutsummaryrefslogtreecommitdiffstats
path: root/common/nextpnr.cc
diff options
context:
space:
mode:
Diffstat (limited to 'common/nextpnr.cc')
-rw-r--r--common/nextpnr.cc110
1 files changed, 110 insertions, 0 deletions
diff --git a/common/nextpnr.cc b/common/nextpnr.cc
index 903ab9e4..514017c6 100644
--- a/common/nextpnr.cc
+++ b/common/nextpnr.cc
@@ -53,6 +53,107 @@ void IdString::initialize_add(const BaseCtx *ctx, const char *s, int idx)
ctx->idstring_idx_to_str->push_back(&insert_rc.first->first);
}
+TimingConstrObjectId BaseCtx::timingWildcardObject()
+{
+ TimingConstrObjectId id;
+ id.index = 0;
+ return id;
+}
+
+TimingConstrObjectId BaseCtx::timingClockDomainObject(NetInfo *clockDomain)
+{
+ NPNR_ASSERT(clockDomain->clkconstr != nullptr);
+ if (clockDomain->clkconstr->domain_tmg_id != TimingConstrObjectId()) {
+ return clockDomain->clkconstr->domain_tmg_id;
+ } else {
+ TimingConstraintObject obj;
+ TimingConstrObjectId id;
+ id.index = int(constraintObjects.size());
+ obj.id = id;
+ obj.type = TimingConstraintObject::CLOCK_DOMAIN;
+ obj.entity = clockDomain->name;
+ clockDomain->clkconstr->domain_tmg_id = id;
+ constraintObjects.push_back(obj);
+ return id;
+ }
+}
+
+TimingConstrObjectId BaseCtx::timingNetObject(NetInfo *net)
+{
+ if (net->tmg_id != TimingConstrObjectId()) {
+ return net->tmg_id;
+ } else {
+ TimingConstraintObject obj;
+ TimingConstrObjectId id;
+ id.index = int(constraintObjects.size());
+ obj.id = id;
+ obj.type = TimingConstraintObject::NET;
+ obj.entity = net->name;
+ constraintObjects.push_back(obj);
+ net->tmg_id = id;
+ return id;
+ }
+}
+
+TimingConstrObjectId BaseCtx::timingCellObject(CellInfo *cell)
+{
+ if (cell->tmg_id != TimingConstrObjectId()) {
+ return cell->tmg_id;
+ } else {
+ TimingConstraintObject obj;
+ TimingConstrObjectId id;
+ id.index = int(constraintObjects.size());
+ obj.id = id;
+ obj.type = TimingConstraintObject::CELL;
+ obj.entity = cell->name;
+ constraintObjects.push_back(obj);
+ cell->tmg_id = id;
+ return id;
+ }
+}
+
+TimingConstrObjectId BaseCtx::timingPortObject(CellInfo *cell, IdString port)
+{
+ if (cell->ports.at(port).tmg_id != TimingConstrObjectId()) {
+ return cell->ports.at(port).tmg_id;
+ } else {
+ TimingConstraintObject obj;
+ TimingConstrObjectId id;
+ id.index = int(constraintObjects.size());
+ obj.id = id;
+ obj.type = TimingConstraintObject::CELL_PORT;
+ obj.entity = cell->name;
+ obj.port = port;
+ constraintObjects.push_back(obj);
+ cell->ports.at(port).tmg_id = id;
+ return id;
+ }
+}
+
+void BaseCtx::addConstraint(std::unique_ptr<TimingConstraint> constr)
+{
+ for (auto fromObj : constr->from)
+ constrsFrom.emplace(fromObj, constr.get());
+ for (auto toObj : constr->to)
+ constrsTo.emplace(toObj, constr.get());
+ IdString name = constr->name;
+ constraints[name] = std::move(constr);
+}
+
+void BaseCtx::removeConstraint(IdString constrName)
+{
+ TimingConstraint *constr = constraints[constrName].get();
+ for (auto fromObj : constr->from) {
+ auto fromConstrs = constrsFrom.equal_range(fromObj);
+ constrsFrom.erase(std::find(fromConstrs.first, fromConstrs.second, std::make_pair(fromObj, constr)));
+ }
+ for (auto toObj : constr->to) {
+ auto toConstrs = constrsFrom.equal_range(toObj);
+ constrsFrom.erase(std::find(toConstrs.first, toConstrs.second, std::make_pair(toObj, constr)));
+ }
+ constraints.erase(constrName);
+}
+
const char *BaseCtx::nameOfBel(BelId bel) const
{
const Context *ctx = getCtx();
@@ -306,4 +407,13 @@ void Context::check() const
}
}
+void BaseCtx::addClock(IdString net, float freq)
+{
+ std::unique_ptr<ClockConstraint> cc(new ClockConstraint());
+ cc->period = getCtx()->getDelayFromNS(1000 / freq);
+ cc->high = getCtx()->getDelayFromNS(500 / freq);
+ cc->low = getCtx()->getDelayFromNS(500 / freq);
+ nets.at(net)->clkconstr = std::move(cc);
+}
+
NEXTPNR_NAMESPACE_END