Sta::insert_buffer
This commit is contained in:
parent
325e284441
commit
895c4c97c1
|
|
@ -80,6 +80,20 @@ for compatibility in this current release.
|
|||
The read_parasitics command has been renamed read_spef and no longer
|
||||
supports the SPF format.
|
||||
|
||||
....
|
||||
|
||||
The make_net command now takes a single net name argument and returns
|
||||
the net.
|
||||
|
||||
The delete_instance command deletes a single instance instead of a list
|
||||
of instances.
|
||||
|
||||
The delete_net command deletes a single net instead of a list
|
||||
of nets.
|
||||
|
||||
The disconnect_pins command is renamed disconnect_pin and disconnects a
|
||||
single pin.
|
||||
|
||||
Release 1.11.0 2017/08/18
|
||||
-------------------------
|
||||
|
||||
|
|
|
|||
BIN
doc/OpenSTA.odt
BIN
doc/OpenSTA.odt
Binary file not shown.
|
|
@ -1231,6 +1231,14 @@ ConcreteNetwork::makeTerm(Pin *pin,
|
|||
return reinterpret_cast<Term*>(cterm);
|
||||
}
|
||||
|
||||
Pin *
|
||||
ConcreteNetwork::connect(Instance *inst,
|
||||
LibertyPort *port,
|
||||
Net *net)
|
||||
{
|
||||
return connect(inst, reinterpret_cast<Port*>(port), net);
|
||||
}
|
||||
|
||||
Pin *
|
||||
ConcreteNetwork::connect(Instance *inst,
|
||||
Port *port,
|
||||
|
|
|
|||
|
|
@ -196,6 +196,9 @@ public:
|
|||
virtual Pin *connect(Instance *inst,
|
||||
Port *port,
|
||||
Net *net);
|
||||
virtual Pin *connect(Instance *inst,
|
||||
LibertyPort *port,
|
||||
Net *net);
|
||||
virtual void disconnectPin(Pin *pin);
|
||||
virtual void deletePin(Pin *pin);
|
||||
virtual Net *makeNet(const char *name,
|
||||
|
|
|
|||
|
|
@ -491,6 +491,9 @@ public:
|
|||
virtual Pin *connect(Instance *inst,
|
||||
Port *port,
|
||||
Net *net) = 0;
|
||||
virtual Pin *connect(Instance *inst,
|
||||
LibertyPort *port,
|
||||
Net *net) = 0;
|
||||
// makePin/connectPin replaced by connect.
|
||||
virtual void connectPin(Pin *pin,
|
||||
Net *net) __attribute__ ((deprecated));
|
||||
|
|
|
|||
|
|
@ -943,6 +943,14 @@ NetworkNameAdapter::connect(Instance *inst,
|
|||
return network_edit_->connect(inst, port, net);
|
||||
}
|
||||
|
||||
Pin *
|
||||
NetworkNameAdapter::connect(Instance *inst,
|
||||
LibertyPort *port,
|
||||
Net *net)
|
||||
{
|
||||
return network_edit_->connect(inst, port, net);
|
||||
}
|
||||
|
||||
void
|
||||
NetworkNameAdapter::disconnectPin(Pin *pin)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -130,6 +130,9 @@ public:
|
|||
virtual Pin *connect(Instance *inst,
|
||||
Port *port,
|
||||
Net *net);
|
||||
virtual Pin *connect(Instance *inst,
|
||||
LibertyPort *port,
|
||||
Net *net);
|
||||
virtual void disconnectPin(Pin *pin);
|
||||
virtual void deleteNet(Net *net);
|
||||
virtual void deletePin(Pin *pin);
|
||||
|
|
|
|||
|
|
@ -3673,6 +3673,16 @@ Sta::connectPin(Instance *inst,
|
|||
connectPinAfter(pin);
|
||||
}
|
||||
|
||||
void
|
||||
Sta::connectPin(Instance *inst,
|
||||
LibertyPort *port,
|
||||
Net *net)
|
||||
{
|
||||
NetworkEdit *network = networkCmdEdit();
|
||||
Pin *pin = network->connect(inst, port, net);
|
||||
connectPinAfter(pin);
|
||||
}
|
||||
|
||||
void
|
||||
Sta::disconnectPin(Pin *pin)
|
||||
{
|
||||
|
|
@ -3681,6 +3691,47 @@ Sta::disconnectPin(Pin *pin)
|
|||
network->disconnectPin(pin);
|
||||
}
|
||||
|
||||
void
|
||||
Sta::insertBuffer(const char *buffer_name,
|
||||
LibertyCell *buffer_cell,
|
||||
Net *net,
|
||||
PinSeq *load_pins,
|
||||
const char *buffer_out_net_name)
|
||||
{
|
||||
Instance *parent = network_->topInstance();
|
||||
LibertyPort *buffer_in_port = findCellPort(buffer_cell, PortDirection::input());
|
||||
LibertyPort *buffer_out_port = findCellPort(buffer_cell, PortDirection::output());
|
||||
if (buffer_in_port && buffer_out_port) {
|
||||
Instance *buffer = makeInstance(buffer_name, buffer_cell, parent);
|
||||
connectPin(buffer, buffer_in_port, net);
|
||||
|
||||
Net *buffer_out_net = makeNet(buffer_out_net_name, parent);
|
||||
connectPin(buffer, buffer_out_port, buffer_out_net);
|
||||
|
||||
PinSeq::Iterator pin_iter(load_pins);
|
||||
while (pin_iter.hasNext()) {
|
||||
Pin *load_pin = pin_iter.next();
|
||||
auto load_inst = network_->instance(load_pin);
|
||||
auto load_port = network_->port(load_pin);
|
||||
disconnectPin(load_pin);
|
||||
connectPin(load_inst, load_port, buffer_out_net);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LibertyPort *
|
||||
Sta::findCellPort(LibertyCell *cell,
|
||||
PortDirection *dir)
|
||||
{
|
||||
LibertyCellPortIterator port_iter(cell);
|
||||
while (port_iter.hasNext()) {
|
||||
auto port = port_iter.next();
|
||||
if (port->direction() == dir)
|
||||
return port;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Network edit before/after methods.
|
||||
|
|
|
|||
|
|
@ -1081,11 +1081,9 @@ public:
|
|||
float elmore);
|
||||
|
||||
// TCL network edit function support.
|
||||
// create_cell
|
||||
virtual Instance *makeInstance(const char *name,
|
||||
LibertyCell *cell,
|
||||
Instance *parent);
|
||||
// remove_cell
|
||||
virtual void deleteInstance(Instance *inst);
|
||||
// replace_cell
|
||||
virtual void replaceCell(Instance *inst,
|
||||
|
|
@ -1097,9 +1095,22 @@ public:
|
|||
virtual void connectPin(Instance *inst,
|
||||
Port *port,
|
||||
Net *net);
|
||||
virtual void connectPin(Instance *inst,
|
||||
LibertyPort *port,
|
||||
Net *net);
|
||||
// disconnect_net
|
||||
virtual void disconnectPin(Pin *pin);
|
||||
|
||||
// Insert a buffer_cell instance named inst_name by adding it's input
|
||||
// pin on net and moving load_pins from net to the output of
|
||||
// the instance. buffer_cell must have one input and one output port.
|
||||
// The buffer's parent is the top_instance.
|
||||
void insertBuffer(const char *buffer_name,
|
||||
LibertyCell *buffer_cell,
|
||||
Net *net,
|
||||
PinSeq *load_pins,
|
||||
const char *buffer_out_net_name);
|
||||
|
||||
// Network edit before/after methods.
|
||||
void makeInstanceAfter(Instance *inst);
|
||||
// Not used by Sta (connectPinAfter).
|
||||
|
|
@ -1292,6 +1303,8 @@ protected:
|
|||
void powerPreamble();
|
||||
void disableFanoutCrprPruning(Vertex *vertex,
|
||||
int &fanou);
|
||||
LibertyPort *findCellPort(LibertyCell *cell,
|
||||
PortDirection *dir);
|
||||
|
||||
CmdNamespace cmd_namespace_;
|
||||
Instance *current_instance_;
|
||||
|
|
|
|||
|
|
@ -93,4 +93,16 @@ disconnect_pin_cmd(Pin *pin)
|
|||
Sta::sta()->disconnectPin(pin);
|
||||
}
|
||||
|
||||
void
|
||||
insert_buffer_cmd(const char *buffer_name,
|
||||
LibertyCell *buffer_cell,
|
||||
Net *net,
|
||||
PinSeq *load_pins,
|
||||
const char *buffer_out_net_name)
|
||||
{
|
||||
Sta::sta()->insertBuffer(buffer_name, buffer_cell, net, load_pins,
|
||||
buffer_out_net_name);
|
||||
delete load_pins;
|
||||
}
|
||||
|
||||
%} // inline
|
||||
|
|
|
|||
|
|
@ -18,7 +18,66 @@
|
|||
|
||||
namespace eval sta {
|
||||
|
||||
proc connect_pin { net pin } {
|
||||
set insts_port [parse_connect_pin $pin]
|
||||
if { $insts_port == 0 } {
|
||||
return 0
|
||||
}
|
||||
set net [get_net_warn "net" $net]
|
||||
if { $net == "NULL" } {
|
||||
return 0
|
||||
}
|
||||
lassign $insts_port inst port
|
||||
connect_pin_cmd $inst $port $net
|
||||
return 1
|
||||
}
|
||||
|
||||
proc parse_connect_pin { arg } {
|
||||
set path_regexp [path_regexp]
|
||||
set insts_port {}
|
||||
if { [is_object $arg] } {
|
||||
set object_type [object_type $arg]
|
||||
if { $object_type == "Pin" } {
|
||||
set pin $arg
|
||||
set inst [$pin instance]
|
||||
set port [$pin port]
|
||||
} elseif { $object_type == "Port" } {
|
||||
# Explicit port arg - convert to pin.
|
||||
set pin [find_pin [get_name $arg]]
|
||||
set inst [$pin instance]
|
||||
set port [$pin port]
|
||||
} else {
|
||||
sta_error "unsupported object type $object_type."
|
||||
}
|
||||
} else {
|
||||
if {[regexp $path_regexp $arg ignore path_name port_name]} {
|
||||
set inst [find_instance $path_name]
|
||||
if { $inst == "NULL" } {
|
||||
return 0
|
||||
}
|
||||
} else {
|
||||
set inst [top_instance]
|
||||
set port_name $arg
|
||||
}
|
||||
set cell [$inst cell]
|
||||
set port [$cell find_port $port_name]
|
||||
if { $port == "NULL" } {
|
||||
return 0
|
||||
}
|
||||
set pin [$inst find_pin $port_name]
|
||||
}
|
||||
|
||||
# Make sure the pin is not currently connected to a net.
|
||||
if { $pin != "NULL" \
|
||||
&& ![$pin is_hierarchical] \
|
||||
&& [$pin net] != "NULL" } {
|
||||
return 0
|
||||
}
|
||||
return [list $inst $port]
|
||||
}
|
||||
|
||||
proc connect_pins { net pins } {
|
||||
sta_warn "connect_pins is deprecated. Use connect_pin."
|
||||
# Visit the pins to make sure command will succeed.
|
||||
set insts_ports [parse_connect_pins $pins]
|
||||
if { $insts_ports == 0 } {
|
||||
|
|
@ -36,105 +95,61 @@ proc connect_pins { net pins } {
|
|||
|
||||
proc parse_connect_pins { arg } {
|
||||
set path_regexp [path_regexp]
|
||||
set insts_ports {}
|
||||
set inst_ports {}
|
||||
# Copy backslashes that will be removed by foreach.
|
||||
set arg [string map {\\ \\\\} $arg]
|
||||
foreach obj $arg {
|
||||
if { [is_object $obj] } {
|
||||
set object_type [object_type $obj]
|
||||
if { $object_type == "Pin" } {
|
||||
set pin $obj
|
||||
set inst [$pin instance]
|
||||
set port [$pin port]
|
||||
} elseif { $object_type == "Port" } {
|
||||
# Explicit port arg - convert to pin.
|
||||
set pin [find_pin [get_name $obj]]
|
||||
set inst [$pin instance]
|
||||
set port [$pin port]
|
||||
} else {
|
||||
sta_error "unsupported object type $object_type."
|
||||
}
|
||||
} else {
|
||||
if {[regexp $path_regexp $obj ignore path_name port_name]} {
|
||||
set inst [find_instance $path_name]
|
||||
if { $inst == "NULL" } {
|
||||
return 0
|
||||
}
|
||||
} else {
|
||||
set inst [top_instance]
|
||||
set port_name $obj
|
||||
}
|
||||
set cell [$inst cell]
|
||||
set port [$cell find_port $port_name]
|
||||
if { $port == "NULL" } {
|
||||
return 0
|
||||
}
|
||||
set pin [$inst find_pin $port_name]
|
||||
}
|
||||
|
||||
# Make sure the pin is not currently connected to a net.
|
||||
if { $pin != "NULL" \
|
||||
&& ![$pin is_hierarchical] \
|
||||
&& [$pin net] != "NULL" } {
|
||||
set inst_port [parse_connect_pin $obj]
|
||||
if { $inst_port == 0 } {
|
||||
return 0
|
||||
}
|
||||
lappend insts_ports $inst $port
|
||||
set inst_ports [concat $inst_ports $inst_port]
|
||||
}
|
||||
return $insts_ports
|
||||
return $inst_ports
|
||||
}
|
||||
|
||||
################################################################
|
||||
|
||||
proc delete_instance { instances } {
|
||||
# Copy backslashes that will be removed by foreach.
|
||||
set instances1 [string map {\\ \\\\} $instances]
|
||||
foreach obj $instances1 {
|
||||
if { [is_object $obj] } {
|
||||
set object_type [object_type $obj]
|
||||
if { $object_type == "Instance" } {
|
||||
set inst $obj
|
||||
} else {
|
||||
sta_error "unsupported object type $object_type."
|
||||
}
|
||||
proc delete_instance { instance } {
|
||||
if { [is_object $instance] } {
|
||||
set object_type [object_type $instance]
|
||||
if { $object_type == "Instance" } {
|
||||
set inst $obj
|
||||
} else {
|
||||
set inst [find_instance $obj]
|
||||
}
|
||||
if { $inst != "NULL" } {
|
||||
delete_instance_cmd $inst
|
||||
sta_error "unsupported object type $object_type."
|
||||
}
|
||||
} else {
|
||||
set inst [find_instance $instance]
|
||||
}
|
||||
if { $inst != "NULL" } {
|
||||
delete_instance_cmd $inst
|
||||
}
|
||||
}
|
||||
|
||||
################################################################
|
||||
|
||||
proc delete_net { net_list } {
|
||||
# Copy backslashes that will be removed by foreach.
|
||||
set net_list [string map {\\ \\\\} $net_list]
|
||||
foreach obj $net_list {
|
||||
if { [is_object $obj] } {
|
||||
set object_type [object_type $obj]
|
||||
if { $object_type == "Net" } {
|
||||
set net $obj
|
||||
} else {
|
||||
sta_error "unsupported object type $object_type."
|
||||
}
|
||||
} else {
|
||||
set net [find_net $obj]
|
||||
}
|
||||
if { $net != "NULL" } {
|
||||
delete_net_cmd $net
|
||||
proc delete_net { net } {
|
||||
if { [is_object $net] } {
|
||||
set object_type [object_type $net]
|
||||
if { $object_type != "Net" } {
|
||||
sta_error "unsupported object type $object_type."
|
||||
}
|
||||
} else {
|
||||
set net [find_net $net]
|
||||
}
|
||||
if { $net != "NULL" } {
|
||||
delete_net_cmd $net
|
||||
}
|
||||
}
|
||||
|
||||
################################################################
|
||||
|
||||
proc disconnect_pins { net pins } {
|
||||
proc disconnect_pin { net pin } {
|
||||
set net [get_net_warn "net" $net]
|
||||
if { $net == "NULL" } {
|
||||
return 0
|
||||
}
|
||||
if { $pins == "-all" } {
|
||||
if { $pin == "-all" } {
|
||||
set iter [$net connected_pin_iterator]
|
||||
while {[$iter has_next]} {
|
||||
set pin [$iter next]
|
||||
|
|
@ -143,46 +158,43 @@ proc disconnect_pins { net pins } {
|
|||
$iter finish
|
||||
return 1
|
||||
} else {
|
||||
# Copy backslashes that will be removed by foreach.
|
||||
set pins [string map {\\ \\\\} $pins]
|
||||
# Visit the pins to make sure command will succeed.
|
||||
foreach pin $pins {
|
||||
set pin1 [get_port_pin_warn "pin" $pin]
|
||||
if { $pin1 == "NULL" } {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
foreach pin $pins {
|
||||
set pin1 [get_port_pin_warn "pin" $pin]
|
||||
set pin1 [get_port_pin_warn "pin" $pin]
|
||||
if { $pin1 == "NULL" } {
|
||||
return 0
|
||||
} else {
|
||||
disconnect_pin_cmd $pin1
|
||||
return 1
|
||||
}
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
proc disconnect_pins { net pins } {
|
||||
sta_warn "disconnect_pins is deprecated. Use disconnect_pin."
|
||||
foreach pin $pins {
|
||||
disconnect_pin $net $pins
|
||||
}
|
||||
}
|
||||
|
||||
################################################################
|
||||
|
||||
proc make_instance { inst_names lib_cell } {
|
||||
proc make_instance { inst_path lib_cell } {
|
||||
set lib_cell [get_lib_cell_warn "lib_cell" $lib_cell]
|
||||
if { $lib_cell != "NULL" } {
|
||||
set path_regexp [path_regexp]
|
||||
foreach inst_path $inst_names {
|
||||
if {[regexp $path_regexp $inst_path ignore path_name inst_name]} {
|
||||
set parent [find_instance $path_name]
|
||||
if { $parent == "NULL" } {
|
||||
# Parent instance not found. This could be a typo, but since
|
||||
# SDC does not escape hierarchy dividers it can also be
|
||||
# an escaped name.
|
||||
set inst_name $inst_path
|
||||
set parent [top_instance]
|
||||
}
|
||||
} else {
|
||||
if {[regexp $path_regexp $inst_path ignore path_name inst_name]} {
|
||||
set parent [find_instance $path_name]
|
||||
if { $parent == "NULL" } {
|
||||
# Parent instance not found. This could be a typo, but since
|
||||
# SDC does not escape hierarchy dividers it can also be
|
||||
# an escaped name.
|
||||
set inst_name $inst_path
|
||||
set parent [top_instance]
|
||||
}
|
||||
make_instance_cmd $inst_name $lib_cell $parent
|
||||
} else {
|
||||
set inst_name $inst_path
|
||||
set parent [top_instance]
|
||||
}
|
||||
return 1
|
||||
return [make_instance_cmd $inst_name $lib_cell $parent]
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
|
|
@ -190,29 +202,19 @@ proc make_instance { inst_names lib_cell } {
|
|||
|
||||
################################################################
|
||||
|
||||
proc make_net { net_list } {
|
||||
# Visit the net names to make sure command will succeed.
|
||||
set path_regexp [path_regexp]
|
||||
foreach net $net_list {
|
||||
if {[regexp $path_regexp $net ignore path_name net_name]} {
|
||||
set parent [find_instance $path_name]
|
||||
if { $parent == "NULL" } {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
}
|
||||
proc make_net { net_name } {
|
||||
# Copy backslashes that will be removed by foreach.
|
||||
set net_list [string map {\\ \\\\} $net_list]
|
||||
foreach net $net_list {
|
||||
if {[regexp $path_regexp $net ignore path_name net_name]} {
|
||||
set parent [find_instance $path_name]
|
||||
} else {
|
||||
set net_name $net
|
||||
set parent [top_instance]
|
||||
set net_name [string map {\\ \\\\} $net_name]
|
||||
set path_regexp [path_regexp]
|
||||
if {[regexp $path_regexp $net_name ignore path_name net_name]} {
|
||||
set parent [find_instance $path_name]
|
||||
if { $parent == "NULL" } {
|
||||
return 0
|
||||
}
|
||||
make_net_cmd $net_name $parent
|
||||
} else {
|
||||
set parent [top_instance]
|
||||
}
|
||||
return 1
|
||||
return [make_net_cmd $net_name $parent]
|
||||
}
|
||||
|
||||
################################################################
|
||||
|
|
@ -237,5 +239,23 @@ proc replace_cell { instances lib_cell } {
|
|||
}
|
||||
}
|
||||
|
||||
################################################################
|
||||
|
||||
proc insert_buffer { buffer_name buffer_cell net load_pins buffer_out_net_name } {
|
||||
set buffer_cell [sta::get_lib_cell_warn "buffer_cell" $buffer_cell]
|
||||
set net [sta::get_net_warn "net" $net]
|
||||
|
||||
# Copy backslashes that will be removed by foreach.
|
||||
set load_pins1 [string map {\\ \\\\} $load_pins]
|
||||
set load_pins {}
|
||||
foreach pin $load_pins1 {
|
||||
set pin1 [get_port_pin_warn "pin" $pin]
|
||||
if { $pin1 != "NULL" } {
|
||||
lappend load_pins $pin1
|
||||
}
|
||||
}
|
||||
insert_buffer_cmd $buffer_name $buffer_cell $net $load_pins $buffer_out_net_name
|
||||
}
|
||||
|
||||
# sta namespace end.
|
||||
}
|
||||
|
|
|
|||
|
|
@ -677,12 +677,16 @@ proc unset_timing_derate { args } {
|
|||
#
|
||||
################################################################
|
||||
|
||||
define_sta_cmd_args "connect_pin" {net pins}
|
||||
# deprecated 2.0.16 05/02/2019
|
||||
define_sta_cmd_args "connect_pins" {net pins}
|
||||
|
||||
define_sta_cmd_args "delete_instance" {cell_list}
|
||||
|
||||
define_sta_cmd_args "delete_net" {net_list}
|
||||
|
||||
define_sta_cmd_args "disconnect_pin" {net -all|pin}
|
||||
# deprecated 2.0.16 05/02/2019
|
||||
define_sta_cmd_args "disconnect_pins" {net -all|pins}
|
||||
|
||||
define_sta_cmd_args "make_instance" {inst_names lib_cell}
|
||||
|
|
@ -691,6 +695,9 @@ define_sta_cmd_args "make_net" {}
|
|||
|
||||
define_sta_cmd_args "replace_cell" {instances lib_cell}
|
||||
|
||||
define_sta_cmd_args "insert_buffer" {buffer_name buffer_cell net load_pins\
|
||||
buffer_out_net_name}
|
||||
|
||||
################################################################
|
||||
#
|
||||
# Delay calculation commands
|
||||
|
|
|
|||
Loading…
Reference in New Issue