sync
This commit is contained in:
parent
c6db5eb0ae
commit
a988588dac
|
|
@ -31,6 +31,10 @@ extern "C" {
|
|||
extern int Sta_Init(Tcl_Interp *interp);
|
||||
}
|
||||
|
||||
namespace sta {
|
||||
extern const char *tcl_inits[];
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
|
|
@ -44,7 +48,7 @@ main(int argc, char **argv)
|
|||
}
|
||||
else {
|
||||
Sta *sta = new Sta;
|
||||
staMain(sta, argc, argv, Sta_Init);
|
||||
staMain(sta, argc, argv, Sta_Init, sta::tcl_inits);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,10 +29,10 @@ typedef sta::Vector<SwigInitFunc> SwigInitFuncSeq;
|
|||
// "Arguments" passed to staTclAppInit.
|
||||
static int sta_argc;
|
||||
static char **sta_argv;
|
||||
static const char **sta_tcl_inits;
|
||||
static SwigInitFunc sta_swig_init;
|
||||
|
||||
static const char *init_filename = "[file join $env(HOME) .sta]";
|
||||
extern const char *tcl_inits[];
|
||||
|
||||
static void
|
||||
sourceTclFileEchoVerbose(const char *filename,
|
||||
|
|
@ -42,7 +42,8 @@ void
|
|||
staMain(Sta *sta,
|
||||
int argc,
|
||||
char **argv,
|
||||
SwigInitFunc swig_init)
|
||||
SwigInitFunc swig_init,
|
||||
const char *tcl_inits[])
|
||||
{
|
||||
initSta();
|
||||
|
||||
|
|
@ -55,7 +56,7 @@ staMain(Sta *sta,
|
|||
if (threads_exists)
|
||||
sta->setThreadCount(thread_count);
|
||||
|
||||
staSetupAppInit(argc, argv, swig_init);
|
||||
staSetupAppInit(argc, argv, swig_init, tcl_inits);
|
||||
// Set argc to 1 so Tcl_Main doesn't source any files.
|
||||
// Tcl_Main never returns.
|
||||
Tcl_Main(1, argv, staTclAppInit);
|
||||
|
|
@ -86,10 +87,12 @@ parseThreadsArg(int argc,
|
|||
void
|
||||
staSetupAppInit(int argc,
|
||||
char **argv,
|
||||
SwigInitFunc swig_init)
|
||||
SwigInitFunc swig_init,
|
||||
const char *tcl_inits[])
|
||||
{
|
||||
sta_argc = argc;
|
||||
sta_argv = argv;
|
||||
sta_tcl_inits = tcl_inits;
|
||||
sta_swig_init = swig_init;
|
||||
}
|
||||
|
||||
|
|
@ -110,7 +113,7 @@ staTclAppInit(Tcl_Interp *interp)
|
|||
sta->setTclInterp(interp);
|
||||
|
||||
// Eval encoded sta TCL sources.
|
||||
evalTclInit(interp, tcl_inits);
|
||||
evalTclInit(interp, sta_tcl_inits);
|
||||
|
||||
if (!findCmdLineFlag(argc, argv, "-no_splash"))
|
||||
Tcl_Eval(interp, "sta::show_splash");
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ struct Tcl_Interp;
|
|||
|
||||
namespace sta {
|
||||
|
||||
class Sta;
|
||||
typedef int (*SwigInitFunc)(Tcl_Interp *);
|
||||
|
||||
// The swig_init function is called to define the swig interface
|
||||
|
|
@ -29,17 +30,16 @@ void
|
|||
staMain(Sta *sta,
|
||||
int argc,
|
||||
char **argv,
|
||||
SwigInitFunc swig_init);
|
||||
SwigInitFunc swig_init,
|
||||
const char *tcl_inits[]);
|
||||
|
||||
// Set arguments passed to staTclAppInit inside the tcl interpreter.
|
||||
void
|
||||
staSetupAppInit(int argc,
|
||||
char **argv,
|
||||
SwigInitFunc swig_init);
|
||||
SwigInitFunc swig_init,
|
||||
const char *tcl_inits[]);
|
||||
|
||||
// The variable tcl_init is an implicit argument to this function that
|
||||
// provides the definitions for builtin tcl commands encoded by
|
||||
// etc/TclEncode.tcl.
|
||||
int
|
||||
staTclAppInit(Tcl_Interp *interp);
|
||||
|
||||
|
|
|
|||
|
|
@ -89,6 +89,14 @@ FuncExpr::deleteSubexprs()
|
|||
delete this;
|
||||
}
|
||||
|
||||
FuncExpr *
|
||||
FuncExpr::copy()
|
||||
{
|
||||
FuncExpr *left = left_ ? left_->copy() : nullptr;
|
||||
FuncExpr *right = right_ ? right_->copy() : nullptr;
|
||||
return new FuncExpr(op_, left, right, port_);
|
||||
}
|
||||
|
||||
LibertyPort *
|
||||
FuncExpr::port() const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@ public:
|
|||
static bool less(const FuncExpr *expr1,
|
||||
const FuncExpr *expr2);
|
||||
|
||||
// Deep copy.
|
||||
FuncExpr *copy();
|
||||
// Delete expression and all of its subexpressions.
|
||||
void deleteSubexprs();
|
||||
// op == op_port
|
||||
|
|
|
|||
|
|
@ -276,7 +276,7 @@ void
|
|||
ConcreteNetwork::deleteTopInstance()
|
||||
{
|
||||
if (top_instance_) {
|
||||
deleteInstance(reinterpret_cast<Instance*>(top_instance_));
|
||||
deleteInstance(top_instance_);
|
||||
top_instance_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
|
@ -296,7 +296,7 @@ ConcreteNetwork::deleteCellNetworkViews()
|
|||
Instance *
|
||||
ConcreteNetwork::topInstance() const
|
||||
{
|
||||
return reinterpret_cast<Instance*>(top_instance_);
|
||||
return top_instance_;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
|
@ -404,9 +404,10 @@ ConcreteNetwork::libertyLibraryIterator() const
|
|||
////////////////////////////////////////////////////////////////
|
||||
|
||||
Library *
|
||||
ConcreteNetwork::makeLibrary(const char *name)
|
||||
ConcreteNetwork::makeLibrary(const char *name,
|
||||
const char *filename)
|
||||
{
|
||||
ConcreteLibrary *library = new ConcreteLibrary(name, nullptr);
|
||||
ConcreteLibrary *library = new ConcreteLibrary(name, filename);
|
||||
addLibrary(library);
|
||||
return reinterpret_cast<Library*>(library);
|
||||
}
|
||||
|
|
@ -1120,7 +1121,7 @@ ConcreteNetwork::makeConcreteInstance(ConcreteCell *cell,
|
|||
{
|
||||
ConcreteInstance *cparent =
|
||||
reinterpret_cast<ConcreteInstance*>(parent);
|
||||
ConcreteInstance *inst = new ConcreteInstance(name, cell, cparent);
|
||||
ConcreteInstance *inst = new ConcreteInstance(cell, name, cparent);
|
||||
if (parent)
|
||||
cparent->addChild(inst);
|
||||
return reinterpret_cast<Instance*>(inst);
|
||||
|
|
@ -1257,7 +1258,7 @@ ConcreteNetwork::connect(Instance *inst,
|
|||
cpin = new ConcretePin(cinst, cport, cnet);
|
||||
cinst->addPin(cpin);
|
||||
}
|
||||
if (cinst == top_instance_) {
|
||||
if (inst == top_instance_) {
|
||||
// makeTerm
|
||||
ConcreteTerm *cterm = new ConcreteTerm(cpin, cnet);
|
||||
cnet->addTerm(cterm);
|
||||
|
|
@ -1296,7 +1297,7 @@ void
|
|||
ConcreteNetwork::disconnectPin(Pin *pin)
|
||||
{
|
||||
ConcretePin *cpin = reinterpret_cast<ConcretePin*>(pin);
|
||||
if (cpin->instance() == top_instance_) {
|
||||
if (reinterpret_cast<Instance*>(cpin->instance()) == top_instance_) {
|
||||
ConcreteTerm *cterm = cpin->term_;
|
||||
if (cterm) {
|
||||
ConcreteNet *cnet = cterm->net_;
|
||||
|
|
@ -1450,19 +1451,26 @@ ConcreteNetwork::visitConnectedPins(const Net *net,
|
|||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
ConcreteInstance::ConcreteInstance(const char *name,
|
||||
ConcreteCell *cell,
|
||||
ConcreteInstance::ConcreteInstance(ConcreteCell *cell,
|
||||
const char *name,
|
||||
ConcreteInstance *parent) :
|
||||
name_(stringCopy(name)),
|
||||
cell_(cell),
|
||||
name_(stringCopy(name)),
|
||||
parent_(parent),
|
||||
children_(nullptr),
|
||||
nets_(nullptr)
|
||||
{
|
||||
int pin_count = reinterpret_cast<ConcreteCell*>(cell)->portBitCount();
|
||||
pins_ = new ConcretePin*[pin_count];
|
||||
for (int i = 0; i < pin_count; i++)
|
||||
pins_[i] = nullptr;
|
||||
initPins();
|
||||
}
|
||||
|
||||
void
|
||||
ConcreteInstance::initPins()
|
||||
{
|
||||
int pin_count = reinterpret_cast<ConcreteCell*>(cell_)->portBitCount();
|
||||
if (pin_count)
|
||||
pins_ = new ConcretePin*[pin_count]{nullptr};
|
||||
else
|
||||
pins_ = nullptr;
|
||||
}
|
||||
|
||||
ConcreteInstance::~ConcreteInstance()
|
||||
|
|
@ -1789,10 +1797,10 @@ ConcreteNetwork::readNetlistBefore()
|
|||
}
|
||||
|
||||
void
|
||||
ConcreteNetwork::setTopInstance(ConcreteInstance *top_inst)
|
||||
ConcreteNetwork::setTopInstance(Instance *top_inst)
|
||||
{
|
||||
if (top_instance_) {
|
||||
deleteInstance(reinterpret_cast<Instance*>(top_instance_));
|
||||
deleteInstance(top_instance_);
|
||||
clearConstantNets();
|
||||
clearNetDrvPinrMap();
|
||||
}
|
||||
|
|
@ -1815,10 +1823,7 @@ ConcreteNetwork::linkNetwork(const char *top_cell_name,
|
|||
deleteTopInstance();
|
||||
Cell *top_cell = findAnyCell(top_cell_name);
|
||||
if (top_cell) {
|
||||
top_instance_ =
|
||||
reinterpret_cast<ConcreteInstance*>(link_func_(top_cell,
|
||||
make_black_boxes,
|
||||
report, this));
|
||||
top_instance_ = link_func_(top_cell, make_black_boxes, report, this);
|
||||
return top_instance_ != nullptr;
|
||||
}
|
||||
else {
|
||||
|
|
|
|||
|
|
@ -155,7 +155,8 @@ public:
|
|||
LogicValue value);
|
||||
|
||||
// Edit methods.
|
||||
virtual Library *makeLibrary(const char *name);
|
||||
virtual Library *makeLibrary(const char *name,
|
||||
const char *filename);
|
||||
virtual LibertyLibrary *makeLibertyLibrary(const char *name,
|
||||
const char *filename);
|
||||
virtual Cell *makeCell(Library *library,
|
||||
|
|
@ -221,7 +222,7 @@ public:
|
|||
|
||||
virtual void readNetlistBefore();
|
||||
virtual void setLinkFunc(LinkNetworkFunc *link);
|
||||
void setTopInstance(ConcreteInstance *top_inst);
|
||||
void setTopInstance(Instance *top_inst);
|
||||
|
||||
using Network::netIterator;
|
||||
using Network::findPin;
|
||||
|
|
@ -250,7 +251,7 @@ protected:
|
|||
// Cell lookup search order sequence.
|
||||
ConcreteLibrarySeq library_seq_;
|
||||
ConcreteLibraryMap library_map_;
|
||||
ConcreteInstance *top_instance_;
|
||||
Instance *top_instance_;
|
||||
NetSet constant_nets_[2]; // LogicValue::zero/one
|
||||
LinkNetworkFunc *link_func_;
|
||||
CellNetworkViewMap cell_network_view_map_;
|
||||
|
|
@ -284,15 +285,16 @@ public:
|
|||
ConcreteNet *net);
|
||||
void deleteNet(ConcreteNet *net);
|
||||
void setCell(LibertyCell *cell);
|
||||
void initPins();
|
||||
|
||||
private:
|
||||
ConcreteInstance(const char *name,
|
||||
ConcreteCell *cell,
|
||||
protected:
|
||||
ConcreteInstance(ConcreteCell *cell,
|
||||
const char *name,
|
||||
ConcreteInstance *parent);
|
||||
~ConcreteInstance();
|
||||
|
||||
const char *name_;
|
||||
ConcreteCell *cell_;
|
||||
const char *name_;
|
||||
ConcreteInstance *parent_;
|
||||
// Array of pins indexed by pin->port->index().
|
||||
ConcretePin **pins_;
|
||||
|
|
@ -373,12 +375,13 @@ public:
|
|||
void mergeInto(ConcreteNet *net);
|
||||
ConcreteNet *mergedInto() { return merged_into_; }
|
||||
|
||||
private:
|
||||
protected:
|
||||
DISALLOW_COPY_AND_ASSIGN(ConcreteNet);
|
||||
ConcreteNet(const char *name,
|
||||
ConcreteInstance *instance);
|
||||
virtual ~ConcreteNet();
|
||||
|
||||
private:
|
||||
const char *name_;
|
||||
ConcreteInstance *instance_;
|
||||
// Pointer to head of linked list of pins.
|
||||
|
|
|
|||
|
|
@ -520,7 +520,8 @@ public:
|
|||
// Called before reading a netlist to delete any previously linked network.
|
||||
virtual void readNetlistBefore() = 0;
|
||||
virtual void setLinkFunc(LinkNetworkFunc *link) = 0;
|
||||
virtual Library *makeLibrary(const char *name) = 0;
|
||||
virtual Library *makeLibrary(const char *name,
|
||||
const char *filename) = 0;
|
||||
// Search the libraries in read order for a cell by name.
|
||||
virtual Cell *findAnyCell(const char *name) = 0;
|
||||
virtual Cell *makeCell(Library *library,
|
||||
|
|
|
|||
105
search/Power.cc
105
search/Power.cc
|
|
@ -405,6 +405,7 @@ Power::ensureActivities()
|
|||
// Propagate activiities across register D->Q.
|
||||
seedRegOutputActivities(reg, bfs);
|
||||
}
|
||||
delete regs;
|
||||
visitor.init();
|
||||
bfs.visit(levelize_->maxLevel(), &visitor);
|
||||
}
|
||||
|
|
@ -546,7 +547,6 @@ Power::findInternalPower(const Pin *to_pin,
|
|||
debugPrint1(debug_, "power", 2, " cap = %s\n",
|
||||
units_->capacitanceUnit()->asString(load_cap));
|
||||
debugPrint0(debug_, "power", 2, " when act/ns duty energy power\n");
|
||||
float input_duty_sum = inputDutySum(inst);
|
||||
float internal = 0.0;
|
||||
LibertyCellInternalPowerIterator pwr_iter(cell);
|
||||
while (pwr_iter.hasNext()) {
|
||||
|
|
@ -554,26 +554,35 @@ Power::findInternalPower(const Pin *to_pin,
|
|||
if (pwr->port() == to_port) {
|
||||
const char *related_pg_pin = pwr->relatedPgPin();
|
||||
const LibertyPort *from_port = pwr->relatedPort();
|
||||
if (from_port == nullptr)
|
||||
// Input port internal power.
|
||||
from_port = to_port;
|
||||
FuncExpr *when = pwr->when();
|
||||
FuncExpr *infered_when = nullptr;
|
||||
if (from_port) {
|
||||
if (when == nullptr) {
|
||||
FuncExpr *func = to_port->function();
|
||||
if (func)
|
||||
infered_when = inferedWhen(func, from_port);
|
||||
}
|
||||
}
|
||||
else
|
||||
from_port = to_port;
|
||||
// If all the "when" clauses exist VSS internal power is ignored.
|
||||
if ((when && internalPowerMissingWhen(cell, to_port, related_pg_pin))
|
||||
|| pgNameVoltage(cell, related_pg_pin, dcalc_ap) != 0.0) {
|
||||
const Pin *from_pin = network_->findPin(inst, from_port);
|
||||
Vertex *from_vertex = graph_->pinLoadVertex(from_pin);
|
||||
float duty;
|
||||
if (when)
|
||||
if (infered_when) {
|
||||
PwrActivity from_activity = findActivity(from_pin);
|
||||
PwrActivity to_activity = findActivity(to_pin);
|
||||
float duty1 = evalActivity(infered_when, inst).duty();
|
||||
duty = from_activity.activity() / to_activity.activity() * duty1;
|
||||
}
|
||||
else if (when)
|
||||
duty = evalActivity(when, inst).duty();
|
||||
else if (search_->isClock(from_vertex))
|
||||
duty = 1.0;
|
||||
else {
|
||||
PwrActivity from_activity = findActivity(from_pin);
|
||||
PwrActivity to_activity = findActivity(to_pin);
|
||||
float duty1 = input_duty_sum - from_activity.duty();
|
||||
duty = from_activity.activity() * (1.0 - duty1) / to_activity.activity();
|
||||
}
|
||||
else
|
||||
duty = 0.5;
|
||||
float port_energy = 0.0;
|
||||
TransRiseFallIterator tr_iter;
|
||||
while (tr_iter.hasNext()) {
|
||||
|
|
@ -596,7 +605,7 @@ Power::findInternalPower(const Pin *to_pin,
|
|||
debugPrint8(debug_, "power", 2, " %s -> %s %s %.2f %.2f %9.2e %9.2e %s\n",
|
||||
from_port->name(),
|
||||
to_port->name(),
|
||||
pwr->when() ? pwr->when()->asString() : " ",
|
||||
when ? when->asString() : (infered_when ? infered_when->asString() : " "),
|
||||
to_activity.activity() * 1e-9,
|
||||
duty,
|
||||
port_energy,
|
||||
|
|
@ -604,11 +613,69 @@ Power::findInternalPower(const Pin *to_pin,
|
|||
related_pg_pin ? related_pg_pin : "no pg_pin");
|
||||
internal += port_internal;
|
||||
}
|
||||
if (infered_when)
|
||||
infered_when->deleteSubexprs();
|
||||
}
|
||||
}
|
||||
result.setInternal(result.internal() + internal);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
static bool
|
||||
isPortRef(FuncExpr *expr,
|
||||
const LibertyPort *port)
|
||||
{
|
||||
return (expr->op() == FuncExpr::op_port
|
||||
&& expr->port() == port)
|
||||
|| (expr->op() == FuncExpr::op_not
|
||||
&& expr->left()->op() == FuncExpr::op_port
|
||||
&& expr->left()->port() == port);
|
||||
}
|
||||
|
||||
static FuncExpr *
|
||||
negate(FuncExpr *expr)
|
||||
{
|
||||
if (expr->op() == FuncExpr::op_not)
|
||||
return expr->left()->copy();
|
||||
else
|
||||
return FuncExpr::makeNot(expr->copy());
|
||||
}
|
||||
|
||||
FuncExpr *
|
||||
Power::inferedWhen(FuncExpr *expr,
|
||||
const LibertyPort *from_port)
|
||||
{
|
||||
switch (expr->op()) {
|
||||
case FuncExpr::op_port: {
|
||||
if (expr->port() == from_port)
|
||||
return FuncExpr::makeOne();
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
case FuncExpr::op_not:
|
||||
return inferedWhen(expr->left(), from_port);
|
||||
case FuncExpr::op_or:
|
||||
case FuncExpr::op_xor: {
|
||||
if (isPortRef(expr->left(), from_port))
|
||||
return negate(expr->right());
|
||||
if (isPortRef(expr->right(), from_port))
|
||||
return negate(expr->left());
|
||||
}
|
||||
case FuncExpr::op_and: {
|
||||
if (isPortRef(expr->left(), from_port))
|
||||
return expr->right()->copy();
|
||||
if (isPortRef(expr->right(), from_port))
|
||||
return expr->left()->copy();
|
||||
}
|
||||
case FuncExpr::op_one:
|
||||
case FuncExpr::op_zero:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
// Return true if some a "when" clause for the internal power to_port
|
||||
// is missing.
|
||||
bool
|
||||
|
|
@ -645,20 +712,6 @@ funcExprPortCount(FuncExpr *expr)
|
|||
return port_count;
|
||||
}
|
||||
|
||||
float
|
||||
Power::inputDutySum(const Instance *inst)
|
||||
{
|
||||
float duty_sum = 0.0;
|
||||
InstancePinIterator *pin_iter = network_->pinIterator(inst);
|
||||
while (pin_iter->hasNext()) {
|
||||
const Pin *pin = pin_iter->next();
|
||||
if (network_->direction(pin)->isAnyInput())
|
||||
duty_sum += findClkedActivity(pin).duty();
|
||||
}
|
||||
delete pin_iter;
|
||||
return duty_sum;
|
||||
}
|
||||
|
||||
void
|
||||
Power::findLeakagePower(const Instance *,
|
||||
LibertyCell *cell,
|
||||
|
|
|
|||
|
|
@ -147,10 +147,11 @@ protected:
|
|||
BfsFwdIterator &bfs);
|
||||
PwrActivity evalActivity(FuncExpr *expr,
|
||||
const Instance *inst);
|
||||
float inputDutySum(const Instance *inst);
|
||||
bool internalPowerMissingWhen(LibertyCell *cell,
|
||||
const LibertyPort *to_port,
|
||||
const char *related_pg_pin);
|
||||
FuncExpr *inferedWhen(FuncExpr *expr,
|
||||
const LibertyPort *from_port);
|
||||
|
||||
private:
|
||||
PwrActivity global_activity_;
|
||||
|
|
|
|||
|
|
@ -2652,7 +2652,6 @@ PropertyValue
|
|||
pin_property(const Pin *pin,
|
||||
const char *property)
|
||||
{
|
||||
cmdGraph();
|
||||
return getProperty(pin, property, Sta::sta());
|
||||
}
|
||||
|
||||
|
|
@ -2660,7 +2659,6 @@ PropertyValue
|
|||
instance_property(const Instance *inst,
|
||||
const char *property)
|
||||
{
|
||||
cmdGraph();
|
||||
return getProperty(inst, property, Sta::sta());
|
||||
}
|
||||
|
||||
|
|
@ -2668,7 +2666,6 @@ PropertyValue
|
|||
net_property(const Net *net,
|
||||
const char *property)
|
||||
{
|
||||
cmdGraph();
|
||||
return getProperty(net, property, Sta::sta());
|
||||
}
|
||||
|
||||
|
|
@ -2676,7 +2673,6 @@ PropertyValue
|
|||
port_property(const Port *port,
|
||||
const char *property)
|
||||
{
|
||||
cmdGraph();
|
||||
return getProperty(port, property, Sta::sta());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,8 +14,6 @@
|
|||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
# Network commands.
|
||||
|
||||
namespace eval sta {
|
||||
|
||||
# Defined by SWIG interface Verilog.i.
|
||||
|
|
|
|||
|
|
@ -204,7 +204,7 @@ VerilogReader::init(const char *filename)
|
|||
|
||||
library_ = network_->findLibrary("verilog");
|
||||
if (library_ == nullptr)
|
||||
library_ = network_->makeLibrary("verilog");
|
||||
library_ = network_->makeLibrary("verilog", nullptr);
|
||||
|
||||
report_stmt_stats_ = debugCheck(debug_, "verilog", 1);
|
||||
module_count_ = 0;
|
||||
|
|
|
|||
Loading…
Reference in New Issue