Merge branch 'parallaxsw:master' into libarcs_smallfix
This commit is contained in:
commit
28177e93f7
BIN
doc/OpenSTA.odt
BIN
doc/OpenSTA.odt
Binary file not shown.
BIN
doc/OpenSTA.pdf
BIN
doc/OpenSTA.pdf
Binary file not shown.
|
|
@ -541,6 +541,8 @@ public:
|
||||||
// for all the defined corners.
|
// for all the defined corners.
|
||||||
static void checkLibertyCorners();
|
static void checkLibertyCorners();
|
||||||
void ensureVoltageWaveforms(const DcalcAnalysisPtSeq &dcalc_aps);
|
void ensureVoltageWaveforms(const DcalcAnalysisPtSeq &dcalc_aps);
|
||||||
|
const char *footprint() const;
|
||||||
|
void setFootprint(const char *footprint);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void addPort(ConcretePort *port);
|
void addPort(ConcretePort *port);
|
||||||
|
|
@ -631,6 +633,7 @@ protected:
|
||||||
bool has_internal_ports_;
|
bool has_internal_ports_;
|
||||||
bool have_voltage_waveforms_;
|
bool have_voltage_waveforms_;
|
||||||
std::mutex waveform_lock_;
|
std::mutex waveform_lock_;
|
||||||
|
const char *footprint_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class LibertyLibrary;
|
friend class LibertyLibrary;
|
||||||
|
|
|
||||||
|
|
@ -154,6 +154,8 @@ public:
|
||||||
bool includes_pin_caps,
|
bool includes_pin_caps,
|
||||||
const ParasiticAnalysisPt *ap) = 0;
|
const ParasiticAnalysisPt *ap) = 0;
|
||||||
virtual ParasiticNodeSeq nodes(const Parasitic *parasitic) const = 0;
|
virtual ParasiticNodeSeq nodes(const Parasitic *parasitic) const = 0;
|
||||||
|
virtual void report(const Parasitic *parasitic) const;
|
||||||
|
virtual const Net *net(const Parasitic *parasitic) const = 0;
|
||||||
virtual ParasiticResistorSeq resistors(const Parasitic *parasitic) const = 0;
|
virtual ParasiticResistorSeq resistors(const Parasitic *parasitic) const = 0;
|
||||||
virtual ParasiticCapacitorSeq capacitors(const Parasitic *parasitic) const = 0;
|
virtual ParasiticCapacitorSeq capacitors(const Parasitic *parasitic) const = 0;
|
||||||
// Delete parasitic network if it exists.
|
// Delete parasitic network if it exists.
|
||||||
|
|
|
||||||
|
|
@ -768,8 +768,8 @@ LibertyLibrary::makeCornerMap(LibertyCell *cell1,
|
||||||
cell2->name());
|
cell2->name());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto arc_set1 : cell1->timing_arc_sets_) {
|
for (TimingArcSet *arc_set1 : cell1->timing_arc_sets_) {
|
||||||
auto arc_set2 = cell2->findTimingArcSet(arc_set1);
|
TimingArcSet *arc_set2 = cell2->findTimingArcSet(arc_set1);
|
||||||
if (arc_set2) {
|
if (arc_set2) {
|
||||||
if (link) {
|
if (link) {
|
||||||
const TimingArcSeq &arcs1 = arc_set1->arcs();
|
const TimingArcSeq &arcs1 = arc_set1->arcs();
|
||||||
|
|
@ -789,7 +789,7 @@ LibertyLibrary::makeCornerMap(LibertyCell *cell1,
|
||||||
report->warn(1111, "cell %s/%s %s -> %s timing group %s not found in cell %s/%s.",
|
report->warn(1111, "cell %s/%s %s -> %s timing group %s not found in cell %s/%s.",
|
||||||
cell1->library()->name(),
|
cell1->library()->name(),
|
||||||
cell1->name(),
|
cell1->name(),
|
||||||
arc_set1->from()->name(),
|
arc_set1->from() ? arc_set1->from()->name() : "",
|
||||||
arc_set1->to()->name(),
|
arc_set1->to()->name(),
|
||||||
arc_set1->role()->asString(),
|
arc_set1->role()->asString(),
|
||||||
cell2->library()->name(),
|
cell2->library()->name(),
|
||||||
|
|
@ -940,7 +940,8 @@ LibertyCell::LibertyCell(LibertyLibrary *library,
|
||||||
leakage_power_(0.0),
|
leakage_power_(0.0),
|
||||||
leakage_power_exists_(false),
|
leakage_power_exists_(false),
|
||||||
has_internal_ports_(false),
|
has_internal_ports_(false),
|
||||||
have_voltage_waveforms_(false)
|
have_voltage_waveforms_(false),
|
||||||
|
footprint_(nullptr)
|
||||||
{
|
{
|
||||||
liberty_cell_ = this;
|
liberty_cell_ = this;
|
||||||
}
|
}
|
||||||
|
|
@ -968,6 +969,8 @@ LibertyCell::~LibertyCell()
|
||||||
ocv_derate_map_.deleteContents();
|
ocv_derate_map_.deleteContents();
|
||||||
|
|
||||||
pg_port_map_.deleteContents();
|
pg_port_map_.deleteContents();
|
||||||
|
|
||||||
|
stringDelete(footprint_);
|
||||||
}
|
}
|
||||||
|
|
||||||
LibertyPort *
|
LibertyPort *
|
||||||
|
|
@ -1989,6 +1992,18 @@ LibertyCell::ensureVoltageWaveforms(const DcalcAnalysisPtSeq &dcalc_aps)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LibertyCell::setFootprint(const char *footprint)
|
||||||
|
{
|
||||||
|
footprint_ = stringCopy(footprint);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char*
|
||||||
|
LibertyCell::footprint() const
|
||||||
|
{
|
||||||
|
return footprint_;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
LibertyCellPortIterator::LibertyCellPortIterator(const LibertyCell *cell) :
|
LibertyCellPortIterator::LibertyCellPortIterator(const LibertyCell *cell) :
|
||||||
|
|
|
||||||
|
|
@ -310,6 +310,7 @@ LibertyReader::defineVisitors()
|
||||||
defineAttrVisitor("switch_cell_type", &LibertyReader::visitSwitchCellType);
|
defineAttrVisitor("switch_cell_type", &LibertyReader::visitSwitchCellType);
|
||||||
defineAttrVisitor("interface_timing", &LibertyReader::visitInterfaceTiming);
|
defineAttrVisitor("interface_timing", &LibertyReader::visitInterfaceTiming);
|
||||||
defineAttrVisitor("scaling_factors", &LibertyReader::visitScalingFactors);
|
defineAttrVisitor("scaling_factors", &LibertyReader::visitScalingFactors);
|
||||||
|
defineAttrVisitor("cell_footprint", &LibertyReader::visitCellFootprint);
|
||||||
|
|
||||||
// Pins
|
// Pins
|
||||||
defineGroupVisitor("pin", &LibertyReader::beginPin,&LibertyReader::endPin);
|
defineGroupVisitor("pin", &LibertyReader::beginPin,&LibertyReader::endPin);
|
||||||
|
|
@ -3065,6 +3066,16 @@ LibertyReader::visitClockGatingIntegratedCell(LibertyAttr *attr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LibertyReader::visitCellFootprint(LibertyAttr *attr)
|
||||||
|
{
|
||||||
|
if (cell_) {
|
||||||
|
const char *footprint = getAttrString(attr);
|
||||||
|
if (footprint)
|
||||||
|
cell_->setFootprint(stringCopy(footprint));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -205,6 +205,7 @@ public:
|
||||||
virtual void visitInterfaceTiming(LibertyAttr *attr);
|
virtual void visitInterfaceTiming(LibertyAttr *attr);
|
||||||
virtual void visitScalingFactors(LibertyAttr *attr);
|
virtual void visitScalingFactors(LibertyAttr *attr);
|
||||||
virtual void visitCellLeakagePower(LibertyAttr *attr);
|
virtual void visitCellLeakagePower(LibertyAttr *attr);
|
||||||
|
virtual void visitCellFootprint(LibertyAttr *attr);
|
||||||
|
|
||||||
virtual void beginPin(LibertyGroup *group);
|
virtual void beginPin(LibertyGroup *group);
|
||||||
virtual void endPin(LibertyGroup *group);
|
virtual void endPin(LibertyGroup *group);
|
||||||
|
|
|
||||||
|
|
@ -596,13 +596,14 @@ ConcreteParasiticNetwork::findParasiticNode(const Pin *pin) const
|
||||||
ConcreteParasiticNode *
|
ConcreteParasiticNode *
|
||||||
ConcreteParasiticNetwork::ensureParasiticNode(const Net *net,
|
ConcreteParasiticNetwork::ensureParasiticNode(const Net *net,
|
||||||
int id,
|
int id,
|
||||||
const Network *)
|
const Network *network)
|
||||||
{
|
{
|
||||||
ConcreteParasiticNode *node;
|
ConcreteParasiticNode *node;
|
||||||
NetIdPair net_id(net, id);
|
NetIdPair net_id(net, id);
|
||||||
auto id_node = sub_nodes_.find(net_id);
|
auto id_node = sub_nodes_.find(net_id);
|
||||||
if (id_node == sub_nodes_.end()) {
|
if (id_node == sub_nodes_.end()) {
|
||||||
node = new ConcreteParasiticNode(net, id, net != net_);
|
Net *net1 = network->highestNetAbove(const_cast<Net*>(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_ = max((int) max_node_id_, id);
|
||||||
|
|
@ -1287,6 +1288,17 @@ ConcreteParasitics::deleteParasiticNetworks(const Net *net)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Net *
|
||||||
|
ConcreteParasitics::net(const Parasitic *parasitic) const
|
||||||
|
{
|
||||||
|
const ConcreteParasiticNetwork *cparasitic =
|
||||||
|
static_cast<const ConcreteParasiticNetwork*>(parasitic);
|
||||||
|
if (cparasitic->isParasiticNetwork())
|
||||||
|
return cparasitic->net();
|
||||||
|
else
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ConcreteParasitics::includesPinCaps(const Parasitic *parasitic) const
|
ConcreteParasitics::includesPinCaps(const Parasitic *parasitic) const
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -112,6 +112,7 @@ public:
|
||||||
void deleteParasiticNetwork(const Net *net,
|
void deleteParasiticNetwork(const Net *net,
|
||||||
const ParasiticAnalysisPt *ap) override;
|
const ParasiticAnalysisPt *ap) override;
|
||||||
void deleteParasiticNetworks(const Net *net) override;
|
void deleteParasiticNetworks(const Net *net) override;
|
||||||
|
const Net *net(const Parasitic *parasitic) const override;
|
||||||
bool includesPinCaps(const Parasitic *parasitic) const override;
|
bool includesPinCaps(const Parasitic *parasitic) const override;
|
||||||
ParasiticNode *findParasiticNode(Parasitic *parasitic,
|
ParasiticNode *findParasiticNode(Parasitic *parasitic,
|
||||||
const Net *net,
|
const Net *net,
|
||||||
|
|
|
||||||
|
|
@ -207,7 +207,7 @@ public:
|
||||||
const Network *network);
|
const Network *network);
|
||||||
virtual ~ConcreteParasiticNetwork();
|
virtual ~ConcreteParasiticNetwork();
|
||||||
virtual bool isParasiticNetwork() const { return true; }
|
virtual bool isParasiticNetwork() const { return true; }
|
||||||
const Net *net() { return net_; }
|
const Net *net() const { return net_; }
|
||||||
bool includesPinCaps() const { return includes_pin_caps_; }
|
bool includesPinCaps() const { return includes_pin_caps_; }
|
||||||
ConcreteParasiticNode *findParasiticNode(const Net *net,
|
ConcreteParasiticNode *findParasiticNode(const Net *net,
|
||||||
int id,
|
int id,
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
#include "Error.hh"
|
#include "Error.hh"
|
||||||
#include "Debug.hh"
|
#include "Debug.hh"
|
||||||
|
#include "Units.hh"
|
||||||
#include "Liberty.hh"
|
#include "Liberty.hh"
|
||||||
#include "Wireload.hh"
|
#include "Wireload.hh"
|
||||||
#include "Network.hh"
|
#include "Network.hh"
|
||||||
|
|
@ -34,6 +35,47 @@ Parasitics::Parasitics(StaState *sta) :
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Parasitics::report(const Parasitic *parasitic) const
|
||||||
|
{
|
||||||
|
if (isParasiticNetwork(parasitic)) {
|
||||||
|
const Unit *cap_unit = units_->capacitanceUnit();
|
||||||
|
report_->reportLine("Net %s %s",
|
||||||
|
network_->pathName(net(parasitic)),
|
||||||
|
cap_unit->asString(capacitance(parasitic)));
|
||||||
|
report_->reportLine("Nodes:");
|
||||||
|
for (ParasiticNode *node : nodes(parasitic))
|
||||||
|
report_->reportLine("%s%s %s",
|
||||||
|
name(node),
|
||||||
|
isExternal(node) ? " (ext)" : "",
|
||||||
|
cap_unit->asString(nodeGndCap(node)));
|
||||||
|
report_->reportLine("Resistors:");
|
||||||
|
for (ParasiticResistor *res : resistors(parasitic)) {
|
||||||
|
ParasiticNode *node1 = this->node1(res);
|
||||||
|
ParasiticNode *node2 = this->node2(res);
|
||||||
|
report_->reportLine("%zu %s%s %s%s %s",
|
||||||
|
id(res),
|
||||||
|
name(node1),
|
||||||
|
isExternal(node1) ? " (ext)" : "",
|
||||||
|
name(node2),
|
||||||
|
isExternal(node2) ? " (ext)" : "",
|
||||||
|
units_->resistanceUnit()->asString(value(res)));
|
||||||
|
}
|
||||||
|
report_->reportLine("Coupling Capacitors:");
|
||||||
|
for (ParasiticCapacitor *cap : capacitors(parasitic)) {
|
||||||
|
ParasiticNode *node1 = this->node1(cap);
|
||||||
|
ParasiticNode *node2 = this->node2(cap);
|
||||||
|
report_->reportLine("%zu %s%s %s%s %s",
|
||||||
|
id(cap),
|
||||||
|
name(node1),
|
||||||
|
isExternal(node1) ? " (ext)" : "",
|
||||||
|
name(node2),
|
||||||
|
isExternal(node2) ? " (ext)" : "",
|
||||||
|
cap_unit->asString(value(cap)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const Net *
|
const Net *
|
||||||
Parasitics::findParasiticNet(const Pin *pin) const
|
Parasitics::findParasiticNet(const Pin *pin) const
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -155,60 +155,53 @@ ReduceToPi::reducePiDfs(const Pin *drvr_pin,
|
||||||
double &dwn_cap,
|
double &dwn_cap,
|
||||||
double &max_resistance)
|
double &max_resistance)
|
||||||
{
|
{
|
||||||
if (parasitics_->isExternal(node)) {
|
double coupling_cap = 0.0;
|
||||||
y1 = y2 = y3 = 0.0;
|
ParasiticCapacitorSeq &capacitors = capacitor_map_[node];
|
||||||
max_resistance = 0.0;
|
for (ParasiticCapacitor *capacitor : capacitors)
|
||||||
dwn_cap = 0.0;
|
coupling_cap += parasitics_->value(capacitor);
|
||||||
}
|
|
||||||
else {
|
|
||||||
double coupling_cap = 0.0;
|
|
||||||
ParasiticCapacitorSeq &capacitors = capacitor_map_[node];
|
|
||||||
for (ParasiticCapacitor *capacitor : capacitors)
|
|
||||||
coupling_cap += parasitics_->value(capacitor);
|
|
||||||
|
|
||||||
dwn_cap = parasitics_->nodeGndCap(node)
|
dwn_cap = parasitics_->nodeGndCap(node)
|
||||||
+ coupling_cap * coupling_cap_multiplier_
|
+ coupling_cap * coupling_cap_multiplier_
|
||||||
+ 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 = max(max_resistance, src_resistance);
|
||||||
|
|
||||||
visit(node);
|
visit(node);
|
||||||
ParasiticResistorSeq &resistors = resistor_map_[node];
|
ParasiticResistorSeq &resistors = resistor_map_[node];
|
||||||
for (ParasiticResistor *resistor : resistors) {
|
for (ParasiticResistor *resistor : resistors) {
|
||||||
if (!isLoopResistor(resistor)) {
|
if (!isLoopResistor(resistor)) {
|
||||||
ParasiticNode *onode = parasitics_->otherNode(resistor, node);
|
ParasiticNode *onode = parasitics_->otherNode(resistor, node);
|
||||||
// One commercial extractor creates resistors with identical from/to nodes.
|
// One commercial extractor creates resistors with identical from/to nodes.
|
||||||
if (onode != node
|
if (onode != node
|
||||||
&& resistor != from_res) {
|
&& resistor != from_res) {
|
||||||
if (isVisited(onode)) {
|
if (isVisited(onode)) {
|
||||||
// Resistor loop.
|
// Resistor loop.
|
||||||
debugPrint(debug_, "parasitic_reduce", 2, " loop detected thru resistor %zu",
|
debugPrint(debug_, "parasitic_reduce", 2, " loop detected thru resistor %zu",
|
||||||
parasitics_->id(resistor));
|
parasitics_->id(resistor));
|
||||||
markLoopResistor(resistor);
|
markLoopResistor(resistor);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
double r = parasitics_->value(resistor);
|
double r = parasitics_->value(resistor);
|
||||||
double yd1, yd2, yd3, dcap;
|
double yd1, yd2, yd3, dcap;
|
||||||
reducePiDfs(drvr_pin, onode, resistor, src_resistance + r,
|
reducePiDfs(drvr_pin, onode, resistor, src_resistance + r,
|
||||||
yd1, yd2, yd3, dcap, max_resistance);
|
yd1, yd2, yd3, dcap, max_resistance);
|
||||||
// Rule 3. Upstream traversal of a series resistor.
|
// Rule 3. Upstream traversal of a series resistor.
|
||||||
// Rule 4. Parallel admittances add.
|
// Rule 4. Parallel admittances add.
|
||||||
y1 += yd1;
|
y1 += yd1;
|
||||||
y2 += yd2 - r * yd1 * yd1;
|
y2 += yd2 - r * yd1 * yd1;
|
||||||
y3 += yd3 - 2 * r * yd1 * yd2 + r * r * yd1 * yd1 * yd1;
|
y3 += yd3 - 2 * r * yd1 * yd2 + r * r * yd1 * yd1 * yd1;
|
||||||
dwn_cap += dcap;
|
dwn_cap += dcap;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setDownstreamCap(node, dwn_cap);
|
|
||||||
leave(node);
|
|
||||||
debugPrint(debug_, "parasitic_reduce", 3,
|
|
||||||
" node %s y1=%.3g y2=%.3g y3=%.3g cap=%.3g",
|
|
||||||
parasitics_->name(node), y1, y2, y3, dwn_cap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setDownstreamCap(node, dwn_cap);
|
||||||
|
leave(node);
|
||||||
|
debugPrint(debug_, "parasitic_reduce", 3,
|
||||||
|
" node %s y1=%.3g y2=%.3g y3=%.3g cap=%.3g",
|
||||||
|
parasitics_->name(node), y1, y2, y3, dwn_cap);
|
||||||
}
|
}
|
||||||
|
|
||||||
float
|
float
|
||||||
|
|
|
||||||
|
|
@ -5240,6 +5240,8 @@ Sdc::exceptionFromClkStates(const Pin *pin,
|
||||||
exceptionFromStates(first_from_inst_exceptions_.findKey(inst),
|
exceptionFromStates(first_from_inst_exceptions_.findKey(inst),
|
||||||
pin, rf, min_max, true, states);
|
pin, rf, min_max, true, states);
|
||||||
}
|
}
|
||||||
|
exceptionThruStates(first_thru_pin_exceptions_.findKey(pin),
|
||||||
|
rf, min_max, states);
|
||||||
}
|
}
|
||||||
if (!first_from_clk_exceptions_.empty())
|
if (!first_from_clk_exceptions_.empty())
|
||||||
exceptionFromStates(first_from_clk_exceptions_.findKey(clk),
|
exceptionFromStates(first_from_clk_exceptions_.findKey(clk),
|
||||||
|
|
|
||||||
25
sdc/Sdc.tcl
25
sdc/Sdc.tcl
|
|
@ -408,25 +408,22 @@ proc current_design { {design ""} } {
|
||||||
|
|
||||||
# Generic get_* filter.
|
# Generic get_* filter.
|
||||||
proc filter_objs { filter objects filter_function object_type } {
|
proc filter_objs { filter objects filter_function object_type } {
|
||||||
set filter_regexp1 {@?([a-zA-Z_]+) *(==|!=|=~|!~) *([0-9a-zA-Z_\*]+)}
|
set filter_regexp1 {@?([a-zA-Z_]+) *((==|!=|=~|!~) *([0-9a-zA-Z_\*]+))?}
|
||||||
set filter_or_regexp "($filter_regexp1) *\\|\\| *($filter_regexp1)"
|
set filter_or_regexp "($filter_regexp1) *\\|\\| *($filter_regexp1)"
|
||||||
set filter_and_regexp "($filter_regexp1) *&& *($filter_regexp1)"
|
set filter_and_regexp "($filter_regexp1) *&& *($filter_regexp1)"
|
||||||
set filtered_objects {}
|
set filtered_objects {}
|
||||||
# Ignore sub-exprs in filter_regexp1 for expr2 match var.
|
# Ignore sub-exprs in filter_regexp1 for expr2 match var.
|
||||||
if { [regexp $filter_or_regexp $filter ignore expr1 \
|
if { [regexp $filter_or_regexp $filter ignore expr1 ignore ignore ignore ignore expr2] } {
|
||||||
ignore ignore ignore expr2] } {
|
set filtered_objects1 [filter_objs $expr1 $objects $filter_function $object_type]
|
||||||
regexp $filter_regexp1 $expr1 ignore attr_name op arg
|
set filtered_objects2 [filter_objs $expr2 $objects $filter_function $object_type]
|
||||||
set filtered_objects1 [$filter_function $attr_name $op $arg $objects]
|
|
||||||
regexp $filter_regexp1 $expr2 ignore attr_name op arg
|
|
||||||
set filtered_objects2 [$filter_function $attr_name $op $arg $objects]
|
|
||||||
set filtered_objects [concat $filtered_objects1 $filtered_objects2]
|
set filtered_objects [concat $filtered_objects1 $filtered_objects2]
|
||||||
} elseif { [regexp $filter_and_regexp $filter ignore expr1 \
|
} elseif { [regexp $filter_and_regexp $filter ignore expr1 ignore ignore ignore ignore expr2] } {
|
||||||
ignore ignore ignore expr2] } {
|
set filtered_objects [filter_objs $expr1 $objects $filter_function $object_type]
|
||||||
regexp $filter_regexp1 $expr1 ignore attr_name op arg
|
set filtered_objects [filter_objs $expr2 $filtered_objects $filter_function $object_type]
|
||||||
set filtered_objects [$filter_function $attr_name $op $arg $objects]
|
} elseif { [regexp $filter_regexp1 $filter ignore attr_name ignore op arg] } {
|
||||||
regexp $filter_regexp1 $expr2 ignore attr_name op arg
|
# If no op/arg, use <attr_name>==1 by default.
|
||||||
set filtered_objects [$filter_function $attr_name $op $arg $filtered_objects]
|
set op [expr {($op == "") ? "==" : $op}]
|
||||||
} elseif { [regexp $filter_regexp1 $filter ignore attr_name op arg] } {
|
set arg [expr {($arg == "") ? "1" : $arg}]
|
||||||
set filtered_objects [$filter_function $attr_name $op $arg $objects]
|
set filtered_objects [$filter_function $attr_name $op $arg $objects]
|
||||||
} else {
|
} else {
|
||||||
sta_error 350 "unsupported $object_type -filter expression."
|
sta_error 350 "unsupported $object_type -filter expression."
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,34 @@
|
||||||
get_cells
|
[get_cells -filter liberty_cell==BUFx2_ASAP7_75t_R *]
|
||||||
u1
|
u1
|
||||||
get_clocks
|
[get_clocks -filter is_virtual==0 *]
|
||||||
clk
|
clk
|
||||||
get_clocks 2
|
[get_clocks -filter is_virtual==1 *]
|
||||||
vclk
|
vclk
|
||||||
get_lib_cells
|
[get_clocks -filter is_virtual *]
|
||||||
|
vclk
|
||||||
|
[get_clocks -filter is_virtual&&is_generated *]
|
||||||
|
[get_clocks -filter is_virtual&&is_generated==0 *]
|
||||||
|
vclk
|
||||||
|
[get_clocks -filter is_virtual||is_generated *]
|
||||||
|
vclk
|
||||||
|
[get_clocks -filter is_virtual==0||is_generated *]
|
||||||
|
clk
|
||||||
|
[get_lib_cells -filter is_buffer==1 *]
|
||||||
asap7_small/BUFx2_ASAP7_75t_R
|
asap7_small/BUFx2_ASAP7_75t_R
|
||||||
get_lib_cells 2
|
[get_lib_cells -filter is_inverter==0 *]
|
||||||
asap7_small/AND2x2_ASAP7_75t_R
|
asap7_small/AND2x2_ASAP7_75t_R
|
||||||
asap7_small/BUFx2_ASAP7_75t_R
|
asap7_small/BUFx2_ASAP7_75t_R
|
||||||
asap7_small/DFFHQx4_ASAP7_75t_R
|
asap7_small/DFFHQx4_ASAP7_75t_R
|
||||||
get_lib_pins
|
[get_lib_pins -filter direction==input BUFx2_ASAP7_75t_R/*]
|
||||||
A
|
A
|
||||||
get_lib_pins 2
|
[get_lib_pins -filter direction==output BUFx2_ASAP7_75t_R/*]
|
||||||
Y
|
Y
|
||||||
get_libs
|
[get_libs -filter name==asap7_small *]
|
||||||
asap7_small
|
asap7_small
|
||||||
get_nets
|
[get_nets -filter name=~*q *]
|
||||||
r1q
|
r1q
|
||||||
r2q
|
r2q
|
||||||
get_pins
|
[get_pins -filter direction==input *]
|
||||||
r1/CLK
|
r1/CLK
|
||||||
r1/D
|
r1/D
|
||||||
r2/CLK
|
r2/CLK
|
||||||
|
|
@ -29,17 +38,17 @@ r3/D
|
||||||
u1/A
|
u1/A
|
||||||
u2/A
|
u2/A
|
||||||
u2/B
|
u2/B
|
||||||
get_pins 2
|
[get_pins -filter direction==output *]
|
||||||
r1/Q
|
r1/Q
|
||||||
r2/Q
|
r2/Q
|
||||||
r3/Q
|
r3/Q
|
||||||
u1/Y
|
u1/Y
|
||||||
u2/Y
|
u2/Y
|
||||||
get_ports
|
[get_ports -filter direction==input *]
|
||||||
clk1
|
clk1
|
||||||
clk2
|
clk2
|
||||||
clk3
|
clk3
|
||||||
in1
|
in1
|
||||||
in2
|
in2
|
||||||
get_ports 2
|
[get_ports -filter direction==output *]
|
||||||
out
|
out
|
||||||
|
|
|
||||||
|
|
@ -6,29 +6,39 @@ create_clock -name clk -period 500 {clk1 clk2 clk3}
|
||||||
create_clock -name vclk -period 1000
|
create_clock -name vclk -period 1000
|
||||||
|
|
||||||
# Test filters for each SDC command
|
# Test filters for each SDC command
|
||||||
puts "get_cells"
|
puts {[get_cells -filter liberty_cell==BUFx2_ASAP7_75t_R *]}
|
||||||
report_object_full_names [get_cells -filter liberty_cell==BUFx2_ASAP7_75t_R *]
|
report_object_full_names [get_cells -filter liberty_cell==BUFx2_ASAP7_75t_R *]
|
||||||
puts "get_clocks"
|
puts {[get_clocks -filter is_virtual==0 *]}
|
||||||
report_object_full_names [get_clocks -filter is_virtual==0 *]
|
report_object_full_names [get_clocks -filter is_virtual==0 *]
|
||||||
puts "get_clocks 2"
|
puts {[get_clocks -filter is_virtual==1 *]}
|
||||||
report_object_full_names [get_clocks -filter is_virtual==1 *]
|
report_object_full_names [get_clocks -filter is_virtual==1 *]
|
||||||
puts "get_lib_cells"
|
puts {[get_clocks -filter is_virtual *]}
|
||||||
|
report_object_full_names [get_clocks -filter is_virtual *]
|
||||||
|
puts {[get_clocks -filter is_virtual&&is_generated *]}
|
||||||
|
report_object_full_names [get_clocks -filter is_virtual&&is_generated *]
|
||||||
|
puts {[get_clocks -filter is_virtual&&is_generated==0 *]}
|
||||||
|
report_object_full_names [get_clocks -filter is_virtual&&is_generated==0 *]
|
||||||
|
puts {[get_clocks -filter is_virtual||is_generated *]}
|
||||||
|
report_object_full_names [get_clocks -filter is_virtual||is_generated *]
|
||||||
|
puts {[get_clocks -filter is_virtual==0||is_generated *]}
|
||||||
|
report_object_full_names [get_clocks -filter is_virtual==0||is_generated *]
|
||||||
|
puts {[get_lib_cells -filter is_buffer==1 *]}
|
||||||
report_object_full_names [get_lib_cells -filter is_buffer==1 *]
|
report_object_full_names [get_lib_cells -filter is_buffer==1 *]
|
||||||
puts "get_lib_cells 2"
|
puts {[get_lib_cells -filter is_inverter==0 *]}
|
||||||
report_object_full_names [get_lib_cells -filter is_inverter==0 *]
|
report_object_full_names [get_lib_cells -filter is_inverter==0 *]
|
||||||
puts "get_lib_pins"
|
puts {[get_lib_pins -filter direction==input BUFx2_ASAP7_75t_R/*]}
|
||||||
report_object_full_names [get_lib_pins -filter direction==input BUFx2_ASAP7_75t_R/*]
|
report_object_full_names [get_lib_pins -filter direction==input BUFx2_ASAP7_75t_R/*]
|
||||||
puts "get_lib_pins 2"
|
puts {[get_lib_pins -filter direction==output BUFx2_ASAP7_75t_R/*]}
|
||||||
report_object_full_names [get_lib_pins -filter direction==output BUFx2_ASAP7_75t_R/*]
|
report_object_full_names [get_lib_pins -filter direction==output BUFx2_ASAP7_75t_R/*]
|
||||||
puts "get_libs"
|
puts {[get_libs -filter name==asap7_small *]}
|
||||||
report_object_full_names [get_libs -filter name==asap7_small *]
|
report_object_full_names [get_libs -filter name==asap7_small *]
|
||||||
puts "get_nets"
|
puts {[get_nets -filter name=~*q *]}
|
||||||
report_object_full_names [get_nets -filter name=~*q *]
|
report_object_full_names [get_nets -filter name=~*q *]
|
||||||
puts "get_pins"
|
puts {[get_pins -filter direction==input *]}
|
||||||
report_object_full_names [get_pins -filter direction==input *]
|
report_object_full_names [get_pins -filter direction==input *]
|
||||||
puts "get_pins 2"
|
puts {[get_pins -filter direction==output *]}
|
||||||
report_object_full_names [get_pins -filter direction==output *]
|
report_object_full_names [get_pins -filter direction==output *]
|
||||||
puts "get_ports"
|
puts {[get_ports -filter direction==input *]}
|
||||||
report_object_full_names [get_ports -filter direction==input *]
|
report_object_full_names [get_ports -filter direction==input *]
|
||||||
puts "get_ports 2"
|
puts {[get_ports -filter direction==output *]}
|
||||||
report_object_full_names [get_ports -filter direction==output *]
|
report_object_full_names [get_ports -filter direction==output *]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue