Skip to content

Commit 25f588a

Browse files
authored
Merge pull request #7845 from The-OpenROAD-Project-staging/secure-jhkim-test
rsz: added -buffer_cell & -verbose arguments for buffer_ports command
2 parents eb3857b + 598ab3c commit 25f588a

24 files changed

+557
-37
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
*.orig
1212
*.vscode
1313
*.sw[opqr]
14+
*.code-workspace
1415
TAGS
1516
*~
1617
\#*#

src/rsz/README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,14 +208,15 @@ The `buffer_ports -inputs` command adds a buffer between the input and its
208208
loads. The `buffer_ports -outputs` adds a buffer between the port driver
209209
and the output port. Inserting buffers on input and output ports makes
210210
the block input capacitances and output drives independent of the block
211-
internals.
211+
internals. It uses the buffer library cell defined by `-buffer_cell` if it is given.
212212

213213
```tcl
214214
buffer_ports
215215
[-inputs]
216216
[-outputs]
217217
[-max_utilization util]
218218
[-buffer_cell buf_cell]
219+
[-verbose]
219220
```
220221

221222
#### Options
@@ -224,6 +225,8 @@ buffer_ports
224225
| ----- | ----- |
225226
| `-inputs`, `-outputs` | Insert a buffer between the input and load, output and load respectively. The default behavior is `-inputs` and `-outputs` set if neither is specified. |
226227
| `-max_utilization` | Defines the percentage of core area used. |
228+
| `-buffer_cell` | Specifies the buffer cell type to be used. |
229+
| `-verbose` | Enable verbose logging. |
227230

228231
#### Instance Name Prefixes
229232

src/rsz/include/rsz/Resizer.hh

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -259,8 +259,8 @@ class Resizer : public dbStaState, public dbNetworkObserver
259259
// Remove all or selected buffers from the netlist.
260260
void removeBuffers(InstanceSeq insts);
261261
void unbufferNet(Net* net);
262-
void bufferInputs();
263-
void bufferOutputs();
262+
void bufferInputs(LibertyCell* buffer_cell = nullptr, bool verbose = false);
263+
void bufferOutputs(LibertyCell* buffer_cell = nullptr, bool verbose = false);
264264

265265
// from sta::dbNetworkObserver callbacks
266266
void postReadLiberty() override;
@@ -446,8 +446,10 @@ class Resizer : public dbStaState, public dbNetworkObserver
446446
double computeDesignArea();
447447
void initDesignArea();
448448
void ensureLevelDrvrVertices();
449-
Instance* bufferInput(const Pin* top_pin, LibertyCell* buffer_cell);
450-
void bufferOutput(const Pin* top_pin, LibertyCell* buffer_cell);
449+
Instance* bufferInput(const Pin* top_pin,
450+
LibertyCell* buffer_cell,
451+
bool verbose);
452+
void bufferOutput(const Pin* top_pin, LibertyCell* buffer_cell, bool verbose);
451453
bool hasTristateOrDontTouchDriver(const Net* net);
452454
bool isTristateDriver(const Pin* pin);
453455
void checkLibertyForAllCorners();
@@ -457,6 +459,7 @@ class Resizer : public dbStaState, public dbNetworkObserver
457459
float max_drive_resist);
458460
void findBuffers();
459461
void findFastBuffers();
462+
LibertyCell* selectBufferCell(LibertyCell* buffer_cell = nullptr);
460463
bool isLinkCell(LibertyCell* cell) const;
461464
void findTargetLoads();
462465
void balanceBin(const std::vector<odb::dbInst*>& bin,

src/rsz/src/Resizer.cc

Lines changed: 77 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -746,17 +746,44 @@ void Resizer::findBuffers()
746746
}
747747
}
748748

749+
LibertyCell* Resizer::selectBufferCell(LibertyCell* user_buffer_cell)
750+
{
751+
// Prefer user-specified buffer cell if provided.
752+
if (user_buffer_cell) {
753+
return user_buffer_cell;
754+
}
755+
756+
// Otherwise, find the weakest buffer with the lowest drive resistance.
757+
findBuffers(); // updates buffer_lowest_drive_
758+
759+
// No buffer?
760+
if (buffer_lowest_drive_ == nullptr) {
761+
logger_->error(RSZ, 23, "No buffers found.");
762+
}
763+
764+
return buffer_lowest_drive_;
765+
}
766+
749767
bool Resizer::isLinkCell(LibertyCell* cell) const
750768
{
751769
return network_->findLibertyCell(cell->name()) == cell;
752770
}
753771

754772
////////////////////////////////////////////////////////////////
755773

756-
void Resizer::bufferInputs()
774+
void Resizer::bufferInputs(LibertyCell* buffer_cell, bool verbose)
757775
{
758776
init();
759-
findBuffers();
777+
778+
// Use buffer_cell. If it is null, find the buffer w/ lowest drive resistance.
779+
LibertyCell* selected_buffer_cell = selectBufferCell(buffer_cell);
780+
if (verbose) {
781+
logger_->info(RSZ,
782+
29,
783+
"Start input port buffering with {}.",
784+
selected_buffer_cell->name());
785+
}
786+
760787
sta_->ensureClkNetwork();
761788
inserted_buffer_count_ = 0;
762789
buffer_moved_into_core_ = false;
@@ -776,14 +803,18 @@ void Resizer::bufferInputs()
776803
// Hands off special nets.
777804
&& !db_network_->isSpecial(net) && hasPins(net)) {
778805
// repair_design will resize to target slew.
779-
bufferInput(pin, buffer_lowest_drive_);
806+
bufferInput(pin, selected_buffer_cell, verbose);
780807
}
781808
}
782809
}
783810

811+
logger_->info(RSZ,
812+
27,
813+
"Inserted {} {} input buffers.",
814+
inserted_buffer_count_,
815+
selected_buffer_cell->name());
816+
784817
if (inserted_buffer_count_ > 0) {
785-
logger_->info(
786-
RSZ, 27, "Inserted {} input buffers.", inserted_buffer_count_);
787818
level_drvr_vertices_valid_ = false;
788819
}
789820
}
@@ -852,7 +883,9 @@ void Resizer::SwapNetNames(odb::dbITerm* iterm_to, odb::dbITerm* iterm_from)
852883
Make sure all the top pins are buffered
853884
*/
854885

855-
Instance* Resizer::bufferInput(const Pin* top_pin, LibertyCell* buffer_cell)
886+
Instance* Resizer::bufferInput(const Pin* top_pin,
887+
LibertyCell* buffer_cell,
888+
bool verbose)
856889
{
857890
dbNet* top_pin_flat_net = db_network_->flatNet(top_pin);
858891
odb::dbModNet* top_pin_hier_net = db_network_->hierNet(top_pin);
@@ -897,9 +930,20 @@ Instance* Resizer::bufferInput(const Pin* top_pin, LibertyCell* buffer_cell)
897930
delete pin_iter;
898931
// dont buffer, buffers
899932
if (has_dont_touch || !has_non_buffer) {
933+
if (verbose) {
934+
logger_->info(RSZ,
935+
213,
936+
"Skipping input port {} buffering.",
937+
network_->name(top_pin));
938+
}
900939
return nullptr;
901940
}
902941

942+
if (verbose) {
943+
logger_->info(
944+
RSZ, 214, "Buffering input port {}.", network_->name(top_pin));
945+
}
946+
903947
// make the buffer and its output net.
904948
string buffer_name = makeUniqueInstName("input");
905949
Instance* parent = db_network_->topInstance();
@@ -972,10 +1016,19 @@ Instance* Resizer::bufferInput(const Pin* top_pin, LibertyCell* buffer_cell)
9721016
return buffer;
9731017
}
9741018

975-
void Resizer::bufferOutputs()
1019+
void Resizer::bufferOutputs(LibertyCell* buffer_cell, bool verbose)
9761020
{
9771021
init();
978-
findBuffers();
1022+
1023+
// Use buffer_cell. If it is null, find the buffer w/ lowest drive resistance.
1024+
LibertyCell* selected_buffer_cell = selectBufferCell(buffer_cell);
1025+
if (verbose) {
1026+
logger_->info(RSZ,
1027+
31,
1028+
"Start output port buffering with {}.",
1029+
selected_buffer_cell->name());
1030+
}
1031+
9791032
inserted_buffer_count_ = 0;
9801033
buffer_moved_into_core_ = false;
9811034

@@ -995,14 +1048,18 @@ void Resizer::bufferOutputs()
9951048
// drivers.
9961049
&& !hasTristateOrDontTouchDriver(net) && !vertex->isConstant()
9971050
&& hasPins(net)) {
998-
bufferOutput(pin, buffer_lowest_drive_);
1051+
bufferOutput(pin, selected_buffer_cell, verbose);
9991052
}
10001053
}
10011054
}
10021055

1056+
logger_->info(RSZ,
1057+
28,
1058+
"Inserted {} {} output buffers.",
1059+
inserted_buffer_count_,
1060+
selected_buffer_cell->name());
1061+
10031062
if (inserted_buffer_count_ > 0) {
1004-
logger_->info(
1005-
RSZ, 28, "Inserted {} output buffers.", inserted_buffer_count_);
10061063
level_drvr_vertices_valid_ = false;
10071064
}
10081065
}
@@ -1039,8 +1096,15 @@ bool Resizer::isTristateDriver(const Pin* pin)
10391096
return port && port->direction()->isAnyTristate();
10401097
}
10411098

1042-
void Resizer::bufferOutput(const Pin* top_pin, LibertyCell* buffer_cell)
1099+
void Resizer::bufferOutput(const Pin* top_pin,
1100+
LibertyCell* buffer_cell,
1101+
bool verbose)
10431102
{
1103+
if (verbose) {
1104+
logger_->info(
1105+
RSZ, 215, "Buffering output port {}.", network_->name(top_pin));
1106+
}
1107+
10441108
NetworkEdit* network = networkEdit();
10451109

10461110
odb::dbITerm* top_pin_op_iterm;
@@ -1056,6 +1120,7 @@ void Resizer::bufferOutput(const Pin* top_pin, LibertyCell* buffer_cell)
10561120
sta_->disconnectPin(const_cast<Pin*>(top_pin));
10571121

10581122
LibertyPort *input, *output;
1123+
assert(buffer_cell);
10591124
buffer_cell->bufferPorts(input, output);
10601125

10611126
string buffer_name = makeUniqueInstName("output");

src/rsz/src/Resizer.i

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// SPDX-License-Identifier: BSD-3-Clause
22
// Copyright (c) 2019-2025, The OpenROAD Authors
33

4+
// clang-format off
5+
46
%{
57

68
#include <cstdint>
@@ -409,19 +411,19 @@ set_dont_touch_net(Net *net,
409411
}
410412

411413
void
412-
buffer_inputs()
414+
buffer_inputs(LibertyCell *buffer_cell, bool verbose)
413415
{
414416
ensureLinked();
415417
Resizer *resizer = getResizer();
416-
resizer->bufferInputs();
418+
resizer->bufferInputs(buffer_cell, verbose);
417419
}
418420

419421
void
420-
buffer_outputs()
422+
buffer_outputs(LibertyCell *buffer_cell, bool verbose)
421423
{
422424
ensureLinked();
423425
Resizer *resizer = getResizer();
424-
resizer->bufferOutputs();
426+
resizer->bufferOutputs(buffer_cell, verbose);
425427
}
426428

427429
void

src/rsz/src/Resizer.tcl

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,29 @@ proc get_db_tech_checked { } {
99
}
1010
return $tech
1111
}
12+
13+
proc parse_buffer_cell { keys_var } {
14+
upvar 1 $keys_var keys
15+
set buffer_cell "NULL"
16+
17+
if { [info exists keys(-buffer_cell)] } {
18+
set buffer_cell_name $keys(-buffer_cell)
19+
if { $buffer_cell_name ne "" } {
20+
set buffer_cell [sta::get_lib_cell_error "-buffer_cell" $buffer_cell_name]
21+
22+
# the lib cell is a buffer?
23+
if { $buffer_cell ne "NULL" && ![get_property $buffer_cell is_buffer] } {
24+
utl::error RSZ 211 "[get_name $buffer_cell] is not a buffer."
25+
}
26+
}
27+
}
28+
return $buffer_cell
1229
}
1330

31+
# namespace eval rsz
32+
}
33+
34+
1435
# Units are from OpenSTA (ie Liberty file or set_cmd_units).
1536
sta::define_cmd_args "set_layer_rc" { [-layer layer]\
1637
[-via via_layer]\
@@ -441,28 +462,34 @@ proc report_dont_touch { args } {
441462
}
442463

443464
sta::define_cmd_args "buffer_ports" {[-inputs] [-outputs]\
444-
[-max_utilization util]\
445-
[-buffer_cell buf_cell]}
465+
[-max_utilization util]\
466+
[-buffer_cell buf_cell]\
467+
[-verbose]}
446468

447469
proc buffer_ports { args } {
448470
sta::parse_key_args "buffer_ports" args \
449471
keys {-buffer_cell -max_utilization} \
450-
flags {-inputs -outputs}
472+
flags {-inputs -outputs -verbose}
451473

452474
set buffer_inputs [info exists flags(-inputs)]
453475
set buffer_outputs [info exists flags(-outputs)]
454476
if { !$buffer_inputs && !$buffer_outputs } {
455477
set buffer_inputs 1
456478
set buffer_outputs 1
457479
}
480+
481+
set verbose [info exists flags(-verbose)]
482+
458483
sta::check_argc_eq0 "buffer_ports" $args
459484

460485
rsz::set_max_utilization [rsz::parse_max_util keys]
486+
set buffer_cell [rsz::parse_buffer_cell keys]
487+
461488
if { $buffer_inputs } {
462-
rsz::buffer_inputs
489+
rsz::buffer_inputs $buffer_cell $verbose
463490
}
464491
if { $buffer_outputs } {
465-
rsz::buffer_outputs
492+
rsz::buffer_outputs $buffer_cell $verbose
466493
}
467494
}
468495

@@ -1056,7 +1083,7 @@ proc replace_arith_modules { args } {
10561083
if { [info exists keys(-target)] } {
10571084
set target $keys(-target)
10581085
if { [lsearch -exact {setup hold power area} $target] == -1 } {
1059-
util::error "RSZ" 164 "-target needs to be one of setup, hold, power, area"
1086+
utl::error "RSZ" 164 "-target needs to be one of setup, hold, power, area"
10601087
}
10611088
} else {
10621089
set target "setup"

src/rsz/test/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ or_integration_tests(
1212
buffer_ports6
1313
buffer_ports7
1414
buffer_ports8
15+
buffer_ports9
16+
buffer_ports10
1517
buffer_varying_lengths
1618
clone_flat
1719
clone_hier

src/rsz/test/buffer_ports1.ok

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@
44
[INFO ODB-0131] Created 5 components and 27 component-terminals.
55
[INFO ODB-0132] Created 2 special nets and 10 connections.
66
[INFO ODB-0133] Created 12 nets and 14 connections.
7-
[INFO RSZ-0027] Inserted 2 input buffers.
8-
[INFO RSZ-0028] Inserted 1 output buffers.
7+
[INFO RSZ-0027] Inserted 2 BUF_X1 input buffers.
8+
[INFO RSZ-0028] Inserted 1 BUF_X1 output buffers.
99
No differences found.

0 commit comments

Comments
 (0)