Add iCE40 pseudo-pips for lut permutation

Signed-off-by: Clifford Wolf <clifford@clifford.at>
This commit is contained in:
Clifford Wolf 2018-08-03 17:37:59 +02:00
parent 80e6b17ec9
commit 2a1d54389f
6 changed files with 157 additions and 27 deletions

View File

@ -174,6 +174,7 @@ Arch::Arch(ArchArgs args) : args(args)
if (package_info == nullptr) if (package_info == nullptr)
log_error("Unsupported package '%s'.\n", args.package.c_str()); 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); bel_to_cell.resize(chip_info->num_bels);
wire_to_net.resize(chip_info->num_wires); wire_to_net.resize(chip_info->num_wires);
pip_to_net.resize(chip_info->num_pips); pip_to_net.resize(chip_info->num_pips);
@ -192,6 +193,7 @@ Arch::Arch(ArchArgs args) : args(args)
id_i2 = id("I2"); id_i2 = id("I2");
id_i3 = id("I3"); id_i3 = id("I3");
id_dff_en = id("DFF_ENABLE"); id_dff_en = id("DFF_ENABLE");
id_carry_en = id("CARRY_ENABLE");
id_neg_clk = id("NEG_CLK"); id_neg_clk = id("NEG_CLK");
id_cin = id("CIN"); id_cin = id("CIN");
id_cout = id("COUT"); id_cout = id("COUT");
@ -541,7 +543,6 @@ std::vector<GroupId> Arch::getGroups() const
group.type = GroupId::TYPE_LOCAL_SW; group.type = GroupId::TYPE_LOCAL_SW;
ret.push_back(group); ret.push_back(group);
#if 0
if (type == TILE_LOGIC) if (type == TILE_LOGIC)
{ {
group.type = GroupId::TYPE_LC0_SW; group.type = GroupId::TYPE_LC0_SW;
@ -568,7 +569,6 @@ std::vector<GroupId> Arch::getGroups() const
group.type = GroupId::TYPE_LC7_SW; group.type = GroupId::TYPE_LC7_SW;
ret.push_back(group); ret.push_back(group);
} }
#endif
} }
} }
return ret; return ret;
@ -763,6 +763,18 @@ std::vector<GraphicElement> Arch::getDecalGraphics(DecalId decal) const
el.y2 = y + local_swbox_y2; el.y2 = y + local_swbox_y2;
ret.push_back(el); 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) { if (decal.type == DecalId::TYPE_WIRE) {
@ -913,6 +925,7 @@ void Arch::assignCellInfo(CellInfo *cell)
cell->belType = belTypeFromId(cell->type); cell->belType = belTypeFromId(cell->type);
if (cell->type == id_icestorm_lc) { if (cell->type == id_icestorm_lc) {
cell->lcInfo.dffEnable = bool_or_default(cell->params, id_dff_en); 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.negClk = bool_or_default(cell->params, id_neg_clk);
cell->lcInfo.clk = get_net_or_empty(cell, id_clk); cell->lcInfo.clk = get_net_or_empty(cell, id_clk);
cell->lcInfo.cen = get_net_or_empty(cell, id_cen); cell->lcInfo.cen = get_net_or_empty(cell, id_cen);

View File

@ -64,6 +64,13 @@ NPNR_PACKED_STRUCT(struct BelPortPOD {
}); });
NPNR_PACKED_STRUCT(struct PipInfoPOD { NPNR_PACKED_STRUCT(struct PipInfoPOD {
enum PipFlags : uint32_t
{
FLAG_NONE = 0,
FLAG_ROUTETHRU = 1,
FLAG_NOCARRY = 2
};
// RelPtr<char> name; // RelPtr<char> name;
int32_t src, dst; int32_t src, dst;
int32_t fast_delay; int32_t fast_delay;
@ -72,6 +79,7 @@ NPNR_PACKED_STRUCT(struct PipInfoPOD {
int16_t src_seg, dst_seg; int16_t src_seg, dst_seg;
int16_t switch_mask; int16_t switch_mask;
int32_t switch_index; int32_t switch_index;
PipFlags flags;
}); });
NPNR_PACKED_STRUCT(struct WireSegmentPOD { NPNR_PACKED_STRUCT(struct WireSegmentPOD {
@ -373,6 +381,7 @@ struct Arch : BaseCtx
mutable std::unordered_map<IdString, int> pip_by_name; mutable std::unordered_map<IdString, int> pip_by_name;
mutable std::unordered_map<Loc, int> bel_by_loc; mutable std::unordered_map<Loc, int> bel_by_loc;
std::vector<bool> bel_carry;
std::vector<IdString> bel_to_cell; std::vector<IdString> bel_to_cell;
std::vector<IdString> wire_to_net; std::vector<IdString> wire_to_net;
std::vector<IdString> pip_to_net; std::vector<IdString> pip_to_net;
@ -414,9 +423,12 @@ struct Arch : BaseCtx
{ {
NPNR_ASSERT(bel != BelId()); NPNR_ASSERT(bel != BelId());
NPNR_ASSERT(bel_to_cell[bel.index] == IdString()); NPNR_ASSERT(bel_to_cell[bel.index] == IdString());
auto &c = cells[cell];
bel_to_cell[bel.index] = cell; bel_to_cell[bel.index] = cell;
cells[cell]->bel = bel; bel_carry[bel.index] = (c->type == id_icestorm_lc && c->lcInfo.carryEnable);
cells[cell]->belStrength = strength; c->bel = bel;
c->belStrength = strength;
refreshUiBel(bel); refreshUiBel(bel);
} }
@ -427,6 +439,7 @@ struct Arch : BaseCtx
cells[bel_to_cell[bel.index]]->bel = BelId(); cells[bel_to_cell[bel.index]]->bel = BelId();
cells[bel_to_cell[bel.index]]->belStrength = STRENGTH_NONE; cells[bel_to_cell[bel.index]]->belStrength = STRENGTH_NONE;
bel_to_cell[bel.index] = IdString(); bel_to_cell[bel.index] = IdString();
bel_carry[bel.index] = false;
refreshUiBel(bel); refreshUiBel(bel);
} }
@ -614,14 +627,23 @@ struct Arch : BaseCtx
bool checkPipAvail(PipId pip) const bool checkPipAvail(PipId pip) const
{ {
NPNR_ASSERT(pip != PipId()); NPNR_ASSERT(pip != PipId());
int switch_idx = chip_info->pip_data[pip.index].switch_index; auto &pi = chip_info->pip_data[pip.index];
auto &si = chip_info->bits_info->switches[pi.switch_index];
if (switches_locked[switch_idx] != IdString()) if (switches_locked[pi.switch_index] != IdString())
return false; return false;
int bel_idx = chip_info->bits_info->switches[switch_idx].bel; if (pi.flags & PipInfoPOD::FLAG_ROUTETHRU) {
if (bel_idx >= 0 && bel_to_cell[bel_idx] != IdString()) NPNR_ASSERT(si.bel >= 0);
return false; if (bel_to_cell[si.bel] != IdString())
return false;
}
if (pi.flags & PipInfoPOD::FLAG_NOCARRY) {
NPNR_ASSERT(si.bel >= 0);
if (bel_carry[si.bel])
return false;
}
return true; return true;
} }
@ -781,7 +803,7 @@ struct Arch : BaseCtx
IdString id_icestorm_lc, id_sb_io, id_sb_gb; IdString id_icestorm_lc, id_sb_io, id_sb_gb;
IdString id_cen, id_clk, id_sr; IdString id_cen, id_clk, id_sr;
IdString id_i0, id_i1, id_i2, id_i3; IdString id_i0, id_i1, id_i2, id_i3;
IdString id_dff_en, id_neg_clk; IdString id_dff_en, id_carry_en, id_neg_clk;
IdString id_cin, id_cout; IdString id_cin, id_cout;
IdString id_o, id_lo; IdString id_o, id_lo;
IdString id_icestorm_ram, id_rclk, id_wclk; IdString id_icestorm_ram, id_rclk, id_wclk;

View File

@ -167,7 +167,9 @@ struct ArchCellInfo
{ {
struct struct
{ {
bool dffEnable, negClk; bool dffEnable;
bool carryEnable;
bool negClk;
int inputCount; int inputCount;
const NetInfo *clk, *cen, *sr; const NetInfo *clk, *cen, *sr;
} lcInfo; } lcInfo;

View File

@ -190,6 +190,8 @@ def wire_type(name):
wt = "LOCAL" wt = "LOCAL"
elif name in ("in_0", "in_1", "in_2", "in_3", "cout", "lout", "out", "fabout") or name.startswith("slf_op") or name.startswith("O_"): elif name in ("in_0", "in_1", "in_2", "in_3", "cout", "lout", "out", "fabout") or name.startswith("slf_op") or name.startswith("O_"):
wt = "LOCAL" wt = "LOCAL"
elif name in ("in_0_lut", "in_1_lut", "in_2_lut", "in_3_lut"):
wt = "LOCAL"
elif name.startswith("local_g") or name.startswith("glb2local_"): elif name.startswith("local_g") or name.startswith("glb2local_"):
wt = "LOCAL" wt = "LOCAL"
elif name.startswith("span4_horz_") or name.startswith("sp4_h_"): elif name.startswith("span4_horz_") or name.startswith("sp4_h_"):
@ -265,9 +267,12 @@ def pipdelay(src_idx, dst_idx, db):
if src[2].startswith("local_") and dst[2] in ("io_0/D_OUT_0", "io_0/D_OUT_1", "io_0/OUT_ENB", "io_1/D_OUT_0", "io_1/D_OUT_1", "io_1/OUT_ENB"): if src[2].startswith("local_") and dst[2] in ("io_0/D_OUT_0", "io_0/D_OUT_1", "io_0/OUT_ENB", "io_1/D_OUT_0", "io_1/D_OUT_1", "io_1/OUT_ENB"):
return db["IoInMux.I.O"] return db["IoInMux.I.O"]
if re.match(r"lutff_\d+/in_\d+", dst[2]): if re.match(r"lutff_\d+/in_\d+$", dst[2]):
return db["InMux.I.O"] return db["InMux.I.O"]
if re.match(r"lutff_\d+/in_\d+_lut", dst[2]):
return 0
if re.match(r"ram/(MASK|RADDR|WADDR|WDATA)_", dst[2]): if re.match(r"ram/(MASK|RADDR|WADDR|WDATA)_", dst[2]):
return db["InMux.I.O"] return db["InMux.I.O"]
@ -472,7 +477,7 @@ with open(args.filename, "r") as f:
wire_uphill[wire_b] = set() wire_uphill[wire_b] = set()
wire_downhill[wire_a].add(wire_b) wire_downhill[wire_a].add(wire_b)
wire_uphill[wire_b].add(wire_a) wire_uphill[wire_b].add(wire_a)
pip_xy[(wire_a, wire_b)] = (mode[2], mode[3], int(line[0], 2), len(switches) - 1) pip_xy[(wire_a, wire_b)] = (mode[2], mode[3], int(line[0], 2), len(switches) - 1, 0)
continue continue
if mode[0] == "bits": if mode[0] == "bits":
@ -508,11 +513,14 @@ def add_wire(x, y, name):
wire_names[wname] = wire_idx wire_names[wname] = wire_idx
wire_names_r[wire_idx] = wname wire_names_r[wire_idx] = wname
wire_segments[wire_idx] = dict() wire_segments[wire_idx] = dict()
if ("TILE_WIRE_" + wname[2].upper().replace("/", "_")) in gfx_wire_ids:
wire_segments[wire_idx][(wname[0], wname[1])] = wname[2]
return wire_idx
def add_switch(x, y, bel=-1): def add_switch(x, y, bel=-1):
switches.append((x, y, [], bel)) switches.append((x, y, [], bel))
def add_pip(src, dst): def add_pip(src, dst, flags=0):
x, y, _, _ = switches[-1] x, y, _, _ = switches[-1]
if src not in wire_downhill: if src not in wire_downhill:
@ -523,7 +531,7 @@ def add_pip(src, dst):
wire_uphill[dst] = set() wire_uphill[dst] = set()
wire_uphill[dst].add(src) wire_uphill[dst].add(src)
pip_xy[(src, dst)] = (x, y, 0, len(switches) - 1) pip_xy[(src, dst)] = (x, y, 0, len(switches) - 1, flags)
# Add virtual padin wires # Add virtual padin wires
for i in range(8): for i in range(8):
@ -557,10 +565,11 @@ def add_bel_lc(x, y, z):
else: else:
wire_cin = wire_names[(x, y, "lutff_%d/cout" % (z-1))] wire_cin = wire_names[(x, y, "lutff_%d/cout" % (z-1))]
wire_in_0 = wire_names[(x, y, "lutff_%d/in_0" % z)] wire_in_0 = add_wire(x, y, "lutff_%d/in_0_lut" % z)
wire_in_1 = wire_names[(x, y, "lutff_%d/in_1" % z)] wire_in_1 = add_wire(x, y, "lutff_%d/in_1_lut" % z)
wire_in_2 = wire_names[(x, y, "lutff_%d/in_2" % z)] wire_in_2 = add_wire(x, y, "lutff_%d/in_2_lut" % z)
wire_in_3 = wire_names[(x, y, "lutff_%d/in_3" % z)] wire_in_3 = add_wire(x, y, "lutff_%d/in_3_lut" % z)
wire_out = wire_names[(x, y, "lutff_%d/out" % z)] wire_out = wire_names[(x, y, "lutff_%d/out" % z)]
wire_cout = wire_names[(x, y, "lutff_%d/cout" % z)] wire_cout = wire_names[(x, y, "lutff_%d/cout" % z)]
wire_lout = wire_names[(x, y, "lutff_%d/lout" % z)] if z < 7 else None wire_lout = wire_names[(x, y, "lutff_%d/lout" % z)] if z < 7 else None
@ -583,10 +592,21 @@ def add_bel_lc(x, y, z):
# route-through LUTs # route-through LUTs
add_switch(x, y, bel) add_switch(x, y, bel)
add_pip(wire_in_0, wire_out) add_pip(wire_in_0, wire_out, 1)
add_pip(wire_in_1, wire_out) add_pip(wire_in_1, wire_out, 1)
add_pip(wire_in_2, wire_out) add_pip(wire_in_2, wire_out, 1)
add_pip(wire_in_3, wire_out) add_pip(wire_in_3, wire_out, 1)
# LUT permutation pips
for i in range(4):
add_switch(x, y, bel)
for j in range(4):
if (i == j) or ((i, j) == (1, 2)) or ((i, j) == (2, 1)):
flags = 0
else:
flags = 2
add_pip(wire_names[(x, y, "lutff_%d/in_%d" % (z, i))],
wire_names[(x, y, "lutff_%d/in_%d_lut" % (z, j))], flags)
def add_bel_io(x, y, z): def add_bel_io(x, y, z):
bel = len(bel_name) bel = len(bel_name)
@ -898,6 +918,7 @@ for wire in range(num_wires):
pi["y"] = pip_xy[(src, wire)][1] pi["y"] = pip_xy[(src, wire)][1]
pi["switch_mask"] = pip_xy[(src, wire)][2] pi["switch_mask"] = pip_xy[(src, wire)][2]
pi["switch_index"] = pip_xy[(src, wire)][3] pi["switch_index"] = pip_xy[(src, wire)][3]
pi["flags"] = pip_xy[(src, wire)][4]
pipinfo.append(pi) pipinfo.append(pi)
pips.append(pipcache[(src, wire)]) pips.append(pipcache[(src, wire)])
num_uphill = len(pips) num_uphill = len(pips)
@ -923,6 +944,7 @@ for wire in range(num_wires):
pi["y"] = pip_xy[(wire, dst)][1] pi["y"] = pip_xy[(wire, dst)][1]
pi["switch_mask"] = pip_xy[(wire, dst)][2] pi["switch_mask"] = pip_xy[(wire, dst)][2]
pi["switch_index"] = pip_xy[(wire, dst)][3] pi["switch_index"] = pip_xy[(wire, dst)][3]
pi["flags"] = pip_xy[(wire, dst)][4]
pipinfo.append(pi) pipinfo.append(pi)
pips.append(pipcache[(wire, dst)]) pips.append(pipcache[(wire, dst)])
num_downhill = len(pips) num_downhill = len(pips)
@ -1080,6 +1102,7 @@ for info in pipinfo:
bba.u16(dst_seg, "dst_seg") bba.u16(dst_seg, "dst_seg")
bba.u16(info["switch_mask"], "switch_mask") bba.u16(info["switch_mask"], "switch_mask")
bba.u32(info["switch_index"], "switch_index") bba.u32(info["switch_index"], "switch_index")
bba.u32(info["flags"], "flags")
switchinfo = [] switchinfo = []
for switch in switches: for switch in switches:

View File

@ -391,6 +391,17 @@ void gfxTileWire(std::vector<GraphicElement> &g, int x, int y, GfxTileWireId id,
int z = idx / 4; int z = idx / 4;
int input = idx % 4; int input = idx % 4;
el.x1 = x + local_swbox_x2; el.x1 = x + local_swbox_x2;
el.x2 = x + lut_swbox_x1;
el.y1 = y + (logic_cell_y1 + logic_cell_y2) / 2 - 0.0075 + (0.005 * input) + z * logic_cell_pitch;
el.y2 = el.y1;
g.push_back(el);
}
if (id >= TILE_WIRE_LUTFF_0_IN_0_LUT && id <= TILE_WIRE_LUTFF_7_IN_3_LUT) {
int idx = id - TILE_WIRE_LUTFF_0_IN_0_LUT;
int z = idx / 4;
int input = idx % 4;
el.x1 = x + lut_swbox_x2;
el.x2 = x + logic_cell_x1; el.x2 = x + logic_cell_x1;
el.y1 = y + (logic_cell_y1 + logic_cell_y2) / 2 - 0.0075 + (0.005 * input) + z * logic_cell_pitch; el.y1 = y + (logic_cell_y1 + logic_cell_y2) / 2 - 0.0075 + (0.005 * input) + z * logic_cell_pitch;
el.y2 = el.y1; el.y2 = el.y1;
@ -706,9 +717,9 @@ void gfxTilePip(std::vector<GraphicElement> &g, int x, int y, GfxTileWireId src,
return; return;
} }
if (TILE_WIRE_LUTFF_0_IN_0 <= src && src <= TILE_WIRE_LUTFF_7_IN_3 && TILE_WIRE_LUTFF_0_OUT <= dst && dst <= TILE_WIRE_LUTFF_7_OUT) { if (TILE_WIRE_LUTFF_0_IN_0_LUT <= src && src <= TILE_WIRE_LUTFF_7_IN_3_LUT && TILE_WIRE_LUTFF_0_OUT <= dst && dst <= TILE_WIRE_LUTFF_7_OUT) {
int lut_idx = (src - TILE_WIRE_LUTFF_0_IN_0) / 4; int lut_idx = (src - TILE_WIRE_LUTFF_0_IN_0_LUT) / 4;
int in_idx = (src - TILE_WIRE_LUTFF_0_IN_0) % 4; int in_idx = (src - TILE_WIRE_LUTFF_0_IN_0_LUT) % 4;
GraphicElement el; GraphicElement el;
el.type = GraphicElement::TYPE_ARROW; el.type = GraphicElement::TYPE_ARROW;
@ -721,6 +732,22 @@ void gfxTilePip(std::vector<GraphicElement> &g, int x, int y, GfxTileWireId src,
return; return;
} }
if (TILE_WIRE_LUTFF_0_IN_0 <= src && src <= TILE_WIRE_LUTFF_7_IN_3 && TILE_WIRE_LUTFF_0_IN_0_LUT <= dst && dst <= TILE_WIRE_LUTFF_7_IN_3_LUT) {
int lut_idx = (src - TILE_WIRE_LUTFF_0_IN_0) / 4;
int in_idx = (src - TILE_WIRE_LUTFF_0_IN_0) % 4;
int out_idx = (dst - TILE_WIRE_LUTFF_0_IN_0_LUT) % 4;
GraphicElement el;
el.type = GraphicElement::TYPE_ARROW;
el.style = style;
el.x1 = x + lut_swbox_x1;
el.x2 = x + lut_swbox_x2;
el.y1 = y + (logic_cell_y1 + logic_cell_y2) / 2 - 0.0075 + (0.005 * in_idx) + lut_idx * logic_cell_pitch;
el.y2 = y + (logic_cell_y1 + logic_cell_y2) / 2 - 0.0075 + (0.005 * out_idx) + lut_idx * logic_cell_pitch;
g.push_back(el);
return;
}
if (src == TILE_WIRE_CARRY_IN && dst == TILE_WIRE_CARRY_IN_MUX) { if (src == TILE_WIRE_CARRY_IN && dst == TILE_WIRE_CARRY_IN_MUX) {
GraphicElement el; GraphicElement el;
el.type = GraphicElement::TYPE_ARROW; el.type = GraphicElement::TYPE_ARROW;

View File

@ -34,7 +34,10 @@ const float local_swbox_x2 = 0.73;
const float local_swbox_y1 = 0.05; const float local_swbox_y1 = 0.05;
const float local_swbox_y2 = 0.55; const float local_swbox_y2 = 0.55;
const float logic_cell_x1 = 0.76; const float lut_swbox_x1 = 0.76;
const float lut_swbox_x2 = 0.80;
const float logic_cell_x1 = 0.83;
const float logic_cell_x2 = 0.95; const float logic_cell_x2 = 0.95;
const float logic_cell_y1 = 0.05; const float logic_cell_y1 = 0.05;
const float logic_cell_y2 = 0.10; const float logic_cell_y2 = 0.10;
@ -135,6 +138,46 @@ enum GfxTileWireId
TILE_WIRE_LUTFF_7_IN_2, TILE_WIRE_LUTFF_7_IN_2,
TILE_WIRE_LUTFF_7_IN_3, TILE_WIRE_LUTFF_7_IN_3,
TILE_WIRE_LUTFF_0_IN_0_LUT,
TILE_WIRE_LUTFF_0_IN_1_LUT,
TILE_WIRE_LUTFF_0_IN_2_LUT,
TILE_WIRE_LUTFF_0_IN_3_LUT,
TILE_WIRE_LUTFF_1_IN_0_LUT,
TILE_WIRE_LUTFF_1_IN_1_LUT,
TILE_WIRE_LUTFF_1_IN_2_LUT,
TILE_WIRE_LUTFF_1_IN_3_LUT,
TILE_WIRE_LUTFF_2_IN_0_LUT,
TILE_WIRE_LUTFF_2_IN_1_LUT,
TILE_WIRE_LUTFF_2_IN_2_LUT,
TILE_WIRE_LUTFF_2_IN_3_LUT,
TILE_WIRE_LUTFF_3_IN_0_LUT,
TILE_WIRE_LUTFF_3_IN_1_LUT,
TILE_WIRE_LUTFF_3_IN_2_LUT,
TILE_WIRE_LUTFF_3_IN_3_LUT,
TILE_WIRE_LUTFF_4_IN_0_LUT,
TILE_WIRE_LUTFF_4_IN_1_LUT,
TILE_WIRE_LUTFF_4_IN_2_LUT,
TILE_WIRE_LUTFF_4_IN_3_LUT,
TILE_WIRE_LUTFF_5_IN_0_LUT,
TILE_WIRE_LUTFF_5_IN_1_LUT,
TILE_WIRE_LUTFF_5_IN_2_LUT,
TILE_WIRE_LUTFF_5_IN_3_LUT,
TILE_WIRE_LUTFF_6_IN_0_LUT,
TILE_WIRE_LUTFF_6_IN_1_LUT,
TILE_WIRE_LUTFF_6_IN_2_LUT,
TILE_WIRE_LUTFF_6_IN_3_LUT,
TILE_WIRE_LUTFF_7_IN_0_LUT,
TILE_WIRE_LUTFF_7_IN_1_LUT,
TILE_WIRE_LUTFF_7_IN_2_LUT,
TILE_WIRE_LUTFF_7_IN_3_LUT,
TILE_WIRE_LUTFF_0_LOUT, TILE_WIRE_LUTFF_0_LOUT,
TILE_WIRE_LUTFF_1_LOUT, TILE_WIRE_LUTFF_1_LOUT,
TILE_WIRE_LUTFF_2_LOUT, TILE_WIRE_LUTFF_2_LOUT,