Merge remote-tracking branch 'parallax/master'
This commit is contained in:
commit
fe280fcf8b
|
|
@ -336,6 +336,7 @@ add_custom_command(OUTPUT ${STA_TCL_INIT}
|
|||
# Do not use REQUIRED because it also requires TK, which is not used by OpenSTA.
|
||||
find_package(TCL)
|
||||
|
||||
# Referenced by util/StaConfig.hh.cmake
|
||||
set(TCL_READLINE 0)
|
||||
# check for tclReadline
|
||||
if (USE_TCL_READLINE)
|
||||
|
|
@ -352,13 +353,19 @@ if (USE_TCL_READLINE)
|
|||
)
|
||||
if (TCL_READLINE_LIBRARY)
|
||||
message(STATUS "TCL readline library: ${TCL_READLINE_LIBRARY}")
|
||||
# Referenced by StaConfig.hh.cmake
|
||||
set(TCL_READLINE 1)
|
||||
else()
|
||||
message(STATUS "TCL readline library: NOT FOUND")
|
||||
endif()
|
||||
|
||||
find_path(TCL_READLINE_INCLUDE tclreadline.h)
|
||||
if (TCL_READLINE_INCLUDE)
|
||||
message(STATUS "TCL readline header: ${TCL_READLINE_INCLUDE}/tclreadline.h")
|
||||
else()
|
||||
message(STATUS "TCL readline header: NOT FOUND")
|
||||
endif()
|
||||
|
||||
if (TCL_READLINE_LIBRARY AND TCL_READLINE_INCLUDE)
|
||||
set(TCL_READLINE 1)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
|
@ -515,21 +522,14 @@ target_link_libraries(OpenSTA
|
|||
${CUDD_LIB}
|
||||
)
|
||||
|
||||
if (TCL_READLINE_LIBRARY)
|
||||
target_link_libraries(OpenSTA ${TCL_READLINE_LIBRARY})
|
||||
endif()
|
||||
|
||||
if (ZLIB_LIBRARIES)
|
||||
target_link_libraries(OpenSTA ${ZLIB_LIBRARIES})
|
||||
endif()
|
||||
|
||||
target_link_libraries(OpenSTA )
|
||||
|
||||
target_include_directories(OpenSTA
|
||||
PUBLIC
|
||||
include
|
||||
${TCL_INCLUDE_PATH}
|
||||
${TCL_READLINE_INCLUDE}
|
||||
|
||||
PRIVATE
|
||||
include/sta
|
||||
|
|
@ -537,6 +537,13 @@ target_include_directories(OpenSTA
|
|||
${CUDD_INCLUDE}
|
||||
)
|
||||
|
||||
if (TCL_READLINE)
|
||||
target_link_libraries(OpenSTA ${TCL_READLINE_LIBRARY})
|
||||
target_include_directories(OpenSTA
|
||||
PUBLIC
|
||||
${TCL_READLINE_INCLUDE})
|
||||
endif()
|
||||
|
||||
# common to gcc/clang
|
||||
set(CXX_FLAGS -Wall -Wextra -pedantic -Wcast-qual -Wredundant-decls -Wformat-security)
|
||||
|
||||
|
|
|
|||
|
|
@ -2,31 +2,32 @@ FROM ubuntu:18.04
|
|||
LABEL author="James Cherry"
|
||||
LABEL maintainer="James Cherry <cherry@parallaxsw.com>"
|
||||
|
||||
# install basics
|
||||
# Install basics
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
RUN apt-get update && \
|
||||
apt-get install -y wget apt-utils git cmake gcc tcl-dev swig bison flex
|
||||
apt-get install -y wget cmake gcc tcl-dev tcl-tclreadline libeigen3-dev swig bison flex
|
||||
|
||||
# download CUDD
|
||||
RUN wget https://www.davidkebo.com/source/cudd_versions/cudd-3.0.0.tar.gz && \
|
||||
# Download CUDD
|
||||
RUN wget https://raw.githubusercontent.com/davidkebo/cudd/main/cudd_versions/cudd-3.0.0.tar.gz && \
|
||||
tar -xvf cudd-3.0.0.tar.gz && \
|
||||
rm cudd-3.0.0.tar.gz
|
||||
|
||||
# install CUDD
|
||||
# Install CUDD
|
||||
RUN cd cudd-3.0.0 && \
|
||||
mkdir ../cudd && \
|
||||
./configure --prefix=$HOME/cudd && \
|
||||
make && \
|
||||
./configure && \
|
||||
make -j`nproc` && \
|
||||
make install
|
||||
|
||||
# copy files and install OpenSTA
|
||||
# Copy files and install OpenSTA
|
||||
RUN mkdir OpenSTA
|
||||
COPY . OpenSTA
|
||||
RUN cd OpenSTA && \
|
||||
rm -rf build && \
|
||||
mkdir build && \
|
||||
cd build && \
|
||||
cmake .. -DCUDD=$HOME/cudd && \
|
||||
make
|
||||
cmake .. && \
|
||||
make -j`nproc`
|
||||
|
||||
# Run sta on entry
|
||||
ENTRYPOINT ["OpenSTA/app/sta"]
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <cstdlib> // exit
|
||||
#include <filesystem>
|
||||
#include <tcl.h>
|
||||
#if TCL_READLINE
|
||||
#include <tclreadline.h>
|
||||
|
|
|
|||
BIN
doc/OpenSTA.odt
BIN
doc/OpenSTA.odt
Binary file not shown.
BIN
doc/OpenSTA.pdf
BIN
doc/OpenSTA.pdf
Binary file not shown.
956
doc/messages.txt
956
doc/messages.txt
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,85 @@
|
|||
#!/bin/sh
|
||||
# The next line is executed by /bin/sh, but not Tcl \
|
||||
exec tclsh $0 ${1+"$@"}
|
||||
|
||||
# Parallax Static Timing Analyzer
|
||||
# Copyright (c) 2020, Parallax Software, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# No part of this document may be copied, transmitted or
|
||||
# disclosed in any form or fashion without the express
|
||||
# written consent of Parallax Software, Inc.
|
||||
|
||||
# Find warning/error message IDs and detect collisions.
|
||||
# Usage: FindMessages.tcl > doc/messages.txt
|
||||
|
||||
proc scan_file { file warn_regexp } {
|
||||
global msgs
|
||||
|
||||
if { [file exists $file] } {
|
||||
set in_stream [open $file r]
|
||||
gets $in_stream line
|
||||
set file_line 1
|
||||
|
||||
while { ![eof $in_stream] } {
|
||||
if { [regexp -- $warn_regexp $line ignore1 ignore2 msg_id msg] } {
|
||||
lappend msgs "$msg_id $file $file_line $msg"
|
||||
}
|
||||
gets $in_stream line
|
||||
incr file_line
|
||||
}
|
||||
close $in_stream
|
||||
} else {
|
||||
puts "Warning: file $file not found."
|
||||
}
|
||||
}
|
||||
|
||||
set subdirs {app dcalc graph liberty network parasitics \
|
||||
power sdc sdf search spice util verilog tcl}
|
||||
set files_c {}
|
||||
foreach subdir $subdirs {
|
||||
set files [glob -nocomplain [file join $subdir "*.{cc,hh,yy,ll,i}"]]
|
||||
set files_c [concat $files_c $files]
|
||||
}
|
||||
set warn_regexp_c {(criticalError|->warn|->fileWarn|->error|->fileError|libWarn|libError| warn)\(([0-9]+),.*(".+")}
|
||||
|
||||
set files_tcl {}
|
||||
foreach subdir $subdirs {
|
||||
set files_tcl [concat $files_tcl [glob -nocomplain [file join $subdir "*.tcl"]]]
|
||||
}
|
||||
set warn_regexp_tcl {(sta_warn|sta_error|sta_warn_error) ([0-9]+) (".+")}
|
||||
|
||||
proc scan_files {files warn_regexp } {
|
||||
foreach file $files {
|
||||
scan_file $file $warn_regexp
|
||||
}
|
||||
}
|
||||
|
||||
proc check_msgs { } {
|
||||
global msgs
|
||||
|
||||
set msgs [lsort -index 0 -integer $msgs]
|
||||
set prev_id -1
|
||||
foreach msg $msgs {
|
||||
set msg_id [lindex $msg 0]
|
||||
if { $msg_id == $prev_id } {
|
||||
puts "Warning: $msg_id duplicated"
|
||||
}
|
||||
set prev_id $msg_id
|
||||
}
|
||||
}
|
||||
|
||||
proc report_msgs { } {
|
||||
global msgs
|
||||
|
||||
foreach msg_info $msgs {
|
||||
lassign $msg_info msg_id file line msg1
|
||||
puts "[format %04d $msg_id] [format %-25s [file tail $file]:$line] $msg1"
|
||||
}
|
||||
}
|
||||
|
||||
set msgs {}
|
||||
scan_files $files_c $warn_regexp_c
|
||||
scan_files $files_tcl $warn_regexp_tcl
|
||||
check_msgs
|
||||
report_msgs
|
||||
|
|
@ -59,7 +59,7 @@ LibertyLibrary::LibertyLibrary(const char *name,
|
|||
const char *filename) :
|
||||
ConcreteLibrary(name, filename, true),
|
||||
units_(new Units()),
|
||||
delay_model_type_(DelayModelType::cmos_linear), // default
|
||||
delay_model_type_(DelayModelType::table), // default
|
||||
nominal_process_(0.0),
|
||||
nominal_voltage_(0.0),
|
||||
nominal_temperature_(0.0),
|
||||
|
|
|
|||
|
|
@ -2153,11 +2153,9 @@ LibertyReader::makeStatetable()
|
|||
LibertyPortSeq internal_ports;
|
||||
for (const string &internal : statetable_->internalPorts()) {
|
||||
LibertyPort *port = cell_->findLibertyPort(internal.c_str());
|
||||
if (port)
|
||||
internal_ports.push_back(port);
|
||||
else
|
||||
libWarn(0000, statetable_->line(), "statetable internal port %s not found.",
|
||||
internal.c_str());
|
||||
if (port == nullptr)
|
||||
port = builder_.makePort(cell_, internal.c_str());
|
||||
internal_ports.push_back(port);
|
||||
}
|
||||
cell_->makeStatetable(input_ports, internal_ports, statetable_->table());
|
||||
statetable_ = nullptr;
|
||||
|
|
@ -3860,7 +3858,7 @@ LibertyReader::beginSequential(LibertyGroup *group,
|
|||
if (has_size)
|
||||
out_port = builder_.makeBusPort(cell_, out_name, size - 1, 0, nullptr);
|
||||
else
|
||||
out_port = builder_.makePort(cell_,out_name);
|
||||
out_port = builder_.makePort(cell_, out_name);
|
||||
out_port->setDirection(PortDirection::internal());
|
||||
}
|
||||
if (out_inv_name) {
|
||||
|
|
|
|||
47
sdc/Sdc.i
47
sdc/Sdc.i
|
|
@ -1325,13 +1325,58 @@ filter_pins(const char *property,
|
|||
return filter_objects<const Pin>(property, op, pattern, pins);
|
||||
}
|
||||
|
||||
ClockSeq
|
||||
filter_clocks(const char *property,
|
||||
const char *op,
|
||||
const char *pattern,
|
||||
ClockSeq *clocks)
|
||||
{
|
||||
return filter_objects<Clock>(property, op, pattern, clocks);
|
||||
}
|
||||
|
||||
LibertyCellSeq
|
||||
filter_lib_cells(const char *property,
|
||||
const char *op,
|
||||
const char *pattern,
|
||||
LibertyCellSeq *cells)
|
||||
{
|
||||
return filter_objects<LibertyCell>(property, op, pattern, cells);
|
||||
}
|
||||
|
||||
LibertyPortSeq
|
||||
filter_lib_pins(const char *property,
|
||||
const char *op,
|
||||
const char *pattern,
|
||||
LibertyPortSeq *pins)
|
||||
{
|
||||
return filter_objects<LibertyPort>(property, op, pattern, pins);
|
||||
}
|
||||
|
||||
LibertyLibrarySeq
|
||||
filter_liberty_libraries(const char *property,
|
||||
const char *op,
|
||||
const char *pattern,
|
||||
LibertyLibrarySeq *libs)
|
||||
{
|
||||
return filter_objects<LibertyLibrary>(property, op, pattern, libs);
|
||||
}
|
||||
|
||||
NetSeq
|
||||
filter_nets(const char *property,
|
||||
const char *op,
|
||||
const char *pattern,
|
||||
NetSeq *nets)
|
||||
{
|
||||
return filter_objects<const Net>(property, op, pattern, nets);
|
||||
}
|
||||
|
||||
EdgeSeq
|
||||
filter_timing_arcs(const char *property,
|
||||
const char *op,
|
||||
const char *pattern,
|
||||
EdgeSeq *edges)
|
||||
{
|
||||
return filter_objects<sta::Edge>(property, op, pattern, edges);
|
||||
return filter_objects<Edge>(property, op, pattern, edges);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
156
sdc/Sdc.tcl
156
sdc/Sdc.tcl
|
|
@ -406,6 +406,36 @@ 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)"
|
||||
set filtered_objects {}
|
||||
# Ignore sub-exprs in filter_regexp1 for expr2 match var.
|
||||
if { [regexp $filter_or_regexp $filter ignore expr1 \
|
||||
ignore ignore ignore expr2] } {
|
||||
regexp $filter_regexp1 $expr1 ignore attr_name op arg
|
||||
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]
|
||||
} elseif { [regexp $filter_and_regexp $filter ignore expr1 \
|
||||
ignore ignore ignore expr2] } {
|
||||
regexp $filter_regexp1 $expr1 ignore attr_name op arg
|
||||
set filtered_objects [$filter_function $attr_name $op $arg $objects]
|
||||
regexp $filter_regexp1 $expr2 ignore attr_name op arg
|
||||
set filtered_objects [$filter_function $attr_name $op $arg $filtered_objects]
|
||||
} elseif { [regexp $filter_regexp1 $filter ignore attr_name op arg] } {
|
||||
set filtered_objects [$filter_function $attr_name $op $arg $objects]
|
||||
} else {
|
||||
sta_error 350 "unsupported $object_type -filter expression."
|
||||
}
|
||||
return $filtered_objects
|
||||
}
|
||||
|
||||
################################################################
|
||||
|
||||
define_cmd_args "get_cells" \
|
||||
{[-hierarchical] [-hsc separator] [-filter expr]\
|
||||
[-regexp] [-nocase] [-quiet] [-of_objects objects] [patterns]}
|
||||
|
|
@ -473,46 +503,19 @@ proc get_cells { args } {
|
|||
}
|
||||
}
|
||||
if [info exists keys(-filter)] {
|
||||
set insts [filter_insts1 $keys(-filter) $insts]
|
||||
set insts [filter_objs $keys(-filter) $insts filter_insts "instance"]
|
||||
}
|
||||
return $insts
|
||||
}
|
||||
|
||||
proc filter_insts1 { filter objects } {
|
||||
variable filter_regexp1
|
||||
variable filter_or_regexp
|
||||
variable filter_and_regexp
|
||||
set filtered_objects {}
|
||||
# Ignore sub-exprs in filter_regexp1 for expr2 match var.
|
||||
if { [regexp $filter_or_regexp $filter ignore expr1 \
|
||||
ignore ignore ignore expr2] } {
|
||||
regexp $filter_regexp1 $expr1 ignore attr_name op arg
|
||||
set filtered_objects1 [filter_insts $attr_name $op $arg $objects]
|
||||
regexp $filter_regexp1 $expr2 ignore attr_name op arg
|
||||
set filtered_objects2 [filter_insts $attr_name $op $arg $objects]
|
||||
set filtered_objects [concat $filtered_objects1 $filtered_objects2]
|
||||
} elseif { [regexp $filter_and_regexp $filter ignore expr1 \
|
||||
ignore ignore ignore expr2] } {
|
||||
regexp $filter_regexp1 $expr1 ignore attr_name op arg
|
||||
set filtered_objects [filter_insts $attr_name $op $arg $objects]
|
||||
regexp $filter_regexp1 $expr2 ignore attr_name op arg
|
||||
set filtered_objects [filter_insts $attr_name $op $arg $filtered_objects]
|
||||
} elseif { [regexp $filter_regexp1 $filter ignore attr_name op arg] } {
|
||||
set filtered_objects [filter_insts $attr_name $op $arg $objects]
|
||||
} else {
|
||||
sta_error 350 "unsupported instance -filter expression."
|
||||
}
|
||||
return $filtered_objects
|
||||
}
|
||||
|
||||
################################################################
|
||||
|
||||
define_cmd_args "get_clocks" {[-regexp] [-nocase] [-quiet] patterns}
|
||||
define_cmd_args "get_clocks" {[-regexp] [-nocase] [-quiet] [-filter expr] patterns}
|
||||
|
||||
define_cmd_alias "get_clock" "get_clocks"
|
||||
|
||||
proc get_clocks { args } {
|
||||
parse_key_args "get_clocks" args keys {} flags {-regexp -nocase -quiet}
|
||||
parse_key_args "get_clocks" args keys {-filter} flags {-regexp -nocase -quiet}
|
||||
check_argc_eq1 "get_clocks" $args
|
||||
check_nocase_flag flags
|
||||
|
||||
|
|
@ -531,20 +534,23 @@ proc get_clocks { args } {
|
|||
}
|
||||
}
|
||||
}
|
||||
if [info exists keys(-filter)] {
|
||||
set clocks [filter_objs $keys(-filter) $clocks filter_clocks "clock"]
|
||||
}
|
||||
return $clocks
|
||||
}
|
||||
|
||||
################################################################
|
||||
|
||||
define_cmd_args "get_lib_cells" \
|
||||
{[-hsc separator] [-regexp] [-nocase] [-quiet]\
|
||||
{[-hsc separator] [-regexp] [-nocase] [-quiet] [-filter expr]\
|
||||
[-of_objects objects] [patterns]}
|
||||
|
||||
define_cmd_alias "get_lib_cell" "get_lib_cells"
|
||||
|
||||
proc get_lib_cells { args } {
|
||||
global hierarchy_separator
|
||||
parse_key_args "get_lib_cells" args keys {-hsc -of_objects} \
|
||||
parse_key_args "get_lib_cells" args keys {-hsc -of_objects -filter} \
|
||||
flags {-regexp -nocase -quiet}
|
||||
check_nocase_flag flags
|
||||
|
||||
|
|
@ -598,20 +604,23 @@ proc get_lib_cells { args } {
|
|||
}
|
||||
}
|
||||
}
|
||||
if [info exists keys(-filter)] {
|
||||
set cells [filter_objs $keys(-filter) $cells filter_lib_cells "liberty cell"]
|
||||
}
|
||||
return $cells
|
||||
}
|
||||
|
||||
################################################################
|
||||
|
||||
define_cmd_args "get_lib_pins" \
|
||||
{[-hsc separator] [-regexp] [-nocase] [-quiet] patterns}
|
||||
{[-hsc separator] [-regexp] [-nocase] [-quiet] [-filter expr] patterns}
|
||||
|
||||
define_cmd_alias "get_lib_pin" "get_lib_pins"
|
||||
|
||||
# "get_lib_ports" in sta terminology.
|
||||
proc get_lib_pins { args } {
|
||||
global hierarchy_separator
|
||||
parse_key_args "get_lib_pins" args keys {-hsc} flags {-regexp -nocase -quiet}
|
||||
parse_key_args "get_lib_pins" args keys {-hsc -filter} flags {-regexp -nocase -quiet}
|
||||
check_argc_eq1 "get_lib_pins" $args
|
||||
check_nocase_flag flags
|
||||
|
||||
|
|
@ -668,6 +677,9 @@ proc get_lib_pins { args } {
|
|||
}
|
||||
}
|
||||
}
|
||||
if [info exists keys(-filter)] {
|
||||
set ports [filter_objs $keys(-filter) $ports filter_lib_pins "liberty port"]
|
||||
}
|
||||
return $ports
|
||||
}
|
||||
|
||||
|
|
@ -680,12 +692,12 @@ proc check_nocase_flag { flags_var } {
|
|||
|
||||
################################################################
|
||||
|
||||
define_cmd_args "get_libs" {[-regexp] [-nocase] [-quiet] patterns}
|
||||
define_cmd_args "get_libs" {[-regexp] [-nocase] [-quiet] [-filter expr] patterns}
|
||||
|
||||
define_cmd_alias "get_lib" "get_libs"
|
||||
|
||||
proc get_libs { args } {
|
||||
parse_key_args "get_libs" args keys {} flags {-regexp -nocase -quiet}
|
||||
parse_key_args "get_libs" args keys {-filter} flags {-regexp -nocase -quiet}
|
||||
check_argc_eq1 "get_libs" $args
|
||||
check_nocase_flag flags
|
||||
|
||||
|
|
@ -704,6 +716,9 @@ proc get_libs { args } {
|
|||
}
|
||||
}
|
||||
}
|
||||
if [info exists keys(-filter)] {
|
||||
set libs [filter_objs $keys(-filter) $libs filter_liberty_libraries "liberty library"]
|
||||
}
|
||||
return $libs
|
||||
}
|
||||
|
||||
|
|
@ -737,7 +752,7 @@ proc find_liberty_libraries_matching { pattern regexp nocase } {
|
|||
################################################################
|
||||
|
||||
define_cmd_args "get_nets" \
|
||||
{[-hierarchical] [-hsc separator] [-regexp] [-nocase] [-quiet]\
|
||||
{[-hierarchical] [-hsc separator] [-regexp] [-nocase] [-quiet] [-filter expr]\
|
||||
[-of_objects objects] [patterns]}
|
||||
|
||||
define_cmd_alias "get_net" "get_nets"
|
||||
|
|
@ -745,7 +760,7 @@ define_cmd_alias "get_net" "get_nets"
|
|||
proc get_nets { args } {
|
||||
global hierarchy_separator
|
||||
|
||||
parse_key_args get_nets args keys {-hsc -of_objects} \
|
||||
parse_key_args get_nets args keys {-hsc -of_objects -filter} \
|
||||
flags {-hierarchical -regexp -nocase -quiet}
|
||||
check_nocase_flag flags
|
||||
|
||||
|
|
@ -791,6 +806,9 @@ proc get_nets { args } {
|
|||
}
|
||||
}
|
||||
}
|
||||
if [info exists keys(-filter)] {
|
||||
set nets [filter_objs $keys(-filter) $nets filter_nets "net"]
|
||||
}
|
||||
return $nets
|
||||
}
|
||||
|
||||
|
|
@ -858,38 +876,11 @@ proc get_pins { args } {
|
|||
}
|
||||
}
|
||||
if [info exists keys(-filter)] {
|
||||
set pins [filter_pins1 $keys(-filter) $pins]
|
||||
set pins [filter_objs $keys(-filter) $pins filter_pins "pin"]
|
||||
}
|
||||
return $pins
|
||||
}
|
||||
|
||||
proc filter_pins1 { filter objects } {
|
||||
variable filter_regexp1
|
||||
variable filter_or_regexp
|
||||
variable filter_and_regexp
|
||||
set filtered_objects {}
|
||||
# Ignore sub-exprs in filter_regexp1 for expr2 match var.
|
||||
if { [regexp $filter_or_regexp $filter ignore expr1 \
|
||||
ignore ignore ignore expr2] } {
|
||||
regexp $filter_regexp1 $expr1 ignore attr_name op arg
|
||||
set filtered_objects1 [filter_pins $attr_name $op $arg $objects]
|
||||
regexp $filter_regexp1 $expr2 ignore attr_name op arg
|
||||
set filtered_objects2 [filter_pins $attr_name $op $arg $objects]
|
||||
set filtered_objects [concat $filtered_objects1 $filtered_objects2]
|
||||
} elseif { [regexp $filter_and_regexp $filter ignore expr1 \
|
||||
ignore ignore ignore expr2] } {
|
||||
regexp $filter_regexp1 $expr1 ignore attr_name op arg
|
||||
set filtered_objects [filter_pins $attr_name $op $arg $objects]
|
||||
regexp $filter_regexp1 $expr2 ignore attr_name op arg
|
||||
set filtered_objects [filter_pins $attr_name $op $arg $filtered_objects]
|
||||
} elseif { [regexp $filter_regexp1 $filter ignore attr_name op arg] } {
|
||||
set filtered_objects [filter_pins $attr_name $op $arg $objects]
|
||||
} else {
|
||||
sta_error 364 "unsupported pin -filter expression."
|
||||
}
|
||||
return $filtered_objects
|
||||
}
|
||||
|
||||
################################################################
|
||||
|
||||
define_cmd_args "get_ports" \
|
||||
|
|
@ -930,42 +921,11 @@ proc get_ports { args } {
|
|||
}
|
||||
}
|
||||
if [info exists keys(-filter)] {
|
||||
set ports [filter_ports1 $keys(-filter) $ports]
|
||||
set ports [filter_objs $keys(-filter) $ports filter_ports "port"]
|
||||
}
|
||||
return $ports
|
||||
}
|
||||
|
||||
variable filter_regexp1 {@?([a-zA-Z_]+) *(==|!=|=~|!~) *([0-9a-zA-Z_\*]+)}
|
||||
variable filter_or_regexp "($filter_regexp1) *\\|\\| *($filter_regexp1)"
|
||||
variable filter_and_regexp "($filter_regexp1) *&& *($filter_regexp1)"
|
||||
|
||||
proc filter_ports1 { filter objects } {
|
||||
variable filter_regexp1
|
||||
variable filter_or_regexp
|
||||
variable filter_and_regexp
|
||||
set filtered_objects {}
|
||||
# Ignore sub-exprs in filter_regexp1 for expr2 match var.
|
||||
if { [regexp $filter_or_regexp $filter ignore expr1 \
|
||||
ignore ignore ignore expr2] } {
|
||||
regexp $filter_regexp1 $expr1 ignore attr_name op arg
|
||||
set filtered_objects1 [filter_ports $attr_name $op $arg $objects]
|
||||
regexp $filter_regexp1 $expr2 ignore attr_name op arg
|
||||
set filtered_objects2 [filter_ports $attr_name $op $arg $objects]
|
||||
set filtered_objects [concat $filtered_objects1 $filtered_objects2]
|
||||
} elseif { [regexp $filter_and_regexp $filter ignore expr1 \
|
||||
ignore ignore ignore expr2] } {
|
||||
regexp $filter_regexp1 $expr1 ignore attr_name op arg
|
||||
set filtered_objects [filter_ports $attr_name $op $arg $objects]
|
||||
regexp $filter_regexp1 $expr2 ignore attr_name op arg
|
||||
set filtered_objects [filter_ports $attr_name $op $arg $filtered_objects]
|
||||
} elseif { [regexp $filter_regexp1 $filter ignore attr_name op arg] } {
|
||||
set filtered_objects [filter_ports $attr_name $op $arg $objects]
|
||||
} else {
|
||||
sta_error 367 "unsupported port -filter expression."
|
||||
}
|
||||
return $filtered_objects
|
||||
}
|
||||
|
||||
################################################################
|
||||
#
|
||||
# Timing Constraints
|
||||
|
|
|
|||
30
tcl/Sta.tcl
30
tcl/Sta.tcl
|
|
@ -171,7 +171,7 @@ proc get_timing_edges_cmd { cmd cmd_args } {
|
|||
cmd_usage_error $cmd
|
||||
}
|
||||
if [info exists keys(-filter)] {
|
||||
set arcs [filter_timing_arcs1 $keys(-filter) $arcs]
|
||||
set arcs [filter_objs $keys(-filter) $arcs filter_timing_arcs "timing arc"]
|
||||
}
|
||||
return $arcs
|
||||
}
|
||||
|
|
@ -260,34 +260,6 @@ proc get_timing_arcs_to { to_pin_arg } {
|
|||
return $edges
|
||||
}
|
||||
|
||||
proc filter_timing_arcs1 { filter objects } {
|
||||
variable filter_regexp1
|
||||
variable filter_or_regexp
|
||||
variable filter_and_regexp
|
||||
set filtered_objects {}
|
||||
# Ignore sub-exprs in filter_regexp1 for expr2 match var.
|
||||
if { [regexp $filter_or_regexp $filter ignore expr1 \
|
||||
ignore ignore ignore expr2] } {
|
||||
regexp $filter_regexp1 $expr1 ignore attr_name op arg
|
||||
set filtered_objects1 [filter_timing_arcs $attr_name $op $arg $objects]
|
||||
regexp $filter_regexp1 $expr2 ignore attr_name op arg
|
||||
set filtered_objects2 [filter_timing_arcs $attr_name $op $arg $objects]
|
||||
set filtered_objects [concat $filtered_objects1 $filtered_objects2]
|
||||
} elseif { [regexp $filter_and_regexp $filter ignore expr1 \
|
||||
ignore ignore ignore expr2] } {
|
||||
regexp $filter_regexp1 $expr1 ignore attr_name op arg
|
||||
set filtered_objects [filter_timing_arcs $attr_name $op $arg $objects]
|
||||
regexp $filter_regexp1 $expr2 ignore attr_name op arg
|
||||
set filtered_objects [filter_timing_arcs $attr_name $op \
|
||||
$arg $filtered_objects]
|
||||
} elseif { [regexp $filter_regexp1 $filter ignore attr_name op arg] } {
|
||||
set filtered_objects [filter_timing_arcs $attr_name $op $arg $objects]
|
||||
} else {
|
||||
sta_error 541 "unsupported -filter expression."
|
||||
}
|
||||
return $filtered_objects
|
||||
}
|
||||
|
||||
################################################################
|
||||
|
||||
define_cmd_args "report_clock_properties" {[clocks]}
|
||||
|
|
|
|||
|
|
@ -524,6 +524,10 @@ using namespace sta;
|
|||
seqTclList<CellSeq, Cell>($1, SWIGTYPE_p_Cell, interp);
|
||||
}
|
||||
|
||||
%typemap(in) LibertyCellSeq* {
|
||||
$1 = tclListSeqPtr<LibertyCell*>($input, SWIGTYPE_p_LibertyCell, interp);
|
||||
}
|
||||
|
||||
%typemap(out) LibertyCellSeq * {
|
||||
seqPtrTclList<LibertyCellSeq, LibertyCell>($1, SWIGTYPE_p_LibertyCell, interp);
|
||||
}
|
||||
|
|
@ -532,6 +536,10 @@ using namespace sta;
|
|||
seqTclList<LibertyCellSeq, LibertyCell>($1, SWIGTYPE_p_LibertyCell, interp);
|
||||
}
|
||||
|
||||
%typemap(in) LibertyPortSeq* {
|
||||
$1 = tclListSeqPtr<LibertyPort*>($input, SWIGTYPE_p_LibertyPort, interp);
|
||||
}
|
||||
|
||||
%typemap(out) LibertyPortSeq {
|
||||
seqTclList<LibertyPortSeq, LibertyPort>($1, SWIGTYPE_p_LibertyPort, interp);
|
||||
}
|
||||
|
|
@ -750,6 +758,14 @@ using namespace sta;
|
|||
Tcl_SetObjResult(interp, obj);
|
||||
}
|
||||
|
||||
%typemap(in) LibertyLibrarySeq* {
|
||||
$1 = tclListSeqPtr<LibertyLibrary*>($input, SWIGTYPE_p_LibertyLibrary, interp);
|
||||
}
|
||||
|
||||
%typemap(out) LibertyLibrarySeq {
|
||||
seqTclList<LibertyLibrarySeq, LibertyLibrary>($1, SWIGTYPE_p_LibertyLibrary, interp);
|
||||
}
|
||||
|
||||
%typemap(out) Pin* {
|
||||
Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false);
|
||||
Tcl_SetObjResult(interp, obj);
|
||||
|
|
@ -759,7 +775,6 @@ using namespace sta;
|
|||
seqPtrTclList<PinSeq, Pin>($1, SWIGTYPE_p_Pin, interp);
|
||||
}
|
||||
|
||||
|
||||
%typemap(out) PinSeq {
|
||||
seqTclList<PinSeq, Pin>($1, SWIGTYPE_p_Pin, interp);
|
||||
}
|
||||
|
|
@ -769,6 +784,10 @@ using namespace sta;
|
|||
Tcl_SetObjResult(interp, obj);
|
||||
}
|
||||
|
||||
%typemap(in) NetSeq* {
|
||||
$1 = tclListSeqPtr<const Net*>($input, SWIGTYPE_p_Net, interp);
|
||||
}
|
||||
|
||||
%typemap(out) NetSeq* {
|
||||
seqPtrTclList<NetSeq, Net>($1, SWIGTYPE_p_Net, interp);
|
||||
}
|
||||
|
|
@ -810,6 +829,10 @@ using namespace sta;
|
|||
$1 = tclListSeq<const Clock*>($input, SWIGTYPE_p_Clock, interp);
|
||||
}
|
||||
|
||||
%typemap(in) ClockSeq* {
|
||||
$1 = tclListSeqPtr<Clock*>($input, SWIGTYPE_p_Clock, interp);
|
||||
}
|
||||
|
||||
%typemap(out) ClockSeq* {
|
||||
seqPtrTclList<ClockSeq, Clock>($1, SWIGTYPE_p_Clock, interp);
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -0,0 +1,45 @@
|
|||
get_cells
|
||||
u1
|
||||
get_clocks
|
||||
clk
|
||||
get_clocks 2
|
||||
vclk
|
||||
get_lib_cells
|
||||
asap7_small/BUFx2_ASAP7_75t_R
|
||||
get_lib_cells 2
|
||||
asap7_small/AND2x2_ASAP7_75t_R
|
||||
asap7_small/BUFx2_ASAP7_75t_R
|
||||
asap7_small/DFFHQx4_ASAP7_75t_R
|
||||
get_lib_pins
|
||||
A
|
||||
get_lib_pins 2
|
||||
Y
|
||||
get_libs
|
||||
asap7_small
|
||||
get_nets
|
||||
r1q
|
||||
r2q
|
||||
get_pins
|
||||
r1/CLK
|
||||
r1/D
|
||||
r2/CLK
|
||||
r2/D
|
||||
r3/CLK
|
||||
r3/D
|
||||
u1/A
|
||||
u2/A
|
||||
u2/B
|
||||
get_pins 2
|
||||
r1/Q
|
||||
r2/Q
|
||||
r3/Q
|
||||
u1/Y
|
||||
u2/Y
|
||||
get_ports
|
||||
clk1
|
||||
clk2
|
||||
clk3
|
||||
in1
|
||||
in2
|
||||
get_ports 2
|
||||
out
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
# Read in design and libraries
|
||||
read_liberty asap7_small.lib.gz
|
||||
read_verilog reg1_asap7.v
|
||||
link_design top
|
||||
create_clock -name clk -period 500 {clk1 clk2 clk3}
|
||||
create_clock -name vclk -period 1000
|
||||
|
||||
# Test filters for each SDC command
|
||||
puts "get_cells"
|
||||
report_object_full_names [get_cells -filter liberty_cell==BUFx2_ASAP7_75t_R *]
|
||||
puts "get_clocks"
|
||||
report_object_full_names [get_clocks -filter is_virtual==0 *]
|
||||
puts "get_clocks 2"
|
||||
report_object_full_names [get_clocks -filter is_virtual==1 *]
|
||||
puts "get_lib_cells"
|
||||
report_object_full_names [get_lib_cells -filter is_buffer==1 *]
|
||||
puts "get_lib_cells 2"
|
||||
report_object_full_names [get_lib_cells -filter is_inverter==0 *]
|
||||
puts "get_lib_pins"
|
||||
report_object_full_names [get_lib_pins -filter direction==input BUFx2_ASAP7_75t_R/*]
|
||||
puts "get_lib_pins 2"
|
||||
report_object_full_names [get_lib_pins -filter direction==output BUFx2_ASAP7_75t_R/*]
|
||||
puts "get_libs"
|
||||
report_object_full_names [get_libs -filter name==asap7_small *]
|
||||
puts "get_nets"
|
||||
report_object_full_names [get_nets -filter name=~*q *]
|
||||
puts "get_pins"
|
||||
report_object_full_names [get_pins -filter direction==input *]
|
||||
puts "get_pins 2"
|
||||
report_object_full_names [get_pins -filter direction==output *]
|
||||
puts "get_ports"
|
||||
report_object_full_names [get_ports -filter direction==input *]
|
||||
puts "get_ports 2"
|
||||
report_object_full_names [get_ports -filter direction==output *]
|
||||
|
|
@ -125,6 +125,7 @@ record_sta_tests {
|
|||
prima3
|
||||
verilog_attribute
|
||||
liberty_arcs_one2one
|
||||
get_filter
|
||||
}
|
||||
|
||||
define_test_group fast [group_tests all]
|
||||
|
|
|
|||
Loading…
Reference in New Issue