1 /* 2 * nextpnr -- Next Generation Place and Route 3 * 4 * Copyright (C) 2018 Clifford Wolf <clifford@symbioticeda.com> 5 * 6 * Permission to use, copy, modify, and/or distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 * 18 */ 19 20 #ifndef NEXTPNR_H 21 #error Include "arch.h" via "nextpnr.h" only. 22 #endif 23 24 NEXTPNR_NAMESPACE_BEGIN 25 26 /**** Everything in this section must be kept in sync with chipdb.py ****/ 27 28 template <typename T> struct RelPtr 29 { 30 int32_t offset; 31 32 // void set(const T *ptr) { 33 // offset = reinterpret_cast<const char*>(ptr) - 34 // reinterpret_cast<const char*>(this); 35 // } 36 getRelPtr37 const T *get() const { return reinterpret_cast<const T *>(reinterpret_cast<const char *>(this) + offset); } 38 39 const T &operator[](size_t index) const { return get()[index]; } 40 41 const T &operator*() const { return *(get()); } 42 43 const T *operator->() const { return get(); } 44 }; 45 46 NPNR_PACKED_STRUCT(struct BelWirePOD { 47 int32_t port; 48 int32_t type; 49 int32_t wire_index; 50 }); 51 52 NPNR_PACKED_STRUCT(struct BelInfoPOD { 53 RelPtr<char> name; 54 int32_t type; 55 int32_t num_bel_wires; 56 RelPtr<BelWirePOD> bel_wires; 57 int8_t x, y, z; 58 int8_t padding_0; 59 }); 60 61 NPNR_PACKED_STRUCT(struct BelPortPOD { 62 int32_t bel_index; 63 int32_t port; 64 }); 65 66 NPNR_PACKED_STRUCT(struct PipInfoPOD { 67 enum PipFlags : uint32_t 68 { 69 FLAG_NONE = 0, 70 FLAG_ROUTETHRU = 1, 71 FLAG_NOCARRY = 2 72 }; 73 74 // RelPtr<char> name; 75 int32_t src, dst; 76 int32_t fast_delay; 77 int32_t slow_delay; 78 int8_t x, y; 79 int16_t src_seg, dst_seg; 80 int16_t switch_mask; 81 int32_t switch_index; 82 PipFlags flags; 83 }); 84 85 NPNR_PACKED_STRUCT(struct WireSegmentPOD { 86 int8_t x, y; 87 int16_t index; 88 }); 89 90 NPNR_PACKED_STRUCT(struct WireInfoPOD { 91 enum WireType : int8_t 92 { 93 WIRE_TYPE_NONE = 0, 94 WIRE_TYPE_GLB2LOCAL = 1, 95 WIRE_TYPE_GLB_NETWK = 2, 96 WIRE_TYPE_LOCAL = 3, 97 WIRE_TYPE_LUTFF_IN = 4, 98 WIRE_TYPE_LUTFF_IN_LUT = 5, 99 WIRE_TYPE_LUTFF_LOUT = 6, 100 WIRE_TYPE_LUTFF_OUT = 7, 101 WIRE_TYPE_LUTFF_COUT = 8, 102 WIRE_TYPE_LUTFF_GLOBAL = 9, 103 WIRE_TYPE_CARRY_IN_MUX = 10, 104 WIRE_TYPE_SP4_V = 11, 105 WIRE_TYPE_SP4_H = 12, 106 WIRE_TYPE_SP12_V = 13, 107 WIRE_TYPE_SP12_H = 14 108 }; 109 110 RelPtr<char> name; 111 int32_t num_uphill, num_downhill; 112 RelPtr<int32_t> pips_uphill, pips_downhill; 113 114 int32_t num_bel_pins; 115 RelPtr<BelPortPOD> bel_pins; 116 117 int32_t num_segments; 118 RelPtr<WireSegmentPOD> segments; 119 120 int32_t fast_delay; 121 int32_t slow_delay; 122 123 int8_t x, y, z; 124 WireType type; 125 }); 126 127 NPNR_PACKED_STRUCT(struct PackagePinPOD { 128 RelPtr<char> name; 129 int32_t bel_index; 130 }); 131 132 NPNR_PACKED_STRUCT(struct PackageInfoPOD { 133 RelPtr<char> name; 134 int32_t num_pins; 135 RelPtr<PackagePinPOD> pins; 136 }); 137 138 enum TileType : uint32_t 139 { 140 TILE_NONE = 0, 141 TILE_LOGIC = 1, 142 TILE_IO = 2, 143 TILE_RAMB = 3, 144 TILE_RAMT = 4, 145 TILE_DSP0 = 5, 146 TILE_DSP1 = 6, 147 TILE_DSP2 = 7, 148 TILE_DSP3 = 8, 149 TILE_IPCON = 9 150 }; 151 152 NPNR_PACKED_STRUCT(struct ConfigBitPOD { int8_t row, col; }); 153 154 NPNR_PACKED_STRUCT(struct ConfigEntryPOD { 155 RelPtr<char> name; 156 int32_t num_bits; 157 RelPtr<ConfigBitPOD> bits; 158 }); 159 160 NPNR_PACKED_STRUCT(struct TileInfoPOD { 161 int8_t cols, rows; 162 int16_t num_config_entries; 163 RelPtr<ConfigEntryPOD> entries; 164 }); 165 166 static const int max_switch_bits = 5; 167 168 NPNR_PACKED_STRUCT(struct SwitchInfoPOD { 169 int32_t num_bits; 170 int32_t bel; 171 int8_t x, y; 172 ConfigBitPOD cbits[max_switch_bits]; 173 }); 174 175 NPNR_PACKED_STRUCT(struct IerenInfoPOD { 176 int8_t iox, ioy, ioz; 177 int8_t ierx, iery, ierz; 178 }); 179 180 NPNR_PACKED_STRUCT(struct BitstreamInfoPOD { 181 int32_t num_switches, num_ierens; 182 RelPtr<TileInfoPOD> tiles_nonrouting; 183 RelPtr<SwitchInfoPOD> switches; 184 RelPtr<IerenInfoPOD> ierens; 185 }); 186 187 NPNR_PACKED_STRUCT(struct BelConfigEntryPOD { 188 RelPtr<char> entry_name; 189 RelPtr<char> cbit_name; 190 int8_t x, y; 191 int16_t padding; 192 }); 193 194 // Stores mapping between bel parameters and config bits, 195 // for extra cells where this mapping is non-trivial 196 NPNR_PACKED_STRUCT(struct BelConfigPOD { 197 int32_t bel_index; 198 int32_t num_entries; 199 RelPtr<BelConfigEntryPOD> entries; 200 }); 201 202 NPNR_PACKED_STRUCT(struct CellPathDelayPOD { 203 int32_t from_port; 204 int32_t to_port; 205 int32_t fast_delay; 206 int32_t slow_delay; 207 }); 208 209 NPNR_PACKED_STRUCT(struct CellTimingPOD { 210 int32_t type; 211 int32_t num_paths; 212 RelPtr<CellPathDelayPOD> path_delays; 213 }); 214 215 NPNR_PACKED_STRUCT(struct GlobalNetworkInfoPOD { 216 uint8_t gb_x; 217 uint8_t gb_y; 218 219 uint8_t pi_gb_x; 220 uint8_t pi_gb_y; 221 uint8_t pi_gb_pio; 222 223 uint8_t pi_eb_bank; 224 uint16_t pi_eb_x; 225 uint16_t pi_eb_y; 226 227 uint16_t pad; 228 }); 229 230 NPNR_PACKED_STRUCT(struct ChipInfoPOD { 231 int32_t width, height; 232 int32_t num_bels, num_wires, num_pips; 233 int32_t num_switches, num_belcfgs, num_packages; 234 int32_t num_timing_cells, num_global_networks; 235 RelPtr<BelInfoPOD> bel_data; 236 RelPtr<WireInfoPOD> wire_data; 237 RelPtr<PipInfoPOD> pip_data; 238 RelPtr<TileType> tile_grid; 239 RelPtr<BitstreamInfoPOD> bits_info; 240 RelPtr<BelConfigPOD> bel_config; 241 RelPtr<PackageInfoPOD> packages_data; 242 RelPtr<CellTimingPOD> cell_timing; 243 RelPtr<GlobalNetworkInfoPOD> global_network_info; 244 RelPtr<RelPtr<char>> tile_wire_names; 245 }); 246 247 /************************ End of chipdb section. ************************/ 248 249 struct BelIterator 250 { 251 int cursor; 252 253 BelIterator operator++() 254 { 255 cursor++; 256 return *this; 257 } 258 BelIterator operator++(int) 259 { 260 BelIterator prior(*this); 261 cursor++; 262 return prior; 263 } 264 265 bool operator!=(const BelIterator &other) const { return cursor != other.cursor; } 266 267 bool operator==(const BelIterator &other) const { return cursor == other.cursor; } 268 269 BelId operator*() const 270 { 271 BelId ret; 272 ret.index = cursor; 273 return ret; 274 } 275 }; 276 277 struct BelRange 278 { 279 BelIterator b, e; beginBelRange280 BelIterator begin() const { return b; } endBelRange281 BelIterator end() const { return e; } 282 }; 283 284 // ----------------------------------------------------------------------- 285 286 struct BelPinIterator 287 { 288 const BelPortPOD *ptr = nullptr; 289 290 void operator++() { ptr++; } 291 bool operator!=(const BelPinIterator &other) const { return ptr != other.ptr; } 292 293 BelPin operator*() const 294 { 295 BelPin ret; 296 ret.bel.index = ptr->bel_index; 297 ret.pin = ptr->port; 298 return ret; 299 } 300 }; 301 302 struct BelPinRange 303 { 304 BelPinIterator b, e; beginBelPinRange305 BelPinIterator begin() const { return b; } endBelPinRange306 BelPinIterator end() const { return e; } 307 }; 308 309 // ----------------------------------------------------------------------- 310 311 struct WireIterator 312 { 313 int cursor = -1; 314 315 void operator++() { cursor++; } 316 bool operator!=(const WireIterator &other) const { return cursor != other.cursor; } 317 318 WireId operator*() const 319 { 320 WireId ret; 321 ret.index = cursor; 322 return ret; 323 } 324 }; 325 326 struct WireRange 327 { 328 WireIterator b, e; beginWireRange329 WireIterator begin() const { return b; } endWireRange330 WireIterator end() const { return e; } 331 }; 332 333 // ----------------------------------------------------------------------- 334 335 struct AllPipIterator 336 { 337 int cursor = -1; 338 339 void operator++() { cursor++; } 340 bool operator!=(const AllPipIterator &other) const { return cursor != other.cursor; } 341 342 PipId operator*() const 343 { 344 PipId ret; 345 ret.index = cursor; 346 return ret; 347 } 348 }; 349 350 struct AllPipRange 351 { 352 AllPipIterator b, e; beginAllPipRange353 AllPipIterator begin() const { return b; } endAllPipRange354 AllPipIterator end() const { return e; } 355 }; 356 357 // ----------------------------------------------------------------------- 358 359 struct PipIterator 360 { 361 const int *cursor = nullptr; 362 363 void operator++() { cursor++; } 364 bool operator!=(const PipIterator &other) const { return cursor != other.cursor; } 365 366 PipId operator*() const 367 { 368 PipId ret; 369 ret.index = *cursor; 370 return ret; 371 } 372 }; 373 374 struct PipRange 375 { 376 PipIterator b, e; beginPipRange377 PipIterator begin() const { return b; } endPipRange378 PipIterator end() const { return e; } 379 }; 380 381 struct ArchArgs 382 { 383 enum ArchArgsTypes 384 { 385 NONE, 386 LP384, 387 LP1K, 388 LP4K, 389 LP8K, 390 HX1K, 391 HX4K, 392 HX8K, 393 UP3K, 394 UP5K, 395 U1K, 396 U2K, 397 U4K 398 } type = NONE; 399 std::string package; 400 }; 401 402 struct Arch : BaseCtx 403 { 404 bool fast_part; 405 const ChipInfoPOD *chip_info; 406 const PackageInfoPOD *package_info; 407 408 mutable std::unordered_map<IdString, int> bel_by_name; 409 mutable std::unordered_map<IdString, int> wire_by_name; 410 mutable std::unordered_map<IdString, int> pip_by_name; 411 mutable std::unordered_map<Loc, int> bel_by_loc; 412 413 std::vector<bool> bel_carry; 414 std::vector<CellInfo *> bel_to_cell; 415 std::vector<NetInfo *> wire_to_net; 416 std::vector<NetInfo *> pip_to_net; 417 std::vector<WireId> switches_locked; 418 419 ArchArgs args; 420 Arch(ArchArgs args); 421 422 static bool isAvailable(ArchArgs::ArchArgsTypes chip); 423 static std::vector<std::string> getSupportedPackages(ArchArgs::ArchArgsTypes chip); 424 425 std::string getChipName() const; 426 archIdArch427 IdString archId() const { return id("ice40"); } archArgsArch428 ArchArgs archArgs() const { return args; } 429 IdString archArgsToId(ArchArgs args) const; 430 431 // ------------------------------------------------- 432 getGridDimXArch433 int getGridDimX() const { return chip_info->width; } getGridDimYArch434 int getGridDimY() const { return chip_info->height; } getTileBelDimZArch435 int getTileBelDimZ(int, int) const { return 8; } getTilePipDimZArch436 int getTilePipDimZ(int, int) const { return 1; } 437 438 // ------------------------------------------------- 439 440 BelId getBelByName(IdString name) const; 441 getBelNameArch442 IdString getBelName(BelId bel) const 443 { 444 NPNR_ASSERT(bel != BelId()); 445 return id(chip_info->bel_data[bel.index].name.get()); 446 } 447 getBelChecksumArch448 uint32_t getBelChecksum(BelId bel) const { return bel.index; } 449 bindBelArch450 void bindBel(BelId bel, CellInfo *cell, PlaceStrength strength) 451 { 452 NPNR_ASSERT(bel != BelId()); 453 NPNR_ASSERT(bel_to_cell[bel.index] == nullptr); 454 455 bel_to_cell[bel.index] = cell; 456 bel_carry[bel.index] = (cell->type == id_ICESTORM_LC && cell->lcInfo.carryEnable); 457 cell->bel = bel; 458 cell->belStrength = strength; 459 refreshUiBel(bel); 460 } 461 unbindBelArch462 void unbindBel(BelId bel) 463 { 464 NPNR_ASSERT(bel != BelId()); 465 NPNR_ASSERT(bel_to_cell[bel.index] != nullptr); 466 bel_to_cell[bel.index]->bel = BelId(); 467 bel_to_cell[bel.index]->belStrength = STRENGTH_NONE; 468 bel_to_cell[bel.index] = nullptr; 469 bel_carry[bel.index] = false; 470 refreshUiBel(bel); 471 } 472 checkBelAvailArch473 bool checkBelAvail(BelId bel) const 474 { 475 NPNR_ASSERT(bel != BelId()); 476 return bel_to_cell[bel.index] == nullptr; 477 } 478 getBoundBelCellArch479 CellInfo *getBoundBelCell(BelId bel) const 480 { 481 NPNR_ASSERT(bel != BelId()); 482 return bel_to_cell[bel.index]; 483 } 484 getConflictingBelCellArch485 CellInfo *getConflictingBelCell(BelId bel) const 486 { 487 NPNR_ASSERT(bel != BelId()); 488 return bel_to_cell[bel.index]; 489 } 490 getBelsArch491 BelRange getBels() const 492 { 493 BelRange range; 494 range.b.cursor = 0; 495 range.e.cursor = chip_info->num_bels; 496 return range; 497 } 498 getBelLocationArch499 Loc getBelLocation(BelId bel) const 500 { 501 NPNR_ASSERT(bel != BelId()); 502 Loc loc; 503 loc.x = chip_info->bel_data[bel.index].x; 504 loc.y = chip_info->bel_data[bel.index].y; 505 loc.z = chip_info->bel_data[bel.index].z; 506 return loc; 507 } 508 509 BelId getBelByLocation(Loc loc) const; 510 BelRange getBelsByTile(int x, int y) const; 511 getBelGlobalBufArch512 bool getBelGlobalBuf(BelId bel) const { return chip_info->bel_data[bel.index].type == ID_SB_GB; } 513 getBelTypeArch514 IdString getBelType(BelId bel) const 515 { 516 NPNR_ASSERT(bel != BelId()); 517 return IdString(chip_info->bel_data[bel.index].type); 518 } 519 520 std::vector<std::pair<IdString, std::string>> getBelAttrs(BelId bel) const; 521 522 WireId getBelPinWire(BelId bel, IdString pin) const; 523 PortType getBelPinType(BelId bel, IdString pin) const; 524 std::vector<IdString> getBelPins(BelId bel) const; 525 526 bool isBelLocked(BelId bel) const; 527 528 // ------------------------------------------------- 529 530 WireId getWireByName(IdString name) const; 531 getWireNameArch532 IdString getWireName(WireId wire) const 533 { 534 NPNR_ASSERT(wire != WireId()); 535 return id(chip_info->wire_data[wire.index].name.get()); 536 } 537 538 IdString getWireType(WireId wire) const; 539 std::vector<std::pair<IdString, std::string>> getWireAttrs(WireId wire) const; 540 getWireChecksumArch541 uint32_t getWireChecksum(WireId wire) const { return wire.index; } 542 bindWireArch543 void bindWire(WireId wire, NetInfo *net, PlaceStrength strength) 544 { 545 NPNR_ASSERT(wire != WireId()); 546 NPNR_ASSERT(wire_to_net[wire.index] == nullptr); 547 wire_to_net[wire.index] = net; 548 net->wires[wire].pip = PipId(); 549 net->wires[wire].strength = strength; 550 refreshUiWire(wire); 551 } 552 unbindWireArch553 void unbindWire(WireId wire) 554 { 555 NPNR_ASSERT(wire != WireId()); 556 NPNR_ASSERT(wire_to_net[wire.index] != nullptr); 557 558 auto &net_wires = wire_to_net[wire.index]->wires; 559 auto it = net_wires.find(wire); 560 NPNR_ASSERT(it != net_wires.end()); 561 562 auto pip = it->second.pip; 563 if (pip != PipId()) { 564 pip_to_net[pip.index] = nullptr; 565 switches_locked[chip_info->pip_data[pip.index].switch_index] = WireId(); 566 } 567 568 net_wires.erase(it); 569 wire_to_net[wire.index] = nullptr; 570 refreshUiWire(wire); 571 } 572 checkWireAvailArch573 bool checkWireAvail(WireId wire) const 574 { 575 NPNR_ASSERT(wire != WireId()); 576 return wire_to_net[wire.index] == nullptr; 577 } 578 getBoundWireNetArch579 NetInfo *getBoundWireNet(WireId wire) const 580 { 581 NPNR_ASSERT(wire != WireId()); 582 return wire_to_net[wire.index]; 583 } 584 getConflictingWireWireArch585 WireId getConflictingWireWire(WireId wire) const { return wire; } 586 getConflictingWireNetArch587 NetInfo *getConflictingWireNet(WireId wire) const 588 { 589 NPNR_ASSERT(wire != WireId()); 590 return wire_to_net[wire.index]; 591 } 592 getWireDelayArch593 DelayInfo getWireDelay(WireId wire) const 594 { 595 DelayInfo delay; 596 NPNR_ASSERT(wire != WireId()); 597 if (fast_part) 598 delay.delay = chip_info->wire_data[wire.index].fast_delay; 599 else 600 delay.delay = chip_info->wire_data[wire.index].slow_delay; 601 return delay; 602 } 603 getWireBelPinsArch604 BelPinRange getWireBelPins(WireId wire) const 605 { 606 BelPinRange range; 607 NPNR_ASSERT(wire != WireId()); 608 range.b.ptr = chip_info->wire_data[wire.index].bel_pins.get(); 609 range.e.ptr = range.b.ptr + chip_info->wire_data[wire.index].num_bel_pins; 610 return range; 611 } 612 getWiresArch613 WireRange getWires() const 614 { 615 WireRange range; 616 range.b.cursor = 0; 617 range.e.cursor = chip_info->num_wires; 618 return range; 619 } 620 621 // ------------------------------------------------- 622 623 PipId getPipByName(IdString name) const; 624 bindPipArch625 void bindPip(PipId pip, NetInfo *net, PlaceStrength strength) 626 { 627 NPNR_ASSERT(pip != PipId()); 628 NPNR_ASSERT(pip_to_net[pip.index] == nullptr); 629 NPNR_ASSERT(switches_locked[chip_info->pip_data[pip.index].switch_index] == WireId()); 630 631 WireId dst; 632 dst.index = chip_info->pip_data[pip.index].dst; 633 NPNR_ASSERT(wire_to_net[dst.index] == nullptr); 634 635 pip_to_net[pip.index] = net; 636 switches_locked[chip_info->pip_data[pip.index].switch_index] = dst; 637 638 wire_to_net[dst.index] = net; 639 net->wires[dst].pip = pip; 640 net->wires[dst].strength = strength; 641 refreshUiPip(pip); 642 refreshUiWire(dst); 643 } 644 unbindPipArch645 void unbindPip(PipId pip) 646 { 647 NPNR_ASSERT(pip != PipId()); 648 NPNR_ASSERT(pip_to_net[pip.index] != nullptr); 649 NPNR_ASSERT(switches_locked[chip_info->pip_data[pip.index].switch_index] != WireId()); 650 651 WireId dst; 652 dst.index = chip_info->pip_data[pip.index].dst; 653 NPNR_ASSERT(wire_to_net[dst.index] != nullptr); 654 wire_to_net[dst.index] = nullptr; 655 pip_to_net[pip.index]->wires.erase(dst); 656 657 pip_to_net[pip.index] = nullptr; 658 switches_locked[chip_info->pip_data[pip.index].switch_index] = WireId(); 659 refreshUiPip(pip); 660 refreshUiWire(dst); 661 } 662 ice40_pip_hard_unavailArch663 bool ice40_pip_hard_unavail(PipId pip) const 664 { 665 NPNR_ASSERT(pip != PipId()); 666 auto &pi = chip_info->pip_data[pip.index]; 667 auto &si = chip_info->bits_info->switches[pi.switch_index]; 668 669 if (pi.flags & PipInfoPOD::FLAG_ROUTETHRU) { 670 NPNR_ASSERT(si.bel >= 0); 671 if (bel_to_cell[si.bel] != nullptr) 672 return true; 673 } 674 675 if (pi.flags & PipInfoPOD::FLAG_NOCARRY) { 676 NPNR_ASSERT(si.bel >= 0); 677 if (bel_carry[si.bel]) 678 return true; 679 } 680 681 return false; 682 } 683 checkPipAvailArch684 bool checkPipAvail(PipId pip) const 685 { 686 if (ice40_pip_hard_unavail(pip)) 687 return false; 688 689 auto &pi = chip_info->pip_data[pip.index]; 690 return switches_locked[pi.switch_index] == WireId(); 691 } 692 getBoundPipNetArch693 NetInfo *getBoundPipNet(PipId pip) const 694 { 695 NPNR_ASSERT(pip != PipId()); 696 return pip_to_net[pip.index]; 697 } 698 getConflictingPipWireArch699 WireId getConflictingPipWire(PipId pip) const 700 { 701 if (ice40_pip_hard_unavail(pip)) 702 return WireId(); 703 704 return switches_locked[chip_info->pip_data[pip.index].switch_index]; 705 } 706 getConflictingPipNetArch707 NetInfo *getConflictingPipNet(PipId pip) const 708 { 709 if (ice40_pip_hard_unavail(pip)) 710 return nullptr; 711 712 WireId wire = switches_locked[chip_info->pip_data[pip.index].switch_index]; 713 return wire == WireId() ? nullptr : wire_to_net[wire.index]; 714 } 715 getPipsArch716 AllPipRange getPips() const 717 { 718 AllPipRange range; 719 range.b.cursor = 0; 720 range.e.cursor = chip_info->num_pips; 721 return range; 722 } 723 getPipLocationArch724 Loc getPipLocation(PipId pip) const 725 { 726 Loc loc; 727 loc.x = chip_info->pip_data[pip.index].x; 728 loc.y = chip_info->pip_data[pip.index].y; 729 loc.z = 0; 730 return loc; 731 } 732 733 IdString getPipName(PipId pip) const; 734 735 IdString getPipType(PipId pip) const; 736 std::vector<std::pair<IdString, std::string>> getPipAttrs(PipId pip) const; 737 getPipChecksumArch738 uint32_t getPipChecksum(PipId pip) const { return pip.index; } 739 getPipSrcWireArch740 WireId getPipSrcWire(PipId pip) const 741 { 742 WireId wire; 743 NPNR_ASSERT(pip != PipId()); 744 wire.index = chip_info->pip_data[pip.index].src; 745 return wire; 746 } 747 getPipDstWireArch748 WireId getPipDstWire(PipId pip) const 749 { 750 WireId wire; 751 NPNR_ASSERT(pip != PipId()); 752 wire.index = chip_info->pip_data[pip.index].dst; 753 return wire; 754 } 755 getPipDelayArch756 DelayInfo getPipDelay(PipId pip) const 757 { 758 DelayInfo delay; 759 NPNR_ASSERT(pip != PipId()); 760 if (fast_part) 761 delay.delay = chip_info->pip_data[pip.index].fast_delay; 762 else 763 delay.delay = chip_info->pip_data[pip.index].slow_delay; 764 return delay; 765 } 766 getPipsDownhillArch767 PipRange getPipsDownhill(WireId wire) const 768 { 769 PipRange range; 770 NPNR_ASSERT(wire != WireId()); 771 range.b.cursor = chip_info->wire_data[wire.index].pips_downhill.get(); 772 range.e.cursor = range.b.cursor + chip_info->wire_data[wire.index].num_downhill; 773 return range; 774 } 775 getPipsUphillArch776 PipRange getPipsUphill(WireId wire) const 777 { 778 PipRange range; 779 NPNR_ASSERT(wire != WireId()); 780 range.b.cursor = chip_info->wire_data[wire.index].pips_uphill.get(); 781 range.e.cursor = range.b.cursor + chip_info->wire_data[wire.index].num_uphill; 782 return range; 783 } 784 getWireAliasesArch785 PipRange getWireAliases(WireId wire) const 786 { 787 PipRange range; 788 NPNR_ASSERT(wire != WireId()); 789 range.b.cursor = nullptr; 790 range.e.cursor = nullptr; 791 return range; 792 } 793 794 BelId getPackagePinBel(const std::string &pin) const; 795 std::string getBelPackagePin(BelId bel) const; 796 797 // ------------------------------------------------- 798 799 GroupId getGroupByName(IdString name) const; 800 IdString getGroupName(GroupId group) const; 801 std::vector<GroupId> getGroups() const; 802 std::vector<BelId> getGroupBels(GroupId group) const; 803 std::vector<WireId> getGroupWires(GroupId group) const; 804 std::vector<PipId> getGroupPips(GroupId group) const; 805 std::vector<GroupId> getGroupGroups(GroupId group) const; 806 807 // ------------------------------------------------- 808 809 delay_t estimateDelay(WireId src, WireId dst) const; 810 delay_t predictDelay(const NetInfo *net_info, const PortRef &sink) const; getDelayEpsilonArch811 delay_t getDelayEpsilon() const { return 20; } getRipupDelayPenaltyArch812 delay_t getRipupDelayPenalty() const { return 200; } getDelayNSArch813 float getDelayNS(delay_t v) const { return v * 0.001; } getDelayFromNSArch814 DelayInfo getDelayFromNS(float ns) const 815 { 816 DelayInfo del; 817 del.delay = delay_t(ns * 1000); 818 return del; 819 } getDelayChecksumArch820 uint32_t getDelayChecksum(delay_t v) const { return v; } 821 bool getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t &budget) const; 822 823 ArcBounds getRouteBoundingBox(WireId src, WireId dst) const; 824 825 // ------------------------------------------------- 826 827 bool pack(); 828 bool place(); 829 bool route(); 830 831 // ------------------------------------------------- 832 833 std::vector<GraphicElement> getDecalGraphics(DecalId decal) const; 834 835 DecalXY getBelDecal(BelId bel) const; 836 DecalXY getWireDecal(WireId wire) const; 837 DecalXY getPipDecal(PipId pip) const; 838 DecalXY getGroupDecal(GroupId group) const; 839 840 // ------------------------------------------------- 841 842 // Get the delay through a cell from one port to another, returning false 843 // if no path exists. This only considers combinational delays, as required by the Arch API 844 bool getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const; 845 // getCellDelayInternal is similar to the above, but without false path checks and including clock to out delays 846 // for internal arch use only 847 bool getCellDelayInternal(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const; 848 // Get the port class, also setting clockInfoCount to the number of TimingClockingInfos associated with a port 849 TimingPortClass getPortTimingClass(const CellInfo *cell, IdString port, int &clockInfoCount) const; 850 // Get the TimingClockingInfo of a port 851 TimingClockingInfo getPortClockingInfo(const CellInfo *cell, IdString port, int index) const; 852 // Return true if a port is a net 853 bool isGlobalNet(const NetInfo *net) const; 854 855 // ------------------------------------------------- 856 857 // Perform placement validity checks, returning false on failure (all 858 // implemented in arch_place.cc) 859 860 // Whether or not a given cell can be placed at a given Bel 861 // This is not intended for Bel type checks, but finer-grained constraints 862 // such as conflicting set/reset signals, etc 863 bool isValidBelForCell(CellInfo *cell, BelId bel) const; 864 865 // Return true whether all Bels at a given location are valid 866 bool isBelLocationValid(BelId bel) const; 867 868 // Helper function for above 869 bool logicCellsCompatible(const CellInfo **it, const size_t size) const; 870 871 // ------------------------------------------------- 872 // Assign architecure-specific arguments to nets and cells, which must be 873 // called between packing or further 874 // netlist modifications, and validity checks 875 void assignArchInfo(); 876 void assignCellInfo(CellInfo *cell); 877 878 // ------------------------------------------------- getIOBSharingPLLPinArch879 BelPin getIOBSharingPLLPin(BelId pll, IdString pll_pin) const 880 { 881 auto wire = getBelPinWire(pll, pll_pin); 882 for (auto src_bel : getWireBelPins(wire)) { 883 if (getBelType(src_bel.bel) == id_SB_IO && src_bel.pin == id_D_IN_0) { 884 return src_bel; 885 } 886 } 887 NPNR_ASSERT_FALSE("Expected PLL pin to share an output with an SB_IO D_IN_{0,1}"); 888 } 889 getDrivenGlobalNetworkArch890 int getDrivenGlobalNetwork(BelId bel) const 891 { 892 NPNR_ASSERT(getBelType(bel) == id_SB_GB); 893 IdString glb_net = getWireName(getBelPinWire(bel, id_GLOBAL_BUFFER_OUTPUT)); 894 return std::stoi(std::string("") + glb_net.str(this).back()); 895 } 896 897 static const std::string defaultPlacer; 898 static const std::vector<std::string> availablePlacers; 899 static const std::string defaultRouter; 900 static const std::vector<std::string> availableRouters; 901 }; 902 903 void ice40DelayFuzzerMain(Context *ctx); 904 905 NEXTPNR_NAMESPACE_END 906