diff options
Diffstat (limited to 'passes')
| -rw-r--r-- | passes/pmgen/xilinx_dsp.cc | 12 | ||||
| -rw-r--r-- | passes/pmgen/xilinx_dsp.pmg | 39 | 
2 files changed, 48 insertions, 3 deletions
diff --git a/passes/pmgen/xilinx_dsp.cc b/passes/pmgen/xilinx_dsp.cc index e7b72e312..105ad1fa1 100644 --- a/passes/pmgen/xilinx_dsp.cc +++ b/passes/pmgen/xilinx_dsp.cc @@ -39,6 +39,7 @@ void pack_xilinx_dsp(dict<SigBit, Cell*> &bit_to_driver, xilinx_dsp_pm &pm)  	log("ffB:     %s\n", log_id(st.ffB, "--"));  	log("dsp:     %s\n", log_id(st.dsp, "--"));  	log("addAB:   %s\n", log_id(st.addAB, "--")); +	log("ffM:     %s\n", log_id(st.ffM, "--"));  	log("ffP:     %s\n", log_id(st.ffP, "--"));  	//log("muxP:  %s\n", log_id(st.muxP, "--"));  	log("sigPused: %s\n", log_signal(st.sigPused)); @@ -95,6 +96,17 @@ void pack_xilinx_dsp(dict<SigBit, Cell*> &bit_to_driver, xilinx_dsp_pm &pm)  			//	cell->setPort("\\CEB2", st.ffB->getPort("\\EN"));  			else log_abort();  		} +		if (st.ffM) { +			SigSpec D = st.ffM->getPort("\\D"); +			SigSpec Q = st.ffM->getPort("\\Q"); +			P.replace(pm.sigmap(D), Q); +			cell->setParam("\\MREG", State::S1); +			if (st.ffP->type == "$dff") +				cell->setPort("\\CEM", State::S1); +			//else if (st.ffP->type == "$dffe") +			//	cell->setPort("\\CEP", st.ffP->getPort("\\EN")); +			else log_abort(); +		}  		if (st.ffP) {  			SigSpec D;  			//if (st.muxP) diff --git a/passes/pmgen/xilinx_dsp.pmg b/passes/pmgen/xilinx_dsp.pmg index 47e6a0050..08b432b8e 100644 --- a/passes/pmgen/xilinx_dsp.pmg +++ b/passes/pmgen/xilinx_dsp.pmg @@ -2,7 +2,7 @@ pattern xilinx_dsp  state <SigBit> clock  state <std::set<SigBit>> sigAset sigBset -state <SigSpec> sigC sigP sigPused +state <SigSpec> sigC sigM sigMused sigP sigPused  state <Cell*> addAB  match dsp @@ -18,6 +18,12 @@ code sigAset sigBset  	sigBset = B.to_sigbit_set();  endcode +code sigM +	sigM = port(dsp, \P); +	//if (GetSize(sigH) <= 10) +	//	reject; +endcode +  match ffA  	if param(dsp, \AREG).as_int() == 0  	if !sigAset.empty() @@ -63,8 +69,35 @@ code clock  	}  endcode -code sigP -	sigP = port(dsp, \P); +match ffM +	if param(dsp, \MREG).as_int() == 0 +	select ffM->type.in($dff) +	// DSP48E1 does not support clock inversion +	select param(ffM, \CLK_POLARITY).as_bool() +	select nusers(port(ffM, \D)) == 2 +	//index <SigSpec> port(ffM, \D) === sigM.extract(0, GetSize(port(ffM, \D))) // TODO: Why doesn't this work!?! +	filter port(ffM, \D) == sigM.extract(0, GetSize(port(ffM, \D))) +    filter nusers(sigM.extract_end(param(ffM, \WIDTH).as_int())) == 1 +	optional +endmatch + +code clock sigM sigP +	if (ffM) { +        log_warning("M FOUND!\n"); +		sigM = port(ffM, \Q); +		for (auto b : sigM) +			if (b.wire->get_bool_attribute(\keep)) +				reject; + +		SigBit c = port(ffB, \CLK).as_bit(); + +		if (clock != SigBit() && c != clock) +			reject; + +		clock = c; +	} + +	sigP = sigM;  endcode  match addA  | 
