diff options
Diffstat (limited to 'ice40/arch.cc')
-rw-r--r-- | ice40/arch.cc | 102 |
1 files changed, 54 insertions, 48 deletions
diff --git a/ice40/arch.cc b/ice40/arch.cc index 3934e8f0..5d79a487 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -174,6 +174,7 @@ Arch::Arch(ArchArgs args) : args(args) if (package_info == nullptr) log_error("Unsupported package '%s'.\n", args.package.c_str()); + bel_carry.resize(chip_info->num_bels); bel_to_cell.resize(chip_info->num_bels); wire_to_net.resize(chip_info->num_wires); pip_to_net.resize(chip_info->num_pips); @@ -192,6 +193,7 @@ Arch::Arch(ArchArgs args) : args(args) id_i2 = id("I2"); id_i3 = id("I3"); id_dff_en = id("DFF_ENABLE"); + id_carry_en = id("CARRY_ENABLE"); id_neg_clk = id("NEG_CLK"); id_cin = id("CIN"); id_cout = id("COUT"); @@ -399,6 +401,44 @@ WireId Arch::getWireByName(IdString name) const return ret; } +IdString Arch::getWireType(WireId wire) const +{ + NPNR_ASSERT(wire != WireId()); + switch (chip_info->wire_data[wire.index].type) { + case WireInfoPOD::WIRE_TYPE_NONE: + return IdString(); + case WireInfoPOD::WIRE_TYPE_GLB2LOCAL: + return id("GLB2LOCAL"); + case WireInfoPOD::WIRE_TYPE_GLB_NETWK: + return id("GLB_NETWK"); + case WireInfoPOD::WIRE_TYPE_LOCAL: + return id("LOCAL"); + case WireInfoPOD::WIRE_TYPE_LUTFF_IN: + return id("LUTFF_IN"); + case WireInfoPOD::WIRE_TYPE_LUTFF_IN_LUT: + return id("LUTFF_IN_LUT"); + case WireInfoPOD::WIRE_TYPE_LUTFF_LOUT: + return id("LUTFF_LOUT"); + case WireInfoPOD::WIRE_TYPE_LUTFF_OUT: + return id("LUTFF_OUT"); + case WireInfoPOD::WIRE_TYPE_LUTFF_COUT: + return id("LUTFF_COUT"); + case WireInfoPOD::WIRE_TYPE_LUTFF_GLOBAL: + return id("LUTFF_GLOBAL"); + case WireInfoPOD::WIRE_TYPE_CARRY_IN_MUX: + return id("CARRY_IN_MUX"); + case WireInfoPOD::WIRE_TYPE_SP4_V: + return id("SP4_V"); + case WireInfoPOD::WIRE_TYPE_SP4_H: + return id("SP4_H"); + case WireInfoPOD::WIRE_TYPE_SP12_V: + return id("SP12_V"); + case WireInfoPOD::WIRE_TYPE_SP12_H: + return id("SP12_H"); + } + return IdString(); +} + // ----------------------------------------------------------------------- PipId Arch::getPipByName(IdString name) const @@ -541,9 +581,7 @@ std::vector<GroupId> Arch::getGroups() const group.type = GroupId::TYPE_LOCAL_SW; ret.push_back(group); -#if 0 - if (type == TILE_LOGIC) - { + if (type == TILE_LOGIC) { group.type = GroupId::TYPE_LC0_SW; ret.push_back(group); @@ -568,7 +606,6 @@ std::vector<GroupId> Arch::getGroups() const group.type = GroupId::TYPE_LC7_SW; ret.push_back(group); } -#endif } } return ret; @@ -600,50 +637,6 @@ std::vector<GroupId> Arch::getGroupGroups(GroupId group) const // ----------------------------------------------------------------------- -delay_t Arch::estimateDelay(WireId src, WireId dst) const -{ - NPNR_ASSERT(src != WireId()); - int x1 = chip_info->wire_data[src.index].x; - int y1 = chip_info->wire_data[src.index].y; - - NPNR_ASSERT(dst != WireId()); - int x2 = chip_info->wire_data[dst.index].x; - int y2 = chip_info->wire_data[dst.index].y; - - int xd = x2 - x1, yd = y2 - y1; - int xscale = 120, yscale = 120, offset = 0; - - return xscale * abs(xd) + yscale * abs(yd) + offset; -} - -delay_t Arch::predictDelay(const NetInfo *net_info, const PortRef &sink) const -{ - const auto &driver = net_info->driver; - auto driver_loc = getBelLocation(driver.cell->bel); - auto sink_loc = getBelLocation(sink.cell->bel); - - if (driver.port == id_cout) { - if (driver_loc.y == sink_loc.y) - return 0; - return 250; - } - - int xd = sink_loc.x - driver_loc.x, yd = sink_loc.y - driver_loc.y; - int xscale = 120, yscale = 120, offset = 0; - - // if (chip_info->wire_data[src.index].type == WIRE_TYPE_SP4_VERT) { - // yd = yd < -4 ? yd + 4 : (yd < 0 ? 0 : yd); - // offset = 500; - // } - - if (driver.port == id_o) - offset += 330; - if (sink.port == id_i0 || sink.port == id_i1 || sink.port == id_i2 || sink.port == id_i3) - offset += 260; - - return xscale * abs(xd) + yscale * abs(yd) + offset; -} - delay_t Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay_t budget) const { const auto &driver = net_info->driver; @@ -768,6 +761,18 @@ std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const el.y2 = y + local_swbox_y2; ret.push_back(el); } + + if (GroupId::TYPE_LC0_SW <= type && type <= GroupId::TYPE_LC7_SW) { + GraphicElement el; + el.type = GraphicElement::TYPE_BOX; + el.style = GraphicElement::STYLE_FRAME; + + el.x1 = x + lut_swbox_x1; + el.x2 = x + lut_swbox_x2; + el.y1 = y + logic_cell_y1 + logic_cell_pitch * (type - GroupId::TYPE_LC0_SW); + el.y2 = y + logic_cell_y2 + logic_cell_pitch * (type - GroupId::TYPE_LC0_SW); + ret.push_back(el); + } } if (decal.type == DecalId::TYPE_WIRE) { @@ -918,6 +923,7 @@ void Arch::assignCellInfo(CellInfo *cell) cell->belType = belTypeFromId(cell->type); if (cell->type == id_icestorm_lc) { cell->lcInfo.dffEnable = bool_or_default(cell->params, id_dff_en); + cell->lcInfo.carryEnable = bool_or_default(cell->params, id_carry_en); cell->lcInfo.negClk = bool_or_default(cell->params, id_neg_clk); cell->lcInfo.clk = get_net_or_empty(cell, id_clk); cell->lcInfo.cen = get_net_or_empty(cell, id_cen); |