From ef2488e4059b70921c0cd376cf40683ed3cb5dbf Mon Sep 17 00:00:00 2001 From: gatecat Date: Mon, 16 Mar 2026 09:38:16 +0000 Subject: [PATCH] xilinx: Index control sets Signed-off-by: gatecat --- himbaechel/uarch/xilinx/xilinx.cc | 46 ++++++++++++++++++++++++++++++- himbaechel/uarch/xilinx/xilinx.h | 2 ++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/himbaechel/uarch/xilinx/xilinx.cc b/himbaechel/uarch/xilinx/xilinx.cc index ad41cdbd..18271674 100644 --- a/himbaechel/uarch/xilinx/xilinx.cc +++ b/himbaechel/uarch/xilinx/xilinx.cc @@ -39,6 +39,30 @@ NEXTPNR_NAMESPACE_BEGIN + +struct FFControlSet +{ + unsigned flags = 0; + enum { + IS_LATCH = 1, + IS_CLKINV = 2, + IS_SRINV = 4, + FFSYNC = 8, + }; + IdString clk, sr, ce; + bool operator==(const FFControlSet &other) const { + return flags == other.flags && clk == other.clk + && ce == other.ce && sr == other.sr; + }; + unsigned hash() const { + unsigned hash = mkhash(clk.hash(), sr.hash()); + hash = mkhash(hash, ce.hash()); + hash = mkhash(hash, flags); + return hash; + } +}; + + XilinxImpl::~XilinxImpl() {}; po::options_description XilinxImpl::getUArchOptions() @@ -274,7 +298,7 @@ bool XilinxImpl::is_pip_unavail(PipId pip) const return false; } -void XilinxImpl::prePlace() { assign_cell_tags(); } +void XilinxImpl::prePlace() { assign_cell_tags(); index_control_sets(); } void XilinxImpl::postPlace() { @@ -542,6 +566,26 @@ void XilinxImpl::assign_cell_tags() } } +void XilinxImpl::index_control_sets() { + idict control_sets; + for (auto &cell : ctx->cells) { + CellInfo *ci = cell.second.get(); + if (ci->type == id_SLICE_FFX) { + auto &ct = cell_tags.at(ci->flat_index); + FFControlSet ctrl_set; + ctrl_set.clk = ct.ff.clk ? ct.ff.clk->name : IdString(); + ctrl_set.ce = ct.ff.ce ? ct.ff.ce->name : IdString(); + ctrl_set.sr = ct.ff.clk ? ct.ff.sr->name : IdString(); + ctrl_set.flags = (ct.ff.is_clkinv ? FFControlSet::IS_CLKINV : 0) | + (ct.ff.is_srinv ? FFControlSet::IS_SRINV : 0) | + (ct.ff.is_latch ? FFControlSet::IS_LATCH : 0) | + (ct.ff.ffsync ? FFControlSet::FFSYNC : 0); + ct.ff.control_set = control_sets(ctrl_set); + } + } + log_info("Indexed %d control sets.\n", int(control_sets.size())); +} + bool XilinxImpl::is_general_routing(WireId wire) const { IdString intent = ctx->getWireType(wire); diff --git a/himbaechel/uarch/xilinx/xilinx.h b/himbaechel/uarch/xilinx/xilinx.h index ceaa2c87..434d85c5 100644 --- a/himbaechel/uarch/xilinx/xilinx.h +++ b/himbaechel/uarch/xilinx/xilinx.h @@ -49,6 +49,7 @@ struct XilinxCellTags bool is_latch, is_clkinv, is_srinv, ffsync; bool is_paired; NetInfo *clk, *sr, *ce, *d; + int32_t control_set; } ff; struct { @@ -183,6 +184,7 @@ struct XilinxImpl : HimbaechelAPI private: HimbaechelHelpers h; void assign_cell_tags(); + void index_control_sets(); }; NEXTPNR_NAMESPACE_END