diff options
Diffstat (limited to 'ice40/arch.cc')
-rw-r--r-- | ice40/arch.cc | 78 |
1 files changed, 63 insertions, 15 deletions
diff --git a/ice40/arch.cc b/ice40/arch.cc index 107bf56a..bdfb13fe 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -141,18 +141,23 @@ Arch::Arch(ArchArgs args) : args(args) #ifdef ICE40_HX1K_ONLY if (args.type == ArchArgs::HX1K) { + fast_part = true; chip_info = get_chip_info(reinterpret_cast<const RelPtr<ChipInfoPOD> *>(chipdb_blob_1k)); } else { log_error("Unsupported iCE40 chip type.\n"); } #else if (args.type == ArchArgs::LP384) { + fast_part = false; chip_info = get_chip_info(reinterpret_cast<const RelPtr<ChipInfoPOD> *>(chipdb_blob_384)); } else if (args.type == ArchArgs::LP1K || args.type == ArchArgs::HX1K) { + fast_part = args.type == ArchArgs::HX1K; chip_info = get_chip_info(reinterpret_cast<const RelPtr<ChipInfoPOD> *>(chipdb_blob_1k)); } else if (args.type == ArchArgs::UP5K) { + fast_part = false; chip_info = get_chip_info(reinterpret_cast<const RelPtr<ChipInfoPOD> *>(chipdb_blob_5k)); } else if (args.type == ArchArgs::LP8K || args.type == ArchArgs::HX8K) { + fast_part = args.type == ArchArgs::HX8K; chip_info = get_chip_info(reinterpret_cast<const RelPtr<ChipInfoPOD> *>(chipdb_blob_8k)); } else { log_error("Unsupported iCE40 chip type.\n"); @@ -199,7 +204,7 @@ Arch::Arch(ArchArgs args) : args(args) // ----------------------------------------------------------------------- -std::string Arch::getChipName() +std::string Arch::getChipName() const { #ifdef ICE40_HX1K_ONLY if (args.type == ArchArgs::HX1K) { @@ -306,9 +311,23 @@ PortType Arch::getBelPinType(BelId bel, PortPin pin) const int num_bel_wires = chip_info->bel_data[bel.index].num_bel_wires; const BelWirePOD *bel_wires = chip_info->bel_data[bel.index].bel_wires.get(); - for (int i = 0; i < num_bel_wires; i++) - if (bel_wires[i].port == pin) - return PortType(bel_wires[i].type); + if (num_bel_wires < 7) { + for (int i = 0; i < num_bel_wires; i++) { + if (bel_wires[i].port == pin) + return PortType(bel_wires[i].type); + } + } else { + int b = 0, e = num_bel_wires-1; + while (b <= e) { + int i = (b+e) / 2; + if (bel_wires[i].port == pin) + return PortType(bel_wires[i].type); + if (bel_wires[i].port > pin) + e = i-1; + else + b = i+1; + } + } return PORT_INOUT; } @@ -322,10 +341,25 @@ WireId Arch::getBelPinWire(BelId bel, PortPin pin) const int num_bel_wires = chip_info->bel_data[bel.index].num_bel_wires; const BelWirePOD *bel_wires = chip_info->bel_data[bel.index].bel_wires.get(); - for (int i = 0; i < num_bel_wires; i++) { - if (bel_wires[i].port == pin) { - ret.index = bel_wires[i].wire_index; - break; + if (num_bel_wires < 7) { + for (int i = 0; i < num_bel_wires; i++) { + if (bel_wires[i].port == pin) { + ret.index = bel_wires[i].wire_index; + break; + } + } + } else { + int b = 0, e = num_bel_wires-1; + while (b <= e) { + int i = (b+e) / 2; + if (bel_wires[i].port == pin) { + ret.index = bel_wires[i].wire_index; + break; + } + if (bel_wires[i].port > pin) + e = i-1; + else + b = i+1; } } @@ -608,6 +642,20 @@ delay_t Arch::predictDelay(const NetInfo *net_info, const PortRef &sink) const return xscale * abs(xd) + yscale * abs(yd) + offset; } +delay_t Arch::getBudgetOverride(NetInfo *net_info, int user_idx, delay_t budget) const +{ + const auto &driver = net_info->driver; + if (driver.port == id_cout) { + const auto &sink = net_info->users[user_idx]; + auto driver_loc = getBelLocation(driver.cell->bel); + auto sink_loc = getBelLocation(sink.cell->bel); + if (driver_loc.y == sink_loc.y) + return 0; + return 250; + } + return budget; +} + // ----------------------------------------------------------------------- bool Arch::place() { return placer1(getCtx()); } @@ -791,29 +839,29 @@ std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const // ----------------------------------------------------------------------- -bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, delay_t &delay) const +bool Arch::getCellDelay(const CellInfo *cell, IdString fromPort, IdString toPort, DelayInfo &delay) const { if (cell->type == id_icestorm_lc) { if ((fromPort == id_i0 || fromPort == id_i1 || fromPort == id_i2 || fromPort == id_i3) && (toPort == id_o || toPort == id_lo)) { - delay = 450; + delay.delay = 450; return true; } else if (fromPort == id_cin && toPort == id_cout) { - delay = 120; + delay.delay = 120; return true; } else if (fromPort == id_i1 && toPort == id_cout) { - delay = 260; + delay.delay = 260; return true; } else if (fromPort == id_i2 && toPort == id_cout) { - delay = 230; + delay.delay = 230; return true; } else if (fromPort == id_clk && toPort == id_o) { - delay = 540; + delay.delay = 540; return true; } } else if (cell->type == id_icestorm_ram) { if (fromPort == id_rclk) { - delay = 2140; + delay.delay = 2140; return true; } } |