Skip to content

Commit d310f0b

Browse files
authored
Merge pull request #8805 from gadfort/pad-imp
pad: add user control of `place_pads` mode and fix rounding error in uniform placement
2 parents 7e265db + 79eb94e commit d310f0b

16 files changed

+2409
-422
lines changed

src/pad/README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ place_pads -row IO_SOUTH u_reset.u_in u_reset.u_out
219219
```tcl
220220
place_pads
221221
-row row_name
222+
[-mode mode]
222223
pads
223224
```
224225

@@ -227,8 +228,18 @@ place_pads
227228
| Switch Name | Description |
228229
| ----- | ----- |
229230
| `-row` | Name of the row to place the pad into, examples include: `IO_NORTH`, `IO_SOUTH`, `IO_WEST`, `IO_EAST`, `IO_NORTH_0`, `IO_NORTH_1`. |
231+
| `-mode` | Select the mode to use during pad placement, choices are `bump_aligned` and `uniform`. Default will select `bump_aligned` if possible, otherwise fallback to `uniform`. |
230232
| `pads` | Name of the instances in the order they should be placed (left to right for `IO_SOUTH` and `IO_NORTH` and bottom to top for `IO_WEST` and `IO_EAST`). |
231233

234+
#### Modes
235+
236+
In `uniform` mode, the pads will be evenly spread out across the row they are assigned to, as shown in the figure below.
237+
238+
<img src="./doc/image/mode_uniform.png" width=450px>
239+
240+
In `bump_aligned` mode, the pads will be clustered near their assigned bumps to minimize RDL routing distances, as shown below.
241+
242+
<img src="./doc/image/mode_bump_aligned.png" width=450px>
232243

233244
### Placing Pads Manually
234245

60.8 KB
Loading

src/pad/doc/image/mode_uniform.png

52.8 KB
Loading

src/pad/include/pad/ICeWall.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,13 @@ namespace pad {
2626
class RDLRouter;
2727
class RDLGui;
2828

29+
enum class PlacementStrategy
30+
{
31+
DEFAULT,
32+
BUMP_ALIGNED,
33+
UNIFORM
34+
};
35+
2936
class ICeWall
3037
{
3138
public:
@@ -67,7 +74,9 @@ class ICeWall
6774
odb::dbRow* row,
6875
int location,
6976
bool mirror);
70-
void placePads(const std::vector<odb::dbInst*>& insts, odb::dbRow* row);
77+
void placePads(const std::vector<odb::dbInst*>& insts,
78+
odb::dbRow* row,
79+
const PlacementStrategy& mode);
7180
void placeCorner(odb::dbMaster* master, int ring_index);
7281
void placeFiller(const std::vector<odb::dbMaster*>& masters,
7382
odb::dbRow* row,

src/pad/src/ICeWall.cpp

Lines changed: 72 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "RDLRouter.h"
2121
#include "Utilities.h"
2222
#include "boost/icl/interval_set.hpp"
23+
#include "gui/gui.h"
2324
#include "odb/db.h"
2425
#include "odb/dbTransform.h"
2526
#include "odb/dbTypes.h"
@@ -678,7 +679,9 @@ int64_t ICeWall::computePadBumpDistance(odb::dbInst* inst,
678679
return std::numeric_limits<int64_t>::max();
679680
}
680681

681-
void ICeWall::placePads(const std::vector<odb::dbInst*>& insts, odb::dbRow* row)
682+
void ICeWall::placePads(const std::vector<odb::dbInst*>& insts,
683+
odb::dbRow* row,
684+
const PlacementStrategy& mode)
682685
{
683686
auto* block = getBlock();
684687
if (block == nullptr) {
@@ -727,8 +730,18 @@ void ICeWall::placePads(const std::vector<odb::dbInst*>& insts, odb::dbRow* row)
727730
break;
728731
}
729732

733+
const double dbus = block->getDbUnitsPerMicron();
734+
debugPrint(logger_,
735+
utl::PAD,
736+
"Place",
737+
1,
738+
"{}: Row width ({:.4f} um), total instance ({}) width {:.4f} um)",
739+
row->getName(),
740+
row_width / dbus,
741+
inst_widths.size(),
742+
total_width / dbus);
743+
730744
if (total_width > row_width) {
731-
const double dbus = block->getDbUnitsPerMicron();
732745
logger_->error(
733746
utl::PAD,
734747
40,
@@ -760,17 +773,34 @@ void ICeWall::placePads(const std::vector<odb::dbInst*>& insts, odb::dbRow* row)
760773
}
761774
}
762775

763-
if (!iterm_connections.empty()) {
764-
placePadsBumpAligned(insts,
765-
row,
766-
inst_widths,
767-
total_width,
768-
row_width,
769-
row_start,
770-
iterm_connections);
771-
} else {
772-
placePadsUniform(
773-
insts, row, inst_widths, total_width, row_width, row_start);
776+
PlacementStrategy use_mode = mode;
777+
if (use_mode == PlacementStrategy::DEFAULT) {
778+
if (!iterm_connections.empty()) {
779+
use_mode = PlacementStrategy::BUMP_ALIGNED;
780+
}
781+
}
782+
if (use_mode == PlacementStrategy::BUMP_ALIGNED
783+
&& iterm_connections.empty()) {
784+
logger_->warn(
785+
utl::PAD, 9, "Unable to use bump_aligned mode, switching to uniform");
786+
use_mode = PlacementStrategy::UNIFORM;
787+
}
788+
789+
switch (use_mode) {
790+
case PlacementStrategy::BUMP_ALIGNED:
791+
placePadsBumpAligned(insts,
792+
row,
793+
inst_widths,
794+
total_width,
795+
row_width,
796+
row_start,
797+
iterm_connections);
798+
break;
799+
case PlacementStrategy::UNIFORM:
800+
case PlacementStrategy::DEFAULT:
801+
placePadsUniform(
802+
insts, row, inst_widths, total_width, row_width, row_start);
803+
break;
774804
}
775805

776806
logger_->info(
@@ -916,6 +946,9 @@ void ICeWall::placePadsBumpAligned(
916946

917947
int offset = row_start;
918948

949+
const bool gui_debug
950+
= logger_->debugCheck(utl::PAD, "Place", 1) && gui::Gui::enabled();
951+
919952
int max_travel = row_width - pads_width;
920953
// iterate over pads in order
921954
for (auto itr = insts.begin(); itr != insts.end();) {
@@ -988,6 +1021,10 @@ void ICeWall::placePadsBumpAligned(
9881021
* row->getSpacing();
9891022

9901023
performPadFlip(row, ginst, iterm_connections);
1024+
1025+
if (gui_debug) {
1026+
gui::Gui::get()->pause();
1027+
}
9911028
}
9921029

9931030
// more iterator to next unplaced pad
@@ -1002,9 +1039,25 @@ void ICeWall::placePadsUniform(const std::vector<odb::dbInst*>& insts,
10021039
int row_width,
10031040
int row_start) const
10041041
{
1005-
const double dbus = getBlock()->getDbUnitsPerMicron();
1006-
const int target_spacing = (row_width - pads_width) / (insts.size() + 1);
1042+
const bool gui_debug
1043+
= logger_->debugCheck(utl::PAD, "Place", 1) && gui::Gui::enabled();
1044+
1045+
const float initial_target_spacing
1046+
= static_cast<float>(row_width - pads_width) / (insts.size() + 1);
1047+
const int site_width
1048+
= std::min(row->getSite()->getWidth(), row->getSite()->getHeight());
1049+
const int target_spacing
1050+
= std::floor(initial_target_spacing / site_width) * site_width;
10071051
int offset = row_start + target_spacing;
1052+
1053+
const double dbus = getBlock()->getDbUnitsPerMicron();
1054+
debugPrint(logger_,
1055+
utl::PAD,
1056+
"Place",
1057+
1,
1058+
"Placing pads with uniform: spacing {:.4f} um",
1059+
target_spacing / dbus);
1060+
10081061
for (auto* inst : insts) {
10091062
debugPrint(logger_,
10101063
utl::PAD,
@@ -1022,6 +1075,10 @@ void ICeWall::placePadsUniform(const std::vector<odb::dbInst*>& insts,
10221075
/* allow_shift */ true);
10231076
offset += inst_widths.at(inst);
10241077
offset += target_spacing;
1078+
1079+
if (gui_debug) {
1080+
gui::Gui::get()->pause();
1081+
}
10251082
}
10261083
}
10271084

src/pad/src/pad.i

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,18 @@ utl::Logger* getLogger();
2626
%include "exception.i"
2727
%include "../../Exception.i"
2828

29+
%typemap(in) pad::PlacementStrategy {
30+
char *str = Tcl_GetStringFromObj($input, 0);
31+
if (strcasecmp(str, "bump_aligned") == 0) {
32+
$1 = pad::PlacementStrategy::BUMP_ALIGNED;
33+
} else if (strcasecmp(str, "uniform") == 0) {
34+
$1 = pad::PlacementStrategy::UNIFORM;
35+
} else if (strcasecmp(str, "default") == 0) {
36+
$1 = pad::PlacementStrategy::DEFAULT;
37+
} else {
38+
$1 = pad::PlacementStrategy::DEFAULT;
39+
}
40+
}
2941

3042
%inline %{
3143

@@ -77,9 +89,9 @@ void place_pad(odb::dbMaster* master, const char* name, odb::dbRow* row, int loc
7789
ord::getICeWall()->placePad(master, name, row, location, mirror);
7890
}
7991

80-
void place_pads(const std::vector<odb::dbInst*>& insts, odb::dbRow* row)
92+
void place_pads(const std::vector<odb::dbInst*>& insts, odb::dbRow* row, pad::PlacementStrategy mode)
8193
{
82-
ord::getICeWall()->placePads(insts, row);
94+
ord::getICeWall()->placePads(insts, row, mode);
8395
}
8496

8597
void place_corner(odb::dbMaster* master, int ring_index)

src/pad/src/pad.tcl

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -234,11 +234,12 @@ proc place_pad { args } {
234234
}
235235

236236
sta::define_cmd_args "place_pads" {-row row_name \
237+
[-mode mode] \
237238
pads}
238239

239240
proc place_pads { args } {
240241
sta::parse_key_args "place_pads" args \
241-
keys {-row} \
242+
keys {-row -mode} \
242243
flags {}
243244

244245
if { $args == {} } {
@@ -249,6 +250,11 @@ proc place_pads { args } {
249250
set args [lindex $args 0]
250251
}
251252

253+
set mode "default"
254+
if { [info exists keys(-mode)] } {
255+
set mode $keys(-mode)
256+
}
257+
252258
set insts []
253259
foreach inst $args {
254260
lappend insts [pad::find_instance $inst]
@@ -257,7 +263,8 @@ proc place_pads { args } {
257263
pad::assert_required place_pads -row
258264
pad::place_pads \
259265
$insts \
260-
[pad::get_row $keys(-row)]
266+
[pad::get_row $keys(-row)] \
267+
$mode
261268
}
262269

263270
sta::define_cmd_args "place_io_fill" {-row row_name \

src/pad/test/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ COMPULSORY_TESTS = [
3434
"place_pad_wrong_master",
3535
"place_pads_bumps",
3636
"place_pads_bumps_bump_overlap",
37+
"place_pads_bumps_strategy",
3738
"place_pads_too_many",
3839
"place_pads_uniform",
3940
"place_pads_uniform_slip",

src/pad/test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ or_integration_tests(
2727
place_pad_overblockage
2828
place_pad_with_bumps
2929
place_pads_bumps_bump_overlap
30+
place_pads_bumps_strategy
3031
place_pad_wrong_master
3132
place_pads_bumps
3233
place_pads_too_many

0 commit comments

Comments
 (0)