diff options
Diffstat (limited to 'ice40/arch.cc')
-rw-r--r-- | ice40/arch.cc | 305 |
1 files changed, 78 insertions, 227 deletions
diff --git a/ice40/arch.cc b/ice40/arch.cc index 4727597b..adc37dbd 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -2,7 +2,6 @@ * nextpnr -- Next Generation Place and Route * * Copyright (C) 2018 Clifford Wolf <clifford@symbioticeda.com> - * Copyright (C) 2018 Serge Bazanski <q3k@symbioticeda.com> * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -29,6 +28,8 @@ NEXTPNR_NAMESPACE_BEGIN +// ----------------------------------------------------------------------- + IdString Arch::belTypeToId(BelType type) const { if (type == TYPE_ICESTORM_LC) @@ -238,6 +239,22 @@ IdString Arch::archArgsToId(ArchArgs args) const // ----------------------------------------------------------------------- +BelId Arch::getBelByName(IdString name) const +{ + BelId ret; + + if (bel_by_name.empty()) { + for (int i = 0; i < chip_info->num_bels; i++) + bel_by_name[id(chip_info->bel_data[i].name.get())] = i; + } + + auto it = bel_by_name.find(name); + if (it != bel_by_name.end()) + ret.index = it->second; + + return ret; +} + BelRange Arch::getBelsAtSameTile(BelId bel) const { BelRange br; @@ -256,8 +273,63 @@ BelRange Arch::getBelsAtSameTile(BelId bel) const return br; } +WireId Arch::getWireBelPin(BelId bel, PortPin pin) const +{ + WireId ret; + + NPNR_ASSERT(bel != BelId()); + + 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; + } + + return ret; +} + // ----------------------------------------------------------------------- +WireId Arch::getWireByName(IdString name) const +{ + WireId ret; + + if (wire_by_name.empty()) { + for (int i = 0; i < chip_info->num_wires; i++) + wire_by_name[id(chip_info->wire_data[i].name.get())] = i; + } + + auto it = wire_by_name.find(name); + if (it != wire_by_name.end()) + ret.index = it->second; + + return ret; +} + +// ----------------------------------------------------------------------- + +PipId Arch::getPipByName(IdString name) const +{ + PipId ret; + + if (pip_by_name.empty()) { + for (int i = 0; i < chip_info->num_pips; i++) { + PipId pip; + pip.index = i; + pip_by_name[getPipName(pip)] = i; + } + } + + auto it = pip_by_name.find(name); + if (it != pip_by_name.end()) + ret.index = it->second; + + return ret; +} + IdString Arch::getPipName(PipId pip) const { NPNR_ASSERT(pip != PipId()); @@ -300,8 +372,6 @@ std::string Arch::getBelPackagePin(BelId bel) const // ----------------------------------------------------------------------- -// TODO(cliffordvienna): lock all of this - GroupId Arch::getGroupByName(IdString name) const { for (auto g : getGroups()) @@ -425,7 +495,7 @@ DecalXY Arch::getGroupDecal(GroupId group) const return decalxy; }; -std::vector<GraphicElement> ArchReadMethods::getDecalGraphics(DecalId decal) const +std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const { std::vector<GraphicElement> ret; @@ -458,7 +528,7 @@ std::vector<GraphicElement> ArchReadMethods::getDecalGraphics(DecalId decal) con BelId bel; bel.index = decal.index; - auto bel_type = parent_->getBelType(bel); + auto bel_type = getBelType(bel); if (bel_type == TYPE_ICESTORM_LC) { GraphicElement el; @@ -533,7 +603,8 @@ std::vector<GraphicElement> ArchReadMethods::getDecalGraphics(DecalId decal) con } if (bel_type == TYPE_ICESTORM_RAM) { - for (int i = 0; i < 2; i++) { + for (int i = 0; i < 2; i++) + { int tx = chip_info->bel_data[bel.index].x; int ty = chip_info->bel_data[bel.index].y + i; @@ -543,7 +614,7 @@ std::vector<GraphicElement> ArchReadMethods::getDecalGraphics(DecalId decal) con el.x1 = chip_info->bel_data[bel.index].x + logic_cell_x1; el.x2 = chip_info->bel_data[bel.index].x + logic_cell_x2; el.y1 = chip_info->bel_data[bel.index].y + logic_cell_y1; - el.y2 = chip_info->bel_data[bel.index].y + logic_cell_y2 + 7 * logic_cell_pitch; + el.y2 = chip_info->bel_data[bel.index].y + logic_cell_y2 + 7*logic_cell_pitch; el.z = 0; ret.push_back(el); @@ -620,224 +691,4 @@ bool Arch::isGlobalNet(const NetInfo *net) const return net->driver.cell != nullptr && net->driver.port == id_glb_buf_out; } -// ----------------------------------------------------------------------- - -bool ArchReadMethods::checkBelAvail(BelId bel) const -{ - NPNR_ASSERT(bel != BelId()); - return bel_to_cell[bel.index] == IdString(); -} - -IdString ArchReadMethods::getBoundBelCell(BelId bel) const -{ - NPNR_ASSERT(bel != BelId()); - return bel_to_cell[bel.index]; -} - -IdString ArchReadMethods::getConflictingBelCell(BelId bel) const -{ - NPNR_ASSERT(bel != BelId()); - return bel_to_cell[bel.index]; -} - -WireId ArchReadMethods::getWireBelPin(BelId bel, PortPin pin) const -{ - WireId ret; - - NPNR_ASSERT(bel != BelId()); - - 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; - } - - return ret; -} - -WireId ArchReadMethods::getWireByName(IdString name) const -{ - WireId ret; - - if (wire_by_name.empty()) { - for (int i = 0; i < chip_info->num_wires; i++) - wire_by_name[parent_->id(chip_info->wire_data[i].name.get())] = i; - } - - auto it = wire_by_name.find(name); - if (it != wire_by_name.end()) - ret.index = it->second; - - return ret; -} - -bool ArchReadMethods::checkWireAvail(WireId wire) const -{ - NPNR_ASSERT(wire != WireId()); - return wire_to_net[wire.index] == IdString(); -} - -IdString ArchReadMethods::getBoundWireNet(WireId wire) const -{ - NPNR_ASSERT(wire != WireId()); - return wire_to_net[wire.index]; -} - -IdString ArchReadMethods::getConflictingWireNet(WireId wire) const -{ - NPNR_ASSERT(wire != WireId()); - return wire_to_net[wire.index]; -} - -PipId ArchReadMethods::getPipByName(IdString name) const -{ - PipId ret; - - if (pip_by_name.empty()) { - for (int i = 0; i < chip_info->num_pips; i++) { - PipId pip; - pip.index = i; - pip_by_name[parent_->getPipName(pip)] = i; - } - } - - auto it = pip_by_name.find(name); - if (it != pip_by_name.end()) - ret.index = it->second; - - return ret; -} - -bool ArchReadMethods::checkPipAvail(PipId pip) const -{ - NPNR_ASSERT(pip != PipId()); - return switches_locked[chip_info->pip_data[pip.index].switch_index] == IdString(); -} - -IdString ArchReadMethods::getBoundPipNet(PipId pip) const -{ - NPNR_ASSERT(pip != PipId()); - return pip_to_net[pip.index]; -} - -IdString ArchReadMethods::getConflictingPipNet(PipId pip) const -{ - NPNR_ASSERT(pip != PipId()); - return switches_locked[chip_info->pip_data[pip.index].switch_index]; -} - -BelId ArchReadMethods::getBelByName(IdString name) const -{ - BelId ret; - - if (bel_by_name.empty()) { - for (int i = 0; i < chip_info->num_bels; i++) - bel_by_name[parent_->id(chip_info->bel_data[i].name.get())] = i; - } - - auto it = bel_by_name.find(name); - if (it != bel_by_name.end()) - ret.index = it->second; - - return ret; -} - -// ----------------------------------------------------------------------- - -void ArchMutateMethods::bindBel(BelId bel, IdString cell, PlaceStrength strength) -{ - NPNR_ASSERT(bel != BelId()); - NPNR_ASSERT(bel_to_cell[bel.index] == IdString()); - bel_to_cell[bel.index] = cell; - parent_->cells[cell]->bel = bel; - parent_->cells[cell]->belStrength = strength; - refreshUiBel(bel); -} - -void ArchMutateMethods::unbindBel(BelId bel) -{ - NPNR_ASSERT(bel != BelId()); - NPNR_ASSERT(bel_to_cell[bel.index] != IdString()); - parent_->cells[bel_to_cell[bel.index]]->bel = BelId(); - parent_->cells[bel_to_cell[bel.index]]->belStrength = STRENGTH_NONE; - bel_to_cell[bel.index] = IdString(); - refreshUiBel(bel); -} - -void ArchMutateMethods::bindWire(WireId wire, IdString net, PlaceStrength strength) -{ - NPNR_ASSERT(wire != WireId()); - NPNR_ASSERT(wire_to_net[wire.index] == IdString()); - - wire_to_net[wire.index] = net; - parent_->nets[net]->wires[wire].pip = PipId(); - parent_->nets[net]->wires[wire].strength = strength; - refreshUiWire(wire); -} - -void ArchMutateMethods::unbindWire(WireId wire) -{ - NPNR_ASSERT(wire != WireId()); - NPNR_ASSERT(wire_to_net[wire.index] != IdString()); - - auto &net_wires = parent_->nets[wire_to_net[wire.index]]->wires; - auto it = net_wires.find(wire); - NPNR_ASSERT(it != net_wires.end()); - - auto pip = it->second.pip; - if (pip != PipId()) { - pip_to_net[pip.index] = IdString(); - switches_locked[chip_info->pip_data[pip.index].switch_index] = IdString(); - refreshUiPip(pip); - } - - net_wires.erase(it); - wire_to_net[wire.index] = IdString(); - refreshUiWire(wire); -} - -void ArchMutateMethods::bindPip(PipId pip, IdString net, PlaceStrength strength) -{ - NPNR_ASSERT(pip != PipId()); - NPNR_ASSERT(pip_to_net[pip.index] == IdString()); - NPNR_ASSERT(switches_locked[chip_info->pip_data[pip.index].switch_index] == IdString()); - - pip_to_net[pip.index] = net; - switches_locked[chip_info->pip_data[pip.index].switch_index] = net; - - WireId dst; - dst.index = chip_info->pip_data[pip.index].dst; - NPNR_ASSERT(wire_to_net[dst.index] == IdString()); - wire_to_net[dst.index] = net; - parent_->nets[net]->wires[dst].pip = pip; - parent_->nets[net]->wires[dst].strength = strength; - - refreshUiPip(pip); - refreshUiWire(dst); -} - -void ArchMutateMethods::unbindPip(PipId pip) -{ - NPNR_ASSERT(pip != PipId()); - NPNR_ASSERT(pip_to_net[pip.index] != IdString()); - NPNR_ASSERT(switches_locked[chip_info->pip_data[pip.index].switch_index] != IdString()); - - WireId dst; - dst.index = chip_info->pip_data[pip.index].dst; - NPNR_ASSERT(wire_to_net[dst.index] != IdString()); - wire_to_net[dst.index] = IdString(); - parent_->nets[pip_to_net[pip.index]]->wires.erase(dst); - - pip_to_net[pip.index] = IdString(); - switches_locked[chip_info->pip_data[pip.index].switch_index] = IdString(); - - refreshUiPip(pip); - refreshUiWire(dst); -} - -CellInfo *ArchMutateMethods::getCell(IdString cell) { return parent_->cells.at(cell).get(); } - NEXTPNR_NAMESPACE_END |