From 141abe60a69b2bec10cd82958d909d54cc2225c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miodrag=20Milanovi=C4=87?= Date: Fri, 5 Sep 2025 08:37:29 +0200 Subject: [PATCH] gatemate: cleanup BRAM handling (#1551) --- himbaechel/uarch/gatemate/constids.inc | 192 ++-------------------- himbaechel/uarch/gatemate/extra_data.h | 3 +- himbaechel/uarch/gatemate/gatemate.cc | 16 +- himbaechel/uarch/gatemate/gen/arch_gen.py | 4 +- himbaechel/uarch/gatemate/pack_bram.cc | 33 ++-- 5 files changed, 45 insertions(+), 203 deletions(-) diff --git a/himbaechel/uarch/gatemate/constids.inc b/himbaechel/uarch/gatemate/constids.inc index b7caeec2..00542b9e 100644 --- a/himbaechel/uarch/gatemate/constids.inc +++ b/himbaechel/uarch/gatemate/constids.inc @@ -972,9 +972,9 @@ X(CPE_RAMIO_L) //X(OUT) //X(RAM_O) -// hardware primitive CPE_LT_FULL -X(CPE_LT_FULL) -// CPE_LT_FULL pins +// hardware primitive CPE_BRIDGE +X(CPE_BRIDGE) +// CPE_BRIDGE pins //X(IN1) //X(IN2) //X(IN3) @@ -983,11 +983,24 @@ X(IN5) X(IN6) X(IN7) X(IN8) +X(MUXOUT) + +// hardware primitive CPE_LT_FULL +X(CPE_LT_FULL) +// CPE_LT_FULL pins +//X(IN1) +//X(IN2) +//X(IN3) +//X(IN4) +//X(IN5) +//X(IN6) +//X(IN7) +//X(IN8) X(OUT1) X(OUT2) X(CPOUT1) X(CPOUT2) -X(MUXOUT) +//X(MUXOUT) //X(CINX) //X(PINX) //X(CINY1) @@ -1751,176 +1764,6 @@ X(F_RSTN) //X(CLOCK3) //X(CLOCK4) -// hardware primitive RAM_HALF_U -X(RAM_HALF_U) -// RAM_HALF_U pins -//X(CLKA[0]) -//X(ENA[0]) -//X(GLWEA[0]) -//X(CLKB[0]) -//X(ENB[0]) -//X(GLWEB[0]) -//X(WEA[0]) -//X(WEA[1]) -//X(WEA[2]) -//X(WEA[3]) -//X(WEA[4]) -//X(WEA[5]) -//X(WEA[6]) -//X(WEA[7]) -//X(WEA[8]) -//X(WEA[9]) -//X(WEA[10]) -//X(WEA[11]) -//X(WEA[12]) -//X(WEA[13]) -//X(WEA[14]) -//X(WEA[15]) -//X(WEA[16]) -//X(WEA[17]) -//X(WEA[18]) -//X(WEA[19]) -//X(WEB[0]) -//X(WEB[1]) -//X(WEB[2]) -//X(WEB[3]) -//X(WEB[4]) -//X(WEB[5]) -//X(WEB[6]) -//X(WEB[7]) -//X(WEB[8]) -//X(WEB[9]) -//X(WEB[10]) -//X(WEB[11]) -//X(WEB[12]) -//X(WEB[13]) -//X(WEB[14]) -//X(WEB[15]) -//X(WEB[16]) -//X(WEB[17]) -//X(WEB[18]) -//X(WEB[19]) -//X(ADDRA0[0]) -//X(ADDRA0[1]) -//X(ADDRA0[2]) -//X(ADDRA0[3]) -//X(ADDRA0[4]) -//X(ADDRA0[5]) -//X(ADDRA0[6]) -//X(ADDRA0[7]) -//X(ADDRA0[8]) -//X(ADDRA0[9]) -//X(ADDRA0[10]) -//X(ADDRA0[11]) -//X(ADDRA0[12]) -//X(ADDRA0[13]) -//X(ADDRA0[14]) -//X(ADDRA0[15]) -//X(ADDRB0[0]) -//X(ADDRB0[1]) -//X(ADDRB0[2]) -//X(ADDRB0[3]) -//X(ADDRB0[4]) -//X(ADDRB0[5]) -//X(ADDRB0[6]) -//X(ADDRB0[7]) -//X(ADDRB0[8]) -//X(ADDRB0[9]) -//X(ADDRB0[10]) -//X(ADDRB0[11]) -//X(ADDRB0[12]) -//X(ADDRB0[13]) -//X(ADDRB0[14]) -//X(ADDRB0[15]) -//X(DIA[0]) -//X(DIA[1]) -//X(DIA[2]) -//X(DIA[3]) -//X(DIA[4]) -//X(DIA[5]) -//X(DIA[6]) -//X(DIA[7]) -//X(DIA[8]) -//X(DIA[9]) -//X(DIA[10]) -//X(DIA[11]) -//X(DIA[12]) -//X(DIA[13]) -//X(DIA[14]) -//X(DIA[15]) -//X(DIA[16]) -//X(DIA[17]) -//X(DIA[18]) -//X(DIA[19]) -//X(DIB[0]) -//X(DIB[1]) -//X(DIB[2]) -//X(DIB[3]) -//X(DIB[4]) -//X(DIB[5]) -//X(DIB[6]) -//X(DIB[7]) -//X(DIB[8]) -//X(DIB[9]) -//X(DIB[10]) -//X(DIB[11]) -//X(DIB[12]) -//X(DIB[13]) -//X(DIB[14]) -//X(DIB[15]) -//X(DIB[16]) -//X(DIB[17]) -//X(DIB[18]) -//X(DIB[19]) -//X(DOA[0]) -//X(DOA[1]) -//X(DOA[2]) -//X(DOA[3]) -//X(DOA[4]) -//X(DOA[5]) -//X(DOA[6]) -//X(DOA[7]) -//X(DOA[8]) -//X(DOA[9]) -//X(DOA[10]) -//X(DOA[11]) -//X(DOA[12]) -//X(DOA[13]) -//X(DOA[14]) -//X(DOA[15]) -//X(DOA[16]) -//X(DOA[17]) -//X(DOA[18]) -//X(DOA[19]) -//X(DOB[0]) -//X(DOB[1]) -//X(DOB[2]) -//X(DOB[3]) -//X(DOB[4]) -//X(DOB[5]) -//X(DOB[6]) -//X(DOB[7]) -//X(DOB[8]) -//X(DOB[9]) -//X(DOB[10]) -//X(DOB[11]) -//X(DOB[12]) -//X(DOB[13]) -//X(DOB[14]) -//X(DOB[15]) -//X(DOB[16]) -//X(DOB[17]) -//X(DOB[18]) -//X(DOB[19]) -//X(ECC1B_ERRA[0]) -//X(ECC1B_ERRB[0]) -//X(ECC2B_ERRA[0]) -//X(ECC2B_ERRB[0]) -//X(CLOCK1) -//X(CLOCK2) -//X(CLOCK3) -//X(CLOCK4) - // hardware primitive RAM_HALF_L X(RAM_HALF_L) // RAM_HALF_L pins @@ -2621,7 +2464,6 @@ X(CPE_DUMMY) X(CPE_LATCH) X(L2T4_UPPER) X(CPE_MX8) -X(CPE_BRIDGE) X(MULT_INVERT) X(RAM_HALF) X(RAM_HALF_DUMMY) diff --git a/himbaechel/uarch/gatemate/extra_data.h b/himbaechel/uarch/gatemate/extra_data.h index 108e666b..a7923036 100644 --- a/himbaechel/uarch/gatemate/extra_data.h +++ b/himbaechel/uarch/gatemate/extra_data.h @@ -106,8 +106,7 @@ enum CPE_Z CPE_LT_FULL_Z = 8, CPE_BRIDGE_Z = 9, RAM_FULL_Z = 10, - RAM_HALF_U_Z = 11, - RAM_HALF_L_Z = 12, + RAM_HALF_L_Z = 11, }; enum ClusterPlacement diff --git a/himbaechel/uarch/gatemate/gatemate.cc b/himbaechel/uarch/gatemate/gatemate.cc index 9cb86f7b..f7d8c787 100644 --- a/himbaechel/uarch/gatemate/gatemate.cc +++ b/himbaechel/uarch/gatemate/gatemate.cc @@ -168,7 +168,7 @@ bool GateMateImpl::isBelLocationValid(BelId bel, bool explain_invalid) const if (cell->belStrength != PlaceStrength::STRENGTH_FIXED && tile_extra_data(bel.tile)->die != preferred_die) return false; - if (getBelBucketForCellType(ctx->getBelType(bel)) == id_CPE_FF) { + if (getBelBucketForBel(bel) == id_CPE_FF) { Loc loc = ctx->getBelLocation(bel); const CellInfo *adj_half = ctx->getBoundBelCell( ctx->getBelByLocation(Loc(loc.x, loc.y, loc.z == CPE_FF_L_Z ? CPE_FF_U_Z : CPE_FF_L_Z))); @@ -189,11 +189,11 @@ bool GateMateImpl::isBelLocationValid(BelId bel, bool explain_invalid) const } } return true; - } else if (ctx->getBelBucketForBel(bel) == id_RAM_HALF) { + } else if (getBelBucketForBel(bel) == id_RAM_HALF) { Loc loc = ctx->getBelLocation(bel); const CellInfo *adj_half = ctx->getBoundBelCell(ctx->getBelByLocation(Loc(loc.x, loc.z == RAM_HALF_L_Z ? loc.y - 8 : loc.y + 8, - loc.z == RAM_HALF_L_Z ? RAM_HALF_U_Z : RAM_HALF_L_Z))); + loc.z == RAM_HALF_L_Z ? RAM_FULL_Z : RAM_HALF_L_Z))); if (adj_half) { const auto &half_data = fast_cell_info.at(cell->flat_index); if (half_data.used) { @@ -499,7 +499,7 @@ void GateMateImpl::assign_cell_info() fc.config = get_dff_config(ci); fc.used = true; } - if (ci->type == id_RAM_HALF) { + if (getBelBucketForCellType(ci->type) == id_RAM_HALF) { fc.config = get_ram_config(ci); fc.used = true; } @@ -518,7 +518,7 @@ IdString GateMateImpl::getBelBucketForCellType(IdString cell_type) const return id_CPE_FF; else if (cell_type.in(id_CPE_RAMIO, id_CPE_RAMI, id_CPE_RAMO)) return id_CPE_RAMIO; - else if (cell_type.in(id_RAM_HALF, id_RAM_HALF_DUMMY)) + else if (cell_type.in(id_RAM, id_RAM_HALF, id_RAM_HALF_DUMMY)) return id_RAM_HALF; else return cell_type; @@ -533,7 +533,7 @@ BelBucketId GateMateImpl::getBelBucketForBel(BelId bel) const return id_CPE_FF; else if (bel_type.in(id_CPE_RAMIO_U, id_CPE_RAMIO_L)) return id_CPE_RAMIO; - else if (bel_type.in(id_RAM_HALF_U, id_RAM_HALF_L)) + else if (bel_type.in(id_RAM, id_RAM_HALF_L)) return id_RAM_HALF; return bel_type; } @@ -554,8 +554,8 @@ bool GateMateImpl::isValidBelForCellType(IdString cell_type, BelId bel) const return cell_type.in(id_CPE_FF_L, id_CPE_FF, id_CPE_LATCH); else if (bel_type.in(id_CPE_RAMIO_U, id_CPE_RAMIO_L)) return cell_type.in(id_CPE_RAMIO, id_CPE_RAMI, id_CPE_RAMO); - else if (bel_type == id_RAM_HALF_U) - return cell_type.in(id_RAM_HALF, id_RAM_HALF_DUMMY); + else if (bel_type == id_RAM) + return cell_type.in(id_RAM_HALF, id_RAM); else if (bel_type == id_RAM_HALF_L) return cell_type.in(id_RAM_HALF, id_RAM_HALF_DUMMY); else diff --git a/himbaechel/uarch/gatemate/gen/arch_gen.py b/himbaechel/uarch/gatemate/gen/arch_gen.py index 4acdb41e..fc73585d 100644 --- a/himbaechel/uarch/gatemate/gen/arch_gen.py +++ b/himbaechel/uarch/gatemate/gen/arch_gen.py @@ -194,7 +194,7 @@ def set_timings(ch): # assert k in timing, f"pip class {k} not found in timing data" # tmg.set_pip_class(grade=speed, name=k, delay=convert_timing(timing[k])) -EXPECTED_VERSION = 1.6 +EXPECTED_VERSION = 1.7 def main(): # Range needs to be +1, but we are adding +2 more to coordinates, since @@ -234,7 +234,7 @@ def main(): tt.create_wire(wire.name, wire.type) for prim in sorted(die.get_primitives_for_type(type_name)): bel = tt.create_bel(prim.name, prim.type, prim.z) - if (prim.name in ["CPE_LT_FULL", "CPE_BRIDGE", "RAM"]): + if (prim.name in ["CPE_LT_FULL", "CPE_BRIDGE"]): bel.flags |= BEL_FLAG_HIDDEN extra = BelExtraData() for constr in sorted(die.get_pins_constraint(type_name, prim.name, prim.type)): diff --git a/himbaechel/uarch/gatemate/pack_bram.cc b/himbaechel/uarch/gatemate/pack_bram.cc index 6c9c3ba3..3d174326 100644 --- a/himbaechel/uarch/gatemate/pack_bram.cc +++ b/himbaechel/uarch/gatemate/pack_bram.cc @@ -318,21 +318,6 @@ void GateMatePacker::pack_ram() log_error("Unknown CAS parameter value '%s' for cell %s.\n", cas.c_str(), ci.name.c_str(ctx)); } - if (!split) { - CellInfo *cell = ctx->createCell(ctx->idf("%s$dummy$u", ci.name.c_str(ctx)), id_RAM_HALF_DUMMY); - ci.constr_children.push_back(cell); - cell->constr_abs_z = true; - cell->constr_z = RAM_HALF_U_Z; - cell->cluster = ci.cluster; - - cell = ctx->createCell(ctx->idf("%s$dummy$l", ci.name.c_str(ctx)), id_RAM_HALF_DUMMY); - ci.constr_children.push_back(cell); - cell->constr_abs_z = true; - cell->constr_y = +8; - cell->constr_z = RAM_HALF_L_Z; - cell->cluster = ci.cluster; - } - // RAM and Write Modes std::string ram_mode_str = str_or_default(ci.params, id_RAM_MODE, "SDP"); if (ram_mode_str != "SDP" && ram_mode_str != "TDP") @@ -356,6 +341,17 @@ void GateMatePacker::pack_ram() // id_RAM_cfg_datbm_sel ci.params[id_RAM_cfg_cascade_enable] = Property(cascade, 2); + if (!split) { + CellInfo *cell = ctx->createCell(ctx->idf("%s$dummy$l", ci.name.c_str(ctx)), id_RAM_HALF_DUMMY); + ci.constr_children.push_back(cell); + cell->constr_abs_z = true; + cell->constr_y = +8; + cell->constr_z = RAM_HALF_L_Z; + cell->cluster = ci.cluster; + cell->params[id_RAM_cfg_ecc_enable] = Property(b_ecc_en << 1 | a_ecc_en, 2); + cell->params[id_RAM_cfg_sram_mode] = Property(ram_mode << 1 | split, 2); + } + pack_ram_cell(ci, item, split); if (is_fifo) { @@ -542,7 +538,7 @@ void GateMatePacker::repack_ram() for (auto &cell : ctx->cells) { if (cell.second->type.in(id_RAM_HALF)) { Loc l = ctx->getBelLocation(cell.second->bel); - if (l.z == RAM_HALF_U_Z) { + if (l.z == RAM_FULL_Z) { rams[Loc(l.x, l.y, 0)].first = cell.second.get(); } else { rams[Loc(l.x, l.y - 8, 0)].second = cell.second.get(); @@ -558,6 +554,11 @@ void GateMatePacker::repack_ram() if (!ram.second.second) name = ctx->idf("%s$full", ram.second.first->name.c_str(ctx)); + if (ram.second.first) + ctx->unbindBel(ram.second.first->bel); + if (ram.second.second) + ctx->unbindBel(ram.second.second->bel); + CellInfo *cell = ctx->createCell(name, id_RAM); BelId bel = ctx->getBelByLocation({ram.first.x, ram.first.y, RAM_FULL_Z}); ctx->bindBel(bel, cell, PlaceStrength::STRENGTH_FIXED);