get_* -filter allow true/false, '.' in glob pattern resolves #416

Signed-off-by: James Cherry <cherry@parallaxsw.com>
This commit is contained in:
James Cherry 2026-04-04 16:19:41 -07:00
parent d6e826ef8b
commit 548b665412
12 changed files with 118 additions and 128 deletions

View File

@ -40,67 +40,56 @@ class Report;
PortSeq PortSeq
filterPorts(std::string_view filter_expression, filterPorts(std::string_view filter_expression,
PortSeq *objects, PortSeq *objects,
bool bool_props_as_int,
Sta *sta); Sta *sta);
InstanceSeq InstanceSeq
filterInstances(std::string_view filter_expression, filterInstances(std::string_view filter_expression,
InstanceSeq *objects, InstanceSeq *objects,
bool bool_props_as_int,
Sta *sta); Sta *sta);
PinSeq PinSeq
filterPins(std::string_view filter_expression, filterPins(std::string_view filter_expression,
PinSeq *objects, PinSeq *objects,
bool bool_props_as_int,
Sta *sta); Sta *sta);
NetSeq NetSeq
filterNets(std::string_view filter_expression, filterNets(std::string_view filter_expression,
NetSeq *objects, NetSeq *objects,
bool bool_props_as_int,
Sta *sta); Sta *sta);
ClockSeq ClockSeq
filterClocks(std::string_view filter_expression, filterClocks(std::string_view filter_expression,
ClockSeq *objects, ClockSeq *objects,
bool bool_props_as_int,
Sta *sta); Sta *sta);
LibertyCellSeq LibertyCellSeq
filterLibCells(std::string_view filter_expression, filterLibCells(std::string_view filter_expression,
LibertyCellSeq *objects, LibertyCellSeq *objects,
bool bool_props_as_int,
Sta *sta); Sta *sta);
LibertyPortSeq LibertyPortSeq
filterLibPins(std::string_view filter_expression, filterLibPins(std::string_view filter_expression,
LibertyPortSeq *objects, LibertyPortSeq *objects,
bool bool_props_as_int,
Sta *sta); Sta *sta);
LibertyLibrarySeq LibertyLibrarySeq
filterLibertyLibraries(std::string_view filter_expression, filterLibertyLibraries(std::string_view filter_expression,
LibertyLibrarySeq *objects, LibertyLibrarySeq *objects,
bool bool_props_as_int,
Sta *sta); Sta *sta);
EdgeSeq EdgeSeq
filterTimingArcs(std::string_view filter_expression, filterTimingArcs(std::string_view filter_expression,
EdgeSeq *objects, EdgeSeq *objects,
bool bool_props_as_int,
Sta *sta); Sta *sta);
PathEndSeq PathEndSeq
filterPathEnds(std::string_view filter_expression, filterPathEnds(std::string_view filter_expression,
PathEndSeq *objects, PathEndSeq *objects,
bool bool_props_as_int,
Sta *sta); Sta *sta);
// For FilterExpr unit tests. // For FilterExpr unit tests.
StringSeq StringSeq
filterExprToPostfix(std::string_view expr, filterExprToPostfix(std::string_view expr,
bool bool_props_as_int,
Report *report); Report *report);
} // namespace } // namespace

View File

@ -73,9 +73,9 @@ public:
FilterExpr(std::string_view expression, FilterExpr(std::string_view expression,
Report *report); Report *report);
std::vector<std::unique_ptr<Token>> postfix(bool bool_props_as_int); std::vector<std::unique_ptr<Token>> postfix();
private: private:
std::vector<std::unique_ptr<Token>> lex(bool bool_props_as_int); std::vector<std::unique_ptr<Token>> lex();
std::vector<std::unique_ptr<Token>> shuntingYard(std::vector<std::unique_ptr<Token>> &infix); std::vector<std::unique_ptr<Token>> shuntingYard(std::vector<std::unique_ptr<Token>> &infix);
std::string raw_; std::string raw_;
@ -106,20 +106,21 @@ FilterExpr::FilterExpr(std::string_view expression,
} }
std::vector<std::unique_ptr<FilterExpr::Token>> std::vector<std::unique_ptr<FilterExpr::Token>>
FilterExpr::postfix(bool bool_props_as_int) FilterExpr::postfix()
{ {
auto infix = lex(bool_props_as_int); auto infix = lex();
return shuntingYard(infix); return shuntingYard(infix);
} }
std::vector<std::unique_ptr<FilterExpr::Token>> std::vector<std::unique_ptr<FilterExpr::Token>>
FilterExpr::lex(bool bool_props_as_int) FilterExpr::lex()
{ {
std::vector<std::pair<std::regex, Token::Kind>> token_regexes = { std::vector<std::pair<std::regex, Token::Kind>> token_regexes = {
{std::regex("^\\s+"), Token::Kind::skip}, {std::regex("^\\s+"), Token::Kind::skip},
{std::regex("^defined\\(([a-zA-Z_]+)\\)"), Token::Kind::defined}, {std::regex("^defined\\(([a-zA-Z_]+)\\)"), Token::Kind::defined},
{std::regex("^undefined\\(([a-zA-Z_]+)\\)"), Token::Kind::undefined}, {std::regex("^undefined\\(([a-zA-Z_]+)\\)"), Token::Kind::undefined},
{std::regex("^@?([a-zA-Z_]+) *((==|!=|=~|!~) *([0-9a-zA-Z_\\/$\\[\\]*?]+))?"), Token::Kind::predicate}, {std::regex("^@?([a-zA-Z_]+) *((==|!=|=~|!~) *([0-9a-zA-Z_\\/$\\[\\]*?.]+))?"),
Token::Kind::predicate},
{std::regex("^(&&)"), Token::Kind::op_and}, {std::regex("^(&&)"), Token::Kind::op_and},
{std::regex("^(\\|\\|)"), Token::Kind::op_or}, {std::regex("^(\\|\\|)"), Token::Kind::op_or},
{std::regex("^(!)"), Token::Kind::op_inv}, {std::regex("^(!)"), Token::Kind::op_inv},
@ -139,9 +140,9 @@ FilterExpr::lex(bool bool_props_as_int)
std::string property = token_match[1].str(); std::string property = token_match[1].str();
// The default operation on a predicate if an op and arg are // The default operation on a predicate if an op and arg are
// omitted is 'arg == 1' / 'arg == true'. // omitted is 'prop == 1 || true'.
std::string op = "=="; std::string op = "==";
std::string arg = (bool_props_as_int ? "1" : "true"); std::string arg = "1";
if (token_match[2].length() != 0) { if (token_match[2].length() != 0) {
op = token_match[3].str(); op = token_match[3].str();
@ -250,13 +251,18 @@ filterObjects(const char *property,
bool not_pattern_match = stringEq(op, "!~"); bool not_pattern_match = stringEq(op, "!~");
for (T *object : all) { for (T *object : all) {
PropertyValue value = properties.getProperty(object, property); PropertyValue value = properties.getProperty(object, property);
std::string prop_str = value.to_string(network); std::string prop = value.to_string(network);
const char *prop = prop_str.c_str(); if (value.type() == PropertyValue::Type::bool_) {
if (prop && // Canonicalize bool true/false to 1/0.
((exact_match && stringEq(prop, pattern)) if (stringEqual(pattern, "true"))
|| (not_match && !stringEq(prop, pattern)) pattern = "1";
|| (pattern_match && patternMatch(pattern, prop)) else if (stringEqual(pattern, "false"))
|| (not_pattern_match && !patternMatch(pattern, prop)))) pattern = "0";
}
if ((exact_match && stringEq(prop.c_str(), pattern))
|| (not_match && !stringEq(prop.c_str(), pattern))
|| (pattern_match && patternMatch(pattern, prop))
|| (not_pattern_match && !patternMatch(pattern, prop)))
filtered_objects.insert(object); filtered_objects.insert(object);
} }
return filtered_objects; return filtered_objects;
@ -265,7 +271,6 @@ filterObjects(const char *property,
template <typename T> std::vector<T*> template <typename T> std::vector<T*>
filterObjects(std::string_view filter_expression, filterObjects(std::string_view filter_expression,
std::vector<T*> *objects, std::vector<T*> *objects,
bool bool_props_as_int,
Sta *sta) Sta *sta)
{ {
Report *report = sta->report(); Report *report = sta->report();
@ -278,7 +283,7 @@ filterObjects(std::string_view filter_expression,
all.insert(object); all.insert(object);
FilterExpr filter(filter_expression, report); FilterExpr filter(filter_expression, report);
auto postfix = filter.postfix(bool_props_as_int); auto postfix = filter.postfix();
std::stack<std::set<T*>> eval_stack; std::stack<std::set<T*>> eval_stack;
for (auto &token : postfix) { for (auto &token : postfix) {
if (token->kind == FilterExpr::Token::Kind::op_or) { if (token->kind == FilterExpr::Token::Kind::op_or) {
@ -405,100 +410,89 @@ filterObjects(std::string_view filter_expression,
PortSeq PortSeq
filterPorts(std::string_view filter_expression, filterPorts(std::string_view filter_expression,
PortSeq *objects, PortSeq *objects,
bool bool_props_as_int,
Sta *sta) Sta *sta)
{ {
return filterObjects<const Port>(filter_expression, objects, bool_props_as_int, sta); return filterObjects<const Port>(filter_expression, objects, sta);
} }
InstanceSeq InstanceSeq
filterInstances(std::string_view filter_expression, filterInstances(std::string_view filter_expression,
InstanceSeq *objects, InstanceSeq *objects,
bool bool_props_as_int,
Sta *sta) Sta *sta)
{ {
return filterObjects<const Instance>(filter_expression, objects, bool_props_as_int, sta); return filterObjects<const Instance>(filter_expression, objects, sta);
} }
PinSeq PinSeq
filterPins(std::string_view filter_expression, filterPins(std::string_view filter_expression,
PinSeq *objects, PinSeq *objects,
bool bool_props_as_int,
Sta *sta) Sta *sta)
{ {
return filterObjects<const Pin>(filter_expression, objects, bool_props_as_int, sta); return filterObjects<const Pin>(filter_expression, objects, sta);
} }
NetSeq NetSeq
filterNets(std::string_view filter_expression, filterNets(std::string_view filter_expression,
NetSeq *objects, NetSeq *objects,
bool bool_props_as_int,
Sta *sta) Sta *sta)
{ {
return filterObjects<const Net>(filter_expression, objects, bool_props_as_int, sta); return filterObjects<const Net>(filter_expression, objects, sta);
} }
ClockSeq ClockSeq
filterClocks(std::string_view filter_expression, filterClocks(std::string_view filter_expression,
ClockSeq *objects, ClockSeq *objects,
bool bool_props_as_int,
Sta *sta) Sta *sta)
{ {
return filterObjects<Clock>(filter_expression, objects, bool_props_as_int, sta); return filterObjects<Clock>(filter_expression, objects, sta);
} }
LibertyCellSeq LibertyCellSeq
filterLibCells(std::string_view filter_expression, filterLibCells(std::string_view filter_expression,
LibertyCellSeq *objects, LibertyCellSeq *objects,
bool bool_props_as_int,
Sta *sta) Sta *sta)
{ {
return filterObjects<LibertyCell>(filter_expression, objects, bool_props_as_int, sta); return filterObjects<LibertyCell>(filter_expression, objects, sta);
} }
LibertyPortSeq LibertyPortSeq
filterLibPins(std::string_view filter_expression, filterLibPins(std::string_view filter_expression,
LibertyPortSeq *objects, LibertyPortSeq *objects,
bool bool_props_as_int,
Sta *sta) Sta *sta)
{ {
return filterObjects<LibertyPort>(filter_expression, objects, bool_props_as_int, sta); return filterObjects<LibertyPort>(filter_expression, objects, sta);
} }
LibertyLibrarySeq LibertyLibrarySeq
filterLibertyLibraries(std::string_view filter_expression, filterLibertyLibraries(std::string_view filter_expression,
LibertyLibrarySeq *objects, LibertyLibrarySeq *objects,
bool bool_props_as_int,
Sta *sta) Sta *sta)
{ {
return filterObjects<LibertyLibrary>(filter_expression, objects, bool_props_as_int, sta); return filterObjects<LibertyLibrary>(filter_expression, objects, sta);
} }
EdgeSeq EdgeSeq
filterTimingArcs(std::string_view filter_expression, filterTimingArcs(std::string_view filter_expression,
EdgeSeq *objects, EdgeSeq *objects,
bool bool_props_as_int,
Sta *sta) Sta *sta)
{ {
return filterObjects<Edge>(filter_expression, objects, bool_props_as_int, sta); return filterObjects<Edge>(filter_expression, objects, sta);
} }
PathEndSeq PathEndSeq
filterPathEnds(std::string_view filter_expression, filterPathEnds(std::string_view filter_expression,
PathEndSeq *objects, PathEndSeq *objects,
bool bool_props_as_int,
Sta *sta) Sta *sta)
{ {
return filterObjects<PathEnd>(filter_expression, objects, bool_props_as_int, sta); return filterObjects<PathEnd>(filter_expression, objects, sta);
} }
StringSeq StringSeq
filterExprToPostfix(std::string_view expr, filterExprToPostfix(std::string_view expr,
bool bool_props_as_int,
Report *report) Report *report)
{ {
FilterExpr filter(expr, report); FilterExpr filter(expr, report);
auto postfix = filter.postfix(bool_props_as_int); auto postfix = filter.postfix();
StringSeq result; StringSeq result;
for (auto &token : postfix) for (auto &token : postfix)
result.push_back(token->text); result.push_back(token->text);

View File

@ -1493,101 +1493,90 @@ find_register_output_pins(ClockSet *clks,
PortSeq PortSeq
filter_ports(const char *filter_expression, filter_ports(const char *filter_expression,
PortSeq *ports, PortSeq *ports)
bool bool_props_as_int)
{ {
sta::Sta *sta = Sta::sta(); sta::Sta *sta = Sta::sta();
return filterPorts(filter_expression, ports, bool_props_as_int, sta); return filterPorts(filter_expression, ports, sta);
} }
InstanceSeq InstanceSeq
filter_insts(const char *filter_expression, filter_insts(const char *filter_expression,
InstanceSeq *insts, InstanceSeq *insts)
bool bool_props_as_int)
{ {
sta::Sta *sta = Sta::sta(); sta::Sta *sta = Sta::sta();
return filterInstances(filter_expression, insts, bool_props_as_int, sta); return filterInstances(filter_expression, insts, sta);
} }
PinSeq PinSeq
filter_pins(const char *filter_expression, filter_pins(const char *filter_expression,
PinSeq *pins, PinSeq *pins)
bool bool_props_as_int)
{ {
sta::Sta *sta = Sta::sta(); sta::Sta *sta = Sta::sta();
return filterPins(filter_expression, pins, bool_props_as_int, sta); return filterPins(filter_expression, pins, sta);
} }
NetSeq NetSeq
filter_nets(const char *filter_expression, filter_nets(const char *filter_expression,
NetSeq *nets, NetSeq *nets)
bool bool_props_as_int)
{ {
sta::Sta *sta = Sta::sta(); sta::Sta *sta = Sta::sta();
return filterNets(filter_expression, nets, bool_props_as_int, sta); return filterNets(filter_expression, nets, sta);
} }
ClockSeq ClockSeq
filter_clocks(const char *filter_expression, filter_clocks(const char *filter_expression,
ClockSeq *clocks, ClockSeq *clocks)
bool bool_props_as_int)
{ {
sta::Sta *sta = Sta::sta(); sta::Sta *sta = Sta::sta();
return filterClocks(filter_expression, clocks, bool_props_as_int, sta); return filterClocks(filter_expression, clocks, sta);
} }
LibertyCellSeq LibertyCellSeq
filter_lib_cells(const char *filter_expression, filter_lib_cells(const char *filter_expression,
LibertyCellSeq *cells, LibertyCellSeq *cells)
bool bool_props_as_int)
{ {
sta::Sta *sta = Sta::sta(); sta::Sta *sta = Sta::sta();
return filterLibCells(filter_expression, cells, bool_props_as_int, sta); return filterLibCells(filter_expression, cells, sta);
} }
LibertyPortSeq LibertyPortSeq
filter_lib_pins(const char *filter_expression, filter_lib_pins(const char *filter_expression,
LibertyPortSeq *pins, LibertyPortSeq *pins)
bool bool_props_as_int)
{ {
sta::Sta *sta = Sta::sta(); sta::Sta *sta = Sta::sta();
return filterLibPins(filter_expression, pins, bool_props_as_int, sta); return filterLibPins(filter_expression, pins, sta);
} }
LibertyLibrarySeq LibertyLibrarySeq
filter_liberty_libraries(const char *filter_expression, filter_liberty_libraries(const char *filter_expression,
LibertyLibrarySeq *libs, LibertyLibrarySeq *libs)
bool bool_props_as_int)
{ {
sta::Sta *sta = Sta::sta(); sta::Sta *sta = Sta::sta();
return filterLibertyLibraries(filter_expression, libs, bool_props_as_int, sta); return filterLibertyLibraries(filter_expression, libs, sta);
} }
EdgeSeq EdgeSeq
filter_timing_arcs(const char *filter_expression, filter_timing_arcs(const char *filter_expression,
EdgeSeq *edges, EdgeSeq *edges)
bool bool_props_as_int)
{ {
sta::Sta *sta = Sta::sta(); sta::Sta *sta = Sta::sta();
return filterTimingArcs(filter_expression, edges, bool_props_as_int, sta); return filterTimingArcs(filter_expression, edges, sta);
} }
PathEndSeq PathEndSeq
filter_path_ends(const char *filter_expression, filter_path_ends(const char *filter_expression,
PathEndSeq *path_ends, PathEndSeq *path_ends)
bool bool_props_as_int)
{ {
sta::Sta *sta = Sta::sta(); sta::Sta *sta = Sta::sta();
return filterPathEnds(filter_expression, path_ends, bool_props_as_int, sta); return filterPathEnds(filter_expression, path_ends, sta);
} }
// For FilterExpr unit tests. // For FilterExpr unit tests.
StringSeq StringSeq
filter_expr_to_postfix(const char* expr, filter_expr_to_postfix(const char* expr)
bool bool_props_as_int)
{ {
Report *report = Sta::sta()->report(); Report *report = Sta::sta()->report();
return filterExprToPostfix(expr, bool_props_as_int, report); return filterExprToPostfix(expr, report);
} }
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////

View File

@ -393,7 +393,7 @@ proc get_cells { args } {
} }
} }
if [info exists keys(-filter)] { if [info exists keys(-filter)] {
set insts [filter_insts $keys(-filter) $insts 1] set insts [filter_insts $keys(-filter) $insts]
} }
return $insts return $insts
} }
@ -436,7 +436,7 @@ proc get_clocks { args } {
} }
} }
if [info exists keys(-filter)] { if [info exists keys(-filter)] {
set clocks [filter_clocks $keys(-filter) $clocks 1] set clocks [filter_clocks $keys(-filter) $clocks]
} }
return $clocks return $clocks
} }
@ -517,7 +517,7 @@ proc get_lib_cells { args } {
} }
} }
if [info exists keys(-filter)] { if [info exists keys(-filter)] {
set cells [filter_lib_cells $keys(-filter) $cells 1] set cells [filter_lib_cells $keys(-filter) $cells]
} }
return $cells return $cells
} }
@ -621,7 +621,7 @@ proc get_lib_pins { args } {
} }
} }
if [info exists keys(-filter)] { if [info exists keys(-filter)] {
set ports [filter_lib_pins $keys(-filter) $ports 1] set ports [filter_lib_pins $keys(-filter) $ports]
} }
return $ports return $ports
} }
@ -671,7 +671,7 @@ proc get_libs { args } {
} }
} }
if [info exists keys(-filter)] { if [info exists keys(-filter)] {
set libs [filter_liberty_libraries $keys(-filter) $libs 1] set libs [filter_liberty_libraries $keys(-filter) $libs]
} }
return $libs return $libs
} }
@ -772,7 +772,7 @@ proc get_nets { args } {
} }
} }
if [info exists keys(-filter)] { if [info exists keys(-filter)] {
set nets [filter_nets $keys(-filter) $nets 1] set nets [filter_nets $keys(-filter) $nets]
} }
return $nets return $nets
} }
@ -863,7 +863,7 @@ proc get_pins { args } {
} }
} }
if [info exists keys(-filter)] { if [info exists keys(-filter)] {
set pins [filter_pins $keys(-filter) $pins 1] set pins [filter_pins $keys(-filter) $pins]
} }
return $pins return $pins
} }
@ -919,7 +919,7 @@ proc get_ports { args } {
} }
} }
if [info exists keys(-filter)] { if [info exists keys(-filter)] {
set ports [filter_ports $keys(-filter) $ports 1] set ports [filter_ports $keys(-filter) $ports]
} }
return $ports return $ports
} }

View File

@ -564,7 +564,7 @@ PropertyValue::to_string(const Network *network) const
case Type::float_: case Type::float_:
return unit_->asString(float_, 6); return unit_->asString(float_, 6);
case Type::bool_: case Type::bool_:
// true/false would be better but these are TCL true/false values. // These are TCL true/false values.
if (bool_) if (bool_)
return "1"; return "1";
else else

View File

@ -300,7 +300,7 @@ proc get_timing_edges_cmd { cmd cmd_args } {
cmd_usage_error $cmd cmd_usage_error $cmd
} }
if [info exists keys(-filter)] { if [info exists keys(-filter)] {
set arcs [filter_timing_arcs $keys(-filter) $arcs 1] set arcs [filter_timing_arcs $keys(-filter) $arcs]
} }
return $arcs return $arcs
} }

Binary file not shown.

View File

@ -1,24 +1,11 @@
[get_cells -filter liberty_cell==BUFx2_ASAP7_75t_R *] [get_cells -filter liberty_cell==BUFx2_ASAP7_75t_R *]
u1 u1
[get_clocks -filter is_virtual==0 *]
clk
[get_clocks -filter is_virtual==1 *]
vclk
[get_clocks -filter is_virtual *] [get_clocks -filter is_virtual *]
vclk vclk
[get_clocks -filter is_virtual&&is_generated *] [get_lib_cells -filter is_buffer *]
[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 -filter is_inverter==0 *] [get_lib_cells -filter is_inverter *]
asap7_small/AND2x2_ASAP7_75t_R asap7_small/INVx2_ASAP7_75t_R
asap7_small/BUFx2_ASAP7_75t_R
asap7_small/DFFHQx4_ASAP7_75t_R
[get_lib_pins -filter direction==input BUFx2_ASAP7_75t_R/*] [get_lib_pins -filter direction==input BUFx2_ASAP7_75t_R/*]
A A
[get_lib_pins -filter direction==output BUFx2_ASAP7_75t_R/*] [get_lib_pins -filter direction==output BUFx2_ASAP7_75t_R/*]
@ -54,9 +41,22 @@ in2
out out
[get_cells -filter {name ~= *r1*} *] [get_cells -filter {name ~= *r1*} *]
Error: 2600 -filter parsing failed at '~= *r1*'. Error: 2600 -filter parsing failed at '~= *r1*'.
direction == input && name =~ clk*
clk1 clk1
clk2 clk2
clk3 clk3
(direction == input) && (name =~ clk*)"
clk1 clk1
clk2 clk2
clk3 clk3
[get_clocks -filter is_virtual||is_generated *]
vclk
[get_clocks -filter is_virtual==0 *]
clk
[get_clocks -filter is_virtual==false *]
clk
[get_clocks -filter is_virtual==1 *]
vclk
[get_clocks -filter is_virtual==true *]
vclk
{direction == input} {name =~ clk*} {is_clock == 1} && &&

View File

@ -5,29 +5,16 @@ link_design top
create_clock -name clk -period 500 {clk1 clk2 clk3} 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 get_* command.
puts {[get_cells -filter liberty_cell==BUFx2_ASAP7_75t_R *]} 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 -filter is_virtual==0 *]}
report_object_full_names [get_clocks -filter is_virtual==0 *]
puts {[get_clocks -filter is_virtual==1 *]}
report_object_full_names [get_clocks -filter is_virtual==1 *]
puts {[get_clocks -filter is_virtual *]} puts {[get_clocks -filter is_virtual *]}
report_object_full_names [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 *]} puts {[get_lib_cells -filter is_buffer *]}
report_object_full_names [get_lib_cells -filter is_buffer==1 *] report_object_full_names [get_lib_cells -filter is_buffer *]
puts {[get_lib_cells -filter is_inverter==0 *]} puts {[get_lib_cells -filter is_inverter *]}
report_object_full_names [get_lib_cells -filter is_inverter==0 *] report_object_full_names [get_lib_cells -filter is_inverter *]
puts {[get_lib_pins -filter direction==input BUFx2_ASAP7_75t_R/*]} 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/*]
@ -55,9 +42,32 @@ puts {[get_cells -filter {name ~= *r1*} *]}
catch {get_cells -filter {name ~= *r1*} *} result catch {get_cells -filter {name ~= *r1*} *} result
puts $result puts $result
# AND pattern match expr # AND expr
puts {direction == input && name =~ clk*}
report_object_names [get_ports -filter "direction == input && name =~ clk*" *] report_object_names [get_ports -filter "direction == input && name =~ clk*" *]
# parens around sub-exprs # parens around sub-exprs
puts {(direction == input) && (name =~ clk*)"}
report_object_names [get_ports -filter "(direction == input) && (name =~ clk*)" *] report_object_names [get_ports -filter "(direction == input) && (name =~ clk*)" *]
sta::filter_expr_to_postfix "direction == input && name =~ clk* && is_clock" 1 # OR expr
puts {[get_clocks -filter is_virtual||is_generated *]}
report_object_full_names [get_clocks -filter is_virtual||is_generated *]
# unary==0 / unary==false
puts {[get_clocks -filter is_virtual==0 *]}
report_object_full_names [get_clocks -filter is_virtual==0 *]
puts {[get_clocks -filter is_virtual==false *]}
report_object_full_names [get_clocks -filter is_virtual==false *]
# unary==1 / unary==true
puts {[get_clocks -filter is_virtual==1 *]}
report_object_full_names [get_clocks -filter is_virtual==1 *]
puts {[get_clocks -filter is_virtual==true *]}
report_object_full_names [get_clocks -filter is_virtual==true *]
# glob pattern with . (literal dot, no match symantics)
report_object_full_names [get_cells -filter {name =~ .1} *]
puts [sta::filter_expr_to_postfix "direction == input && name =~ clk* && is_clock"]

View File

@ -5,6 +5,7 @@ Y
[get_lib_pins -of_objects [get_lib_cells *]] [get_lib_pins -of_objects [get_lib_cells *]]
A A
A A
A
B B
CLK CLK
D D
@ -13,3 +14,4 @@ IQN
Q Q
Y Y
Y Y
Y

View File

@ -11,9 +11,11 @@ vclk
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
asap7_small/INVx2_ASAP7_75t_R
[get_lib_pins] [get_lib_pins]
A A
A A
A
B B
CLK CLK
D D
@ -22,6 +24,7 @@ IQN
Q Q
Y Y
Y Y
Y
[get_libs] [get_libs]
asap7_small asap7_small
[get_nets] [get_nets]

View File

@ -9,9 +9,11 @@ vclk
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
asap7_small/INVx2_ASAP7_75t_R
[get_lib_pins [get_lib_pins]] [get_lib_pins [get_lib_pins]]
A A
A A
A
B B
CLK CLK
D D
@ -20,6 +22,7 @@ IQN
Q Q
Y Y
Y Y
Y
[get_libs [get_libs]] [get_libs [get_libs]]
asap7_small asap7_small
[get_nets [get_nets]] [get_nets [get_nets]]