Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into drt_minor_refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
bnmfw committed Sep 26, 2024
2 parents ba0b104 + f00ed2f commit 625c965
Show file tree
Hide file tree
Showing 27 changed files with 145,911 additions and 39 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/github-actions-lint-tcl.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:

- name: Install tclint
run: |
python -m pip install tclint==0.3.2
python -m pip install tclint==0.4.1
- name: Lint
run: |
Expand Down
1 change: 1 addition & 0 deletions src/cts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ clock_tree_synthesis
| `-dont_use_dummy_load` | Don't apply dummy buffer or inverter cells at clock tree leaves to balance loads. The default values is `False`. |
| `-sink_buffer_max_cap_derate` | Use this option to control automatic buffer selection. To favor strong(weak) drive strength buffers use a small(large) value. The default value is `0.01`, meaning that buffers are selected by derating max cap limit by 0.01. The value of 1.0 means no derating of max cap limit. |
| `-delay_buffer_derate` | This option balances latencies between macro cells and registers by inserting delay buffers. The default value is `1.0`, meaning all needed delay buffers are inserted. A value of 0.5 means only half of necessary delay buffers are inserted. A value of 0.0 means no insertion of delay buffers. |
| `-library` | This option specifies the name of library from which clock buffers will be selected, such as the LVT or uLVT library. It is assumed that the library has already been loaded using the read_liberty command. If this option is not specified, clock buffers will be chosen from the currently loaded libraries, which may not include LVT or uLVT cells. |

### Report CTS

Expand Down
4 changes: 4 additions & 0 deletions src/cts/src/CtsOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,9 @@ class CtsOptions
float getDelayBufferDerate() const { return delayBufferDerate_; }
void enableDummyLoad(bool dummyLoad) { dummyLoad_ = dummyLoad; }
bool dummyLoadEnabled() const { return dummyLoad_; }
void setCtsLibrary(const char* name) { ctsLibrary_ = name; }
const char* getCtsLibrary() { return ctsLibrary_.c_str(); }
bool isCtsLibrarySet() { return !ctsLibrary_.empty(); }

private:
std::string clockNets_ = "";
Expand Down Expand Up @@ -307,6 +310,7 @@ class CtsOptions
float sinkBufferMaxCapDerate_ = sinkBufferMaxCapDerateDefault_;
bool dummyLoad_ = true;
float delayBufferDerate_ = 1.0; // no derate
std::string ctsLibrary_;
};

} // namespace cts
33 changes: 33 additions & 0 deletions src/cts/src/TritonCTS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,23 @@ int TritonCTS::getBufferFanoutLimit(const std::string& bufferName)

void TritonCTS::setupCharacterization()
{
// Check if CTS library is valid
if (options_->isCtsLibrarySet()) {
sta::Library* lib = network_->findLibrary(options_->getCtsLibrary());
if (lib == nullptr) {
logger_->error(CTS,
209,
"Library {} cannot be found because it is not "
"loaded or name is incorrect",
options_->getCtsLibrary());
} else {
logger_->info(CTS,
210,
"Clock buffers will be chosen from library {}",
options_->getCtsLibrary());
}
}

openSta_->checkFanoutLimitPreamble();
// Finalize root/sink buffers
std::string rootBuffer = selectRootBuffer(rootBuffers_);
Expand Down Expand Up @@ -591,6 +608,10 @@ void TritonCTS::inferBufferList(std::vector<std::string>& buffers)
sta::LibertyLibraryIterator* lib_iter = network_->libertyLibraryIterator();
while (lib_iter->hasNext()) {
sta::LibertyLibrary* lib = lib_iter->next();
if (options_->isCtsLibrarySet()
&& strcmp(lib->name(), options_->getCtsLibrary()) != 0) {
continue;
}
for (sta::LibertyCell* buffer : *lib->buffers()) {
if (buffer->isClockCell() && isClockCellCandidate(buffer)) {
buffers.emplace_back(buffer->name());
Expand All @@ -612,6 +633,10 @@ void TritonCTS::inferBufferList(std::vector<std::string>& buffers)
sta::LibertyLibraryIterator* lib_iter = network_->libertyLibraryIterator();
while (lib_iter->hasNext()) {
sta::LibertyLibrary* lib = lib_iter->next();
if (options_->isCtsLibrarySet()
&& strcmp(lib->name(), options_->getCtsLibrary()) != 0) {
continue;
}
for (sta::LibertyCell* buffer :
lib->findLibertyCellsMatching(&patternClkBuf)) {
if (buffer->isBuffer() && isClockCellCandidate(buffer)) {
Expand All @@ -631,6 +656,10 @@ void TritonCTS::inferBufferList(std::vector<std::string>& buffers)
lib_iter = network_->libertyLibraryIterator();
while (lib_iter->hasNext()) {
sta::LibertyLibrary* lib = lib_iter->next();
if (options_->isCtsLibrarySet()
&& strcmp(lib->name(), options_->getCtsLibrary()) != 0) {
continue;
}
for (sta::LibertyCell* buffer :
lib->findLibertyCellsMatching(&patternBuf)) {
if (buffer->isBuffer() && isClockCellCandidate(buffer)) {
Expand All @@ -646,6 +675,10 @@ void TritonCTS::inferBufferList(std::vector<std::string>& buffers)
lib_iter = network_->libertyLibraryIterator();
while (lib_iter->hasNext()) {
sta::LibertyLibrary* lib = lib_iter->next();
if (options_->isCtsLibrarySet()
&& strcmp(lib->name(), options_->getCtsLibrary()) != 0) {
continue;
}
for (sta::LibertyCell* buffer : *lib->buffers()) {
if (isClockCellCandidate(buffer)) {
buffers.emplace_back(buffer->name());
Expand Down
6 changes: 6 additions & 0 deletions src/cts/src/TritonCTS.i
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,12 @@ set_delay_buffer_derate(float derate)
getTritonCts()->getParms()->setDelayBufferDerate(derate);
}

void
set_cts_library(const char* name)
{
getTritonCts()->getParms()->setCtsLibrary(name);
}

void
run_triton_cts()
{
Expand Down
13 changes: 9 additions & 4 deletions src/cts/src/TritonCTS.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ sta::define_cmd_args "clock_tree_synthesis" {[-wire_unit unit]
[-sink_buffer_max_cap_derate] \
[-dont_use_dummy_load] \
[-delay_buffer_derate] \
[-library] \
};# checker off

proc clock_tree_synthesis { args } {
Expand All @@ -99,13 +100,18 @@ proc clock_tree_synthesis { args } {
-clustering_exponent \
-clustering_unbalance_ratio -sink_clustering_max_diameter \
-sink_clustering_levels -tree_buf \
-sink_buffer_max_cap_derate -delay_buffer_derate} \
-sink_buffer_max_cap_derate -delay_buffer_derate -library} \
flags {-post_cts_disable -sink_clustering_enable -balance_levels \
-obstruction_aware -apply_ndr -dont_use_dummy_load
};# checker off

sta::check_argc_eq0 "clock_tree_synthesis" $args

if { [info exists keys(-library)] } {
set cts_library $keys(-library)
cts::set_cts_library $cts_library
}

if { [info exists flags(-post_cts_disable)] } {
utl::warn CTS 115 "-post_cts_disable is obsolete."
}
Expand Down Expand Up @@ -195,15 +201,15 @@ proc clock_tree_synthesis { args } {

if { [info exists keys(-sink_buffer_max_cap_derate)] } {
set derate $keys(-sink_buffer_max_cap_derate)
if {[expr {$derate > 1.0 || $derate < 0.0 }]} {
if { $derate > 1.0 || $derate < 0.0 } {
utl::error CTS 109 "sink_buffer_max_cap_derate needs to be between 0 and 1.0."
}
cts::set_sink_buffer_max_cap_derate $derate
}

if { [info exists keys(-delay_buffer_derate)] } {
set buffer_derate $keys(-delay_buffer_derate)
if {[expr {$buffer_derate < 0.0 }]} {
if { $buffer_derate < 0.0 } {
utl::error CTS 123 "delay_buffer_derate needs to be greater than or equal to 0."
}
cts::set_delay_buffer_derate $buffer_derate
Expand All @@ -219,7 +225,6 @@ proc clock_tree_synthesis { args } {

cts::set_apply_ndr [info exists flags(-apply_ndr)]


if { [ord::get_db_block] == "NULL" } {
utl::error CTS 103 "No design block found."
}
Expand Down
101 changes: 101 additions & 0 deletions src/cts/test/lvt_lib.ok
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
[INFO ODB-0227] LEF file: Nangate45/Nangate45.lef, created 22 layers, 27 vias, 135 library cells
[INFO ODB-0227] LEF file: Nangate45/Nangate45_lvt.lef, created 135 library cells
[INFO CTS-0210] Clock buffers will be chosen from library NangateOpenCellLibrary_lvt
[INFO CTS-0050] Root buffer is CLKBUF_X1_L.
[INFO CTS-0051] Sink buffer is CLKBUF_X1_L.
[INFO CTS-0052] The following clock buffers will be used for CTS:
CLKBUF_X1_L
[INFO CTS-0049] Characterization buffer is CLKBUF_X1_L.
[INFO CTS-0007] Net "clk" found for clock "clk".
[INFO CTS-0010] Clock net "clk" has 151 sinks.
[INFO CTS-0010] Clock net "CELL/clk2" has 150 sinks.
[INFO CTS-0008] TritonCTS found 2 clock nets.
[INFO CTS-0097] Characterization used 1 buffer(s) types.
[INFO CTS-0200] 0 placement blockages have been identified.
[INFO CTS-0201] 0 placed hard macros will be treated like blockages.
[INFO CTS-0027] Generating H-Tree topology for net clk.
[INFO CTS-0028] Total number of sinks: 151.
[INFO CTS-0030] Number of static layers: 0.
[INFO CTS-0020] Wire segment unit: 14000 dbu (7 um).
[INFO CTS-0023] Original sink region: [(8785, 6785), (197672, 95673)].
[INFO CTS-0024] Normalized sink region: [(0.6275, 0.484643), (14.1194, 6.83379)].
[INFO CTS-0025] Width: 13.4919.
[INFO CTS-0026] Height: 6.3491.
Level 1
Direction: Horizontal
Sinks per sub-region: 76
Sub-region size: 6.7460 X 6.3491
[INFO CTS-0034] Segment length (rounded): 4.
Level 2
Direction: Vertical
Sinks per sub-region: 38
Sub-region size: 6.7460 X 3.1746
[INFO CTS-0034] Segment length (rounded): 1.
Level 3
Direction: Horizontal
Sinks per sub-region: 19
Sub-region size: 3.3730 X 3.1746
[INFO CTS-0034] Segment length (rounded): 1.
Level 4
Direction: Vertical
Sinks per sub-region: 10
Sub-region size: 3.3730 X 1.5873
[INFO CTS-0034] Segment length (rounded): 1.
[INFO CTS-0032] Stop criterion found. Max number of sinks is 15.
[INFO CTS-0035] Number of sinks covered: 151.
[INFO CTS-0200] 0 placement blockages have been identified.
[INFO CTS-0201] 0 placed hard macros will be treated like blockages.
[INFO CTS-0027] Generating H-Tree topology for net CELL\/clk2.
[INFO CTS-0028] Total number of sinks: 150.
[INFO CTS-0030] Number of static layers: 0.
[INFO CTS-0020] Wire segment unit: 14000 dbu (7 um).
[INFO CTS-0023] Original sink region: [(8785, 95673), (197672, 184561)].
[INFO CTS-0024] Normalized sink region: [(0.6275, 6.83379), (14.1194, 13.1829)].
[INFO CTS-0025] Width: 13.4919.
[INFO CTS-0026] Height: 6.3491.
Level 1
Direction: Horizontal
Sinks per sub-region: 75
Sub-region size: 6.7460 X 6.3491
[INFO CTS-0034] Segment length (rounded): 4.
Level 2
Direction: Vertical
Sinks per sub-region: 38
Sub-region size: 6.7460 X 3.1746
[INFO CTS-0034] Segment length (rounded): 1.
Level 3
Direction: Horizontal
Sinks per sub-region: 19
Sub-region size: 3.3730 X 3.1746
[INFO CTS-0034] Segment length (rounded): 1.
Level 4
Direction: Vertical
Sinks per sub-region: 10
Sub-region size: 3.3730 X 1.5873
[INFO CTS-0034] Segment length (rounded): 1.
[INFO CTS-0032] Stop criterion found. Max number of sinks is 15.
[INFO CTS-0035] Number of sinks covered: 150.
[INFO CTS-0018] Created 17 clock buffers.
[INFO CTS-0012] Minimum number of buffers in the clock path: 2.
[INFO CTS-0013] Maximum number of buffers in the clock path: 2.
[INFO CTS-0015] Created 17 clock nets.
[INFO CTS-0016] Fanout distribution for the current clock = 7:1, 8:4, 9:5, 10:3, 12:2, 13:1..
[INFO CTS-0017] Max level of the clock tree: 4.
[INFO CTS-0018] Created 17 clock buffers.
[INFO CTS-0012] Minimum number of buffers in the clock path: 2.
[INFO CTS-0013] Maximum number of buffers in the clock path: 2.
[INFO CTS-0015] Created 17 clock nets.
[INFO CTS-0016] Fanout distribution for the current clock = 7:3, 8:2, 9:4, 10:4, 12:2, 13:1..
[INFO CTS-0017] Max level of the clock tree: 4.
[INFO CTS-0098] Clock net "clk"
[INFO CTS-0099] Sinks 166
[INFO CTS-0100] Leaf buffers 0
[INFO CTS-0101] Average sink wire length 121.61 um
[INFO CTS-0102] Path depth 2 - 2
[INFO CTS-0207] Leaf load cells 30
[INFO CTS-0098] Clock net "CELL\/clk2"
[INFO CTS-0099] Sinks 165
[INFO CTS-0100] Leaf buffers 0
[INFO CTS-0101] Average sink wire length 66.44 um
[INFO CTS-0102] Path depth 2 - 2
[INFO CTS-0207] Leaf load cells 30
19 changes: 19 additions & 0 deletions src/cts/test/lvt_lib.tcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
source "helpers.tcl"
source "cts-helpers.tcl"

read_liberty Nangate45/Nangate45_typ.lib
read_liberty Nangate45/Nangate45_lvt.lib
read_lef Nangate45/Nangate45.lef
read_lef Nangate45/Nangate45_lvt.lef

set block [make_array 300 200000 200000 150]

sta::db_network_defined

create_clock -period 5 clk

set_wire_rc -clock -layer metal5

clock_tree_synthesis -library NangateOpenCellLibrary_lvt


2 changes: 2 additions & 0 deletions src/cts/test/regression_tests.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ record_tests {
simple_test
simple_test_clustered
simple_test_clustered_max_cap
simple_test_hier
lvt_lib
#cts_readme_msgs_check
#cts_man_tcl_check
}
2 changes: 1 addition & 1 deletion src/dpl/src/Opendp.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ proc get_inst_grid_bbox { inst_name } {
}

proc format_grid { x w } {
if { [expr $x % $w] == 0 } {
if { $x % $w == 0 } {
return [expr $x / $w]
} else {
return [format "%.2f" [expr $x / double($w)]]
Expand Down
3 changes: 3 additions & 0 deletions src/drt/src/pa/FlexPA_prep.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1502,6 +1502,9 @@ int FlexPA::initPinAccess(T* pin, frInstTerm* inst_term)
macro_cell_pin_no_ap_cnt_++;
}
} else {
if (inst_term == nullptr) {
logger_->error(DRT, 254, "inst_term can not be nullptr");
}
// write to pa
const int pin_access_idx = unique_insts_.getPAIndex(inst_term->getInst());
for (auto& ap : aps) {
Expand Down
2 changes: 1 addition & 1 deletion src/mpl2/src/mpl.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ proc mpl_debug { args } {

set coarse [info exists flags(-coarse)]
set fine [info exists flags(-fine)]
if { [expr !$coarse && !$fine] } {
if { !$coarse && !$fine } {
set coarse true
set fine true
}
Expand Down
6 changes: 3 additions & 3 deletions src/pad/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,9 @@ make_io_sites
| `-vertical_site` | Name of the site for the vertical pads (north and south). |
| `-corner_site` | Name of the site for the corner cells. |
| `-offset` | Offset from the die edge to place the rows. |
| `-rotation_horizontal` | Rotation to apply to the horizontal sites to ensure pads are placed correctly. The default value is `R0`. |
| `-rotation_vertical` | Rotation to apply to the vertical sites to ensure pads are placed correctly. The default value is `R0`. |
| `-rotation_corner` | Rotation to apply to the corner sites to ensure pads are placed correctly. The default value is `R0`. |
| `-rotation_horizontal` | Rotation to apply to the horizontal sites to ensure pads are placed correctly. The default value is `R0` for the western (left) row when different sites are specified for hortizontal and vertical rows, the default value is `MXR90` when the same site is specified. |
| `-rotation_vertical` | Rotation to apply to the vertical sites to ensure pads are placed correctly. The default value is `R0` for the southern (bottom) row. |
| `-rotation_corner` | Rotation to apply to the corner sites to ensure pads are placed correctly. The default value is `R0` for the south west (lower left) corner. |
| `-ring_index` | Used to specify the index of the ring in case of multiple rings. |


Expand Down
20 changes: 11 additions & 9 deletions src/pad/src/ICeWall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -447,8 +447,8 @@ void ICeWall::makeIORow(odb::dbSite* horizontal_site,
const odb::dbRowDir& direction,
int site_width) {
const std::string row_name = getRowName(name, ring_index);
odb::dbTransform rotation(orient);
rotation.concat(row_rotation);
odb::dbTransform rotation(row_rotation);
rotation.concat(orient);
odb::dbRow::create(block,
row_name.c_str(),
site,
Expand All @@ -459,19 +459,22 @@ void ICeWall::makeIORow(odb::dbSite* horizontal_site,
sites,
site_width);
};
const odb::dbOrientType south_rotation_ver = odb::dbOrientType::R0;
const odb::dbOrientType north_rotation_ver = south_rotation_ver.flipX();
odb::dbOrientType west_rotation_hor = odb::dbOrientType::MXR90;
if (vertical_site != horizontal_site) {
west_rotation_hor = odb::dbOrientType::R0;
}
const odb::dbOrientType east_rotation_hor = west_rotation_hor.flipY();
create_row(row_north_,
vertical_site,
x_sites,
{nw->getBBox().xMax(),
outer_io.yMax() - static_cast<int>(vertical_box.maxDXDY())},
odb::dbOrientType::MX,
north_rotation_ver,
rotation_ver,
odb::dbRowDir::HORIZONTAL,
vertical_box.minDXDY());
odb::dbOrientType east_rotation_hor = odb::dbOrientType::R90;
if (vertical_site != horizontal_site) {
east_rotation_hor = odb::dbOrientType::R0;
}
create_row(row_east_,
horizontal_site,
y_sites,
Expand All @@ -485,11 +488,10 @@ void ICeWall::makeIORow(odb::dbSite* horizontal_site,
vertical_site,
x_sites,
{sw->getBBox().xMax(), outer_io.yMin()},
odb::dbOrientType::R0,
south_rotation_ver,
rotation_ver,
odb::dbRowDir::HORIZONTAL,
vertical_box.minDXDY());
const odb::dbOrientType west_rotation_hor = east_rotation_hor.flipY();
create_row(row_west_,
horizontal_site,
y_sites,
Expand Down
Loading

0 comments on commit 625c965

Please sign in to comment.