From: Eddie Hung Date: Wed, 21 Aug 2019 03:18:17 +0000 (-0700) Subject: Merge remote-tracking branch 'origin/master' into xc7dsp X-Git-Tag: working-ls180~1039^2~231 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b7a48e3e0f49f09e12a2b394b62256a87c398dbc;p=yosys.git Merge remote-tracking branch 'origin/master' into xc7dsp --- b7a48e3e0f49f09e12a2b394b62256a87c398dbc diff --cc passes/pmgen/Makefile.inc index e33866670,790811d4c..faed7c5e3 --- a/passes/pmgen/Makefile.inc +++ b/passes/pmgen/Makefile.inc @@@ -4,16 -9,15 +9,21 @@@ $(eval $(call add_extra_objs,passes/pmg # -------------------------------------- - passes/pmgen/%.o: passes/pmgen/%_pm.h + OBJS += passes/pmgen/ice40_dsp.o passes/pmgen/ice40_dsp.o: passes/pmgen/ice40_dsp_pm.h - passes/pmgen/xilinx_dsp.o: passes/pmgen/xilinx_dsp_pm.h - EXTRA_OBJS += passes/pmgen/ice40_dsp_pm.h - EXTRA_OBJS += passes/pmgen/xilinx_dsp_pm.h - .SECONDARY: passes/pmgen/ice40_dsp_pm.h - .SECONDARY: passes/pmgen/xilinx_dsp_pm.h + $(eval $(call add_extra_objs,passes/pmgen/ice40_dsp_pm.h)) - passes/pmgen/%_pm.h: passes/pmgen/pmgen.py passes/pmgen/%.pmg - $(P) mkdir -p passes/pmgen && python3 $< -o $@ -p $* $(filter-out $<,$^) + # -------------------------------------- + + OBJS += passes/pmgen/ice40_wrapcarry.o + passes/pmgen/ice40_wrapcarry.o: passes/pmgen/ice40_wrapcarry_pm.h -$(eval $(call add_extra_objs,passes/pmgen/test_pmgen_pm.h)) ++$(eval $(call add_extra_objs,passes/pmgen/ice40_wrapcarry_pm.h)) ++ ++# -------------------------------------- ++ ++OBJS += passes/pmgen/xilinx_dsp.o ++passes/pmgen/xilinx_dsp.o: passes/pmgen/xilinx_dsp_pm.h ++$(eval $(call add_extra_objs,passes/pmgen/xilinx_dsp.h)) # -------------------------------------- diff --cc passes/pmgen/ice40_dsp.pmg index b387ca0a2,7003092bb..cf7957ff3 --- a/passes/pmgen/ice40_dsp.pmg +++ b/passes/pmgen/ice40_dsp.pmg @@@ -187,106 -139,25 +187,107 @@@ code muxA muxAB = muxB; endcode -match ffS - if muxAB - select ffS->type.in($dff) - select nusers(port(ffS, \D)) == 2 - index port(ffS, \D) === port(muxAB, \Y) - index port(ffS, \Q) === sigS +// Extract the bits of P that actually have a consumer +// (as opposed to being a dummy) +code sigOused + for (int i = 0; i < GetSize(sigO); i++) + if (!sigO[i].wire || nusers(sigO[i]) == 1) + sigOused.append(State::Sx); + else + sigOused.append(sigO[i]); +endcode + +match ffO_lo + if nusers(sigOused.extract(0,std::min(16,GetSize(sigOused)))) == 2 + select ffO_lo->type.in($dff) + optional endmatch -code clock clock_pol clock_vld - if (ffS) { - SigBit c = port(ffS, \CLK).as_bit(); - bool cp = param(ffS, \CLK_POLARITY).as_bool(); +code + if (ffO_lo) { + SigSpec O = sigOused.extract(0,std::min(16,param(ffO_lo, \WIDTH).as_int())); + O.remove_const(); + if (!includes(port(ffO_lo, \D).to_sigbit_set(), O.to_sigbit_set())) + reject; + } +endcode - if (clock_vld && (c != clock || cp != clock_pol)) +match ffO_hi + if GetSize(sigOused) > 16 + if nusers(sigOused.extract_end(16)) == 2 + select ffO_hi->type.in($dff) + optional +endmatch + +code + if (ffO_hi) { + SigSpec O = sigOused.extract_end(16); + O.remove_const(); + if (!includes(port(ffO_hi, \D).to_sigbit_set(), O.to_sigbit_set())) reject; + } +endcode - clock = c; - clock_pol = cp; - clock_vld = true; +code clock clock_pol sigO sigCD + if (ffO_lo || ffO_hi) { + if (mul->type == \SB_MAC16) { + // Ensure that register is not already used + if (param(mul, \TOPOUTPUT_SELECT).as_int() == 1 || + param(mul, \BOTOUTPUT_SELECT).as_int() == 1) + reject; + + // Ensure that OLOADTOP/OLOADBOT is unused or zero + if ((mul->hasPort(\OLOADTOP) && !port(mul, \OLOADTOP).is_fully_zero()) + || (mul->hasPort(\OLOADBOT) && !port(mul, \OLOADBOT).is_fully_zero())) + reject; + } + + if (ffO_lo) { + for (auto b : port(ffO_lo, \Q)) + if (b.wire->get_bool_attribute(\keep)) + reject; + + SigBit c = port(ffO_lo, \CLK).as_bit(); + bool cp = param(ffO_lo, \CLK_POLARITY).as_bool(); + + if (clock != SigBit() && (c != clock || cp != clock_pol)) + reject; + + clock = c; + clock_pol = cp; + + sigO.replace(port(ffO_lo, \D), port(ffO_lo, \Q)); + } + + if (ffO_hi) { + for (auto b : port(ffO_hi, \Q)) + if (b.wire->get_bool_attribute(\keep)) + reject; + + SigBit c = port(ffO_hi, \CLK).as_bit(); + bool cp = param(ffO_hi, \CLK_POLARITY).as_bool(); + + if (clock != SigBit() && (c != clock || cp != clock_pol)) + reject; + + clock = c; + clock_pol = cp; + + sigO.replace(port(ffO_hi, \D), port(ffO_hi, \Q)); + } + + // Loading value into output register is not + // supported unless using accumulator + if (muxAB) { + if (sigCD != sigO) + reject; + if (muxA) + sigCD = port(muxAB, \B); + else if (muxB) + sigCD = port(muxAB, \A); + else log_abort(); + sigCD.extend_u0(32, addAB && param(addAB, \A_SIGNED).as_bool() && param(addAB, \B_SIGNED).as_bool()); + } } + accept; endcode diff --cc techlibs/xilinx/synth_xilinx.cc index 102c896aa,7ba67409b..26d01ce40 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@@ -107,7 -104,7 +107,7 @@@ struct SynthXilinxPass : public ScriptP } std::string top_opt, edif_file, blif_file, family; - bool flatten, retime, vpr, nobram, nodram, nosrl, nocarry, nowidelut, nodsp, abc9; - bool flatten, retime, vpr, nobram, nolutram, nosrl, nocarry, nowidelut, abc9; ++ bool flatten, retime, vpr, nobram, nolutram, nosrl, nocarry, nowidelut, nodsp, abc9; int widemux; void clear_flags() YS_OVERRIDE