Skip to content

Commit 5098fed

Browse files
authored
Merge pull request The-OpenROAD-Project#6765 from QuantamHD/make_rows
ifp: Adds make_rows command
2 parents efdc8d1 + 17d47f8 commit 5098fed

File tree

10 files changed

+483
-147
lines changed

10 files changed

+483
-147
lines changed

src/ifp/README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,33 @@ make_tracks
9595
| `[-x_offset]`, `[-y_offset]` | If set, overrides the LEF technology x-/y- offset. Use the same unit as in the LEFT file. |
9696
| `[-x_pitch]`, `[-y_pitch]` | If set, overrides the LEF technology x-/y- pitch. Use the same unit as in the LEF file. |
9797

98+
### Make Rows
99+
100+
The `make_rows` command removes existing rows.
101+
Use the `make_rows` command to add rows to an existing floorplan. Useful,
102+
if your floorplan is stored as a floorplan def without rows.
103+
104+
```tcl
105+
make_rows
106+
(-core_area {llx lly urx ury}) | (-core_space (space | {bottom top left right}))
107+
-site site_name
108+
[-additional_sites site_names]
109+
[-flip_sites site_names]
110+
[-row_parity NONE|EVEN|ODD]
111+
```
112+
113+
#### Options
114+
115+
116+
| Switch Name | Description |
117+
| ----- | ----- |
118+
| `-core_area` | Core area coordinates in microns (lower left x/y and upper right x/y coordinates). |
119+
| `-core_space` | Space around the core in microns. Allowed values are either one value for all margins or a set of four values, one for each margin. The order of the four values are: `{bottom top left right}`. |
120+
| `-site` | Site name. |
121+
| `[-additional_sites]` | Tcl list of sites to make rows for (e.g. `{SITEXX, SITEYY}`) |
122+
| `[-flip_sites]` | Flip the orientations of rows matching these sites. Sites listed under this option will create `FS`-oriented rows at even indices and `N`-oriented rows at odd ones, and vice versa for sites not listed under this option. (e.g. `{SITEXX, SITEYY}`) |
123+
| `[-row_parity]` | Snap to either an odd (`ODD`) or even (`EVEN`) number of rows. Defaults to `NONE` (no constraint on parity). |
124+
98125
### Insert tieoff cells
99126

100127
This comamnd inserts tiecells.

src/ifp/include/ifp/InitFloorplan.hh

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,41 @@ class InitFloorplan
9494
void insertTiecells(odb::dbMTerm* tie_term,
9595
const std::string& prefix = "TIEOFF_");
9696

97+
// Rect in DBU to set the die area of the top level block.
98+
void makeDie(const odb::Rect& die);
99+
100+
// utilization is in [0, 100]%. This routine will calculate the required
101+
// core area for all the standard cells and macros based on the desired
102+
// utilization. It will then add core space to each side, and will set
103+
// the die area of the top level block to that calculated value.
104+
void makeDieUtilization(double utilization,
105+
double aspect_ratio,
106+
int core_space_bottom,
107+
int core_space_top,
108+
int core_space_left,
109+
int core_space_right);
110+
111+
// The base_site determines the single-height rows. For hybrid rows it is
112+
// a site containing a row pattern. core space is the padding on each side
113+
// to inset the rows.
114+
void makeRowsWithSpacing(int core_space_bottom,
115+
int core_space_top,
116+
int core_space_left,
117+
int core_space_right,
118+
odb::dbSite* base_site,
119+
const std::vector<odb::dbSite*>& additional_sites
120+
= {},
121+
RowParity row_parity = RowParity::NONE,
122+
const std::set<odb::dbSite*>& flipped_sites = {});
123+
124+
// The base_site determines the single-height rows. For hybrid rows it is
125+
// a site containing a row pattern.
126+
void makeRows(const odb::Rect& core,
127+
odb::dbSite* base_site,
128+
const std::vector<odb::dbSite*>& additional_sites = {},
129+
RowParity row_parity = RowParity::NONE,
130+
const std::set<odb::dbSite*>& flipped_sites = {});
131+
97132
void makeTracks();
98133
void makeTracks(odb::dbTechLayer* layer,
99134
int x_offset,

src/ifp/src/InitFloorplan.cc

Lines changed: 120 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,26 @@ using odb::uint;
8888

8989
using upf::eval_upf;
9090

91+
namespace {
92+
void validateCoreSpacing(odb::dbBlock* block,
93+
utl::Logger* logger,
94+
int core_space_bottom,
95+
int core_space_top,
96+
int core_space_left,
97+
int core_space_right)
98+
{
99+
utl::Validator v(logger, IFP);
100+
v.check_non_negative(
101+
"core_space_bottom (um) ", block->dbuToMicrons(core_space_bottom), 32);
102+
v.check_non_negative(
103+
"core_space_top (um) ", block->dbuToMicrons(core_space_top), 33);
104+
v.check_non_negative(
105+
"core_space_left (um) ", block->dbuToMicrons(core_space_left), 34);
106+
v.check_non_negative(
107+
"core_space_right (um) ", block->dbuToMicrons(core_space_right), 35);
108+
}
109+
} // namespace
110+
91111
InitFloorplan::InitFloorplan(dbBlock* block,
92112
Logger* logger,
93113
sta::dbNetwork* network)
@@ -106,19 +126,53 @@ void InitFloorplan::initFloorplan(
106126
const std::vector<odb::dbSite*>& additional_sites,
107127
RowParity row_parity,
108128
const std::set<odb::dbSite*>& flipped_sites)
129+
{
130+
makeDieUtilization(utilization,
131+
aspect_ratio,
132+
core_space_bottom,
133+
core_space_top,
134+
core_space_left,
135+
core_space_right);
136+
makeRowsWithSpacing(core_space_bottom,
137+
core_space_top,
138+
core_space_left,
139+
core_space_right,
140+
base_site,
141+
additional_sites,
142+
row_parity,
143+
flipped_sites);
144+
}
145+
146+
// The base_site determines the single-height rows. For hybrid rows it is
147+
// a site containing a row pattern.
148+
void InitFloorplan::initFloorplan(
149+
const odb::Rect& die,
150+
const odb::Rect& core,
151+
odb::dbSite* base_site,
152+
const std::vector<odb::dbSite*>& additional_sites,
153+
RowParity row_parity,
154+
const std::set<odb::dbSite*>& flipped_sites)
155+
{
156+
makeDie(die);
157+
makeRows(core, base_site, additional_sites, row_parity, flipped_sites);
158+
}
159+
160+
void InitFloorplan::makeDieUtilization(double utilization,
161+
double aspect_ratio,
162+
int core_space_bottom,
163+
int core_space_top,
164+
int core_space_left,
165+
int core_space_right)
109166
{
110167
utl::Validator v(logger_, IFP);
111168
v.check_non_negative("utilization", utilization, 12);
112-
v.check_non_negative(
113-
"core_space_bottom (um) ", block_->dbuToMicrons(core_space_bottom), 32);
114-
v.check_non_negative(
115-
"core_space_top (um) ", block_->dbuToMicrons(core_space_top), 33);
116-
v.check_non_negative(
117-
"core_space_left (um) ", block_->dbuToMicrons(core_space_left), 34);
118-
v.check_non_negative(
119-
"core_space_right (um) ", block_->dbuToMicrons(core_space_right), 35);
120169
v.check_positive("aspect_ratio", aspect_ratio, 36);
121-
170+
validateCoreSpacing(block_,
171+
logger_,
172+
core_space_bottom,
173+
core_space_top,
174+
core_space_left,
175+
core_space_right);
122176
utilization /= 100;
123177
const double design_area = designArea();
124178
const double core_area = design_area / utilization;
@@ -133,12 +187,17 @@ void InitFloorplan::initFloorplan(
133187
const int die_ly = 0;
134188
const int die_ux = core_ux + core_space_right;
135189
const int die_uy = core_uy + core_space_top;
136-
initFloorplan({die_lx, die_ly, die_ux, die_uy},
137-
{core_lx, core_ly, core_ux, core_uy},
138-
base_site,
139-
additional_sites,
140-
row_parity,
141-
flipped_sites);
190+
191+
makeDie({die_lx, die_ly, die_ux, die_uy});
192+
}
193+
194+
void InitFloorplan::makeDie(const odb::Rect& die)
195+
{
196+
Rect die_area(snapToMfgGrid(die.xMin()),
197+
snapToMfgGrid(die.yMin()),
198+
snapToMfgGrid(die.xMax()),
199+
snapToMfgGrid(die.yMax()));
200+
block_->setDieArea(die_area);
142201
}
143202

144203
double InitFloorplan::designArea()
@@ -191,30 +250,62 @@ static int divCeil(int dividend, int divisor)
191250
return ceil(static_cast<double>(dividend) / divisor);
192251
}
193252

194-
void InitFloorplan::initFloorplan(
195-
const odb::Rect& die,
196-
const odb::Rect& core,
253+
void InitFloorplan::makeRowsWithSpacing(
254+
int core_space_bottom,
255+
int core_space_top,
256+
int core_space_left,
257+
int core_space_right,
197258
odb::dbSite* base_site,
198259
const std::vector<odb::dbSite*>& additional_sites,
199260
RowParity row_parity,
200261
const std::set<odb::dbSite*>& flipped_sites)
201262
{
202-
if (!die.contains(core)) {
263+
odb::Rect block_die_area = block_->getDieArea();
264+
if (block_die_area.area() == 0) {
265+
logger_->error(IFP, 64, "Floorplan die area is 0. Cannot build rows.");
266+
}
267+
268+
validateCoreSpacing(block_,
269+
logger_,
270+
core_space_bottom,
271+
core_space_top,
272+
core_space_left,
273+
core_space_right);
274+
275+
int lower_left_x = block_die_area.ll().x();
276+
int lower_left_y = block_die_area.ll().y();
277+
int upper_right_x = block_die_area.ur().x();
278+
int upper_right_y = block_die_area.ur().y();
279+
280+
int core_lx = lower_left_x + core_space_left;
281+
int core_ly = lower_left_y + core_space_bottom;
282+
int core_ux = upper_right_x - core_space_right;
283+
int core_uy = upper_right_y - core_space_top;
284+
285+
makeRows({core_lx, core_ly, core_ux, core_uy},
286+
base_site,
287+
additional_sites,
288+
row_parity,
289+
flipped_sites);
290+
}
291+
292+
void InitFloorplan::makeRows(const odb::Rect& core,
293+
odb::dbSite* base_site,
294+
const std::vector<odb::dbSite*>& additional_sites,
295+
RowParity row_parity,
296+
const std::set<odb::dbSite*>& flipped_sites)
297+
{
298+
odb::Rect block_die_area = block_->getDieArea();
299+
if (block_die_area.area() == 0) {
300+
logger_->error(IFP, 63, "Floorplan die area is 0. Cannot build rows.");
301+
}
302+
303+
if (!block_die_area.contains(core)) {
203304
logger_->error(IFP, 55, "Die area must contain the core area.");
204305
}
205306

206307
checkInstanceDimensions(core);
207308

208-
Rect die_area(snapToMfgGrid(die.xMin()),
209-
snapToMfgGrid(die.yMin()),
210-
snapToMfgGrid(die.xMax()),
211-
snapToMfgGrid(die.yMax()));
212-
block_->setDieArea(die_area);
213-
214-
if (!base_site) {
215-
return; // skip row building
216-
}
217-
218309
// The same site can appear in more than one LEF file and therefore
219310
// in more than one dbLib. We merge them by name to avoid duplicate
220311
// rows.

src/ifp/src/InitFloorplan.i

Lines changed: 59 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include "ord/OpenRoad.hh"
4141
#include "ord/Design.h"
4242
#include "utl/Logger.h"
43+
#include "odb/geom.h"
4344

4445
// Defined by OpenRoad.i
4546
namespace ord {
@@ -89,48 +90,29 @@ static utl::Logger* getLogger() {
8990

9091
namespace ifp {
9192

92-
void
93-
init_floorplan_core(ord::Design* design,
93+
void make_die(ord::Design* design,
9494
int die_lx,
9595
int die_ly,
9696
int die_ux,
97-
int die_uy,
98-
int core_lx,
99-
int core_ly,
100-
int core_ux,
101-
int core_uy,
102-
odb::dbSite* site,
103-
const std::vector<odb::dbSite*>& additional_sites,
104-
ifp::RowParity row_parity,
105-
const std::vector<odb::dbSite*>& flipped_sites)
97+
int die_uy)
10698
{
107-
std::set<odb::dbSite*> flipped_sites_set(flipped_sites.begin(),
108-
flipped_sites.end());
109-
design->getFloorplan().initFloorplan({die_lx, die_ly, die_ux, die_uy},
110-
{core_lx, core_ly, core_ux, core_uy},
111-
site, additional_sites, row_parity, flipped_sites_set);
99+
design->getFloorplan().makeDie({die_lx, die_ly, die_ux, die_uy});
112100
}
113101

114-
void
115-
init_floorplan_util(ord::Design* design,
116-
double util,
117-
double aspect_ratio,
118-
int core_space_bottom,
119-
int core_space_top,
120-
int core_space_left,
121-
int core_space_right,
122-
odb::dbSite* site,
123-
const std::vector<odb::dbSite*>& additional_sites,
124-
ifp::RowParity row_parity,
125-
const std::vector<odb::dbSite*>& flipped_sites)
102+
void make_die_util(ord::Design* design,
103+
double util,
104+
double aspect_ratio,
105+
int core_space_bottom,
106+
int core_space_top,
107+
int core_space_left,
108+
int core_space_right)
126109
{
127-
std::set<odb::dbSite*> flipped_sites_set(flipped_sites.begin(),
128-
flipped_sites.end());
129-
design->getFloorplan().initFloorplan(util, aspect_ratio,
130-
core_space_bottom, core_space_top,
131-
core_space_left, core_space_right,
132-
site, additional_sites, row_parity,
133-
flipped_sites_set);
110+
design->getFloorplan().makeDieUtilization(util,
111+
aspect_ratio,
112+
core_space_bottom,
113+
core_space_top,
114+
core_space_left,
115+
core_space_right);
134116
}
135117

136118
void
@@ -146,6 +128,48 @@ make_layer_tracks(ord::Design* design)
146128
design->getFloorplan().makeTracks();
147129
}
148130

131+
void
132+
make_rows_with_spacing(ord::Design* design,
133+
int spacing_lx,
134+
int spacing_ly,
135+
int spacing_ux,
136+
int spacing_uy,
137+
odb::dbSite* site,
138+
const std::vector<odb::dbSite*>& additional_sites,
139+
ifp::RowParity row_parity,
140+
const std::vector<odb::dbSite*>& flipped_sites)
141+
{
142+
std::set<odb::dbSite*> flipped_sites_set(flipped_sites.begin(),
143+
flipped_sites.end());
144+
design->getFloorplan().makeRowsWithSpacing(spacing_lx, spacing_ly,
145+
spacing_ux, spacing_uy,
146+
site,
147+
additional_sites,
148+
row_parity,
149+
flipped_sites_set);
150+
}
151+
152+
void
153+
make_rows(ord::Design* design,
154+
int core_lx,
155+
int core_ly,
156+
int core_ux,
157+
int core_uy,
158+
odb::dbSite* site,
159+
const std::vector<odb::dbSite*>& additional_sites,
160+
ifp::RowParity row_parity,
161+
const std::vector<odb::dbSite*>& flipped_sites)
162+
{
163+
164+
std::set<odb::dbSite*> flipped_sites_set(flipped_sites.begin(),
165+
flipped_sites.end());
166+
design->getFloorplan().makeRows({core_lx, core_ly, core_ux, core_uy},
167+
site,
168+
additional_sites,
169+
row_parity,
170+
flipped_sites_set);
171+
}
172+
149173
void
150174
make_layer_tracks(ord::Design* design,
151175
odb::dbTechLayer* layer,

0 commit comments

Comments
 (0)