diff --git a/himbaechel/uarch/ng-ultra/extra_data.h b/himbaechel/uarch/ng-ultra/extra_data.h index e396624f..c4aca007 100644 --- a/himbaechel/uarch/ng-ultra/extra_data.h +++ b/himbaechel/uarch/ng-ultra/extra_data.h @@ -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, diff --git a/himbaechel/uarch/ng-ultra/gen/arch_gen.py b/himbaechel/uarch/ng-ultra/gen/arch_gen.py index 39e8e7f0..3cfb5191 100644 --- a/himbaechel/uarch/ng-ultra/gen/arch_gen.py +++ b/himbaechel/uarch/ng-ultra/gen/arch_gen.py @@ -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 diff --git a/himbaechel/uarch/ng-ultra/ng_ultra.cc b/himbaechel/uarch/ng-ultra/ng_ultra.cc index a11120b2..f634ae48 100644 --- a/himbaechel/uarch/ng-ultra/ng_ultra.cc +++ b/himbaechel/uarch/ng-ultra/ng_ultra.cc @@ -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 map = @@ -591,7 +600,6 @@ Loc getXRFFE(Loc root, int pos) return result; } - Loc getCDCFE(Loc root, int pos) { static const std::vector cdc1 = @@ -963,10 +971,8 @@ bool NgUltraImpl::getChildPlacement(const BaseClusterInfo *cluster, Loc root_loc Loc child_loc = if_using_basecluster(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: diff --git a/himbaechel/uarch/ng-ultra/pack.cc b/himbaechel/uarch/ng-ultra/pack.cc index fcdd0785..6c787b21 100644 --- a/himbaechel/uarch/ng-ultra/pack.cc +++ b/himbaechel/uarch/ng-ultra/pack.cc @@ -294,6 +294,63 @@ void NgUltraPacker::bind_attr_loc(CellInfo *cell, dict *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(); diff --git a/himbaechel/uarch/ng-ultra/pack.h b/himbaechel/uarch/ng-ultra/pack.h index d97e40d9..1ac8a0a6 100644 --- a/himbaechel/uarch/ng-ultra/pack.h +++ b/himbaechel/uarch/ng-ultra/pack.h @@ -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();