mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 05:19:11 +00:00 
			
		
		
		
	Add support for CEB, remove check on nusers
This commit is contained in:
		
							parent
							
								
									0166e02e78
								
							
						
					
					
						commit
						05282afc25
					
				
					 2 changed files with 33 additions and 16 deletions
				
			
		| 
						 | 
					@ -34,6 +34,7 @@ void pack_xilinx_dsp(dict<SigBit, Cell*> &bit_to_driver, xilinx_dsp_pm &pm)
 | 
				
			||||||
	log("ffA:        %s\n", log_id(st.ffA, "--"));
 | 
						log("ffA:        %s\n", log_id(st.ffA, "--"));
 | 
				
			||||||
	log("ffAmux:     %s\n", log_id(st.ffAmux, "--"));
 | 
						log("ffAmux:     %s\n", log_id(st.ffAmux, "--"));
 | 
				
			||||||
	log("ffB:        %s\n", log_id(st.ffB, "--"));
 | 
						log("ffB:        %s\n", log_id(st.ffB, "--"));
 | 
				
			||||||
 | 
						log("ffBmux:     %s\n", log_id(st.ffBmux, "--"));
 | 
				
			||||||
	log("dsp:        %s\n", log_id(st.dsp, "--"));
 | 
						log("dsp:        %s\n", log_id(st.dsp, "--"));
 | 
				
			||||||
	log("ffM:        %s\n", log_id(st.ffM, "--"));
 | 
						log("ffM:        %s\n", log_id(st.ffM, "--"));
 | 
				
			||||||
	log("ffMmux:     %s\n", log_id(st.ffMmux, "--"));
 | 
						log("ffMmux:     %s\n", log_id(st.ffMmux, "--"));
 | 
				
			||||||
| 
						 | 
					@ -81,8 +82,6 @@ void pack_xilinx_dsp(dict<SigBit, Cell*> &bit_to_driver, xilinx_dsp_pm &pm)
 | 
				
			||||||
			SigSpec D = st.ffA->getPort("\\D");
 | 
								SigSpec D = st.ffA->getPort("\\D");
 | 
				
			||||||
			SigSpec Q = pm.sigmap(st.ffA->getPort("\\Q"));
 | 
								SigSpec Q = pm.sigmap(st.ffA->getPort("\\Q"));
 | 
				
			||||||
			A.replace(Q, D);
 | 
								A.replace(Q, D);
 | 
				
			||||||
 | 
					 | 
				
			||||||
			cell->setParam("\\AREG", 1);
 | 
					 | 
				
			||||||
			if (st.ffAmux) {
 | 
								if (st.ffAmux) {
 | 
				
			||||||
				SigSpec Y = st.ffAmux->getPort("\\Y");
 | 
									SigSpec Y = st.ffAmux->getPort("\\Y");
 | 
				
			||||||
				SigSpec AB = st.ffAmux->getPort(st.ffAmuxAB == "\\A" ? "\\B" : "\\A");
 | 
									SigSpec AB = st.ffAmux->getPort(st.ffAmuxAB == "\\A" ? "\\B" : "\\A");
 | 
				
			||||||
| 
						 | 
					@ -92,19 +91,25 @@ void pack_xilinx_dsp(dict<SigBit, Cell*> &bit_to_driver, xilinx_dsp_pm &pm)
 | 
				
			||||||
			else
 | 
								else
 | 
				
			||||||
				cell->setPort("\\CEA2", State::S1);
 | 
									cell->setPort("\\CEA2", State::S1);
 | 
				
			||||||
			cell->setPort("\\A", A);
 | 
								cell->setPort("\\A", A);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								cell->setParam("\\AREG", 1);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (st.ffB) {
 | 
							if (st.ffB) {
 | 
				
			||||||
			SigSpec B = cell->getPort("\\B");
 | 
								SigSpec B = cell->getPort("\\B");
 | 
				
			||||||
			SigSpec D = st.ffB->getPort("\\D");
 | 
								SigSpec D = st.ffB->getPort("\\D");
 | 
				
			||||||
			SigSpec Q = st.ffB->getPort("\\Q");
 | 
								SigSpec Q = st.ffB->getPort("\\Q");
 | 
				
			||||||
			B.replace(Q, D);
 | 
								B.replace(Q, D);
 | 
				
			||||||
			cell->setPort("\\B", B);
 | 
								if (st.ffBmux) {
 | 
				
			||||||
			cell->setParam("\\BREG", 1);
 | 
									SigSpec Y = st.ffBmux->getPort("\\Y");
 | 
				
			||||||
			if (st.ffB->type == "$dff")
 | 
									SigSpec AB = st.ffBmux->getPort(st.ffBmuxAB == "\\A" ? "\\B" : "\\A");
 | 
				
			||||||
 | 
									B.replace(Y, AB);
 | 
				
			||||||
 | 
									cell->setPort("\\CEB2", st.ffBmux->getPort("\\S"));
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
				cell->setPort("\\CEB2", State::S1);
 | 
									cell->setPort("\\CEB2", State::S1);
 | 
				
			||||||
			//else if (st.ffB->type == "$dffe")
 | 
								cell->setPort("\\B", B);
 | 
				
			||||||
			//	cell->setPort("\\CEB2", st.ffB->getPort("\\EN"));
 | 
					
 | 
				
			||||||
			else log_abort();
 | 
								cell->setParam("\\BREG", 1);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (st.ffM) {
 | 
							if (st.ffM) {
 | 
				
			||||||
			SigSpec D = st.ffM->getPort("\\D");
 | 
								SigSpec D = st.ffM->getPort("\\D");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,14 +1,14 @@
 | 
				
			||||||
pattern xilinx_dsp
 | 
					pattern xilinx_dsp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
state <SigBit> clock
 | 
					state <SigBit> clock
 | 
				
			||||||
state <SigSpec> sigA sigffAmux sigB sigC sigM sigP
 | 
					state <SigSpec> sigA sigffAmux sigB sigffBmux sigC sigM sigP
 | 
				
			||||||
state <IdString> ffAmuxAB ffMmuxAB postAddAB postAddMuxAB
 | 
					state <IdString> ffAmuxAB ffBmuxAB ffMmuxAB postAddAB postAddMuxAB
 | 
				
			||||||
 | 
					
 | 
				
			||||||
match dsp
 | 
					match dsp
 | 
				
			||||||
	select dsp->type.in(\DSP48E1)
 | 
						select dsp->type.in(\DSP48E1)
 | 
				
			||||||
endmatch
 | 
					endmatch
 | 
				
			||||||
 | 
					
 | 
				
			||||||
code sigA sigffAmux sigB sigM
 | 
					code sigA sigffAmux sigB sigffBmux sigM
 | 
				
			||||||
	sigA = port(dsp, \A);
 | 
						sigA = port(dsp, \A);
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	for (i = GetSize(sigA)-1; i > 0; i--)
 | 
						for (i = GetSize(sigA)-1; i > 0; i--)
 | 
				
			||||||
| 
						 | 
					@ -46,7 +46,6 @@ match ffA
 | 
				
			||||||
	select param(ffA, \CLK_POLARITY).as_bool()
 | 
						select param(ffA, \CLK_POLARITY).as_bool()
 | 
				
			||||||
	filter GetSize(port(ffA, \Q)) >= GetSize(sigA)
 | 
						filter GetSize(port(ffA, \Q)) >= GetSize(sigA)
 | 
				
			||||||
	slice offset GetSize(port(ffA, \Q))
 | 
						slice offset GetSize(port(ffA, \Q))
 | 
				
			||||||
	filter offset+GetSize(sigA) <= GetSize(port(ffA, \Q)) && nusers(port(ffA, \Q).extract(offset, GetSize(sigA))) <= 3
 | 
					 | 
				
			||||||
	filter offset+GetSize(sigA) <= GetSize(port(ffA, \Q)) && port(ffA, \Q).extract(offset, GetSize(sigA)) == sigA
 | 
						filter offset+GetSize(sigA) <= GetSize(port(ffA, \Q)) && port(ffA, \Q).extract(offset, GetSize(sigA)) == sigA
 | 
				
			||||||
	optional
 | 
						optional
 | 
				
			||||||
endmatch
 | 
					endmatch
 | 
				
			||||||
| 
						 | 
					@ -59,19 +58,19 @@ code sigA sigffAmux clock
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		clock = port(ffA, \CLK).as_bit();
 | 
							clock = port(ffA, \CLK).as_bit();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (nusers(sigA) == 3)
 | 
							sigffAmux = sigA;
 | 
				
			||||||
			sigffAmux = sigA;
 | 
					 | 
				
			||||||
		sigA.replace(port(ffA, \Q), port(ffA, \D));
 | 
							sigA.replace(port(ffA, \Q), port(ffA, \D));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
endcode
 | 
					endcode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
match ffAmux
 | 
					match ffAmux
 | 
				
			||||||
	if sigffAmux != SigSpec()
 | 
						if ffA
 | 
				
			||||||
	select ffAmux->type.in($mux)
 | 
						select ffAmux->type.in($mux)
 | 
				
			||||||
	choice <IdString> AB {\A, \B}
 | 
						choice <IdString> AB {\A, \B}
 | 
				
			||||||
	index <SigSpec> port(ffAmux, \Y) === sigA
 | 
						index <SigSpec> port(ffAmux, \Y) === sigA
 | 
				
			||||||
	index <SigSpec> port(ffAmux, AB) === sigffAmux
 | 
						index <SigSpec> port(ffAmux, AB) === sigffAmux
 | 
				
			||||||
	set ffAmuxAB AB
 | 
						set ffAmuxAB AB
 | 
				
			||||||
 | 
						semioptional
 | 
				
			||||||
endmatch
 | 
					endmatch
 | 
				
			||||||
 | 
					
 | 
				
			||||||
match ffB
 | 
					match ffB
 | 
				
			||||||
| 
						 | 
					@ -85,7 +84,7 @@ match ffB
 | 
				
			||||||
	optional
 | 
						optional
 | 
				
			||||||
endmatch
 | 
					endmatch
 | 
				
			||||||
 | 
					
 | 
				
			||||||
code clock
 | 
					code sigB sigffBmux clock
 | 
				
			||||||
	if (ffB) {
 | 
						if (ffB) {
 | 
				
			||||||
		for (auto b : port(ffB, \Q))
 | 
							for (auto b : port(ffB, \Q))
 | 
				
			||||||
			if (b.wire->get_bool_attribute(\keep))
 | 
								if (b.wire->get_bool_attribute(\keep))
 | 
				
			||||||
| 
						 | 
					@ -97,9 +96,22 @@ code clock
 | 
				
			||||||
			reject;
 | 
								reject;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		clock = c;
 | 
							clock = c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							sigffBmux = sigB;
 | 
				
			||||||
 | 
							sigB.replace(port(ffB, \Q), port(ffB, \D));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
endcode
 | 
					endcode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					match ffBmux
 | 
				
			||||||
 | 
						if ffB
 | 
				
			||||||
 | 
						select ffBmux->type.in($mux)
 | 
				
			||||||
 | 
						choice <IdString> AB {\A, \B}
 | 
				
			||||||
 | 
						index <SigSpec> port(ffBmux, \Y) === sigB
 | 
				
			||||||
 | 
						index <SigSpec> port(ffBmux, AB) === sigffBmux
 | 
				
			||||||
 | 
						set ffBmuxAB AB
 | 
				
			||||||
 | 
						semioptional
 | 
				
			||||||
 | 
					endmatch
 | 
				
			||||||
 | 
					
 | 
				
			||||||
match ffMmux
 | 
					match ffMmux
 | 
				
			||||||
	select ffMmux->type.in($mux)
 | 
						select ffMmux->type.in($mux)
 | 
				
			||||||
	select nusers(port(ffMmux, \Y)) == 2
 | 
						select nusers(port(ffMmux, \Y)) == 2
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue