diff --git a/techlibs/xilinx/xilinx_dsp.cc b/techlibs/xilinx/xilinx_dsp.cc index 862db21f3..2c63da3c8 100644 --- a/techlibs/xilinx/xilinx_dsp.cc +++ b/techlibs/xilinx/xilinx_dsp.cc @@ -64,18 +64,61 @@ static Cell* addDsp(Module *module) { return cell; } +SigPool simd_signals(Module *module, SigMap* sigmap) +{ + SigPool simd_signals; + // Mark representatives of wires that have the attribute + for (auto wire : module->wires()) { + SigSpec reps = (*sigmap)(wire); + log_assert(reps.size() == wire->width); + for (int i = 0; i < reps.size(); i++) { + auto bit = reps[i]; + auto src_bit = SigBit(wire, i); + if (src_bit.is_wire() && src_bit.wire->has_attribute(ID::use_dsp)) { + if (src_bit.wire->get_strpool_attribute(ID::use_dsp).count("simd")) { + simd_signals.add(bit); + } + } + } + } + // Also mark all aliases of those representatives + for (auto wire : module->wires()) { + SigSpec reps = (*sigmap)(wire); + log_assert(reps.size() == wire->width); + for (int i = 0; i < reps.size(); i++) { + auto bit = reps[i]; + auto src_bit = SigBit(wire, i); + if (simd_signals.check(bit)) { + simd_signals.add(src_bit); + } + } + } + // This seems silly, but that's generalized RTLIL for you! + return simd_signals; +} + +bool is_allowed(SigSpec& sig, SigPool& allowed_bits) +{ + for (auto bit : sig.bits()) { + if (!allowed_bits.check(bit)) { + return false; + } + } + return true; +} + void xilinx_simd_pack(Module *module, SigMap* sigmap, const std::vector &selected_cells) { std::deque simd12_add, simd12_sub; std::deque simd24_add, simd24_sub; + SigPool simds = simd_signals(module, sigmap); + for (auto cell : selected_cells) { if (!cell->type.in(ID($add), ID($sub))) continue; SigSpec Y = cell->getPort(ID::Y); - if (!Y.is_chunk()) - continue; - if (!Y.as_chunk().wire->get_strpool_attribute(ID(use_dsp)).count("simd")) + if (!is_allowed(Y, simds)) continue; if (GetSize(Y) > 25) continue; diff --git a/tests/arch/xilinx/xilinx_srl.ys b/tests/arch/xilinx/xilinx_srl.ys index b8df0e55a..5d5f36355 100644 --- a/tests/arch/xilinx/xilinx_srl.ys +++ b/tests/arch/xilinx/xilinx_srl.ys @@ -1,6 +1,10 @@ -read_verilog xilinx_srl.v +read_verilog -icells xilinx_srl.v design -save read - +blackbox +select =* +design -save boxes +design -reset +design -load read design -copy-to model $__XILINX_SHREG_ hierarchy -top xilinx_srl_static_test prep @@ -35,12 +39,12 @@ sat -verify -prove-asserts -show-ports -seq 5 miter ########## design -load read -design -copy-to model $__XILINX_SHREG_ hierarchy -top xilinx_srl_variable_test prep design -save gold xilinx_srl -variable +design -copy-from boxes =$__XILINX_SHREG_ opt #stat @@ -54,7 +58,7 @@ design -stash gate design -import gold -as gold design -import gate -as gate -design -copy-from model -as $__XILINX_SHREG_ \$__XILINX_SHREG_ +design -copy-from model -as gate.$__XILINX_SHREG_ \$__XILINX_SHREG_ prep miter -equiv -flatten -make_assert -make_outputs gold gate miter