From cb1f01f3a637cbaacf4e2a6a891f9857a6574b47 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 14 Jan 2025 14:21:50 +0100 Subject: [PATCH] Some CC_DFF improvements --- himbaechel/uarch/gatemate/constids.inc | 4 ++ himbaechel/uarch/gatemate/gatemate.cc | 29 ++++++++++++++ himbaechel/uarch/gatemate/gen/arch_gen.py | 14 ++++++- himbaechel/uarch/gatemate/pack.cc | 48 ++++++++++++++++++----- 4 files changed, 84 insertions(+), 11 deletions(-) diff --git a/himbaechel/uarch/gatemate/constids.inc b/himbaechel/uarch/gatemate/constids.inc index a5bc0be2..766c3ebf 100644 --- a/himbaechel/uarch/gatemate/constids.inc +++ b/himbaechel/uarch/gatemate/constids.inc @@ -116,6 +116,10 @@ X(R) X(S) X(FF_INIT) X(2D_IN) +X(SR_VAL) +X(SR_INV) +X(EN_INV) +X(CLK_INV) X(CC_BUFG) X(BUFG) diff --git a/himbaechel/uarch/gatemate/gatemate.cc b/himbaechel/uarch/gatemate/gatemate.cc index 847c72f9..1e38aed6 100644 --- a/himbaechel/uarch/gatemate/gatemate.cc +++ b/himbaechel/uarch/gatemate/gatemate.cc @@ -90,6 +90,25 @@ void updateLUT(Context *ctx, CellInfo *cell, IdString port, IdString init) } } +void updateINV(Context *ctx, CellInfo *cell, IdString port) +{ + if (cell->params.count(port) == 0) return; + unsigned init_val = int_or_default(cell->params, port); + WireId pin_wire = ctx->getBelPinWire(cell->bel, port); + for (PipId pip : ctx->getPipsUphill(pin_wire)) { + if (!ctx->getBoundPipNet(pip)) + continue; + const auto extra_data = *reinterpret_cast( + chip_pip_info(ctx->chip_info, pip).extra_data.get()); + if (!extra_data.name) + continue; + if (extra_data.type == PipExtra::PIP_EXTRA_MUX && (extra_data.flags & MUX_CPE_INV)) { + cell->params[port] = Property(init_val==1 ? 2 : 1, 2); + } + } +} + + void GateMateImpl::postRoute() { ctx->assignArchInfo(); @@ -127,6 +146,14 @@ void GateMateImpl::postRoute() cell->params[id_INIT_L20] = Property(0b1010, 4); cell->params[id_O1] = Property(0b11, 2); cell->params[id_RAM_O1] = Property(1, 1); + } else if (IdString(extra_data.name) == id_O1) { + cell->params[id_INIT_L00] = Property(0b1010, 4); + cell->params[id_INIT_L01] = Property(0b1111, 4); + cell->params[id_INIT_L02] = Property(0b1111, 4); + cell->params[id_INIT_L03] = Property(0b1111, 4); + cell->params[id_INIT_L10] = Property(0b1000, 4); + cell->params[id_INIT_L20] = Property(0b1010, 4); + cell->params[id_O1] = Property(0b11, 2); } else { log_error("Issue adding pass trough signal for %s.\n",IdString(extra_data.name).c_str(ctx)); } @@ -149,6 +176,8 @@ void GateMateImpl::postRoute() updateLUT(ctx, cell.second.get(), id_IN6, id_INIT_L02); updateLUT(ctx, cell.second.get(), id_IN7, id_INIT_L03); updateLUT(ctx, cell.second.get(), id_IN8, id_INIT_L03); + updateINV(ctx, cell.second.get(), id_CLK); + updateINV(ctx, cell.second.get(), id_EN); } } diff --git a/himbaechel/uarch/gatemate/gen/arch_gen.py b/himbaechel/uarch/gatemate/gen/arch_gen.py index 1e526679..0830a915 100644 --- a/himbaechel/uarch/gatemate/gen/arch_gen.py +++ b/himbaechel/uarch/gatemate/gen/arch_gen.py @@ -102,9 +102,19 @@ def main(): pp.extra_data = PipExtraData(PIP_EXTRA_MUX, ch.strs.id(f"CPE.IN{i}_INV"), 1, i, MUX_CPE_INV | MUX_INVERT) tt.create_wire("CPE.V_CLK", "CPE_VIRTUAL_WIRE") pp = tt.create_pip("CPE.V_CLK", "CPE.CLK") - pp.extra_data = PipExtraData(PIP_EXTRA_MUX, ch.strs.id("CPE.CLK"), 2, 1, MUX_VISIBLE) + pp.extra_data = PipExtraData(PIP_EXTRA_MUX, ch.strs.id("CPE.CLK_INV"), 1, 0, 0) pp = tt.create_pip("CPE.V_CLK", "CPE.CLK") - pp.extra_data = PipExtraData(PIP_EXTRA_MUX, ch.strs.id("CPE.CLK"), 2, 2, MUX_VISIBLE | MUX_INVERT) + pp.extra_data = PipExtraData(PIP_EXTRA_MUX, ch.strs.id("CPE.CLK_INV"), 1, 1, MUX_CPE_INV| MUX_INVERT) + tt.create_wire("CPE.V_EN", "CPE_VIRTUAL_WIRE") + pp = tt.create_pip("CPE.V_EN", "CPE.EN") + pp.extra_data = PipExtraData(PIP_EXTRA_MUX, ch.strs.id("CPE.EN_INV"), 1, 0, 0) + pp = tt.create_pip("CPE.V_EN", "CPE.EN") + pp.extra_data = PipExtraData(PIP_EXTRA_MUX, ch.strs.id("CPE.EN_INV"), 1, 1, MUX_CPE_INV| MUX_INVERT) + tt.create_wire("CPE.V_SR", "CPE_VIRTUAL_WIRE") + pp = tt.create_pip("CPE.V_SR", "CPE.SR") + pp.extra_data = PipExtraData(PIP_EXTRA_MUX, ch.strs.id("CPE.SR_INV"), 1, 0, 0) + pp = tt.create_pip("CPE.V_SR", "CPE.SR") + pp.extra_data = PipExtraData(PIP_EXTRA_MUX, ch.strs.id("CPE.SR_INV"), 1, 1, MUX_CPE_INV| MUX_INVERT) if "GPIO" in type_name: tt.create_wire("GPIO.OUT_D1", "WIRE_INTERNAL") tt.create_wire("GPIO.OUT_D2", "WIRE_INTERNAL") diff --git a/himbaechel/uarch/gatemate/pack.cc b/himbaechel/uarch/gatemate/pack.cc index 8f16616c..e9b0214e 100644 --- a/himbaechel/uarch/gatemate/pack.cc +++ b/himbaechel/uarch/gatemate/pack.cc @@ -361,7 +361,6 @@ void GateMatePacker::pack_cpe() continue; ci.renamePort(id_D, id_IN1); ci.renamePort(id_Q, id_OUT2); - ci.disconnectPort(id_EN); ci.disconnectPort(id_SR); ci.params[id_O2] = Property(0b00, 2); ci.params[id_2D_IN] = Property(1, 1); @@ -371,17 +370,48 @@ void GateMatePacker::pack_cpe() ci.params[id_INIT_L03] = Property(0b1111, 4); ci.params[id_INIT_L10] = Property(0b1000, 4); ci.params[id_INIT_L20] = Property(0b1100, 4); - ci.params[id_EN] = Property(0b11, 2); + + NetInfo *en_net = ci.getPort(id_EN); + if (en_net) { + bool invert = int_or_default(ci.params, id_EN_INV, 0) == 1; + if (en_net->name == ctx->id("$PACKER_GND")) { + ci.params[id_EN] = Property(invert ? 0b11 : 0b00, 2); + ci.disconnectPort(id_EN); + } else if (en_net->name == ctx->id("$PACKER_VCC")) { + ci.params[id_EN] = Property(invert ? 0b00 : 0b11, 2); + ci.disconnectPort(id_EN); + } else { + ci.params[id_EN] = Property(invert ? 0b01 : 0b10, 2); + } + } + ci.unsetParam(id_EN_INV); + + NetInfo *clk_net = ci.getPort(id_CLK); + if (clk_net) { + bool invert = int_or_default(ci.params, id_CLK_INV, 0) == 1; + if (clk_net->name == ctx->id("$PACKER_GND")) { + ci.params[id_CLK] = Property(invert ? 0b11 : 0b00, 2); + ci.disconnectPort(id_CLK); + } else if (clk_net->name == ctx->id("$PACKER_VCC")) { + ci.params[id_CLK] = Property(invert ? 0b00 : 0b11, 2); + ci.disconnectPort(id_CLK); + } else { + ci.params[id_CLK] = Property(invert ? 0b01 : 0b10, 2); + } + } + ci.unsetParam(id_CLK_INV); + ci.params[id_R] = Property(0b11, 2); ci.params[id_S] = Property(0b11, 2); - ci.params[id_CLK] = Property(0b10, 2); - ci.params[id_FF_INIT] = Property(0b10, 2); - ci.unsetParam(ctx->id("SR_VAL")); - ci.unsetParam(ctx->id("SR_INV")); - ci.unsetParam(ctx->id("EN_INV")); - ci.unsetParam(ctx->id("CLK_INV")); - ci.unsetParam(ctx->id("INIT")); + ci.unsetParam(id_SR_VAL); + ci.unsetParam(id_SR_INV); + bool init = int_or_default(ci.params, id_INIT, 0) == 1; + if (init) + ci.params[id_FF_INIT] = Property(0b11, 2); + else + ci.params[id_FF_INIT] = Property(0b10, 2); + ci.unsetParam(id_INIT); ci.type = id_CPE; }