Merge remote-tracking branch 'origin/master' into xc7dsp
authorEddie Hung <eddie@fpgeh.com>
Wed, 21 Aug 2019 03:18:17 +0000 (20:18 -0700)
committerEddie Hung <eddie@fpgeh.com>
Wed, 21 Aug 2019 03:18:17 +0000 (20:18 -0700)
1  2 
passes/pmgen/Makefile.inc
passes/pmgen/ice40_dsp.pmg
techlibs/ice40/Makefile.inc
techlibs/ice40/synth_ice40.cc
techlibs/xilinx/Makefile.inc
techlibs/xilinx/cells_sim.v
techlibs/xilinx/synth_xilinx.cc

index e33866670611feeb4e42cbd583d8b3c78abd4b5e,790811d4c2ba846b6030b7648647d9f58c192519..faed7c5e3d709aa32c9e0af44ea2746e5d377ebb
@@@ -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))
  
  # --------------------------------------
  
index b387ca0a2f3fd969b78d79c934d665df96ad0760,7003092bb05d521bc59cea7fa5e524dc423e00bf..cf7957ff31f890c4e2da2ab1c770221e63439728
@@@ -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 <SigSpec> port(ffS, \D) === port(muxAB, \Y)
 -      index <SigSpec> 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
Simple merge
Simple merge
Simple merge
Simple merge
index 102c896aabc0fa875047e9fb16e331f3d76b9dab,7ba67409b5a368533304c1cc22eb78bf43953eb5..26d01ce4013f485b609419621f810312e521c6a5
@@@ -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