Initial XLUT support
This commit is contained in:
parent
294e97babf
commit
37dadd121a
@ -42,6 +42,10 @@ enum ClusterPlacement
|
||||
PLACE_CY_FE2,
|
||||
PLACE_CY_FE3,
|
||||
PLACE_CY_FE4,
|
||||
PLACE_XLUT_FE1,
|
||||
PLACE_XLUT_FE2,
|
||||
PLACE_XLUT_FE3,
|
||||
PLACE_XLUT_FE4,
|
||||
PLACE_XRF_I1,
|
||||
PLACE_XRF_I2,
|
||||
PLACE_XRF_I3,
|
||||
|
@ -376,6 +376,10 @@ def create_tile_types(ch: Chip, bels, bel_pins, crossbars, interconnects, muxes,
|
||||
# LUT bypass
|
||||
by = tt.create_pip(f"{name}.I1",f"{name}.LO","BYPASS")
|
||||
by.extra_data = PipExtraData(ch.strs.id(name),PIP_EXTRA_BYPASS,1,0)
|
||||
elif (tile_type.startswith("TILE") and bel=="XLUT"):
|
||||
for out in ["G1","G2","G3","G4"]:
|
||||
vi = tt.create_pip(f"{name}.J",f"{name}.{out}","Virtual")
|
||||
vi.extra_data = PipExtraData(ch.strs.id(name),PIP_EXTRA_VIRTUAL,0,0)
|
||||
elif (tile_type.startswith("TILE") and bel=="CY"):
|
||||
# matrix of each input to each output combination
|
||||
# crossbar but use mux placeholder for convenience
|
||||
@ -384,16 +388,16 @@ def create_tile_types(ch: Chip, bels, bel_pins, crossbars, interconnects, muxes,
|
||||
pd = tt.create_pip(f"{name}."+inp,f"{name}."+out,"MATRIX_PIP")
|
||||
pd.extra_data = PipExtraData(ch.strs.id(f"{name}."+inp),PIP_EXTRA_MUX,int(inp[1:])-1,int(out[1:])-1)
|
||||
|
||||
#elif (tile_type.startswith("CKG") and bel=="WFG"):
|
||||
# by = tt.create_pip(f"{name}.ZI",f"{name}.ZO","BYPASS")
|
||||
# by.extra_data = PipExtraData(ch.strs.id(name),PIP_EXTRA_BYPASS,0,0)
|
||||
#elif (tile_type.startswith("TUBE") and bel=="GCK"):
|
||||
# # 20 clock signals comming to 20 GCK, SI1 is bypass
|
||||
# by = tt.create_pip(f"{name}.SI1",f"{name}.SO","BYPASS")
|
||||
# by.extra_data = PipExtraData(ch.strs.id(name),PIP_EXTRA_BYPASS,0,0)
|
||||
# # there are CMD signals that can be bypassed as well
|
||||
# by = tt.create_pip(f"{name}.CMD",f"{name}.SO","BYPASS")
|
||||
# by.extra_data = PipExtraData(ch.strs.id(name),PIP_EXTRA_BYPASS,1,0)
|
||||
elif (tile_type.startswith("CKG") and bel=="WFG"):
|
||||
by = tt.create_pip(f"{name}.ZI",f"{name}.ZO","BYPASS")
|
||||
by.extra_data = PipExtraData(ch.strs.id(name),PIP_EXTRA_BYPASS,0,0)
|
||||
elif (tile_type.startswith("TUBE") and bel=="GCK"):
|
||||
# 20 clock signals comming to 20 GCK, SI1 is bypass
|
||||
by = tt.create_pip(f"{name}.SI1",f"{name}.SO","BYPASS")
|
||||
by.extra_data = PipExtraData(ch.strs.id(name),PIP_EXTRA_BYPASS,0,0)
|
||||
# there are CMD signals that can be bypassed as well
|
||||
by = tt.create_pip(f"{name}.CMD",f"{name}.SO","BYPASS")
|
||||
by.extra_data = PipExtraData(ch.strs.id(name),PIP_EXTRA_BYPASS,1,0)
|
||||
|
||||
|
||||
# Add LUT permutation
|
||||
|
@ -512,6 +512,15 @@ Loc getCYFE(Loc root, int pos)
|
||||
return result;
|
||||
}
|
||||
|
||||
Loc getXLUTFE(Loc root, int pos)
|
||||
{
|
||||
Loc result;
|
||||
result.x = root.x;
|
||||
result.y = root.y;
|
||||
result.z = root.z - BEL_XLUT_Z + 8 * pos;
|
||||
return result;
|
||||
}
|
||||
|
||||
Loc getXRFFE(Loc root, int pos)
|
||||
{
|
||||
static const std::vector<Loc> map =
|
||||
@ -591,7 +600,6 @@ Loc getXRFFE(Loc root, int pos)
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Loc getCDCFE(Loc root, int pos)
|
||||
{
|
||||
static const std::vector<Loc> cdc1 =
|
||||
@ -963,10 +971,8 @@ bool NgUltraImpl::getChildPlacement(const BaseClusterInfo *cluster, Loc root_loc
|
||||
Loc child_loc = if_using_basecluster<Loc>(child, [&](const BaseClusterInfo *child) {
|
||||
switch(child->constr_z) {
|
||||
case PLACE_CY_CHAIN : { Loc l = getNextLocInCYChain(prev); prev = l; return l; }
|
||||
case PLACE_CY_FE1: return getCYFE(root_loc,0);
|
||||
case PLACE_CY_FE2: return getCYFE(root_loc,1);
|
||||
case PLACE_CY_FE3: return getCYFE(root_loc,2);
|
||||
case PLACE_CY_FE4: return getCYFE(root_loc,3);
|
||||
case PLACE_CY_FE1 ... PLACE_CY_FE4: return getCYFE(root_loc, child->constr_z - PLACE_CY_FE1 );
|
||||
case PLACE_XLUT_FE1 ... PLACE_XLUT_FE4: return getXLUTFE(root_loc, child->constr_z - PLACE_XLUT_FE1 );
|
||||
case PLACE_XRF_I1 ... PLACE_XRF_WEA:
|
||||
return getXRFFE(root_loc, child->constr_z - PLACE_XRF_I1 );
|
||||
case PLACE_CDC_AI1 ... PLACE_CDC_DDRSTI:
|
||||
|
@ -294,6 +294,63 @@ void NgUltraPacker::bind_attr_loc(CellInfo *cell, dict<IdString, Property> *attr
|
||||
}
|
||||
}
|
||||
|
||||
void NgUltraPacker::pack_xluts(void)
|
||||
{
|
||||
log_info("Pack XLUTs...\n");
|
||||
int lut_only = 0;//, lut_and_ff = 0;
|
||||
for (auto &cell : ctx->cells) {
|
||||
CellInfo &ci = *cell.second;
|
||||
if (!ci.type.in(id_NX_LUT))
|
||||
continue;
|
||||
if (!ci.params.count(id_lut_table))
|
||||
log_error("Cell '%s' missing lut_table\n", ci.name.c_str(ctx));
|
||||
|
||||
if (ci.cluster!=ClusterId())
|
||||
continue;
|
||||
CellInfo *lut[4];
|
||||
if (!ci.getPort(id_I1))
|
||||
continue;
|
||||
if (!ci.getPort(id_I2))
|
||||
continue;
|
||||
if (!ci.getPort(id_I3))
|
||||
continue;
|
||||
if (!ci.getPort(id_I4))
|
||||
continue;
|
||||
lut[0] = net_driven_by(ctx, ci.getPort(id_I1), is_lut, id_O);
|
||||
if (!lut[0] || ci.getPort(id_I1)->users.entries()!=1)
|
||||
continue;
|
||||
lut[1] = net_driven_by(ctx, ci.getPort(id_I2), is_lut, id_O);
|
||||
if (!lut[1] || ci.getPort(id_I2)->users.entries()!=1)
|
||||
continue;
|
||||
lut[2] = net_driven_by(ctx, ci.getPort(id_I3), is_lut, id_O);
|
||||
if (!lut[2] || ci.getPort(id_I3)->users.entries()!=1)
|
||||
continue;
|
||||
lut[3] = net_driven_by(ctx, ci.getPort(id_I4), is_lut, id_O);
|
||||
if (!lut[3] || ci.getPort(id_I4)->users.entries()!=1)
|
||||
continue;
|
||||
|
||||
ci.type = id_XLUT;
|
||||
bind_attr_loc(&ci, &ci.attrs);
|
||||
ci.cluster = ci.name;
|
||||
lut_only++;
|
||||
for (int i=0;i<4;i++) {
|
||||
ci.constr_children.push_back(lut[i]);
|
||||
lut[i]->cluster = ci.cluster;
|
||||
lut[i]->type = id_BEYOND_FE;
|
||||
lut[i]->constr_z = PLACE_XLUT_FE1 + i;
|
||||
lut[i]->renamePort(id_O, id_LO);
|
||||
lut[i]->params[id_lut_used] = Property(1,1);
|
||||
lut[i]->timing_index = ctx->get_cell_timing_idx(ctx->id("BEYOND_FE_LUT"));
|
||||
lut_only++;
|
||||
}
|
||||
}
|
||||
if (lut_only)
|
||||
log_info(" %6d FEs used as LUT only\n", lut_only);
|
||||
//if (lut_and_ff)
|
||||
// log_info(" %6d FEs used as LUT and DFF\n", lut_and_ff);
|
||||
flush_cells();
|
||||
}
|
||||
|
||||
void NgUltraPacker::pack_lut_dffs(void)
|
||||
{
|
||||
log_info("Pack LUT-DFFs...\n");
|
||||
@ -1774,6 +1831,7 @@ void NgUltraImpl::pack()
|
||||
packer.pack_cdcs();
|
||||
packer.pack_fifos();
|
||||
packer.pack_cys();
|
||||
packer.pack_xluts();
|
||||
packer.pack_lut_dffs();
|
||||
packer.pack_dffs();
|
||||
|
||||
|
@ -46,6 +46,7 @@ struct NgUltraPacker
|
||||
// LUTs & FFs
|
||||
void update_lut_init();
|
||||
void update_dffs();
|
||||
void pack_xluts();
|
||||
void pack_lut_dffs();
|
||||
void pack_dffs();
|
||||
void pack_cys();
|
||||
|
Loading…
Reference in New Issue
Block a user