aboutsummaryrefslogtreecommitdiffstats
path: root/ice40/arch.cc
diff options
context:
space:
mode:
authorDavid Shah <davey1576@gmail.com>2018-08-05 14:31:43 +0200
committerGitHub <noreply@github.com>2018-08-05 14:31:43 +0200
commitba97c233fb6e4502f3465a602f997cc2382f0e06 (patch)
tree3a62397aebff56e2031f3d5c6c930ead2699d641 /ice40/arch.cc
parent8a9b3626d32e8845dc51044e0f281c0ccdb7e53a (diff)
parent287fe7e89451b952d15c7839aff9cb3db12bf807 (diff)
downloadnextpnr-ba97c233fb6e4502f3465a602f997cc2382f0e06.tar.gz
nextpnr-ba97c233fb6e4502f3465a602f997cc2382f0e06.tar.bz2
nextpnr-ba97c233fb6e4502f3465a602f997cc2382f0e06.zip
Merge pull request #36 from YosysHQ/lutperm
Add LUT input permutations, improvements in ice40 timing model, improvements in router
Diffstat (limited to 'ice40/arch.cc')
-rw-r--r--ice40/arch.cc102
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);