mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 11:42:30 +00:00 
			
		
		
		
	Improve pattern matcher to match subsets of $dffe? cells
This commit is contained in:
		
							parent
							
								
									79d63479ea
								
							
						
					
					
						commit
						08fe63c61e
					
				
					 2 changed files with 22 additions and 12 deletions
				
			
		|  | @ -39,7 +39,8 @@ 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_WIDTH:  %d\n", st.P_WIDTH); | ||||
| 	log("P_used: %s\n", log_signal(st.P_used)); | ||||
| 	log_module(pm.module); | ||||
| #endif | ||||
| 
 | ||||
| 	log("Analysing %s.%s for Xilinx DSP register packing.\n", log_id(pm.module), log_id(st.dsp)); | ||||
|  | @ -79,8 +80,13 @@ void pack_xilinx_dsp(xilinx_dsp_pm &pm) | |||
| 		} | ||||
| 		if (st.ffP) { | ||||
| 			SigSpec P = cell->getPort("\\P"); | ||||
| 			SigSpec D; | ||||
| 			if (st.muxP) | ||||
| 				D = st.muxP->getPort("\\B"); | ||||
| 			else | ||||
| 				D = st.ffP->getPort("\\D"); | ||||
| 			SigSpec Q = st.ffP->getPort("\\Q"); | ||||
| 			P.replace(Q, P.extract(0, GetSize(Q))); | ||||
| 			P.replace(D, Q); | ||||
| 			cell->setPort("\\P", Q); | ||||
| 			cell->setParam("\\PREG", State::S1); | ||||
| 			if (st.ffP->type == "$dff") | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| pattern xilinx_dsp | ||||
| 
 | ||||
| state <SigBit> clock | ||||
| state <int> P_WIDTH | ||||
| state <SigSpec> P_used | ||||
| 
 | ||||
| match dsp | ||||
| 	select dsp->type.in(\DSP48E1) | ||||
|  | @ -39,22 +39,25 @@ code clock | |||
| 	} | ||||
| endcode | ||||
| 
 | ||||
| code P_WIDTH | ||||
| // Extract the bits of P that actually have a consumer | ||||
| // (as opposed to being a sign extension) | ||||
| code P_used | ||||
| 	SigSpec P = port(dsp, \P); | ||||
| 	int i; | ||||
| 	for (i = GetSize(P); i > 0; i--) | ||||
| 		if (nusers(P[i-1]) > 1) | ||||
| 			break; | ||||
| 	P_WIDTH = i; | ||||
| 	P_used = P.extract(0, i).remove_const(); | ||||
| endcode | ||||
| 
 | ||||
| match ffP | ||||
| 	if !P_used.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() == P_WIDTH | ||||
| 	filter port(ffP, \D) == port(dsp, \P).extract(0, P_WIDTH) | ||||
| 	filter param(ffP, \WIDTH).as_int() >= GetSize(P_used) | ||||
| 	filter includes(port(ffP, \D).to_sigbit_set(), P_used.to_sigbit_set()) | ||||
| 	optional | ||||
| endmatch | ||||
| 
 | ||||
|  | @ -63,12 +66,12 @@ endmatch | |||
| //   since that would lose information helpful for | ||||
| //   efficient wide-mux inference | ||||
| match muxP | ||||
| 	if !ffP | ||||
| 	if !P_used.empty() && !ffP | ||||
| 	select muxP->type.in($mux) | ||||
| 	select port(muxP, \A).is_fully_undef() | ||||
| 	filter param(muxP, \WIDTH).as_int() == P_WIDTH | ||||
| 	filter port(muxP, \B) == port(dsp, \P).extract(0, P_WIDTH) | ||||
| 	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()) | ||||
| 	optional | ||||
| endmatch | ||||
| 
 | ||||
|  | @ -78,7 +81,8 @@ match ffY | |||
| 	select nusers(port(ffY, \D)) == 2 | ||||
| 	// DSP48E1 does not support clock inversion | ||||
| 	select param(ffY, \CLK_POLARITY).as_bool() | ||||
| 	index <SigSpec> port(ffY, \D) === port(muxP, \Y) | ||||
| 	filter param(ffY, \WIDTH).as_int() >= GetSize(P_used) | ||||
| 	filter includes(port(ffY, \D).to_sigbit_set(), port(muxP, \Y).to_sigbit_set()) | ||||
| endmatch | ||||
| 
 | ||||
| code ffP clock | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue