diff --git a/himbaechel/uarch/gatemate/extra_data.h b/himbaechel/uarch/gatemate/extra_data.h index cd11799e..0a4cb978 100644 --- a/himbaechel/uarch/gatemate/extra_data.h +++ b/himbaechel/uarch/gatemate/extra_data.h @@ -43,9 +43,8 @@ NPNR_PACKED_STRUCT(struct GateMatePipExtraDataPOD { uint8_t plane; uint8_t dummy1; uint16_t dummy2; - uint32_t data; - uint32_t mask; - int32_t resource; + uint32_t block; + uint32_t resource; }); NPNR_PACKED_STRUCT(struct GateMateBelPinConstraintPOD { @@ -129,21 +128,22 @@ enum ClusterPlacement enum PipMask { - IS_MULT = 1 << 0, - IS_ADDF = 1 << 1, - IS_COMP = 1 << 2, - C_SELX = 1 << 3, - C_SELY1 = 1 << 4, - C_SELY2 = 1 << 5, - C_SEL_C = 1 << 6, - C_SEL_P = 1 << 7, - C_Y12 = 1 << 8, - C_CX_I = 1 << 9, - C_CY1_I = 1 << 10, - C_CY2_I = 1 << 11, - C_PX_I = 1 << 12, - C_PY1_I = 1 << 13, - C_PY2_I = 1 << 14, + C_SELX = 1 << 0, + C_SELY1 = 1 << 1, + C_SELY2 = 1 << 2, + C_SEL_C = 1 << 3, + C_SEL_P = 1 << 4, + C_Y12 = 1 << 5, + C_CX_I = 1 << 6, + C_CY1_I = 1 << 7, + C_CY2_I = 1 << 8, + C_PX_I = 1 << 9, + C_PY1_I = 1 << 10, + C_PY2_I = 1 << 11, + + IS_MULT = 1 << 29, + IS_ADDF = 1 << 30, + IS_COMP = 1 << 31, }; struct PllCfgRecord diff --git a/himbaechel/uarch/gatemate/gatemate.cc b/himbaechel/uarch/gatemate/gatemate.cc index dc702bec..652b6720 100644 --- a/himbaechel/uarch/gatemate/gatemate.cc +++ b/himbaechel/uarch/gatemate/gatemate.cc @@ -331,8 +331,8 @@ void GateMateImpl::postPlace() if (marked_used) used_cpes[cell.second.get()->bel.tile] = true; - uint32_t mask = 0; - uint32_t data = 0; + uint32_t mask = pip_mask[cell.second.get()->bel.tile]; + uint32_t data = pip_data[cell.second.get()->bel.tile]; if (cell.second.get()->type == id_CPE_MULT) { mask |= PipMask::IS_MULT; data |= PipMask::IS_MULT; @@ -368,10 +368,18 @@ bool GateMateImpl::checkPipAvail(PipId pip) const if (extra_data.value == 1 && IdString(extra_data.name).in(id_C_CLKSEL, id_C_ENSEL)) return false; } - if (extra_data.type == PipExtra::PIP_EXTRA_MUX && (extra_data.mask != 0)) { - if (pip_mask[pip.tile] & extra_data.mask) { - if ((pip_data[pip.tile] & extra_data.mask) != extra_data.data) + if (extra_data.type == PipExtra::PIP_EXTRA_MUX && (extra_data.block != 0)) { + if (pip_mask[pip.tile] & extra_data.block) { + //printf("blocking %s - > %s at %s\n",ctx->getPipName(pip)[2].c_str(ctx),ctx->getPipName(pip)[1].c_str(ctx),ctx->getPipName(pip)[0].c_str(ctx)); + return false; + } + } + if (extra_data.type == PipExtra::PIP_EXTRA_MUX && (extra_data.resource != 0)) { + if (pip_mask[pip.tile] & extra_data.resource) { + if ((pip_data[pip.tile] & extra_data.resource) != (extra_data.value ? extra_data.resource : 0)) { + //printf("blocking %s - > %s at %s\n",ctx->getPipName(pip)[2].c_str(ctx),ctx->getPipName(pip)[1].c_str(ctx),ctx->getPipName(pip)[0].c_str(ctx)); return false; + } } } if (extra_data.type != PipExtra::PIP_EXTRA_MUX || (extra_data.flags & MUX_ROUTING) == 0) @@ -506,7 +514,23 @@ void GateMateImpl::reassign_cplines(NetInfo *ni, const dict &net ctx->bindBel(bel, cell, PlaceStrength::STRENGTH_FIXED); } - cell->setParam(IdString(extra_data.resource), Property(extra_data.value, extra_data.bits)); + auto resource_map = dict{ + { PipMask::C_SELX, id_C_SELX }, + { PipMask::C_SELY1, id_C_SELY1 }, + { PipMask::C_SELY2, id_C_SELY2 }, + { PipMask::C_SEL_C, id_C_SEL_C }, + { PipMask::C_SEL_P, id_C_SEL_P }, + { PipMask::C_Y12, id_C_Y12 }, + { PipMask::C_CX_I, id_C_CX_I }, + { PipMask::C_CY1_I, id_C_CY1_I }, + { PipMask::C_CY2_I, id_C_CY2_I }, + { PipMask::C_PX_I, id_C_PX_I }, + { PipMask::C_PY1_I, id_C_PY1_I }, + { PipMask::C_PY2_I, id_C_PY2_I, }, + }; + + NPNR_ASSERT(resource_map.count(extra_data.resource)); + cell->setParam(resource_map.at(extra_data.resource), Property(extra_data.value, extra_data.bits)); // We have to discover the ports needed by this config. auto input_port_map = dict{ diff --git a/himbaechel/uarch/gatemate/gen/arch_gen.py b/himbaechel/uarch/gatemate/gen/arch_gen.py index 3ca46b0c..0a4c4ab3 100644 --- a/himbaechel/uarch/gatemate/gen/arch_gen.py +++ b/himbaechel/uarch/gatemate/gen/arch_gen.py @@ -73,9 +73,8 @@ class PipExtraData(BBAStruct): value: int = 0 invert: int = 0 plane: int = 0 - data: int = 0 - mask: int = 0 - resource: IdString = IdString(0) + block: int = 0 + resource: int = 0 def serialise_lists(self, context: str, bba: BBAWriter): pass @@ -88,9 +87,8 @@ class PipExtraData(BBAStruct): bba.u8(self.plane) bba.u8(0) bba.u16(0) - bba.u32(self.data) - bba.u32(self.mask) - bba.u32(self.resource.index) + bba.u32(self.block) + bba.u32(self.resource) @dataclass class BelPinConstraint(BBAStruct): @@ -316,7 +314,7 @@ def main(): plane = int(mux.name[10:12]) if mux.name == "CPE.C_SN": mux_flags |= MUX_ROUTING - pp.extra_data = PipExtraData(PIP_EXTRA_MUX, ch.strs.id(mux.name), mux.bits, mux.value, mux_flags, plane, mux.data, mux.mask, ch.strs.id(mux.resource) if mux.resource else IdString(0)) + pp.extra_data = PipExtraData(PIP_EXTRA_MUX, ch.strs.id(mux.name), mux.bits, mux.value, mux_flags, plane, mux.block, mux.resource) if type_name in new_wires: for wire in sorted(new_wires[type_name]): delay = wire_delay[wire] diff --git a/himbaechel/uarch/gatemate/gfx.cc b/himbaechel/uarch/gatemate/gfx.cc index db9b1e84..a4325475 100644 --- a/himbaechel/uarch/gatemate/gfx.cc +++ b/himbaechel/uarch/gatemate/gfx.cc @@ -41,6 +41,13 @@ void GateMateImpl::drawBel(std::vector &g, GraphicElement::style el.y2 = el.y1 + 0.50; g.push_back(el); break; + case id_CPE_CPLINES.index: + el.x1 = loc.x + 0.72; + el.x2 = el.x1 + 0.06; + el.y1 = loc.y + 0.25; + el.y2 = el.y1 + 0.50; + g.push_back(el); + break; case id_CPE_LT_L.index: el.x1 = loc.x + 0.20; el.x2 = el.x1 + 0.20;