Merge remote-tracking branch 'upstream/master' into update-upstream

Get levelizations fixes

Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
This commit is contained in:
Matt Liberty 2026-03-07 19:26:14 +00:00
commit b5b2f540c0
108 changed files with 5147 additions and 8139 deletions

6
.github/dependabot.yml vendored Normal file
View File

@ -0,0 +1,6 @@
version: 2
updates:
- package-ecosystem: github-actions
directory: "/"
schedule:
interval: "daily"

54
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,54 @@
name: CI
on:
push:
pull_request:
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
with:
submodules: true
- name: Set up dependencies
run: |
sudo apt-get update && sudo apt-get install -y flex libfl-dev bison tcl-dev tcl-tclreadline libeigen3-dev ninja-build
- name: Set up cudd-3.0.0
run: |
wget https://github.com/oscc-ip/artifact/releases/download/cudd-3.0.0/build.tar.gz
mkdir -p cudd
tar -zxvf build.tar.gz -Ccudd
- name: Build
run: |
mkdir build
cd build
cmake .. -G Ninja -DCUDD_DIR=$(pwd)/../cudd -DCMAKE_INSTALL_PREFIX=$(pwd)/install -DCMAKE_BUILD_TYPE=Release
cmake --build . --target all -- -j $(nproc)
cmake --install .
tar -zcvf build.tar.gz -Cinstall .
- name: Test
run: |
cd test
./regression
- name: Upload Artifacts
uses: actions/upload-artifact@v7
if: ${{ !cancelled() }}
with:
name: artifact
path: |
build/install/*
- name: Upload Test Result
uses: actions/upload-artifact@v7
if: ${{ !cancelled() }}
with:
name: result
path: |
test/results/*

View File

@ -244,7 +244,6 @@ set(STA_SOURCE
util/StringSeq.cc util/StringSeq.cc
util/StringSet.cc util/StringSet.cc
util/StringUtil.cc util/StringUtil.cc
util/TokenParser.cc
util/Transition.cc util/Transition.cc
verilog/VerilogReader.cc verilog/VerilogReader.cc

2
CODEOWNERS Normal file
View File

@ -0,0 +1,2 @@
# For CI/CD issues
/.github/ @kazutoiris

View File

@ -6,9 +6,11 @@ LABEL maintainer="James Cherry <cherry@parallaxsw.com>"
ARG DEBIAN_FRONTEND=noninteractive ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && \ RUN apt-get update && \
apt-get install -y \ apt-get install -y \
git \
wget \ wget \
cmake \ cmake \
gcc \ gcc \
gdb \
tcl-dev \ tcl-dev \
tcl-tclreadline \ tcl-tclreadline \
libeigen3-dev \ libeigen3-dev \

View File

@ -39,7 +39,6 @@ namespace sta {
extern const char *tcl_inits[]; extern const char *tcl_inits[];
} }
using std::string;
using sta::stringEq; using sta::stringEq;
using sta::findCmdLineFlag; using sta::findCmdLineFlag;
using sta::Sta; using sta::Sta;
@ -129,7 +128,7 @@ staTclAppInit(int argc,
if (!findCmdLineFlag(argc, argv, "-no_init")) { if (!findCmdLineFlag(argc, argv, "-no_init")) {
const char *home = getenv("HOME"); const char *home = getenv("HOME");
if (home) { if (home) {
string init_path = home; std::string init_path = home;
init_path += "/"; init_path += "/";
init_path += init_filename; init_path += init_filename;
if (std::filesystem::is_regular_file(init_path.c_str())) if (std::filesystem::is_regular_file(init_path.c_str()))

View File

@ -35,8 +35,6 @@
namespace sta { namespace sta {
using std::make_shared;
Waveform Waveform
ArcDcalcWaveforms::inputWaveform(ArcDcalcArg &dcalc_arg, ArcDcalcWaveforms::inputWaveform(ArcDcalcArg &dcalc_arg,
const Scene *scene, const Scene *scene,
@ -68,8 +66,8 @@ ArcDcalcWaveforms::inputWaveform(ArcDcalcArg &dcalc_arg,
FloatSeq time_values; FloatSeq time_values;
for (float time : in_waveform.axis1()->values()) for (float time : in_waveform.axis1()->values())
time_values.push_back(time + dcalc_arg.inputDelay()); time_values.push_back(time + dcalc_arg.inputDelay());
TableAxisPtr time_axis = make_shared<TableAxis>(TableAxisVariable::time, TableAxisPtr time_axis = std::make_shared<TableAxis>(TableAxisVariable::time,
std::move(time_values)); std::move(time_values));
// Scale the waveform from 0:vdd. // Scale the waveform from 0:vdd.
FloatSeq *scaled_values = new FloatSeq; FloatSeq *scaled_values = new FloatSeq;
for (float value : *in_waveform.values()) { for (float value : *in_waveform.values()) {

View File

@ -63,10 +63,6 @@ namespace sta {
// ra_get_r // ra_get_r
// ra_get_s // ra_get_s
using std::string;
using std::abs;
using std::vector;
struct delay_work; struct delay_work;
struct delay_c; struct delay_c;
@ -151,15 +147,15 @@ public:
const LoadPinIndexMap &load_pin_index_map, const LoadPinIndexMap &load_pin_index_map,
const Scene *scene, const Scene *scene,
const MinMax *min_max) override; const MinMax *min_max) override;
string reportGateDelay(const Pin *drvr_pin, std::string reportGateDelay(const Pin *drvr_pin,
const TimingArc *arc, const TimingArc *arc,
const Slew &in_slew, const Slew &in_slew,
float load_cap, float load_cap,
const Parasitic *parasitic, const Parasitic *parasitic,
const LoadPinIndexMap &load_pin_index_map, const LoadPinIndexMap &load_pin_index_map,
const Scene *scene, const Scene *scene,
const MinMax *min_max, const MinMax *min_max,
int digits) override; int digits) override;
void finishDrvrPin() override; void finishDrvrPin() override;
void delay_work_set_thresholds(delay_work *D, void delay_work_set_thresholds(delay_work *D,
double lo, double lo,
@ -240,7 +236,7 @@ private:
int pin_n_; int pin_n_;
ArnoldiReduce *reduce_; ArnoldiReduce *reduce_;
delay_work *delay_work_; delay_work *delay_work_;
vector<rcmodel*> unsaved_parasitics_; std::vector<rcmodel*> unsaved_parasitics_;
bool pocv_enabled_; bool pocv_enabled_;
}; };
@ -469,7 +465,7 @@ ArnoldiDelayCalc::gateDelaySlew(const LibertyCell *drvr_cell,
return dcalc_result; return dcalc_result;
} }
string std::string
ArnoldiDelayCalc::reportGateDelay(const Pin *drvr_pin, ArnoldiDelayCalc::reportGateDelay(const Pin *drvr_pin,
const TimingArc *arc, const TimingArc *arc,
const Slew &in_slew, const Slew &in_slew,
@ -610,7 +606,8 @@ delay_work_get_residues(delay_work *D,int term_index)
// calculate_poles_res // calculate_poles_res
// //
void arnoldi1::calculate_poles_res(delay_work *D,double rdrive) void arnoldi1::calculate_poles_res(delay_work *D,
double rdrive)
{ {
if (n > D->nmax) delay_work_alloc(D,n); if (n > D->nmax) delay_work_alloc(D,n);
double *p = D->poles; double *p = D->poles;
@ -689,7 +686,7 @@ tridiagEV(int n,double *din,double *ein,double *d,double **v)
e[0] = 0.0; e[0] = 0.0;
for (h=n-1;h>=1;h--) { for (h=n-1;h>=1;h--) {
iter = 0; iter = 0;
while (abs(e[h])>1e-18) { // 1e-6ps while (std::abs(e[h])>1e-18) { // 1e-6ps
m=0; m=0;
if (m != h) { if (m != h) {
if (iter++ == 20) if (iter++ == 20)
@ -819,14 +816,14 @@ solve_t_bracketed(double s,int order,double *p,double *rr,
if (0.0<f2) return x2; if (0.0<f2) return x2;
if (f1<0.0) return x1; if (f1<0.0) return x1;
} }
dxold = abs(x2-x1); dxold = std::abs(x2-x1);
dx = dxold; dx = dxold;
get_dv(rts,s,order,p,rr,&f,&df); get_dv(rts,s,order,p,rr,&f,&df);
f -= val; f -= val;
double flast = 0.0; double flast = 0.0;
for (j=1;j<10;j++) { for (j=1;j<10;j++) {
if ((((rts-xh)*df-f)*((rts-xl)*df-f) >= 0.0) if ((((rts-xh)*df-f)*((rts-xl)*df-f) >= 0.0)
|| (abs(2.0*f) > abs(dxold*df))) { || (std::abs(2.0*f) > std::abs(dxold*df))) {
dxold = dx; dxold = dx;
dx = 0.5*(xh-xl); dx = 0.5*(xh-xl);
if (flast*f >0.0) { if (flast*f >0.0) {
@ -850,7 +847,7 @@ solve_t_bracketed(double s,int order,double *p,double *rr,
return rts; return rts;
} }
} }
if (abs(dx) < xacc) { if (std::abs(dx) < xacc) {
return rts; return rts;
} }
get_dv(rts,s,order,p,rr,&f,&df); f -= val; get_dv(rts,s,order,p,rr,&f,&df); f -= val;
@ -859,7 +856,7 @@ solve_t_bracketed(double s,int order,double *p,double *rr,
else else
xh = rts; xh = rts;
} }
if (abs(f)<1e-6) // 1uV if (std::abs(f)<1e-6) // 1uV
return rts; return rts;
return 0.5*(xl+xh); return 0.5*(xl+xh);
} }
@ -1265,28 +1262,28 @@ ArnoldiDelayCalc::ra_solve_for_s(delay_work *D,
f = (ptlo-pthi)/p - tlohi; f = (ptlo-pthi)/p - tlohi;
df = dlo-dhi; df = dlo-dhi;
s = s - f/df; s = s - f/df;
if (abs(f)<.001e-12) return; // .001ps if (std::abs(f)<.001e-12) return; // .001ps
ra_solve_for_pt(p*s,vlo,&ptlo,&dlo); ra_solve_for_pt(p*s,vlo,&ptlo,&dlo);
ra_solve_for_pt(p*s,vhi,&pthi,&dhi); ra_solve_for_pt(p*s,vhi,&pthi,&dhi);
f = (ptlo-pthi)/p - tlohi; f = (ptlo-pthi)/p - tlohi;
df = dlo-dhi; df = dlo-dhi;
s = s - f/df; s = s - f/df;
if (abs(f)<.001e-12) return; // .001ps if (std::abs(f)<.001e-12) return; // .001ps
ra_solve_for_pt(p*s,vlo,&ptlo,&dlo); ra_solve_for_pt(p*s,vlo,&ptlo,&dlo);
ra_solve_for_pt(p*s,vhi,&pthi,&dhi); ra_solve_for_pt(p*s,vhi,&pthi,&dhi);
f = (ptlo-pthi)/p - tlohi; f = (ptlo-pthi)/p - tlohi;
df = dlo-dhi; df = dlo-dhi;
s = s - f/df; s = s - f/df;
if (abs(f)<.001e-12) return; // .001ps if (std::abs(f)<.001e-12) return; // .001ps
ra_solve_for_pt(p*s,vlo,&ptlo,&dlo); ra_solve_for_pt(p*s,vlo,&ptlo,&dlo);
ra_solve_for_pt(p*s,vhi,&pthi,&dhi); ra_solve_for_pt(p*s,vhi,&pthi,&dhi);
f = (ptlo-pthi)/p - tlohi; f = (ptlo-pthi)/p - tlohi;
df = dlo-dhi; df = dlo-dhi;
s = s - f/df; s = s - f/df;
if (abs(f)<.001e-12) return; // .001ps if (std::abs(f)<.001e-12) return; // .001ps
ra_solve_for_pt(p*s,vlo,&ptlo,&dlo); ra_solve_for_pt(p*s,vlo,&ptlo,&dlo);
ra_solve_for_pt(p*s,vhi,&pthi,&dhi); ra_solve_for_pt(p*s,vhi,&pthi,&dhi);
@ -1294,7 +1291,7 @@ ArnoldiDelayCalc::ra_solve_for_s(delay_work *D,
df = dlo-dhi; df = dlo-dhi;
s = s - f/df; s = s - f/df;
if (abs(f)>.5e-12) // .5ps if (std::abs(f)>.5e-12) // .5ps
debugPrint(debug_, "arnoldi", 1, "ra_solve_for_s p %g tlohi %s err %s", debugPrint(debug_, "arnoldi", 1, "ra_solve_for_s p %g tlohi %s err %s",
p, p,
units_->timeUnit()->asString(tlohi), units_->timeUnit()->asString(tlohi),

View File

@ -38,8 +38,6 @@
namespace sta { namespace sta {
using std::string;
rcmodel::rcmodel() : rcmodel::rcmodel() :
pinV(nullptr) pinV(nullptr)
{ {
@ -621,7 +619,7 @@ ArnoldiReduce::makeRcmodelFromTs()
report_->reportLine(" d[%d] %s", report_->reportLine(" d[%d] %s",
h, h,
units_->timeUnit()->asString(d[h])); units_->timeUnit()->asString(d[h]));
string line = stdstrPrint("U[%d]",h); std::string line = stdstrPrint("U[%d]",h);
for (i=0;i<nterms;i++) for (i=0;i<nterms;i++)
line += stdstrPrint(" %6.2e",U[h][i]); line += stdstrPrint(" %6.2e",U[h][i]);
report_->reportLineString(line); report_->reportLineString(line);

View File

@ -24,6 +24,8 @@
#include "CcsCeffDelayCalc.hh" #include "CcsCeffDelayCalc.hh"
#include <cmath>
#include "Debug.hh" #include "Debug.hh"
#include "Units.hh" #include "Units.hh"
#include "Liberty.hh" #include "Liberty.hh"
@ -38,17 +40,11 @@
namespace sta { namespace sta {
using std::string;
// Implementaion based on: // Implementaion based on:
// "Gate Delay Estimation with Library Compatible Current Source Models // "Gate Delay Estimation with Library Compatible Current Source Models
// and Effective Capacitance", D. Garyfallou et al, // and Effective Capacitance", D. Garyfallou et al,
// IEEE Transactions on Very Large Scale Integration (VLSI) Systems, March 2021 // IEEE Transactions on Very Large Scale Integration (VLSI) Systems, March 2021
using std::abs;
using std::exp;
using std::make_shared;
ArcDelayCalc * ArcDelayCalc *
makeCcsCeffDelayCalc(StaState *sta) makeCcsCeffDelayCalc(StaState *sta)
{ {
@ -144,7 +140,7 @@ CcsCeffDelayCalc::gateDelaySlew(const LibertyLibrary *drvr_library,
findCsmWaveform(); findCsmWaveform();
ref_time_ = output_waveforms_->referenceTime(in_slew_); ref_time_ = output_waveforms_->referenceTime(in_slew_);
gate_delay = region_times_[region_vth_idx_] - ref_time_; gate_delay = region_times_[region_vth_idx_] - ref_time_;
drvr_slew = abs(region_times_[region_vh_idx_] - region_times_[region_vl_idx_]); drvr_slew = std::abs(region_times_[region_vh_idx_] - region_times_[region_vl_idx_]);
debugPrint(debug_, "ccs_dcalc", 2, debugPrint(debug_, "ccs_dcalc", 2,
"gate_delay %s drvr_slew %s (initial)", "gate_delay %s drvr_slew %s (initial)",
delayAsString(gate_delay, this), delayAsString(gate_delay, this),
@ -184,12 +180,12 @@ CcsCeffDelayCalc::gateDelaySlew(const LibertyLibrary *drvr_library,
} }
findCsmWaveform(); findCsmWaveform();
gate_delay = region_times_[region_vth_idx_] - ref_time_; gate_delay = region_times_[region_vth_idx_] - ref_time_;
drvr_slew = abs(region_times_[region_vh_idx_] - region_times_[region_vl_idx_]); drvr_slew = std::abs(region_times_[region_vh_idx_] - region_times_[region_vl_idx_]);
debugPrint(debug_, "ccs_dcalc", 2, debugPrint(debug_, "ccs_dcalc", 2,
"gate_delay %s drvr_slew %s", "gate_delay %s drvr_slew %s",
delayAsString(gate_delay, this), delayAsString(gate_delay, this),
delayAsString(drvr_slew, this)); delayAsString(drvr_slew, this));
if (abs(delayAsFloat(drvr_slew) - prev_drvr_slew) < .01 * prev_drvr_slew) if (std::abs(delayAsFloat(drvr_slew) - prev_drvr_slew) < .01 * prev_drvr_slew)
break; break;
prev_drvr_slew = delayAsFloat(drvr_slew); prev_drvr_slew = delayAsFloat(drvr_slew);
} }
@ -529,8 +525,8 @@ CcsCeffDelayCalc::drvrWaveform()
drvr_volts->push_back(v); drvr_volts->push_back(v);
} }
} }
TableAxisPtr drvr_time_axis = make_shared<TableAxis>(TableAxisVariable::time, TableAxisPtr drvr_time_axis = std::make_shared<TableAxis>(TableAxisVariable::time,
std::move(*drvr_times)); std::move(*drvr_times));
delete drvr_times; delete drvr_times;
Table drvr_table(drvr_volts, drvr_time_axis); Table drvr_table(drvr_volts, drvr_time_axis);
return drvr_table; return drvr_table;
@ -561,8 +557,8 @@ CcsCeffDelayCalc::loadWaveform(const Pin *load_pin)
double v1 = (drvr_rf_ == RiseFall::rise()) ? v : vdd_ - v; double v1 = (drvr_rf_ == RiseFall::rise()) ? v : vdd_ - v;
load_volts->push_back(v1); load_volts->push_back(v1);
} }
TableAxisPtr load_time_axis = make_shared<TableAxis>(TableAxisVariable::time, TableAxisPtr load_time_axis = std::make_shared<TableAxis>(TableAxisVariable::time,
std::move(*load_times)); std::move(*load_times));
delete load_times; delete load_times;
Table load_table(load_volts, load_time_axis); Table load_table(load_volts, load_time_axis);
return load_table; return load_table;
@ -606,8 +602,8 @@ CcsCeffDelayCalc::drvrRampWaveform(const Pin *in_pin,
double v1 = (drvr_rf == RiseFall::rise()) ? v : vdd_ - v; double v1 = (drvr_rf == RiseFall::rise()) ? v : vdd_ - v;
load_volts->push_back(v1); load_volts->push_back(v1);
} }
TableAxisPtr load_time_axis = make_shared<TableAxis>(TableAxisVariable::time, TableAxisPtr load_time_axis = std::make_shared<TableAxis>(TableAxisVariable::time,
std::move(*load_times)); std::move(*load_times));
delete load_times; delete load_times;
Table load_table(load_volts, load_time_axis); Table load_table(load_volts, load_time_axis);
return load_table; return load_table;
@ -663,7 +659,7 @@ CcsCeffDelayCalc::makeWaveformPreamble(const Pin *in_pin,
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
string std::string
CcsCeffDelayCalc::reportGateDelay(const Pin *drvr_pin, CcsCeffDelayCalc::reportGateDelay(const Pin *drvr_pin,
const TimingArc *arc, const TimingArc *arc,
const Slew &in_slew, const Slew &in_slew,
@ -680,7 +676,7 @@ CcsCeffDelayCalc::reportGateDelay(const Pin *drvr_pin,
pi_elmore = parasitics_->reduceToPiElmore(parasitic, drvr_pin_, rf, pi_elmore = parasitics_->reduceToPiElmore(parasitic, drvr_pin_, rf,
scene, min_max); scene, min_max);
} }
string report = table_dcalc_->reportGateDelay(drvr_pin, arc, in_slew, load_cap, std::string report = table_dcalc_->reportGateDelay(drvr_pin, arc, in_slew, load_cap,
pi_elmore, load_pin_index_map, pi_elmore, load_pin_index_map,
scene, min_max, digits); scene, min_max, digits);
parasitics_->deleteDrvrReducedParasitics(drvr_pin); parasitics_->deleteDrvrReducedParasitics(drvr_pin);

View File

@ -38,9 +38,6 @@
namespace sta { namespace sta {
using std::string;
using std::log;
DelayCalcBase::DelayCalcBase(StaState *sta) : DelayCalcBase::DelayCalcBase(StaState *sta) :
ArcDelayCalc(sta) ArcDelayCalc(sta)
{ {
@ -101,9 +98,9 @@ DelayCalcBase::dspfWireDelaySlew(const Pin *load_pin,
vh = load_library->slewUpperThreshold(rf); vh = load_library->slewUpperThreshold(rf);
slew_derate = load_library->slewDerateFromLibrary(); slew_derate = load_library->slewDerateFromLibrary();
} }
wire_delay = -elmore * log(1.0 - vth); wire_delay = -elmore * std::log(1.0 - vth);
load_slew = drvr_slew + elmore * log((1.0 - vl) / (1.0 - vh)) / slew_derate; load_slew = drvr_slew + elmore * std::log((1.0 - vl) / (1.0 - vh)) / slew_derate;
load_slew = drvr_slew + elmore * log((1.0 - vl) / (1.0 - vh)) / slew_derate; load_slew = drvr_slew + elmore * std::log((1.0 - vl) / (1.0 - vh)) / slew_derate;
} }
void void
@ -173,7 +170,7 @@ DelayCalcBase::checkDelay(const Pin *check_pin,
return delay_zero; return delay_zero;
} }
string std::string
DelayCalcBase::reportCheckDelay(const Pin *check_pin, DelayCalcBase::reportCheckDelay(const Pin *check_pin,
const TimingArc *arc, const TimingArc *arc,
const Slew &from_slew, const Slew &from_slew,

View File

@ -32,8 +32,9 @@
#include "DmpCeff.hh" #include "DmpCeff.hh"
#include <algorithm> // abs, min #include <algorithm>
#include <cmath> // sqrt, log #include <cmath>
#include <functional>
#include "Report.hh" #include "Report.hh"
#include "Debug.hh" #include "Debug.hh"
@ -50,15 +51,6 @@
namespace sta { namespace sta {
using std::string;
using std::abs;
using std::min;
using std::max;
using std::sqrt;
using std::log;
using std::isnan;
using std::function;
// Tolerance (as a scale of value) for driver parameters (Ceff, delta t, t0). // Tolerance (as a scale of value) for driver parameters (Ceff, delta t, t0).
static const double driver_param_tol = .01; static const double driver_param_tol = .01;
// Waveform threshold crossing time tolerance (1.0 = 100%). // Waveform threshold crossing time tolerance (1.0 = 100%).
@ -107,7 +99,7 @@ newtonRaphson(const int max_iter,
const int n, const int n,
const double x_tol, const double x_tol,
// eval(state) is called to fill fvec and fjac. // eval(state) is called to fill fvec and fjac.
function<void ()> eval, std::function<void ()> eval,
// Temporaries supplied by caller. // Temporaries supplied by caller.
double *fvec, double *fvec,
double **fjac, double **fjac,
@ -337,7 +329,7 @@ DmpAlg::findDriverParams(double ceff)
gateDelays(ceff, t_vth, t_vl, slew); gateDelays(ceff, t_vth, t_vl, slew);
// Scale slew to 0-100% // Scale slew to 0-100%
double dt = slew / (vh_ - vl_); double dt = slew / (vh_ - vl_);
double t0 = t_vth + log(1.0 - vth_) * rd_ * ceff - vth_ * dt; double t0 = t_vth + std::log(1.0 - vth_) * rd_ * ceff - vth_ * dt;
x_[DmpParam::dt] = dt; x_[DmpParam::dt] = dt;
x_[DmpParam::t0] = t0; x_[DmpParam::t0] = t0;
newtonRaphson(100, x_, nr_order_, driver_param_tol, newtonRaphson(100, x_, nr_order_, driver_param_tol,
@ -461,7 +453,7 @@ DmpAlg::showFvec()
void void
DmpAlg::showJacobian() DmpAlg::showJacobian()
{ {
string line = " "; std::string line = " ";
for (int j = 0; j < nr_order_; j++) for (int j = 0; j < nr_order_; j++)
line += stdstrPrint("%12s", dmp_param_index_strings[j]); line += stdstrPrint("%12s", dmp_param_index_strings[j]);
report_->reportLineString(line); report_->reportLineString(line);
@ -894,7 +886,7 @@ DmpPi::init(const LibertyLibrary *drvr_library,
k0_ = 1.0 / (rd_ * c2_); k0_ = 1.0 / (rd_ * c2_);
double a = rpi_ * rd_ * c1_ * c2_; double a = rpi_ * rd_ * c1_ * c2_;
double b = rd_ * (c1_ + c2_) + rpi_ * c1_; double b = rd_ * (c1_ + c2_) + rpi_ * c1_;
double sqrt_ = sqrt(b * b - 4 * a); double sqrt_ = std::sqrt(b * b - 4 * a);
p1_ = (b + sqrt_) / (2 * a); p1_ = (b + sqrt_) / (2 * a);
p2_ = (b - sqrt_) / (2 * a); p2_ = (b - sqrt_) / (2 * a);
@ -1282,7 +1274,7 @@ newtonRaphson(const int max_iter,
double x[], double x[],
const int size, const int size,
const double x_tol, const double x_tol,
function<void ()> eval, std::function<void ()> eval,
// Temporaries supplied by caller. // Temporaries supplied by caller.
double *fvec, double *fvec,
double **fjac, double **fjac,
@ -1300,7 +1292,7 @@ newtonRaphson(const int max_iter,
bool all_under_x_tol = true; bool all_under_x_tol = true;
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
if (abs(p[i]) > abs(x[i]) * x_tol) if (std::abs(p[i]) > std::abs(x[i]) * x_tol)
all_under_x_tol = false; all_under_x_tol = false;
x[i] += p[i]; x[i] += p[i];
} }
@ -1334,7 +1326,7 @@ luDecomp(double **a,
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
double big = 0.0; double big = 0.0;
for (int j = 0; j < size; j++) { for (int j = 0; j < size; j++) {
double temp = abs(a[i][j]); double temp = std::abs(a[i][j]);
if (temp > big) if (temp > big)
big = temp; big = temp;
} }
@ -1363,7 +1355,7 @@ luDecomp(double **a,
for (int k = 0; k < j; k++) for (int k = 0; k < j; k++)
sum -= a[i][k] * a[k][j]; sum -= a[i][k] * a[k][j];
a[i][j] = sum; a[i][j] = sum;
double dum = scale[i] * abs(sum); double dum = scale[i] * std::abs(sum);
if (dum >= big) { if (dum >= big) {
big = dum; big = dum;
imax = i; imax = i;
@ -1507,7 +1499,7 @@ DmpCeffDelayCalc::gateDelay(const Pin *drvr_pin,
float in_slew1 = delayAsFloat(in_slew); float in_slew1 = delayAsFloat(in_slew);
float c2, rpi, c1; float c2, rpi, c1;
parasitics_->piModel(parasitic, c2, rpi, c1); parasitics_->piModel(parasitic, c2, rpi, c1);
if (isnan(c2) || isnan(c1) || isnan(rpi)) if (std::isnan(c2) || std::isnan(c1) || std::isnan(rpi))
report_->error(1040, "parasitic Pi model has NaNs."); report_->error(1040, "parasitic Pi model has NaNs.");
setCeffAlgorithm(drvr_library, drvr_cell, pinPvt(drvr_pin, scene, min_max), setCeffAlgorithm(drvr_library, drvr_cell, pinPvt(drvr_pin, scene, min_max),
table_model, rf, in_slew1, c2, rpi, c1); table_model, rf, in_slew1, c2, rpi, c1);
@ -1583,7 +1575,7 @@ DmpCeffDelayCalc::setCeffAlgorithm(const LibertyLibrary *drvr_library,
dmp_alg_->name()); dmp_alg_->name());
} }
string std::string
DmpCeffDelayCalc::reportGateDelay(const Pin *drvr_pin, DmpCeffDelayCalc::reportGateDelay(const Pin *drvr_pin,
const TimingArc *arc, const TimingArc *arc,
const Slew &in_slew, const Slew &in_slew,
@ -1598,7 +1590,7 @@ DmpCeffDelayCalc::reportGateDelay(const Pin *drvr_pin,
parasitic, load_pin_index_map, scene, min_max); parasitic, load_pin_index_map, scene, min_max);
GateTableModel *model = arc->gateTableModel(scene, min_max); GateTableModel *model = arc->gateTableModel(scene, min_max);
float c_eff = 0.0; float c_eff = 0.0;
string result; std::string result;
const LibertyCell *drvr_cell = arc->to()->libertyCell(); const LibertyCell *drvr_cell = arc->to()->libertyCell();
const LibertyLibrary *drvr_library = drvr_cell->libertyLibrary(); const LibertyLibrary *drvr_library = drvr_cell->libertyLibrary();
const Units *units = drvr_library->units(); const Units *units = drvr_library->units();
@ -1653,7 +1645,7 @@ gateModelRd(const LibertyCell *cell,
gate_model->gateDelay(pvt, in_slew, cap1, pocv_enabled, d1, s1); gate_model->gateDelay(pvt, in_slew, cap1, pocv_enabled, d1, s1);
gate_model->gateDelay(pvt, in_slew, cap2, pocv_enabled, d2, s2); gate_model->gateDelay(pvt, in_slew, cap2, pocv_enabled, d2, s2);
double vth = cell->libertyLibrary()->outputThreshold(rf); double vth = cell->libertyLibrary()->outputThreshold(rf);
float rd = -log(vth) * abs(delayAsFloat(d1) - delayAsFloat(d2)) / (cap2 - cap1); float rd = -std::log(vth) * std::abs(delayAsFloat(d1) - delayAsFloat(d2)) / (cap2 - cap1);
return rd; return rd;
} }

View File

@ -28,8 +28,6 @@
namespace sta { namespace sta {
using std::abs;
double double
findRoot(FindRootFunc func, findRoot(FindRootFunc func,
double x1, double x1,
@ -76,7 +74,7 @@ findRoot(FindRootFunc func,
// Swap x1/x2 so func(x1) < 0. // Swap x1/x2 so func(x1) < 0.
std::swap(x1, x2); std::swap(x1, x2);
double root = (x1 + x2) * 0.5; double root = (x1 + x2) * 0.5;
double dx_prev = abs(x2 - x1); double dx_prev = std::abs(x2 - x1);
double dx = dx_prev; double dx = dx_prev;
double y, dy; double y, dy;
func(root, y, dy); func(root, y, dy);
@ -84,7 +82,7 @@ findRoot(FindRootFunc func,
// Newton/raphson out of range. // Newton/raphson out of range.
if ((((root - x2) * dy - y) * ((root - x1) * dy - y) > 0.0) if ((((root - x2) * dy - y) * ((root - x1) * dy - y) > 0.0)
// Not decreasing fast enough. // Not decreasing fast enough.
|| (abs(2.0 * y) > abs(dx_prev * dy))) { || (std::abs(2.0 * y) > std::abs(dx_prev * dy))) {
// Bisect x1/x2 interval. // Bisect x1/x2 interval.
dx_prev = dx; dx_prev = dx;
dx = (x2 - x1) * 0.5; dx = (x2 - x1) * 0.5;
@ -95,7 +93,7 @@ findRoot(FindRootFunc func,
dx = y / dy; dx = y / dy;
root -= dx; root -= dx;
} }
if (abs(dx) <= x_tol * abs(root)) { if (std::abs(dx) <= x_tol * std::abs(root)) {
// Converged. // Converged.
fail = false; fail = false;
return root; return root;

View File

@ -24,6 +24,8 @@
#include "GraphDelayCalc.hh" #include "GraphDelayCalc.hh"
#include <cmath>
#include <array>
#include <set> #include <set>
#include "ContainerHelpers.hh" #include "ContainerHelpers.hh"
@ -53,10 +55,6 @@
namespace sta { namespace sta {
using std::string;
using std::abs;
using std::array;
static const Slew default_slew = 0.0; static const Slew default_slew = 0.0;
static bool static bool
@ -941,7 +939,7 @@ GraphDelayCalc::findDriverDelays1(Vertex *drvr_vertex,
initSlew(drvr_vertex); initSlew(drvr_vertex);
initWireDelays(drvr_vertex); initWireDelays(drvr_vertex);
bool delay_changed = false; bool delay_changed = false;
array<bool, RiseFall::index_count> delay_exists = {false, false}; std::array<bool, RiseFall::index_count> delay_exists = {false, false};
VertexInEdgeIterator edge_iter(drvr_vertex, graph_); VertexInEdgeIterator edge_iter(drvr_vertex, graph_);
while (edge_iter.hasNext()) { while (edge_iter.hasNext()) {
Edge *edge = edge_iter.next(); Edge *edge = edge_iter.next();
@ -983,7 +981,7 @@ GraphDelayCalc::findLatchEdgeDelays(Edge *edge)
Instance *drvr_inst = network_->instance(drvr_pin); Instance *drvr_inst = network_->instance(drvr_pin);
debugPrint(debug_, "delay_calc", 2, "find latch D->Q %s", debugPrint(debug_, "delay_calc", 2, "find latch D->Q %s",
sdc_network_->pathName(drvr_inst)); sdc_network_->pathName(drvr_inst));
array<bool, RiseFall::index_count> delay_exists = {false, false}; std::array<bool, RiseFall::index_count> delay_exists = {false, false};
LoadPinIndexMap load_pin_index_map = makeLoadPinIndexMap(drvr_vertex); LoadPinIndexMap load_pin_index_map = makeLoadPinIndexMap(drvr_vertex);
bool delay_changed = findDriverEdgeDelays(drvr_vertex, nullptr, edge, bool delay_changed = findDriverEdgeDelays(drvr_vertex, nullptr, edge,
arc_delay_calc_, load_pin_index_map, arc_delay_calc_, load_pin_index_map,
@ -999,7 +997,7 @@ GraphDelayCalc::findDriverEdgeDelays(Vertex *drvr_vertex,
ArcDelayCalc *arc_delay_calc, ArcDelayCalc *arc_delay_calc,
LoadPinIndexMap &load_pin_index_map, LoadPinIndexMap &load_pin_index_map,
// Return value. // Return value.
array<bool, RiseFall::index_count> &delay_exists) std::array<bool, RiseFall::index_count> &delay_exists)
{ {
Vertex *from_vertex = edge->from(graph_); Vertex *from_vertex = edge->from(graph_);
const TimingArcSet *arc_set = edge->timingArcSet(); const TimingArcSet *arc_set = edge->timingArcSet();
@ -1231,7 +1229,7 @@ GraphDelayCalc::annotateDelaySlew(Edge *edge,
float gate_delay1 = delayAsFloat(gate_delay); float gate_delay1 = delayAsFloat(gate_delay);
float prev_gate_delay1 = delayAsFloat(prev_gate_delay); float prev_gate_delay1 = delayAsFloat(prev_gate_delay);
if (prev_gate_delay1 == 0.0 if (prev_gate_delay1 == 0.0
|| (abs(gate_delay1 - prev_gate_delay1) / prev_gate_delay1 || (std::abs(gate_delay1 - prev_gate_delay1) / prev_gate_delay1
> incremental_delay_tolerance_)) > incremental_delay_tolerance_))
delay_changed = true; delay_changed = true;
graph_->setArcDelay(edge, arc, ap_index, gate_delay); graph_->setArcDelay(edge, arc, ap_index, gate_delay);
@ -1660,7 +1658,7 @@ GraphDelayCalc::checkEdgeClkSlew(const Vertex *from_vertex,
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
string std::string
GraphDelayCalc::reportDelayCalc(const Edge *edge, GraphDelayCalc::reportDelayCalc(const Edge *edge,
const TimingArc *arc, const TimingArc *arc,
const Scene *scene, const Scene *scene,
@ -1673,7 +1671,7 @@ GraphDelayCalc::reportDelayCalc(const Edge *edge,
const TimingRole *role = arc->role(); const TimingRole *role = arc->role();
const Instance *inst = network_->instance(to_pin); const Instance *inst = network_->instance(to_pin);
const TimingArcSet *arc_set = edge->timingArcSet(); const TimingArcSet *arc_set = edge->timingArcSet();
string result; std::string result;
const RiseFall *from_rf = arc->fromEdge()->asRiseFall(); const RiseFall *from_rf = arc->fromEdge()->asRiseFall();
const RiseFall *to_rf = arc->toEdge()->asRiseFall(); const RiseFall *to_rf = arc->toEdge()->asRiseFall();
if (from_rf && to_rf) { if (from_rf && to_rf) {

View File

@ -40,9 +40,6 @@
namespace sta { namespace sta {
using std::string;
using std::isnan;
ArcDelayCalc * ArcDelayCalc *
makeLumpedCapDelayCalc(StaState *sta) makeLumpedCapDelayCalc(StaState *sta)
{ {
@ -146,7 +143,7 @@ LumpedCapDelayCalc::gateDelay(const Pin *drvr_pin,
Slew drvr_slew; Slew drvr_slew;
float in_slew1 = delayAsFloat(in_slew); float in_slew1 = delayAsFloat(in_slew);
// NaNs cause seg faults during table lookup. // NaNs cause seg faults during table lookup.
if (isnan(load_cap) || isnan(delayAsFloat(in_slew))) if (std::isnan(load_cap) || std::isnan(delayAsFloat(in_slew)))
report_->error(1350, "gate delay input variable is NaN"); report_->error(1350, "gate delay input variable is NaN");
model->gateDelay(pinPvt(drvr_pin, scene, min_max), in_slew1, load_cap, model->gateDelay(pinPvt(drvr_pin, scene, min_max), in_slew1, load_cap,
variables_->pocvEnabled(), variables_->pocvEnabled(),
@ -170,14 +167,15 @@ LumpedCapDelayCalc::makeResult(const LibertyLibrary *drvr_library,
for (const auto [load_pin, load_idx] : load_pin_index_map) { for (const auto [load_pin, load_idx] : load_pin_index_map) {
ArcDelay wire_delay = 0.0; ArcDelay wire_delay = 0.0;
Slew load_slew = drvr_slew;
thresholdAdjust(load_pin, drvr_library, rf, wire_delay, drvr_slew); thresholdAdjust(load_pin, drvr_library, rf, wire_delay, drvr_slew);
dcalc_result.setWireDelay(load_idx, wire_delay); dcalc_result.setWireDelay(load_idx, wire_delay);
dcalc_result.setLoadSlew(load_idx, drvr_slew); dcalc_result.setLoadSlew(load_idx, load_slew);
} }
return dcalc_result; return dcalc_result;
} }
string std::string
LumpedCapDelayCalc::reportGateDelay(const Pin *check_pin, LumpedCapDelayCalc::reportGateDelay(const Pin *check_pin,
const TimingArc *arc, const TimingArc *arc,
const Slew &in_slew, const Slew &in_slew,

View File

@ -34,8 +34,6 @@
namespace sta { namespace sta {
using std::vector;
ParallelDelayCalc::ParallelDelayCalc(StaState *sta): ParallelDelayCalc::ParallelDelayCalc(StaState *sta):
DelayCalcBase(sta) DelayCalcBase(sta)
{ {
@ -71,8 +69,8 @@ ParallelDelayCalc::gateDelaysParallel(ArcDcalcArgSeq &dcalc_args,
ArcDcalcResultSeq dcalc_results(drvr_count); ArcDcalcResultSeq dcalc_results(drvr_count);
Slew slew_sum = 0.0; Slew slew_sum = 0.0;
ArcDelay load_delay_sum = 0.0; ArcDelay load_delay_sum = 0.0;
vector<ArcDelay> intrinsic_delays(dcalc_args.size()); std::vector<ArcDelay> intrinsic_delays(dcalc_args.size());
vector<ArcDelay> load_delays(dcalc_args.size()); std::vector<ArcDelay> load_delays(dcalc_args.size());
for (size_t drvr_idx = 0; drvr_idx < drvr_count; drvr_idx++) { for (size_t drvr_idx = 0; drvr_idx < drvr_count; drvr_idx++) {
ArcDcalcArg &dcalc_arg = dcalc_args[drvr_idx]; ArcDcalcArg &dcalc_arg = dcalc_args[drvr_idx];
ArcDcalcResult &dcalc_result = dcalc_results[drvr_idx]; ArcDcalcResult &dcalc_result = dcalc_results[drvr_idx];

View File

@ -44,9 +44,6 @@
namespace sta { namespace sta {
using std::string;
using std::abs;
using std::make_shared;
using Eigen::SparseLU; using Eigen::SparseLU;
using Eigen::HouseholderQR; using Eigen::HouseholderQR;
using Eigen::ColPivHouseholderQR; using Eigen::ColPivHouseholderQR;
@ -726,7 +723,7 @@ PrimaDelayCalc::dcalcResults()
ThresholdTimes &drvr_times = threshold_times_[drvr_node]; ThresholdTimes &drvr_times = threshold_times_[drvr_node];
float ref_time = output_waveforms_[drvr_idx]->referenceTime(dcalc_arg.inSlewFlt()); float ref_time = output_waveforms_[drvr_idx]->referenceTime(dcalc_arg.inSlewFlt());
ArcDelay gate_delay = drvr_times[threshold_vth] - ref_time; ArcDelay gate_delay = drvr_times[threshold_vth] - ref_time;
Slew drvr_slew = abs(drvr_times[threshold_vh] - drvr_times[threshold_vl]); Slew drvr_slew = std::abs(drvr_times[threshold_vh] - drvr_times[threshold_vl]);
dcalc_result.setGateDelay(gate_delay); dcalc_result.setGateDelay(gate_delay);
dcalc_result.setDrvrSlew(drvr_slew); dcalc_result.setDrvrSlew(drvr_slew);
debugPrint(debug_, "ccs_dcalc", 2, debugPrint(debug_, "ccs_dcalc", 2,
@ -743,7 +740,7 @@ PrimaDelayCalc::dcalcResults()
ThresholdTimes &wire_times = threshold_times_[load_node]; ThresholdTimes &wire_times = threshold_times_[load_node];
ThresholdTimes &drvr_times = threshold_times_[drvr_node]; ThresholdTimes &drvr_times = threshold_times_[drvr_node];
ArcDelay wire_delay = wire_times[threshold_vth] - drvr_times[threshold_vth]; ArcDelay wire_delay = wire_times[threshold_vth] - drvr_times[threshold_vth];
Slew load_slew = abs(wire_times[threshold_vh] - wire_times[threshold_vl]); Slew load_slew = std::abs(wire_times[threshold_vh] - wire_times[threshold_vl]);
debugPrint(debug_, "ccs_dcalc", 2, debugPrint(debug_, "ccs_dcalc", 2,
"load %s %s delay %s slew %s", "load %s %s delay %s slew %s",
network_->pathName(load_pin), network_->pathName(load_pin),
@ -908,7 +905,7 @@ PrimaDelayCalc::recordWaveformStep(double time)
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
string std::string
PrimaDelayCalc::reportGateDelay(const Pin *drvr_pin, PrimaDelayCalc::reportGateDelay(const Pin *drvr_pin,
const TimingArc *arc, const TimingArc *arc,
const Slew &in_slew, const Slew &in_slew,
@ -959,8 +956,8 @@ Waveform
PrimaDelayCalc::watchWaveform(const Pin *pin) PrimaDelayCalc::watchWaveform(const Pin *pin)
{ {
FloatSeq &voltages = watch_pin_values_[pin]; FloatSeq &voltages = watch_pin_values_[pin];
TableAxisPtr time_axis = make_shared<TableAxis>(TableAxisVariable::time, TableAxisPtr time_axis = std::make_shared<TableAxis>(TableAxisVariable::time,
FloatSeq(times_)); FloatSeq(times_));
Table waveform(new FloatSeq(voltages), time_axis); Table waveform(new FloatSeq(voltages), time_axis);
return waveform; return waveform;
} }
@ -1003,7 +1000,7 @@ void
PrimaDelayCalc::reportMatrix(MatrixSd &matrix) PrimaDelayCalc::reportMatrix(MatrixSd &matrix)
{ {
for (Eigen::Index i = 0; i < matrix.rows(); i++) { for (Eigen::Index i = 0; i < matrix.rows(); i++) {
string line = "| "; std::string line = "| ";
for (Eigen::Index j = 0; j < matrix.cols(); j++) { for (Eigen::Index j = 0; j < matrix.cols(); j++) {
std::string entry = stdstrPrint("%10.3e", matrix.coeff(i, j)); std::string entry = stdstrPrint("%10.3e", matrix.coeff(i, j));
line += entry; line += entry;

View File

@ -28,8 +28,6 @@
namespace sta { namespace sta {
using std::string;
ArcDelayCalc * ArcDelayCalc *
makeUnitDelayCalc(StaState *sta) makeUnitDelayCalc(StaState *sta)
{ {
@ -142,7 +140,7 @@ UnitDelayCalc::unitDelayResult(const LoadPinIndexMap &load_pin_index_map)
return dcalc_result; return dcalc_result;
} }
string std::string
UnitDelayCalc::reportGateDelay(const Pin *, UnitDelayCalc::reportGateDelay(const Pin *,
const TimingArc *, const TimingArc *,
const Slew &, const Slew &,
@ -153,7 +151,7 @@ UnitDelayCalc::reportGateDelay(const Pin *,
const MinMax *, const MinMax *,
int) int)
{ {
string result("Delay = 1.0\n"); std::string result("Delay = 1.0\n");
result += "Slew = 0.0\n"; result += "Slew = 0.0\n";
return result; return result;
} }
@ -170,7 +168,7 @@ UnitDelayCalc::checkDelay(const Pin *,
return units_->timeUnit()->scale(); return units_->timeUnit()->scale();
} }
string std::string
UnitDelayCalc::reportCheckDelay(const Pin *, UnitDelayCalc::reportCheckDelay(const Pin *,
const TimingArc *, const TimingArc *,
const Slew &, const Slew &,

View File

@ -61,7 +61,7 @@ foreach subdir $subdirs {
set files [glob -nocomplain [file join $subdir "*.{cc,hh,yy,ll,i}"]] set files [glob -nocomplain [file join $subdir "*.{cc,hh,yy,ll,i}"]]
set files_c [concat $files_c $files] set files_c [concat $files_c $files]
} }
set warn_regexp_c {(?:(?:->critical|->warn|->fileWarn|->error|->fileError|libWarn|libError| warn)\(|tclArgError\(interp,\s*)([0-9]+),.*(".+")} set warn_regexp_c {(?:(?:->critical|->warn|->fileWarn|->error|->fileError|criticalError|libWarn|libError)\(|tclArgError\(interp,\s*)([0-9]+),.*(".+")}
set files_tcl {} set files_tcl {}
foreach subdir $subdirs { foreach subdir $subdirs {

View File

@ -17,4 +17,3 @@ define_scene ff -liberty NangateOpenCellLibrary_fast
report_checks -path_delay min_max report_checks -path_delay min_max
# report typical scene # report typical scene
report_checks -scene tt report_checks -scene tt

View File

@ -39,8 +39,6 @@
namespace sta { namespace sta {
using std::string;
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
// //
// Graph // Graph
@ -985,12 +983,12 @@ Vertex::setObjectIdx(ObjectIdx idx)
object_idx_ = idx; object_idx_ = idx;
} }
string std::string
Vertex::to_string(const StaState *sta) const Vertex::to_string(const StaState *sta) const
{ {
const Network *network = sta->sdcNetwork(); const Network *network = sta->sdcNetwork();
if (network->direction(pin_)->isBidirect()) { if (network->direction(pin_)->isBidirect()) {
string str = network->pathName(pin_); std::string str = network->pathName(pin_);
str += ' '; str += ' ';
str += is_bidirect_drvr_ ? "driver" : "load"; str += is_bidirect_drvr_ ? "driver" : "load";
return str; return str;
@ -1002,7 +1000,7 @@ Vertex::to_string(const StaState *sta) const
const char * const char *
Vertex::name(const Network *network) const Vertex::name(const Network *network) const
{ {
string name = to_string(network); std::string name = to_string(network);
return makeTmpString(name); return makeTmpString(name);
} }
@ -1229,13 +1227,15 @@ Edge::setObjectIdx(ObjectIdx idx)
object_idx_ = idx; object_idx_ = idx;
} }
string std::string
Edge::to_string(const StaState *sta) const Edge::to_string(const StaState *sta) const
{ {
const Graph *graph = sta->graph(); const Graph *graph = sta->graph();
string str = from(graph)->to_string(sta); std::string str = from(graph)->to_string(sta);
str += " -> "; str += " -> ";
str += to(graph)->to_string(sta); str += to(graph)->to_string(sta);
str += " ";
str += role()->to_string();
FuncExpr *when = arc_set_->cond(); FuncExpr *when = arc_set_->cond();
if (when) { if (when) {
str += " "; str += " ";

View File

@ -171,6 +171,7 @@ path_iterator(const RiseFall *rf,
} // Vertex methods } // Vertex methods
%extend Edge { %extend Edge {
std::string to_string() { return self->to_string(Sta::sta()); };
Vertex *from() { return self->from(Sta::sta()->graph()); } Vertex *from() { return self->from(Sta::sta()->graph()); }
Vertex *to() { return self->to(Sta::sta()->graph()); } Vertex *to() { return self->to(Sta::sta()->graph()); }
Pin *from_pin() { return self->from(Sta::sta()->graph())->pin(); } Pin *from_pin() { return self->from(Sta::sta()->graph())->pin(); }

View File

@ -253,7 +253,7 @@ public:
float wire_delay) const; float wire_delay) const;
// Check for supported axis variables. // Check for supported axis variables.
// Return true if axes are supported. // Return true if axes are supported.
static bool checkSlewDegradationAxes(const TablePtr &table); static bool checkSlewDegradationAxes(const TableModel *table_model);
float defaultInputPinCap() const { return default_input_pin_cap_; } float defaultInputPinCap() const { return default_input_pin_cap_; }
void setDefaultInputPinCap(float cap); void setDefaultInputPinCap(float cap);
@ -892,10 +892,6 @@ public:
float clkTreeDelay(float in_slew, float clkTreeDelay(float in_slew,
const RiseFall *from_rf, const RiseFall *from_rf,
const MinMax *min_max) const; const MinMax *min_max) const;
// deprecated 2024-06-22
RiseFallMinMax clkTreeDelays() const __attribute__ ((deprecated));
// deprecated 2024-02-27
RiseFallMinMax clockTreePathDelays() const __attribute__ ((deprecated));
static bool equiv(const LibertyPort *port1, static bool equiv(const LibertyPort *port1,
const LibertyPort *port2); const LibertyPort *port2);
@ -916,7 +912,6 @@ protected:
void setMinPort(LibertyPort *min); void setMinPort(LibertyPort *min);
void addScaledPort(OperatingConditions *op_cond, void addScaledPort(OperatingConditions *op_cond,
LibertyPort *scaled_port); LibertyPort *scaled_port);
RiseFallMinMax clkTreeDelays1() const;
void setMemberFlag(bool value, void setMemberFlag(bool value,
const std::function<void(LibertyPort*, bool)> &setter); const std::function<void(LibertyPort*, bool)> &setter);
void setMemberFloat(float value, void setMemberFloat(float value,
@ -1051,7 +1046,7 @@ public:
void setScale(ScaleFactorType type, void setScale(ScaleFactorType type,
ScaleFactorPvt pvt, ScaleFactorPvt pvt,
float scale); float scale);
void print(); void report(Report *report);
protected: protected:
std::string name_; std::string name_;

View File

@ -32,6 +32,7 @@
#include "SdcClass.hh" #include "SdcClass.hh"
#include "StaState.hh" #include "StaState.hh"
#include "SearchClass.hh" #include "SearchClass.hh"
#include "StringUtil.hh"
namespace sta { namespace sta {
@ -42,7 +43,6 @@ using PathGroupIterator = PathEndSeq::iterator;
using PathGroupClkMap = std::map<const Clock*, PathGroup*>; using PathGroupClkMap = std::map<const Clock*, PathGroup*>;
using PathGroupNamedMap = std::map<const char*, PathGroup*, CharPtrLess>; using PathGroupNamedMap = std::map<const char*, PathGroup*, CharPtrLess>;
using PathGroupSeq = std::vector<PathGroup*>; using PathGroupSeq = std::vector<PathGroup*>;
using StdStringSeq = std::vector<std::string>;
// A collection of PathEnds grouped and sorted for reporting. // A collection of PathEnds grouped and sorted for reporting.
class PathGroup class PathGroup

View File

@ -40,6 +40,7 @@
#include "SearchPred.hh" #include "SearchPred.hh"
#include "VertexVisitor.hh" #include "VertexVisitor.hh"
#include "Path.hh" #include "Path.hh"
#include "StringUtil.hh"
namespace sta { namespace sta {
@ -70,7 +71,6 @@ using VertexSlackMapSeq = std::vector<VertexSlackMap>;
using WorstSlacksSeq = std::vector<WorstSlacks>; using WorstSlacksSeq = std::vector<WorstSlacks>;
using DelayDblSeq = std::vector<DelayDbl>; using DelayDblSeq = std::vector<DelayDbl>;
using ExceptionPathSeq = std::vector<ExceptionPath*>; using ExceptionPathSeq = std::vector<ExceptionPath*>;
using StdStringSeq = std::vector<std::string>;
class Search : public StaState class Search : public StaState
{ {

View File

@ -30,6 +30,7 @@
#include <functional> #include <functional>
#include "StringSeq.hh" #include "StringSeq.hh"
#include "StringUtil.hh"
#include "LibertyClass.hh" #include "LibertyClass.hh"
#include "NetworkClass.hh" #include "NetworkClass.hh"
#include "SdcClass.hh" #include "SdcClass.hh"
@ -80,7 +81,6 @@ using SceneNameMap = std::map<std::string, Scene*>;
using SlowDrvrIterator = Iterator<Instance*>; using SlowDrvrIterator = Iterator<Instance*>;
using CheckError = StringSeq; using CheckError = StringSeq;
using CheckErrorSeq = std::vector<CheckError*>; using CheckErrorSeq = std::vector<CheckError*>;
using StdStringSeq = std::vector<std::string>;
enum class CmdNamespace { sta, sdc }; enum class CmdNamespace { sta, sdc };
using ParasiticsNameMap = std::map<std::string, Parasitics*>; using ParasiticsNameMap = std::map<std::string, Parasitics*>;
// Path::slack/arrival/required function. // Path::slack/arrival/required function.
@ -988,16 +988,6 @@ public:
void setReportPathDigits(int digits); void setReportPathDigits(int digits);
void setReportPathNoSplit(bool no_split); void setReportPathNoSplit(bool no_split);
void setReportPathSigmas(bool report_sigmas); void setReportPathSigmas(bool report_sigmas);
// Header above reportPathEnd results.
void reportPathEndHeader();
// Footer below reportPathEnd results.
void reportPathEndFooter();
// Format report_path_endpoint only:
// Previous path end is used to detect path group changes
// so headers are reported by group.
void reportPathEnd(PathEnd *end,
PathEnd *prev_end,
bool last);
void reportPathEnd(PathEnd *end); void reportPathEnd(PathEnd *end);
void reportPathEnds(PathEndSeq *ends); void reportPathEnds(PathEndSeq *ends);
ReportPath *reportPath() { return report_path_; } ReportPath *reportPath() { return report_path_; }
@ -1302,13 +1292,13 @@ public:
void clkPinsInvalid(const Mode *mode); void clkPinsInvalid(const Mode *mode);
// The following functions assume ensureClkNetwork() has been called. // The following functions assume ensureClkNetwork() has been called.
bool isClock(const Pin *pin, bool isClock(const Pin *pin,
const Mode *mode) const; const Mode *mode);
bool isClock(const Net *net, bool isClock(const Net *net,
const Mode *mode) const; const Mode *mode);
bool isIdealClock(const Pin *pin, bool isIdealClock(const Pin *pin,
const Mode *mode) const; const Mode *mode);
bool isPropagatedClock(const Pin *pin, bool isPropagatedClock(const Pin *pin,
const Mode *mode) const; const Mode *mode);
const PinSet *pins(const Clock *clk, const PinSet *pins(const Clock *clk,
const Mode *mode); const Mode *mode);
@ -1522,10 +1512,12 @@ protected:
void reportDelaysWrtClks(const Pin *pin, void reportDelaysWrtClks(const Pin *pin,
const Scene *scene, const Scene *scene,
int digits, int digits,
bool find_required,
PathDelayFunc get_path_delay); PathDelayFunc get_path_delay);
void reportDelaysWrtClks(Vertex *vertex, void reportDelaysWrtClks(Vertex *vertex,
const Scene *scene, const Scene *scene,
int digits, int digits,
bool find_required,
PathDelayFunc get_path_delay); PathDelayFunc get_path_delay);
void reportDelaysWrtClks(Vertex *vertex, void reportDelaysWrtClks(Vertex *vertex,
const ClockEdge *clk_edge, const ClockEdge *clk_edge,

View File

@ -31,7 +31,6 @@
namespace sta { namespace sta {
using StringSeq = std::vector<const char*>; using StringSeq = std::vector<const char*>;
using StdStringSeq = std::vector<std::string>;
void void
deleteContents(StringSeq *strings); deleteContents(StringSeq *strings);

View File

@ -31,7 +31,6 @@ namespace sta {
using StringSet = std::set<const char*, CharPtrLess>; using StringSet = std::set<const char*, CharPtrLess>;
using StdStringSet = std::set<std::string>; using StdStringSet = std::set<std::string>;
using StdStringSeq = std::vector<std::string>;
void void
deleteContents(StringSet *strings); deleteContents(StringSet *strings);

View File

@ -33,6 +33,8 @@
namespace sta { namespace sta {
using StdStringSeq = std::vector<std::string>;
inline bool inline bool
stringEq(const char *str1, stringEq(const char *str1,
const char *str2) const char *str2)
@ -201,12 +203,9 @@ deleteTmpStrings();
void void
trimRight(std::string &str); trimRight(std::string &str);
using StringVector = std::vector<std::string>; // Spit text into delimiter separated tokens and skip whitepace.
StdStringSeq
void parseTokens(const std::string &s,
split(const std::string &text, const char delimiter);
const std::string &delims,
// Return values.
StringVector &tokens);
} // namespace } // namespace

View File

@ -49,6 +49,7 @@ using FloatTable = std::vector<FloatSeq>;
// Sequence of 1D tables (order 1). // Sequence of 1D tables (order 1).
using Table1Seq = std::vector<Table*>; using Table1Seq = std::vector<Table*>;
using Waveform = Table; using Waveform = Table;
using TableModelsEarlyLate = std::array<TableModel*, EarlyLate::index_count>;
TableAxisVariable TableAxisVariable
stringTableAxisVariable(const char *variable); stringTableAxisVariable(const char *variable);
@ -63,11 +64,14 @@ class GateTableModel : public GateTimingModel
public: public:
GateTableModel(LibertyCell *cell, GateTableModel(LibertyCell *cell,
TableModel *delay_model, TableModel *delay_model,
TableModel *delay_sigma_models[EarlyLate::index_count], TableModelsEarlyLate delay_sigma_models,
TableModel *slew_model, TableModel *slew_model,
TableModel *slew_sigma_models[EarlyLate::index_count], TableModelsEarlyLate slew_sigma_models,
ReceiverModelPtr receiver_model, ReceiverModelPtr receiver_model,
OutputWaveforms *output_waveforms); OutputWaveforms *output_waveforms);
GateTableModel(LibertyCell *cell,
TableModel *delay_model,
TableModel *slew_model);
~GateTableModel() override; ~GateTableModel() override;
void gateDelay(const Pvt *pvt, void gateDelay(const Pvt *pvt,
float in_slew, float in_slew,
@ -100,7 +104,7 @@ public:
OutputWaveforms *outputWaveforms() const { return output_waveforms_.get(); } OutputWaveforms *outputWaveforms() const { return output_waveforms_.get(); }
// Check the axes before making the model. // Check the axes before making the model.
// Return true if the model axes are supported. // Return true if the model axes are supported.
static bool checkAxes(const TablePtr &table); static bool checkAxes(const TableModel *table);
protected: protected:
void maxCapSlew(float in_slew, void maxCapSlew(float in_slew,
@ -135,9 +139,9 @@ protected:
static bool checkAxis(const TableAxis *axis); static bool checkAxis(const TableAxis *axis);
std::unique_ptr<TableModel> delay_model_; std::unique_ptr<TableModel> delay_model_;
std::array<std::unique_ptr<TableModel>, EarlyLate::index_count> delay_sigma_models_; TableModelsEarlyLate delay_sigma_models_;
std::unique_ptr<TableModel> slew_model_; std::unique_ptr<TableModel> slew_model_;
std::array<std::unique_ptr<TableModel>, EarlyLate::index_count> slew_sigma_models_; TableModelsEarlyLate slew_sigma_models_;
ReceiverModelPtr receiver_model_; ReceiverModelPtr receiver_model_;
std::unique_ptr<OutputWaveforms> output_waveforms_; std::unique_ptr<OutputWaveforms> output_waveforms_;
}; };
@ -147,7 +151,9 @@ class CheckTableModel : public CheckTimingModel
public: public:
CheckTableModel(LibertyCell *cell, CheckTableModel(LibertyCell *cell,
TableModel *model, TableModel *model,
TableModel *sigma_models[EarlyLate::index_count]); TableModelsEarlyLate sigma_models);
CheckTableModel(LibertyCell *cell,
TableModel *model);
~CheckTableModel() override; ~CheckTableModel() override;
ArcDelay checkDelay(const Pvt *pvt, ArcDelay checkDelay(const Pvt *pvt,
float from_slew, float from_slew,
@ -166,7 +172,7 @@ public:
// Check the axes before making the model. // Check the axes before making the model.
// Return true if the model axes are supported. // Return true if the model axes are supported.
static bool checkAxes(const TablePtr table); static bool checkAxes(const TableModel *table);
protected: protected:
void setIsScaled(bool is_scaled) override; void setIsScaled(bool is_scaled) override;
@ -197,7 +203,7 @@ protected:
static bool checkAxis(const TableAxis *axis); static bool checkAxis(const TableAxis *axis);
std::unique_ptr<TableModel> model_; std::unique_ptr<TableModel> model_;
std::array<std::unique_ptr<TableModel>, EarlyLate::index_count> sigma_models_; TableModelsEarlyLate sigma_models_;
}; };
class TableAxis class TableAxis
@ -254,6 +260,8 @@ public:
const TableAxis *axis2() const { return axis2_.get(); } const TableAxis *axis2() const { return axis2_.get(); }
const TableAxis *axis3() const { return axis3_.get(); } const TableAxis *axis3() const { return axis3_.get(); }
const TableAxisPtr axis1ptr() const { return axis1_; } const TableAxisPtr axis1ptr() const { return axis1_; }
const TableAxisPtr axis2ptr() const { return axis2_; }
const TableAxisPtr axis3ptr() const { return axis3_; }
void setIsScaled(bool is_scaled); void setIsScaled(bool is_scaled);
float value(size_t axis_idx1, float value(size_t axis_idx1,
@ -409,7 +417,7 @@ public:
void setCapacitanceModel(TableModel table_model, void setCapacitanceModel(TableModel table_model,
size_t segment, size_t segment,
const RiseFall *rf); const RiseFall *rf);
static bool checkAxes(TablePtr table); static bool checkAxes(const TableModel *table);
private: private:
std::vector<TableModel> capacitance_models_; std::vector<TableModel> capacitance_models_;

View File

@ -99,7 +99,7 @@ class TimingArcAttrs
public: public:
TimingArcAttrs(); TimingArcAttrs();
TimingArcAttrs(TimingSense sense); TimingArcAttrs(TimingSense sense);
virtual ~TimingArcAttrs(); ~TimingArcAttrs();
TimingType timingType() const { return timing_type_; } TimingType timingType() const { return timing_type_; }
void setTimingType(TimingType type); void setTimingType(TimingType type);
TimingSense timingSense() const { return timing_sense_; } TimingSense timingSense() const { return timing_sense_; }
@ -145,7 +145,8 @@ class TimingArcSet
friend class LibertyCell; friend class LibertyCell;
public: public:
virtual ~TimingArcSet(); ~TimingArcSet();
std::string to_string();
LibertyCell *libertyCell() const; LibertyCell *libertyCell() const;
LibertyPort *from() const { return from_; } LibertyPort *from() const { return from_; }
LibertyPort *to() const { return to_; } LibertyPort *to() const { return to_; }
@ -175,6 +176,7 @@ public:
// other conditional timing arcs between the same pins. // other conditional timing arcs between the same pins.
bool isCondDefault() const { return is_cond_default_; } bool isCondDefault() const { return is_cond_default_; }
void setIsCondDefault(bool is_default); void setIsCondDefault(bool is_default);
const FuncExpr *when() const { return attrs_->cond(); }
// SDF IOPATHs match sdfCond. // SDF IOPATHs match sdfCond.
// sdfCond (IOPATH) reuses sdfCondStart (timing check) variable. // sdfCond (IOPATH) reuses sdfCondStart (timing check) variable.
const std::string &sdfCond() const { return attrs_->sdfCondStart(); } const std::string &sdfCond() const { return attrs_->sdfCondStart(); }
@ -249,7 +251,7 @@ public:
TimingArcSet *set() const { return set_; } TimingArcSet *set() const { return set_; }
TimingSense sense() const; TimingSense sense() const;
// Index in TimingArcSet. // Index in TimingArcSet.
unsigned index() const { return index_; } size_t index() const { return index_; }
TimingModel *model() const { return model_; } TimingModel *model() const { return model_; }
GateTimingModel *gateModel(const Scene *scene, GateTimingModel *gateModel(const Scene *scene,
const MinMax *min_max) const; const MinMax *min_max) const;
@ -270,7 +272,7 @@ public:
protected: protected:
TimingModel *model(const Scene *scene, TimingModel *model(const Scene *scene,
const MinMax *min_max) const; const MinMax *min_max) const;
void setIndex(unsigned index); void setIndex(size_t index);
void addScaledModel(const OperatingConditions *op_cond, void addScaledModel(const OperatingConditions *op_cond,
TimingModel *scaled_model); TimingModel *scaled_model);

View File

@ -78,6 +78,7 @@ public:
[[nodiscard]] bool isNonSeqTimingCheck() const { return is_non_seq_check_; } [[nodiscard]] bool isNonSeqTimingCheck() const { return is_non_seq_check_; }
[[nodiscard]] bool isDataCheck() const; [[nodiscard]] bool isDataCheck() const;
[[nodiscard]] bool isLatchDtoQ() const; [[nodiscard]] bool isLatchDtoQ() const;
[[nodiscard]] bool isLatchEnToQ() const;
const TimingRole *genericRole() const; const TimingRole *genericRole() const;
const TimingRole *sdfRole() const; const TimingRole *sdfRole() const;
// Timing check data path min/max. // Timing check data path min/max.

View File

@ -1,52 +0,0 @@
// OpenSTA, Static Timing Analyzer
// Copyright (c) 2025, Parallax Software, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software.
//
// Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
//
// This notice may not be removed or altered from any source distribution.
#pragma once
namespace sta {
// Iterate over the tokens in str separated by character sep.
// Similar in functionality to strtok, but does not leave the string
// side-effected. This is preferable to using strtok because it leaves
// string terminators where the separators were.
// Using STL string functions to parse tokens is messy and extremely slow
// on the RogueWave/Solaris implementation, apparently because of mutexes
// on temporary strings.
class TokenParser
{
public:
TokenParser(const char *str,
const char *delimiters);
bool hasNext();
char *next();
private:
const char *delimiters_;
char *token_;
char *token_end_;
char token_delimiter_;
bool first_;
};
} // namespace

View File

@ -48,6 +48,7 @@ public:
static const RiseFall *fall() { return &fall_; } static const RiseFall *fall() { return &fall_; }
static int riseIndex() { return rise_.sdf_triple_index_; } static int riseIndex() { return rise_.sdf_triple_index_; }
static int fallIndex() { return fall_.sdf_triple_index_; } static int fallIndex() { return fall_.sdf_triple_index_; }
const std::string &to_string_long() const { return name_; }
const std::string &to_string() const { return short_name_; } const std::string &to_string() const { return short_name_; }
const char *name() const { return name_.c_str(); } const char *name() const { return name_.c_str(); }
const char *shortName() const { return short_name_.c_str(); } const char *shortName() const { return short_name_.c_str(); }

View File

@ -38,8 +38,6 @@
namespace sta { namespace sta {
using std::max;
static unsigned static unsigned
hashCell(const LibertyCell *cell); hashCell(const LibertyCell *cell);
static unsigned static unsigned

View File

@ -30,8 +30,6 @@
namespace sta { namespace sta {
using std::string;
FuncExpr * FuncExpr *
FuncExpr::makePort(LibertyPort *port) FuncExpr::makePort(LibertyPort *port)
{ {
@ -199,20 +197,20 @@ FuncExpr::portTimingSense(const LibertyPort *port) const
return TimingSense::unknown; return TimingSense::unknown;
} }
string std::string
FuncExpr::to_string() const FuncExpr::to_string() const
{ {
return to_string(false); return to_string(false);
} }
string std::string
FuncExpr::to_string(bool with_parens) const FuncExpr::to_string(bool with_parens) const
{ {
switch (op_) { switch (op_) {
case Op::port: case Op::port:
return port_->name(); return port_->name();
case Op::not_: { case Op::not_: {
string result = "!"; std::string result = "!";
result += left_ ? left_->to_string(true) : "?"; result += left_ ? left_->to_string(true) : "?";
return result; return result;
} }
@ -231,12 +229,12 @@ FuncExpr::to_string(bool with_parens) const
} }
} }
string std::string
FuncExpr::to_string(bool with_parens, FuncExpr::to_string(bool with_parens,
char op) const char op) const
{ {
string right = right_->to_string(true); std::string right = right_->to_string(true);
string result; std::string result;
if (with_parens) if (with_parens)
result += '('; result += '(';
result += left_ ? left_->to_string(true) : "?"; result += left_ ? left_->to_string(true) : "?";

View File

@ -37,7 +37,7 @@ namespace sta {
FuncExpr * FuncExpr *
parseFuncExpr(const char *func, parseFuncExpr(const char *func,
LibertyCell *cell, const LibertyCell *cell,
const char *error_msg, const char *error_msg,
Report *report) Report *report)
{ {
@ -56,7 +56,7 @@ parseFuncExpr(const char *func,
} }
LibExprReader::LibExprReader(const char *func, LibExprReader::LibExprReader(const char *func,
LibertyCell *cell, const LibertyCell *cell,
const char *error_msg, const char *error_msg,
Report *report) : Report *report) :
func_(func), func_(func),
@ -69,7 +69,7 @@ LibExprReader::LibExprReader(const char *func,
// defined in LibertyReader.cc // defined in LibertyReader.cc
LibertyPort * LibertyPort *
libertyReaderFindPort(LibertyCell *cell, libertyReaderFindPort(const LibertyCell *cell,
const char *port_name); const char *port_name);
FuncExpr * FuncExpr *

View File

@ -32,7 +32,7 @@ class LibertyCell;
FuncExpr * FuncExpr *
parseFuncExpr(const char *func, parseFuncExpr(const char *func,
LibertyCell *cell, const LibertyCell *cell,
const char *error_msg, const char *error_msg,
Report *report); Report *report);

View File

@ -35,7 +35,7 @@ class LibExprReader
{ {
public: public:
LibExprReader(const char *func, LibExprReader(const char *func,
LibertyCell *cell, const LibertyCell *cell,
const char *error_msg, const char *error_msg,
Report *report); Report *report);
FuncExpr *makeFuncExprPort(const char *port_name); FuncExpr *makeFuncExprPort(const char *port_name);
@ -55,7 +55,7 @@ public:
private: private:
const char *func_; const char *func_;
LibertyCell *cell_; const LibertyCell *cell_;
const char *error_msg_; const char *error_msg_;
Report *report_; Report *report_;
FuncExpr *result_; FuncExpr *result_;

View File

@ -50,8 +50,6 @@
namespace sta { namespace sta {
using std::string;
void void
initLiberty() initLiberty()
{ {
@ -111,8 +109,6 @@ LibertyLibrary::LibertyLibrary(const char *name,
LibertyLibrary::~LibertyLibrary() LibertyLibrary::~LibertyLibrary()
{ {
delete scale_factors_;
for (auto rf_index : RiseFall::rangeIndex()) { for (auto rf_index : RiseFall::rangeIndex()) {
TableModel *model = wire_slew_degradation_tbls_[rf_index]; TableModel *model = wire_slew_degradation_tbls_[rf_index];
delete model; delete model;
@ -271,14 +267,14 @@ LibertyLibrary::setScaleFactors(ScaleFactors *scales)
ScaleFactors * ScaleFactors *
LibertyLibrary::makeScaleFactors(const char *name) LibertyLibrary::makeScaleFactors(const char *name)
{ {
auto [it, inserted] = scale_factors_map_.emplace(std::string(name), name); auto [it, inserted] = scale_factors_map_.emplace(name, name);
return &it->second; return &it->second;
} }
ScaleFactors * ScaleFactors *
LibertyLibrary::findScaleFactors(const char *name) LibertyLibrary::findScaleFactors(const char *name)
{ {
return findKeyValuePtr(scale_factors_map_, std::string(name)); return findKeyValuePtr(scale_factors_map_, name);
} }
float float
@ -400,20 +396,20 @@ LibertyLibrary::degradeWireSlew(const TableModel *model,
// Check for supported axis variables. // Check for supported axis variables.
// Return true if axes are supported. // Return true if axes are supported.
bool bool
LibertyLibrary::checkSlewDegradationAxes(const TablePtr &table) LibertyLibrary::checkSlewDegradationAxes(const TableModel *table_model)
{ {
switch (table->order()) { switch (table_model->order()) {
case 0: case 0:
return true; return true;
case 1: { case 1: {
const TableAxis *axis1 = table->axis1(); const TableAxis *axis1 = table_model->axis1();
TableAxisVariable var1 = axis1->variable(); TableAxisVariable var1 = axis1->variable();
return var1 == TableAxisVariable::output_pin_transition return var1 == TableAxisVariable::output_pin_transition
|| var1 == TableAxisVariable::connect_delay; || var1 == TableAxisVariable::connect_delay;
} }
case 2: { case 2: {
const TableAxis *axis1 = table->axis1(); const TableAxis *axis1 = table_model->axis1();
const TableAxis *axis2 = table->axis2(); const TableAxis *axis2 = table_model->axis2();
TableAxisVariable var1 = axis1->variable(); TableAxisVariable var1 = axis1->variable();
TableAxisVariable var2 = axis2->variable(); TableAxisVariable var2 = axis2->variable();
return (var1 == TableAxisVariable::output_pin_transition return (var1 == TableAxisVariable::output_pin_transition
@ -1269,8 +1265,7 @@ LibertyCell::makeInternalPower(LibertyPort *port,
const std::shared_ptr<FuncExpr> &when, const std::shared_ptr<FuncExpr> &when,
InternalPowerModels &models) InternalPowerModels &models)
{ {
internal_powers_.emplace_back(port, related_port, related_pg_pin, internal_powers_.emplace_back(port, related_port, related_pg_pin, when, models);
when, models);
port_internal_powers_[port].push_back(internal_powers_.size() - 1); port_internal_powers_[port].push_back(internal_powers_.size() - 1);
} }
@ -1485,6 +1480,10 @@ LibertyCell::makeSequential(int size,
port_to_seq_map_[sequentials_.back().output()] = idx; port_to_seq_map_[sequentials_.back().output()] = idx;
port_to_seq_map_[sequentials_.back().outputInv()] = idx; port_to_seq_map_[sequentials_.back().outputInv()] = idx;
} }
delete clk;
delete data;
delete clear;
delete preset;
} }
Sequential * Sequential *
@ -1680,45 +1679,58 @@ LibertyCell::makeLatchEnables(Report *report,
{ {
if (hasSequentials() if (hasSequentials()
|| hasInferedRegTimingArcs()) { || hasInferedRegTimingArcs()) {
for (auto en_to_q : timing_arc_sets_) { for (TimingArcSet *d_to_q : timing_arc_sets_) {
if (en_to_q->role() == TimingRole::latchEnToQ()) { if (d_to_q->role() == TimingRole::latchDtoQ()) {
LibertyPort *en = en_to_q->from(); LibertyPort *d = d_to_q->from();
LibertyPort *q = en_to_q->to(); LibertyPort *q = d_to_q->to();
for (TimingArcSet *d_to_q : timingArcSetsTo(q)) { TimingArcSet *en_to_q = nullptr;
if (d_to_q->role() == TimingRole::latchDtoQ() TimingArcSet *en_to_q_when = nullptr;
&& condMatch(en_to_q, d_to_q)) { // Prefer en_to_q with matching when.
LibertyPort *d = d_to_q->from(); for (TimingArcSet *arc_to_q : timingArcSetsTo(q)) {
const RiseFall *en_rf = en_to_q->isRisingFallingEdge(); if (arc_to_q->role() == TimingRole::latchEnToQ()) {
if (en_rf) { if (condMatch(arc_to_q, d_to_q))
TimingArcSet *setup_check = findLatchSetup(d, en, en_rf, q, d_to_q, en_to_q_when = arc_to_q;
report); else
LatchEnable *latch_enable = makeLatchEnable(d, en, en_rf, q, d_to_q, en_to_q = arc_to_q;
en_to_q, }
setup_check, }
debug); if (en_to_q_when)
FuncExpr *en_func = latch_enable->enableFunc(); en_to_q = en_to_q_when;
if (en_func) { if (en_to_q) {
TimingSense en_sense = en_func->portTimingSense(en); LibertyPort *en = en_to_q->from();
if (en_sense == TimingSense::positive_unate const RiseFall *en_rf = en_to_q->isRisingFallingEdge();
&& en_rf != RiseFall::rise()) if (en_rf) {
report->warn(1114, "cell %s/%s %s -> %s latch enable %s_edge is inconsistent with latch group enable function positive sense.", TimingArcSet *setup_check = findLatchSetup(d, en, en_rf, q, d_to_q, report);
library_->name(), LatchEnable *latch_enable = makeLatchEnable(d, en, en_rf, q, d_to_q,
name(), en_to_q, setup_check, debug);
en->name(), FuncExpr *en_func = latch_enable->enableFunc();
q->name(), if (en_func) {
en_rf == RiseFall::rise()?"rising":"falling"); TimingSense en_sense = en_func->portTimingSense(en);
else if (en_sense == TimingSense::negative_unate if (en_sense == TimingSense::positive_unate
&& en_rf != RiseFall::fall()) && en_rf != RiseFall::rise())
report->warn(1115, "cell %s/%s %s -> %s latch enable %s_edge is inconsistent with latch group enable function negative sense.", report->warn(1114, "cell %s/%s %s -> %s latch enable %s_edge is inconsistent with latch group enable function positive sense.",
library_->name(), library_->name(),
name(), name(),
en->name(), en->name(),
q->name(), q->name(),
en_rf == RiseFall::rise()?"rising":"falling"); en_rf == RiseFall::rise()?"rising":"falling");
} else if (en_sense == TimingSense::negative_unate
&& en_rf != RiseFall::fall())
report->warn(1115, "cell %s/%s %s -> %s latch enable %s_edge is inconsistent with latch group enable function negative sense.",
library_->name(),
name(),
en->name(),
q->name(),
en_rf == RiseFall::rise()?"rising":"falling");
} }
} }
} }
else
report->warn(1121, "cell %s/%s no latch enable found for %s -> %s.",
library_->name(),
name(),
d->name(),
q->name());
} }
} }
} }
@ -1811,8 +1823,7 @@ LibertyCell::makeLatchEnable(LibertyPort *d,
Debug *debug) Debug *debug)
{ {
FuncExpr *en_func = findLatchEnableFunc(d, en, en_rf); FuncExpr *en_func = findLatchEnableFunc(d, en, en_rf);
latch_enables_.emplace_back(d, en, en_rf, en_func, q, d_to_q, en_to_q, latch_enables_.emplace_back(d, en, en_rf, en_func, q, d_to_q, en_to_q, setup_check);
setup_check);
size_t idx = latch_enables_.size() - 1; size_t idx = latch_enables_.size() - 1;
latch_d_to_q_map_[d_to_q] = idx; latch_d_to_q_map_[d_to_q] = idx;
latch_check_map_[setup_check] = idx; latch_check_map_[setup_check] = idx;
@ -2703,13 +2714,13 @@ LibertyPort::setReceiverModel(ReceiverModelPtr receiver_model)
receiver_model_ = receiver_model; receiver_model_ = receiver_model;
} }
string std::string
portLibertyToSta(const char *port_name) portLibertyToSta(const char *port_name)
{ {
constexpr char bus_brkt_left = '['; constexpr char bus_brkt_left = '[';
constexpr char bus_brkt_right = ']'; constexpr char bus_brkt_right = ']';
size_t name_length = strlen(port_name); size_t name_length = strlen(port_name);
string sta_name; std::string sta_name;
for (size_t i = 0; i < name_length; i++) { for (size_t i = 0; i < name_length; i++) {
char ch = port_name[i]; char ch = port_name[i];
if (ch == bus_brkt_left if (ch == bus_brkt_left
@ -2735,33 +2746,6 @@ LibertyPort::setDriverWaveform(DriverWaveform *driver_waveform,
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
RiseFallMinMax
LibertyPort::clockTreePathDelays() const
{
return clkTreeDelays1();
}
RiseFallMinMax
LibertyPort::clkTreeDelays() const
{
return clkTreeDelays1();
}
RiseFallMinMax
LibertyPort::clkTreeDelays1() const
{
RiseFallMinMax delays;
for (const RiseFall *from_rf : RiseFall::range()) {
for (const RiseFall *to_rf : RiseFall::range()) {
for (const MinMax *min_max : MinMax::range()) {
float delay = clkTreeDelay(0.0, from_rf, to_rf, min_max);
delays.setValue(from_rf, min_max, delay);
}
}
}
return delays;
}
float float
LibertyPort::clkTreeDelay(float in_slew, LibertyPort::clkTreeDelay(float in_slew,
const RiseFall *rf, const RiseFall *rf,
@ -3087,7 +3071,8 @@ OperatingConditions::setWireloadTree(WireloadTree tree)
static EnumNameMap<ScaleFactorType> scale_factor_type_map = static EnumNameMap<ScaleFactorType> scale_factor_type_map =
{{ScaleFactorType::pin_cap, "pin_cap"}, {{ScaleFactorType::pin_cap, "pin_cap"},
{ScaleFactorType::wire_cap, "wire_res"}, {ScaleFactorType::wire_cap, "wire_cap"},
{ScaleFactorType::wire_res, "wire_res"},
{ScaleFactorType::min_period, "min_period"}, {ScaleFactorType::min_period, "min_period"},
{ScaleFactorType::cell, "cell"}, {ScaleFactorType::cell, "cell"},
{ScaleFactorType::hold, "hold"}, {ScaleFactorType::hold, "hold"},
@ -3124,7 +3109,9 @@ scaleFactorTypeRiseFallSuffix(ScaleFactorType type)
|| type == ScaleFactorType::recovery || type == ScaleFactorType::recovery
|| type == ScaleFactorType::removal || type == ScaleFactorType::removal
|| type == ScaleFactorType::nochange || type == ScaleFactorType::nochange
|| type == ScaleFactorType::skew; || type == ScaleFactorType::skew
|| type == ScaleFactorType::leakage_power
|| type == ScaleFactorType::internal_power;
} }
bool bool
@ -3144,7 +3131,8 @@ scaleFactorTypeLowHighSuffix(ScaleFactorType type)
EnumNameMap<ScaleFactorPvt> scale_factor_pvt_names = EnumNameMap<ScaleFactorPvt> scale_factor_pvt_names =
{{ScaleFactorPvt::process, "process"}, {{ScaleFactorPvt::process, "process"},
{ScaleFactorPvt::volt, "volt"}, {ScaleFactorPvt::volt, "volt"},
{ScaleFactorPvt::temp, "temp"} {ScaleFactorPvt::temp, "temp"},
{ScaleFactorPvt::unknown, "unknown"}
}; };
ScaleFactorPvt ScaleFactorPvt
@ -3214,31 +3202,32 @@ ScaleFactors::scale(ScaleFactorType type,
} }
void void
ScaleFactors::print() ScaleFactors::report(Report *report)
{ {
printf("%10s", " "); std::string line = " ";
for (int pvt_index = 0; pvt_index < scale_factor_pvt_count; pvt_index++) { for (int pvt_index = 0; pvt_index < scale_factor_pvt_count; pvt_index++) {
ScaleFactorPvt pvt = (ScaleFactorPvt) pvt_index; ScaleFactorPvt pvt = (ScaleFactorPvt) pvt_index;
printf("%10s", scaleFactorPvtName(pvt)); stringAppend(line, "%10s", scaleFactorPvtName(pvt));
} }
printf("\n"); report->reportLineString(line);
for (int type_index = 0; type_index < scale_factor_type_count; type_index++) { for (int type_index = 0; type_index < scale_factor_type_count; type_index++) {
ScaleFactorType type = (ScaleFactorType) type_index; ScaleFactorType type = (ScaleFactorType) type_index;
printf("%10s ", scaleFactorTypeName(type)); stringPrint(line, "%10s ", scaleFactorTypeName(type));
for (int pvt_index = 0; pvt_index < scale_factor_pvt_count; pvt_index++) { for (int pvt_index = 0; pvt_index < scale_factor_pvt_count; pvt_index++) {
if (scaleFactorTypeRiseFallSuffix(type) if (scaleFactorTypeRiseFallSuffix(type)
|| scaleFactorTypeRiseFallPrefix(type) || scaleFactorTypeRiseFallPrefix(type)
|| scaleFactorTypeLowHighSuffix(type)) { || scaleFactorTypeLowHighSuffix(type)) {
printf(" %.3f,%.3f", stringAppend(line, " %.3f,%.3f",
scales_[type_index][pvt_index][RiseFall::riseIndex()], scales_[type_index][pvt_index][RiseFall::riseIndex()],
scales_[type_index][pvt_index][RiseFall::fallIndex()]); scales_[type_index][pvt_index][RiseFall::fallIndex()]);
} }
else { else {
printf(" %.3f", stringAppend(line, " %.3f",
scales_[type_index][pvt_index][0]); scales_[type_index][pvt_index][0]);
} }
} }
printf("\n"); report->reportLineString(line);
} }
} }

View File

@ -363,6 +363,7 @@ scan_signal_type()
%extend TimingArcSet { %extend TimingArcSet {
LibertyPort *from() { return self->from(); } LibertyPort *from() { return self->from(); }
LibertyPort *to() { return self->to(); } LibertyPort *to() { return self->to(); }
std::string to_string() { return self->to_string(); }
const TimingRole *role() { return self->role(); } const TimingRole *role() { return self->role(); }
const char *sdf_cond() { return self->sdfCond().c_str(); } const char *sdf_cond() { return self->sdfCond().c_str(); }
@ -378,6 +379,16 @@ full_name()
to); to);
} }
const std::string
when()
{
const FuncExpr *when = self->when();
if (when)
return when->to_string();
else
return "";
}
TimingArcSeq & TimingArcSeq &
timing_arcs() { return self->arcs(); } timing_arcs() { return self->arcs(); }

View File

@ -74,6 +74,11 @@ proc report_lib_cell_ { cell scene } {
if { $filename != "" } { if { $filename != "" } {
report_line "File $filename" report_line "File $filename"
} }
report_lib_ports $cell $scene
report_timing_arcs $cell
}
proc report_lib_ports { cell scene } {
set iter [$cell liberty_port_iterator] set iter [$cell liberty_port_iterator]
while {[$iter has_next]} { while {[$iter has_next]} {
set port [$iter next] set port [$iter next]
@ -115,5 +120,24 @@ proc report_lib_port { port scene } {
report_line " ${indent}$port_name [liberty_port_direction $port]$enable$func[port_capacitance_str $port $scene $sta_report_default_digits]" report_line " ${indent}$port_name [liberty_port_direction $port]$enable$func[port_capacitance_str $port $scene $sta_report_default_digits]"
} }
proc report_timing_arcs { cell } {
set timing_arcs [$cell timing_arc_sets]
if { [llength $timing_arcs] > 0 } {
puts ""
puts "Timing arcs"
foreach timing_arc $timing_arcs {
puts " [$timing_arc to_string]"
puts " [$timing_arc role]"
set when [$timing_arc when]
if { $when != "" } {
puts " when $when"
}
foreach arc [$timing_arc timing_arcs] {
puts " [$arc from_edge] -> [$arc to_edge]"
}
}
}
}
# sta namespace end # sta namespace end
} }

View File

@ -35,14 +35,11 @@
namespace sta { namespace sta {
using std::string; LibertyBuilder::LibertyBuilder(Debug *debug,
Report *report) :
void debug_(debug),
LibertyBuilder::init(Debug *debug, report_(report)
Report *report)
{ {
debug_ = debug;
report_ = report;
} }
LibertyCell * LibertyCell *
@ -105,7 +102,7 @@ LibertyBuilder::makeBusPortBit(ConcreteLibrary *library,
const char *bus_name, const char *bus_name,
int bit_index) int bit_index)
{ {
string bit_name; std::string bit_name;
stringPrint(bit_name, "%s%c%d%c", stringPrint(bit_name, "%s%c%d%c",
bus_name, bus_name,
library->busBrktLeft(), library->busBrktLeft(),
@ -189,6 +186,7 @@ LibertyBuilder::makeTimingArcs(LibertyCell *cell,
case TimingType::combinational: case TimingType::combinational:
if (seq if (seq
&& seq->isLatch() && seq->isLatch()
&& seq->data()
&& seq->data()->hasPort(from_port)) && seq->data()->hasPort(from_port))
// Latch D->Q timing arcs. // Latch D->Q timing arcs.
return makeLatchDtoQArcs(cell, from_port, to_port, return makeLatchDtoQArcs(cell, from_port, to_port,
@ -307,8 +305,9 @@ LibertyBuilder::makeCombinationalArcs(LibertyCell *cell,
{ {
FuncExpr *func = to_port->function(); FuncExpr *func = to_port->function();
FuncExpr *enable = to_port->tristateEnable(); FuncExpr *enable = to_port->tristateEnable();
TimingArcSet *arc_set = makeTimingArcSet(cell, from_port, to_port, TimingArcSet *arc_set = cell->makeTimingArcSet(from_port, to_port, nullptr,
TimingRole::combinational(), attrs); TimingRole::combinational(),
attrs);
TimingSense sense = attrs->timingSense(); TimingSense sense = attrs->timingSense();
if (sense == TimingSense::unknown) { if (sense == TimingSense::unknown) {
// Timing sense not specified - find it from function. // Timing sense not specified - find it from function.
@ -388,8 +387,9 @@ LibertyBuilder::makeLatchDtoQArcs(LibertyCell *cell,
TimingSense sense, TimingSense sense,
TimingArcAttrsPtr attrs) TimingArcAttrsPtr attrs)
{ {
TimingArcSet *arc_set = makeTimingArcSet(cell, from_port, to_port, TimingArcSet *arc_set = cell->makeTimingArcSet(from_port, to_port, nullptr,
TimingRole::latchDtoQ(), attrs); TimingRole::latchDtoQ(),
attrs);
TimingModel *model; TimingModel *model;
const RiseFall *to_rf = RiseFall::rise(); const RiseFall *to_rf = RiseFall::rise();
model = attrs->model(to_rf); model = attrs->model(to_rf);
@ -456,8 +456,8 @@ LibertyBuilder::makeFromTransitionArcs(LibertyCell *cell,
const TimingRole *role, const TimingRole *role,
TimingArcAttrsPtr attrs) TimingArcAttrsPtr attrs)
{ {
TimingArcSet *arc_set = makeTimingArcSet(cell, from_port, to_port, TimingArcSet *arc_set = cell->makeTimingArcSet(from_port, to_port,
related_out, role, attrs); related_out, role, attrs);
for (auto to_rf : RiseFall::range()) { for (auto to_rf : RiseFall::range()) {
TimingModel *model = attrs->model(to_rf); TimingModel *model = attrs->model(to_rf);
if (model) if (model)
@ -476,8 +476,8 @@ LibertyBuilder::makePresetClrArcs(LibertyCell *cell,
TimingArcSet *arc_set = nullptr; TimingArcSet *arc_set = nullptr;
TimingModel *model = attrs->model(to_rf); TimingModel *model = attrs->model(to_rf);
if (model) { if (model) {
arc_set = makeTimingArcSet(cell, from_port, to_port, arc_set = cell->makeTimingArcSet(from_port, to_port, nullptr,
TimingRole::regSetClr(), attrs); TimingRole::regSetClr(), attrs);
const RiseFall *opp_rf = to_rf->opposite(); const RiseFall *opp_rf = to_rf->opposite();
switch (attrs->timingSense()) { switch (attrs->timingSense()) {
case TimingSense::positive_unate: case TimingSense::positive_unate:
@ -509,8 +509,9 @@ LibertyBuilder::makeTristateEnableArcs(LibertyCell *cell,
bool to_fall, bool to_fall,
TimingArcAttrsPtr attrs) TimingArcAttrsPtr attrs)
{ {
TimingArcSet *arc_set = makeTimingArcSet(cell, from_port, to_port, TimingArcSet *arc_set = cell->makeTimingArcSet(from_port, to_port, nullptr,
TimingRole::tristateEnable(), attrs); TimingRole::tristateEnable(),
attrs);
FuncExpr *tristate_enable = to_port->tristateEnable(); FuncExpr *tristate_enable = to_port->tristateEnable();
TimingSense sense = attrs->timingSense(); TimingSense sense = attrs->timingSense();
if (sense == TimingSense::unknown && tristate_enable) if (sense == TimingSense::unknown && tristate_enable)
@ -579,9 +580,9 @@ LibertyBuilder::makeTristateDisableArcs(LibertyCell *cell,
bool to_fall, bool to_fall,
TimingArcAttrsPtr attrs) TimingArcAttrsPtr attrs)
{ {
TimingArcSet *arc_set = makeTimingArcSet(cell, from_port, to_port, TimingArcSet *arc_set = cell->makeTimingArcSet(from_port, to_port, nullptr,
TimingRole::tristateDisable(), TimingRole::tristateDisable(),
attrs); attrs);
TimingSense sense = attrs->timingSense(); TimingSense sense = attrs->timingSense();
FuncExpr *tristate_enable = to_port->tristateEnable(); FuncExpr *tristate_enable = to_port->tristateEnable();
if (sense == TimingSense::unknown && tristate_enable) if (sense == TimingSense::unknown && tristate_enable)
@ -648,7 +649,8 @@ LibertyBuilder::makeClockTreePathArcs(LibertyCell *cell,
const TimingRole *role, const TimingRole *role,
TimingArcAttrsPtr attrs) TimingArcAttrsPtr attrs)
{ {
TimingArcSet *arc_set = makeTimingArcSet(cell, nullptr, to_port, role, attrs); TimingArcSet *arc_set = cell->makeTimingArcSet(nullptr, to_port, nullptr,
role, attrs);
for (const RiseFall *to_rf : RiseFall::range()) { for (const RiseFall *to_rf : RiseFall::range()) {
TimingModel *model = attrs->model(to_rf); TimingModel *model = attrs->model(to_rf);
if (model) { if (model) {
@ -683,8 +685,8 @@ LibertyBuilder::makeMinPulseWidthArcs(LibertyCell *cell,
{ {
if (from_port == nullptr) if (from_port == nullptr)
from_port = to_port; from_port = to_port;
TimingArcSet *arc_set = makeTimingArcSet(cell, from_port, to_port, related_out, TimingArcSet *arc_set = cell->makeTimingArcSet(from_port, to_port, related_out,
role, attrs); role, attrs);
for (const RiseFall *from_rf : RiseFall::range()) { for (const RiseFall *from_rf : RiseFall::range()) {
TimingModel *model = attrs->model(from_rf); TimingModel *model = attrs->model(from_rf);
if (model) if (model)
@ -695,27 +697,6 @@ LibertyBuilder::makeMinPulseWidthArcs(LibertyCell *cell,
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
TimingArcSet *
LibertyBuilder::makeTimingArcSet(LibertyCell *cell,
LibertyPort *from,
LibertyPort *to,
const TimingRole *role,
TimingArcAttrsPtr attrs)
{
return cell->makeTimingArcSet(from, to, nullptr, role, attrs);
}
TimingArcSet *
LibertyBuilder::makeTimingArcSet(LibertyCell *cell,
LibertyPort *from,
LibertyPort *to,
LibertyPort *related_out,
const TimingRole *role,
TimingArcAttrsPtr attrs)
{
return cell->makeTimingArcSet(from, to, related_out, role, attrs);
}
TimingArc * TimingArc *
LibertyBuilder::makeTimingArc(TimingArcSet *set, LibertyBuilder::makeTimingArc(TimingArcSet *set,
const RiseFall *from_rf, const RiseFall *from_rf,

View File

@ -38,23 +38,21 @@ class Report;
class LibertyBuilder class LibertyBuilder
{ {
public: public:
LibertyBuilder() {} LibertyBuilder(Debug *debug,
virtual ~LibertyBuilder() {} Report *report);
void init(Debug *debug, LibertyCell *makeCell(LibertyLibrary *library,
Report *report); const char *name,
virtual LibertyCell *makeCell(LibertyLibrary *library, const char *filename);
const char *name, LibertyPort *makePort(LibertyCell *cell,
const char *filename); const char *name);
virtual LibertyPort *makePort(LibertyCell *cell, LibertyPort *makeBusPort(LibertyCell *cell,
const char *name); const char *bus_name,
virtual LibertyPort *makeBusPort(LibertyCell *cell, int from_index,
const char *bus_name, int to_index,
int from_index, BusDcl *bus_dcl);
int to_index, LibertyPort *makeBundlePort(LibertyCell *cell,
BusDcl *bus_dcl); const char *name,
virtual LibertyPort *makeBundlePort(LibertyCell *cell, ConcretePortSeq *members);
const char *name,
ConcretePortSeq *members);
// Build timing arc sets and their arcs given a type and sense. // Build timing arc sets and their arcs given a type and sense.
// Port functions and cell latches are also used by this builder // Port functions and cell latches are also used by this builder
// to get the correct roles. // to get the correct roles.
@ -100,29 +98,18 @@ protected:
int from_index, int from_index,
int to_index); int to_index);
// Bus port bit (internal to makeBusPortBits). // Bus port bit (internal to makeBusPortBits).
virtual LibertyPort *makePort(LibertyCell *cell, LibertyPort *makePort(LibertyCell *cell,
const char *bit_name, const char *bit_name,
int bit_index); int bit_index);
void makeBusPortBit(ConcreteLibrary *library, void makeBusPortBit(ConcreteLibrary *library,
LibertyCell *cell, LibertyCell *cell,
ConcretePort *bus_port, ConcretePort *bus_port,
const char *bus_name, const char *bus_name,
int index); int index);
virtual TimingArcSet *makeTimingArcSet(LibertyCell *cell, TimingArc *makeTimingArc(TimingArcSet *set,
LibertyPort *from, const Transition *from_rf,
LibertyPort *to, const Transition *to_rf,
const TimingRole *role, TimingModel *model);
TimingArcAttrsPtr attrs);
virtual TimingArcSet *makeTimingArcSet(LibertyCell *cell,
LibertyPort *from,
LibertyPort *to,
LibertyPort *related_out,
const TimingRole *role,
TimingArcAttrsPtr attrs);
virtual TimingArc *makeTimingArc(TimingArcSet *set,
const Transition *from_rf,
const Transition *to_rf,
TimingModel *model);
TimingArc *makeTimingArc(TimingArcSet *set, TimingArc *makeTimingArc(TimingArcSet *set,
const RiseFall *from_rf, const RiseFall *from_rf,
const RiseFall *to_rf, const RiseFall *to_rf,

View File

@ -42,8 +42,8 @@ using sta::Report;
using sta::Debug; using sta::Debug;
using sta::Network; using sta::Network;
using sta::LibertyReader; using sta::LibertyReader;
using sta::LibertyAttr;
using sta::LibertyGroup; using sta::LibertyGroup;
using sta::LibertySimpleAttr;
using sta::TimingGroup; using sta::TimingGroup;
using sta::LibertyCell; using sta::LibertyCell;
using sta::LibertyPort; using sta::LibertyPort;
@ -164,13 +164,6 @@ class BigcoLibertyBuilder : public LibertyBuilder
public: public:
virtual LibertyCell *makeCell(LibertyLibrary *library, const char *name, virtual LibertyCell *makeCell(LibertyLibrary *library, const char *name,
const char *filename); const char *filename);
protected:
virtual TimingArcSet *makeTimingArcSet(LibertyCell *cell, LibertyPort *from,
LibertyPort *to,
LibertyPort *related_out,
const TimingRole *role,
TimingArcAttrsPtr attrs) override;
}; };
LibertyCell * LibertyCell *
@ -182,16 +175,6 @@ BigcoLibertyBuilder::makeCell(LibertyLibrary *library, const char *name,
return cell; return cell;
} }
TimingArcSet *
BigcoLibertyBuilder::makeTimingArcSet(LibertyCell *cell, LibertyPort *from,
LibertyPort *to,
LibertyPort *related_out,
const TimingRole *role,
TimingArcAttrsPtr attrs)
{
return cell->makeTimingArcSet(from, to, related_out, role, attrs);
}
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
// Liberty reader to parse Bigco attributes. // Liberty reader to parse Bigco attributes.
@ -201,22 +184,18 @@ public:
BigcoLibertyReader(LibertyBuilder *builder); BigcoLibertyReader(LibertyBuilder *builder);
protected: protected:
virtual void visitAttr1(LibertyAttr *attr); virtual void visitAttr1(const LibertySimpleAttr *attr);
virtual void visitAttr2(LibertyAttr *attr); virtual void visitAttr2(const LibertySimpleAttr *attr);
virtual void beginLibrary(LibertyGroup *group); virtual void beginLibrary(const LibertyGroup *group,
const LibertyGroup *library_group);
virtual TimingGroup *makeTimingGroup(int line); virtual TimingGroup *makeTimingGroup(int line);
virtual void beginCell(LibertyGroup *group); virtual void beginCell(const LibertyGroup *group,
const LibertyGroup *library_group);
}; };
BigcoLibertyReader::BigcoLibertyReader(LibertyBuilder *builder) : BigcoLibertyReader::BigcoLibertyReader(LibertyBuilder *builder) :
LibertyReader(builder) LibertyReader(builder)
{ {
// Define a visitor for the "thingy" attribute.
// Note that the function descriptor passed to defineAttrVisitor
// must be defined by the LibertyVisitor class, so a number of
// extra visitor functions are pre-defined for extensions.
defineAttrVisitor("thingy", &LibertyReader::visitAttr1);
defineAttrVisitor("frob", &LibertyReader::visitAttr2);
} }
bool bool
@ -228,12 +207,13 @@ libertyCellRequired(const char *)
// Prune cells from liberty file based on libertyCellRequired predicate. // Prune cells from liberty file based on libertyCellRequired predicate.
void void
BigcoLibertyReader::beginCell(LibertyGroup *group) BigcoLibertyReader::beginCell(const LibertyGroup *group,
const LibertyGroup *library_group)
{ {
const char *name = group->firstName(); const char *name = group->firstName();
if (name if (name
&& libertyCellRequired(name)) && libertyCellRequired(name))
LibertyReader::beginCell(group); LibertyReader::beginCell(group, library_group);
} }
TimingGroup * TimingGroup *
@ -244,15 +224,16 @@ BigcoLibertyReader::makeTimingGroup(int line)
// Called at the beginning of a library group. // Called at the beginning of a library group.
void void
BigcoLibertyReader::beginLibrary(LibertyGroup *group) BigcoLibertyReader::beginLibrary(const LibertyGroup *group,
const LibertyGroup *library_group)
{ {
LibertyReader::beginLibrary(group); LibertyReader::beginLibrary(group, library_group);
// Do Bigco stuff here. // Do Bigco stuff here.
printf("Bigco was here.\n"); printf("Bigco was here.\n");
} }
void void
BigcoLibertyReader::visitAttr1(LibertyAttr *attr) BigcoLibertyReader::visitAttr1(const LibertySimpleAttr *attr)
{ {
const char *thingy = getAttrString(attr); const char *thingy = getAttrString(attr);
if (thingy) { if (thingy) {
@ -263,7 +244,7 @@ BigcoLibertyReader::visitAttr1(LibertyAttr *attr)
} }
void void
BigcoLibertyReader::visitAttr2(LibertyAttr *attr) BigcoLibertyReader::visitAttr2(const LibertySimpleAttr *attr)
{ {
const char *frob = getAttrString(attr); const char *frob = getAttrString(attr);
if (frob) { if (frob) {

View File

@ -87,14 +87,14 @@ EOL \r?\n
{FLOAT}{TOKEN_END} { {FLOAT}{TOKEN_END} {
/* Push back the TOKEN_END character. */ /* Push back the TOKEN_END character. */
yyless(yyleng - 1); yyless(yyleng - 1);
yylval->emplace<float>(strtod(yytext, nullptr)); yylval->emplace<float>(strtof(yytext, nullptr));
return token::FLOAT; return token::FLOAT;
} }
{ALPHA}({ALPHA}|_|{DIGIT})*{TOKEN_END} { {ALPHA}({ALPHA}|_|{DIGIT})*{TOKEN_END} {
/* Push back the TOKEN_END character. */ /* Push back the TOKEN_END character. */
yyless(yyleng - 1); yyless(yyleng - 1);
yylval->emplace<std::string>(yytext); yylval->emplace<std::string>(yytext, yyleng);
return token::KEYWORD; return token::KEYWORD;
} }
@ -107,7 +107,7 @@ EOL \r?\n
{TOKEN}{TOKEN_END} { {TOKEN}{TOKEN_END} {
/* Push back the TOKEN_END character. */ /* Push back the TOKEN_END character. */
yyless(yyleng - 1); yyless(yyleng - 1);
yylval->emplace<std::string>(yytext); yylval->emplace<std::string>(yytext, yyleng);
return token::STRING; return token::STRING;
} }
@ -141,7 +141,7 @@ EOL \r?\n
<qstring>{EOL} { <qstring>{EOL} {
error("unterminated string constant"); error("unterminated string constant");
BEGIN(INITIAL); BEGIN(INITIAL);
yylval->emplace<std::string>(token_); yylval->emplace<std::string>(token_);
return token::STRING; return token::STRING;
} }

View File

@ -52,7 +52,7 @@ sta::LibertyParse::error(const location_type &loc,
%require "3.2" %require "3.2"
%skeleton "lalr1.cc" %skeleton "lalr1.cc"
%debug //%debug
%define api.namespace {sta} %define api.namespace {sta}
%locations %locations
%define api.location.file "LibertyLocation.hh" %define api.location.file "LibertyLocation.hh"
@ -72,7 +72,7 @@ sta::LibertyParse::error(const location_type &loc,
%left '^' %left '^'
%left '!' %left '!'
%type <sta::LibertyStmt *> statement complex_attr simple_attr variable group file %type <void *> statement complex_attr simple_attr variable group file
%type <sta::LibertyAttrValueSeq *> attr_values %type <sta::LibertyAttrValueSeq *> attr_values
%type <sta::LibertyAttrValue *> attr_value %type <sta::LibertyAttrValue *> attr_value
%type <std::string> string expr expr_term expr_term1 volt_expr %type <std::string> string expr expr_term expr_term1 volt_expr
@ -158,11 +158,11 @@ string:
attr_value: attr_value:
FLOAT FLOAT
{ $$ = reader->makeFloatAttrValue($1); } { $$ = reader->makeAttrValueFloat($1); }
| expr | expr
{ $$ = reader->makeStringAttrValue(std::move($1)); } { $$ = reader->makeAttrValueString(std::move($1)); }
| volt_expr | volt_expr
{ $$ = reader->makeStringAttrValue(std::move($1)); } { $$ = reader->makeAttrValueString(std::move($1)); }
; ;
/* Voltage expressions are ignored. */ /* Voltage expressions are ignored. */

View File

@ -37,8 +37,6 @@
namespace sta { namespace sta {
using std::string;
void void
parseLibertyFile(const char *filename, parseLibertyFile(const char *filename,
LibertyGroupVisitor *library_visitor, LibertyGroupVisitor *library_visitor,
@ -65,26 +63,28 @@ LibertyParser::LibertyParser(const char *filename,
} }
void void
LibertyParser::setFilename(const string &filename) LibertyParser::setFilename(const std::string &filename)
{ {
filename_ = filename; filename_ = filename;
} }
LibertyStmt * LibertyDefine *
LibertyParser::makeDefine(LibertyAttrValueSeq *values, LibertyParser::makeDefine(const LibertyAttrValueSeq *values,
int line) int line)
{ {
LibertyDefine *define = nullptr; LibertyDefine *define = nullptr;
if (values->size() == 3) { if (values->size() == 3) {
std::string define_name = (*values)[0]->stringValue(); const std::string &define_name = (*values)[0]->stringValue();
const std::string &group_type_name = (*values)[1]->stringValue(); const std::string &group_type_name = (*values)[1]->stringValue();
const std::string &value_type_name = (*values)[2]->stringValue(); const std::string &value_type_name = (*values)[2]->stringValue();
LibertyAttrType value_type = attrValueType(value_type_name.c_str()); LibertyAttrType value_type = attrValueType(value_type_name);
LibertyGroupType group_type = groupType(group_type_name.c_str()); LibertyGroupType group_type = groupType(group_type_name);
define = new LibertyDefine(std::move(define_name), group_type, define = new LibertyDefine(std::move(define_name), group_type, value_type, line);
value_type, line);
LibertyGroup *group = this->group(); LibertyGroup *group = this->group();
group->addStmt(define); group->addDefine(define);
for (auto value : *values)
delete value;
delete values;
} }
else else
report_->fileWarn(24, filename_.c_str(), line, report_->fileWarn(24, filename_.c_str(), line,
@ -96,42 +96,47 @@ LibertyParser::makeDefine(LibertyAttrValueSeq *values,
// used to define valid attribute types. Beyond "string" these are // used to define valid attribute types. Beyond "string" these are
// guesses. // guesses.
LibertyAttrType LibertyAttrType
LibertyParser::attrValueType(const char *value_type_name) LibertyParser::attrValueType(const std::string &value_type_name)
{ {
if (stringEq(value_type_name, "string")) if (value_type_name == "string")
return LibertyAttrType::attr_string; return LibertyAttrType::attr_string;
else if (stringEq(value_type_name, "integer")) else if (value_type_name == "integer")
return LibertyAttrType::attr_int; return LibertyAttrType::attr_int;
else if (stringEq(value_type_name, "float")) else if (value_type_name == "float")
return LibertyAttrType::attr_double; return LibertyAttrType::attr_double;
else if (stringEq(value_type_name, "boolean")) else if (value_type_name == "boolean")
return LibertyAttrType::attr_boolean; return LibertyAttrType::attr_boolean;
else else
return LibertyAttrType::attr_unknown; return LibertyAttrType::attr_unknown;
} }
LibertyGroupType LibertyGroupType
LibertyParser::groupType(const char *group_type_name) LibertyParser::groupType(const std::string &group_type_name)
{ {
if (stringEq(group_type_name, "library")) if (group_type_name == "library")
return LibertyGroupType::library; return LibertyGroupType::library;
else if (stringEq(group_type_name, "cell")) else if (group_type_name == "cell")
return LibertyGroupType::cell; return LibertyGroupType::cell;
else if (stringEq(group_type_name, "pin")) else if (group_type_name == "pin")
return LibertyGroupType::pin; return LibertyGroupType::pin;
else if (stringEq(group_type_name, "timing")) else if (group_type_name == "timing")
return LibertyGroupType::timing; return LibertyGroupType::timing;
else else
return LibertyGroupType::unknown; return LibertyGroupType::unknown;
} }
void void
LibertyParser::groupBegin(std::string type, LibertyParser::groupBegin(const std::string type,
LibertyAttrValueSeq *params, LibertyAttrValueSeq *params,
int line) int line)
{ {
LibertyGroup *group = new LibertyGroup(std::move(type), params, line); LibertyGroup *group =
group_visitor_->begin(group); new LibertyGroup(std::move(type),
params ? std::move(*params) : LibertyAttrValueSeq(),
line);
delete params;
LibertyGroup *parent_group = group_stack_.empty() ? nullptr : group_stack_.back();
group_visitor_->begin(group, parent_group);
group_stack_.push_back(group); group_stack_.push_back(group);
} }
@ -139,20 +144,13 @@ LibertyGroup *
LibertyParser::groupEnd() LibertyParser::groupEnd()
{ {
LibertyGroup *group = this->group(); LibertyGroup *group = this->group();
group_visitor_->end(group);
group_stack_.pop_back(); group_stack_.pop_back();
LibertyGroup *parent = LibertyGroup *parent =
group_stack_.empty() ? nullptr : group_stack_.back(); group_stack_.empty() ? nullptr : group_stack_.back();
if (parent && group_visitor_->save(group)) { if (parent)
parent->addStmt(group); parent->addSubgroup(group);
return group; group_visitor_->end(group, parent);
} return group;
else if (group_visitor_->save(group))
return group;
else {
delete group;
return nullptr;
}
} }
LibertyGroup * LibertyGroup *
@ -167,240 +165,65 @@ LibertyParser::deleteGroups()
deleteContents(group_stack_); deleteContents(group_stack_);
} }
LibertyStmt * LibertySimpleAttr *
LibertyParser::makeSimpleAttr(std::string name, LibertyParser::makeSimpleAttr(const std::string name,
LibertyAttrValue *value, const LibertyAttrValue *value,
int line) int line)
{ {
LibertyAttr *attr = new LibertySimpleAttr(std::move(name), value, line); LibertySimpleAttr *attr = new LibertySimpleAttr(std::move(name),
group_visitor_->visitAttr(attr); std::move(*value), line);
delete value;
LibertyGroup *group = this->group(); LibertyGroup *group = this->group();
if (group && group_visitor_->save(attr)) { group->addAttr(attr);
group->addStmt(attr); group_visitor_->visitAttr(attr);
return attr; return attr;
}
else {
delete attr;
return nullptr;
}
} }
LibertyStmt * LibertyComplexAttr *
LibertyParser::makeComplexAttr(std::string name, LibertyParser::makeComplexAttr(const std::string name,
LibertyAttrValueSeq *values, const LibertyAttrValueSeq *values,
int line) int line)
{ {
// Defines have the same syntax as complex attributes. // Defines have the same syntax as complex attributes.
// Detect and convert them. // Detect and convert them.
if (name == "define") { if (name == "define") {
LibertyStmt *define = makeDefine(values, line); makeDefine(values, line);
deleteContents(values); return nullptr; // Define is not a complex attr; already added to group
delete values;
return define;
} }
else { else {
LibertyAttr *attr = new LibertyComplexAttr(std::move(name), values, line); LibertyComplexAttr *attr = new LibertyComplexAttr(std::move(name),
std::move(*values),
line);
delete values;
LibertyGroup *group = this->group();
group->addAttr(attr);
group_visitor_->visitAttr(attr); group_visitor_->visitAttr(attr);
if (group_visitor_->save(attr)) { return attr;
LibertyGroup *group = this->group();
group->addStmt(attr);
return attr;
}
delete attr;
return nullptr;
} }
} }
LibertyStmt * LibertyVariable *
LibertyParser::makeVariable(std::string var, LibertyParser::makeVariable(const std::string var,
float value, float value,
int line) int line)
{ {
LibertyVariable *variable = new LibertyVariable(std::move(var), value, line); LibertyVariable *variable = new LibertyVariable(std::move(var), value, line);
LibertyGroup *group = this->group();
group->addVariable(variable);
group_visitor_->visitVariable(variable); group_visitor_->visitVariable(variable);
if (group_visitor_->save(variable)) return variable;
return variable;
else {
delete variable;
return nullptr;
}
} }
LibertyAttrValue * LibertyAttrValue *
LibertyParser::makeStringAttrValue(std::string value) LibertyParser::makeAttrValueString(std::string value)
{ {
return new LibertyStringAttrValue(std::move(value)); return new LibertyAttrValue(std::move(value));
} }
LibertyAttrValue * LibertyAttrValue *
LibertyParser::makeFloatAttrValue(float value) LibertyParser::makeAttrValueFloat(float value)
{
return new LibertyFloatAttrValue(value);
}
const std::string &
LibertyFloatAttrValue::stringValue() const
{
criticalError(1127, "LibertyStringAttrValue called for float value");
static std::string null;
return null;
}
////////////////////////////////////////////////////////////////
LibertyStmt::LibertyStmt(int line) :
line_(line)
{
}
LibertyGroup::LibertyGroup(std::string type,
LibertyAttrValueSeq *params,
int line) :
LibertyStmt(line),
type_(std::move(type)),
params_(params),
stmts_(nullptr)
{
}
void
LibertyGroup::addStmt(LibertyStmt *stmt)
{
if (stmts_ == nullptr)
stmts_ = new LibertyStmtSeq;
stmts_->push_back(stmt);
}
LibertyGroup::~LibertyGroup()
{
if (params_) {
deleteContents(params_);
delete params_;
}
if (stmts_) {
deleteContents(stmts_);
delete stmts_;
}
}
const char *
LibertyGroup::firstName()
{
if (params_ && params_->size() > 0) {
LibertyAttrValue *value = (*params_)[0];
if (value->isString())
return value->stringValue().c_str();
}
return nullptr;
}
const char *
LibertyGroup::secondName()
{
if (params_ && params_->size() > 1) {
LibertyAttrValue *value = (*params_)[1];
if (value->isString())
return value->stringValue().c_str();
}
return nullptr;
}
////////////////////////////////////////////////////////////////
LibertyAttr::LibertyAttr(std::string name,
int line) :
LibertyStmt(line),
name_(std::move(name))
{
}
LibertySimpleAttr::LibertySimpleAttr(std::string name,
LibertyAttrValue *value,
int line) :
LibertyAttr(std::move(name), line),
value_(value)
{
}
LibertySimpleAttr::~LibertySimpleAttr()
{
delete value_;
}
LibertyAttrValueSeq *
LibertySimpleAttr::values() const
{
criticalError(1125, "valueIterator called for LibertySimpleAttribute");
return nullptr;
}
////////////////////////////////////////////////////////////////
LibertyComplexAttr::LibertyComplexAttr(std::string name,
LibertyAttrValueSeq *values,
int line) :
LibertyAttr(std::move(name), line),
values_(values)
{
}
LibertyComplexAttr::~LibertyComplexAttr()
{
if (values_) {
deleteContents(values_);
delete values_;
}
}
LibertyAttrValue *
LibertyComplexAttr::firstValue()
{
if (values_ && values_->size() > 0)
return (*values_)[0];
else
return nullptr;
}
LibertyStringAttrValue::LibertyStringAttrValue(std::string value) :
LibertyAttrValue(),
value_(std::move(value))
{
}
float
LibertyStringAttrValue::floatValue() const
{
criticalError(1126, "LibertyStringAttrValue called for float value");
return 0.0;
}
LibertyFloatAttrValue::LibertyFloatAttrValue(float value) :
value_(value)
{
}
////////////////////////////////////////////////////////////////
LibertyDefine::LibertyDefine(std::string name,
LibertyGroupType group_type,
LibertyAttrType value_type,
int line) :
LibertyStmt(line),
name_(std::move(name)),
group_type_(group_type),
value_type_(value_type)
{
}
////////////////////////////////////////////////////////////////
LibertyVariable::LibertyVariable(std::string var,
float value,
int line) :
LibertyStmt(line),
var_(std::move(var)),
value_(value)
{ {
return new LibertyAttrValue(value);
} }
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
@ -425,13 +248,13 @@ LibertyScanner::includeBegin()
error("nested include_file's are not supported"); error("nested include_file's are not supported");
else { else {
// include_file(filename); // include_file(filename);
std::regex include_regexp("include_file *\\( *([^)]+) *\\) *;?"); static const std::regex include_regexp("include_file *\\( *([^)]+) *\\) *;?");
std::cmatch matches; std::cmatch matches;
if (std::regex_match(yytext, matches, include_regexp)) { if (std::regex_match(yytext, matches, include_regexp)) {
string filename = matches[1].str(); std::string filename = matches[1].str();
gzstream::igzstream *stream = new gzstream::igzstream(filename.c_str()); gzstream::igzstream *stream = new gzstream::igzstream(filename.c_str());
if (stream->is_open()) { if (stream->is_open()) {
yypush_buffer_state(yy_create_buffer(stream, 256)); yypush_buffer_state(yy_create_buffer(stream, 16384));
filename_prev_ = filename_; filename_prev_ = filename_;
stream_prev_ = stream_; stream_prev_ = stream_;
@ -471,4 +294,323 @@ LibertyScanner::error(const char *msg)
report_->fileError(1866, filename_.c_str(), lineno(), "%s", msg); report_->fileError(1866, filename_.c_str(), lineno(), "%s", msg);
} }
////////////////////////////////////////////////////////////////
LibertyGroup::LibertyGroup(std::string type,
LibertyAttrValueSeq params,
int line) :
type_(std::move(type)),
params_(std::move(params)),
line_(line)
{
}
LibertyGroup::~LibertyGroup()
{
clear();
}
void
LibertyGroup::clear()
{
deleteContents(params_);
deleteContents(simple_attr_map_);
for (auto &attr : complex_attr_map_)
deleteContents(attr.second);
complex_attr_map_.clear();
deleteContents(subgroups_);
subgroup_map_.clear();
deleteContents(define_map_);
deleteContents(variables_);
}
void
LibertyGroup::addSubgroup(LibertyGroup *subgroup)
{
subgroups_.push_back(subgroup);
subgroup_map_[subgroup->type()].push_back(subgroup);
}
void
LibertyGroup::deleteSubgroup(const LibertyGroup *subgroup)
{
if (subgroup == subgroups_.back()) {
subgroups_.pop_back();
subgroup_map_[subgroup->type()].pop_back();
delete subgroup;
}
else
criticalError(1128, "LibertyAttrValue::floatValue() called on string");
}
void
LibertyGroup::addDefine(LibertyDefine *define)
{
const std::string &define_name = define->name();
LibertyDefine *prev_define = findKey(define_map_, define_name);
if (prev_define) {
define_map_.erase(define_name);
delete prev_define;
}
define_map_[define_name] = define;
}
void
LibertyGroup::addAttr(LibertySimpleAttr *attr)
{
// Only keep the most recent simple attribute value.
const auto &itr = simple_attr_map_.find(attr->name());
if (itr != simple_attr_map_.end())
delete itr->second;
simple_attr_map_[attr->name()] = attr;
}
void
LibertyGroup::addAttr(LibertyComplexAttr *attr)
{
complex_attr_map_[attr->name()].push_back(attr);
}
void
LibertyGroup::addVariable(LibertyVariable *var)
{
variables_.push_back(var);
}
const char *
LibertyGroup::firstName() const
{
if (params_.size() >= 1) {
LibertyAttrValue *value = params_[0];
if (value->isString())
return value->stringValue().c_str();
}
return nullptr;
}
const char *
LibertyGroup::secondName() const
{
LibertyAttrValue *value = params_[1];
if (value->isString())
return value->stringValue().c_str();
else
return nullptr;
}
const LibertyGroupSeq &
LibertyGroup::findSubgroups(const std::string type) const
{
return findKeyValue(subgroup_map_, type);
}
const LibertyGroup *
LibertyGroup::findSubgroup(const std::string type) const
{
const LibertyGroupSeq &groups = findKeyValue(subgroup_map_, type);
if (groups.size() >= 1)
return groups[0];
else
return nullptr;
}
const LibertySimpleAttr *
LibertyGroup::findSimpleAttr(const std::string attr_name) const
{
return findKeyValue(simple_attr_map_, attr_name);
}
const LibertyComplexAttrSeq &
LibertyGroup::findComplexAttrs(const std::string attr_name) const
{
return findKeyValue(complex_attr_map_, attr_name);
}
const LibertyComplexAttr *
LibertyGroup::findComplexAttr(const std::string attr_name) const
{
const LibertyComplexAttrSeq &attrs = findKeyValue(complex_attr_map_, attr_name);
if (attrs.size() >= 1)
return attrs[0];
else
return nullptr;
}
const std::string *
LibertyGroup::findAttrString(const std::string attr_name) const
{
const LibertySimpleAttr *attr = findSimpleAttr(attr_name);
if (attr)
return &attr->value().stringValue();
else
return nullptr;
}
void
LibertyGroup::findAttrFloat(const std::string attr_name,
// Return values.
float &value,
bool &exists) const
{
const LibertySimpleAttr *attr = findSimpleAttr(attr_name);
if (attr) {
const LibertyAttrValue &attr_value = attr->value();
if (attr_value.isFloat()) {
value = attr_value.floatValue();
exists = true;
return;
}
else {
// Possibly quoted string float.
const std::string &float_str = attr_value.stringValue();
char *end = nullptr;
value = std::strtof(float_str.c_str(), &end);
if (end) {
exists = true;
return;
}
}
}
exists = false;
}
void
LibertyGroup::findAttrInt(const std::string attr_name,
// Return values.
int &value,
bool &exists) const
{
const LibertySimpleAttr *attr = findSimpleAttr(attr_name);
if (attr) {
const LibertyAttrValue &attr_value = attr->value();
if (attr_value.isFloat()) {
value = static_cast<int>(attr_value.floatValue());
exists = true;
return;
}
}
exists = false;
}
////////////////////////////////////////////////////////////////
LibertySimpleAttr::LibertySimpleAttr(const std::string name,
const LibertyAttrValue value,
int line) :
name_(std::move(name)),
line_(line),
value_(std::move(value))
{
}
const std::string *
LibertySimpleAttr::stringValue() const
{
return &value().stringValue();
}
////////////////////////////////////////////////////////////////
LibertyComplexAttr::LibertyComplexAttr(std::string name,
const LibertyAttrValueSeq values,
int line) :
name_(std::move(name)),
values_(std::move(values)),
line_(line)
{
}
LibertyComplexAttr::~LibertyComplexAttr()
{
deleteContents(values_);
}
const LibertyAttrValue *
LibertyComplexAttr::firstValue() const
{
if (values_.size() > 0)
return values_[0];
else
return nullptr;
}
////////////////////////////////////////////////////////////////
LibertyAttrValue::LibertyAttrValue(std::string value) :
string_value_(std::move(value))
{
}
LibertyAttrValue::LibertyAttrValue(float value) :
float_value_(value)
{
}
bool
LibertyAttrValue::isFloat() const
{
return string_value_.empty();
}
bool
LibertyAttrValue::isString() const
{
return !string_value_.empty();
}
float
LibertyAttrValue::floatValue() const
{
if (!string_value_.empty())
criticalError(1127, "LibertyAttrValue::floatValue() called on string");
return float_value_;
}
void
LibertyAttrValue::floatValue(// Return values.
float &value,
bool &valid) const
{
valid = false;
if (string_value_.empty()) {
value = float_value_;
valid = true;
}
else {
// Some floats are enclosed in quotes.
char *end;
value = strtof(string_value_.c_str(), &end);
if ((*end == '\0'
|| isspace(*end))
// strtof support INF as a valid float.
&& string_value_ != "inf") {
valid = true;
}
}
}
////////////////////////////////////////////////////////////////
LibertyDefine::LibertyDefine(std::string name,
LibertyGroupType group_type,
LibertyAttrType value_type,
int line) :
name_(std::move(name)),
group_type_(group_type),
value_type_(value_type),
line_(line)
{
}
////////////////////////////////////////////////////////////////
LibertyVariable::LibertyVariable(std::string var,
float value,
int line) :
var_(std::move(var)),
value_(value),
line_(line)
{
}
} // namespace } // namespace

View File

@ -34,20 +34,22 @@ namespace sta {
class Report; class Report;
class LibertyGroupVisitor; class LibertyGroupVisitor;
class LibertyStmt;
class LibertyGroup; class LibertyGroup;
class LibertyAttr;
class LibertyDefine; class LibertyDefine;
class LibertySimpleAttr;
class LibertyComplexAttr;
class LibertyAttrValue; class LibertyAttrValue;
class LibertyVariable; class LibertyVariable;
class LibertyScanner; class LibertyScanner;
using LibertyStmtSeq = std::vector<LibertyStmt*>;
using LibertyGroupSeq = std::vector<LibertyGroup*>; using LibertyGroupSeq = std::vector<LibertyGroup*>;
using LibertyAttrSeq = std::vector<LibertyAttr*>; using LibertySubGroupMap = std::map<std::string, LibertyGroupSeq>;
using LibertyAttrMap = std::map<std::string, LibertyAttr*>; using LibertySimpleAttrMap = std::map<std::string, LibertySimpleAttr*>;
using LibertyComplexAttrSeq = std::vector<LibertyComplexAttr*>;
using LibertyComplexAttrMap = std::map<std::string, LibertyComplexAttrSeq>;
using LibertyDefineMap = std::map<std::string, LibertyDefine*>; using LibertyDefineMap = std::map<std::string, LibertyDefine*>;
using LibertyAttrValueSeq = std::vector<LibertyAttrValue*>; using LibertyAttrValueSeq = std::vector<LibertyAttrValue*>;
using LibertyVariableSeq = std::vector<LibertyVariable*>;
using LibertyVariableMap = std::map<std::string, float>; using LibertyVariableMap = std::map<std::string, float>;
using LibertyGroupVisitorMap = std::map<std::string, LibertyGroupVisitor*>; using LibertyGroupVisitorMap = std::map<std::string, LibertyGroupVisitor*>;
@ -65,27 +67,27 @@ public:
const std::string &filename() const { return filename_; } const std::string &filename() const { return filename_; }
void setFilename(const std::string &filename); void setFilename(const std::string &filename);
Report *report() const { return report_; } Report *report() const { return report_; }
LibertyStmt *makeDefine(LibertyAttrValueSeq *values, LibertyDefine *makeDefine(const LibertyAttrValueSeq *values,
int line); int line);
LibertyAttrType attrValueType(const char *value_type_name); LibertyAttrType attrValueType(const std::string &value_type_name);
LibertyGroupType groupType(const char *group_type_name); LibertyGroupType groupType(const std::string &group_type_name);
void groupBegin(std::string type, void groupBegin(const std::string type,
LibertyAttrValueSeq *params, LibertyAttrValueSeq *params,
int line); int line);
LibertyGroup *groupEnd(); LibertyGroup *groupEnd();
LibertyGroup *group(); LibertyGroup *group();
void deleteGroups(); void deleteGroups();
LibertyStmt *makeSimpleAttr(std::string name, LibertySimpleAttr *makeSimpleAttr(const std::string name,
LibertyAttrValue *value, const LibertyAttrValue *value,
int line); int line);
LibertyStmt *makeComplexAttr(std::string name, LibertyComplexAttr *makeComplexAttr(const std::string name,
LibertyAttrValueSeq *values, const LibertyAttrValueSeq *values,
int line); int line);
LibertyAttrValue *makeStringAttrValue(std::string value); LibertyAttrValue *makeAttrValueString(const std::string value);
LibertyAttrValue *makeFloatAttrValue(float value); LibertyAttrValue *makeAttrValueFloat(float value);
LibertyStmt *makeVariable(std::string var, LibertyVariable *makeVariable(const std::string var,
float value, float value,
int line); int line);
private: private:
std::string filename_; std::string filename_;
@ -94,178 +96,171 @@ private:
LibertyGroupSeq group_stack_; LibertyGroupSeq group_stack_;
}; };
// Abstract base class for liberty statements.
class LibertyStmt
{
public:
LibertyStmt(int line);
virtual ~LibertyStmt() {}
int line() const { return line_; }
virtual bool isGroup() const { return false; }
virtual bool isAttribute() const { return false; }
virtual bool isSimpleAttr() const { return false; }
virtual bool isComplexAttr() const { return false; }
virtual bool isDefine() const { return false; }
virtual bool isVariable() const { return false; }
protected:
int line_;
};
// Groups are a type keyword with a set of parameters and statements
// enclosed in brackets.
// type([param1][, param2]...) { stmts.. }
class LibertyGroup : public LibertyStmt
{
public:
LibertyGroup(std::string type,
LibertyAttrValueSeq *params,
int line);
virtual ~LibertyGroup();
virtual bool isGroup() const { return true; }
const std::string &type() const { return type_; }
LibertyAttrValueSeq *params() const { return params_; }
// First param as a string.
const char *firstName();
// Second param as a string.
const char *secondName();
void addStmt(LibertyStmt *stmt);
LibertyStmtSeq *stmts() const { return stmts_; }
protected:
void parseNames(LibertyAttrValueSeq *values);
std::string type_;
LibertyAttrValueSeq *params_;
LibertyStmtSeq *stmts_;
};
// Abstract base class for attributes.
class LibertyAttr : public LibertyStmt
{
public:
LibertyAttr(std::string name,
int line);
const std::string &name() const { return name_; }
virtual LibertyAttrValueSeq *values() const = 0;
virtual LibertyAttrValue *firstValue() = 0;
protected:
std::string name_;
};
// Abstract base class for simple attributes.
// name : value;
class LibertySimpleAttr : public LibertyAttr
{
public:
LibertySimpleAttr(std::string name,
LibertyAttrValue *value,
int line);
virtual ~LibertySimpleAttr();
bool isSimpleAttr() const override { return true; };
LibertyAttrValue *firstValue() override { return value_; };
LibertyAttrValueSeq *values() const override;
private:
LibertyAttrValue *value_;
};
// Complex attributes have multiple values.
// name(attr_value1[, attr_value2]...);
class LibertyComplexAttr : public LibertyAttr
{
public:
LibertyComplexAttr(std::string name,
LibertyAttrValueSeq *values,
int line);
virtual ~LibertyComplexAttr();
bool isComplexAttr() const override { return true; };
LibertyAttrValue *firstValue() override ;
LibertyAttrValueSeq *values() const override { return values_; }
private:
LibertyAttrValueSeq *values_;
};
// Attribute values are a string or float. // Attribute values are a string or float.
class LibertyAttrValue class LibertyAttrValue
{ {
public: public:
LibertyAttrValue() {} LibertyAttrValue() {}
virtual ~LibertyAttrValue() {} LibertyAttrValue(float value);
virtual bool isString() const = 0; LibertyAttrValue(std::string value);
virtual bool isFloat() const = 0; bool isString() const;
virtual float floatValue() const = 0; bool isFloat() const;
virtual const std::string &stringValue() const = 0; float floatValue() const;
}; void floatValue(// Return values.
float &value,
class LibertyStringAttrValue : public LibertyAttrValue bool &valid) const;
{ const std::string &stringValue() const { return string_value_; }
public:
LibertyStringAttrValue(std::string value);
virtual ~LibertyStringAttrValue() {}
bool isFloat() const override { return false; }
bool isString() const override { return true; }
float floatValue() const override ;
const std::string &stringValue() const override { return value_; }
private: private:
std::string value_; float float_value_;
std::string string_value_;
}; };
class LibertyFloatAttrValue : public LibertyAttrValue // Groups are a type keyword with a set of parameters and statements
// enclosed in brackets.
// type([param1][, param2]...) { stmts.. }
class LibertyGroup
{ {
public: public:
LibertyFloatAttrValue(float value); LibertyGroup(const std::string type,
virtual ~LibertyFloatAttrValue() {} const LibertyAttrValueSeq params,
bool isString() const override { return false; } int line);
bool isFloat() const override { return true; } ~LibertyGroup();
float floatValue() const override { return value_; } void clear();
const std::string &stringValue() const override; const std::string &type() const { return type_; }
const LibertyAttrValueSeq &params() const { return params_; }
// First param as a string.
const char *firstName() const;
// Second param as a string.
const char *secondName() const;
int line() const { return line_; }
const LibertyGroupSeq &findSubgroups(const std::string type) const;
const LibertyGroup *findSubgroup(const std::string type) const;
const LibertySimpleAttr *findSimpleAttr(const std::string attr_name) const;
const LibertyComplexAttrSeq &findComplexAttrs(const std::string attr_name) const;
const LibertyComplexAttr *findComplexAttr(const std::string attr_name) const;
const std::string *findAttrString(const std::string attr_name) const;
void findAttrFloat(const std::string attr_name,
// Return values.
float &value,
bool &exists) const;
void findAttrInt(const std::string attr_name,
// Return values.
int &value,
bool &exists) const;
const LibertyGroupSeq &subgroups() const { return subgroups_; }
const LibertyDefineMap &defineMap() const { return define_map_; }
void addSubgroup(LibertyGroup *subgroup);
void deleteSubgroup(const LibertyGroup *subgroup);
void addAttr(LibertySimpleAttr *attr);
void addAttr(LibertyComplexAttr *attr);
void addDefine(LibertyDefine *define);
void addVariable(LibertyVariable *var);
protected:
std::string type_;
LibertyAttrValueSeq params_;
int line_;
LibertySimpleAttrMap simple_attr_map_;
LibertyComplexAttrMap complex_attr_map_;
LibertyGroupSeq subgroups_;
LibertySubGroupMap subgroup_map_;
LibertyDefineMap define_map_;
LibertyVariableSeq variables_;
};
class LibertyGroupLineLess
{
public:
bool
operator()(const LibertyGroup *group1,
const LibertyGroup *group2) const {
return group1->line() < group2->line();
}
};
// Simple attributes: name : value;
class LibertySimpleAttr
{
public:
LibertySimpleAttr(const std::string name,
const LibertyAttrValue value,
int line);
const std::string &name() const { return name_; }
const LibertyAttrValue &value() const { return value_; };
const std::string *stringValue() const;
int line() const { return line_; }
private: private:
float value_; std::string name_;
int line_;
LibertyAttrValue value_;
};
// Complex attributes have multiple values.
// name(attr_value1[, attr_value2]...);
class LibertyComplexAttr
{
public:
LibertyComplexAttr(const std::string name,
const LibertyAttrValueSeq values,
int line);
~LibertyComplexAttr();
const std::string &name() const { return name_; }
const LibertyAttrValue *firstValue() const;
const LibertyAttrValueSeq &values() const { return values_; }
int line() const { return line_; }
private:
std::string name_;
LibertyAttrValueSeq values_;
int line_;
}; };
// Define statements define new simple attributes. // Define statements define new simple attributes.
// define(attribute_name, group_name, attribute_type); // define(attribute_name, group_name, attribute_type);
// attribute_type is string|integer|float. // attribute_type is string|integer|float.
class LibertyDefine : public LibertyStmt class LibertyDefine
{ {
public: public:
LibertyDefine(std::string name, LibertyDefine(std::string name,
LibertyGroupType group_type, LibertyGroupType group_type,
LibertyAttrType value_type, LibertyAttrType value_type,
int line); int line);
virtual bool isDefine() const { return true; }
const std::string &name() const { return name_; } const std::string &name() const { return name_; }
LibertyGroupType groupType() const { return group_type_; } LibertyGroupType groupType() const { return group_type_; }
LibertyAttrType valueType() const { return value_type_; } LibertyAttrType valueType() const { return value_type_; }
int line() const { return line_; }
private: private:
std::string name_; std::string name_;
LibertyGroupType group_type_; LibertyGroupType group_type_;
LibertyAttrType value_type_; LibertyAttrType value_type_;
int line_;
}; };
// The Liberty User Guide Version 2003.12 fails to document variables. // The Liberty User Guide Version 2003.12 fails to document variables.
// var = value; // var = value;
// The only example I have only uses float values, so I am assuming // The only example I have only uses float values, so I am assuming
// that is all that is supported (which is probably wrong). // that is all that is supported (which is probably wrong).
class LibertyVariable : public LibertyStmt class LibertyVariable
{ {
public: public:
LibertyVariable(std::string var, LibertyVariable(std::string var,
float value, float value,
int line); int line);
bool isVariable() const override { return true; } int line() const { return line_; }
const std::string &variable() const { return var_; } const std::string &variable() const { return var_; }
float value() const { return value_; } float value() const { return value_; }
private: private:
std::string var_; std::string var_;
float value_; float value_;
int line_;
}; };
class LibertyGroupVisitor class LibertyGroupVisitor
@ -273,14 +268,13 @@ class LibertyGroupVisitor
public: public:
LibertyGroupVisitor() {} LibertyGroupVisitor() {}
virtual ~LibertyGroupVisitor() {} virtual ~LibertyGroupVisitor() {}
virtual void begin(LibertyGroup *group) = 0; virtual void begin(const LibertyGroup *group,
virtual void end(LibertyGroup *group) = 0; LibertyGroup *parent_group) = 0;
virtual void visitAttr(LibertyAttr *attr) = 0; virtual void end(const LibertyGroup *group,
LibertyGroup *parent_group) = 0;
virtual void visitAttr(const LibertySimpleAttr *attr) = 0;
virtual void visitAttr(const LibertyComplexAttr *attr) = 0;
virtual void visitVariable(LibertyVariable *variable) = 0; virtual void visitVariable(LibertyVariable *variable) = 0;
// Predicates to save parse structure after visits.
virtual bool save(LibertyGroup *group) = 0;
virtual bool save(LibertyAttr *attr) = 0;
virtual bool save(LibertyVariable *variable) = 0;
}; };
void void

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -25,7 +25,7 @@
#include "LibertyWriter.hh" #include "LibertyWriter.hh"
#include <cstdlib> #include <cstdlib>
#include <algorithm> #include <cmath>
#include "Units.hh" #include "Units.hh"
#include "FuncExpr.hh" #include "FuncExpr.hh"
@ -39,8 +39,6 @@
namespace sta { namespace sta {
using std::abs;
class LibertyWriter class LibertyWriter
{ {
public: public:
@ -271,7 +269,7 @@ LibertyWriter::writeBusDcls()
fprintf(stream_, " type (\"%s\") {\n", dcl->name().c_str()); fprintf(stream_, " type (\"%s\") {\n", dcl->name().c_str());
fprintf(stream_, " base_type : array;\n"); fprintf(stream_, " base_type : array;\n");
fprintf(stream_, " data_type : bit;\n"); fprintf(stream_, " data_type : bit;\n");
fprintf(stream_, " bit_width : %d;\n", abs(dcl->from() - dcl->to() + 1)); fprintf(stream_, " bit_width : %d;\n", std::abs(dcl->from() - dcl->to() + 1));
fprintf(stream_, " bit_from : %d;\n", dcl->from()); fprintf(stream_, " bit_from : %d;\n", dcl->from());
fprintf(stream_, " bit_to : %d;\n", dcl->to()); fprintf(stream_, " bit_to : %d;\n", dcl->to());
fprintf(stream_, " }\n"); fprintf(stream_, " }\n");

View File

@ -29,8 +29,6 @@
namespace sta { namespace sta {
using std::string;
GateLinearModel::GateLinearModel(LibertyCell *cell, GateLinearModel::GateLinearModel(LibertyCell *cell,
float intrinsic, float intrinsic,
float resistance) : float resistance) :
@ -53,7 +51,7 @@ GateLinearModel::gateDelay(const Pvt *,
drvr_slew = 0.0; drvr_slew = 0.0;
} }
string std::string
GateLinearModel::reportGateDelay(const Pvt *, GateLinearModel::reportGateDelay(const Pvt *,
float, float,
float load_cap, float load_cap,
@ -65,7 +63,7 @@ GateLinearModel::reportGateDelay(const Pvt *,
const Unit *time_unit = units->timeUnit(); const Unit *time_unit = units->timeUnit();
const Unit *res_unit = units->resistanceUnit(); const Unit *res_unit = units->resistanceUnit();
const Unit *cap_unit = units->capacitanceUnit(); const Unit *cap_unit = units->capacitanceUnit();
string result = "Delay = "; std::string result = "Delay = ";
result += time_unit->asString(intrinsic_, digits); result += time_unit->asString(intrinsic_, digits);
result += " + "; result += " + ";
result += res_unit->asString(resistance_, digits); result += res_unit->asString(resistance_, digits);
@ -105,7 +103,7 @@ CheckLinearModel::checkDelay(const Pvt *,
return intrinsic_; return intrinsic_;
} }
string std::string
CheckLinearModel::reportCheckDelay(const Pvt *, CheckLinearModel::reportCheckDelay(const Pvt *,
float, float,
const char *, const char *,
@ -117,7 +115,7 @@ CheckLinearModel::reportCheckDelay(const Pvt *,
const LibertyLibrary *library = cell_->libertyLibrary(); const LibertyLibrary *library = cell_->libertyLibrary();
const Units *units = library->units(); const Units *units = library->units();
const Unit *time_unit = units->timeUnit(); const Unit *time_unit = units->timeUnit();
string result = "Check = "; std::string result = "Check = ";
result += time_unit->asString(intrinsic_, digits); result += time_unit->asString(intrinsic_, digits);
return result; return result;
} }

View File

@ -35,25 +35,17 @@
namespace sta { namespace sta {
using std::string;
using std::min;
using std::max;
using std::abs;
using std::make_shared;
size_t size_t
findValueIndex(float value, findValueIndex(float value,
const FloatSeq *values); const FloatSeq *values);
static void static void
sigmaModelsMvOwner(TableModel *models[EarlyLate::index_count], sigmaModelsDelete(TableModelsEarlyLate &models);
std::array<std::unique_ptr<TableModel>, static std::string
EarlyLate::index_count> &out);
static string
reportPvt(const LibertyCell *cell, reportPvt(const LibertyCell *cell,
const Pvt *pvt, const Pvt *pvt,
int digits); int digits);
static void static void
appendSpaces(string &result, appendSpaces(std::string &result,
int count); int count);
TimingModel::TimingModel(LibertyCell *cell) : TimingModel::TimingModel(LibertyCell *cell) :
@ -63,40 +55,50 @@ TimingModel::TimingModel(LibertyCell *cell) :
GateTableModel::GateTableModel(LibertyCell *cell, GateTableModel::GateTableModel(LibertyCell *cell,
TableModel *delay_model, TableModel *delay_model,
TableModel *delay_sigma_models[EarlyLate::index_count], TableModelsEarlyLate delay_sigma_models,
TableModel *slew_model, TableModel *slew_model,
TableModel *slew_sigma_models[EarlyLate::index_count], TableModelsEarlyLate slew_sigma_models,
ReceiverModelPtr receiver_model, ReceiverModelPtr receiver_model,
OutputWaveforms *output_waveforms) : OutputWaveforms *output_waveforms) :
GateTimingModel(cell), GateTimingModel(cell),
delay_model_(delay_model), delay_model_(delay_model),
delay_sigma_models_(std::move(delay_sigma_models)),
slew_model_(slew_model), slew_model_(slew_model),
slew_sigma_models_(std::move(slew_sigma_models)),
receiver_model_(receiver_model), receiver_model_(receiver_model),
output_waveforms_(output_waveforms) output_waveforms_(output_waveforms)
{ {
sigmaModelsMvOwner(delay_sigma_models, delay_sigma_models_);
sigmaModelsMvOwner(slew_sigma_models, slew_sigma_models_);
} }
GateTableModel::~GateTableModel() = default; GateTableModel::GateTableModel(LibertyCell *cell,
TableModel *delay_model,
TableModel *slew_model) :
GateTimingModel(cell),
delay_model_(delay_model),
delay_sigma_models_{},
slew_model_(slew_model),
slew_sigma_models_{},
receiver_model_(nullptr),
output_waveforms_(nullptr)
{
}
GateTableModel::~GateTableModel()
{
sigmaModelsDelete(slew_sigma_models_);
sigmaModelsDelete(delay_sigma_models_);
}
static void static void
sigmaModelsMvOwner(TableModel *models[EarlyLate::index_count], sigmaModelsDelete(TableModelsEarlyLate &models)
std::array<std::unique_ptr<TableModel>,
EarlyLate::index_count> &out)
{ {
TableModel *early_model = models ? models[EarlyLate::earlyIndex()] : nullptr; TableModel *early_model = models[EarlyLate::earlyIndex()];
TableModel *late_model = models ? models[EarlyLate::lateIndex()] : nullptr; TableModel *late_model = models[EarlyLate::lateIndex()];
if (early_model) { if (early_model == late_model)
out[EarlyLate::earlyIndex()].reset(early_model); delete early_model;
if (late_model && late_model != early_model) { else {
out[EarlyLate::lateIndex()].reset(late_model); delete early_model;
} else if (late_model == early_model) { delete late_model;
out[EarlyLate::lateIndex()] =
std::make_unique<TableModel>(*out[EarlyLate::earlyIndex()]);
}
} else if (late_model) {
out[EarlyLate::lateIndex()].reset(late_model);
} }
} }
@ -122,19 +124,19 @@ GateTableModel::gateDelay(const Pvt *pvt,
float sigma_early = 0.0; float sigma_early = 0.0;
float sigma_late = 0.0; float sigma_late = 0.0;
if (pocv_enabled && delay_sigma_models_[EarlyLate::earlyIndex()]) if (pocv_enabled && delay_sigma_models_[EarlyLate::earlyIndex()])
sigma_early = findValue(pvt, delay_sigma_models_[EarlyLate::earlyIndex()].get(), sigma_early = findValue(pvt, delay_sigma_models_[EarlyLate::earlyIndex()],
in_slew, load_cap, 0.0); in_slew, load_cap, 0.0);
if (pocv_enabled && delay_sigma_models_[EarlyLate::lateIndex()]) if (pocv_enabled && delay_sigma_models_[EarlyLate::lateIndex()])
sigma_late = findValue(pvt, delay_sigma_models_[EarlyLate::lateIndex()].get(), sigma_late = findValue(pvt, delay_sigma_models_[EarlyLate::lateIndex()],
in_slew, load_cap, 0.0); in_slew, load_cap, 0.0);
gate_delay = makeDelay(delay, sigma_early, sigma_late); gate_delay = makeDelay(delay, sigma_early, sigma_late);
float slew = findValue(pvt, slew_model_.get(), in_slew, load_cap, 0.0); float slew = findValue(pvt, slew_model_.get(), in_slew, load_cap, 0.0);
if (pocv_enabled && slew_sigma_models_[EarlyLate::earlyIndex()]) if (pocv_enabled && slew_sigma_models_[EarlyLate::earlyIndex()])
sigma_early = findValue(pvt, slew_sigma_models_[EarlyLate::earlyIndex()].get(), sigma_early = findValue(pvt, slew_sigma_models_[EarlyLate::earlyIndex()],
in_slew, load_cap, 0.0); in_slew, load_cap, 0.0);
if (pocv_enabled && slew_sigma_models_[EarlyLate::lateIndex()]) if (pocv_enabled && slew_sigma_models_[EarlyLate::lateIndex()])
sigma_late = findValue(pvt, slew_sigma_models_[EarlyLate::lateIndex()].get(), sigma_late = findValue(pvt, slew_sigma_models_[EarlyLate::lateIndex()],
in_slew, load_cap, 0.0); in_slew, load_cap, 0.0);
// Clip negative slews to zero. // Clip negative slews to zero.
if (slew < 0.0) if (slew < 0.0)
@ -154,34 +156,34 @@ GateTableModel::gateDelay(const Pvt *pvt,
gateDelay(pvt, in_slew, load_cap, pocv_enabled, gate_delay, drvr_slew); gateDelay(pvt, in_slew, load_cap, pocv_enabled, gate_delay, drvr_slew);
} }
string std::string
GateTableModel::reportGateDelay(const Pvt *pvt, GateTableModel::reportGateDelay(const Pvt *pvt,
float in_slew, float in_slew,
float load_cap, float load_cap,
bool pocv_enabled, bool pocv_enabled,
int digits) const int digits) const
{ {
string result = reportPvt(cell_, pvt, digits); std::string result = reportPvt(cell_, pvt, digits);
result += reportTableLookup("Delay", pvt, delay_model_.get(), in_slew, result += reportTableLookup("Delay", pvt, delay_model_.get(), in_slew,
load_cap, 0.0, digits); load_cap, 0.0, digits);
if (pocv_enabled && delay_sigma_models_[EarlyLate::earlyIndex()]) if (pocv_enabled && delay_sigma_models_[EarlyLate::earlyIndex()])
result += reportTableLookup("Delay sigma(early)", pvt, result += reportTableLookup("Delay sigma(early)", pvt,
delay_sigma_models_[EarlyLate::earlyIndex()].get(), delay_sigma_models_[EarlyLate::earlyIndex()],
in_slew, load_cap, 0.0, digits); in_slew, load_cap, 0.0, digits);
if (pocv_enabled && delay_sigma_models_[EarlyLate::lateIndex()]) if (pocv_enabled && delay_sigma_models_[EarlyLate::lateIndex()])
result += reportTableLookup("Delay sigma(late)", pvt, result += reportTableLookup("Delay sigma(late)", pvt,
delay_sigma_models_[EarlyLate::lateIndex()].get(), delay_sigma_models_[EarlyLate::lateIndex()],
in_slew, load_cap, 0.0, digits); in_slew, load_cap, 0.0, digits);
result += '\n'; result += '\n';
result += reportTableLookup("Slew", pvt, slew_model_.get(), in_slew, result += reportTableLookup("Slew", pvt, slew_model_.get(), in_slew,
load_cap, 9.0, digits); load_cap, 9.0, digits);
if (pocv_enabled && slew_sigma_models_[EarlyLate::earlyIndex()]) if (pocv_enabled && slew_sigma_models_[EarlyLate::earlyIndex()])
result += reportTableLookup("Slew sigma(early)", pvt, result += reportTableLookup("Slew sigma(early)", pvt,
slew_sigma_models_[EarlyLate::earlyIndex()].get(), slew_sigma_models_[EarlyLate::earlyIndex()],
in_slew, load_cap, 0.0, digits); in_slew, load_cap, 0.0, digits);
if (pocv_enabled && slew_sigma_models_[EarlyLate::lateIndex()]) if (pocv_enabled && slew_sigma_models_[EarlyLate::lateIndex()])
result += reportTableLookup("Slew sigma(late)", pvt, result += reportTableLookup("Slew sigma(late)", pvt,
slew_sigma_models_[EarlyLate::lateIndex()].get(), slew_sigma_models_[EarlyLate::lateIndex()],
in_slew, load_cap, 0.0, digits); in_slew, load_cap, 0.0, digits);
float drvr_slew = findValue(pvt, slew_model_.get(), in_slew, load_cap, 0.0); float drvr_slew = findValue(pvt, slew_model_.get(), in_slew, load_cap, 0.0);
if (drvr_slew < 0.0) if (drvr_slew < 0.0)
@ -189,7 +191,7 @@ GateTableModel::reportGateDelay(const Pvt *pvt,
return result; return result;
} }
string std::string
GateTableModel::reportTableLookup(const char *result_name, GateTableModel::reportTableLookup(const char *result_name,
const Pvt *pvt, const Pvt *pvt,
const TableModel *model, const TableModel *model,
@ -285,13 +287,13 @@ GateTableModel::driveResistance(const Pvt *pvt) const
const TableModel * const TableModel *
GateTableModel::delaySigmaModel(const EarlyLate *el) const GateTableModel::delaySigmaModel(const EarlyLate *el) const
{ {
return delay_sigma_models_[el->index()].get(); return delay_sigma_models_[el->index()];
} }
const TableModel * const TableModel *
GateTableModel::slewSigmaModel(const EarlyLate *el) const GateTableModel::slewSigmaModel(const EarlyLate *el) const
{ {
return slew_sigma_models_[el->index()].get(); return slew_sigma_models_[el->index()];
} }
void void
@ -354,7 +356,7 @@ GateTableModel::axisValue(const TableAxis *axis,
} }
bool bool
GateTableModel::checkAxes(const TablePtr &table) GateTableModel::checkAxes(const TableModel *table)
{ {
const TableAxis *axis1 = table->axis1(); const TableAxis *axis1 = table->axis1();
const TableAxis *axis2 = table->axis2(); const TableAxis *axis2 = table->axis2();
@ -395,7 +397,7 @@ ReceiverModel::setCapacitanceModel(TableModel table_model,
} }
bool bool
ReceiverModel::checkAxes(TablePtr table) ReceiverModel::checkAxes(const TableModel *table)
{ {
const TableAxis *axis1 = table->axis1(); const TableAxis *axis1 = table->axis1();
const TableAxis *axis2 = table->axis2(); const TableAxis *axis2 = table->axis2();
@ -415,14 +417,25 @@ ReceiverModel::checkAxes(TablePtr table)
CheckTableModel::CheckTableModel(LibertyCell *cell, CheckTableModel::CheckTableModel(LibertyCell *cell,
TableModel *model, TableModel *model,
TableModel *sigma_models[EarlyLate::index_count]) : TableModelsEarlyLate sigma_models) :
CheckTimingModel(cell), CheckTimingModel(cell),
model_(model) model_(model),
sigma_models_(std::move(sigma_models))
{ {
sigmaModelsMvOwner(sigma_models, sigma_models_);
} }
CheckTableModel::~CheckTableModel() = default; CheckTableModel::CheckTableModel(LibertyCell *cell,
TableModel *model) :
CheckTimingModel(cell),
model_(model),
sigma_models_{}
{
}
CheckTableModel::~CheckTableModel()
{
sigmaModelsDelete(sigma_models_);
}
void void
CheckTableModel::setIsScaled(bool is_scaled) CheckTableModel::setIsScaled(bool is_scaled)
@ -434,7 +447,7 @@ CheckTableModel::setIsScaled(bool is_scaled)
const TableModel * const TableModel *
CheckTableModel::sigmaModel(const EarlyLate *el) const CheckTableModel::sigmaModel(const EarlyLate *el) const
{ {
return sigma_models_[el->index()].get(); return sigma_models_[el->index()];
} }
ArcDelay ArcDelay
@ -449,10 +462,10 @@ CheckTableModel::checkDelay(const Pvt *pvt,
float sigma_early = 0.0; float sigma_early = 0.0;
float sigma_late = 0.0; float sigma_late = 0.0;
if (pocv_enabled && sigma_models_[EarlyLate::earlyIndex()]) if (pocv_enabled && sigma_models_[EarlyLate::earlyIndex()])
sigma_early = findValue(pvt, sigma_models_[EarlyLate::earlyIndex()].get(), sigma_early = findValue(pvt, sigma_models_[EarlyLate::earlyIndex()],
from_slew, to_slew, related_out_cap); from_slew, to_slew, related_out_cap);
if (pocv_enabled && sigma_models_[EarlyLate::lateIndex()]) if (pocv_enabled && sigma_models_[EarlyLate::lateIndex()])
sigma_late = findValue(pvt, sigma_models_[EarlyLate::lateIndex()].get(), sigma_late = findValue(pvt, sigma_models_[EarlyLate::lateIndex()],
from_slew, to_slew, related_out_cap); from_slew, to_slew, related_out_cap);
return makeDelay(mean, sigma_early, sigma_late); return makeDelay(mean, sigma_early, sigma_late);
} }
@ -477,7 +490,7 @@ CheckTableModel::findValue(const Pvt *pvt,
return 0.0; return 0.0;
} }
string std::string
CheckTableModel::reportCheckDelay(const Pvt *pvt, CheckTableModel::reportCheckDelay(const Pvt *pvt,
float from_slew, float from_slew,
const char *from_slew_annotation, const char *from_slew_annotation,
@ -486,23 +499,23 @@ CheckTableModel::reportCheckDelay(const Pvt *pvt,
bool pocv_enabled, bool pocv_enabled,
int digits) const int digits) const
{ {
string result = reportTableDelay("Check", pvt, model_.get(), std::string result = reportTableDelay("Check", pvt, model_.get(),
from_slew, from_slew_annotation, to_slew, from_slew, from_slew_annotation, to_slew,
related_out_cap, digits); related_out_cap, digits);
if (pocv_enabled && sigma_models_[EarlyLate::earlyIndex()]) if (pocv_enabled && sigma_models_[EarlyLate::earlyIndex()])
result += reportTableDelay("Check sigma early", pvt, result += reportTableDelay("Check sigma early", pvt,
sigma_models_[EarlyLate::earlyIndex()].get(), sigma_models_[EarlyLate::earlyIndex()],
from_slew, from_slew_annotation, to_slew, from_slew, from_slew_annotation, to_slew,
related_out_cap, digits); related_out_cap, digits);
if (pocv_enabled && sigma_models_[EarlyLate::lateIndex()]) if (pocv_enabled && sigma_models_[EarlyLate::lateIndex()])
result += reportTableDelay("Check sigma late", pvt, result += reportTableDelay("Check sigma late", pvt,
sigma_models_[EarlyLate::lateIndex()].get(), sigma_models_[EarlyLate::lateIndex()],
from_slew, from_slew_annotation, to_slew, from_slew, from_slew_annotation, to_slew,
related_out_cap, digits); related_out_cap, digits);
return result; return result;
} }
string std::string
CheckTableModel::reportTableDelay(const char *result_name, CheckTableModel::reportTableDelay(const char *result_name,
const Pvt *pvt, const Pvt *pvt,
const TableModel *model, const TableModel *model,
@ -516,7 +529,7 @@ CheckTableModel::reportTableDelay(const char *result_name,
float axis_value1, axis_value2, axis_value3; float axis_value1, axis_value2, axis_value3;
findAxisValues(from_slew, to_slew, related_out_cap, findAxisValues(from_slew, to_slew, related_out_cap,
axis_value1, axis_value2, axis_value3); axis_value1, axis_value2, axis_value3);
string result = reportPvt(cell_, pvt, digits); std::string result = reportPvt(cell_, pvt, digits);
result += model_->reportValue(result_name, cell_, pvt, result += model_->reportValue(result_name, cell_, pvt,
axis_value1, from_slew_annotation, axis_value2, axis_value1, from_slew_annotation, axis_value2,
axis_value3, axis_value3,
@ -587,7 +600,7 @@ CheckTableModel::axisValue(const TableAxis *axis,
} }
bool bool
CheckTableModel::checkAxes(const TablePtr table) CheckTableModel::checkAxes(const TableModel *table)
{ {
const TableAxis *axis1 = table->axis1(); const TableAxis *axis1 = table->axis1();
const TableAxis *axis2 = table->axis2(); const TableAxis *axis2 = table->axis2();
@ -716,7 +729,7 @@ TableModel::scaleFactor(const LibertyCell *cell,
rf_index_, cell, pvt); rf_index_, cell, pvt);
} }
string std::string
TableModel::reportValue(const char *result_name, TableModel::reportValue(const char *result_name,
const LibertyCell *cell, const LibertyCell *cell,
const Pvt *pvt, const Pvt *pvt,
@ -727,7 +740,7 @@ TableModel::reportValue(const char *result_name,
const Unit *table_unit, const Unit *table_unit,
int digits) const int digits) const
{ {
string result = table_->reportValue("Table value", cell, pvt, value1, std::string result = table_->reportValue("Table value", cell, pvt, value1,
comment1, value2, value3, table_unit, digits); comment1, value2, value3, table_unit, digits);
result += reportPvtScaleFactor(cell, pvt, digits); result += reportPvtScaleFactor(cell, pvt, digits);
@ -739,7 +752,7 @@ TableModel::reportValue(const char *result_name,
return result; return result;
} }
static string static std::string
reportPvt(const LibertyCell *cell, reportPvt(const LibertyCell *cell,
const Pvt *pvt, const Pvt *pvt,
int digits) int digits)
@ -748,7 +761,7 @@ reportPvt(const LibertyCell *cell,
if (pvt == nullptr) if (pvt == nullptr)
pvt = library->defaultOperatingConditions(); pvt = library->defaultOperatingConditions();
if (pvt) { if (pvt) {
string result; std::string result;
stringPrint(result, "P = %.*f V = %.*f T = %.*f\n", stringPrint(result, "P = %.*f V = %.*f T = %.*f\n",
digits, pvt->process(), digits, pvt->process(),
digits, pvt->voltage(), digits, pvt->voltage(),
@ -758,7 +771,7 @@ reportPvt(const LibertyCell *cell,
return ""; return "";
} }
string std::string
TableModel::reportPvtScaleFactor(const LibertyCell *cell, TableModel::reportPvtScaleFactor(const LibertyCell *cell,
const Pvt *pvt, const Pvt *pvt,
int digits) const int digits) const
@ -766,7 +779,7 @@ TableModel::reportPvtScaleFactor(const LibertyCell *cell,
if (pvt == nullptr) if (pvt == nullptr)
pvt = cell->libertyLibrary()->defaultOperatingConditions(); pvt = cell->libertyLibrary()->defaultOperatingConditions();
if (pvt) { if (pvt) {
string result; std::string result;
stringPrint(result, "PVT scale factor = %.*f\n", stringPrint(result, "PVT scale factor = %.*f\n",
digits, digits,
scaleFactor(cell, pvt)); scaleFactor(cell, pvt));
@ -1147,7 +1160,7 @@ Table::reportValueOrder0(const char *result_name,
const Unit *table_unit, const Unit *table_unit,
int digits) const int digits) const
{ {
string result = result_name; std::string result = result_name;
result += " constant = "; result += " constant = ";
result += table_unit->asString(value_, digits); result += table_unit->asString(value_, digits);
if (comment1) if (comment1)
@ -1168,7 +1181,7 @@ Table::reportValueOrder1(const char *result_name,
{ {
const Units *units = cell->libertyLibrary()->units(); const Units *units = cell->libertyLibrary()->units();
const Unit *unit1 = axis1_->unit(units); const Unit *unit1 = axis1_->unit(units);
string result = "Table is indexed by\n "; std::string result = "Table is indexed by\n ";
result += axis1_->variableString(); result += axis1_->variableString();
result += " = "; result += " = ";
result += unit1->asString(value1, digits); result += unit1->asString(value1, digits);
@ -1209,7 +1222,7 @@ Table::reportValueOrder2(const char *result_name,
const Units *units = cell->libertyLibrary()->units(); const Units *units = cell->libertyLibrary()->units();
const Unit *unit1 = axis1_->unit(units); const Unit *unit1 = axis1_->unit(units);
const Unit *unit2 = axis2_->unit(units); const Unit *unit2 = axis2_->unit(units);
string result = "------- "; std::string result = "------- ";
result += axis1_->variableString(); result += axis1_->variableString();
result += " = "; result += " = ";
result += unit1->asString(value1, digits); result += unit1->asString(value1, digits);
@ -1270,7 +1283,7 @@ Table::reportValueOrder3(const char *result_name,
const Unit *unit1 = axis1_->unit(units); const Unit *unit1 = axis1_->unit(units);
const Unit *unit2 = axis2_->unit(units); const Unit *unit2 = axis2_->unit(units);
const Unit *unit3 = axis3_->unit(units); const Unit *unit3 = axis3_->unit(units);
string result = " --------- "; std::string result = " --------- ";
result += axis1_->variableString(); result += axis1_->variableString();
result += " = "; result += " = ";
result += unit1->asString(value1, digits); result += unit1->asString(value1, digits);
@ -1372,7 +1385,7 @@ Table::report(const Units *units,
const Unit *unit1 = axis1_->unit(units); const Unit *unit1 = axis1_->unit(units);
report->reportLine("%s", tableVariableString(axis1_->variable())); report->reportLine("%s", tableVariableString(axis1_->variable()));
report->reportLine("------------------------------"); report->reportLine("------------------------------");
string line; std::string line;
for (size_t index1 = 0; index1 < axis1_->size(); index1++) { for (size_t index1 = 0; index1 < axis1_->size(); index1++) {
line += unit1->asString(axis1_->axisValue(index1), digits); line += unit1->asString(axis1_->axisValue(index1), digits);
line += " "; line += " ";
@ -1391,7 +1404,7 @@ Table::report(const Units *units,
const Unit *unit2 = axis2_->unit(units); const Unit *unit2 = axis2_->unit(units);
report->reportLine("%s", tableVariableString(axis2_->variable())); report->reportLine("%s", tableVariableString(axis2_->variable()));
report->reportLine(" ------------------------------"); report->reportLine(" ------------------------------");
string line = " "; std::string line = " ";
for (size_t index2 = 0; index2 < axis2_->size(); index2++) { for (size_t index2 = 0; index2 < axis2_->size(); index2++) {
line += unit2->asString(axis2_->axisValue(index2), digits); line += unit2->asString(axis2_->axisValue(index2), digits);
line += " "; line += " ";
@ -1417,7 +1430,7 @@ Table::report(const Units *units,
unit1->asString(axis1_->axisValue(axis_index1), digits)); unit1->asString(axis1_->axisValue(axis_index1), digits));
report->reportLine("%s", tableVariableString(axis3_->variable())); report->reportLine("%s", tableVariableString(axis3_->variable()));
report->reportLine(" ------------------------------"); report->reportLine(" ------------------------------");
string line = " "; std::string line = " ";
for (size_t axis_index3 = 0; axis_index3 < axis3_->size(); axis_index3++) { for (size_t axis_index3 = 0; axis_index3 < axis3_->size(); axis_index3++) {
line += unit3->asString(axis3_->axisValue(axis_index3), digits); line += unit3->asString(axis3_->axisValue(axis_index3), digits);
line += " "; line += " ";
@ -1436,7 +1449,7 @@ Table::report(const Units *units,
} }
static void static void
appendSpaces(string &result, appendSpaces(std::string &result,
int count) int count)
{ {
while (count--) while (count--)
@ -1736,7 +1749,7 @@ OutputWaveforms::findVoltages(size_t wave_index,
// Make voltage -> current table. // Make voltage -> current table.
FloatSeq axis_volts = volts; FloatSeq axis_volts = volts;
TableAxisPtr volt_axis = TableAxisPtr volt_axis =
make_shared<TableAxis>(TableAxisVariable::input_voltage, std::move(axis_volts)); std::make_shared<TableAxis>(TableAxisVariable::input_voltage, std::move(axis_volts));
FloatSeq *currents1 = new FloatSeq(*currents->values()); FloatSeq *currents1 = new FloatSeq(*currents->values());
Table *volt_currents = new Table(currents1, volt_axis); Table *volt_currents = new Table(currents1, volt_axis);
voltage_currents_[wave_index] = volt_currents; voltage_currents_[wave_index] = volt_currents;
@ -1755,7 +1768,7 @@ OutputWaveforms::currentWaveform(float slew,
times->push_back(time); times->push_back(time);
currents->push_back(current); currents->push_back(current);
} }
TableAxisPtr time_axis = make_shared<TableAxis>(TableAxisVariable::time, std::move(*times)); TableAxisPtr time_axis = std::make_shared<TableAxis>(TableAxisVariable::time, std::move(*times));
delete times; delete times;
return Table(currents, time_axis); return Table(currents, time_axis);
} }
@ -1932,7 +1945,7 @@ OutputWaveforms::voltageWaveform(float slew,
times.push_back(time); times.push_back(time);
volts.push_back(volt); volts.push_back(volt);
} }
TableAxisPtr time_axis = make_shared<TableAxis>(TableAxisVariable::time, TableAxisPtr time_axis = std::make_shared<TableAxis>(TableAxisVariable::time,
std::move(times)); std::move(times));
return Table(std::move(volts), time_axis); return Table(std::move(volts), time_axis);
} }
@ -2057,7 +2070,7 @@ OutputWaveforms::voltageCurrentWaveform(float slew,
currents->push_back(current); currents->push_back(current);
} }
TableAxisPtr volt_axis = TableAxisPtr volt_axis =
make_shared<TableAxis>(TableAxisVariable::input_voltage, std::move(*volts)); std::make_shared<TableAxis>(TableAxisVariable::input_voltage, std::move(*volts));
delete volts; delete volts;
return Table(currents, volt_axis); return Table(currents, volt_axis);
} }
@ -2076,12 +2089,12 @@ OutputWaveforms::finalResistance()
const FloatSeq &voltages = voltage_currents->axis1()->values(); const FloatSeq &voltages = voltage_currents->axis1()->values();
FloatSeq *currents = voltage_currents->values(); FloatSeq *currents = voltage_currents->values();
size_t idx_last1 = voltages.size() - 2; size_t idx_last1 = voltages.size() - 2;
return (vdd_ - voltages[idx_last1]) / abs((*currents)[idx_last1]); return (vdd_ - voltages[idx_last1]) / std::abs((*currents)[idx_last1]);
} }
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
DriverWaveform::DriverWaveform(const string &name, DriverWaveform::DriverWaveform(const std::string &name,
TablePtr waveforms) : TablePtr waveforms) :
name_(name), name_(name),
waveforms_(waveforms) waveforms_(waveforms)
@ -2099,7 +2112,7 @@ DriverWaveform::waveform(float slew)
time_values->push_back(time); time_values->push_back(time);
volt_values->push_back(volt); volt_values->push_back(volt);
} }
TableAxisPtr time_axis = make_shared<TableAxis>(TableAxisVariable::time, TableAxisPtr time_axis = std::make_shared<TableAxis>(TableAxisVariable::time,
std::move(*time_values)); std::move(*time_values));
delete time_values; delete time_values;
Table waveform(volt_values, time_axis); Table waveform(volt_values, time_axis);

View File

@ -35,9 +35,6 @@
namespace sta { namespace sta {
using std::string;
using std::make_shared;
static bool static bool
timingArcsEquiv(const TimingArcSet *set1, timingArcsEquiv(const TimingArcSet *set1,
const TimingArcSet *set2); const TimingArcSet *set2);
@ -204,6 +201,15 @@ TimingArcSet::TimingArcSet(const TimingRole *role,
{ {
} }
std::string
TimingArcSet::to_string()
{
std::string str = from_->name();
str += " -> ";
str += to_->name();
return str;
}
TimingArcSet::~TimingArcSet() TimingArcSet::~TimingArcSet()
{ {
deleteContents(arcs_); deleteContents(arcs_);
@ -326,7 +332,7 @@ TimingArcSet::isRisingFallingEdge() const
if (from_rf1 == from_rf2) if (from_rf1 == from_rf2)
return from_rf1; return from_rf1;
} }
if (arcs_.size() == 1) if (arc_count == 1)
return arcs_[0]->fromEdge()->asRiseFall(); return arcs_[0]->fromEdge()->asRiseFall();
else else
return nullptr; return nullptr;
@ -501,7 +507,7 @@ TimingArcSet::wireArcIndex(const RiseFall *rf)
void void
TimingArcSet::init() TimingArcSet::init()
{ {
wire_timing_arc_attrs_ = make_shared<TimingArcAttrs>(TimingSense::positive_unate); wire_timing_arc_attrs_ = std::make_shared<TimingArcAttrs>(TimingSense::positive_unate);
wire_timing_arc_set_ = new TimingArcSet(TimingRole::wire(), wire_timing_arc_attrs_); wire_timing_arc_set_ = new TimingArcSet(TimingRole::wire(), wire_timing_arc_attrs_);
new TimingArc(wire_timing_arc_set_, Transition::rise(), new TimingArc(wire_timing_arc_set_, Transition::rise(),
Transition::rise(), nullptr); Transition::rise(), nullptr);
@ -539,18 +545,18 @@ TimingArc::~TimingArc()
delete scaled_models_; delete scaled_models_;
} }
string std::string
TimingArc::to_string() const TimingArc::to_string() const
{ {
if (set_->role()->isWire()) { if (set_->role()->isWire()) {
string str = "wire "; std::string str = "wire ";
str += from_rf_->to_string(); str += from_rf_->to_string();
str += " -> "; str += " -> ";
str += to_rf_->to_string(); str += to_rf_->to_string();
return str; return str;
} }
else { else {
string str = set_->from()->name(); std::string str = set_->from()->name();
str += " "; str += " ";
str += from_rf_->to_string(); str += from_rf_->to_string();
str += " -> "; str += " -> ";
@ -622,7 +628,7 @@ TimingArc::equiv(const TimingArc *arc1,
} }
void void
TimingArc::setIndex(unsigned index) TimingArc::setIndex(size_t index)
{ {
index_ = index; index_ = index;
} }

View File

@ -163,6 +163,12 @@ TimingRole::isLatchDtoQ() const
return this == &latch_d_q_; return this == &latch_d_q_;
} }
bool
TimingRole::isLatchEnToQ() const
{
return this == &latch_en_q_;
}
bool bool
TimingRole::isTimingCheckBetween() const TimingRole::isTimingCheckBetween() const
{ {

View File

@ -32,9 +32,6 @@
namespace sta { namespace sta {
using std::abs;
Unit::Unit(const char *suffix) : Unit::Unit(const char *suffix) :
scale_(1.0), scale_(1.0),
suffix_(suffix), suffix_(suffix),
@ -175,12 +172,12 @@ Unit::asString(float value,
int digits) const int digits) const
{ {
// Special case INF because it blows up otherwise. // Special case INF because it blows up otherwise.
if (abs(value) >= INF * .1) if (std::abs(value) >= INF * .1)
return (value > 0.0) ? "INF" : "-INF"; return (value > 0.0) ? "INF" : "-INF";
else { else {
float scaled_value = value / scale_; float scaled_value = value / scale_;
// prevent "-0.00" on slowaris // prevent "-0.00" on slowaris
if (abs(scaled_value) < 1E-6) if (std::abs(scaled_value) < 1E-6)
scaled_value = 0.0; scaled_value = 0.0;
return stringPrintTmp("%.*f", digits, scaled_value); return stringPrintTmp("%.*f", digits, scaled_value);
} }

View File

@ -24,6 +24,7 @@
#include "ConcreteLibrary.hh" #include "ConcreteLibrary.hh"
#include <cmath>
#include <cstdlib> #include <cstdlib>
#include <limits> #include <limits>
@ -35,13 +36,6 @@
namespace sta { namespace sta {
using std::string;
using std::map;
using std::min;
using std::max;
using std::abs;
using std::swap;
static constexpr char escape_ = '\\'; static constexpr char escape_ = '\\';
ConcreteLibrary::ConcreteLibrary(const char *name, ConcreteLibrary::ConcreteLibrary(const char *name,
@ -228,7 +222,7 @@ ConcreteCell::makeBusPortBit(ConcretePort *bus_port,
const char *bus_name, const char *bus_name,
int bit_index) int bit_index)
{ {
string bit_name; std::string bit_name;
stringPrint(bit_name, "%s%c%d%c", stringPrint(bit_name, "%s%c%d%c",
bus_name, bus_name,
library_->busBrktLeft(), library_->busBrktLeft(),
@ -272,14 +266,14 @@ ConcreteCell::setIsLeaf(bool is_leaf)
} }
void void
ConcreteCell::setAttribute(const string &key, ConcreteCell::setAttribute(const std::string &key,
const string &value) const std::string &value)
{ {
attribute_map_[key] = value; attribute_map_[key] = value;
} }
string std::string
ConcreteCell::getAttribute(const string &key) const ConcreteCell::getAttribute(const std::string &key) const
{ {
const auto &itr = attribute_map_.find(key); const auto &itr = attribute_map_.find(key);
if (itr != attribute_map_.end()) if (itr != attribute_map_.end())
@ -350,8 +344,8 @@ void
BusPort::addBusBit(ConcretePort *port, BusPort::addBusBit(ConcretePort *port,
int index) int index)
{ {
from_ = min(from_, index); from_ = std::min(from_, index);
to_ = max(to_, index); to_ = std::max(to_, index);
members_.push_back(port); members_.push_back(port);
} }
@ -362,7 +356,7 @@ ConcreteCell::groupBusPorts(const char bus_brkt_left,
{ {
const char bus_brkts_left[2]{bus_brkt_left, '\0'}; const char bus_brkts_left[2]{bus_brkt_left, '\0'};
const char bus_brkts_right[2]{bus_brkt_right, '\0'}; const char bus_brkts_right[2]{bus_brkt_right, '\0'};
map<string, BusPort> bus_map; std::map<std::string, BusPort> bus_map;
// Find ungrouped bus ports. // Find ungrouped bus ports.
// Remove bus bit ports from the ports_ vector during the scan by // Remove bus bit ports from the ports_ vector during the scan by
// keeping an index to the next insertion index and skipping over // keeping an index to the next insertion index and skipping over
@ -372,7 +366,7 @@ ConcreteCell::groupBusPorts(const char bus_brkt_left,
for (ConcretePort *port : ports) { for (ConcretePort *port : ports) {
const char *port_name = port->name(); const char *port_name = port->name();
bool is_bus; bool is_bus;
string bus_name; std::string bus_name;
int index; int index;
parseBusName(port_name, bus_brkts_left, bus_brkts_right, escape_, parseBusName(port_name, bus_brkts_left, bus_brkts_right, escape_,
is_bus, bus_name, index); is_bus, bus_name, index);
@ -402,7 +396,7 @@ ConcreteCell::groupBusPorts(const char bus_brkt_left,
(*members)[member_index] = bus_bit; (*members)[member_index] = bus_bit;
} }
if (msb_first) if (msb_first)
swap(from, to); std::swap(from, to);
ConcretePort *port = makeBusPort(bus_name.c_str(), from, to, members); ConcretePort *port = makeBusPort(bus_name.c_str(), from, to, members);
port->setDirection(bus_port.direction()); port->setDirection(bus_port.direction());
} }
@ -505,7 +499,7 @@ int
ConcretePort::size() const ConcretePort::size() const
{ {
if (is_bus_) if (is_bus_)
return abs(to_index_ - from_index_) + 1; return std::abs(to_index_ - from_index_) + 1;
else if (is_bundle_) else if (is_bundle_)
return static_cast<int>(member_ports_->size()); return static_cast<int>(member_ports_->size());
else else

View File

@ -35,8 +35,6 @@
namespace sta { namespace sta {
using std::string;
static void static void
makeChildNetwork(Instance *proto, makeChildNetwork(Instance *proto,
Instance *parent, Instance *parent,
@ -581,8 +579,8 @@ ConcreteNetwork::setIsLeaf(Cell *cell,
void void
ConcreteNetwork::setAttribute(Cell *cell, ConcreteNetwork::setAttribute(Cell *cell,
const string &key, const std::string &key,
const string &value) const std::string &value)
{ {
ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell); ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
ccell->setAttribute(key, value); ccell->setAttribute(key, value);
@ -628,9 +626,9 @@ ConcreteNetwork::filename(const Cell *cell)
return ccell->filename(); return ccell->filename();
} }
string std::string
ConcreteNetwork::getAttribute(const Cell *cell, ConcreteNetwork::getAttribute(const Cell *cell,
const string &key) const const std::string &key) const
{ {
const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell); const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
return ccell->getAttribute(key); return ccell->getAttribute(key);
@ -967,9 +965,9 @@ ConcreteNetwork::id(const Instance *instance) const
return inst->id(); return inst->id();
} }
string std::string
ConcreteNetwork::getAttribute(const Instance *inst, ConcreteNetwork::getAttribute(const Instance *inst,
const string &key) const const std::string &key) const
{ {
const ConcreteInstance *cinst = reinterpret_cast<const ConcreteInstance*>(inst); const ConcreteInstance *cinst = reinterpret_cast<const ConcreteInstance*>(inst);
return cinst->getAttribute(key); return cinst->getAttribute(key);
@ -1389,8 +1387,8 @@ ConcreteNetwork::connect(Instance *inst,
void void
ConcreteNetwork::setAttribute(Instance *inst, ConcreteNetwork::setAttribute(Instance *inst,
const string &key, const std::string &key,
const string &value) const std::string &value)
{ {
ConcreteInstance *cinst = reinterpret_cast<ConcreteInstance*>(inst); ConcreteInstance *cinst = reinterpret_cast<ConcreteInstance*>(inst);
cinst->setAttribute(key, value); cinst->setAttribute(key, value);
@ -1718,14 +1716,14 @@ ConcreteInstance::childIterator() const
} }
void void
ConcreteInstance::setAttribute(const string &key, ConcreteInstance::setAttribute(const std::string &key,
const string &value) const std::string &value)
{ {
attribute_map_[key] = value; attribute_map_[key] = value;
} }
string std::string
ConcreteInstance::getAttribute(const string &key) const ConcreteInstance::getAttribute(const std::string &key) const
{ {
const auto &itr = attribute_map_.find(key); const auto &itr = attribute_map_.find(key);
if (itr != attribute_map_.end()) if (itr != attribute_map_.end())

View File

@ -37,8 +37,6 @@
namespace sta { namespace sta {
using std::string;
Network::Network() : Network::Network() :
default_liberty_(nullptr), default_liberty_(nullptr),
divider_('/'), divider_('/'),
@ -76,7 +74,7 @@ Network::findPortsMatching(const Cell *cell,
{ {
PortSeq matches; PortSeq matches;
bool is_bus, is_range, subscript_wild; bool is_bus, is_range, subscript_wild;
string bus_name; std::string bus_name;
int from, to; int from, to;
parseBusName(pattern->pattern(), '[', ']', '\\', parseBusName(pattern->pattern(), '[', ']', '\\',
is_bus, is_range, bus_name, from, to, subscript_wild); is_bus, is_range, bus_name, from, to, subscript_wild);
@ -1043,12 +1041,12 @@ Network::findInstPinsHierMatching(const Instance *instance,
// Return value. // Return value.
PinSeq &matches) const PinSeq &matches) const
{ {
string inst_name = name(instance); std::string inst_name = name(instance);
InstancePinIterator *pin_iter = pinIterator(instance); InstancePinIterator *pin_iter = pinIterator(instance);
while (pin_iter->hasNext()) { while (pin_iter->hasNext()) {
const Pin *pin = pin_iter->next(); const Pin *pin = pin_iter->next();
const char *port_name = name(port(pin)); const char *port_name = name(port(pin));
string pin_name = inst_name + divider_ + port_name; std::string pin_name = inst_name + divider_ + port_name;
if (pattern->match(pin_name.c_str())) if (pattern->match(pin_name.c_str()))
matches.push_back(pin); matches.push_back(pin);
} }

View File

@ -32,8 +32,6 @@
namespace sta { namespace sta {
using std::string;
bool bool
isBusName(const char *name, isBusName(const char *name,
const char brkt_left, const char brkt_left,
@ -60,7 +58,7 @@ parseBusName(const char *name,
const char escape, const char escape,
// Return values. // Return values.
bool &is_bus, bool &is_bus,
string &bus_name, std::string &bus_name,
int &index) int &index)
{ {
const char brkts_left[2] = {brkt_left, '\0'}; const char brkts_left[2] = {brkt_left, '\0'};
@ -76,7 +74,7 @@ parseBusName(const char *name,
char escape, char escape,
// Return values. // Return values.
bool &is_bus, bool &is_bus,
string &bus_name, std::string &bus_name,
int &index) int &index)
{ {
is_bus = false; is_bus = false;
@ -110,7 +108,7 @@ parseBusName(const char *name,
// Return values. // Return values.
bool &is_bus, bool &is_bus,
bool &is_range, bool &is_range,
string &bus_name, std::string &bus_name,
int &from, int &from,
int &to, int &to,
bool &subscript_wild) bool &subscript_wild)
@ -129,7 +127,7 @@ parseBusName(const char *name,
// Return values. // Return values.
bool &is_bus, bool &is_bus,
bool &is_range, bool &is_range,
string &bus_name, std::string &bus_name,
int &from, int &from,
int &to, int &to,
bool &subscript_wild) bool &subscript_wild)
@ -173,13 +171,13 @@ parseBusName(const char *name,
} }
} }
string std::string
escapeChars(const char *token, escapeChars(const char *token,
const char ch1, const char ch1,
const char ch2, const char ch2,
const char escape) const char escape)
{ {
string escaped; std::string escaped;
for (const char *s = token; *s; s++) { for (const char *s = token; *s; s++) {
char ch = *s; char ch = *s;
if (ch == escape) { if (ch == escape) {

View File

@ -30,13 +30,10 @@
namespace sta { namespace sta {
using std::string; static std::string
using std::to_string;
static string
escapeDividers(const char *token, escapeDividers(const char *token,
const Network *network); const Network *network);
static string static std::string
escapeBrackets(const char *token, escapeBrackets(const char *token,
const Network *network); const Network *network);
@ -137,9 +134,9 @@ NetworkNameAdapter::id(const Cell *cell) const
return network_->id(cell); return network_->id(cell);
} }
string std::string
NetworkNameAdapter::getAttribute(const Cell *cell, NetworkNameAdapter::getAttribute(const Cell *cell,
const string &key) const const std::string &key) const
{ {
return network_->getAttribute(cell, key); return network_->getAttribute(cell, key);
} }
@ -355,9 +352,9 @@ NetworkNameAdapter::cell(const Instance *instance) const
return network_->cell(instance); return network_->cell(instance);
} }
string std::string
NetworkNameAdapter::getAttribute(const Instance *inst, NetworkNameAdapter::getAttribute(const Instance *inst,
const string &key) const const std::string &key) const
{ {
return network_->getAttribute(inst, key); return network_->getAttribute(inst, key);
} }
@ -675,16 +672,16 @@ SdcNetwork::findPort(const Cell *cell,
if (port == nullptr) { if (port == nullptr) {
// Look for matches after escaping brackets. // Look for matches after escaping brackets.
bool is_bus; bool is_bus;
string bus_name; std::string bus_name;
int index; int index;
parseBusName(name, '[', ']', pathEscape(), is_bus, bus_name, index); parseBusName(name, '[', ']', pathEscape(), is_bus, bus_name, index);
if (is_bus) { if (is_bus) {
string escaped1 = escapeBrackets(name, this); std::string escaped1 = escapeBrackets(name, this);
port = network_->findPort(cell, escaped1.c_str()); port = network_->findPort(cell, escaped1.c_str());
if (port == nullptr) { if (port == nullptr) {
// Try escaping base foo\[0\][1] // Try escaping base foo\[0\][1]
string escaped2; std::string escaped2;
string escaped_bus_name = escapeBrackets(bus_name.c_str(), this); std::string escaped_bus_name = escapeBrackets(bus_name.c_str(), this);
stringPrint(escaped2, "%s[%d]", stringPrint(escaped2, "%s[%d]",
escaped_bus_name.c_str(), escaped_bus_name.c_str(),
index); index);
@ -693,7 +690,7 @@ SdcNetwork::findPort(const Cell *cell,
} }
else { else {
// Try escaping brackets foo\[0\].bar // Try escaping brackets foo\[0\].bar
string escaped = escapeBrackets(name, this); std::string escaped = escapeBrackets(name, this);
port = network_->findPort(cell, escaped.c_str()); port = network_->findPort(cell, escaped.c_str());
} }
} }
@ -708,19 +705,19 @@ SdcNetwork::findPortsMatching(const Cell *cell,
if (matches.empty()) { if (matches.empty()) {
// Look for matches after escaping brackets. // Look for matches after escaping brackets.
bool is_bus; bool is_bus;
string bus_name; std::string bus_name;
int index; int index;
parseBusName(pattern->pattern(), '[', ']', pathEscape(), parseBusName(pattern->pattern(), '[', ']', pathEscape(),
is_bus, bus_name, index); is_bus, bus_name, index);
if (is_bus) { if (is_bus) {
string escaped1 = escapeBrackets(pattern->pattern(), this); std::string escaped1 = escapeBrackets(pattern->pattern(), this);
PatternMatch escaped_pattern1(escaped1.c_str(), pattern); PatternMatch escaped_pattern1(escaped1.c_str(), pattern);
matches = network_->findPortsMatching(cell, &escaped_pattern1); matches = network_->findPortsMatching(cell, &escaped_pattern1);
if (matches.empty()) { if (matches.empty()) {
// Try escaping base foo\[0\][1] // Try escaping base foo\[0\][1]
string escaped_name = escapeBrackets(bus_name.c_str(), this); std::string escaped_name = escapeBrackets(bus_name.c_str(), this);
escaped_name += '['; escaped_name += '[';
escaped_name += to_string(index); escaped_name += std::to_string(index);
escaped_name += ']'; escaped_name += ']';
PatternMatch escaped_pattern2(escaped_name.c_str(), pattern); PatternMatch escaped_pattern2(escaped_name.c_str(), pattern);
matches = network_->findPortsMatching(cell, &escaped_pattern2); matches = network_->findPortsMatching(cell, &escaped_pattern2);
@ -728,7 +725,7 @@ SdcNetwork::findPortsMatching(const Cell *cell,
} }
else { else {
// Try escaping brackets foo\[0\].bar // Try escaping brackets foo\[0\].bar
string escaped = escapeBrackets(pattern->pattern(), this); std::string escaped = escapeBrackets(pattern->pattern(), this);
PatternMatch escaped_pattern(escaped.c_str(), pattern); PatternMatch escaped_pattern(escaped.c_str(), pattern);
matches = network_->findPortsMatching(cell, &escaped_pattern); matches = network_->findPortsMatching(cell, &escaped_pattern);
} }
@ -796,7 +793,7 @@ SdcNetwork::findInstance(const char *path_name) const
parent = network_->topInstance(); parent = network_->topInstance();
Instance *child = findChild(parent, child_name); Instance *child = findChild(parent, child_name);
if (child == nullptr) { if (child == nullptr) {
string escaped_name = escapeDividers(child_name, this); std::string escaped_name = escapeDividers(child_name, this);
child = findChild(parent, escaped_name.c_str()); child = findChild(parent, escaped_name.c_str());
} }
return child; return child;
@ -808,10 +805,10 @@ SdcNetwork::findInstanceRelative(const Instance *inst,
{ {
Instance *inst1 = network_->findInstanceRelative(inst, path_name); Instance *inst1 = network_->findInstanceRelative(inst, path_name);
if (inst1 == nullptr) { if (inst1 == nullptr) {
string path_name1 = escapeBrackets(path_name, this); std::string path_name1 = escapeBrackets(path_name, this);
inst1 = network_->findInstanceRelative(inst, path_name1.c_str()); inst1 = network_->findInstanceRelative(inst, path_name1.c_str());
if (inst1 == nullptr) { if (inst1 == nullptr) {
string path_name2 = escapeDividers(path_name1.c_str(), network_); std::string path_name2 = escapeDividers(path_name1.c_str(), network_);
inst1 = network_->findInstanceRelative(inst, path_name2.c_str()); inst1 = network_->findInstanceRelative(inst, path_name2.c_str());
} }
} }
@ -848,7 +845,7 @@ SdcNetwork::findChild(const Instance *parent,
{ {
Instance *child = network_->findChild(parent, name); Instance *child = network_->findChild(parent, name);
if (child == nullptr) { if (child == nullptr) {
string escaped = escapeBrackets(name, this); std::string escaped = escapeBrackets(name, this);
child = network_->findChild(parent, escaped.c_str()); child = network_->findChild(parent, escaped.c_str());
} }
return child; return child;
@ -873,8 +870,8 @@ SdcNetwork::findNet(const Instance *instance,
{ {
Net *net = network_->findNet(instance, net_name); Net *net = network_->findNet(instance, net_name);
if (net == nullptr) { if (net == nullptr) {
string net_name1 = escapeBrackets(net_name, this); std::string net_name1 = escapeBrackets(net_name, this);
string net_name2 = escapeDividers(net_name1.c_str(), network_); std::string net_name2 = escapeDividers(net_name1.c_str(), network_);
net = network_->findNet(instance, net_name2.c_str()); net = network_->findNet(instance, net_name2.c_str());
} }
return net; return net;
@ -886,15 +883,15 @@ SdcNetwork::findNetRelative(const Instance *inst,
{ {
Net *net = network_->findNetRelative(inst, path_name); Net *net = network_->findNetRelative(inst, path_name);
if (net == nullptr) { if (net == nullptr) {
string path_name1 = escapeDividers(path_name, network_); std::string path_name1 = escapeDividers(path_name, network_);
net = network_->findNetRelative(inst, path_name1.c_str()); net = network_->findNetRelative(inst, path_name1.c_str());
if (net == nullptr) { if (net == nullptr) {
string path_name2 = escapeBrackets(path_name, network_); std::string path_name2 = escapeBrackets(path_name, network_);
net = network_->findNetRelative(inst, path_name2.c_str()); net = network_->findNetRelative(inst, path_name2.c_str());
if (net == nullptr) { if (net == nullptr) {
string path_name3 = escapeDividers(path_name2.c_str(), network_); std::string path_name3 = escapeDividers(path_name2.c_str(), network_);
net = network_->findNetRelative(inst, path_name3.c_str()); net = network_->findNetRelative(inst, path_name3.c_str());
} }
} }
@ -926,12 +923,12 @@ SdcNetwork::findInstNetsMatching(const Instance *instance,
network_->findInstNetsMatching(instance, pattern, matches); network_->findInstNetsMatching(instance, pattern, matches);
if (matches.empty()) { if (matches.empty()) {
// Look for matches after escaping path dividers. // Look for matches after escaping path dividers.
string escaped_pattern = escapeDividers(pattern->pattern(), this); std::string escaped_pattern = escapeDividers(pattern->pattern(), this);
const PatternMatch escaped_dividers(escaped_pattern.c_str(), pattern); const PatternMatch escaped_dividers(escaped_pattern.c_str(), pattern);
network_->findInstNetsMatching(instance, &escaped_dividers, matches); network_->findInstNetsMatching(instance, &escaped_dividers, matches);
if (matches.empty()) { if (matches.empty()) {
// Look for matches after escaping brackets. // Look for matches after escaping brackets.
string escaped_pattern2 = escapeBrackets(pattern->pattern(),this); std::string escaped_pattern2 = escapeBrackets(pattern->pattern(),this);
const PatternMatch escaped_brkts(escaped_pattern2.c_str(), pattern); const PatternMatch escaped_brkts(escaped_pattern2.c_str(), pattern);
network_->findInstNetsMatching(instance, &escaped_brkts, matches); network_->findInstNetsMatching(instance, &escaped_brkts, matches);
} }
@ -959,24 +956,24 @@ SdcNetwork::findPin(const Instance *instance,
if (pin == nullptr) { if (pin == nullptr) {
// Look for match after escaping brackets. // Look for match after escaping brackets.
bool is_bus; bool is_bus;
string bus_name; std::string bus_name;
int index; int index;
parseBusName(port_name, '[', ']', pathEscape(), parseBusName(port_name, '[', ']', pathEscape(),
is_bus, bus_name, index); is_bus, bus_name, index);
if (is_bus) { if (is_bus) {
string escaped1 = escapeBrackets(port_name, this); std::string escaped1 = escapeBrackets(port_name, this);
pin = network_->findPin(instance, escaped1.c_str()); pin = network_->findPin(instance, escaped1.c_str());
if (pin == nullptr) { if (pin == nullptr) {
// Try escaping base foo\[0\][1] // Try escaping base foo\[0\][1]
string escaped_bus_name = escapeBrackets(bus_name.c_str(), this); std::string escaped_bus_name = escapeBrackets(bus_name.c_str(), this);
string escaped2; std::string escaped2;
stringPrint(escaped2, "%s[%d]", escaped_bus_name.c_str(), index); stringPrint(escaped2, "%s[%d]", escaped_bus_name.c_str(), index);
pin = network_->findPin(instance, escaped2.c_str()); pin = network_->findPin(instance, escaped2.c_str());
} }
} }
else { else {
// Try escaping port brackets foo\[0\].bar // Try escaping port brackets foo\[0\].bar
string escaped = escapeBrackets(port_name, this); std::string escaped = escapeBrackets(port_name, this);
pin = network_->findPin(instance, escaped.c_str()); pin = network_->findPin(instance, escaped.c_str());
} }
} }
@ -1028,7 +1025,7 @@ SdcNetwork::visitPinTail(const Instance *instance,
if (network_->hasMembers(port)) { if (network_->hasMembers(port)) {
bool bus_matches = tail->match(port_name); bool bus_matches = tail->match(port_name);
if (!bus_matches) { if (!bus_matches) {
string escaped_name = escapeDividers(port_name, network_); std::string escaped_name = escapeDividers(port_name, network_);
bus_matches = tail->match(escaped_name); bus_matches = tail->match(escaped_name);
} }
PortMemberIterator *member_iter = network_->memberIterator(port); PortMemberIterator *member_iter = network_->memberIterator(port);
@ -1044,7 +1041,7 @@ SdcNetwork::visitPinTail(const Instance *instance,
const char *member_name = network_->name(member_port); const char *member_name = network_->name(member_port);
bool member_matches = tail->match(member_name); bool member_matches = tail->match(member_name);
if (!member_matches) { if (!member_matches) {
string escaped_name = escapeDividers(member_name, network_); std::string escaped_name = escapeDividers(member_name, network_);
member_matches = tail->match(escaped_name); member_matches = tail->match(escaped_name);
} }
if (member_matches) { if (member_matches) {
@ -1059,7 +1056,7 @@ SdcNetwork::visitPinTail(const Instance *instance,
else { else {
bool port_matches = tail->match(port_name); bool port_matches = tail->match(port_name);
if (!port_matches) { if (!port_matches) {
string escaped_name = escapeDividers(port_name, network_); std::string escaped_name = escapeDividers(port_name, network_);
port_matches = tail->match(escaped_name); port_matches = tail->match(escaped_name);
} }
if (port_matches) { if (port_matches) {
@ -1081,7 +1078,7 @@ SdcNetwork::makeInstance(LibertyCell *cell,
const char *name, const char *name,
Instance *parent) Instance *parent)
{ {
string escaped_name = escapeDividers(name, this); std::string escaped_name = escapeDividers(name, this);
return network_edit_->makeInstance(cell, escaped_name.c_str(), parent); return network_edit_->makeInstance(cell, escaped_name.c_str(), parent);
} }
@ -1089,7 +1086,7 @@ Net *
SdcNetwork::makeNet(const char *name, SdcNetwork::makeNet(const char *name,
Instance *parent) Instance *parent)
{ {
string escaped_name = escapeDividers(name, this); std::string escaped_name = escapeDividers(name, this);
return network_edit_->makeNet(escaped_name.c_str(), parent); return network_edit_->makeNet(escaped_name.c_str(), parent);
} }
@ -1188,7 +1185,7 @@ SdcNetwork::parsePath(const char *path,
else else
*p++ = ch; *p++ = ch;
if (p - inst_path + 1 > inst_path_length) if (p - inst_path + 1 > inst_path_length)
report_->critical(1500, "inst path string lenth estimate busted"); report_->critical(1500, "inst path std::string lenth estimate busted");
} }
*p = '\0'; *p = '\0';
stringDelete(inst_path); stringDelete(inst_path);
@ -1235,7 +1232,7 @@ SdcNetwork::visitMatches(const Instance *parent,
network_->findChildrenMatching(parent, &matcher, matches); network_->findChildrenMatching(parent, &matcher, matches);
if (has_brkts && matches.empty()) { if (has_brkts && matches.empty()) {
// Look for matches after escaping brackets. // Look for matches after escaping brackets.
string escaped_brkts = escapeBrackets(inst_path, this); std::string escaped_brkts = escapeBrackets(inst_path, this);
const PatternMatch escaped_pattern(escaped_brkts, pattern); const PatternMatch escaped_pattern(escaped_brkts, pattern);
network_->findChildrenMatching(parent, &escaped_pattern, matches); network_->findChildrenMatching(parent, &escaped_pattern, matches);
} }
@ -1257,7 +1254,7 @@ SdcNetwork::visitMatches(const Instance *parent,
*p++ = ch; *p++ = ch;
} }
if (p - inst_path + 1 > inst_path_length) if (p - inst_path + 1 > inst_path_length)
report_->critical(1501, "inst path string lenth estimate exceeded"); report_->critical(1501, "inst path std::string lenth estimate exceeded");
} }
*p = '\0'; *p = '\0';
if (!found_match) { if (!found_match) {
@ -1265,7 +1262,7 @@ SdcNetwork::visitMatches(const Instance *parent,
found_match |= visit_tail(parent, &tail_pattern); found_match |= visit_tail(parent, &tail_pattern);
if (!found_match && has_brkts) { if (!found_match && has_brkts) {
// Look for matches after escaping brackets. // Look for matches after escaping brackets.
string escaped_path = escapeBrackets(inst_path, this); std::string escaped_path = escapeBrackets(inst_path, this);
const PatternMatch escaped_tail(escaped_path, pattern); const PatternMatch escaped_tail(escaped_path, pattern);
found_match |= visit_tail(parent, &escaped_tail); found_match |= visit_tail(parent, &escaped_tail);
} }
@ -1276,7 +1273,7 @@ SdcNetwork::visitMatches(const Instance *parent,
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
static string static std::string
escapeDividers(const char *token, escapeDividers(const char *token,
const Network *network) const Network *network)
{ {
@ -1284,7 +1281,7 @@ escapeDividers(const char *token,
network->pathEscape()); network->pathEscape());
} }
static string static std::string
escapeBrackets(const char *token, escapeBrackets(const char *token,
const Network *network) const Network *network)
{ {

View File

@ -31,39 +31,37 @@
namespace sta { namespace sta {
using std::string;
constexpr char verilog_escape = '\\'; constexpr char verilog_escape = '\\';
static string static std::string
staToVerilog(const char *sta_name); staToVerilog(const char *sta_name);
static string static std::string
staToVerilog2(const char *sta_name); staToVerilog2(const char *sta_name);
static string static std::string
verilogToSta(const string *verilog_name); verilogToSta(const std::string *verilog_name);
string std::string
cellVerilogName(const char *sta_name) cellVerilogName(const char *sta_name)
{ {
return staToVerilog(sta_name); return staToVerilog(sta_name);
} }
string std::string
instanceVerilogName(const char *sta_name) instanceVerilogName(const char *sta_name)
{ {
return staToVerilog(sta_name); return staToVerilog(sta_name);
} }
string std::string
netVerilogName(const char *sta_name) netVerilogName(const char *sta_name)
{ {
bool is_bus; bool is_bus;
string bus_name; std::string bus_name;
int index; int index;
parseBusName(sta_name, '[', ']', verilog_escape, is_bus, bus_name, index); parseBusName(sta_name, '[', ']', verilog_escape, is_bus, bus_name, index);
if (is_bus) { if (is_bus) {
string bus_vname = staToVerilog(bus_name.c_str()); std::string bus_vname = staToVerilog(bus_name.c_str());
string vname; std::string vname;
stringPrint(vname, "%s[%d]", bus_vname.c_str(), index); stringPrint(vname, "%s[%d]", bus_vname.c_str(), index);
return vname; return vname;
} }
@ -71,19 +69,19 @@ netVerilogName(const char *sta_name)
return staToVerilog2(sta_name); return staToVerilog2(sta_name);
} }
string std::string
portVerilogName(const char *sta_name) portVerilogName(const char *sta_name)
{ {
return staToVerilog2(sta_name); return staToVerilog2(sta_name);
} }
static string static std::string
staToVerilog(const char *sta_name) staToVerilog(const char *sta_name)
{ {
// Leave room for leading escape and trailing space if the name // Leave room for leading escape and trailing space if the name
// needs to be escaped. // needs to be escaped.
// Assume the name has to be escaped and start copying while scanning. // Assume the name has to be escaped and start copying while scanning.
string escaped_name = "\\"; std::string escaped_name = "\\";
bool escaped = false; bool escaped = false;
for (const char *s = sta_name; *s ; s++) { for (const char *s = sta_name; *s ; s++) {
char ch = s[0]; char ch = s[0];
@ -107,17 +105,17 @@ staToVerilog(const char *sta_name)
return escaped_name; return escaped_name;
} }
else else
return string(sta_name); return std::string(sta_name);
} }
static string static std::string
staToVerilog2(const char *sta_name) staToVerilog2(const char *sta_name)
{ {
constexpr char bus_brkt_left = '['; constexpr char bus_brkt_left = '[';
constexpr char bus_brkt_right = ']'; constexpr char bus_brkt_right = ']';
// Leave room for leading escape and trailing space if the name // Leave room for leading escape and trailing space if the name
// needs to be escaped. // needs to be escaped.
string escaped_name = "\\"; std::string escaped_name = "\\";
// Assume the name has to be escaped and start copying while scanning. // Assume the name has to be escaped and start copying while scanning.
bool escaped = false; bool escaped = false;
for (const char *s = sta_name; *s ; s++) { for (const char *s = sta_name; *s ; s++) {
@ -144,37 +142,37 @@ staToVerilog2(const char *sta_name)
return escaped_name; return escaped_name;
} }
else else
return string(sta_name); return std::string(sta_name);
} }
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
string std::string
moduleVerilogToSta(const string *module_name) moduleVerilogToSta(const std::string *module_name)
{ {
return verilogToSta(module_name); return verilogToSta(module_name);
} }
string std::string
instanceVerilogToSta(const string *inst_name) instanceVerilogToSta(const std::string *inst_name)
{ {
return verilogToSta(inst_name); return verilogToSta(inst_name);
} }
string std::string
netVerilogToSta(const string *net_name) netVerilogToSta(const std::string *net_name)
{ {
return verilogToSta(net_name); return verilogToSta(net_name);
} }
string std::string
portVerilogToSta(const string *port_name) portVerilogToSta(const std::string *port_name)
{ {
return verilogToSta(port_name); return verilogToSta(port_name);
} }
static string static std::string
verilogToSta(const string *verilog_name) verilogToSta(const std::string *verilog_name)
{ {
if (verilog_name->front() == '\\') { if (verilog_name->front() == '\\') {
constexpr char divider = '/'; constexpr char divider = '/';
@ -184,7 +182,7 @@ verilogToSta(const string *verilog_name)
size_t verilog_name_length = verilog_name->size(); size_t verilog_name_length = verilog_name->size();
if (isspace(verilog_name->back())) if (isspace(verilog_name->back()))
verilog_name_length--; verilog_name_length--;
string sta_name; std::string sta_name;
// Ignore leading '\'. // Ignore leading '\'.
for (size_t i = 1; i < verilog_name_length; i++) { for (size_t i = 1; i < verilog_name_length; i++) {
char ch = verilog_name->at(i); char ch = verilog_name->at(i);
@ -199,7 +197,7 @@ verilogToSta(const string *verilog_name)
return sta_name; return sta_name;
} }
else else
return string(*verilog_name); return std::string(*verilog_name);
} }
} // namespace } // namespace

View File

@ -45,8 +45,6 @@
namespace sta { namespace sta {
using std::max;
ConcreteParasitic::~ConcreteParasitic() ConcreteParasitic::~ConcreteParasitic()
{ {
} }
@ -620,7 +618,7 @@ ConcreteParasiticNetwork::ensureParasiticNode(const Net *net,
node = new ConcreteParasiticNode(net, id, network->highestNetAbove(net1) != net_); node = new ConcreteParasiticNode(net, id, network->highestNetAbove(net1) != net_);
sub_nodes_[net_id] = node; sub_nodes_[net_id] = node;
if (net == net_) if (net == net_)
max_node_id_ = max((int) max_node_id_, id); max_node_id_ = std::max((int) max_node_id_, id);
} }
else else
node = id_node->second; node = id_node->second;

View File

@ -24,6 +24,7 @@
#include "ReduceParasitics.hh" #include "ReduceParasitics.hh"
#include <algorithm>
#include <map> #include <map>
#include <set> #include <set>
@ -38,8 +39,6 @@
namespace sta { namespace sta {
using std::max;
typedef std::map<ParasiticNode*, double> ParasiticNodeValueMap; typedef std::map<ParasiticNode*, double> ParasiticNodeValueMap;
typedef std::map<ParasiticResistor*, double> ResistorCurrentMap; typedef std::map<ParasiticResistor*, double> ResistorCurrentMap;
typedef std::set<ParasiticResistor*> ParasiticResistorSet; typedef std::set<ParasiticResistor*> ParasiticResistorSet;
@ -174,7 +173,7 @@ ReduceToPi::reducePiDfs(const Pin *drvr_pin,
+ pinCapacitance(node); + pinCapacitance(node);
y1 = dwn_cap; y1 = dwn_cap;
y2 = y3 = 0.0; y2 = y3 = 0.0;
max_resistance = max(max_resistance, src_resistance); max_resistance = std::max(max_resistance, src_resistance);
visit(node); visit(node);
ParasiticResistorSeq &resistors = resistor_map_[node]; ParasiticResistorSeq &resistors = resistor_map_[node];

View File

@ -43,8 +43,6 @@
namespace sta { namespace sta {
using std::string;
bool bool
readSpefFile(const std::string &filename, readSpefFile(const std::string &filename,
Instance *instance, Instance *instance,
@ -616,7 +614,7 @@ SpefTriple::value(int index) const
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
SpefScanner::SpefScanner(std::istream *stream, SpefScanner::SpefScanner(std::istream *stream,
const string &filename, const std::string &filename,
SpefReader *reader, SpefReader *reader,
Report *report) : Report *report) :
yyFlexLexer(stream), yyFlexLexer(stream),

View File

@ -72,13 +72,6 @@
namespace sta { namespace sta {
using std::abs;
using std::max;
using std::min;
using std::isnormal;
using std::vector;
using std::map;
static bool static bool
isPositiveUnate(const LibertyCell *cell, isPositiveUnate(const LibertyCell *cell,
const LibertyPort *from, const LibertyPort *from,
@ -292,7 +285,7 @@ Power::reportDesign(const Scene *scene,
PowerResult total, sequential, combinational, clock, macro, pad; PowerResult total, sequential, combinational, clock, macro, pad;
power(scene, total, sequential, combinational, clock, macro, pad); power(scene, total, sequential, combinational, clock, macro, pad);
ReportPower report_power(this); ReportPower report_power(this);
report_power.reportDesign(total, sequential, combinational, clock, macro, pad, digits); report_power.reportDesign(total, sequential, combinational, clock, macro, pad, digits);
} }
void void
@ -734,7 +727,7 @@ percentChange(float value,
return 1.0; return 1.0;
} }
else else
return abs(value - prev) / prev; return std::abs(value - prev) / prev;
} }
// Return true if the activity changed. // Return true if the activity changed.
@ -842,7 +835,7 @@ Power::evalBddDuty(DdNode *bdd,
else if (bdd == Cudd_ReadLogicZero(bdd_.cuddMgr())) else if (bdd == Cudd_ReadLogicZero(bdd_.cuddMgr()))
return 0.0; return 0.0;
else else
criticalError(1100, "unknown cudd constant"); criticalError(2400, "unknown cudd constant");
} }
else { else {
float duty0 = evalBddDuty(Cudd_E(bdd), inst); float duty0 = evalBddDuty(Cudd_E(bdd), inst);
@ -1837,7 +1830,7 @@ Power::clockMinPeriod(const Sdc *sdc)
if (!clks.empty()) { if (!clks.empty()) {
float min_period = INF; float min_period = INF;
for (const Clock *clk : clks) for (const Clock *clk : clks)
min_period = min(min_period, clk->period()); min_period = std::min(min_period, clk->period());
return min_period; return min_period;
} }
else else
@ -1963,7 +1956,7 @@ PwrActivity::check()
// Densities can get very small from multiplying probabilities // Densities can get very small from multiplying probabilities
// through deep chains of logic. Clip them to prevent floating // through deep chains of logic. Clip them to prevent floating
// point anomalies. // point anomalies.
if (abs(density_) < min_density) if (std::abs(density_) < min_density)
density_ = 0.0; density_ = 0.0;
} }

View File

@ -26,6 +26,7 @@
#include <algorithm> #include <algorithm>
#include <cinttypes> #include <cinttypes>
#include <string>
#include "Error.hh" #include "Error.hh"
#include "Debug.hh" #include "Debug.hh"
@ -42,9 +43,6 @@
namespace sta { namespace sta {
using std::string;
using std::min;
bool bool
readSaif(const char *filename, readSaif(const char *filename,
const char *scope, const char *scope,
@ -129,9 +127,9 @@ SaifReader::instancePush(const char *instance_name)
// Check for a match to the annotation scope. // Check for a match to the annotation scope.
saif_scope_.push_back(instance_name); saif_scope_.push_back(instance_name);
string saif_scope; std::string saif_scope;
bool first = true; bool first = true;
for (string &inst : saif_scope_) { for (std::string &inst : saif_scope_) {
if (!first) if (!first)
saif_scope += sdc_network_->pathDivider(); saif_scope += sdc_network_->pathDivider();
saif_scope += inst; saif_scope += inst;
@ -167,7 +165,7 @@ SaifReader::setNetDurations(const char *net_name,
if (in_scope_level_ > 0) { if (in_scope_level_ > 0) {
Instance *parent = path_.empty() ? sdc_network_->topInstance() : path_.back(); Instance *parent = path_.empty() ? sdc_network_->topInstance() : path_.back();
if (parent) { if (parent) {
string unescaped_name = unescaped(net_name); std::string unescaped_name = unescaped(net_name);
const Pin *pin = sdc_network_->findPin(parent, unescaped_name.c_str()); const Pin *pin = sdc_network_->findPin(parent, unescaped_name.c_str());
LibertyPort *liberty_port = pin ? sdc_network_->libertyPort(pin) : nullptr; LibertyPort *liberty_port = pin ? sdc_network_->libertyPort(pin) : nullptr;
if (pin if (pin
@ -194,10 +192,10 @@ SaifReader::setNetDurations(const char *net_name,
stringDelete(net_name); stringDelete(net_name);
} }
string std::string
SaifReader::unescaped(const char *token) SaifReader::unescaped(const char *token)
{ {
string unescaped; std::string unescaped;
for (const char *t = token; *t; t++) { for (const char *t = token; *t; t++) {
char ch = *t; char ch = *t;
if (ch != escape_) if (ch != escape_)
@ -211,7 +209,7 @@ SaifReader::unescaped(const char *token)
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
SaifScanner::SaifScanner(std::istream *stream, SaifScanner::SaifScanner(std::istream *stream,
const string &filename, const std::string &filename,
SaifReader *reader, SaifReader *reader,
Report *report) : Report *report) :
yyFlexLexer(stream), yyFlexLexer(stream),

View File

@ -35,10 +35,6 @@
namespace sta { namespace sta {
using std::vector;
using std::string;
using std::isspace;
// Very imprecise syntax definition // Very imprecise syntax definition
// https://en.wikipedia.org/wiki/Value_change_dump#Structure.2FSyntax // https://en.wikipedia.org/wiki/Value_change_dump#Structure.2FSyntax
// Much better syntax definition // Much better syntax definition
@ -125,7 +121,7 @@ VcdParse::VcdParse(Report *report,
void void
VcdParse::parseTimescale() VcdParse::parseTimescale()
{ {
vector<string> tokens = readStmtTokens(); std::vector<std::string> tokens = readStmtTokens();
if (tokens.size() == 1) { if (tokens.size() == 1) {
size_t last; size_t last;
double time_scale = std::stod(tokens[0], &last); double time_scale = std::stod(tokens[0], &last);
@ -140,7 +136,7 @@ VcdParse::parseTimescale()
} }
void void
VcdParse::setTimeUnit(const string &time_unit, VcdParse::setTimeUnit(const std::string &time_unit,
double time_scale) double time_scale)
{ {
double time_unit_scale = 1.0; double time_unit_scale = 1.0;
@ -177,19 +173,19 @@ static EnumNameMap<VcdVarType> vcd_var_type_map =
void void
VcdParse::parseVar() VcdParse::parseVar()
{ {
vector<string> tokens = readStmtTokens(); std::vector<std::string> tokens = readStmtTokens();
if (tokens.size() == 4 if (tokens.size() == 4
|| tokens.size() == 5) { || tokens.size() == 5) {
string type_name = tokens[0]; std::string type_name = tokens[0];
VcdVarType type = vcd_var_type_map.find(type_name, VcdVarType::unknown); VcdVarType type = vcd_var_type_map.find(type_name, VcdVarType::unknown);
if (type == VcdVarType::unknown) if (type == VcdVarType::unknown)
report_->fileWarn(1370, filename_, file_line_, report_->fileWarn(1370, filename_, file_line_,
"Unknown variable type %s.", "Unknown variable type %s.",
type_name.c_str()); type_name.c_str());
else { else {
size_t width = stoi(tokens[1]); size_t width = std::stoi(tokens[1]);
string &id = tokens[2]; std::string &id = tokens[2];
string name = tokens[3]; std::string name = tokens[3];
// iverilog separates bus base name from bit range. // iverilog separates bus base name from bit range.
if (tokens.size() == 5) { if (tokens.size() == 5) {
// Preserve space after esacaped name. // Preserve space after esacaped name.
@ -208,8 +204,8 @@ VcdParse::parseVar()
void void
VcdParse::parseScope() VcdParse::parseScope()
{ {
vector<string> tokens = readStmtTokens(); std::vector<std::string> tokens = readStmtTokens();
string &scope = tokens[1]; std::string &scope = tokens[1];
scope_.push_back(scope); scope_.push_back(scope);
} }
@ -223,11 +219,11 @@ VcdParse::parseUpscope()
void void
VcdParse::parseVarValues() VcdParse::parseVarValues()
{ {
string token = getToken(); std::string token = getToken();
while (!token.empty()) { while (!token.empty()) {
char char0 = toupper(token[0]); char char0 = toupper(token[0]);
if (char0 == '#' && token.size() > 1) { if (char0 == '#' && token.size() > 1) {
VcdTime time = stoll(token.substr(1)); VcdTime time = std::stoll(token.substr(1));
prev_time_ = time_; prev_time_ = time_;
time_ = time; time_ = time;
if (time_ > prev_time_) if (time_ > prev_time_)
@ -238,15 +234,15 @@ VcdParse::parseVarValues()
|| char0 == 'X' || char0 == 'X'
|| char0 == 'U' || char0 == 'U'
|| char0 == 'Z') { || char0 == 'Z') {
string id = token.substr(1); std::string id = token.substr(1);
if (!reader_->varIdValid(id)) if (!reader_->varIdValid(id))
report_->fileError(805, filename_, file_line_, report_->fileError(805, filename_, file_line_,
"unknown variable %s", id.c_str()); "unknown variable %s", id.c_str());
reader_->varAppendValue(id, time_, char0); reader_->varAppendValue(id, time_, char0);
} }
else if (char0 == 'B') { else if (char0 == 'B') {
string bus_value = token.substr(1); std::string bus_value = token.substr(1);
string id = getToken(); std::string id = getToken();
if (!reader_->varIdValid(id)) if (!reader_->varIdValid(id))
report_->fileError(807, filename_, file_line_, report_->fileError(807, filename_, file_line_,
"unknown variable %s", id.c_str()); "unknown variable %s", id.c_str());
@ -261,12 +257,12 @@ VcdParse::parseVarValues()
reader_->setTimeMax(time_); reader_->setTimeMax(time_);
} }
string std::string
VcdParse::readStmtString() VcdParse::readStmtString()
{ {
stmt_line_ = file_line_; stmt_line_ = file_line_;
string line; std::string line;
string token = getToken(); std::string token = getToken();
while (!token.empty() && token != "$end") { while (!token.empty() && token != "$end") {
if (!line.empty()) if (!line.empty())
line += " "; line += " ";
@ -276,12 +272,12 @@ VcdParse::readStmtString()
return line; return line;
} }
vector<string> std::vector<std::string>
VcdParse::readStmtTokens() VcdParse::readStmtTokens()
{ {
stmt_line_ = file_line_; stmt_line_ = file_line_;
vector<string> tokens; std::vector<std::string> tokens;
string token = getToken(); std::string token = getToken();
while (!token.empty() && token != "$end") { while (!token.empty() && token != "$end") {
tokens.push_back(token); tokens.push_back(token);
token = getToken(); token = getToken();
@ -289,18 +285,18 @@ VcdParse::readStmtTokens()
return tokens; return tokens;
} }
string std::string
VcdParse::getToken() VcdParse::getToken()
{ {
string token; std::string token;
int ch = gzgetc(stream_); int ch = gzgetc(stream_);
// skip whitespace // skip whitespace
while (ch != EOF && isspace(ch)) { while (ch != EOF && std::isspace(ch)) {
if (ch == '\n') if (ch == '\n')
file_line_++; file_line_++;
ch = gzgetc(stream_); ch = gzgetc(stream_);
} }
while (ch != EOF && !isspace(ch)) { while (ch != EOF && !std::isspace(ch)) {
token.push_back(ch); token.push_back(ch);
ch = gzgetc(stream_); ch = gzgetc(stream_);
} }

View File

@ -24,8 +24,10 @@
#include "VcdReader.hh" #include "VcdReader.hh"
#include <cmath>
#include <inttypes.h> #include <inttypes.h>
#include <unordered_map> #include <unordered_map>
#include <vector>
#include "VcdParse.hh" #include "VcdParse.hh"
#include "Debug.hh" #include "Debug.hh"
@ -41,13 +43,6 @@
namespace sta { namespace sta {
using std::string;
using std::abs;
using std::min;
using std::to_string;
using std::vector;
using std::unordered_map;
// Transition count and high time for duty cycle for a group of pins // Transition count and high time for duty cycle for a group of pins
// for one bit of vcd ID. // for one bit of vcd ID.
class VcdCount class VcdCount
@ -117,9 +112,9 @@ VcdCount::highTime(VcdTime time_max) const
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
// VcdCount[bit] // VcdCount[bit]
typedef vector<VcdCount> VcdCounts; using VcdCounts = std::vector<VcdCount>;
// ID -> VcdCount[bit] // ID -> VcdCount[bit]
typedef unordered_map<string, VcdCounts> VcdIdCountsMap; using VcdIdCountsMap = std::unordered_map<std::string, VcdCounts>;
class VcdCountReader : public VcdReader class VcdCountReader : public VcdReader
{ {
@ -134,31 +129,31 @@ public:
double timeScale() const { return time_scale_; } double timeScale() const { return time_scale_; }
// VcdParse callbacks. // VcdParse callbacks.
void setDate(const string &) override {} void setDate(const std::string &) override {}
void setComment(const string &) override {} void setComment(const std::string &) override {}
void setVersion(const string &) override {} void setVersion(const std::string &) override {}
void setTimeUnit(const string &time_unit, void setTimeUnit(const std::string &time_unit,
double time_unit_scale, double time_unit_scale,
double time_scale) override; double time_scale) override;
void setTimeMin(VcdTime time) override; void setTimeMin(VcdTime time) override;
void setTimeMax(VcdTime time) override; void setTimeMax(VcdTime time) override;
void varMinDeltaTime(VcdTime) override {} void varMinDeltaTime(VcdTime) override {}
bool varIdValid(const string &id) override; bool varIdValid(const std::string &id) override;
void makeVar(const VcdScope &scope, void makeVar(const VcdScope &scope,
const string &name, const std::string &name,
VcdVarType type, VcdVarType type,
size_t width, size_t width,
const string &id) override; const std::string &id) override;
void varAppendValue(const string &id, void varAppendValue(const std::string &id,
VcdTime time, VcdTime time,
char value) override; char value) override;
void varAppendBusValue(const string &id, void varAppendBusValue(const std::string &id,
VcdTime time, VcdTime time,
const string &bus_value) override; const std::string &bus_value) override;
private: private:
void addVarPin(const string &pin_name, void addVarPin(const std::string &pin_name,
const string &id, const std::string &id,
size_t width, size_t width,
size_t bit_idx); size_t bit_idx);
@ -189,7 +184,7 @@ VcdCountReader::VcdCountReader(const std::string &scope,
} }
void void
VcdCountReader::setTimeUnit(const string &, VcdCountReader::setTimeUnit(const std::string &,
double time_unit_scale, double time_unit_scale,
double time_scale) double time_scale)
{ {
@ -209,23 +204,23 @@ VcdCountReader::setTimeMax(VcdTime time)
} }
bool bool
VcdCountReader::varIdValid(const string &) VcdCountReader::varIdValid(const std::string &)
{ {
return true; return true;
} }
void void
VcdCountReader::makeVar(const VcdScope &scope, VcdCountReader::makeVar(const VcdScope &scope,
const string &name, const std::string &name,
VcdVarType type, VcdVarType type,
size_t width, size_t width,
const string &id) const std::string &id)
{ {
if (type == VcdVarType::wire if (type == VcdVarType::wire
|| type == VcdVarType::reg) { || type == VcdVarType::reg) {
string path_name; std::string path_name;
bool first = true; bool first = true;
for (const string &context : scope) { for (const std::string &context : scope) {
if (!first) if (!first)
path_name += '/'; path_name += '/';
path_name += context; path_name += context;
@ -238,25 +233,25 @@ VcdCountReader::makeVar(const VcdScope &scope,
path_name += '/'; path_name += '/';
path_name += name; path_name += name;
// Strip the scope from the name. // Strip the scope from the name.
string var_scoped = path_name.substr(scope_length + 1); std::string var_scoped = path_name.substr(scope_length + 1);
if (width == 1) { if (width == 1) {
string pin_name = netVerilogToSta(&var_scoped); std::string pin_name = netVerilogToSta(&var_scoped);
addVarPin(pin_name, id, width, 0); addVarPin(pin_name, id, width, 0);
} }
else { else {
bool is_bus, is_range, subscript_wild; bool is_bus, is_range, subscript_wild;
string bus_name; std::string bus_name;
int from, to; int from, to;
parseBusName(var_scoped.c_str(), '[', ']', '\\', parseBusName(var_scoped.c_str(), '[', ']', '\\',
is_bus, is_range, bus_name, from, to, subscript_wild); is_bus, is_range, bus_name, from, to, subscript_wild);
if (is_bus) { if (is_bus) {
string sta_bus_name = netVerilogToSta(&bus_name); std::string sta_bus_name = netVerilogToSta(&bus_name);
int bit_idx = 0; int bit_idx = 0;
if (to < from) { if (to < from) {
for (int bus_bit = to; bus_bit <= from; bus_bit++) { for (int bus_bit = to; bus_bit <= from; bus_bit++) {
string pin_name = sta_bus_name; std::string pin_name = sta_bus_name;
pin_name += '['; pin_name += '[';
pin_name += to_string(bus_bit); pin_name += std::to_string(bus_bit);
pin_name += ']'; pin_name += ']';
addVarPin(pin_name, id, width, bit_idx); addVarPin(pin_name, id, width, bit_idx);
bit_idx++; bit_idx++;
@ -264,9 +259,9 @@ VcdCountReader::makeVar(const VcdScope &scope,
} }
else { else {
for (int bus_bit = to; bus_bit >= from; bus_bit--) { for (int bus_bit = to; bus_bit >= from; bus_bit--) {
string pin_name = sta_bus_name; std::string pin_name = sta_bus_name;
pin_name += '['; pin_name += '[';
pin_name += to_string(bus_bit); pin_name += std::to_string(bus_bit);
pin_name += ']'; pin_name += ']';
addVarPin(pin_name, id, width, bit_idx); addVarPin(pin_name, id, width, bit_idx);
bit_idx++; bit_idx++;
@ -281,8 +276,8 @@ VcdCountReader::makeVar(const VcdScope &scope,
} }
void void
VcdCountReader::addVarPin(const string &pin_name, VcdCountReader::addVarPin(const std::string &pin_name,
const string &id, const std::string &id,
size_t width, size_t width,
size_t bit_idx) size_t bit_idx)
{ {
@ -303,7 +298,7 @@ VcdCountReader::addVarPin(const string &pin_name,
} }
void void
VcdCountReader::varAppendValue(const string &id, VcdCountReader::varAppendValue(const std::string &id,
VcdTime time, VcdTime time,
char value) char value)
{ {
@ -329,9 +324,9 @@ VcdCountReader::varAppendValue(const string &id,
} }
void void
VcdCountReader::varAppendBusValue(const string &id, VcdCountReader::varAppendBusValue(const std::string &id,
VcdTime time, VcdTime time,
const string &bus_value) const std::string &bus_value)
{ {
const auto &itr = vcd_count_map_.find(id); const auto &itr = vcd_count_map_.find(id);
if (itr != vcd_count_map_.end()) { if (itr != vcd_count_map_.end()) {
@ -476,7 +471,7 @@ ReadVcdActivities::checkClkPeriod(const Pin *pin,
sdc_network_->pathName(pin)); sdc_network_->pathName(pin));
else { else {
double clk_period = clk->period(); double clk_period = clk->period();
if (abs((clk_period - sim_period) / clk_period) > sim_clk_period_tolerance_) if (std::abs((clk_period - sim_period) / clk_period) > sim_clk_period_tolerance_)
// Warn if sim clock period differs from SDC by more than 10%. // Warn if sim clock period differs from SDC by more than 10%.
report_->warn(1452, "clock %s vcd period %s differs from SDC clock period %s", report_->warn(1452, "clock %s vcd period %s differs from SDC clock period %s",
clk->name(), clk->name(),

View File

@ -38,8 +38,6 @@
namespace sta { namespace sta {
using std::string;
static bool static bool
thrusIntersectPts(ExceptionThruSeq *thrus1, thrusIntersectPts(ExceptionThruSeq *thrus1,
ExceptionThruSeq *thrus2, ExceptionThruSeq *thrus2,
@ -326,7 +324,7 @@ ExceptionPath::intersectsPts(ExceptionPath *exception,
const char * const char *
ExceptionPath::fromThruToString(const Network *network) const ExceptionPath::fromThruToString(const Network *network) const
{ {
string str; std::string str;
if (min_max_ != MinMaxAll::all()) { if (min_max_ != MinMaxAll::all()) {
str += " -"; str += " -";
str += min_max_->to_string(); str += min_max_->to_string();
@ -1186,7 +1184,7 @@ ExceptionFromTo::deletePinBefore(const Pin *pin,
const char * const char *
ExceptionFromTo::asString(const Network *network) const ExceptionFromTo::asString(const Network *network) const
{ {
string str; std::string str;
str += " "; str += " ";
str += cmdKeyword(); str += cmdKeyword();
str += " {"; str += " {";
@ -1360,7 +1358,7 @@ ExceptionTo::clone(const Network *network)
const char * const char *
ExceptionTo::asString(const Network *network) const ExceptionTo::asString(const Network *network) const
{ {
string str; std::string str;
if (hasObjects()) if (hasObjects())
str += ExceptionFromTo::asString(network); str += ExceptionFromTo::asString(network);
@ -1679,7 +1677,7 @@ ExceptionThru::~ExceptionThru()
const char * const char *
ExceptionThru::asString(const Network *network) const ExceptionThru::asString(const Network *network) const
{ {
string str; std::string str;
bool first = true; bool first = true;
int obj_count = 0; int obj_count = 0;
if (pins_) { if (pins_) {

View File

@ -62,8 +62,6 @@
namespace sta { namespace sta {
using std::swap;
bool bool
ClockPairLess::operator()(const ClockPair &pair1, ClockPairLess::operator()(const ClockPair &pair1,
const ClockPair &pair2) const const ClockPair &pair2) const
@ -693,10 +691,10 @@ void
Sdc::swapDeratingFactors(Sdc *sdc1, Sdc::swapDeratingFactors(Sdc *sdc1,
Sdc *sdc2) Sdc *sdc2)
{ {
swap(sdc1->derating_factors_, sdc2->derating_factors_); std::swap(sdc1->derating_factors_, sdc2->derating_factors_);
swap(sdc1->net_derating_factors_, sdc2->net_derating_factors_); std::swap(sdc1->net_derating_factors_, sdc2->net_derating_factors_);
swap(sdc1->inst_derating_factors_, sdc2->inst_derating_factors_); std::swap(sdc1->inst_derating_factors_, sdc2->inst_derating_factors_);
swap(sdc1->cell_derating_factors_, sdc2->cell_derating_factors_); std::swap(sdc1->cell_derating_factors_, sdc2->cell_derating_factors_);
} }
void void
@ -1818,7 +1816,7 @@ void
Sdc::swapClockInsertions(Sdc *sdc1, Sdc::swapClockInsertions(Sdc *sdc1,
Sdc *sdc2) Sdc *sdc2)
{ {
swap(sdc1->clk_insertions_, sdc2->clk_insertions_); std::swap(sdc1->clk_insertions_, sdc2->clk_insertions_);
} }
void void
@ -2825,17 +2823,17 @@ void
Sdc::swapPortDelays(Sdc *sdc1, Sdc::swapPortDelays(Sdc *sdc1,
Sdc *sdc2) Sdc *sdc2)
{ {
swap(sdc1->input_delays_, sdc2->input_delays_); std::swap(sdc1->input_delays_, sdc2->input_delays_);
swap(sdc1->input_delay_pin_map_, sdc2->input_delay_pin_map_); std::swap(sdc1->input_delay_pin_map_, sdc2->input_delay_pin_map_);
swap(sdc1->input_delay_ref_pin_map_, sdc2->input_delay_ref_pin_map_); std::swap(sdc1->input_delay_ref_pin_map_, sdc2->input_delay_ref_pin_map_);
swap(sdc1->input_delay_leaf_pin_map_, sdc2->input_delay_leaf_pin_map_); std::swap(sdc1->input_delay_leaf_pin_map_, sdc2->input_delay_leaf_pin_map_);
swap(sdc1->input_delay_internal_pin_map_, sdc2->input_delay_internal_pin_map_); std::swap(sdc1->input_delay_internal_pin_map_, sdc2->input_delay_internal_pin_map_);
swap(sdc1->input_delay_index_, sdc2->input_delay_index_); std::swap(sdc1->input_delay_index_, sdc2->input_delay_index_);
swap(sdc1->output_delays_, sdc2->output_delays_); std::swap(sdc1->output_delays_, sdc2->output_delays_);
swap(sdc1->output_delay_pin_map_, sdc2->output_delay_pin_map_); std::swap(sdc1->output_delay_pin_map_, sdc2->output_delay_pin_map_);
swap(sdc1->output_delay_ref_pin_map_, sdc2->output_delay_ref_pin_map_); std::swap(sdc1->output_delay_ref_pin_map_, sdc2->output_delay_ref_pin_map_);
swap(sdc1->output_delay_leaf_pin_map_, sdc2->output_delay_leaf_pin_map_); std::swap(sdc1->output_delay_leaf_pin_map_, sdc2->output_delay_leaf_pin_map_);
} }
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
@ -3374,8 +3372,8 @@ void
Sdc::swapPortExtCaps(Sdc *sdc1, Sdc::swapPortExtCaps(Sdc *sdc1,
Sdc *sdc2) Sdc *sdc2)
{ {
swap(sdc1->port_ext_cap_map_, sdc2->port_ext_cap_map_); std::swap(sdc1->port_ext_cap_map_, sdc2->port_ext_cap_map_);
swap(sdc1->net_wire_cap_map_, sdc2->net_wire_cap_map_); std::swap(sdc1->net_wire_cap_map_, sdc2->net_wire_cap_map_);
} }
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////

View File

@ -29,6 +29,7 @@
#include <ctime> #include <ctime>
#include <vector> #include <vector>
#include <set> #include <set>
#include <string>
#include "ContainerHelpers.hh" #include "ContainerHelpers.hh"
#include "Zlib.hh" #include "Zlib.hh"
@ -63,8 +64,6 @@
namespace sta { namespace sta {
using std::string;
typedef std::set<ClockSense*> ClockSenseSet; typedef std::set<ClockSense*> ClockSenseSet;
typedef std::vector<ClockSense*> ClockSenseSeq; typedef std::vector<ClockSense*> ClockSenseSeq;
@ -1167,7 +1166,7 @@ WriteSdc::writeDisabledEdgeSense(Edge *edge) const
{ {
gzprintf(stream_, "set_disable_timing "); gzprintf(stream_, "set_disable_timing ");
const char *sense = to_string(edge->sense()); const char *sense = to_string(edge->sense());
string filter; std::string filter;
stringPrint(filter, "sense == %s", sense); stringPrint(filter, "sense == %s", sense);
writeGetTimingArcs(edge, filter.c_str()); writeGetTimingArcs(edge, filter.c_str());
gzprintf(stream_, "\n"); gzprintf(stream_, "\n");

View File

@ -26,6 +26,7 @@
#include <cstdarg> #include <cstdarg>
#include <cctype> #include <cctype>
#include <string>
#include "ContainerHelpers.hh" #include "ContainerHelpers.hh"
#include "Zlib.hh" #include "Zlib.hh"
@ -45,9 +46,6 @@
namespace sta { namespace sta {
using std::string;
using std::to_string;
class SdfTriple class SdfTriple
{ {
public: public:
@ -69,14 +67,14 @@ public:
const std::string *port, const std::string *port,
const std::string *cond); const std::string *cond);
~SdfPortSpec(); ~SdfPortSpec();
const string *port() const { return port_; } const std::string *port() const { return port_; }
const Transition *transition() const { return tr_; } const Transition *transition() const { return tr_; }
const string *cond() const { return cond_; } const std::string *cond() const { return cond_; }
private: private:
const Transition *tr_; const Transition *tr_;
const string *port_; const std::string *port_;
const string *cond_; // timing checks only const std::string *cond_; // timing checks only
}; };
bool bool
@ -162,7 +160,7 @@ SdfReader::setDivider(char divider)
void void
SdfReader::setTimescale(float multiplier, SdfReader::setTimescale(float multiplier,
const string *units) const std::string *units)
{ {
if (multiplier == 1.0 if (multiplier == 1.0
|| multiplier == 10.0 || multiplier == 10.0
@ -182,8 +180,8 @@ SdfReader::setTimescale(float multiplier,
} }
void void
SdfReader::interconnect(const string *from_pin_name, SdfReader::interconnect(const std::string *from_pin_name,
const string *to_pin_name, const std::string *to_pin_name,
SdfTripleSeq *triples) SdfTripleSeq *triples)
{ {
// Ignore non-incremental annotations in incremental only mode. // Ignore non-incremental annotations in incremental only mode.
@ -225,7 +223,7 @@ SdfReader::interconnect(const string *from_pin_name,
} }
void void
SdfReader::port(const string *to_pin_name, SdfReader::port(const std::string *to_pin_name,
SdfTripleSeq *triples) SdfTripleSeq *triples)
{ {
// Ignore non-incremental annotations in incremental only mode. // Ignore non-incremental annotations in incremental only mode.
@ -296,13 +294,13 @@ SdfReader::setEdgeDelays(Edge *edge,
} }
void void
SdfReader::setCell(const string *cell_name) SdfReader::setCell(const std::string *cell_name)
{ {
cell_name_ = cell_name; cell_name_ = cell_name;
} }
void void
SdfReader::setInstance(const string *instance_name) SdfReader::setInstance(const std::string *instance_name)
{ {
if (instance_name) { if (instance_name) {
if (*instance_name == "*") { if (*instance_name == "*") {
@ -344,13 +342,13 @@ SdfReader::cellFinish()
void void
SdfReader::iopath(SdfPortSpec *from_edge, SdfReader::iopath(SdfPortSpec *from_edge,
const string *to_port_name, const std::string *to_port_name,
SdfTripleSeq *triples, SdfTripleSeq *triples,
const string *cond, const std::string *cond,
bool condelse) bool condelse)
{ {
if (instance_) { if (instance_) {
const string *from_port_name = from_edge->port(); const std::string *from_port_name = from_edge->port();
Cell *cell = network_->cell(instance_); Cell *cell = network_->cell(instance_);
Port *from_port = findPort(cell, from_port_name); Port *from_port = findPort(cell, from_port_name);
Port *to_port = findPort(cell, to_port_name); Port *to_port = findPort(cell, to_port_name);
@ -420,7 +418,7 @@ SdfReader::iopath(SdfPortSpec *from_edge,
Port * Port *
SdfReader::findPort(const Cell *cell, SdfReader::findPort(const Cell *cell,
const string *port_name) const std::string *port_name)
{ {
Port *port = network_->findPort(cell, port_name->c_str()); Port *port = network_->findPort(cell, port_name->c_str());
if (port == nullptr) if (port == nullptr)
@ -437,8 +435,8 @@ SdfReader::timingCheck(const TimingRole *role,
SdfTriple *triple) SdfTriple *triple)
{ {
if (instance_) { if (instance_) {
const string *data_port_name = data_edge->port(); const std::string *data_port_name = data_edge->port();
const string *clk_port_name = clk_edge->port(); const std::string *clk_port_name = clk_edge->port();
Cell *cell = network_->cell(instance_); Cell *cell = network_->cell(instance_);
Port *data_port = findPort(cell, data_port_name); Port *data_port = findPort(cell, data_port_name);
Port *clk_port = findPort(cell, clk_port_name); Port *clk_port = findPort(cell, clk_port_name);
@ -515,8 +513,8 @@ SdfReader::annotateCheckEdges(Pin *data_pin,
bool match_generic) bool match_generic)
{ {
bool matched = false; bool matched = false;
const string *cond_start = data_edge->cond(); const std::string *cond_start = data_edge->cond();
const string *cond_end = clk_edge->cond(); const std::string *cond_end = clk_edge->cond();
// Timing check graph edges from clk to data. // Timing check graph edges from clk to data.
Vertex *to_vertex = graph_->pinLoadVertex(data_pin); Vertex *to_vertex = graph_->pinLoadVertex(data_pin);
// Fanin < fanout, so search for driver from load. // Fanin < fanout, so search for driver from load.
@ -557,7 +555,7 @@ SdfReader::timingCheckWidth(SdfPortSpec *edge,
// Ignore non-incremental annotations in incremental only mode. // Ignore non-incremental annotations in incremental only mode.
if (!(is_incremental_only_ && !in_incremental_) if (!(is_incremental_only_ && !in_incremental_)
&& instance_) { && instance_) {
const string *port_name = edge->port(); const std::string *port_name = edge->port();
Cell *cell = network_->cell(instance_); Cell *cell = network_->cell(instance_);
Port *port = findPort(cell, port_name); Port *port = findPort(cell, port_name);
if (port) { if (port) {
@ -604,8 +602,8 @@ SdfReader::timingCheckSetupHold1(SdfPortSpec *data_edge,
const TimingRole *setup_role, const TimingRole *setup_role,
const TimingRole *hold_role) const TimingRole *hold_role)
{ {
const string *data_port_name = data_edge->port(); const std::string *data_port_name = data_edge->port();
const string *clk_port_name = clk_edge->port(); const std::string *clk_port_name = clk_edge->port();
Cell *cell = network_->cell(instance_); Cell *cell = network_->cell(instance_);
Port *data_port = findPort(cell, data_port_name); Port *data_port = findPort(cell, data_port_name);
Port *clk_port = findPort(cell, clk_port_name); Port *clk_port = findPort(cell, clk_port_name);
@ -626,7 +624,7 @@ SdfReader::timingCheckPeriod(SdfPortSpec *edge,
// Ignore non-incremental annotations in incremental only mode. // Ignore non-incremental annotations in incremental only mode.
if (!(is_incremental_only_ && !in_incremental_) if (!(is_incremental_only_ && !in_incremental_)
&& instance_) { && instance_) {
const string *port_name = edge->port(); const std::string *port_name = edge->port();
Cell *cell = network_->cell(instance_); Cell *cell = network_->cell(instance_);
Port *port = findPort(cell, port_name); Port *port = findPort(cell, port_name);
if (port) { if (port) {
@ -683,7 +681,7 @@ SdfReader::device(SdfTripleSeq *triples)
} }
void void
SdfReader::device(const string *to_port_name, SdfReader::device(const std::string *to_port_name,
SdfTripleSeq *triples) SdfTripleSeq *triples)
{ {
// Ignore non-incremental annotations in incremental only mode. // Ignore non-incremental annotations in incremental only mode.
@ -799,7 +797,7 @@ SdfReader::setEdgeArcDelaysCondUse(Edge *edge,
} }
bool bool
SdfReader::condMatch(const string *sdf_cond, SdfReader::condMatch(const std::string *sdf_cond,
const std::string &lib_cond) const std::string &lib_cond)
{ {
// If the sdf is not conditional it matches any library condition. // If the sdf is not conditional it matches any library condition.
@ -828,24 +826,24 @@ SdfReader::condMatch(const string *sdf_cond,
SdfPortSpec * SdfPortSpec *
SdfReader::makePortSpec(const Transition *tr, SdfReader::makePortSpec(const Transition *tr,
const string *port, const std::string *port,
const string *cond) const std::string *cond)
{ {
return new SdfPortSpec(tr, port, cond); return new SdfPortSpec(tr, port, cond);
} }
SdfPortSpec * SdfPortSpec *
SdfReader::makeCondPortSpec(const string *cond_port) SdfReader::makeCondPortSpec(const std::string *cond_port)
{ {
// Search from end to find port name because condition may contain spaces. // Search from end to find port name because condition may contain spaces.
string cond_port1(*cond_port); std::string cond_port1(*cond_port);
trimRight(cond_port1); trimRight(cond_port1);
auto port_idx = cond_port1.find_last_of(" "); auto port_idx = cond_port1.find_last_of(" ");
if (port_idx != cond_port1.npos) { if (port_idx != cond_port1.npos) {
string *port1 = new string(cond_port1.substr(port_idx + 1)); std::string *port1 = new std::string(cond_port1.substr(port_idx + 1));
auto cond_end = cond_port1.find_last_not_of(" ", port_idx); auto cond_end = cond_port1.find_last_not_of(" ", port_idx);
if (cond_end != cond_port1.npos) { if (cond_end != cond_port1.npos) {
string *cond1 = new string(cond_port1.substr(0, cond_end + 1)); std::string *cond1 = new std::string(cond_port1.substr(0, cond_end + 1));
SdfPortSpec *port_spec = new SdfPortSpec(Transition::riseFall(), SdfPortSpec *port_spec = new SdfPortSpec(Transition::riseFall(),
port1, port1,
cond1); cond1);
@ -913,13 +911,13 @@ SdfReader::setInIncremental(bool incr)
in_incremental_ = incr; in_incremental_ = incr;
} }
string * std::string *
SdfReader::unescaped(const string *token) SdfReader::unescaped(const std::string *token)
{ {
char path_escape = network_->pathEscape(); char path_escape = network_->pathEscape();
char path_divider = network_->pathDivider(); char path_divider = network_->pathDivider();
size_t token_length = token->size(); size_t token_length = token->size();
string *unescaped = new string; std::string *unescaped = new std::string;
for (size_t i = 0; i < token_length; i++) { for (size_t i = 0; i < token_length; i++) {
char ch = (*token)[i]; char ch = (*token)[i];
if (ch == escape_) { if (ch == escape_) {
@ -955,11 +953,11 @@ SdfReader::unescaped(const string *token)
return unescaped; return unescaped;
} }
string * std::string *
SdfReader::makePath(const string *head, SdfReader::makePath(const std::string *head,
const string *tail) const std::string *tail)
{ {
string *path = new string(*head); std::string *path = new std::string(*head);
*path += network_->pathDivider(); *path += network_->pathDivider();
*path += *tail; *path += *tail;
delete head; delete head;
@ -967,13 +965,13 @@ SdfReader::makePath(const string *head,
return path; return path;
} }
string * std::string *
SdfReader::makeBusName(string *base_name, SdfReader::makeBusName(std::string *base_name,
int index) int index)
{ {
string *bus_name = unescaped(base_name); std::string *bus_name = unescaped(base_name);
*bus_name += '['; *bus_name += '[';
*bus_name += to_string(index); *bus_name += std::to_string(index);
*bus_name += ']'; *bus_name += ']';
delete base_name; delete base_name;
return bus_name; return bus_name;
@ -1006,10 +1004,10 @@ SdfReader::sdfError(int id,
} }
Pin * Pin *
SdfReader::findPin(const string *name) SdfReader::findPin(const std::string *name)
{ {
if (path_) { if (path_) {
string path_name(path_); std::string path_name(path_);
path_name += divider_; path_name += divider_;
path_name += *name; path_name += *name;
Pin *pin = network_->findPin(path_name.c_str()); Pin *pin = network_->findPin(path_name.c_str());
@ -1020,9 +1018,9 @@ SdfReader::findPin(const string *name)
} }
Instance * Instance *
SdfReader::findInstance(const string *name) SdfReader::findInstance(const std::string *name)
{ {
string inst_name; std::string inst_name;
if (path_) { if (path_) {
inst_name = path_; inst_name = path_;
inst_name += divider_; inst_name += divider_;
@ -1039,8 +1037,8 @@ SdfReader::findInstance(const string *name)
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
SdfPortSpec::SdfPortSpec(const Transition *tr, SdfPortSpec::SdfPortSpec(const Transition *tr,
const string *port, const std::string *port,
const string *cond) : const std::string *cond) :
tr_(tr), tr_(tr),
port_(port), port_(port),
cond_(cond) cond_(cond)
@ -1084,7 +1082,7 @@ SdfTriple::hasValue() const
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
SdfScanner::SdfScanner(std::istream *stream, SdfScanner::SdfScanner(std::istream *stream,
const string &filename, const std::string &filename,
SdfReader *reader, SdfReader *reader,
Report *report) : Report *report) :
yyFlexLexer(stream), yyFlexLexer(stream),

View File

@ -45,8 +45,6 @@
namespace sta { namespace sta {
using std::string;
class SdfWriter : public StaState class SdfWriter : public StaState
{ {
public: public:
@ -108,10 +106,10 @@ protected:
void writeSdfTriple(float min, void writeSdfTriple(float min,
float max); float max);
void writeSdfDelay(double delay); void writeSdfDelay(double delay);
string sdfPortName(const Pin *pin); std::string sdfPortName(const Pin *pin);
string sdfPathName(const Pin *pin); std::string sdfPathName(const Pin *pin);
string sdfPathName(const Instance *inst); std::string sdfPathName(const Instance *inst);
string sdfName(const Instance *inst); std::string sdfName(const Instance *inst);
private: private:
char sdf_divider_; char sdf_divider_;
@ -315,8 +313,8 @@ SdfWriter::writeInterconnectFromPin(Pin *drvr_pin)
Edge *edge = edge_iter.next(); Edge *edge = edge_iter.next();
if (edge->isWire()) { if (edge->isWire()) {
Pin *load_pin = edge->to(graph_)->pin(); Pin *load_pin = edge->to(graph_)->pin();
string drvr_pin_name = sdfPathName(drvr_pin); std::string drvr_pin_name = sdfPathName(drvr_pin);
string load_pin_name = sdfPathName(load_pin); std::string load_pin_name = sdfPathName(load_pin);
gzprintf(stream_, " (INTERCONNECT %s %s ", gzprintf(stream_, " (INTERCONNECT %s %s ",
drvr_pin_name.c_str(), drvr_pin_name.c_str(),
load_pin_name.c_str()); load_pin_name.c_str());
@ -347,7 +345,7 @@ SdfWriter::writeInstHeader(const Instance *inst)
{ {
gzprintf(stream_, " (CELL\n"); gzprintf(stream_, " (CELL\n");
gzprintf(stream_, " (CELLTYPE \"%s\")\n", network_->cellName(inst)); gzprintf(stream_, " (CELLTYPE \"%s\")\n", network_->cellName(inst));
string inst_name = sdfPathName(inst); std::string inst_name = sdfPathName(inst);
gzprintf(stream_, " (INSTANCE %s)\n", inst_name.c_str()); gzprintf(stream_, " (INSTANCE %s)\n", inst_name.c_str());
} }
@ -392,8 +390,8 @@ SdfWriter::writeIopaths(const Instance *inst,
gzprintf(stream_, " (COND %s\n", sdf_cond.c_str()); gzprintf(stream_, " (COND %s\n", sdf_cond.c_str());
gzprintf(stream_, " "); gzprintf(stream_, " ");
} }
string from_pin_name = sdfPortName(from_pin); std::string from_pin_name = sdfPortName(from_pin);
string to_pin_name = sdfPortName(to_pin); std::string to_pin_name = sdfPortName(to_pin);
gzprintf(stream_, " (IOPATH %s %s ", gzprintf(stream_, " (IOPATH %s %s ",
from_pin_name.c_str(), from_pin_name.c_str(),
to_pin_name.c_str()); to_pin_name.c_str());
@ -661,7 +659,7 @@ SdfWriter::writeCheck(Edge *edge,
if (!sdf_cond_start.empty()) if (!sdf_cond_start.empty())
gzprintf(stream_, "(COND %s ", sdf_cond_start.c_str()); gzprintf(stream_, "(COND %s ", sdf_cond_start.c_str());
string to_pin_name = sdfPortName(to_pin); std::string to_pin_name = sdfPortName(to_pin);
if (use_data_edge) { if (use_data_edge) {
gzprintf(stream_, "(%s %s)", gzprintf(stream_, "(%s %s)",
sdfEdge(arc->toEdge()), sdfEdge(arc->toEdge()),
@ -678,7 +676,7 @@ SdfWriter::writeCheck(Edge *edge,
if (!sdf_cond_end.empty()) if (!sdf_cond_end.empty())
gzprintf(stream_, "(COND %s ", sdf_cond_end.c_str()); gzprintf(stream_, "(COND %s ", sdf_cond_end.c_str());
string from_pin_name = sdfPortName(from_pin); std::string from_pin_name = sdfPortName(from_pin);
if (use_clk_edge) if (use_clk_edge)
gzprintf(stream_, "(%s %s)", gzprintf(stream_, "(%s %s)",
sdfEdge(arc->fromEdge()), sdfEdge(arc->fromEdge()),
@ -704,7 +702,7 @@ SdfWriter::writeWidthCheck(const Pin *pin,
float min_width, float min_width,
float max_width) float max_width)
{ {
string pin_name = sdfPortName(pin); std::string pin_name = sdfPortName(pin);
gzprintf(stream_, " (WIDTH (%s %s) ", gzprintf(stream_, " (WIDTH (%s %s) ",
sdfEdge(hi_low->asTransition()), sdfEdge(hi_low->asTransition()),
pin_name.c_str()); pin_name.c_str());
@ -716,7 +714,7 @@ void
SdfWriter::writePeriodCheck(const Pin *pin, SdfWriter::writePeriodCheck(const Pin *pin,
float min_period) float min_period)
{ {
string pin_name = sdfPortName(pin); std::string pin_name = sdfPortName(pin);
gzprintf(stream_, " (PERIOD %s ", pin_name.c_str()); gzprintf(stream_, " (PERIOD %s ", pin_name.c_str());
writeSdfTriple(min_period, min_period); writeSdfTriple(min_period, min_period);
gzprintf(stream_, ")\n"); gzprintf(stream_, ")\n");
@ -734,16 +732,16 @@ SdfWriter::sdfEdge(const Transition *tr)
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
string std::string
SdfWriter::sdfPathName(const Pin *pin) SdfWriter::sdfPathName(const Pin *pin)
{ {
Instance *inst = network_->instance(pin); Instance *inst = network_->instance(pin);
if (network_->isTopInstance(inst)) if (network_->isTopInstance(inst))
return sdfPortName(pin); return sdfPortName(pin);
else { else {
string inst_path = sdfPathName(inst); std::string inst_path = sdfPathName(inst);
string port_name = sdfPortName(pin); std::string port_name = sdfPortName(pin);
string sdf_name = inst_path; std::string sdf_name = inst_path;
sdf_name += sdf_divider_; sdf_name += sdf_divider_;
sdf_name += port_name; sdf_name += port_name;
return sdf_name; return sdf_name;
@ -751,15 +749,15 @@ SdfWriter::sdfPathName(const Pin *pin)
} }
// Based on Network::pathName. // Based on Network::pathName.
string std::string
SdfWriter::sdfPathName(const Instance *instance) SdfWriter::sdfPathName(const Instance *instance)
{ {
InstanceSeq inst_path; InstanceSeq inst_path;
network_->path(instance, inst_path); network_->path(instance, inst_path);
string path_name; std::string path_name;
while (!inst_path.empty()) { while (!inst_path.empty()) {
const Instance *inst = inst_path.back(); const Instance *inst = inst_path.back();
string inst_name = sdfName(inst); std::string inst_name = sdfName(inst);
path_name += inst_name; path_name += inst_name;
inst_path.pop_back(); inst_path.pop_back();
if (!inst_path.empty()) if (!inst_path.empty())
@ -769,11 +767,11 @@ SdfWriter::sdfPathName(const Instance *instance)
} }
// Escape for non-alpha numeric characters. // Escape for non-alpha numeric characters.
string std::string
SdfWriter::sdfName(const Instance *inst) SdfWriter::sdfName(const Instance *inst)
{ {
const char *name = network_->name(inst); const char *name = network_->name(inst);
string sdf_name; std::string sdf_name;
const char *p = name; const char *p = name;
while (*p) { while (*p) {
char ch = *p; char ch = *p;
@ -789,12 +787,12 @@ SdfWriter::sdfName(const Instance *inst)
return sdf_name; return sdf_name;
} }
string std::string
SdfWriter::sdfPortName(const Pin *pin) SdfWriter::sdfPortName(const Pin *pin)
{ {
const char *name = network_->portName(pin); const char *name = network_->portName(pin);
size_t name_length = strlen(name); size_t name_length = strlen(name);
string sdf_name; std::string sdf_name;
constexpr char bus_brkt_left = '['; constexpr char bus_brkt_left = '[';
constexpr char bus_brkt_right = ']'; constexpr char bus_brkt_right = ']';

View File

@ -46,8 +46,6 @@
namespace sta { namespace sta {
using std::string;
CheckTiming::CheckTiming(StaState *sta) : CheckTiming::CheckTiming(StaState *sta) :
StaState(sta), StaState(sta),
mode_(nullptr), mode_(nullptr),
@ -202,7 +200,7 @@ CheckTiming::checkLoops()
loop_count++; loop_count++;
} }
if (loop_count > 0) { if (loop_count > 0) {
string error_msg; std::string error_msg;
errorMsgSubst("Warning: There %is %d combinational loop%s in the design.", errorMsgSubst("Warning: There %is %d combinational loop%s in the design.",
loop_count, error_msg); loop_count, error_msg);
CheckError *error = new CheckError; CheckError *error = new CheckError;
@ -362,7 +360,7 @@ CheckTiming::pushPinErrors(const char *msg,
{ {
if (!pins.empty()) { if (!pins.empty()) {
CheckError *error = new CheckError; CheckError *error = new CheckError;
string error_msg; std::string error_msg;
errorMsgSubst(msg, pins.size(), error_msg); errorMsgSubst(msg, pins.size(), error_msg);
// Copy the error strings because the error deletes them when it // Copy the error strings because the error deletes them when it
// is deleted. // is deleted.
@ -384,7 +382,7 @@ CheckTiming::pushClkErrors(const char *msg,
{ {
if (!clks.empty()) { if (!clks.empty()) {
CheckError *error = new CheckError; CheckError *error = new CheckError;
string error_msg; std::string error_msg;
errorMsgSubst(msg, clks.size(), error_msg); errorMsgSubst(msg, clks.size(), error_msg);
// Copy the error strings because the error deletes them when it // Copy the error strings because the error deletes them when it
// is deleted. // is deleted.
@ -404,7 +402,7 @@ CheckTiming::pushClkErrors(const char *msg,
void void
CheckTiming::errorMsgSubst(const char *msg, CheckTiming::errorMsgSubst(const char *msg,
int obj_count, int obj_count,
string &error_msg) std::string &error_msg)
{ {
for (const char *s = msg; *s; s++) { for (const char *s = msg; *s; s++) {
char ch = *s; char ch = *s;

View File

@ -49,8 +49,6 @@
namespace sta { namespace sta {
using std::abs;
ClkSkews::ClkSkews(StaState *sta) : ClkSkews::ClkSkews(StaState *sta) :
StaState(sta), StaState(sta),
include_internal_latency_(true), include_internal_latency_(true),
@ -148,7 +146,7 @@ ClkSkews::findWorstClkSkew(const SceneSeq &scenes,
float worst_skew = 0.0; float worst_skew = 0.0;
for (const auto& [clk, clk_skews] : skews_) { for (const auto& [clk, clk_skews] : skews_) {
float skew = clk_skews[setup_hold->index()].skew(); float skew = clk_skews[setup_hold->index()].skew();
if (abs(skew) > abs(worst_skew)) if (std::abs(skew) > std::abs(worst_skew))
worst_skew = skew; worst_skew = skew;
} }
return worst_skew; return worst_skew;
@ -210,8 +208,8 @@ ClkSkews::findClkSkew(ConstClockSeq &clks,
ClkSkew &partial_skew_val = partial_skew[setup_hold_idx]; ClkSkew &partial_skew_val = partial_skew[setup_hold_idx];
float partial_skew1 = partial_skew_val.skew(); float partial_skew1 = partial_skew_val.skew();
float final_skew1 = final_skew.skew(); float final_skew1 = final_skew.skew();
if (abs(partial_skew1) > abs(final_skew1) if (std::abs(partial_skew1) > std::abs(final_skew1)
|| (fuzzyEqual(abs(partial_skew1), abs(final_skew1)) || (fuzzyEqual(std::abs(partial_skew1), std::abs(final_skew1))
// Break ties based on source/target path names. // Break ties based on source/target path names.
&& ClkSkew::srcTgtPathNameLess(partial_skew_val, final_skew, this))) && ClkSkew::srcTgtPathNameLess(partial_skew_val, final_skew, this)))
final_skew = partial_skew_val; final_skew = partial_skew_val;
@ -325,7 +323,7 @@ ClkSkews::findClkSkew(Vertex *src_vertex,
delayAsString(probe.crpr(this), this), delayAsString(probe.crpr(this), this),
time_unit->asString(probe.skew())); time_unit->asString(probe.skew()));
if (clk_skew.srcPath() == nullptr if (clk_skew.srcPath() == nullptr
|| abs(probe.skew()) > abs(clk_skew.skew())) || std::abs(probe.skew()) > std::abs(clk_skew.skew()))
clk_skew = probe; clk_skew = probe;
} }
} }

View File

@ -24,8 +24,8 @@
#include "Crpr.hh" #include "Crpr.hh"
#include <algorithm>
#include <cmath> // abs #include <cmath> // abs
#include <stdio.h>
#include "Debug.hh" #include "Debug.hh"
#include "Network.hh" #include "Network.hh"
@ -44,9 +44,6 @@
namespace sta { namespace sta {
using std::min;
using std::abs;
CheckCrpr::CheckCrpr(StaState *sta) : CheckCrpr::CheckCrpr(StaState *sta) :
StaState(sta) StaState(sta)
{ {
@ -60,11 +57,10 @@ CheckCrpr::maxCrpr(const ClkInfo *clk_info)
const Path *crpr_clk_path = clk_info->crprClkPath(this); const Path *crpr_clk_path = clk_info->crprClkPath(this);
if (crpr_clk_path) { if (crpr_clk_path) {
Arrival other_arrival = otherMinMaxArrival(crpr_clk_path); Arrival other_arrival = otherMinMaxArrival(crpr_clk_path);
float crpr_diff = abs(delayAsFloat(crpr_clk_path->arrival(), float crpr_diff = std::abs(delayAsFloat(crpr_clk_path->arrival(),
EarlyLate::late(), EarlyLate::late(), this)
this) - delayAsFloat(other_arrival, EarlyLate::early(),
- delayAsFloat(other_arrival, EarlyLate::early(), this));
this));
return crpr_diff; return crpr_diff;
} }
return 0.0F; return 0.0F;
@ -284,7 +280,7 @@ CheckCrpr::findCrpr1(const Path *src_clk_path,
Arrival tgt_arrival = tgt_clk_path->arrival(); Arrival tgt_arrival = tgt_clk_path->arrival();
float src_clk_time = src_clk_path->clkEdge(this)->time(); float src_clk_time = src_clk_path->clkEdge(this)->time();
float tgt_clk_time = tgt_clk_path->clkEdge(this)->time(); float tgt_clk_time = tgt_clk_path->clkEdge(this)->time();
float crpr_mean = abs(delayAsFloat(src_arrival) - src_clk_time float crpr_mean = std::abs(delayAsFloat(src_arrival) - src_clk_time
- (delayAsFloat(tgt_arrival) - tgt_clk_time)); - (delayAsFloat(tgt_arrival) - tgt_clk_time));
// Remove the sigma from both source and target path arrivals. // Remove the sigma from both source and target path arrivals.
float crpr_sigma2 = delaySigma2(src_arrival, src_el) float crpr_sigma2 = delaySigma2(src_arrival, src_el)
@ -300,7 +296,7 @@ CheckCrpr::findCrpr1(const Path *src_clk_path,
delayAsString(src_delta, this)); delayAsString(src_delta, this));
debugPrint(debug_, "crpr", 2, " tgt delta %s", debugPrint(debug_, "crpr", 2, " tgt delta %s",
delayAsString(tgt_delta, this)); delayAsString(tgt_delta, this));
float common_delay = min(src_delta, tgt_delta); float common_delay = std::min(src_delta, tgt_delta);
debugPrint(debug_, "crpr", 2, " %s delta %s", debugPrint(debug_, "crpr", 2, " %s delta %s",
network_->pathName(src_clk_path->pin(this)), network_->pathName(src_clk_path->pin(this)),
delayAsString(common_delay, this)); delayAsString(common_delay, this));
@ -312,7 +308,7 @@ float
CheckCrpr::crprArrivalDiff(const Path *path) CheckCrpr::crprArrivalDiff(const Path *path)
{ {
Arrival other_arrival = otherMinMaxArrival(path); Arrival other_arrival = otherMinMaxArrival(path);
float crpr_diff = abs(delayAsFloat(path->arrival()) float crpr_diff = std::abs(delayAsFloat(path->arrival())
- delayAsFloat(other_arrival)); - delayAsFloat(other_arrival));
return crpr_diff; return crpr_diff;
} }

View File

@ -24,6 +24,8 @@
#include "Genclks.hh" #include "Genclks.hh"
#include <cmath>
#include "ContainerHelpers.hh" #include "ContainerHelpers.hh"
#include "Stats.hh" #include "Stats.hh"
#include "Debug.hh" #include "Debug.hh"
@ -47,8 +49,6 @@
namespace sta { namespace sta {
using std::max;
class GenclkInfo class GenclkInfo
{ {
public: public:
@ -151,7 +151,7 @@ Genclks::clkPinMaxLevel(const Clock *clk) const
Level max_level = 0; Level max_level = 0;
for (const Pin *pin : clk->leafPins()) { for (const Pin *pin : clk->leafPins()) {
Vertex *vertex = srcPath(pin); Vertex *vertex = srcPath(pin);
max_level = max(max_level, vertex->level()); max_level = std::max(max_level, vertex->level());
} }
return max_level; return max_level;
} }

View File

@ -25,6 +25,7 @@
#include "Levelize.hh" #include "Levelize.hh"
#include <algorithm> #include <algorithm>
#include <cmath>
#include <deque> #include <deque>
#include <limits> #include <limits>
@ -44,8 +45,6 @@
namespace sta { namespace sta {
using std::max;
Levelize::Levelize(StaState *sta) : Levelize::Levelize(StaState *sta) :
StaState(sta), StaState(sta),
levelized_(false), levelized_(false),
@ -325,7 +324,7 @@ Levelize::findCycleBackEdges()
stack.emplace(vertex, new VertexOutEdgeIterator(vertex, graph_)); stack.emplace(vertex, new VertexOutEdgeIterator(vertex, graph_));
EdgeSet back_edges = findBackEdges(path, stack); EdgeSet back_edges = findBackEdges(path, stack);
for (Edge *back_edge : back_edges) for (Edge *back_edge : back_edges)
roots_.insert(back_edge->from(graph_)); roots_.insert(back_edge->to(graph_));
back_edge_count += back_edges.size(); back_edge_count += back_edges.size();
} }
} }
@ -501,16 +500,16 @@ Levelize::assignLevels(VertexSeq &topo_sorted)
Edge *edge = edge_iter.next(); Edge *edge = edge_iter.next();
Vertex *to_vertex = edge->to(graph_); Vertex *to_vertex = edge->to(graph_);
if (searchThru(edge)) if (searchThru(edge))
setLevel(to_vertex, max(to_vertex->level(), setLevel(to_vertex, std::max(to_vertex->level(),
vertex->level() + level_space_)); vertex->level() + level_space_));
} }
// Levelize bidirect driver as if it was a fanout of the bidirect load. // Levelize bidirect driver as if it was a fanout of the bidirect load.
const Pin *pin = vertex->pin(); const Pin *pin = vertex->pin();
if (graph_delay_calc_->bidirectDrvrSlewFromLoad(pin) if (graph_delay_calc_->bidirectDrvrSlewFromLoad(pin)
&& !vertex->isBidirectDriver()) { && !vertex->isBidirectDriver()) {
Vertex *to_vertex = graph_->pinDrvrVertex(pin); Vertex *to_vertex = graph_->pinDrvrVertex(pin);
setLevel(to_vertex, max(to_vertex->level(), setLevel(to_vertex, std::max(to_vertex->level(),
vertex->level() + level_space_)); vertex->level() + level_space_));
} }
} }
} }
@ -528,8 +527,16 @@ Levelize::ensureLatchLevels()
for (Edge *edge : latch_d_to_q_edges_) { for (Edge *edge : latch_d_to_q_edges_) {
Vertex *from = edge->from(graph_); Vertex *from = edge->from(graph_);
Vertex *to = edge->to(graph_); Vertex *to = edge->to(graph_);
if (from->level() == to->level()) if (from->level() == to->level()) {
setLevel(from, from->level() + level_space_); Level adjusted_level = from->level() + level_space_;
debugPrint(debug_, "levelize", 2, "latch %s %d (adjusted %d) -> %s %d",
from->to_string(this).c_str(),
from->level(),
adjusted_level,
to->to_string(this).c_str(),
to->level());
setLevel(from, adjusted_level);
}
} }
latch_d_to_q_edges_.clear(); latch_d_to_q_edges_.clear();
} }
@ -538,11 +545,11 @@ void
Levelize::setLevel(Vertex *vertex, Levelize::setLevel(Vertex *vertex,
Level level) Level level)
{ {
debugPrint(debug_, "levelize", 2, "set level %s %d", debugPrint(debug_, "levelize", 3, "set level %s %d",
vertex->to_string(this).c_str(), vertex->to_string(this).c_str(),
level); level);
vertex->setLevel(level); vertex->setLevel(level);
max_level_ = max(level, max_level_); max_level_ = std::max(level, max_level_);
if (level >= Graph::vertex_level_max) if (level >= Graph::vertex_level_max)
report_->critical(616, "maximum logic level exceeded"); report_->critical(616, "maximum logic level exceeded");
} }
@ -604,7 +611,7 @@ void
Levelize::relevelize() Levelize::relevelize()
{ {
for (Vertex *vertex : relevelize_from_) { for (Vertex *vertex : relevelize_from_) {
debugPrint(debug_, "levelize", 1, "relevelize from %s", debugPrint(debug_, "levelize", 2, "relevelize from %s",
vertex->to_string(this).c_str()); vertex->to_string(this).c_str());
if (isRoot(vertex)) if (isRoot(vertex))
roots_.insert(vertex); roots_.insert(vertex);
@ -643,9 +650,20 @@ Levelize::visit(Vertex *vertex,
visit(to_vertex, edge, level+level_space, level_space, visit(to_vertex, edge, level+level_space, level_space,
path_vertices, path); path_vertices, path);
} }
if (edge->role() == TimingRole::latchDtoQ())
const TimingRole *role = edge->role();
if (role->isLatchDtoQ())
latch_d_to_q_edges_.insert(edge); latch_d_to_q_edges_.insert(edge);
if (role->isLatchEnToQ()) {
VertexInEdgeIterator edge_iter2(to_vertex, graph_);
while (edge_iter2.hasNext()) {
Edge *edge2 = edge_iter2.next();
if (edge2->role()->isLatchDtoQ())
latch_d_to_q_edges_.insert(edge2);
}
}
} }
// Levelize bidirect driver as if it was a fanout of the bidirect load. // Levelize bidirect driver as if it was a fanout of the bidirect load.
if (graph_delay_calc_->bidirectDrvrSlewFromLoad(from_pin) if (graph_delay_calc_->bidirectDrvrSlewFromLoad(from_pin)
&& !vertex->isBidirectDriver()) { && !vertex->isBidirectDriver()) {
@ -677,9 +695,9 @@ Levelize::setLevelIncr(Vertex *vertex,
observer_->levelChangedBefore(vertex); observer_->levelChangedBefore(vertex);
vertex->setLevel(level); vertex->setLevel(level);
} }
max_level_ = max(level, max_level_); max_level_ = std::max(level, max_level_);
if (level >= Graph::vertex_level_max) if (level >= Graph::vertex_level_max)
criticalError(617, "maximum logic level exceeded"); criticalError(618, "maximum logic level exceeded");
} }
void void

View File

@ -26,6 +26,7 @@
#include "MakeTimingModelPvt.hh" #include "MakeTimingModelPvt.hh"
#include <algorithm> #include <algorithm>
#include <cmath>
#include <map> #include <map>
#include "Debug.hh" #include "Debug.hh"
@ -51,11 +52,6 @@
namespace sta { namespace sta {
using std::string;
using std::min;
using std::max;
using std::make_shared;
LibertyLibrary * LibertyLibrary *
makeTimingModel(const char *lib_name, makeTimingModel(const char *lib_name,
const char *cell_name, const char *cell_name,
@ -79,7 +75,7 @@ MakeTimingModel::MakeTimingModel(const char *lib_name,
scene_(scene), scene_(scene),
cell_(nullptr), cell_(nullptr),
min_max_(MinMax::max()), min_max_(MinMax::max()),
lib_builder_(new LibertyBuilder), lib_builder_(new LibertyBuilder(debug_, report_)),
tbl_template_index_(1), tbl_template_index_(1),
sdc_(scene->sdc()), sdc_(scene->sdc()),
sdc_backup_(nullptr), sdc_backup_(nullptr),
@ -305,7 +301,7 @@ MakeEndTimingArcs::visit(PathEnd *path_end)
margins.value(input_rf_, min_max, max_margin, max_exists); margins.value(input_rf_, min_max, max_margin, max_exists);
// Always max margin, even for min/hold checks. // Always max margin, even for min/hold checks.
margins.setValue(input_rf_, min_max, margins.setValue(input_rf_, min_max,
max_exists ? max(max_margin, delay1) : delay1); max_exists ? std::max(max_margin, delay1) : delay1);
} }
} }
@ -606,12 +602,12 @@ MakeTimingModel::makeScalarCheckModel(float value,
ScaleFactorType scale_factor_type, ScaleFactorType scale_factor_type,
const RiseFall *rf) const RiseFall *rf)
{ {
TablePtr table = make_shared<Table>(value); TablePtr table = std::make_shared<Table>(value);
TableTemplate *tbl_template = TableTemplate *tbl_template =
library_->findTableTemplate("scalar", TableTemplateType::delay); library_->findTableTemplate("scalar", TableTemplateType::delay);
TableModel *table_model = new TableModel(table, tbl_template, TableModel *table_model = new TableModel(table, tbl_template,
scale_factor_type, rf); scale_factor_type, rf);
CheckTableModel *check_model = new CheckTableModel(cell_, table_model, nullptr); CheckTableModel *check_model = new CheckTableModel(cell_, table_model);
return check_model; return check_model;
} }
@ -620,17 +616,15 @@ MakeTimingModel::makeGateModelScalar(Delay delay,
Slew slew, Slew slew,
const RiseFall *rf) const RiseFall *rf)
{ {
TablePtr delay_table = make_shared<Table>(delayAsFloat(delay)); TablePtr delay_table = std::make_shared<Table>(delayAsFloat(delay));
TablePtr slew_table = make_shared<Table>(delayAsFloat(slew)); TablePtr slew_table = std::make_shared<Table>(delayAsFloat(slew));
TableTemplate *tbl_template = TableTemplate *tbl_template =
library_->findTableTemplate("scalar", TableTemplateType::delay); library_->findTableTemplate("scalar", TableTemplateType::delay);
TableModel *delay_model = new TableModel(delay_table, tbl_template, TableModel *delay_model = new TableModel(delay_table, tbl_template,
ScaleFactorType::cell, rf); ScaleFactorType::cell, rf);
TableModel *slew_model = new TableModel(slew_table, tbl_template, TableModel *slew_model = new TableModel(slew_table, tbl_template,
ScaleFactorType::cell, rf); ScaleFactorType::cell, rf);
GateTableModel *gate_model = new GateTableModel(cell_, delay_model, nullptr, GateTableModel *gate_model = new GateTableModel(cell_, delay_model, slew_model);
slew_model, nullptr,
nullptr, nullptr);
return gate_model; return gate_model;
} }
@ -638,14 +632,12 @@ TimingModel *
MakeTimingModel::makeGateModelScalar(Delay delay, MakeTimingModel::makeGateModelScalar(Delay delay,
const RiseFall *rf) const RiseFall *rf)
{ {
TablePtr delay_table = make_shared<Table>(delayAsFloat(delay)); TablePtr delay_table = std::make_shared<Table>(delayAsFloat(delay));
TableTemplate *tbl_template = TableTemplate *tbl_template =
library_->findTableTemplate("scalar", TableTemplateType::delay); library_->findTableTemplate("scalar", TableTemplateType::delay);
TableModel *delay_model = new TableModel(delay_table, tbl_template, TableModel *delay_model = new TableModel(delay_table, tbl_template,
ScaleFactorType::cell, rf); ScaleFactorType::cell, rf);
GateTableModel *gate_model = new GateTableModel(cell_, delay_model, nullptr, GateTableModel *gate_model = new GateTableModel(cell_, delay_model, nullptr);
nullptr, nullptr,
nullptr, nullptr);
return gate_model; return gate_model;
} }
@ -712,8 +704,8 @@ MakeTimingModel::makeGateModelTable(const Pin *output_pin,
std::make_shared<TableAxis>(TableAxisVariable::total_output_net_capacitance, std::make_shared<TableAxis>(TableAxisVariable::total_output_net_capacitance,
std::move(axis_values)); std::move(axis_values));
TablePtr delay_table = make_shared<Table>(load_values, load_axis); TablePtr delay_table = std::make_shared<Table>(load_values, load_axis);
TablePtr slew_table = make_shared<Table>(slew_values, load_axis); TablePtr slew_table = std::make_shared<Table>(slew_values, load_axis);
TableTemplate *model_template = ensureTableTemplate(drvr_template, TableTemplate *model_template = ensureTableTemplate(drvr_template,
load_axis); load_axis);
@ -721,10 +713,8 @@ MakeTimingModel::makeGateModelTable(const Pin *output_pin,
ScaleFactorType::cell, rf); ScaleFactorType::cell, rf);
TableModel *slew_model = new TableModel(slew_table, model_template, TableModel *slew_model = new TableModel(slew_table, model_template,
ScaleFactorType::cell, rf); ScaleFactorType::cell, rf);
GateTableModel *gate_model = new GateTableModel(cell_, GateTableModel *gate_model = new GateTableModel(cell_, delay_model,
delay_model, nullptr, slew_model);
slew_model, nullptr,
nullptr, nullptr);
return gate_model; return gate_model;
} }
} }
@ -744,7 +734,7 @@ MakeTimingModel::ensureTableTemplate(const TableTemplate *drvr_template,
{ {
TableTemplate *model_template = findKey(template_map_, drvr_template); TableTemplate *model_template = findKey(template_map_, drvr_template);
if (model_template == nullptr) { if (model_template == nullptr) {
string template_name = "template_"; std::string template_name = "template_";
template_name += std::to_string(tbl_template_index_++); template_name += std::to_string(tbl_template_index_++);
model_template = library_->makeTableTemplate(template_name, model_template = library_->makeTableTemplate(template_name,

View File

@ -1178,7 +1178,7 @@ PathEndLatchCheck::sourceClkOffset(const StaState *sta) const
const TimingRole * const TimingRole *
PathEndLatchCheck::checkRole(const StaState *sta) const PathEndLatchCheck::checkRole(const StaState *sta) const
{ {
if (clk_path_->clkInfo(sta)->isPulseClk()) if (clk_path_ && clk_path_->clkInfo(sta)->isPulseClk())
// Pulse latches use register cycle accounting. // Pulse latches use register cycle accounting.
return TimingRole::setup(); return TimingRole::setup();
else else

View File

@ -24,6 +24,9 @@
#include "Property.hh" #include "Property.hh"
#include <algorithm>
#include <string>
#include "StringUtil.hh" #include "StringUtil.hh"
#include "MinMax.hh" #include "MinMax.hh"
#include "Transition.hh" #include "Transition.hh"
@ -43,22 +46,19 @@
namespace sta { namespace sta {
using std::string;
using std::max;
class PropertyUnknown : public Exception class PropertyUnknown : public Exception
{ {
public: public:
PropertyUnknown(const char *type, PropertyUnknown(const char *type,
const char *property); const char *property);
PropertyUnknown(const char *type, PropertyUnknown(const char *type,
const string property); const std::string property);
virtual ~PropertyUnknown() {} virtual ~PropertyUnknown() {}
virtual const char *what() const noexcept; virtual const char *what() const noexcept;
private: private:
const char *type_; const char *type_;
const string property_; const std::string property_;
}; };
PropertyUnknown::PropertyUnknown(const char *type, PropertyUnknown::PropertyUnknown(const char *type,
@ -70,7 +70,7 @@ PropertyUnknown::PropertyUnknown(const char *type,
} }
PropertyUnknown::PropertyUnknown(const char *type, PropertyUnknown::PropertyUnknown(const char *type,
const string property) : const std::string property) :
Exception(), Exception(),
type_(type), type_(type),
property_(property) property_(property)
@ -556,7 +556,7 @@ PropertyValue::operator=(PropertyValue &&value) noexcept
return *this; return *this;
} }
string std::string
PropertyValue::to_string(const Network *network) const PropertyValue::to_string(const Network *network) const
{ {
switch (type_) { switch (type_) {
@ -683,9 +683,9 @@ Properties::getProperty(const Cell *cell,
return PropertyValue(network->name(cell)); return PropertyValue(network->name(cell));
else if (property == "full_name") { else if (property == "full_name") {
Library *lib = network->library(cell); Library *lib = network->library(cell);
string lib_name = network->name(lib); std::string lib_name = network->name(lib);
string cell_name = network->name(cell); std::string cell_name = network->name(cell);
string full_name = lib_name + network->pathDivider() + cell_name; std::string full_name = lib_name + network->pathDivider() + cell_name;
return PropertyValue(full_name); return PropertyValue(full_name);
} }
else if (property == "library") else if (property == "library")
@ -714,9 +714,9 @@ Properties::getProperty(const LibertyCell *cell,
else if (property == "full_name") { else if (property == "full_name") {
Network *network = sta_->cmdNetwork(); Network *network = sta_->cmdNetwork();
LibertyLibrary *lib = cell->libertyLibrary(); LibertyLibrary *lib = cell->libertyLibrary();
string lib_name = lib->name(); std::string lib_name = lib->name();
string cell_name = cell->name(); std::string cell_name = cell->name();
string full_name = lib_name + network->pathDivider() + cell_name; std::string full_name = lib_name + network->pathDivider() + cell_name;
return PropertyValue(full_name); return PropertyValue(full_name);
} }
else if (property == "filename") else if (property == "filename")
@ -1099,7 +1099,7 @@ Properties::getProperty(Edge *edge,
const std::string &property) const std::string &property)
{ {
if (property == "full_name") { if (property == "full_name") {
string full_name = edge->to_string(sta_); std::string full_name = edge->to_string(sta_);
return PropertyValue(full_name); return PropertyValue(full_name);
} }
if (property == "delay_min_fall") if (property == "delay_min_fall")
@ -1159,7 +1159,7 @@ Properties::getProperty(TimingArcSet *arc_set,
const char *from = arc_set->from()->name(); const char *from = arc_set->from()->name();
const char *to = arc_set->to()->name(); const char *to = arc_set->to()->name();
const char *cell_name = arc_set->libertyCell()->name(); const char *cell_name = arc_set->libertyCell()->name();
string name; std::string name;
stringPrint(name, "%s %s -> %s", cell_name, from, to); stringPrint(name, "%s %s -> %s", cell_name, from, to);
return PropertyValue(name); return PropertyValue(name);
} }

View File

@ -23,6 +23,7 @@
// This notice may not be removed or altered from any source distribution. // This notice may not be removed or altered from any source distribution.
#include <algorithm> // reverse #include <algorithm> // reverse
#include <string>
#include "ReportPath.hh" #include "ReportPath.hh"
@ -63,8 +64,6 @@
namespace sta { namespace sta {
using std::string;
static void static void
hierPinsAbove(const Net *net, hierPinsAbove(const Net *net,
const Network *network, const Network *network,
@ -373,7 +372,7 @@ ReportPath::reportPathEndHeader() const
void void
ReportPath::reportPathEndFooter() const ReportPath::reportPathEndFooter() const
{ {
string header; std::string header;
switch (format_) { switch (format_) {
case ReportPathFormat::full: case ReportPathFormat::full:
case ReportPathFormat::full_clock: case ReportPathFormat::full_clock:
@ -474,7 +473,7 @@ ReportPath::reportFull(const PathEndCheck *end) const
reportSlack(end); reportSlack(end);
} }
string std::string
ReportPath::checkRoleString(const PathEnd *end) const ReportPath::checkRoleString(const PathEnd *end) const
{ {
return stdstrPrint("library %s time", return stdstrPrint("library %s time",
@ -486,7 +485,7 @@ ReportPath::reportEndpoint(const PathEndCheck *end) const
{ {
Instance *inst = network_->instance(end->vertex(this)->pin()); Instance *inst = network_->instance(end->vertex(this)->pin());
const char *inst_name = cmd_network_->pathName(inst); const char *inst_name = cmd_network_->pathName(inst);
string clk_name = tgtClkName(end); std::string clk_name = tgtClkName(end);
const char *rise_fall = asRisingFalling(end->targetClkEndTrans(this)); const char *rise_fall = asRisingFalling(end->targetClkEndTrans(this));
const TimingRole *check_role = end->checkRole(this); const TimingRole *check_role = end->checkRole(this);
const TimingRole *check_generic_role = check_role->genericRole(); const TimingRole *check_generic_role = check_role->genericRole();
@ -593,7 +592,7 @@ ReportPath::reportEndpoint(const PathEndLatchCheck *end) const
{ {
Instance *inst = network_->instance(end->vertex(this)->pin()); Instance *inst = network_->instance(end->vertex(this)->pin());
const char *inst_name = cmd_network_->pathName(inst); const char *inst_name = cmd_network_->pathName(inst);
string clk_name = tgtClkName(end); std::string clk_name = tgtClkName(end);
const char *reg_desc = latchDesc(end); const char *reg_desc = latchDesc(end);
auto reason = stdstrPrint("%s clocked by %s", reg_desc, clk_name.c_str()); auto reason = stdstrPrint("%s clocked by %s", reg_desc, clk_name.c_str());
reportEndpoint(inst_name, reason); reportEndpoint(inst_name, reason);
@ -625,7 +624,7 @@ ReportPath::reportBorrowing(const PathEndLatchCheck *end,
if (borrow_limit_exists) if (borrow_limit_exists)
reportLineTotal("user max time borrow", max_borrow, early_late); reportLineTotal("user max time borrow", max_borrow, early_late);
else { else {
string tgt_clk_name = tgtClkName(end); std::string tgt_clk_name = tgtClkName(end);
Arrival tgt_clk_width = end->targetClkWidth(this); Arrival tgt_clk_width = end->targetClkWidth(this);
const Path *tgt_clk_path = end->targetClkPath(); const Path *tgt_clk_path = end->targetClkPath();
if (tgt_clk_path->clkInfo(search_)->isPropagated()) { if (tgt_clk_path->clkInfo(search_)->isPropagated()) {
@ -691,7 +690,7 @@ ReportPath::reportEndpoint(const PathEndPathDelay *end) const
else { else {
Instance *inst = network_->instance(end->vertex(this)->pin()); Instance *inst = network_->instance(end->vertex(this)->pin());
const char *inst_name = cmd_network_->pathName(inst); const char *inst_name = cmd_network_->pathName(inst);
string clk_name = tgtClkName(end); std::string clk_name = tgtClkName(end);
const char *reg_desc = clkRegLatchDesc(end); const char *reg_desc = clkRegLatchDesc(end);
auto reason = stdstrPrint("%s clocked by %s", reg_desc, clk_name.c_str()); auto reason = stdstrPrint("%s clocked by %s", reg_desc, clk_name.c_str());
reportEndpoint(inst_name, reason); reportEndpoint(inst_name, reason);
@ -723,7 +722,7 @@ ReportPath::reportFull(const PathEndPathDelay *end) const
if (min_max == MinMax::max()) if (min_max == MinMax::max())
margin = -margin; margin = -margin;
string delay_msg = min_max->to_string() + "_delay"; std::string delay_msg = min_max->to_string() + "_delay";
float delay = path_delay->delay(); float delay = path_delay->delay();
reportLine(delay_msg.c_str(), delay, delay, early_late); reportLine(delay_msg.c_str(), delay, delay, early_late);
if (!path_delay->ignoreClkLatency()) { if (!path_delay->ignoreClkLatency()) {
@ -821,7 +820,7 @@ ReportPath::reportEndpointOutputDelay(const PathEndClkConstrained *end) const
if (network_->isTopLevelPort(pin)) { if (network_->isTopLevelPort(pin)) {
// Pin direction is "output" even for bidirects. // Pin direction is "output" even for bidirects.
if (tgt_clk) { if (tgt_clk) {
string clk_name = tgtClkName(end); std::string clk_name = tgtClkName(end);
auto reason = stdstrPrint("output port clocked by %s", clk_name.c_str()); auto reason = stdstrPrint("output port clocked by %s", clk_name.c_str());
reportEndpoint(pin_name, reason); reportEndpoint(pin_name, reason);
} }
@ -830,7 +829,7 @@ ReportPath::reportEndpointOutputDelay(const PathEndClkConstrained *end) const
} }
else { else {
if (tgt_clk) { if (tgt_clk) {
string clk_name = tgtClkName(end); std::string clk_name = tgtClkName(end);
auto reason = stdstrPrint("internal path endpoint clocked by %s", auto reason = stdstrPrint("internal path endpoint clocked by %s",
clk_name.c_str()); clk_name.c_str());
@ -875,7 +874,7 @@ ReportPath::reportEndpoint(const PathEndGatedClock *end) const
{ {
Instance *inst = network_->instance(end->vertex(this)->pin()); Instance *inst = network_->instance(end->vertex(this)->pin());
const char *inst_name = cmd_network_->pathName(inst); const char *inst_name = cmd_network_->pathName(inst);
string clk_name = tgtClkName(end); std::string clk_name = tgtClkName(end);
const RiseFall *clk_end_rf = end->targetClkEndTrans(this); const RiseFall *clk_end_rf = end->targetClkEndTrans(this);
const RiseFall *clk_rf = const RiseFall *clk_rf =
(end->minMax(this) == MinMax::max()) ? clk_end_rf : clk_end_rf->opposite(); (end->minMax(this) == MinMax::max()) ? clk_end_rf : clk_end_rf->opposite();
@ -955,7 +954,7 @@ ReportPath::reportEndpoint(const PathEndDataCheck *end) const
void void
ReportPath::reportEndHeader() const ReportPath::reportEndHeader() const
{ {
string line; std::string line;
// Line one. // Line one.
reportDescription("", line); reportDescription("", line);
line += ' '; line += ' ';
@ -981,8 +980,8 @@ ReportPath::reportEndHeader() const
void void
ReportPath::reportEndLine(const PathEnd *end) const ReportPath::reportEndLine(const PathEnd *end) const
{ {
string line; std::string line;
string endpoint = pathEndpoint(end); std::string endpoint = pathEndpoint(end);
reportDescription(endpoint.c_str(), line); reportDescription(endpoint.c_str(), line);
const EarlyLate *early_late = end->pathEarlyLate(this); const EarlyLate *early_late = end->pathEarlyLate(this);
reportSpaceFieldDelay(end->requiredTimeOffset(this), early_late, line); reportSpaceFieldDelay(end->requiredTimeOffset(this), early_late, line);
@ -996,7 +995,7 @@ ReportPath::reportEndLine(const PathEnd *end) const
void void
ReportPath::reportSummaryHeader() const ReportPath::reportSummaryHeader() const
{ {
string line; std::string line;
reportDescription("Startpoint", line); reportDescription("Startpoint", line);
line += ' '; line += ' ';
reportDescription("Endpoint", line); reportDescription("Endpoint", line);
@ -1010,7 +1009,7 @@ ReportPath::reportSummaryHeader() const
void void
ReportPath::reportSummaryLine(const PathEnd *end) const ReportPath::reportSummaryLine(const PathEnd *end) const
{ {
string line; std::string line;
PathExpanded expanded(end->path(), this); PathExpanded expanded(end->path(), this);
const EarlyLate *early_late = end->pathEarlyLate(this); const EarlyLate *early_late = end->pathEarlyLate(this);
auto startpoint = pathStartpoint(end, expanded); auto startpoint = pathStartpoint(end, expanded);
@ -1025,7 +1024,7 @@ ReportPath::reportSummaryLine(const PathEnd *end) const
report_->reportLineString(line); report_->reportLineString(line);
} }
string std::string
ReportPath::pathStartpoint(const PathEnd *end, ReportPath::pathStartpoint(const PathEnd *end,
const PathExpanded &expanded) const const PathExpanded &expanded) const
{ {
@ -1043,7 +1042,7 @@ ReportPath::pathStartpoint(const PathEnd *end,
} }
} }
string std::string
ReportPath::pathEndpoint(const PathEnd *end) const ReportPath::pathEndpoint(const PathEnd *end) const
{ {
Pin *pin = end->vertex(this)->pin(); Pin *pin = end->vertex(this)->pin();
@ -1078,7 +1077,7 @@ void
ReportPath::reportJson(const PathEnd *end, ReportPath::reportJson(const PathEnd *end,
bool last) const bool last) const
{ {
string result; std::string result;
result += "{\n"; result += "{\n";
stringAppend(result, " \"type\": \"%s\",\n", end->typeName()); stringAppend(result, " \"type\": \"%s\",\n", end->typeName());
stringAppend(result, " \"path_group\": \"%s\",\n", stringAppend(result, " \"path_group\": \"%s\",\n",
@ -1149,7 +1148,7 @@ ReportPath::reportJson(const PathEnd *end,
void void
ReportPath::reportJson(const Path *path) const ReportPath::reportJson(const Path *path) const
{ {
string result; std::string result;
result += "{\n"; result += "{\n";
reportJson(path, "path", 0, false, result); reportJson(path, "path", 0, false, result);
result += "}\n"; result += "}\n";
@ -1161,7 +1160,7 @@ ReportPath::reportJson(const Path *path,
const char *path_name, const char *path_name,
int indent, int indent,
bool trailing_comma, bool trailing_comma,
string &result) const std::string &result) const
{ {
PathExpanded expanded(path, this); PathExpanded expanded(path, this);
reportJson(expanded, path_name, indent, trailing_comma, result); reportJson(expanded, path_name, indent, trailing_comma, result);
@ -1172,7 +1171,7 @@ ReportPath::reportJson(const PathExpanded &expanded,
const char *path_name, const char *path_name,
int indent, int indent,
bool trailing_comma, bool trailing_comma,
string &result) const std::string &result) const
{ {
stringAppend(result, "%*s\"%s\": [\n", indent, "", path_name); stringAppend(result, "%*s\"%s\": [\n", indent, "", path_name);
for (size_t i = expanded.startIndex(); i < expanded.size(); i++) { for (size_t i = expanded.startIndex(); i < expanded.size(); i++) {
@ -1256,7 +1255,7 @@ ReportPath::reportJson(const PathExpanded &expanded,
void void
ReportPath::reportSlackOnlyHeader() const ReportPath::reportSlackOnlyHeader() const
{ {
string line; std::string line;
reportDescription("Group", line); reportDescription("Group", line);
line += ' '; line += ' ';
reportField("Slack", field_total_, line); reportField("Slack", field_total_, line);
@ -1268,7 +1267,7 @@ ReportPath::reportSlackOnlyHeader() const
void void
ReportPath::reportSlackOnly(const PathEnd *end) const ReportPath::reportSlackOnly(const PathEnd *end) const
{ {
string line; std::string line;
const EarlyLate *early_late = end->pathEarlyLate(this); const EarlyLate *early_late = end->pathEarlyLate(this);
reportDescription(end->pathGroup()->name(), line); reportDescription(end->pathGroup()->name(), line);
if (end->isUnconstrained()) if (end->isUnconstrained())
@ -1318,7 +1317,7 @@ ReportPath::reportMpwChecks(const MinPulseWidthCheckSeq &checks,
void void
ReportPath::reportMpwHeaderShort() const ReportPath::reportMpwHeaderShort() const
{ {
string line; std::string line;
reportDescription("", line); reportDescription("", line);
line += ' '; line += ' ';
reportField("Required", field_total_, line); reportField("Required", field_total_, line);
@ -1342,7 +1341,7 @@ ReportPath::reportMpwHeaderShort() const
void void
ReportPath::reportShort(const MinPulseWidthCheck &check) const ReportPath::reportShort(const MinPulseWidthCheck &check) const
{ {
string line; std::string line;
const char *pin_name = cmd_network_->pathName(check.pin(this)); const char *pin_name = cmd_network_->pathName(check.pin(this));
const char *hi_low = mpwCheckHiLow(check); const char *hi_low = mpwCheckHiLow(check);
auto what = stdstrPrint("%s (%s)", pin_name, hi_low); auto what = stdstrPrint("%s (%s)", pin_name, hi_low);
@ -1356,7 +1355,7 @@ ReportPath::reportShort(const MinPulseWidthCheck &check) const
void void
ReportPath::reportVerbose(const MinPulseWidthCheck &check) const ReportPath::reportVerbose(const MinPulseWidthCheck &check) const
{ {
string line; std::string line;
const char *pin_name = cmd_network_->pathName(check.pin(this)); const char *pin_name = cmd_network_->pathName(check.pin(this));
line += "Pin: "; line += "Pin: ";
line += pin_name; line += pin_name;
@ -1462,7 +1461,7 @@ ReportPath::reportChecks(const MinPeriodCheckSeq &checks,
void void
ReportPath::reportPeriodHeaderShort() const ReportPath::reportPeriodHeaderShort() const
{ {
string line; std::string line;
reportDescription("", line); reportDescription("", line);
line += ' '; line += ' ';
reportField("", field_total_, line); reportField("", field_total_, line);
@ -1488,7 +1487,7 @@ ReportPath::reportPeriodHeaderShort() const
void void
ReportPath::reportShort(const MinPeriodCheck &check) const ReportPath::reportShort(const MinPeriodCheck &check) const
{ {
string line; std::string line;
const char *pin_name = cmd_network_->pathName(check.pin()); const char *pin_name = cmd_network_->pathName(check.pin());
reportDescription(pin_name, line); reportDescription(pin_name, line);
reportSpaceFieldDelay(check.period(), EarlyLate::early(), line); reportSpaceFieldDelay(check.period(), EarlyLate::early(), line);
@ -1500,7 +1499,7 @@ ReportPath::reportShort(const MinPeriodCheck &check) const
void void
ReportPath::reportVerbose(const MinPeriodCheck &check) const ReportPath::reportVerbose(const MinPeriodCheck &check) const
{ {
string line; std::string line;
const char *pin_name = cmd_network_->pathName(check.pin()); const char *pin_name = cmd_network_->pathName(check.pin());
line += "Pin: "; line += "Pin: ";
line += pin_name; line += pin_name;
@ -1536,7 +1535,7 @@ ReportPath::reportChecks(const MaxSkewCheckSeq &checks,
void void
ReportPath::reportMaxSkewHeaderShort() const ReportPath::reportMaxSkewHeaderShort() const
{ {
string line; std::string line;
reportDescription("", line); reportDescription("", line);
line += ' '; line += ' ';
reportField("Required", field_total_, line); reportField("Required", field_total_, line);
@ -1562,7 +1561,7 @@ ReportPath::reportMaxSkewHeaderShort() const
void void
ReportPath::reportShort(const MaxSkewCheck &check) const ReportPath::reportShort(const MaxSkewCheck &check) const
{ {
string line; std::string line;
Pin *clk_pin = check.clkPin(this); Pin *clk_pin = check.clkPin(this);
const char *clk_pin_name = network_->pathName(clk_pin); const char *clk_pin_name = network_->pathName(clk_pin);
TimingArc *check_arc = check.checkArc(); TimingArc *check_arc = check.checkArc();
@ -1581,7 +1580,7 @@ ReportPath::reportShort(const MaxSkewCheck &check) const
void void
ReportPath::reportVerbose(const MaxSkewCheck &check) const ReportPath::reportVerbose(const MaxSkewCheck &check) const
{ {
string line; std::string line;
const char *clk_pin_name = cmd_network_->pathName(check.clkPin(this)); const char *clk_pin_name = cmd_network_->pathName(check.clkPin(this));
line += "Constrained Pin: "; line += "Constrained Pin: ";
line += clk_pin_name; line += clk_pin_name;
@ -1617,7 +1616,7 @@ ReportPath::reportSkewClkPath(const char *arrival_msg,
const EarlyLate *early_late = clk_path->minMax(this); const EarlyLate *early_late = clk_path->minMax(this);
const RiseFall *clk_rf = clk_edge->transition(); const RiseFall *clk_rf = clk_edge->transition();
const RiseFall *clk_end_rf = clk_path->transition(this); const RiseFall *clk_end_rf = clk_path->transition(this);
string clk_name = clkName(clk, clk_end_rf != clk_rf); std::string clk_name = clkName(clk, clk_end_rf != clk_rf);
float clk_time = clk_edge->time(); float clk_time = clk_edge->time();
const Arrival &clk_arrival = search_->clkPathArrival(clk_path); const Arrival &clk_arrival = search_->clkPathArrival(clk_path);
Arrival clk_delay = clk_arrival - clk_time; Arrival clk_delay = clk_arrival - clk_time;
@ -1656,7 +1655,7 @@ ReportPath::reportSkewClkPath(const char *arrival_msg,
void void
ReportPath::reportLimitShortHeader(const ReportField *field) const ReportPath::reportLimitShortHeader(const ReportField *field) const
{ {
string line; std::string line;
reportDescription("Pin", line); reportDescription("Pin", line);
line += ' '; line += ' ';
reportField("Limit", field, line); reportField("Limit", field, line);
@ -1676,7 +1675,7 @@ ReportPath::reportLimitShort(const ReportField *field,
float limit, float limit,
float slack) const float slack) const
{ {
string line; std::string line;
const char *pin_name = cmd_network_->pathName(pin); const char *pin_name = cmd_network_->pathName(pin);
reportDescription(pin_name, line); reportDescription(pin_name, line);
line += ' '; line += ' ';
@ -1701,7 +1700,7 @@ ReportPath::reportLimitVerbose(const ReportField *field,
const Scene *scene, const Scene *scene,
const MinMax *min_max) const const MinMax *min_max) const
{ {
string line; std::string line;
line += "Pin "; line += "Pin ";
line += cmd_network_->pathName(pin); line += cmd_network_->pathName(pin);
line += ' '; line += ' ';
@ -1781,7 +1780,7 @@ ReportPath::reportStartpoint(const PathEnd *end,
const Path *clk_path = expanded.clkPath(); const Path *clk_path = expanded.clkPath();
bool clk_inverted = clk_path bool clk_inverted = clk_path
&& clk_rf != clk_path->transition(this); && clk_rf != clk_path->transition(this);
string clk_name = clkName(clk, clk_inverted); std::string clk_name = clkName(clk, clk_inverted);
const char *reg_desc = edgeRegLatchDesc(prev_edge, prev_arc); const char *reg_desc = edgeRegLatchDesc(prev_edge, prev_arc);
auto reason = stdstrPrint("%s clocked by %s", reg_desc, clk_name.c_str()); auto reason = stdstrPrint("%s clocked by %s", reg_desc, clk_name.c_str());
reportStartpoint(inst_name, reason); reportStartpoint(inst_name, reason);
@ -1829,7 +1828,7 @@ ReportPath::pathFromClkPin(const Path *path,
void void
ReportPath::reportStartpoint(const char *start, ReportPath::reportStartpoint(const char *start,
const string reason) const const std::string reason) const
{ {
reportStartEndPoint(start, reason, "Startpoint"); reportStartEndPoint(start, reason, "Startpoint");
} }
@ -1878,17 +1877,17 @@ ReportPath::reportUnclockedEndpoint(const PathEnd *end,
void void
ReportPath::reportEndpoint(const char *end, ReportPath::reportEndpoint(const char *end,
const string reason) const const std::string reason) const
{ {
reportStartEndPoint(end, reason, "Endpoint"); reportStartEndPoint(end, reason, "Endpoint");
} }
void void
ReportPath::reportStartEndPoint(const char *pt, ReportPath::reportStartEndPoint(const char *pt,
string reason, std::string reason,
const char *key) const const char *key) const
{ {
string line; std::string line;
// Account for punctuation in the line. // Account for punctuation in the line.
int line_len = strlen(key) + 2 + strlen(pt) + 2 + reason.size() + 1; int line_len = strlen(key) + 2 + strlen(pt) + 2 + reason.size() + 1;
if (!no_split_ if (!no_split_
@ -1921,7 +1920,7 @@ ReportPath::reportStartEndPoint(const char *pt,
void void
ReportPath::reportGroup(const PathEnd *end) const ReportPath::reportGroup(const PathEnd *end) const
{ {
string line; std::string line;
line = "Path Group: "; line = "Path Group: ";
PathGroup *group = end->pathGroup(); PathGroup *group = end->pathGroup();
line += group ? group->name() : "(none)"; line += group ? group->name() : "(none)";
@ -1946,13 +1945,13 @@ ReportPath::reportGroup(const PathEnd *end) const
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
string std::string
ReportPath::checkRoleReason(const PathEnd *end) const ReportPath::checkRoleReason(const PathEnd *end) const
{ {
return stdstrPrint("%s time", end->checkRole(this)->to_string().c_str()); return stdstrPrint("%s time", end->checkRole(this)->to_string().c_str());
} }
string std::string
ReportPath::tgtClkName(const PathEnd *end) const ReportPath::tgtClkName(const PathEnd *end) const
{ {
const ClockEdge *tgt_clk_edge = end->targetClkEdge(this); const ClockEdge *tgt_clk_edge = end->targetClkEdge(this);
@ -1962,11 +1961,11 @@ ReportPath::tgtClkName(const PathEnd *end) const
return clkName(tgt_clk, clk_end_rf != clk_rf); return clkName(tgt_clk, clk_end_rf != clk_rf);
} }
string std::string
ReportPath::clkName(const Clock *clk, ReportPath::clkName(const Clock *clk,
bool inverted) const bool inverted) const
{ {
string name = clk->name(); std::string name = clk->name();
if (inverted) if (inverted)
name += '\''; name += '\'';
return name; return name;
@ -2088,7 +2087,7 @@ ReportPath::reportSrcClkAndPath(const Path *path,
} }
} }
} }
string clk_name = clkName(clk, clk_rf != clk_end_rf); std::string clk_name = clkName(clk, clk_rf != clk_end_rf);
bool clk_used_as_data = pathFromClkPin(expanded); bool clk_used_as_data = pathFromClkPin(expanded);
bool is_prop = isPropagated(path); bool is_prop = isPropagated(path);
@ -2185,7 +2184,7 @@ ReportPath::reportTgtClk(const PathEnd *end,
Clock *clk = clk_edge->clock(); Clock *clk = clk_edge->clock();
const RiseFall *clk_rf = clk_edge->transition(); const RiseFall *clk_rf = clk_edge->transition();
const RiseFall *clk_end_rf = end->targetClkEndTrans(this); const RiseFall *clk_end_rf = end->targetClkEndTrans(this);
string clk_name = clkName(clk, clk_end_rf != clk_rf); std::string clk_name = clkName(clk, clk_end_rf != clk_rf);
float clk_time = prev_time float clk_time = prev_time
+ end->targetClkTime(this) + end->targetClkTime(this)
+ end->targetClkMcpAdjustment(this) + end->targetClkMcpAdjustment(this)
@ -2439,7 +2438,7 @@ ReportPath::reportPathLine(const Path *path,
{ {
Vertex *vertex = path->vertex(this); Vertex *vertex = path->vertex(this);
Pin *pin = vertex->pin(); Pin *pin = vertex->pin();
const string what = descriptionField(vertex); const std::string what = descriptionField(vertex);
const RiseFall *rf = path->transition(this); const RiseFall *rf = path->transition(this);
bool is_driver = network_->isDriver(pin); bool is_driver = network_->isDriver(pin);
const EarlyLate *early_late = path->minMax(this); const EarlyLate *early_late = path->minMax(this);
@ -2449,7 +2448,7 @@ ReportPath::reportPathLine(const Path *path,
Slew slew = graph_->slew(vertex, rf, slew_index); Slew slew = graph_->slew(vertex, rf, slew_index);
float cap = field_blank_; float cap = field_blank_;
Instance *inst = network_->instance(pin); Instance *inst = network_->instance(pin);
string src_attr = ""; std::string src_attr = "";
if (inst) if (inst)
src_attr = network_->getAttribute(inst, "src"); src_attr = network_->getAttribute(inst, "src");
// Don't show capacitance field for input pins. // Don't show capacitance field for input pins.
@ -2462,7 +2461,7 @@ ReportPath::reportPathLine(const Path *path,
void void
ReportPath::reportRequired(const PathEnd *end, ReportPath::reportRequired(const PathEnd *end,
string margin_msg) const std::string margin_msg) const
{ {
Required req_time = end->requiredTimeOffset(this); Required req_time = end->requiredTimeOffset(this);
const EarlyLate *early_late = end->clkEarlyLate(this); const EarlyLate *early_late = end->clkEarlyLate(this);
@ -2503,7 +2502,7 @@ ReportPath::reportSlack(Slack slack) const
void void
ReportPath::reportSpaceSlack(const PathEnd *end, ReportPath::reportSpaceSlack(const PathEnd *end,
string &result) const std::string &result) const
{ {
Slack slack = end->slack(this); Slack slack = end->slack(this);
reportSpaceSlack(slack, result); reportSpaceSlack(slack, result);
@ -2511,7 +2510,7 @@ ReportPath::reportSpaceSlack(const PathEnd *end,
void void
ReportPath::reportSpaceSlack(Slack slack, ReportPath::reportSpaceSlack(Slack slack,
string &result) const std::string &result) const
{ {
const EarlyLate *early_late = EarlyLate::early(); const EarlyLate *early_late = EarlyLate::early();
reportSpaceFieldDelay(slack, early_late, result); reportSpaceFieldDelay(slack, early_late, result);
@ -2718,7 +2717,7 @@ ReportPath::reportPath6(const Path *path,
bool is_clk_start = path1->vertex(this) == clk_start; bool is_clk_start = path1->vertex(this) == clk_start;
bool is_clk = path1->isClock(search_); bool is_clk = path1->isClock(search_);
Instance *inst = network_->instance(pin); Instance *inst = network_->instance(pin);
string src_attr = ""; std::string src_attr = "";
if (inst) if (inst)
src_attr = network_->getAttribute(inst, "src"); src_attr = network_->getAttribute(inst, "src");
// Always show the search start point (register clk pin). // Always show the search start point (register clk pin).
@ -2804,13 +2803,13 @@ ReportPath::reportPath6(const Path *path,
cap = graph_delay_calc_->loadCap(pin, rf, scene, min_max); cap = graph_delay_calc_->loadCap(pin, rf, scene, min_max);
if (field_fanout_->enabled()) if (field_fanout_->enabled())
fanout = drvrFanout(vertex, scene, min_max); fanout = drvrFanout(vertex, scene, min_max);
const string what = descriptionField(vertex); const std::string what = descriptionField(vertex);
reportLine(what.c_str(), cap, slew, fanout, reportLine(what.c_str(), cap, slew, fanout,
incr, time, false, min_max, rf, src_attr, incr, time, false, min_max, rf, src_attr,
line_case); line_case);
if (report_net_) { if (report_net_) {
const string what2 = descriptionNet(pin); const std::string what2 = descriptionNet(pin);
reportLine(what2.c_str(), field_blank_, field_blank_, field_blank_, reportLine(what2.c_str(), field_blank_, field_blank_, field_blank_,
field_blank_, field_blank_, false, min_max, field_blank_, field_blank_, false, min_max,
nullptr, src_attr, ""); nullptr, src_attr, "");
@ -2823,7 +2822,7 @@ ReportPath::reportPath6(const Path *path,
|| (i == 0) || (i == 0)
|| (i == path_last_index) || (i == path_last_index)
|| is_clk_start) { || is_clk_start) {
const string what = descriptionField(vertex); const std::string what = descriptionField(vertex);
reportLine(what.c_str(), field_blank_, slew, field_blank_, reportLine(what.c_str(), field_blank_, slew, field_blank_,
incr, time, false, min_max, rf, src_attr, incr, time, false, min_max, rf, src_attr,
line_case); line_case);
@ -2843,7 +2842,7 @@ ReportPath::reportHierPinsThru(const Path *path) const
const Edge *prev_edge = path->prevEdge(this); const Edge *prev_edge = path->prevEdge(this);
if (prev_edge && prev_edge->isWire()) { if (prev_edge && prev_edge->isWire()) {
for (const Pin *hpin : hierPinsThruEdge(prev_edge, network_, graph_)) { for (const Pin *hpin : hierPinsThruEdge(prev_edge, network_, graph_)) {
const string what = descriptionField(hpin); const std::string what = descriptionField(hpin);
reportLine(what.c_str(), field_blank_, field_blank_, field_blank_, reportLine(what.c_str(), field_blank_, field_blank_, field_blank_,
field_blank_, field_blank_, false, path->minMax(this), field_blank_, field_blank_, false, path->minMax(this),
nullptr, "", ""); nullptr, "", "");
@ -2874,13 +2873,13 @@ ReportPath::nextArcAnnotated(const Path *next_path,
return graph_->arcDelayAnnotated(edge, arc, ap_index); return graph_->arcDelayAnnotated(edge, arc, ap_index);
} }
string std::string
ReportPath::descriptionField(const Vertex *vertex) const ReportPath::descriptionField(const Vertex *vertex) const
{ {
return descriptionField(vertex->pin()); return descriptionField(vertex->pin());
} }
string std::string
ReportPath::descriptionField(const Pin *pin) const ReportPath::descriptionField(const Pin *pin) const
{ {
const char *pin_name = cmd_network_->pathName(pin); const char *pin_name = cmd_network_->pathName(pin);
@ -2906,7 +2905,7 @@ ReportPath::descriptionField(const Pin *pin) const
return stdstrPrint("%s (%s)", pin_name, name2); return stdstrPrint("%s (%s)", pin_name, name2);
} }
string std::string
ReportPath::descriptionNet(const Pin *pin) const ReportPath::descriptionNet(const Pin *pin) const
{ {
if (network_->isTopLevelPort(pin)) { if (network_->isTopLevelPort(pin)) {
@ -3028,7 +3027,7 @@ ReportPath::pathInputDelayRefPath(const Path *path,
void void
ReportPath::reportPathHeader() const ReportPath::reportPathHeader() const
{ {
string line; std::string line;
bool first_field = true; bool first_field = true;
for (const ReportField *field : fields_) { for (const ReportField *field : fields_) {
if (field->enabled()) { if (field->enabled()) {
@ -3125,10 +3124,10 @@ ReportPath::reportLine(const char *what,
bool total_with_minus, bool total_with_minus,
const EarlyLate *early_late, const EarlyLate *early_late,
const RiseFall *rf, const RiseFall *rf,
string src_attr, std::string src_attr,
const char *line_case) const const char *line_case) const
{ {
string line; std::string line;
size_t field_index = 0; size_t field_index = 0;
bool first_field = true; bool first_field = true;
for (const ReportField *field : fields_) { for (const ReportField *field : fields_) {
@ -3180,7 +3179,7 @@ ReportPath::reportLine(const char *what,
field_index++; field_index++;
} }
// Trim trailing spaces and report the line. // Trim trailing spaces and report the line.
string line_stdstr = line; std::string line_stdstr = line;
trimRight(line_stdstr); trimRight(line_stdstr);
report_->reportLineString(line_stdstr.c_str()); report_->reportLineString(line_stdstr.c_str());
} }
@ -3211,7 +3210,7 @@ ReportPath::reportLineTotal1(const char *what,
bool incr_with_minus, bool incr_with_minus,
const EarlyLate *early_late) const const EarlyLate *early_late) const
{ {
string line; std::string line;
reportDescription(what, line); reportDescription(what, line);
line += ' '; line += ' ';
if (incr_with_minus) if (incr_with_minus)
@ -3231,7 +3230,7 @@ ReportPath::reportDashLineTotal() const
void void
ReportPath::reportDescription(const char *what, ReportPath::reportDescription(const char *what,
string &line) const std::string &line) const
{ {
reportDescription(what, false, false, line); reportDescription(what, false, false, line);
} }
@ -3240,7 +3239,7 @@ void
ReportPath::reportDescription(const char *what, ReportPath::reportDescription(const char *what,
bool first_field, bool first_field,
bool last_field, bool last_field,
string &line) const std::string &line) const
{ {
line += what; line += what;
int length = strlen(what); int length = strlen(what);
@ -3260,7 +3259,7 @@ ReportPath::reportDescription(const char *what,
void void
ReportPath::reportFieldTime(float value, ReportPath::reportFieldTime(float value,
ReportField *field, ReportField *field,
string &line) const std::string &line) const
{ {
if (delayAsFloat(value) == field_blank_) if (delayAsFloat(value) == field_blank_)
reportFieldBlank(field, line); reportFieldBlank(field, line);
@ -3275,7 +3274,7 @@ ReportPath::reportFieldTime(float value,
void void
ReportPath::reportSpaceFieldTime(float value, ReportPath::reportSpaceFieldTime(float value,
string &line) const std::string &line) const
{ {
line += ' '; line += ' ';
reportFieldTime(value, field_total_, line); reportFieldTime(value, field_total_, line);
@ -3284,7 +3283,7 @@ ReportPath::reportSpaceFieldTime(float value,
void void
ReportPath::reportSpaceFieldDelay(Delay value, ReportPath::reportSpaceFieldDelay(Delay value,
const EarlyLate *early_late, const EarlyLate *early_late,
string &line) const std::string &line) const
{ {
line += ' '; line += ' ';
reportTotalDelay(value, early_late, line); reportTotalDelay(value, early_late, line);
@ -3293,7 +3292,7 @@ ReportPath::reportSpaceFieldDelay(Delay value,
void void
ReportPath::reportTotalDelay(Delay value, ReportPath::reportTotalDelay(Delay value,
const EarlyLate *early_late, const EarlyLate *early_late,
string &line) const std::string &line) const
{ {
const char *str = delayAsString(value, early_late, this, digits_); const char *str = delayAsString(value, early_late, this, digits_);
if (stringEq(str, minus_zero_)) if (stringEq(str, minus_zero_))
@ -3307,7 +3306,7 @@ void
ReportPath::reportFieldDelayMinus(Delay value, ReportPath::reportFieldDelayMinus(Delay value,
const EarlyLate *early_late, const EarlyLate *early_late,
const ReportField *field, const ReportField *field,
string &line) const std::string &line) const
{ {
if (delayAsFloat(value) == field_blank_) if (delayAsFloat(value) == field_blank_)
reportFieldBlank(field, line); reportFieldBlank(field, line);
@ -3327,7 +3326,7 @@ void
ReportPath::reportFieldDelay(Delay value, ReportPath::reportFieldDelay(Delay value,
const EarlyLate *early_late, const EarlyLate *early_late,
const ReportField *field, const ReportField *field,
string &line) const std::string &line) const
{ {
if (delayAsFloat(value) == field_blank_) if (delayAsFloat(value) == field_blank_)
reportFieldBlank(field, line); reportFieldBlank(field, line);
@ -3345,7 +3344,7 @@ ReportPath::reportFieldDelay(Delay value,
void void
ReportPath::reportField(float value, ReportPath::reportField(float value,
const ReportField *field, const ReportField *field,
string &line) const std::string &line) const
{ {
if (value == field_blank_) if (value == field_blank_)
reportFieldBlank(field, line); reportFieldBlank(field, line);
@ -3357,7 +3356,7 @@ ReportPath::reportField(float value,
} }
else { else {
// fanout // fanout
string value_str; std::string value_str;
stringPrint(value_str, "%.0f", value); stringPrint(value_str, "%.0f", value);
reportField(value_str.c_str(), field, line); reportField(value_str.c_str(), field, line);
} }
@ -3367,7 +3366,7 @@ ReportPath::reportField(float value,
void void
ReportPath::reportField(const char *value, ReportPath::reportField(const char *value,
const ReportField *field, const ReportField *field,
string &line) const std::string &line) const
{ {
if (field->leftJustify()) if (field->leftJustify())
line += value; line += value;
@ -3379,7 +3378,7 @@ ReportPath::reportField(const char *value,
void void
ReportPath::reportFieldBlank(const ReportField *field, ReportPath::reportFieldBlank(const ReportField *field,
string &line) const std::string &line) const
{ {
line += field->blank(); line += field->blank();
} }
@ -3387,7 +3386,7 @@ ReportPath::reportFieldBlank(const ReportField *field,
void void
ReportPath::reportDashLine() const ReportPath::reportDashLine() const
{ {
string line; std::string line;
for (const ReportField *field : fields_) { for (const ReportField *field : fields_) {
if (field->enabled()) { if (field->enabled()) {
for (int i = 0; i < field->width(); i++) for (int i = 0; i < field->width(); i++)
@ -3401,7 +3400,7 @@ ReportPath::reportDashLine() const
void void
ReportPath::reportDashLine(int line_width) const ReportPath::reportDashLine(int line_width) const
{ {
string line; std::string line;
for (int i = 0; i < line_width; i++) for (int i = 0; i < line_width; i++)
line += '-'; line += '-';
report_->reportLineString(line); report_->reportLineString(line);

View File

@ -24,8 +24,7 @@
#include "Search.hh" #include "Search.hh"
#include <algorithm> #include <vector>
#include <cmath> // abs
#include "ContainerHelpers.hh" #include "ContainerHelpers.hh"
#include "Mutex.hh" #include "Mutex.hh"
@ -70,10 +69,6 @@
namespace sta { namespace sta {
using std::min;
using std::max;
using std::abs;
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
EvalPred::EvalPred(const StaState *sta) : EvalPred::EvalPred(const StaState *sta) :

View File

@ -335,6 +335,14 @@ slow_drivers(int count)
return Sta::sta()->slowDrivers(count); return Sta::sta()->slowDrivers(count);
} }
bool
is_ideal_clock(const Pin *pin)
{
Sta *sta = Sta::sta();
const Mode *mode = sta->cmdMode();
return sta->isIdealClock(pin, mode);
}
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
PathEndSeq PathEndSeq
@ -374,32 +382,12 @@ find_path_ends(ExceptionFrom *from,
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
void
report_path_end_header()
{
Sta::sta()->reportPathEndHeader();
}
void
report_path_end_footer()
{
Sta::sta()->reportPathEndFooter();
}
void void
report_path_end(PathEnd *end) report_path_end(PathEnd *end)
{ {
Sta::sta()->reportPathEnd(end); Sta::sta()->reportPathEnd(end);
} }
void
report_path_end2(PathEnd *end,
PathEnd *prev_end,
bool last)
{
Sta::sta()->reportPathEnd(end, prev_end, last);
}
void void
set_report_path_format(ReportPathFormat format) set_report_path_format(ReportPathFormat format)
{ {

View File

@ -24,7 +24,9 @@
#include "Sta.hh" #include "Sta.hh"
#include <algorithm>
#include <filesystem> #include <filesystem>
#include <string>
#include "Machine.hh" #include "Machine.hh"
#include "ContainerHelpers.hh" #include "ContainerHelpers.hh"
@ -88,10 +90,6 @@
namespace sta { namespace sta {
using std::string;
using std::min;
using std::max;
static bool static bool
libertyPortCapsEqual(const LibertyPort *port1, libertyPortCapsEqual(const LibertyPort *port1,
const LibertyPort *port2); const LibertyPort *port2);
@ -576,7 +574,7 @@ Sta::cmdSdc() const
} }
void void
Sta::setCmdMode(const string &mode_name) Sta::setCmdMode(const std::string &mode_name)
{ {
if (!mode_name.empty()) { if (!mode_name.empty()) {
if (!mode_name_map_.contains(mode_name)) { if (!mode_name_map_.contains(mode_name)) {
@ -2774,32 +2772,12 @@ Sta::setReportPathSigmas(bool report_sigmas)
report_path_->setReportSigmas(report_sigmas); report_path_->setReportSigmas(report_sigmas);
} }
void
Sta::reportPathEndHeader()
{
report_path_->reportPathEndHeader();
}
void
Sta::reportPathEndFooter()
{
report_path_->reportPathEndFooter();
}
void void
Sta::reportPathEnd(PathEnd *end) Sta::reportPathEnd(PathEnd *end)
{ {
report_path_->reportPathEnd(end); report_path_->reportPathEnd(end);
} }
void
Sta::reportPathEnd(PathEnd *end,
PathEnd *prev_end,
bool last)
{
report_path_->reportPathEnd(end, prev_end, last);
}
void void
Sta::reportPathEnds(PathEndSeq *ends) Sta::reportPathEnds(PathEndSeq *ends)
{ {
@ -3228,8 +3206,8 @@ class EndpointPathEndVisitor : public PathEndVisitor
{ {
public: public:
EndpointPathEndVisitor(const std::string &path_group_name, EndpointPathEndVisitor(const std::string &path_group_name,
const MinMax *min_max, const MinMax *min_max,
const StaState *sta); const StaState *sta);
PathEndVisitor *copy() const; PathEndVisitor *copy() const;
void visit(PathEnd *path_end); void visit(PathEnd *path_end);
Slack slack() const { return slack_; } Slack slack() const { return slack_; }
@ -3242,8 +3220,8 @@ private:
}; };
EndpointPathEndVisitor::EndpointPathEndVisitor(const std::string &path_group_name, EndpointPathEndVisitor::EndpointPathEndVisitor(const std::string &path_group_name,
const MinMax *min_max, const MinMax *min_max,
const StaState *sta) : const StaState *sta) :
path_group_name_(path_group_name), path_group_name_(path_group_name),
min_max_(min_max), min_max_(min_max),
slack_(MinMax::min()->initValue()), slack_(MinMax::min()->initValue()),
@ -3274,8 +3252,8 @@ EndpointPathEndVisitor::visit(PathEnd *path_end)
Slack Slack
Sta::endpointSlack(const Pin *pin, Sta::endpointSlack(const Pin *pin,
const std::string &path_group_name, const std::string &path_group_name,
const MinMax *min_max) const MinMax *min_max)
{ {
ensureGraph(); ensureGraph();
Vertex *vertex = graph_->pinLoadVertex(pin); Vertex *vertex = graph_->pinLoadVertex(pin);
@ -3297,7 +3275,8 @@ Sta::reportArrivalWrtClks(const Pin *pin,
const Scene *scene, const Scene *scene,
int digits) int digits)
{ {
reportDelaysWrtClks(pin, scene, digits, searchPreamble();
reportDelaysWrtClks(pin, scene, digits, false,
[] (const Path *path) { [] (const Path *path) {
return path->arrival(); return path->arrival();
}); });
@ -3308,7 +3287,7 @@ Sta::reportRequiredWrtClks(const Pin *pin,
const Scene *scene, const Scene *scene,
int digits) int digits)
{ {
reportDelaysWrtClks(pin, scene, digits, reportDelaysWrtClks(pin, scene, digits, true,
[] (const Path *path) { [] (const Path *path) {
return path->required(); return path->required();
}); });
@ -3319,7 +3298,7 @@ Sta::reportSlackWrtClks(const Pin *pin,
const Scene *scene, const Scene *scene,
int digits) int digits)
{ {
reportDelaysWrtClks(pin, scene, digits, reportDelaysWrtClks(pin, scene, digits, true,
[this] (const Path *path) { [this] (const Path *path) {
return path->slack(this); return path->slack(this);
}); });
@ -3329,24 +3308,29 @@ void
Sta::reportDelaysWrtClks(const Pin *pin, Sta::reportDelaysWrtClks(const Pin *pin,
const Scene *scene, const Scene *scene,
int digits, int digits,
bool find_required,
PathDelayFunc get_path_delay) PathDelayFunc get_path_delay)
{ {
ensureGraph(); ensureGraph();
Vertex *vertex, *bidir_vertex; Vertex *vertex, *bidir_vertex;
graph_->pinVertices(pin, vertex, bidir_vertex); graph_->pinVertices(pin, vertex, bidir_vertex);
if (vertex) if (vertex)
reportDelaysWrtClks(vertex, scene, digits, get_path_delay); reportDelaysWrtClks(vertex, scene, digits, find_required, get_path_delay);
if (bidir_vertex) if (bidir_vertex)
reportDelaysWrtClks(vertex, scene, digits, get_path_delay); reportDelaysWrtClks(vertex, scene, digits, find_required, get_path_delay);
} }
void void
Sta::reportDelaysWrtClks(Vertex *vertex, Sta::reportDelaysWrtClks(Vertex *vertex,
const Scene *scene, const Scene *scene,
int digits, int digits,
bool find_required,
PathDelayFunc get_path_delay) PathDelayFunc get_path_delay)
{ {
findRequired(vertex); if (find_required)
findRequired(vertex);
else
search_->findArrivals(vertex->level());
const Sdc *sdc = scene->sdc(); const Sdc *sdc = scene->sdc();
reportDelaysWrtClks(vertex, nullptr, scene, digits, get_path_delay); reportDelaysWrtClks(vertex, nullptr, scene, digits, get_path_delay);
const ClockEdge *default_clk_edge = sdc->defaultArrivalClock()->edge(RiseFall::rise()); const ClockEdge *default_clk_edge = sdc->defaultArrivalClock()->edge(RiseFall::rise());
@ -3483,7 +3467,7 @@ MinPeriodEndVisitor::visit(PathEnd *path_end)
|| pathIsFromInputPort(path_end)))) { || pathIsFromInputPort(path_end)))) {
Slack slack = path_end->slack(sta_); Slack slack = path_end->slack(sta_);
float period = clk_->period() - delayAsFloat(slack); float period = clk_->period() - delayAsFloat(slack);
min_period_ = max(min_period_, period); min_period_ = std::max(min_period_, period);
} }
} }
@ -3576,12 +3560,12 @@ Sta::worstSlack(const Scene *scene,
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
string std::string
Sta::reportDelayCalc(Edge *edge, Sta::reportDelayCalc(Edge *edge,
TimingArc *arc, TimingArc *arc,
const Scene *scene, const Scene *scene,
const MinMax *min_max, const MinMax *min_max,
int digits) int digits)
{ {
findDelays(); findDelays();
return graph_delay_calc_->reportDelayCalc(edge, arc, scene, min_max, digits); return graph_delay_calc_->reportDelayCalc(edge, arc, scene, min_max, digits);
@ -4122,13 +4106,13 @@ Sta::setResistance(const Net *net,
bool bool
Sta::readSpef(const std::string &name, Sta::readSpef(const std::string &name,
const std::string &filename, const std::string &filename,
Instance *instance, Instance *instance,
Scene *scene, // -scene deprecated 11/20/2025 Scene *scene, // -scene deprecated 11/20/2025
const MinMaxAll *min_max, const MinMaxAll *min_max,
bool pin_cap_included, bool pin_cap_included,
bool keep_coupling_caps, bool keep_coupling_caps,
float coupling_cap_factor, float coupling_cap_factor,
bool reduce) bool reduce)
{ {
ensureLibLinked(); ensureLibLinked();
Parasitics *parasitics = nullptr; Parasitics *parasitics = nullptr;
@ -4162,7 +4146,7 @@ Sta::readSpef(const std::string &name,
} }
bool success = readSpefFile(filename.c_str(), instance, bool success = readSpefFile(filename.c_str(), instance,
pin_cap_included, keep_coupling_caps, pin_cap_included, keep_coupling_caps,
coupling_cap_factor, reduce, coupling_cap_factor, reduce,
scene, min_max, parasitics, this); scene, min_max, parasitics, this);
delaysInvalid(); delaysInvalid();
@ -4176,7 +4160,7 @@ Sta::findParasitics(const std::string &name)
} }
void void
Sta::reportParasiticAnnotation(const string &spef_name, Sta::reportParasiticAnnotation(const std::string &spef_name,
bool report_unannotated) bool report_unannotated)
{ {
ensureLibLinked(); ensureLibLinked();
@ -4712,12 +4696,14 @@ Sta::connectLoadPinAfter(Vertex *vertex)
VertexInEdgeIterator edge_iter(vertex, graph_); VertexInEdgeIterator edge_iter(vertex, graph_);
while (edge_iter.hasNext()) { while (edge_iter.hasNext()) {
Edge *edge = edge_iter.next(); Edge *edge = edge_iter.next();
Vertex *from_vertex = edge->from(graph_); if (!edge->role()->isTimingCheck()) {
graph_delay_calc_->delayInvalid(from_vertex); Vertex *from_vertex = edge->from(graph_);
search_->requiredInvalid(from_vertex); graph_delay_calc_->delayInvalid(from_vertex);
for (Mode *mode : modes_) search_->requiredInvalid(from_vertex);
mode->sdc()->clkHpinDisablesChanged(from_vertex->pin()); levelize_->relevelizeFrom(from_vertex);
levelize_->relevelizeFrom(from_vertex); for (Mode *mode : modes_)
mode->sdc()->clkHpinDisablesChanged(from_vertex->pin());
}
} }
Pin *pin = vertex->pin(); Pin *pin = vertex->pin();
for (Mode *mode : modes_) { for (Mode *mode : modes_) {
@ -4795,12 +4781,14 @@ Sta::deleteEdge(Edge *edge)
edge->from(graph_)->name(sdc_network_), edge->from(graph_)->name(sdc_network_),
edge->to(graph_)->name(sdc_network_)); edge->to(graph_)->name(sdc_network_));
Vertex *to = edge->to(graph_); Vertex *to = edge->to(graph_);
search_->deleteEdgeBefore(edge); if (!edge->role()->isTimingCheck()) {
graph_delay_calc_->delayInvalid(to); search_->deleteEdgeBefore(edge);
levelize_->relevelizeFrom(to); graph_delay_calc_->delayInvalid(to);
levelize_->deleteEdgeBefore(edge); levelize_->relevelizeFrom(to);
for (Mode *mode : modes_) levelize_->deleteEdgeBefore(edge);
mode->sdc()->clkHpinDisablesChanged(edge->from(graph_)->pin()); for (Mode *mode : modes_)
mode->sdc()->clkHpinDisablesChanged(edge->from(graph_)->pin());
}
graph_->deleteEdge(edge); graph_->deleteEdge(edge);
} }
@ -6075,28 +6063,31 @@ Sta::ensureClkNetwork(const Mode *mode)
bool bool
Sta::isClock(const Pin *pin, Sta::isClock(const Pin *pin,
const Mode *mode) const const Mode *mode)
{ {
ensureClkNetwork(mode);
return mode->clkNetwork()->isClock(pin); return mode->clkNetwork()->isClock(pin);
} }
bool bool
Sta::isClock(const Net *net, Sta::isClock(const Net *net,
const Mode *mode) const const Mode *mode)
{ {
ensureClkNetwork(mode);
return mode->clkNetwork()->isClock(net); return mode->clkNetwork()->isClock(net);
} }
bool bool
Sta::isIdealClock(const Pin *pin, Sta::isIdealClock(const Pin *pin,
const Mode *mode) const const Mode *mode)
{ {
ensureClkNetwork(mode);
return mode->clkNetwork()->isIdealClock(pin); return mode->clkNetwork()->isIdealClock(pin);
} }
bool bool
Sta::isPropagatedClock(const Pin *pin, Sta::isPropagatedClock(const Pin *pin,
const Mode *mode) const const Mode *mode)
{ {
return mode->clkNetwork()->isPropagatedClock(pin); return mode->clkNetwork()->isPropagatedClock(pin);
} }
@ -6105,12 +6096,14 @@ const PinSet *
Sta::pins(const Clock *clk, Sta::pins(const Clock *clk,
const Mode *mode) const Mode *mode)
{ {
ensureClkNetwork(mode);
return mode->clkNetwork()->pins(clk); return mode->clkNetwork()->pins(clk);
} }
void void
Sta::clkPinsInvalid(const Mode *mode) Sta::clkPinsInvalid(const Mode *mode)
{ {
ensureClkNetwork(mode);
mode->clkNetwork()->clkPinsInvalid(); mode->clkNetwork()->clkPinsInvalid();
} }

View File

@ -24,6 +24,8 @@
#include "WorstSlack.hh" #include "WorstSlack.hh"
#include <algorithm>
#include "ContainerHelpers.hh" #include "ContainerHelpers.hh"
#include "Debug.hh" #include "Debug.hh"
#include "Report.hh" #include "Report.hh"
@ -34,8 +36,6 @@
namespace sta { namespace sta {
using std::min;
WorstSlacks::WorstSlacks(StaState *sta) : WorstSlacks::WorstSlacks(StaState *sta) :
worst_slacks_(sta->scenePathCount(), sta), worst_slacks_(sta->scenePathCount(), sta),
sta_(sta) sta_(sta)
@ -195,7 +195,7 @@ WorstSlack::sortQueue(PathAPIndex path_ap_index)
sort(vertices, slack_less); sort(vertices, slack_less);
int vertex_count = vertices.size(); int vertex_count = vertices.size();
int threshold_index = min(min_queue_size_, vertex_count - 1); int threshold_index = std::min(min_queue_size_, vertex_count - 1);
Vertex *threshold_vertex = vertices[threshold_index]; Vertex *threshold_vertex = vertices[threshold_index];
slack_threshold_ = search_->wnsSlack(threshold_vertex, path_ap_index); slack_threshold_ = search_->wnsSlack(threshold_vertex, path_ap_index);
debugPrint(debug_, "wns", 3, "threshold %s", debugPrint(debug_, "wns", 3, "threshold %s",

View File

@ -24,8 +24,8 @@
#include "WritePathSpice.hh" #include "WritePathSpice.hh"
#include <string>
#include <fstream> #include <fstream>
#include <string>
#include "Debug.hh" #include "Debug.hh"
#include "Error.hh" #include "Error.hh"
@ -50,11 +50,6 @@
namespace sta { namespace sta {
using std::string;
using std::ofstream;
using std::ifstream;
using std::max;
typedef int Stage; typedef int Stage;
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
@ -112,7 +107,7 @@ private:
// //
Stage stageFirst(); Stage stageFirst();
Stage stageLast(); Stage stageLast();
string stageName(Stage stage); std::string stageName(Stage stage);
int stageGateInputPathIndex(Stage stage); int stageGateInputPathIndex(Stage stage);
int stageDrvrPathIndex(Stage stage); int stageDrvrPathIndex(Stage stage);
int stageLoadPathIndex(Stage stage); int stageLoadPathIndex(Stage stage);
@ -219,7 +214,7 @@ void
WritePathSpice::writeHeader() WritePathSpice::writeHeader()
{ {
const Path *start_path = path_expanded_.startPath(); const Path *start_path = path_expanded_.startPath();
string title = stdstrPrint("Path from %s %s to %s %s", std::string title = stdstrPrint("Path from %s %s to %s %s",
network_->pathName(start_path->pin(this)), network_->pathName(start_path->pin(this)),
start_path->transition(this)->to_string().c_str(), start_path->transition(this)->to_string().c_str(),
network_->pathName(path_->pin(this)), network_->pathName(path_->pin(this)),
@ -291,7 +286,7 @@ WritePathSpice::writeStageInstances()
streamPrint(spice_stream_, "*****************\n\n"); streamPrint(spice_stream_, "*****************\n\n");
for (Stage stage = stageFirst(); stage <= stageLast(); stage++) { for (Stage stage = stageFirst(); stage <= stageLast(); stage++) {
string stage_name = stageName(stage); std::string stage_name = stageName(stage);
const char *stage_cname = stage_name.c_str(); const char *stage_cname = stage_name.c_str();
if (stage == stageFirst()) if (stage == stageFirst())
streamPrint(spice_stream_, "x%s %s %s %s\n", streamPrint(spice_stream_, "x%s %s %s %s\n",
@ -450,7 +445,7 @@ WritePathSpice::writeMeasureSlewStmt(Stage stage,
{ {
const Pin *pin = path->pin(this); const Pin *pin = path->pin(this);
const RiseFall *rf = path->transition(this); const RiseFall *rf = path->transition(this);
string prefix = stageName(stage); std::string prefix = stageName(stage);
writeMeasureSlewStmt(pin, rf, prefix); writeMeasureSlewStmt(pin, rf, prefix);
} }
@ -480,7 +475,7 @@ WritePathSpice::writeInputStage(Stage stage)
// External driver not handled. // External driver not handled.
const char *drvr_pin_name = stageDrvrPinName(stage); const char *drvr_pin_name = stageDrvrPinName(stage);
const char *load_pin_name = stageLoadPinName(stage); const char *load_pin_name = stageLoadPinName(stage);
string prefix = stageName(stage); std::string prefix = stageName(stage);
streamPrint(spice_stream_, ".subckt %s %s %s\n", streamPrint(spice_stream_, ".subckt %s %s %s\n",
prefix.c_str(), prefix.c_str(),
drvr_pin_name, drvr_pin_name,
@ -499,7 +494,7 @@ WritePathSpice::writeGateStage(Stage stage)
const char *drvr_pin_name = stageDrvrPinName(stage); const char *drvr_pin_name = stageDrvrPinName(stage);
const Pin *load_pin = stageLoadPin(stage); const Pin *load_pin = stageLoadPin(stage);
const char *load_pin_name = stageLoadPinName(stage); const char *load_pin_name = stageLoadPinName(stage);
string subckt_name = "stage" + std::to_string(stage); std::string subckt_name = "stage" + std::to_string(stage);
const Instance *inst = stageInstance(stage); const Instance *inst = stageInstance(stage);
LibertyPort *input_port = stageGateInputPort(stage); LibertyPort *input_port = stageGateInputPort(stage);
@ -614,10 +609,10 @@ WritePathSpice::stageLast()
return (path_expanded_.size() + 1) / 2; return (path_expanded_.size() + 1) / 2;
} }
string std::string
WritePathSpice::stageName(Stage stage) WritePathSpice::stageName(Stage stage)
{ {
string name; std::string name;
stringPrint(name, "stage%d", stage); stringPrint(name, "stage%d", stage);
return name; return name;
} }

View File

@ -26,6 +26,8 @@
#include <algorithm> // swap #include <algorithm> // swap
#include <filesystem> #include <filesystem>
#include <fstream>
#include <string>
#include "cudd.h" #include "cudd.h"
@ -50,12 +52,6 @@
namespace sta { namespace sta {
using std::string;
using std::ifstream;
using std::ofstream;
using std::swap;
using std::set;
Net * Net *
pinNet(const Pin *pin, pinNet(const Pin *pin,
const Network *network); const Network *network);
@ -68,7 +64,7 @@ public:
const char *what() const noexcept; const char *what() const noexcept;
protected: protected:
string what_; std::string what_;
}; };
SubcktEndsMissing::SubcktEndsMissing(const char *cell_name, SubcktEndsMissing::SubcktEndsMissing(const char *cell_name,
@ -137,7 +133,7 @@ WriteSpice::initPowerGnd()
} }
void void
WriteSpice::writeHeader(string &title, WriteSpice::writeHeader(std::string &title,
float max_time, float max_time,
float time_step) float time_step)
{ {
@ -159,21 +155,21 @@ WriteSpice::writePrintStmt(StdStringSeq &node_names)
{ {
streamPrint(spice_stream_, ".print tran"); streamPrint(spice_stream_, ".print tran");
if (ckt_sim_ == CircuitSim::xyce) { if (ckt_sim_ == CircuitSim::xyce) {
string csv_filename = replaceFileExt(spice_filename_, "csv"); std::string csv_filename = replaceFileExt(spice_filename_, "csv");
streamPrint(spice_stream_, " format=csv file=%s", csv_filename.c_str()); streamPrint(spice_stream_, " format=csv file=%s", csv_filename.c_str());
writeGnuplotFile(node_names); writeGnuplotFile(node_names);
} }
for (string &name : node_names) for (std::string &name : node_names)
streamPrint(spice_stream_, " v(%s)", name.c_str()); streamPrint(spice_stream_, " v(%s)", name.c_str());
streamPrint(spice_stream_, "\n\n"); streamPrint(spice_stream_, "\n\n");
} }
string std::string
WriteSpice::replaceFileExt(string filename, WriteSpice::replaceFileExt(std::string filename,
const char *ext) const char *ext)
{ {
size_t dot = filename.rfind('.'); size_t dot = filename.rfind('.');
string ext_filename = filename.substr(0, dot + 1); std::string ext_filename = filename.substr(0, dot + 1);
ext_filename += ext; ext_filename += ext;
return ext_filename; return ext_filename;
} }
@ -184,7 +180,7 @@ WriteSpice::writeGnuplotFile(StdStringSeq &node_nanes)
{ {
std::string gnuplot_filename = replaceFileExt(spice_filename_, "gnuplot"); std::string gnuplot_filename = replaceFileExt(spice_filename_, "gnuplot");
std::string csv_filename = replaceFileExt(spice_filename_, "csv"); std::string csv_filename = replaceFileExt(spice_filename_, "csv");
ofstream gnuplot_stream; std::ofstream gnuplot_stream;
gnuplot_stream.open(gnuplot_filename); gnuplot_stream.open(gnuplot_filename);
if (gnuplot_stream.is_open()) { if (gnuplot_stream.is_open()) {
streamPrint(gnuplot_stream, "set datafile separator ','\n"); streamPrint(gnuplot_stream, "set datafile separator ','\n");
@ -206,22 +202,21 @@ void
WriteSpice::writeSubckts(StdStringSet &cell_names) WriteSpice::writeSubckts(StdStringSet &cell_names)
{ {
findCellSubckts(cell_names); findCellSubckts(cell_names);
ifstream lib_subckts_stream(lib_subckt_filename_); std::ifstream lib_subckts_stream(lib_subckt_filename_);
if (lib_subckts_stream.is_open()) { if (lib_subckts_stream.is_open()) {
ofstream subckts_stream(subckt_filename_); std::ofstream subckts_stream(subckt_filename_);
if (subckts_stream.is_open()) { if (subckts_stream.is_open()) {
string line; std::string line;
while (getline(lib_subckts_stream, line)) { while (std::getline(lib_subckts_stream, line)) {
// .subckt <cell_name> [args..] // .subckt <cell_name> [args..]
StringVector tokens; StdStringSeq tokens = parseTokens(line, ' ');
split(line, " \t", tokens);
if (tokens.size() >= 2 if (tokens.size() >= 2
&& stringEqual(tokens[0].c_str(), ".subckt")) { && stringEqual(tokens[0].c_str(), ".subckt")) {
const char *cell_name = tokens[1].c_str(); const char *cell_name = tokens[1].c_str();
if (cell_names.contains(cell_name)) { if (cell_names.contains(cell_name)) {
subckts_stream << line << "\n"; subckts_stream << line << "\n";
bool found_ends = false; bool found_ends = false;
while (getline(lib_subckts_stream, line)) { while (std::getline(lib_subckts_stream, line)) {
subckts_stream << line << "\n"; subckts_stream << line << "\n";
if (stringBeginEqual(line.c_str(), ".ends")) { if (stringBeginEqual(line.c_str(), ".ends")) {
subckts_stream << "\n"; subckts_stream << "\n";
@ -240,13 +235,13 @@ WriteSpice::writeSubckts(StdStringSet &cell_names)
lib_subckts_stream.close(); lib_subckts_stream.close();
if (!cell_names.empty()) { if (!cell_names.empty()) {
string missing_cells; std::string missing_cells;
for (const string &cell_name : cell_names) { for (const std::string &cell_name : cell_names) {
missing_cells += "\n"; missing_cells += "\n";
missing_cells += cell_name; missing_cells += cell_name;
} }
report_->error(1605, "The subkct file %s is missing definitions for %s", report_->error(1605, "The subkct file %s is missing definitions for %s",
lib_subckt_filename_, lib_subckt_filename_,
missing_cells.c_str()); missing_cells.c_str());
} }
} }
@ -261,11 +256,11 @@ WriteSpice::writeSubckts(StdStringSet &cell_names)
void void
WriteSpice::recordSpicePortNames(const char *cell_name, WriteSpice::recordSpicePortNames(const char *cell_name,
StringVector &tokens) StdStringSeq &tokens)
{ {
LibertyCell *cell = network_->findLibertyCell(cell_name); LibertyCell *cell = network_->findLibertyCell(cell_name);
if (cell) { if (cell) {
StringVector &spice_port_names = cell_spice_port_names_[cell_name]; StdStringSeq &spice_port_names = cell_spice_port_names_[cell_name];
for (size_t i = 2; i < tokens.size(); i++) { for (size_t i = 2; i < tokens.size(); i++) {
const char *port_name = tokens[i].c_str(); const char *port_name = tokens[i].c_str();
LibertyPort *port = cell->findLibertyPort(port_name); LibertyPort *port = cell->findLibertyPort(port_name);
@ -285,27 +280,26 @@ WriteSpice::recordSpicePortNames(const char *cell_name,
void void
WriteSpice::findCellSubckts(StdStringSet &cell_names) WriteSpice::findCellSubckts(StdStringSet &cell_names)
{ {
ifstream lib_subckts_stream(lib_subckt_filename_); std::ifstream lib_subckts_stream(lib_subckt_filename_);
if (lib_subckts_stream.is_open()) { if (lib_subckts_stream.is_open()) {
string line; std::string line;
while (getline(lib_subckts_stream, line)) { while (std::getline(lib_subckts_stream, line)) {
// .subckt <cell_name> [args..] // .subckt <cell_name> [args..]
StringVector tokens; StdStringSeq tokens = parseTokens(line, ' ');
split(line, " \t", tokens);
if (tokens.size() >= 2 if (tokens.size() >= 2
&& stringEqual(tokens[0].c_str(), ".subckt")) { && stringEqual(tokens[0].c_str(), ".subckt")) {
const char *cell_name = tokens[1].c_str(); const char *cell_name = tokens[1].c_str();
if (cell_names.contains(cell_name)) { if (cell_names.contains(cell_name)) {
// Scan the subckt definition for subckt calls. // Scan the subckt definition for subckt calls.
string stmt; std::string stmt;
while (getline(lib_subckts_stream, line)) { while (std::getline(lib_subckts_stream, line)) {
if (line[0] == '+') if (line[0] == '+')
stmt += line.substr(1); stmt += line.substr(1);
else { else {
// Process previous statement. // Process previous statement.
if (tolower(stmt[0]) == 'x') { if (tolower(stmt[0]) == 'x') {
split(stmt, " \t", tokens); StdStringSeq tokens = parseTokens(line, ' ');
string &subckt_cell = tokens[tokens.size() - 1]; std::string &subckt_cell = tokens[tokens.size() - 1];
cell_names.insert(subckt_cell); cell_names.insert(subckt_cell);
} }
stmt = line; stmt = line;
@ -329,9 +323,9 @@ WriteSpice::writeSubcktInst(const Instance *inst)
const char *inst_name = network_->pathName(inst); const char *inst_name = network_->pathName(inst);
LibertyCell *cell = network_->libertyCell(inst); LibertyCell *cell = network_->libertyCell(inst);
const char *cell_name = cell->name(); const char *cell_name = cell->name();
StringVector &spice_port_names = cell_spice_port_names_[cell_name]; StdStringSeq &spice_port_names = cell_spice_port_names_[cell_name];
streamPrint(spice_stream_, "x%s", inst_name); streamPrint(spice_stream_, "x%s", inst_name);
for (string subckt_port_name : spice_port_names) { for (std::string subckt_port_name : spice_port_names) {
const char *subckt_port_cname = subckt_port_name.c_str(); const char *subckt_port_cname = subckt_port_name.c_str();
Pin *pin = network_->findPin(inst, subckt_port_cname); Pin *pin = network_->findPin(inst, subckt_port_cname);
LibertyPort *pg_port = cell->findLibertyPort(subckt_port_cname); LibertyPort *pg_port = cell->findLibertyPort(subckt_port_cname);
@ -357,11 +351,11 @@ WriteSpice::writeSubcktInstVoltSrcs(const Instance *inst,
{ {
LibertyCell *cell = network_->libertyCell(inst); LibertyCell *cell = network_->libertyCell(inst);
const char *cell_name = cell->name(); const char *cell_name = cell->name();
StringVector &spice_port_names = cell_spice_port_names_[cell_name]; StdStringSeq &spice_port_names = cell_spice_port_names_[cell_name];
const char *inst_name = network_->pathName(inst); const char *inst_name = network_->pathName(inst);
debugPrint(debug_, "write_spice", 2, "subckt %s", cell->name()); debugPrint(debug_, "write_spice", 2, "subckt %s", cell->name());
for (string subckt_port_sname : spice_port_names) { for (std::string subckt_port_sname : spice_port_names) {
const char *subckt_port_name = subckt_port_sname.c_str(); const char *subckt_port_name = subckt_port_sname.c_str();
LibertyPort *port = cell->findLibertyPort(subckt_port_name); LibertyPort *port = cell->findLibertyPort(subckt_port_name);
const Pin *pin = port ? network_->findPin(inst, port) : nullptr; const Pin *pin = port ? network_->findPin(inst, port) : nullptr;
@ -414,7 +408,7 @@ WriteSpice::writeVoltageSource(const char *inst_name,
const char *port_name, const char *port_name,
float voltage) float voltage)
{ {
string node_name = inst_name; std::string node_name = inst_name;
node_name += '/'; node_name += '/';
node_name += port_name; node_name += port_name;
writeVoltageSource(node_name.c_str(), voltage); writeVoltageSource(node_name.c_str(), voltage);
@ -538,7 +532,7 @@ WriteSpice::writeParasiticNetwork(const Pin *drvr_pin,
const Parasitic *parasitic, const Parasitic *parasitic,
const NetSet &coupling_nets) const NetSet &coupling_nets)
{ {
set<const Pin*> reachable_pins; std::set<const Pin*> reachable_pins;
// Sort resistors for consistent regression results. // Sort resistors for consistent regression results.
ParasiticResistorSeq resistors = parasitics_->resistors(parasitic); ParasiticResistorSeq resistors = parasitics_->resistors(parasitic);
sort(resistors, [this] (const ParasiticResistor *r1, sort(resistors, [this] (const ParasiticResistor *r1,
@ -616,8 +610,8 @@ WriteSpice::writeParasiticNetwork(const Pin *drvr_pin,
const Net *net1 = node1 ? parasitics_->net(node1, network_) : nullptr; const Net *net1 = node1 ? parasitics_->net(node1, network_) : nullptr;
const Net *net2 = node2 ? parasitics_->net(node2, network_) : nullptr; const Net *net2 = node2 ? parasitics_->net(node2, network_) : nullptr;
if (net2 == net) { if (net2 == net) {
swap(net1, net2); std::swap(net1, net2);
swap(node1, node2); std::swap(node1, node2);
} }
if (net2 && coupling_nets.contains(net2)) if (net2 && coupling_nets.contains(net2))
// Write half the capacitance because the coupled net will do the same. // Write half the capacitance because the coupled net will do the same.
@ -1038,7 +1032,7 @@ WriteSpice::writeMeasureDelayStmt(const Pin *from_pin,
const RiseFall *from_rf, const RiseFall *from_rf,
const Pin *to_pin, const Pin *to_pin,
const RiseFall *to_rf, const RiseFall *to_rf,
string prefix) std::string prefix)
{ {
const char *from_pin_name = network_->pathName(from_pin); const char *from_pin_name = network_->pathName(from_pin);
float from_threshold = power_voltage_ * default_library_->inputThreshold(from_rf); float from_threshold = power_voltage_ * default_library_->inputThreshold(from_rf);
@ -1064,7 +1058,7 @@ WriteSpice::writeMeasureDelayStmt(const Pin *from_pin,
void void
WriteSpice::writeMeasureSlewStmt(const Pin *pin, WriteSpice::writeMeasureSlewStmt(const Pin *pin,
const RiseFall *rf, const RiseFall *rf,
string prefix) std::string prefix)
{ {
const char *pin_name = network_->pathName(pin); const char *pin_name = network_->pathName(pin);
const char *spice_rf = spiceTrans(rf); const char *spice_rf = spiceTrans(rf);
@ -1110,7 +1104,7 @@ WriteSpice::spiceTrans(const RiseFall *rf)
// fprintf for c++ streams. // fprintf for c++ streams.
// Yes, I hate formatted output to ostream THAT much. // Yes, I hate formatted output to ostream THAT much.
void void
streamPrint(ofstream &stream, streamPrint(std::ofstream &stream,
const char *fmt, const char *fmt,
...) ...)
{ {

View File

@ -31,6 +31,7 @@
#include "StaState.hh" #include "StaState.hh"
#include "StringSet.hh" #include "StringSet.hh"
#include "StringUtil.hh"
#include "Liberty.hh" #include "Liberty.hh"
#include "GraphClass.hh" #include "GraphClass.hh"
#include "Parasitics.hh" #include "Parasitics.hh"
@ -40,9 +41,8 @@
namespace sta { namespace sta {
using ParasiticNodeMap = std::map<const ParasiticNode*, int>; using ParasiticNodeMap = std::map<const ParasiticNode*, int>;
using CellSpicePortNames = std::map<std::string, StringVector>; using CellSpicePortNames = std::map<std::string, StdStringSeq>;
using LibertyPortLogicValues = std::map<const LibertyPort*, LogicValue>; using LibertyPortLogicValues = std::map<const LibertyPort*, LogicValue>;
using StdStringSeq = std::vector<std::string>;
// Utilities for writing a spice deck. // Utilities for writing a spice deck.
class WriteSpice : public StaState class WriteSpice : public StaState
@ -69,7 +69,7 @@ protected:
void writeSubckts(StdStringSet &cell_names); void writeSubckts(StdStringSet &cell_names);
void findCellSubckts(StdStringSet &cell_names); void findCellSubckts(StdStringSet &cell_names);
void recordSpicePortNames(const char *cell_name, void recordSpicePortNames(const char *cell_name,
StringVector &tokens); StdStringSeq &tokens);
void writeSubcktInst(const Instance *inst); void writeSubcktInst(const Instance *inst);
void writeSubcktInstVoltSrcs(const Instance *inst, void writeSubcktInstVoltSrcs(const Instance *inst,
LibertyPortLogicValues &port_values, LibertyPortLogicValues &port_values,

View File

@ -26,55 +26,49 @@
#include "Xyce.hh" #include "Xyce.hh"
#include <fstream> #include <fstream>
#include <sstream>
#include <memory> #include <memory>
#include <sstream>
#include <string>
#include "Error.hh" #include "Error.hh"
namespace sta { namespace sta {
using std::string;
using std::ifstream;
using std::getline;
using std::stringstream;
using std::vector;
using std::make_shared;
void void
readXyceCsv(const char *csv_filename, readXyceCsv(const char *csv_filename,
// Return values. // Return values.
StdStringSeq &titles, StdStringSeq &titles,
WaveformSeq &waveforms) WaveformSeq &waveforms)
{ {
ifstream file(csv_filename); std::ifstream file(csv_filename);
if (file.is_open()) { if (file.is_open()) {
string line; std::string line;
// Read the header line. // Read the header line.
getline(file, line); std::getline(file, line);
stringstream ss(line); std::stringstream ss(line);
string field; std::string field;
size_t col = 0; size_t col = 0;
while (getline(ss, field, ',')) { while (std::getline(ss, field, ',')) {
// Skip TIME title. // Skip TIME title.
if (col > 0) if (col > 0)
titles.push_back(field); titles.push_back(field);
col++; col++;
} }
vector<FloatSeq> values(titles.size() + 1); std::vector<FloatSeq> values(titles.size() + 1);
while (getline(file, line)) { while (std::getline(file, line)) {
stringstream ss(line); std::stringstream ss(line);
size_t col = 0; size_t col = 0;
while (getline(ss, field, ',')) { while (std::getline(ss, field, ',')) {
float value = std::stof(field); float value = std::stof(field);
values[col].push_back(value); values[col].push_back(value);
col++; col++;
} }
} }
file.close(); file.close();
TableAxisPtr time_axis = make_shared<TableAxis>(TableAxisVariable::time, TableAxisPtr time_axis = std::make_shared<TableAxis>(TableAxisVariable::time,
std::move(values[0])); std::move(values[0]));
for (size_t var = 1; var < values.size(); var++) for (size_t var = 1; var < values.size(); var++)
waveforms.emplace_back(new FloatSeq(values[var]), time_axis); waveforms.emplace_back(new FloatSeq(values[var]), time_axis);
} }

View File

@ -27,11 +27,11 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "StringUtil.hh"
#include "TableModel.hh" #include "TableModel.hh"
namespace sta { namespace sta {
using StdStringSeq = std::vector<std::string>;
using WaveformSeq = std::vector<Table>; using WaveformSeq = std::vector<Table>;
void void

View File

@ -1,4 +1,4 @@
# Tests whether the is_memory attribute works for cells and libcells # Tests whether the is_memory attribute works for instances and cells
read_liberty gf180mcu_sram.lib.gz read_liberty gf180mcu_sram.lib.gz
read_liberty asap7_small.lib.gz read_liberty asap7_small.lib.gz
read_verilog get_is_memory.v read_verilog get_is_memory.v

Binary file not shown.

View File

@ -1,3 +1,4 @@
Warning 1195: liberty_arcs_one2one_1.lib line 45, port Y function size does not match port size.
Warning 1216: liberty_arcs_one2one_1.lib line 48, timing port A and related port Y are different sizes. Warning 1216: liberty_arcs_one2one_1.lib line 48, timing port A and related port Y are different sizes.
report_edges -from partial_wide_inv_cell/A[0] report_edges -from partial_wide_inv_cell/A[0]
A[0] -> Y[0] combinational A[0] -> Y[0] combinational

View File

@ -1,3 +1,4 @@
Warning 1195: liberty_arcs_one2one_2.lib line 45, port Y function size does not match port size.
Warning 1216: liberty_arcs_one2one_2.lib line 48, timing port A and related port Y are different sizes. Warning 1216: liberty_arcs_one2one_2.lib line 48, timing port A and related port Y are different sizes.
report_edges -to partial_wide_inv_cell/Y[0] report_edges -to partial_wide_inv_cell/Y[0]
A[0] -> Y[0] combinational A[0] -> Y[0] combinational

View File

@ -31,7 +31,7 @@ exec tclsh $0 ${1+"$@"}
# Directory containing tests. # Directory containing tests.
set test_dir [file dirname [file normalize [info script]]] set test_dir [file dirname [file normalize [info script]]]
set sta_dir [file normalize [file join $test_dir ".."]] set sta_dir [file dirname $test_dir]
source [file join $test_dir regression_vars.tcl] source [file join $test_dir regression_vars.tcl]
source [file join $test_dir regression.tcl] source [file join $test_dir regression.tcl]

View File

@ -7,4 +7,4 @@ link_design multi_sink
set verilog_file [make_result_file "verilog_write_escape.v"] set verilog_file [make_result_file "verilog_write_escape.v"]
write_verilog $verilog_file write_verilog $verilog_file
report_file $verilog_file report_file $verilog_file
read_verilog $verilog_file read_verilog $verilog_file

View File

@ -31,9 +31,6 @@
namespace sta { namespace sta {
using std::max;
using std::abs;
constexpr static float float_equal_tolerance = 1E-15F; constexpr static float float_equal_tolerance = 1E-15F;
bool bool
@ -43,18 +40,18 @@ fuzzyEqual(float v1,
if (v1 == v2) if (v1 == v2)
return true; return true;
else if (v1 == 0.0) else if (v1 == 0.0)
return abs(v2) < float_equal_tolerance; return std::abs(v2) < float_equal_tolerance;
else if (v2 == 0.0) else if (v2 == 0.0)
return abs(v1) < float_equal_tolerance; return std::abs(v1) < float_equal_tolerance;
else else
return abs(v1 - v2) < 1E-6F * max(abs(v1), abs(v2)); return std::abs(v1 - v2) < 1E-6F * std::max(std::abs(v1), std::abs(v2));
} }
bool bool
fuzzyZero(float v) fuzzyZero(float v)
{ {
return v == 0.0 return v == 0.0
|| abs(v) < float_equal_tolerance; || std::abs(v) < float_equal_tolerance;
} }
bool bool

Some files were not shown because too many files have changed in this diff Show More