Merge remote-tracking branch 'parallax/master'

This commit is contained in:
Matt Liberty 2026-01-28 19:13:58 +00:00
commit 087793e8a0
12 changed files with 63 additions and 142 deletions

View File

@ -1153,7 +1153,9 @@ public:
virtual void disconnectPin(Pin *pin);
virtual void makePortPin(const char *port_name,
PortDirection *dir);
// Notify STA of network change.
// Notify STA that the network has changed without using the network
// editing API. For example, reading a netlist without using the
// builtin network readers.
void networkChanged();
void deleteLeafInstanceBefore(const Instance *inst);
void deleteInstancePinsBefore(const Instance *inst);

View File

@ -1595,15 +1595,7 @@ Power::clockMinPeriod()
}
void
Power::deleteInstanceBefore(const Instance *)
{
activities_valid_ = false;
instance_powers_.clear();
corner_ = nullptr;
}
void
Power::deletePinBefore(const Pin *)
Power::powerInvalid()
{
activities_valid_ = false;
instance_powers_.clear();

View File

@ -108,8 +108,7 @@ public:
float clockMinPeriod();
InstanceSeq highestPowerInstances(size_t count,
const Corner *corner);
void deleteInstanceBefore(const Instance *inst);
void deletePinBefore(const Pin *pin);
void powerInvalid();
protected:
PwrActivity &activity(const Pin *pin);

View File

@ -245,8 +245,6 @@ VcdParse::parseVarValues()
reader_->varAppendValue(id, time_, char0);
}
else if (char0 == 'B') {
if (file_line_ == 148904)
printf("luse\n");
string bus_value = token.substr(1);
string id = getToken();
if (!reader_->varIdValid(id))

View File

@ -469,7 +469,7 @@ ReadVcdActivities::checkClkPeriod(const Pin *pin,
double clk_period = clk->period();
if (abs((clk_period - sim_period) / clk_period) > sim_clk_period_tolerance_)
// 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(1453, "clock %s vcd period %s differs from SDC clock period %s",
clk->name(),
delayAsString(sim_period, this),
delayAsString(clk_period, this));

View File

@ -306,11 +306,18 @@ proc current_design { {design ""} } {
# Generic get_* filter.
proc filter_objs { filter objects filter_function object_type } {
set filter_regexp1 {@?([a-zA-Z_]+) *((==|!=|=~|!~) *([0-9a-zA-Z_\*]+))?}
set filter_or_regexp "($filter_regexp1) *\\|\\| *($filter_regexp1)"
set filter_and_regexp "($filter_regexp1) *&& *($filter_regexp1)"
# Regexp for attr op arg (e.g., full_name =~ *blk*)
set filter_regexp_op {@?([a-zA-Z_]+) *(==|!=|=~|!~) *([0-9a-zA-Z_\*]+)}
# Regexp for bool attr (e.g., is_hierarchical) - anchored for standalone use
set filter_regexp_bool {^@?([a-zA-Z_]+)$}
# Regexp for wildcard attr (e.g., full_name <?> *blk*)
set filter_regexp_wild_op {@?([a-zA-Z_]+) *(.+) *([0-9a-zA-Z_\*]+)}
# Regexp for term in compound expression (no anchors)
set filter_regexp_term {@?([a-zA-Z_]+)( *(==|!=|=~|!~) *([0-9a-zA-Z_\*]+))?}
set filter_or_regexp "($filter_regexp_term) *\\|\\| *($filter_regexp_term)"
set filter_and_regexp "($filter_regexp_term) *&& *($filter_regexp_term)"
set filtered_objects {}
# Ignore sub-exprs in filter_regexp1 for expr2 match var.
# Ignore sub-exprs in filter_regexp for expr2 match var.
if { [regexp $filter_or_regexp $filter ignore expr1 ignore ignore ignore ignore expr2] } {
set filtered_objects1 [filter_objs $expr1 $objects $filter_function $object_type]
set filtered_objects2 [filter_objs $expr2 $objects $filter_function $object_type]
@ -318,11 +325,13 @@ proc filter_objs { filter objects filter_function object_type } {
} elseif { [regexp $filter_and_regexp $filter ignore expr1 ignore ignore ignore ignore expr2] } {
set filtered_objects [filter_objs $expr1 $objects $filter_function $object_type]
set filtered_objects [filter_objs $expr2 $filtered_objects $filter_function $object_type]
} elseif { [regexp $filter_regexp1 $filter ignore attr_name ignore op arg] } {
# If no op/arg, use <attr_name>==1 by default.
set op [expr {($op == "") ? "==" : $op}]
set arg [expr {($arg == "") ? "1" : $arg}]
} elseif { [regexp $filter_regexp_op $filter ignore attr_name op arg] } {
set filtered_objects [$filter_function $attr_name $op $arg $objects]
} elseif { [regexp $filter_regexp_bool $filter ignore attr_name] } {
# Bool property: use <attr_name>==1 by default.
set filtered_objects [$filter_function $attr_name "==" "1" $objects]
} elseif { [regexp $filter_regexp_wild_op $filter ignore attr_name op arg] } {
sta_error 336 "unknown filter operand."
} else {
sta_error 350 "unsupported $object_type -filter expression."
}

View File

@ -415,7 +415,9 @@ PathEnumFaninVisitor::visitFromToPath(const Pin *,
{
// These paths fanin to before_div_ so we know to_vertex matches.
if ((!unique_pins_ || from_vertex != prev_vertex_)
&& (!unique_edges_ || from_rf != prev_arc_->fromEdge()->asRiseFall())
&& (!unique_edges_
|| from_vertex != prev_vertex_
|| from_rf != prev_arc_->fromEdge()->asRiseFall())
&& arc != prev_arc_
&& Tag::matchNoCrpr(to_tag, before_div_tag_)
// Ignore paths that only differ by crpr from same vertex/edge.
@ -440,10 +442,26 @@ PathEnumFaninVisitor::visitFromToPath(const Pin *,
if (crpr_active_)
visited_fanins_.emplace(from_vertex, arc);
}
else
debugPrint(debug_, "path_enum", 3, " pruned %s %s",
edge->to_string(this).c_str(),
arc->to_string().c_str());
else {
if (debug_->check("path_enum", 3)) {
bool unique_pins = !(!unique_pins_ || from_vertex != prev_vertex_);
bool unique_edges = !(!unique_edges_
|| from_rf != prev_arc_->fromEdge()->asRiseFall());
bool same_arc = !(arc != prev_arc_);
bool tag_march = !Tag::matchNoCrpr(to_tag, before_div_tag_);
bool crpr = !(!crpr_active_
|| visited_fanins_.find({from_vertex, arc})
== visited_fanins_.end());
debugPrint(debug_, "path_enum", 3, " pruned %s%s%s%s%s %s %s",
unique_pins ? "unique_pins " : "",
unique_edges ? "unique_edges " : "",
same_arc ? "same_arc " : "",
tag_march ? "tag_march " : "",
crpr ? "crpr " : "",
edge->to_string(this).c_str(),
arc->to_string().c_str());
}
}
return true;
}

View File

@ -4245,6 +4245,7 @@ Sta::makeInstanceAfter(const Instance *inst)
}
}
graph_->makeInstanceEdges(inst);
power_->powerInvalid();
}
}
}
@ -4311,6 +4312,8 @@ Sta::replaceEquivCellAfter(const Instance *inst)
parasitics_->loadPinCapacitanceChanged(pin);
}
delete pin_iter;
clk_skews_->clear();
power_->powerInvalid();
}
}
@ -4381,7 +4384,6 @@ Sta::replaceCellBefore(const Instance *inst,
}
}
delete pin_iter;
clk_skews_->clear();
}
}
@ -4447,6 +4449,7 @@ Sta::connectPinAfter(const Pin *pin)
sdc_->connectPinAfter(pin);
sim_->connectPinAfter(pin);
clk_skews_->clear();
power_->powerInvalid();
}
void
@ -4538,6 +4541,7 @@ Sta::disconnectPinBefore(const Pin *pin)
}
}
clk_skews_->clear();
power_->powerInvalid();
}
}
@ -4582,6 +4586,8 @@ Sta::deleteNetBefore(const Net *net)
delete pin_iter;
}
sdc_->deleteNetBefore(net);
clk_skews_->clear();
power_->powerInvalid();
}
void
@ -4609,7 +4615,8 @@ Sta::deleteLeafInstanceBefore(const Instance *inst)
{
sim_->deleteInstanceBefore(inst);
sdc_->deleteInstanceBefore(inst);
power_->deleteInstanceBefore(inst);
clk_skews_->clear();
power_->powerInvalid();
}
void
@ -4687,8 +4694,6 @@ Sta::deletePinBefore(const Pin *pin)
sdc_->deletePinBefore(pin);
sim_->deletePinBefore(pin);
clk_network_->deletePinBefore(pin);
power_->deletePinBefore(pin);
clk_skews_->clear();
}
void

View File

@ -43,6 +43,7 @@
#include "Path.hh"
#include "DcalcAnalysisPt.hh"
#include "Bdd.hh"
#include "cudd.h"
namespace sta {
@ -850,8 +851,6 @@ WriteSpice::gatePortValues(const Pin *input_pin,
}
}
#if CUDD
void
WriteSpice::gatePortValues(const Instance *,
const FuncExpr *expr,
@ -895,104 +894,6 @@ WriteSpice::gatePortValues(const Instance *,
bdd_.clearVarMap();
}
#else
void
WriteSpice::gatePortValues(const Instance *inst,
const FuncExpr *expr,
const LibertyPort *input_port,
// Return values.
LibertyPortLogicValues &port_values)
{
FuncExpr *left = expr->left();
FuncExpr *right = expr->right();
switch (expr->op()) {
case FuncExpr::op_port:
break;
case FuncExpr::op_not:
gatePortValues(inst, left, input_port, port_values);
break;
case FuncExpr::op_or:
if (left->hasPort(input_port)
&& right->op() == FuncExpr::op_port) {
gatePortValues(inst, left, input_port, port_values);
port_values[right->port()] = LogicValue::zero;
}
else if (left->hasPort(input_port)
&& right->op() == FuncExpr::op_not
&& right->left()->op() == FuncExpr::op_port) {
// input_port + !right_port
gatePortValues(inst, left, input_port, port_values);
port_values[right->left()->port()] = LogicValue::one;
}
else if (right->hasPort(input_port)
&& left->op() == FuncExpr::op_port) {
gatePortValues(inst, right, input_port, port_values);
port_values[left->port()] = LogicValue::zero;
}
else if (right->hasPort(input_port)
&& left->op() == FuncExpr::op_not
&& left->left()->op() == FuncExpr::op_port) {
// input_port + !left_port
gatePortValues(inst, right, input_port, port_values);
port_values[left->left()->port()] = LogicValue::one;
}
else {
gatePortValues(inst, left, input_port, port_values);
gatePortValues(inst, right, input_port, port_values);
}
break;
case FuncExpr::op_and:
if (left->hasPort(input_port)
&& right->op() == FuncExpr::op_port) {
gatePortValues(inst, left, input_port, port_values);
port_values[right->port()] = LogicValue::one;
}
else if (left->hasPort(input_port)
&& right->op() == FuncExpr::op_not
&& right->left()->op() == FuncExpr::op_port) {
// input_port * !right_port
gatePortValues(inst, left, input_port, port_values);
port_values[right->left()->port()] = LogicValue::zero;
}
else if (right->hasPort(input_port)
&& left->op() == FuncExpr::op_port) {
gatePortValues(inst, right, input_port, port_values);
port_values[left->port()] = LogicValue::one;
}
else if (right->hasPort(input_port)
&& left->op() == FuncExpr::op_not
&& left->left()->op() == FuncExpr::op_port) {
// input_port * !left_port
gatePortValues(inst, right, input_port, port_values);
port_values[left->left()->port()] = LogicValue::zero;
}
else {
gatePortValues(inst, left, input_port, port_values);
gatePortValues(inst, right, input_port, port_values);
}
break;
case FuncExpr::op_xor:
// Need to know timing arc sense to get this right.
if (left->port() == input_port
&& right->op() == FuncExpr::op_port)
port_values[right->port()] = LogicValue::zero;
else if (right->port() == input_port
&& left->op() == FuncExpr::op_port)
port_values[left->port()] = LogicValue::zero;
else {
gatePortValues(inst, left, input_port, port_values);
gatePortValues(inst, right, input_port, port_values);
}
break;
case FuncExpr::op_one:
case FuncExpr::op_zero:
break;
}
}
#endif
void
WriteSpice::regPortValues(const Pin *input_pin,
const RiseFall *drvr_rf,

View File

@ -52,3 +52,5 @@ in1
in2
[get_ports -filter direction==output *]
out
[get_cells -filter {name ~= *r1*} *]
Error: get_filter.tcl line 48, unknown filter operand.

View File

@ -42,3 +42,8 @@ puts {[get_ports -filter direction==input *]}
report_object_full_names [get_ports -filter direction==input *]
puts {[get_ports -filter direction==output *]}
report_object_full_names [get_ports -filter direction==output *]
# Test invalid operator ~= (should be =~)
puts {[get_cells -filter {name ~= *r1*} *]}
catch {get_cells -filter {name ~= *r1*} *} result
puts $result

View File

@ -1,13 +1,3 @@
Warning: asap7_simple.lib.gz line 71029, timing group from output port.
Warning: asap7_simple.lib.gz line 71505, timing group from output port.
Warning: asap7_simple.lib.gz line 71981, timing group from output port.
Warning: asap7_simple.lib.gz line 72457, timing group from output port.
Warning: asap7_simple.lib.gz line 72933, timing group from output port.
Warning: asap7_simple.lib.gz line 73409, timing group from output port.
Warning: asap7_simple.lib.gz line 73885, timing group from output port.
Warning: asap7_simple.lib.gz line 81795, timing group from output port.
Warning: asap7_simple.lib.gz line 82271, timing group from output port.
Warning: asap7_simple.lib.gz line 82747, timing group from output port.
Startpoint: r2 (rising edge-triggered flip-flop clocked by clk)
Endpoint: r3 (rising edge-triggered flip-flop clocked by clk)
Path Group: clk