mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 05:19:11 +00:00 
			
		
		
		
	Fix ffPmux to cope with offset
This commit is contained in:
		
							parent
							
								
									fbf1b74946
								
							
						
					
					
						commit
						a945f6c7ef
					
				
					 1 changed files with 35 additions and 13 deletions
				
			
		| 
						 | 
					@ -4,6 +4,7 @@ state <SigBit> clock
 | 
				
			||||||
state <SigSpec> sigA sigffAmuxY sigB sigffBmuxY sigC sigM sigP
 | 
					state <SigSpec> sigA sigffAmuxY sigB sigffBmuxY sigC sigM sigP
 | 
				
			||||||
state <IdString> postAddAB postAddMuxAB
 | 
					state <IdString> postAddAB postAddMuxAB
 | 
				
			||||||
state <bool> ffAenpol ffBenpol ffMenpol ffPenpol
 | 
					state <bool> ffAenpol ffBenpol ffMenpol ffPenpol
 | 
				
			||||||
 | 
					state <int> ffPoffset
 | 
				
			||||||
 | 
					
 | 
				
			||||||
match dsp
 | 
					match dsp
 | 
				
			||||||
	select dsp->type.in(\DSP48E1)
 | 
						select dsp->type.in(\DSP48E1)
 | 
				
			||||||
| 
						 | 
					@ -139,6 +140,8 @@ match ffBmux
 | 
				
			||||||
endmatch
 | 
					endmatch
 | 
				
			||||||
 | 
					
 | 
				
			||||||
match ffMmux
 | 
					match ffMmux
 | 
				
			||||||
 | 
						if param(dsp, \MREG).as_int() == 0
 | 
				
			||||||
 | 
						if nusers(sigM) == 2
 | 
				
			||||||
	select ffMmux->type.in($mux)
 | 
						select ffMmux->type.in($mux)
 | 
				
			||||||
	choice <IdString> BA {\B, \A}
 | 
						choice <IdString> BA {\B, \A}
 | 
				
			||||||
	// new-value net must have exactly two users: dsp and ffM
 | 
						// new-value net must have exactly two users: dsp and ffM
 | 
				
			||||||
| 
						 | 
					@ -164,6 +167,7 @@ endcode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
match ffM
 | 
					match ffM
 | 
				
			||||||
	if param(dsp, \MREG).as_int() == 0
 | 
						if param(dsp, \MREG).as_int() == 0
 | 
				
			||||||
 | 
						if nusers(sigM) == 2
 | 
				
			||||||
	select ffM->type.in($dff)
 | 
						select ffM->type.in($dff)
 | 
				
			||||||
	// DSP48E1 does not support clock inversion
 | 
						// DSP48E1 does not support clock inversion
 | 
				
			||||||
	select param(ffM, \CLK_POLARITY).as_bool()
 | 
						select param(ffM, \CLK_POLARITY).as_bool()
 | 
				
			||||||
| 
						 | 
					@ -235,31 +239,47 @@ endcode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
match ffPmux
 | 
					match ffPmux
 | 
				
			||||||
	if param(dsp, \PREG).as_int() == 0
 | 
						if param(dsp, \PREG).as_int() == 0
 | 
				
			||||||
 | 
						// new-value net must have exactly two users: dsp and ffP
 | 
				
			||||||
	if nusers(sigP) == 2
 | 
						if nusers(sigP) == 2
 | 
				
			||||||
	select ffPmux->type.in($mux)
 | 
						select ffPmux->type.in($mux)
 | 
				
			||||||
	choice <IdString> BA {\B, \A}
 | 
					 | 
				
			||||||
	// new-value net must have exactly two users: dsp and ffP
 | 
					 | 
				
			||||||
	select nusers(port(ffPmux, BA)) == 2
 | 
					 | 
				
			||||||
	define <IdString> AB (BA == \B ? \A : \B)
 | 
					 | 
				
			||||||
	// keep-last-value net must have at least three users: ffPmux, ffP, downstream sink(s)
 | 
					 | 
				
			||||||
	select nusers(port(ffPmux, AB)) >= 3
 | 
					 | 
				
			||||||
	// ffPmux output must have two users: ffPmux and ffP.D
 | 
						// ffPmux output must have two users: ffPmux and ffP.D
 | 
				
			||||||
	select nusers(port(ffPmux, \Y)) == 2
 | 
						select nusers(port(ffPmux, \Y)) == 2
 | 
				
			||||||
	filter GetSize(port(ffPmux, \Y)) <= GetSize(sigP)
 | 
						filter GetSize(port(ffPmux, \Y)) >= GetSize(sigP)
 | 
				
			||||||
	filter port(ffPmux, BA) == sigP.extract(0, GetSize(port(ffPmux, \Y)))
 | 
					
 | 
				
			||||||
	// Remaining bits on sigP must not have any other users
 | 
						choice <IdString> BA {\B, \A}
 | 
				
			||||||
	filter nusers(sigP.extract_end(GetSize(port(ffPmux, BA)))) <= 1
 | 
						slice offset GetSize(port(ffPmux, \Y))
 | 
				
			||||||
 | 
						filter offset+GetSize(sigP) <= GetSize(port(ffPmux, \Y))
 | 
				
			||||||
 | 
						filter port(ffPmux, BA).extract(offset, GetSize(sigP)) == sigP
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						define <IdString> AB (BA == \B ? \A : \B)
 | 
				
			||||||
 | 
						// keep-last-value net must have at least three users: ffPmux, ffP, downstream sink(s)
 | 
				
			||||||
 | 
						filter nusers(port(ffPmux, AB)) >= 3
 | 
				
			||||||
	define <bool> pol (BA == \B)
 | 
						define <bool> pol (BA == \B)
 | 
				
			||||||
	set ffPenpol pol
 | 
						set ffPenpol pol
 | 
				
			||||||
 | 
						set ffPoffset offset
 | 
				
			||||||
	optional
 | 
						optional
 | 
				
			||||||
endmatch
 | 
					endmatch
 | 
				
			||||||
 | 
					
 | 
				
			||||||
code sigP
 | 
					code sigP
 | 
				
			||||||
	if (ffPmux)
 | 
						if (ffPmux)
 | 
				
			||||||
		sigP.replace(port(ffPmux, ffPenpol ? \A : \B), port(ffPmux, \Y));
 | 
							sigP.replace(port(ffPmux, ffPenpol ? \B : \A), port(ffPmux, \Y));
 | 
				
			||||||
endcode
 | 
					endcode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					match ffP_enable
 | 
				
			||||||
 | 
						if ffPmux
 | 
				
			||||||
 | 
						if nusers(sigP) == 2
 | 
				
			||||||
 | 
						select ffP_enable->type.in($dff)
 | 
				
			||||||
 | 
						// DSP48E1 does not support clock inversion
 | 
				
			||||||
 | 
						select param(ffP_enable, \CLK_POLARITY).as_bool()
 | 
				
			||||||
 | 
						index <SigSpec> port(ffP_enable, \D) === port(ffPmux, \Y)
 | 
				
			||||||
 | 
						index <SigSpec> port(ffP_enable, \Q) === port(ffPmux, ffPenpol ? \A : \B)
 | 
				
			||||||
 | 
						filter GetSize(port(ffP_enable, \D)) >= GetSize(sigP)
 | 
				
			||||||
 | 
						filter ffPoffset+GetSize(sigP) <= GetSize(port(ffP_enable, \D))
 | 
				
			||||||
 | 
						filter port(ffP_enable, \D).extract(ffPoffset, GetSize(sigP)) == sigP
 | 
				
			||||||
 | 
					endmatch
 | 
				
			||||||
 | 
					
 | 
				
			||||||
match ffP
 | 
					match ffP
 | 
				
			||||||
 | 
						if !ffP_enable
 | 
				
			||||||
	if param(dsp, \PREG).as_int() == 0
 | 
						if param(dsp, \PREG).as_int() == 0
 | 
				
			||||||
	if nusers(sigP) == 2
 | 
						if nusers(sigP) == 2
 | 
				
			||||||
	select ffP->type.in($dff)
 | 
						select ffP->type.in($dff)
 | 
				
			||||||
| 
						 | 
					@ -269,12 +289,14 @@ match ffP
 | 
				
			||||||
	slice offset GetSize(port(ffP, \D))
 | 
						slice offset GetSize(port(ffP, \D))
 | 
				
			||||||
	filter offset+GetSize(sigP) <= GetSize(port(ffP, \D))
 | 
						filter offset+GetSize(sigP) <= GetSize(port(ffP, \D))
 | 
				
			||||||
	filter port(ffP, \D).extract(offset, GetSize(sigP)) == sigP
 | 
						filter port(ffP, \D).extract(offset, GetSize(sigP)) == sigP
 | 
				
			||||||
	// Check ffPmux (when present) is a $dff enable mux
 | 
					 | 
				
			||||||
	filter !ffPmux || port(ffP, \Q) == port(ffPmux, ffPenpol ? \A : \B)
 | 
					 | 
				
			||||||
	optional
 | 
						optional
 | 
				
			||||||
endmatch
 | 
					endmatch
 | 
				
			||||||
 | 
					
 | 
				
			||||||
code ffP sigP clock
 | 
					code ffP sigP clock
 | 
				
			||||||
 | 
						if (ffP_enable) {
 | 
				
			||||||
 | 
							log_assert(!ffP);
 | 
				
			||||||
 | 
							ffP = ffP_enable;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	if (ffP) {
 | 
						if (ffP) {
 | 
				
			||||||
		for (auto b : port(ffP, \Q))
 | 
							for (auto b : port(ffP, \Q))
 | 
				
			||||||
			if (b.wire->get_bool_attribute(\keep))
 | 
								if (b.wire->get_bool_attribute(\keep))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue