Merge remote-tracking branch 'parallax/master'

Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
This commit is contained in:
Matt Liberty 2024-04-03 22:28:06 -07:00
commit 170c8ace3d
6 changed files with 71 additions and 21 deletions

View File

@ -110,6 +110,7 @@ public:
virtual float sourceClkOffset(const StaState *sta) const = 0; virtual float sourceClkOffset(const StaState *sta) const = 0;
virtual Delay sourceClkLatency(const StaState *sta) const; virtual Delay sourceClkLatency(const StaState *sta) const;
virtual Delay sourceClkInsertionDelay(const StaState *sta) const; virtual Delay sourceClkInsertionDelay(const StaState *sta) const;
virtual Delay sourceClkDelay(const StaState *sta) const;
virtual PathVertex *targetClkPath(); virtual PathVertex *targetClkPath();
virtual const PathVertex *targetClkPath() const; virtual const PathVertex *targetClkPath() const;
virtual const Clock *targetClk(const StaState *sta) const; virtual const Clock *targetClk(const StaState *sta) const;
@ -134,12 +135,15 @@ public:
const TimingRole *checkGenericRole(const StaState *sta) const; const TimingRole *checkGenericRole(const StaState *sta) const;
virtual bool pathDelayMarginIsExternal() const; virtual bool pathDelayMarginIsExternal() const;
virtual PathDelay *pathDelay() const; virtual PathDelay *pathDelay() const;
// This returns the crpr signed with respect to the check type.
// Positive for setup, negative for hold.
virtual Crpr commonClkPessimism(const StaState *sta) const; virtual Crpr commonClkPessimism(const StaState *sta) const;
virtual MultiCyclePath *multiCyclePath() const; virtual MultiCyclePath *multiCyclePath() const;
virtual TimingArc *checkArc() const { return nullptr; } virtual TimingArc *checkArc() const { return nullptr; }
// PathEndDataCheck data clock path. // PathEndDataCheck data clock path.
virtual const PathVertex *dataClkPath() const { return nullptr; } virtual const PathVertex *dataClkPath() const { return nullptr; }
virtual int setupDefaultCycles() const { return 1; } virtual int setupDefaultCycles() const { return 1; }
virtual float clkSkew(const StaState *sta);
static bool less(const PathEnd *path_end1, static bool less(const PathEnd *path_end1,
const PathEnd *path_end2, const PathEnd *path_end2,
@ -160,17 +164,17 @@ public:
// Helper common to multiple PathEnd classes and used // Helper common to multiple PathEnd classes and used
// externally. // externally.
// Target clock insertion delay + latency. // Target clock insertion delay + latency.
static Arrival checkTgtClkDelay(const PathVertex *tgt_clk_path, static Delay checkTgtClkDelay(const PathVertex *tgt_clk_path,
const ClockEdge *tgt_clk_edge, const ClockEdge *tgt_clk_edge,
const TimingRole *check_role, const TimingRole *check_role,
const StaState *sta); const StaState *sta);
static void checkTgtClkDelay(const PathVertex *tgt_clk_path, static void checkTgtClkDelay(const PathVertex *tgt_clk_path,
const ClockEdge *tgt_clk_edge, const ClockEdge *tgt_clk_edge,
const TimingRole *check_role, const TimingRole *check_role,
const StaState *sta, const StaState *sta,
// Return values. // Return values.
Arrival &insertion, Delay &insertion,
Arrival &latency); Delay &latency);
static float checkClkUncertainty(const ClockEdge *src_clk_edge, static float checkClkUncertainty(const ClockEdge *src_clk_edge,
const ClockEdge *tgt_clk_edge, const ClockEdge *tgt_clk_edge,
const PathVertex *tgt_clk_path, const PathVertex *tgt_clk_path,
@ -323,6 +327,8 @@ public:
virtual TimingArc *checkArc() const { return check_arc_; } virtual TimingArc *checkArc() const { return check_arc_; }
virtual int exceptPathCmp(const PathEnd *path_end, virtual int exceptPathCmp(const PathEnd *path_end,
const StaState *sta) const; const StaState *sta) const;
virtual Delay sourceClkDelay(const StaState *sta) const;
virtual float clkSkew(const StaState *sta);
protected: protected:
PathEndCheck(Path *path, PathEndCheck(Path *path,

View File

@ -639,7 +639,7 @@ ConcreteParasiticNetwork::ensureParasiticNode(const Pin *pin,
if (term) if (term)
net = network->net(term); net = network->net(term);
} }
else else if (net)
net = network->highestNetAbove(net); net = network->highestNetAbove(net);
node = new ConcreteParasiticNode(pin, net != net_); node = new ConcreteParasiticNode(pin, net != net_);
pin_nodes_[pin] = node; pin_nodes_[pin] = node;

View File

@ -156,6 +156,12 @@ PathEnd::sourceClkInsertionDelay(const StaState *) const
return delay_zero; return delay_zero;
} }
Delay
PathEnd::sourceClkDelay(const StaState *) const
{
return delay_zero;
}
const Clock * const Clock *
PathEnd::targetClk(const StaState *) const PathEnd::targetClk(const StaState *) const
{ {
@ -325,16 +331,16 @@ PathEnd::clkPath(PathVertex *path,
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
Arrival Delay
PathEnd::checkTgtClkDelay(const PathVertex *tgt_clk_path, PathEnd::checkTgtClkDelay(const PathVertex *tgt_clk_path,
const ClockEdge *tgt_clk_edge, const ClockEdge *tgt_clk_edge,
const TimingRole *check_role, const TimingRole *check_role,
const StaState *sta) const StaState *sta)
{ {
Arrival insertion, latency; Delay insertion, latency;
checkTgtClkDelay(tgt_clk_path, tgt_clk_edge, check_role, sta, checkTgtClkDelay(tgt_clk_path, tgt_clk_edge, check_role, sta,
insertion, latency); insertion, latency);
return Arrival(insertion + latency); return Delay(insertion + latency);
} }
void void
@ -343,8 +349,8 @@ PathEnd::checkTgtClkDelay(const PathVertex *tgt_clk_path,
const TimingRole *check_role, const TimingRole *check_role,
const StaState *sta, const StaState *sta,
// Return values. // Return values.
Arrival &insertion, Delay &insertion,
Arrival &latency) Delay &latency)
{ {
if (tgt_clk_path) { if (tgt_clk_path) {
Search *search = sta->search(); Search *search = sta->search();
@ -364,7 +370,7 @@ PathEnd::checkTgtClkDelay(const PathVertex *tgt_clk_path,
// Propagated clock. Propagated arrival is seeded with // Propagated clock. Propagated arrival is seeded with
// early_late==path_min_max insertion delay. // early_late==path_min_max insertion delay.
Arrival clk_arrival = tgt_clk_path->arrival(sta); Arrival clk_arrival = tgt_clk_path->arrival(sta);
Arrival path_insertion = search->clockInsertion(tgt_clk, tgt_src_pin, Delay path_insertion = search->clockInsertion(tgt_clk, tgt_src_pin,
tgt_clk_rf, min_max, tgt_clk_rf, min_max,
min_max, tgt_path_ap); min_max, tgt_path_ap);
latency = delayRemove(clk_arrival - tgt_clk_edge->time(), path_insertion); latency = delayRemove(clk_arrival - tgt_clk_edge->time(), path_insertion);
@ -673,14 +679,14 @@ PathEndClkConstrained::targetClkArrivalNoCrpr(const StaState *sta) const
+ targetClkMcpAdjustment(sta); + targetClkMcpAdjustment(sta);
} }
Arrival Delay
PathEndClkConstrained::targetClkDelay(const StaState *sta) const PathEndClkConstrained::targetClkDelay(const StaState *sta) const
{ {
return checkTgtClkDelay(targetClkPath(), targetClkEdge(sta), return checkTgtClkDelay(targetClkPath(), targetClkEdge(sta),
checkRole(sta), sta); checkRole(sta), sta);
} }
Arrival Delay
PathEndClkConstrained::targetClkInsertionDelay(const StaState *sta) const PathEndClkConstrained::targetClkInsertionDelay(const StaState *sta) const
{ {
Arrival insertion, latency; Arrival insertion, latency;
@ -736,11 +742,12 @@ PathEndClkConstrained::commonClkPessimism(const StaState *sta) const
if (!crpr_valid_) { if (!crpr_valid_) {
CheckCrpr *check_crpr = sta->search()->checkCrpr(); CheckCrpr *check_crpr = sta->search()->checkCrpr();
crpr_ = check_crpr->checkCrpr(path_.path(), targetClkPath()); crpr_ = check_crpr->checkCrpr(path_.path(), targetClkPath());
if (checkRole(sta)->genericRole() == TimingRole::hold())
crpr_ = -crpr_;
crpr_valid_ = true; crpr_valid_ = true;
} }
return crpr_; if (checkRole(sta)->genericRole() == TimingRole::hold())
return -crpr_;
else
return crpr_;
} }
Required Required
@ -1052,6 +1059,34 @@ PathEndCheck::exceptPathCmp(const PathEnd *path_end,
return cmp; return cmp;
} }
Delay
PathEndCheck::sourceClkDelay(const StaState *sta) const
{
ClkInfo *src_clk_info = path_.tag(sta)->clkInfo();
const PathVertex src_clk_path(src_clk_info->crprClkPath(), sta);
if (!src_clk_path.isNull()) {
if (src_clk_info->isPropagated()) {
// Propagated clock. Propagated arrival is seeded with insertion delay.
Arrival clk_arrival = src_clk_path.arrival(sta);
const ClockEdge *src_clk_edge = src_clk_info->clkEdge();
float insertion = sourceClkInsertionDelay(sta);
return delayRemove(clk_arrival - src_clk_edge->time(), insertion);
}
else
// Ideal clock.
return sourceClkLatency(sta);
}
else
return 0.0;
}
float
PathEndCheck::clkSkew(const StaState *sta)
{
commonClkPessimism(sta);
return sourceClkDelay(sta) - targetClkDelay(sta) - crpr_;
}
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
PathEndLatchCheck::PathEndLatchCheck(Path *path, PathEndLatchCheck::PathEndLatchCheck(Path *path,
@ -1393,7 +1428,7 @@ PathEndOutputDelay::commonClkPessimism(const StaState *sta) const
return crpr_; return crpr_;
} }
Arrival Delay
PathEndOutputDelay::targetClkDelay(const StaState *sta) const PathEndOutputDelay::targetClkDelay(const StaState *sta) const
{ {
if (!clk_path_.isNull()) if (!clk_path_.isNull())
@ -1444,7 +1479,7 @@ PathEndOutputDelay::tgtClkDelay(const ClockEdge *tgt_clk_edge,
latency = 0.0; latency = 0.0;
} }
Arrival Delay
PathEndOutputDelay::targetClkInsertionDelay(const StaState *sta) const PathEndOutputDelay::targetClkInsertionDelay(const StaState *sta) const
{ {
if (!clk_path_.isNull()) if (!clk_path_.isNull())
@ -1823,6 +1858,12 @@ PathEndPathDelay::sourceClkOffset(const StaState *sta) const
return pathDelaySrcClkOffset(path_, path_delay_, src_clk_arrival_, sta); return pathDelaySrcClkOffset(path_, path_delay_, src_clk_arrival_, sta);
} }
float
PathEnd::clkSkew(const StaState *)
{
return 0.0;
}
// Helper shared by PathEndLatchCheck. // Helper shared by PathEndLatchCheck.
float float
PathEnd::pathDelaySrcClkOffset(const PathRef &path, PathEnd::pathDelaySrcClkOffset(const PathRef &path,

View File

@ -508,6 +508,8 @@ Search::deleteFilteredArrivals()
|| from->instances())) || from->instances()))
|| thrus) { || thrus) {
for (Vertex *vertex : *filtered_arrivals_) { for (Vertex *vertex : *filtered_arrivals_) {
if (isClock(vertex))
clk_arrivals_valid_ = false;
deletePaths(vertex); deletePaths(vertex);
arrivalInvalid(vertex); arrivalInvalid(vertex);
requiredInvalid(vertex); requiredInvalid(vertex);

View File

@ -4940,6 +4940,7 @@ bool path_delay_margin_is_external()
Crpr common_clk_pessimism() { return self->commonClkPessimism(Sta::sta()); } Crpr common_clk_pessimism() { return self->commonClkPessimism(Sta::sta()); }
RiseFall *target_clk_end_trans() RiseFall *target_clk_end_trans()
{ return const_cast<RiseFall*>(self->targetClkEndTrans(Sta::sta())); } { return const_cast<RiseFall*>(self->targetClkEndTrans(Sta::sta())); }
float clk_skew() { return self->clkSkew(Sta::sta()); }
} }

View File

@ -932,7 +932,7 @@ VerilogModule::checkInstanceName(VerilogInst *inst,
do { do {
if (replacement_name) if (replacement_name)
stringDelete(replacement_name); stringDelete(replacement_name);
replacement_name = stringPrint("%s_%d", inst_name, i); replacement_name = stringPrint("%s_%d", inst_name, i++);
} while (inst_names.findKey(replacement_name)); } while (inst_names.findKey(replacement_name));
string inst_vname = reader->instanceVerilogName(inst_name); string inst_vname = reader->instanceVerilogName(inst_name);
reader->warn(1396, filename_, inst->line(), reader->warn(1396, filename_, inst->line(),