Skip to content

Commit e8a6ebe

Browse files
authored
Merge pull request #72 from akashlevy/master
Add property-based filtering (`-filter` keyword arg) on all SDC `get_*` commands (+ DRY refactor)
2 parents b59b963 + 582b419 commit e8a6ebe

File tree

10 files changed

+708
-586
lines changed

10 files changed

+708
-586
lines changed

doc/OpenSTA.odt

-818 Bytes
Binary file not shown.

doc/OpenSTA.pdf

10.7 KB
Binary file not shown.

doc/messages.txt

Lines changed: 499 additions & 457 deletions
Large diffs are not rendered by default.

sdc/Sdc.i

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1325,13 +1325,58 @@ filter_pins(const char *property,
13251325
return filter_objects<const Pin>(property, op, pattern, pins);
13261326
}
13271327

1328+
ClockSeq
1329+
filter_clocks(const char *property,
1330+
const char *op,
1331+
const char *pattern,
1332+
ClockSeq *clocks)
1333+
{
1334+
return filter_objects<Clock>(property, op, pattern, clocks);
1335+
}
1336+
1337+
LibertyCellSeq
1338+
filter_lib_cells(const char *property,
1339+
const char *op,
1340+
const char *pattern,
1341+
LibertyCellSeq *cells)
1342+
{
1343+
return filter_objects<LibertyCell>(property, op, pattern, cells);
1344+
}
1345+
1346+
LibertyPortSeq
1347+
filter_lib_pins(const char *property,
1348+
const char *op,
1349+
const char *pattern,
1350+
LibertyPortSeq *pins)
1351+
{
1352+
return filter_objects<LibertyPort>(property, op, pattern, pins);
1353+
}
1354+
1355+
LibertyLibrarySeq
1356+
filter_liberty_libraries(const char *property,
1357+
const char *op,
1358+
const char *pattern,
1359+
LibertyLibrarySeq *libs)
1360+
{
1361+
return filter_objects<LibertyLibrary>(property, op, pattern, libs);
1362+
}
1363+
1364+
NetSeq
1365+
filter_nets(const char *property,
1366+
const char *op,
1367+
const char *pattern,
1368+
NetSeq *nets)
1369+
{
1370+
return filter_objects<const Net>(property, op, pattern, nets);
1371+
}
1372+
13281373
EdgeSeq
13291374
filter_timing_arcs(const char *property,
13301375
const char *op,
13311376
const char *pattern,
13321377
EdgeSeq *edges)
13331378
{
1334-
return filter_objects<sta::Edge>(property, op, pattern, edges);
1379+
return filter_objects<Edge>(property, op, pattern, edges);
13351380
}
13361381

13371382
////////////////////////////////////////////////////////////////

sdc/Sdc.tcl

Lines changed: 58 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,36 @@ proc current_design { {design ""} } {
406406

407407
################################################################
408408

409+
# Generic get_* filter.
410+
proc filter_objs { filter objects filter_function object_type } {
411+
set filter_regexp1 {@?([a-zA-Z_]+) *(==|!=|=~|!~) *([0-9a-zA-Z_\*]+)}
412+
set filter_or_regexp "($filter_regexp1) *\\|\\| *($filter_regexp1)"
413+
set filter_and_regexp "($filter_regexp1) *&& *($filter_regexp1)"
414+
set filtered_objects {}
415+
# Ignore sub-exprs in filter_regexp1 for expr2 match var.
416+
if { [regexp $filter_or_regexp $filter ignore expr1 \
417+
ignore ignore ignore expr2] } {
418+
regexp $filter_regexp1 $expr1 ignore attr_name op arg
419+
set filtered_objects1 [$filter_function $attr_name $op $arg $objects]
420+
regexp $filter_regexp1 $expr2 ignore attr_name op arg
421+
set filtered_objects2 [$filter_function $attr_name $op $arg $objects]
422+
set filtered_objects [concat $filtered_objects1 $filtered_objects2]
423+
} elseif { [regexp $filter_and_regexp $filter ignore expr1 \
424+
ignore ignore ignore expr2] } {
425+
regexp $filter_regexp1 $expr1 ignore attr_name op arg
426+
set filtered_objects [$filter_function $attr_name $op $arg $objects]
427+
regexp $filter_regexp1 $expr2 ignore attr_name op arg
428+
set filtered_objects [$filter_function $attr_name $op $arg $filtered_objects]
429+
} elseif { [regexp $filter_regexp1 $filter ignore attr_name op arg] } {
430+
set filtered_objects [$filter_function $attr_name $op $arg $objects]
431+
} else {
432+
sta_error 350 "unsupported $object_type -filter expression."
433+
}
434+
return $filtered_objects
435+
}
436+
437+
################################################################
438+
409439
define_cmd_args "get_cells" \
410440
{[-hierarchical] [-hsc separator] [-filter expr]\
411441
[-regexp] [-nocase] [-quiet] [-of_objects objects] [patterns]}
@@ -473,46 +503,19 @@ proc get_cells { args } {
473503
}
474504
}
475505
if [info exists keys(-filter)] {
476-
set insts [filter_insts1 $keys(-filter) $insts]
506+
set insts [filter_objs $keys(-filter) $insts filter_insts "instance"]
477507
}
478508
return $insts
479509
}
480510

481-
proc filter_insts1 { filter objects } {
482-
variable filter_regexp1
483-
variable filter_or_regexp
484-
variable filter_and_regexp
485-
set filtered_objects {}
486-
# Ignore sub-exprs in filter_regexp1 for expr2 match var.
487-
if { [regexp $filter_or_regexp $filter ignore expr1 \
488-
ignore ignore ignore expr2] } {
489-
regexp $filter_regexp1 $expr1 ignore attr_name op arg
490-
set filtered_objects1 [filter_insts $attr_name $op $arg $objects]
491-
regexp $filter_regexp1 $expr2 ignore attr_name op arg
492-
set filtered_objects2 [filter_insts $attr_name $op $arg $objects]
493-
set filtered_objects [concat $filtered_objects1 $filtered_objects2]
494-
} elseif { [regexp $filter_and_regexp $filter ignore expr1 \
495-
ignore ignore ignore expr2] } {
496-
regexp $filter_regexp1 $expr1 ignore attr_name op arg
497-
set filtered_objects [filter_insts $attr_name $op $arg $objects]
498-
regexp $filter_regexp1 $expr2 ignore attr_name op arg
499-
set filtered_objects [filter_insts $attr_name $op $arg $filtered_objects]
500-
} elseif { [regexp $filter_regexp1 $filter ignore attr_name op arg] } {
501-
set filtered_objects [filter_insts $attr_name $op $arg $objects]
502-
} else {
503-
sta_error 350 "unsupported instance -filter expression."
504-
}
505-
return $filtered_objects
506-
}
507-
508511
################################################################
509512

510-
define_cmd_args "get_clocks" {[-regexp] [-nocase] [-quiet] patterns}
513+
define_cmd_args "get_clocks" {[-regexp] [-nocase] [-quiet] [-filter expr] patterns}
511514

512515
define_cmd_alias "get_clock" "get_clocks"
513516

514517
proc get_clocks { args } {
515-
parse_key_args "get_clocks" args keys {} flags {-regexp -nocase -quiet}
518+
parse_key_args "get_clocks" args keys {-filter} flags {-regexp -nocase -quiet}
516519
check_argc_eq1 "get_clocks" $args
517520
check_nocase_flag flags
518521

@@ -531,20 +534,23 @@ proc get_clocks { args } {
531534
}
532535
}
533536
}
537+
if [info exists keys(-filter)] {
538+
set clocks [filter_objs $keys(-filter) $clocks filter_clocks "clock"]
539+
}
534540
return $clocks
535541
}
536542

537543
################################################################
538544

539545
define_cmd_args "get_lib_cells" \
540-
{[-hsc separator] [-regexp] [-nocase] [-quiet]\
546+
{[-hsc separator] [-regexp] [-nocase] [-quiet] [-filter expr]\
541547
[-of_objects objects] [patterns]}
542548

543549
define_cmd_alias "get_lib_cell" "get_lib_cells"
544550

545551
proc get_lib_cells { args } {
546552
global hierarchy_separator
547-
parse_key_args "get_lib_cells" args keys {-hsc -of_objects} \
553+
parse_key_args "get_lib_cells" args keys {-hsc -of_objects -filter} \
548554
flags {-regexp -nocase -quiet}
549555
check_nocase_flag flags
550556

@@ -598,20 +604,23 @@ proc get_lib_cells { args } {
598604
}
599605
}
600606
}
607+
if [info exists keys(-filter)] {
608+
set cells [filter_objs $keys(-filter) $cells filter_lib_cells "liberty cell"]
609+
}
601610
return $cells
602611
}
603612

604613
################################################################
605614

606615
define_cmd_args "get_lib_pins" \
607-
{[-hsc separator] [-regexp] [-nocase] [-quiet] patterns}
616+
{[-hsc separator] [-regexp] [-nocase] [-quiet] [-filter expr] patterns}
608617

609618
define_cmd_alias "get_lib_pin" "get_lib_pins"
610619

611620
# "get_lib_ports" in sta terminology.
612621
proc get_lib_pins { args } {
613622
global hierarchy_separator
614-
parse_key_args "get_lib_pins" args keys {-hsc} flags {-regexp -nocase -quiet}
623+
parse_key_args "get_lib_pins" args keys {-hsc -filter} flags {-regexp -nocase -quiet}
615624
check_argc_eq1 "get_lib_pins" $args
616625
check_nocase_flag flags
617626

@@ -668,6 +677,9 @@ proc get_lib_pins { args } {
668677
}
669678
}
670679
}
680+
if [info exists keys(-filter)] {
681+
set ports [filter_objs $keys(-filter) $ports filter_lib_pins "liberty port"]
682+
}
671683
return $ports
672684
}
673685

@@ -680,12 +692,12 @@ proc check_nocase_flag { flags_var } {
680692

681693
################################################################
682694

683-
define_cmd_args "get_libs" {[-regexp] [-nocase] [-quiet] patterns}
695+
define_cmd_args "get_libs" {[-regexp] [-nocase] [-quiet] [-filter expr] patterns}
684696

685697
define_cmd_alias "get_lib" "get_libs"
686698

687699
proc get_libs { args } {
688-
parse_key_args "get_libs" args keys {} flags {-regexp -nocase -quiet}
700+
parse_key_args "get_libs" args keys {-filter} flags {-regexp -nocase -quiet}
689701
check_argc_eq1 "get_libs" $args
690702
check_nocase_flag flags
691703

@@ -704,6 +716,9 @@ proc get_libs { args } {
704716
}
705717
}
706718
}
719+
if [info exists keys(-filter)] {
720+
set libs [filter_objs $keys(-filter) $libs filter_liberty_libraries "liberty library"]
721+
}
707722
return $libs
708723
}
709724

@@ -737,15 +752,15 @@ proc find_liberty_libraries_matching { pattern regexp nocase } {
737752
################################################################
738753

739754
define_cmd_args "get_nets" \
740-
{[-hierarchical] [-hsc separator] [-regexp] [-nocase] [-quiet]\
755+
{[-hierarchical] [-hsc separator] [-regexp] [-nocase] [-quiet] [-filter expr]\
741756
[-of_objects objects] [patterns]}
742757

743758
define_cmd_alias "get_net" "get_nets"
744759

745760
proc get_nets { args } {
746761
global hierarchy_separator
747762

748-
parse_key_args get_nets args keys {-hsc -of_objects} \
763+
parse_key_args get_nets args keys {-hsc -of_objects -filter} \
749764
flags {-hierarchical -regexp -nocase -quiet}
750765
check_nocase_flag flags
751766

@@ -791,6 +806,9 @@ proc get_nets { args } {
791806
}
792807
}
793808
}
809+
if [info exists keys(-filter)] {
810+
set nets [filter_objs $keys(-filter) $nets filter_nets "net"]
811+
}
794812
return $nets
795813
}
796814

@@ -858,38 +876,11 @@ proc get_pins { args } {
858876
}
859877
}
860878
if [info exists keys(-filter)] {
861-
set pins [filter_pins1 $keys(-filter) $pins]
879+
set pins [filter_objs $keys(-filter) $pins filter_pins "pin"]
862880
}
863881
return $pins
864882
}
865883

866-
proc filter_pins1 { filter objects } {
867-
variable filter_regexp1
868-
variable filter_or_regexp
869-
variable filter_and_regexp
870-
set filtered_objects {}
871-
# Ignore sub-exprs in filter_regexp1 for expr2 match var.
872-
if { [regexp $filter_or_regexp $filter ignore expr1 \
873-
ignore ignore ignore expr2] } {
874-
regexp $filter_regexp1 $expr1 ignore attr_name op arg
875-
set filtered_objects1 [filter_pins $attr_name $op $arg $objects]
876-
regexp $filter_regexp1 $expr2 ignore attr_name op arg
877-
set filtered_objects2 [filter_pins $attr_name $op $arg $objects]
878-
set filtered_objects [concat $filtered_objects1 $filtered_objects2]
879-
} elseif { [regexp $filter_and_regexp $filter ignore expr1 \
880-
ignore ignore ignore expr2] } {
881-
regexp $filter_regexp1 $expr1 ignore attr_name op arg
882-
set filtered_objects [filter_pins $attr_name $op $arg $objects]
883-
regexp $filter_regexp1 $expr2 ignore attr_name op arg
884-
set filtered_objects [filter_pins $attr_name $op $arg $filtered_objects]
885-
} elseif { [regexp $filter_regexp1 $filter ignore attr_name op arg] } {
886-
set filtered_objects [filter_pins $attr_name $op $arg $objects]
887-
} else {
888-
sta_error 364 "unsupported pin -filter expression."
889-
}
890-
return $filtered_objects
891-
}
892-
893884
################################################################
894885

895886
define_cmd_args "get_ports" \
@@ -930,42 +921,11 @@ proc get_ports { args } {
930921
}
931922
}
932923
if [info exists keys(-filter)] {
933-
set ports [filter_ports1 $keys(-filter) $ports]
924+
set ports [filter_objs $keys(-filter) $ports filter_ports "port"]
934925
}
935926
return $ports
936927
}
937928

938-
variable filter_regexp1 {@?([a-zA-Z_]+) *(==|!=|=~|!~) *([0-9a-zA-Z_\*]+)}
939-
variable filter_or_regexp "($filter_regexp1) *\\|\\| *($filter_regexp1)"
940-
variable filter_and_regexp "($filter_regexp1) *&& *($filter_regexp1)"
941-
942-
proc filter_ports1 { filter objects } {
943-
variable filter_regexp1
944-
variable filter_or_regexp
945-
variable filter_and_regexp
946-
set filtered_objects {}
947-
# Ignore sub-exprs in filter_regexp1 for expr2 match var.
948-
if { [regexp $filter_or_regexp $filter ignore expr1 \
949-
ignore ignore ignore expr2] } {
950-
regexp $filter_regexp1 $expr1 ignore attr_name op arg
951-
set filtered_objects1 [filter_ports $attr_name $op $arg $objects]
952-
regexp $filter_regexp1 $expr2 ignore attr_name op arg
953-
set filtered_objects2 [filter_ports $attr_name $op $arg $objects]
954-
set filtered_objects [concat $filtered_objects1 $filtered_objects2]
955-
} elseif { [regexp $filter_and_regexp $filter ignore expr1 \
956-
ignore ignore ignore expr2] } {
957-
regexp $filter_regexp1 $expr1 ignore attr_name op arg
958-
set filtered_objects [filter_ports $attr_name $op $arg $objects]
959-
regexp $filter_regexp1 $expr2 ignore attr_name op arg
960-
set filtered_objects [filter_ports $attr_name $op $arg $filtered_objects]
961-
} elseif { [regexp $filter_regexp1 $filter ignore attr_name op arg] } {
962-
set filtered_objects [filter_ports $attr_name $op $arg $objects]
963-
} else {
964-
sta_error 367 "unsupported port -filter expression."
965-
}
966-
return $filtered_objects
967-
}
968-
969929
################################################################
970930
#
971931
# Timing Constraints

tcl/Sta.tcl

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ proc get_timing_edges_cmd { cmd cmd_args } {
171171
cmd_usage_error $cmd
172172
}
173173
if [info exists keys(-filter)] {
174-
set arcs [filter_timing_arcs1 $keys(-filter) $arcs]
174+
set arcs [filter_objs $keys(-filter) $arcs filter_timing_arcs "timing arc"]
175175
}
176176
return $arcs
177177
}
@@ -260,34 +260,6 @@ proc get_timing_arcs_to { to_pin_arg } {
260260
return $edges
261261
}
262262

263-
proc filter_timing_arcs1 { filter objects } {
264-
variable filter_regexp1
265-
variable filter_or_regexp
266-
variable filter_and_regexp
267-
set filtered_objects {}
268-
# Ignore sub-exprs in filter_regexp1 for expr2 match var.
269-
if { [regexp $filter_or_regexp $filter ignore expr1 \
270-
ignore ignore ignore expr2] } {
271-
regexp $filter_regexp1 $expr1 ignore attr_name op arg
272-
set filtered_objects1 [filter_timing_arcs $attr_name $op $arg $objects]
273-
regexp $filter_regexp1 $expr2 ignore attr_name op arg
274-
set filtered_objects2 [filter_timing_arcs $attr_name $op $arg $objects]
275-
set filtered_objects [concat $filtered_objects1 $filtered_objects2]
276-
} elseif { [regexp $filter_and_regexp $filter ignore expr1 \
277-
ignore ignore ignore expr2] } {
278-
regexp $filter_regexp1 $expr1 ignore attr_name op arg
279-
set filtered_objects [filter_timing_arcs $attr_name $op $arg $objects]
280-
regexp $filter_regexp1 $expr2 ignore attr_name op arg
281-
set filtered_objects [filter_timing_arcs $attr_name $op \
282-
$arg $filtered_objects]
283-
} elseif { [regexp $filter_regexp1 $filter ignore attr_name op arg] } {
284-
set filtered_objects [filter_timing_arcs $attr_name $op $arg $objects]
285-
} else {
286-
sta_error 541 "unsupported -filter expression."
287-
}
288-
return $filtered_objects
289-
}
290-
291263
################################################################
292264

293265
define_cmd_args "report_clock_properties" {[clocks]}

0 commit comments

Comments
 (0)