diff options
| -rw-r--r-- | passes/pmgen/ice40_dsp.cc | 7 | ||||
| -rw-r--r-- | passes/pmgen/ice40_dsp.pmg | 53 | ||||
| -rw-r--r-- | passes/pmgen/xilinx_dsp.cc | 2 | ||||
| -rw-r--r-- | passes/pmgen/xilinx_dsp.pmg | 20 | 
4 files changed, 47 insertions, 35 deletions
diff --git a/passes/pmgen/ice40_dsp.cc b/passes/pmgen/ice40_dsp.cc index 963a7d7a1..f6a701540 100644 --- a/passes/pmgen/ice40_dsp.cc +++ b/passes/pmgen/ice40_dsp.cc @@ -23,13 +23,16 @@  USING_YOSYS_NAMESPACE  PRIVATE_NAMESPACE_BEGIN +template<class T> bool includes(const T &lhs, const T &rhs) { +	return std::includes(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); +}  #include "passes/pmgen/ice40_dsp_pm.h"  void create_ice40_dsp(ice40_dsp_pm &pm)  {  	auto &st = pm.st_ice40_dsp; -#if 0 +#if 1  	log("\n");  	log("ffA:   %s\n", log_id(st.ffA, "--"));  	log("ffB:   %s\n", log_id(st.ffB, "--")); @@ -100,7 +103,7 @@ void create_ice40_dsp(ice40_dsp_pm &pm)  	cell->setPort("\\IRSTTOP", State::S0);  	cell->setPort("\\IRSTBOT", State::S0); -	if (st.clock_vld) +	if (st.clock != SigBit())  	{  		cell->setPort("\\CLK", st.clock);  		cell->setPort("\\CE", State::S1); diff --git a/passes/pmgen/ice40_dsp.pmg b/passes/pmgen/ice40_dsp.pmg index f2b7f2169..471b8b519 100644 --- a/passes/pmgen/ice40_dsp.pmg +++ b/passes/pmgen/ice40_dsp.pmg @@ -1,8 +1,9 @@  pattern ice40_dsp  state <SigBit> clock -state <bool> clock_pol clock_vld +state <bool> clock_pol  state <SigSpec> sigA sigB sigY sigS +state <SigSpec> sigYused  state <Cell*> addAB muxAB  match mul @@ -13,68 +14,77 @@ endmatch  match ffA  	select ffA->type.in($dff) -	// select nusers(port(ffA, \Q)) == 2 -	index <SigSpec> port(ffA, \Q) === port(mul, \A) +	filter !port(mul, \A).remove_const().empty() +	filter includes(port(ffA, \Q).to_sigbit_set(), port(mul, \A).remove_const().to_sigbit_set())  	optional  endmatch -code sigA clock clock_pol clock_vld +code sigA clock clock_pol  	sigA = port(mul, \A);  	if (ffA) { -		sigA = port(ffA, \D); +		sigA.replace(port(ffA, \Q), port(ffA, \D));  		clock = port(ffA, \CLK).as_bit();  		clock_pol = param(ffA, \CLK_POLARITY).as_bool(); -		clock_vld = true;  	}  endcode  match ffB  	select ffB->type.in($dff) -	// select nusers(port(ffB, \Q)) == 2 -	index <SigSpec> port(ffB, \Q) === port(mul, \B) +	filter !port(mul, \B).remove_const().empty() +	filter includes(port(ffB, \Q).to_sigbit_set(), port(mul, \B).remove_const().to_sigbit_set())  	optional  endmatch -code sigB clock clock_pol clock_vld +code sigB clock clock_pol  	sigB = port(mul, \B);  	if (ffB) { -		sigB = port(ffB, \D); +		sigB.replace(port(ffB, \Q), port(ffB, \D)); +		  		SigBit c = port(ffB, \CLK).as_bit();  		bool cp = param(ffB, \CLK_POLARITY).as_bool(); -		if (clock_vld && (c != clock || cp != clock_pol)) +		if (clock != SigBit() && (c != clock || cp != clock_pol))  			reject;  		clock = c;  		clock_pol = cp; -		clock_vld = true;  	}  endcode +// Extract the bits of Y that actually have a consumer +// (as opposed to being a sign extension) +code sigY sigYused +	sigY = port(mul, \Y); +	int i; +	for (i = GetSize(sigY); i > 0; i--) +		if (nusers(sigY[i-1]) > 1) +			break; +	sigYused = sigY.extract(0, i).remove_const(); +endcode +  match ffY  	select ffY->type.in($dff)  	select nusers(port(ffY, \D)) == 2 -	index <SigSpec> port(ffY, \D) === port(mul, \Y) +	filter param(ffY, \WIDTH).as_int() >= GetSize(sigYused) +	filter includes(port(ffY, \D).to_sigbit_set(), sigYused.to_sigbit_set())  	optional  endmatch -code sigY clock clock_pol clock_vld -	sigY = port(mul, \Y); - +code clock clock_pol sigY  	if (ffY) { -		sigY = port(ffY, \Q); +		sigY.replace(port(ffY, \D), port(ffY, \Q)); +  		SigBit c = port(ffY, \CLK).as_bit();  		bool cp = param(ffY, \CLK_POLARITY).as_bool(); -		if (clock_vld && (c != clock || cp != clock_pol)) +		if (clock != SigBit() && (c != clock || cp != clock_pol))  			reject;  		clock = c;  		clock_pol = cp; -		clock_vld = true;  	}  endcode @@ -147,16 +157,15 @@ match ffS  	index <SigSpec> port(ffS, \Q) === sigS  endmatch -code clock clock_pol clock_vld +code clock clock_pol  	if (ffS) {  		SigBit c = port(ffS, \CLK).as_bit();  		bool cp = param(ffS, \CLK_POLARITY).as_bool(); -		if (clock_vld && (c != clock || cp != clock_pol)) +		if (clock != SigBit() && (c != clock || cp != clock_pol))  			reject;  		clock = c;  		clock_pol = cp; -		clock_vld = true;  	}  endcode diff --git a/passes/pmgen/xilinx_dsp.cc b/passes/pmgen/xilinx_dsp.cc index c71ac5ef8..d87d63670 100644 --- a/passes/pmgen/xilinx_dsp.cc +++ b/passes/pmgen/xilinx_dsp.cc @@ -39,7 +39,7 @@ void pack_xilinx_dsp(xilinx_dsp_pm &pm)  	log("dsp:   %s\n", log_id(st.dsp, "--"));  	log("ffP:   %s\n", log_id(st.ffP, "--"));  	log("muxP:  %s\n", log_id(st.muxP, "--")); -	log("P_used: %s\n", log_signal(st.P_used)); +	log("sigPused: %s\n", log_signal(st.sigPused));  	log_module(pm.module);  #endif diff --git a/passes/pmgen/xilinx_dsp.pmg b/passes/pmgen/xilinx_dsp.pmg index 7a175123e..a97ab4dd5 100644 --- a/passes/pmgen/xilinx_dsp.pmg +++ b/passes/pmgen/xilinx_dsp.pmg @@ -1,7 +1,7 @@  pattern xilinx_dsp  state <SigBit> clock -state <SigSpec> P_used +state <SigSpec> sigPused  match dsp  	select dsp->type.in(\DSP48E1) @@ -43,23 +43,23 @@ endcode  // Extract the bits of P that actually have a consumer  // (as opposed to being a sign extension) -code P_used +code sigPused  	SigSpec P = port(dsp, \P);  	int i;  	for (i = GetSize(P); i > 0; i--)  		if (nusers(P[i-1]) > 1)  			break; -	P_used = P.extract(0, i).remove_const(); +	sigPused = P.extract(0, i).remove_const();  endcode  match ffP -	if !P_used.empty() +	if !sigPused.empty()  	select ffP->type.in($dff, $dffe)  	select nusers(port(ffP, \D)) == 2  	// DSP48E1 does not support clock inversion  	select param(ffP, \CLK_POLARITY).as_bool() -	filter param(ffP, \WIDTH).as_int() >= GetSize(P_used) -	filter includes(port(ffP, \D).to_sigbit_set(), P_used.to_sigbit_set()) +	filter param(ffP, \WIDTH).as_int() >= GetSize(sigPused) +	filter includes(port(ffP, \D).to_sigbit_set(), sigPused.to_sigbit_set())  	optional  endmatch @@ -68,12 +68,12 @@ endmatch  //   since that would lose information helpful for  //   efficient wide-mux inference  match muxP -	if !P_used.empty() && !ffP +	if !sigPused.empty() && !ffP  	select muxP->type.in($mux)  	select nusers(port(muxP, \B)) == 2  	select port(muxP, \A).is_fully_undef() -	filter param(muxP, \WIDTH).as_int() >= GetSize(P_used) -	filter includes(port(muxP, \B).to_sigbit_set(), P_used.to_sigbit_set()) +	filter param(muxP, \WIDTH).as_int() >= GetSize(sigPused) +	filter includes(port(muxP, \B).to_sigbit_set(), sigPused.to_sigbit_set())  	optional  endmatch @@ -83,7 +83,7 @@ match ffY  	select nusers(port(ffY, \D)) == 2  	// DSP48E1 does not support clock inversion  	select param(ffY, \CLK_POLARITY).as_bool() -	filter param(ffY, \WIDTH).as_int() >= GetSize(P_used) +	filter param(ffY, \WIDTH).as_int() >= GetSize(sigPused)  	filter includes(port(ffY, \D).to_sigbit_set(), port(muxP, \Y).to_sigbit_set())  endmatch  | 
