mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 03:32:29 +00:00 
			
		
		
		
	Fine tune ice40_dsp.pmg, add support for packing subsets of registers
This commit is contained in:
		
							parent
							
								
									8f0e796be1
								
							
						
					
					
						commit
						9ad11ea2cc
					
				
					 4 changed files with 47 additions and 35 deletions
				
			
		|  | @ -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); | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
| 
 | ||||
|  |  | |||
|  | @ -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 | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue