|
10 | 10 | #include <string> |
11 | 11 | #include <vector> |
12 | 12 |
|
| 13 | +#include "bmapParser.h" |
13 | 14 | #include "dbvParser.h" |
14 | 15 | #include "dbxParser.h" |
15 | 16 | #include "objects.h" |
@@ -206,6 +207,13 @@ void ThreeDBlox::createChiplet(const ChipletDef& chiplet) |
206 | 207 |
|
207 | 208 | chip->setOffset(Point(chiplet.offset.x * db_->getDbuPerMicron(), |
208 | 209 | chiplet.offset.y * db_->getDbuPerMicron())); |
| 210 | + if (chip->getChipType() != dbChip::ChipType::HIER |
| 211 | + && chip->getBlock() == nullptr) { |
| 212 | + // blackbox stage, create block |
| 213 | + auto block = odb::dbBlock::create(chip, chiplet.name.c_str()); |
| 214 | + block->setDieArea(Rect(0, 0, chip->getWidth(), chip->getHeight())); |
| 215 | + block->setCoreArea(Rect(0, 0, chip->getWidth(), chip->getHeight())); |
| 216 | + } |
209 | 217 | for (const auto& [_, region] : chiplet.regions) { |
210 | 218 | createRegion(region, chip); |
211 | 219 | } |
@@ -244,7 +252,72 @@ void ThreeDBlox::createRegion(const ChipletRegion& region, dbChip* chip) |
244 | 252 | box); |
245 | 253 | } |
246 | 254 | chip_region->setBox(box); |
| 255 | + // Read bump map file |
| 256 | + if (!region.bmap.empty()) { |
| 257 | + BmapParser parser(logger_); |
| 258 | + BumpMapData data = parser.parseFile(region.bmap); |
| 259 | + for (const auto& entry : data.entries) { |
| 260 | + createBump(entry, chip_region); |
| 261 | + } |
| 262 | + } |
| 263 | +} |
| 264 | + |
| 265 | +void ThreeDBlox::createBump(const BumpMapEntry& entry, |
| 266 | + dbChipRegion* chip_region) |
| 267 | +{ |
| 268 | + auto chip = chip_region->getChip(); |
| 269 | + auto block = chip->getBlock(); |
| 270 | + auto inst = block->findInst(entry.bump_inst_name.c_str()); |
| 271 | + if (inst == nullptr) { |
| 272 | + // create inst |
| 273 | + auto master = db_->findMaster(entry.bump_cell_type.c_str()); |
| 274 | + if (master == nullptr) { |
| 275 | + logger_->error(utl::ODB, |
| 276 | + 531, |
| 277 | + "3DBV Parser Error: Bump cell type {} not found", |
| 278 | + entry.bump_cell_type); |
| 279 | + } |
| 280 | + if (master->getLib()->getTech() != chip->getTech()) { |
| 281 | + logger_->error(utl::ODB, |
| 282 | + 532, |
| 283 | + "3DBV Parser Error: Bump cell type {} is not in the same " |
| 284 | + "tech as the chip region {}/{}", |
| 285 | + entry.bump_cell_type, |
| 286 | + chip->getName(), |
| 287 | + chip_region->getName()); |
| 288 | + } |
| 289 | + inst = dbInst::create(block, master, entry.bump_inst_name.c_str()); |
| 290 | + } |
| 291 | + auto bump = dbChipBump::create(chip_region, inst); |
| 292 | + inst->setOrigin(entry.x * db_->getDbuPerMicron(), |
| 293 | + entry.y * db_->getDbuPerMicron()); |
| 294 | + inst->setPlacementStatus(dbPlacementStatus::FIRM); |
| 295 | + if (entry.net_name != "-") { |
| 296 | + auto net = block->findNet(entry.net_name.c_str()); |
| 297 | + if (net == nullptr) { |
| 298 | + logger_->error(utl::ODB, |
| 299 | + 534, |
| 300 | + "3DBV Parser Error: Bump net {} not found", |
| 301 | + entry.net_name); |
| 302 | + } |
| 303 | + bump->setNet(net); |
| 304 | + inst->getITerms().begin()->connect(net); |
| 305 | + } |
| 306 | + if (entry.port_name != "-") { |
| 307 | + auto bterm = block->findBTerm(entry.port_name.c_str()); |
| 308 | + if (bterm == nullptr) { |
| 309 | + logger_->error(utl::ODB, |
| 310 | + 533, |
| 311 | + "3DBV Parser Error: Bump port {} not found", |
| 312 | + entry.port_name); |
| 313 | + } |
| 314 | + bump->setBTerm(bterm); |
| 315 | + if (bump->getNet()) { |
| 316 | + bterm->connect(bump->getNet()); |
| 317 | + } |
| 318 | + } |
247 | 319 | } |
| 320 | + |
248 | 321 | dbChip* ThreeDBlox::createDesignTopChiplet(const DesignDef& design) |
249 | 322 | { |
250 | 323 | dbChip* chip |
|
0 commit comments