mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 13:29:12 +00:00 
			
		
		
		
	Add support for A1 and B1 registers
This commit is contained in:
		
							parent
							
								
									4369fc17d0
								
							
						
					
					
						commit
						f3081c20e7
					
				
					 2 changed files with 105 additions and 24 deletions
				
			
		| 
						 | 
					@ -259,7 +259,9 @@ void pack_xilinx_dsp(dict<SigBit, Cell*> &bit_to_driver, xilinx_dsp_pm &pm)
 | 
				
			||||||
	log("preAdd:     %s\n", log_id(st.preAdd, "--"));
 | 
						log("preAdd:     %s\n", log_id(st.preAdd, "--"));
 | 
				
			||||||
	log("ffAD:       %s %s %s\n", log_id(st.ffAD, "--"), log_id(st.ffADcemux, "--"), log_id(st.ffADrstmux, "--"));
 | 
						log("ffAD:       %s %s %s\n", log_id(st.ffAD, "--"), log_id(st.ffADcemux, "--"), log_id(st.ffADrstmux, "--"));
 | 
				
			||||||
	log("ffA2:       %s %s %s\n", log_id(st.ffA2, "--"), log_id(st.ffA2cemux, "--"), log_id(st.ffA2rstmux, "--"));
 | 
						log("ffA2:       %s %s %s\n", log_id(st.ffA2, "--"), log_id(st.ffA2cemux, "--"), log_id(st.ffA2rstmux, "--"));
 | 
				
			||||||
 | 
						log("ffA1:       %s %s %s\n", log_id(st.ffA1, "--"), log_id(st.ffA1cemux, "--"), log_id(st.ffA1rstmux, "--"));
 | 
				
			||||||
	log("ffB2:       %s %s %s\n", log_id(st.ffB2, "--"), log_id(st.ffB2cemux, "--"), log_id(st.ffB2rstmux, "--"));
 | 
						log("ffB2:       %s %s %s\n", log_id(st.ffB2, "--"), log_id(st.ffB2cemux, "--"), log_id(st.ffB2rstmux, "--"));
 | 
				
			||||||
 | 
						log("ffB1:       %s %s %s\n", log_id(st.ffB1, "--"), log_id(st.ffB1cemux, "--"), log_id(st.ffB1rstmux, "--"));
 | 
				
			||||||
	log("ffC:        %s %s %s\n", log_id(st.ffC, "--"), log_id(st.ffCcemux, "--"), log_id(st.ffCrstmux, "--"));
 | 
						log("ffC:        %s %s %s\n", log_id(st.ffC, "--"), log_id(st.ffCcemux, "--"), log_id(st.ffCrstmux, "--"));
 | 
				
			||||||
	log("ffD:        %s %s %s\n", log_id(st.ffD, "--"), log_id(st.ffDcemux, "--"), log_id(st.ffDrstmux, "--"));
 | 
						log("ffD:        %s %s %s\n", log_id(st.ffD, "--"), log_id(st.ffDcemux, "--"), log_id(st.ffDrstmux, "--"));
 | 
				
			||||||
	log("dsp:        %s\n", log_id(st.dsp, "--"));
 | 
						log("dsp:        %s\n", log_id(st.dsp, "--"));
 | 
				
			||||||
| 
						 | 
					@ -338,12 +340,14 @@ void pack_xilinx_dsp(dict<SigBit, Cell*> &bit_to_driver, xilinx_dsp_pm &pm)
 | 
				
			||||||
			if (rstmux) {
 | 
								if (rstmux) {
 | 
				
			||||||
				SigSpec Y = rstmux->getPort("\\Y");
 | 
									SigSpec Y = rstmux->getPort("\\Y");
 | 
				
			||||||
				SigSpec AB = rstmux->getPort(rstpol ? "\\A" : "\\B");
 | 
									SigSpec AB = rstmux->getPort(rstpol ? "\\A" : "\\B");
 | 
				
			||||||
				SigSpec S = rstmux->getPort("\\S");
 | 
					 | 
				
			||||||
				if (!A.empty())
 | 
									if (!A.empty())
 | 
				
			||||||
					A.replace(Y, AB);
 | 
										A.replace(Y, AB);
 | 
				
			||||||
				cell->setPort(rstport, rstpol ? S : pm.module->Not(NEW_ID, S));
 | 
									if (rstport != IdString()) {
 | 
				
			||||||
 | 
										SigSpec S = rstmux->getPort("\\S");
 | 
				
			||||||
 | 
										cell->setPort(rstport, rstpol ? S : pm.module->Not(NEW_ID, S));
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			else
 | 
								else if (rstport != IdString())
 | 
				
			||||||
				cell->setPort(rstport, State::S0);
 | 
									cell->setPort(rstport, State::S0);
 | 
				
			||||||
			if (cemux) {
 | 
								if (cemux) {
 | 
				
			||||||
				SigSpec Y = cemux->getPort("\\Y");
 | 
									SigSpec Y = cemux->getPort("\\Y");
 | 
				
			||||||
| 
						 | 
					@ -368,16 +372,26 @@ void pack_xilinx_dsp(dict<SigBit, Cell*> &bit_to_driver, xilinx_dsp_pm &pm)
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (st.ffA2) {
 | 
							if (st.ffA2) {
 | 
				
			||||||
			SigSpec &A2 = cell->connections_.at("\\A");
 | 
								SigSpec &A = cell->connections_.at("\\A");
 | 
				
			||||||
			f(A2, st.ffA2, st.ffA2cemux, st.ffA2cepol, "\\CEA2", st.ffA2rstmux, st.ffArstpol, "\\RSTA");
 | 
								f(A, st.ffA2, st.ffA2cemux, st.ffA2cepol, "\\CEA2", st.ffA2rstmux, st.ffArstpol, "\\RSTA");
 | 
				
			||||||
			pm.add_siguser(A2, cell);
 | 
								pm.add_siguser(A, cell);
 | 
				
			||||||
			cell->setParam("\\AREG", 1);
 | 
								if (st.ffA1) {
 | 
				
			||||||
 | 
									f(A, st.ffA1, st.ffA1cemux, st.ffA1cepol, "\\CEA1", st.ffA1rstmux, st.ffArstpol, IdString());
 | 
				
			||||||
 | 
									cell->setParam("\\AREG", 2);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									cell->setParam("\\AREG", 1);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (st.ffB2) {
 | 
							if (st.ffB2) {
 | 
				
			||||||
			SigSpec &B2 = cell->connections_.at("\\B");
 | 
								SigSpec &B = cell->connections_.at("\\B");
 | 
				
			||||||
			f(B2, st.ffB2, st.ffB2cemux, st.ffB2cepol, "\\CEB2", st.ffB2rstmux, st.ffBrstpol, "\\RSTB");
 | 
								f(B, st.ffB2, st.ffB2cemux, st.ffB2cepol, "\\CEB2", st.ffB2rstmux, st.ffBrstpol, "\\RSTB");
 | 
				
			||||||
			pm.add_siguser(B2, cell);
 | 
								pm.add_siguser(B, cell);
 | 
				
			||||||
			cell->setParam("\\BREG", 1);
 | 
								if (st.ffB1) {
 | 
				
			||||||
 | 
									f(B, st.ffB1, st.ffB1cemux, st.ffB1cepol, "\\CEB1", st.ffB1rstmux, st.ffBrstpol, IdString());
 | 
				
			||||||
 | 
									cell->setParam("\\BREG", 2);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									cell->setParam("\\BREG", 1);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (st.ffC) {
 | 
							if (st.ffC) {
 | 
				
			||||||
			SigSpec &C = cell->connections_.at("\\C");
 | 
								SigSpec &C = cell->connections_.at("\\C");
 | 
				
			||||||
| 
						 | 
					@ -406,14 +420,20 @@ void pack_xilinx_dsp(dict<SigBit, Cell*> &bit_to_driver, xilinx_dsp_pm &pm)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		log("  clock: %s (%s)", log_signal(st.clock), "posedge");
 | 
							log("  clock: %s (%s)", log_signal(st.clock), "posedge");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (st.ffA2)
 | 
							if (st.ffA2) {
 | 
				
			||||||
			log(" ffA2:%s", log_id(st.ffA2));
 | 
								log(" ffA2:%s", log_id(st.ffA2));
 | 
				
			||||||
 | 
								if (st.ffA1)
 | 
				
			||||||
 | 
									log(" ffA1:%s", log_id(st.ffA1));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (st.ffAD)
 | 
							if (st.ffAD)
 | 
				
			||||||
			log(" ffAD:%s", log_id(st.ffAD));
 | 
								log(" ffAD:%s", log_id(st.ffAD));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (st.ffB2)
 | 
							if (st.ffB2) {
 | 
				
			||||||
			log(" ffB2:%s", log_id(st.ffB2));
 | 
								log(" ffB2:%s", log_id(st.ffB2));
 | 
				
			||||||
 | 
								if (st.ffB1)
 | 
				
			||||||
 | 
									log(" ffB1:%s", log_id(st.ffB1));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (st.ffC)
 | 
							if (st.ffC)
 | 
				
			||||||
			log(" ffC:%s", log_id(st.ffC));
 | 
								log(" ffC:%s", log_id(st.ffC));
 | 
				
			||||||
| 
						 | 
					@ -449,17 +469,18 @@ struct XilinxDspPass : public Pass {
 | 
				
			||||||
		log("\n");
 | 
							log("\n");
 | 
				
			||||||
		log("    xilinx_dsp [options] [selection]\n");
 | 
							log("    xilinx_dsp [options] [selection]\n");
 | 
				
			||||||
		log("\n");
 | 
							log("\n");
 | 
				
			||||||
		log("Pack input registers (A, B, C, D, AD; with optional enable/reset), pipeline\n");
 | 
							log("Pack input registers (A2, A1, B2, B1, C, D, AD; with optional enable/reset),\n");
 | 
				
			||||||
		log("registers (M; with optional enable/reset), output registers (P; with optional\n");
 | 
							log("pipeline registers (M; with optional enable/reset), output registers (P; with\n");
 | 
				
			||||||
		log("enable/reset), pre-adder and/or post-adder into Xilinx DSP resources.\n");
 | 
							log("optional enable/reset), pre-adder and/or post-adder into Xilinx DSP resources.\n");
 | 
				
			||||||
		log("\n");
 | 
							log("\n");
 | 
				
			||||||
		log("Multiply-accumulate operations using the post-adder with feedback on the 'C'\n");
 | 
							log("Multiply-accumulate operations using the post-adder with feedback on the 'C'\n");
 | 
				
			||||||
		log("input will be folded into the DSP. In this scenario only, the 'C' input can be\n");
 | 
							log("input will be folded into the DSP. In this scenario only, the 'C' input can be\n");
 | 
				
			||||||
		log("used to override the existing accumulation result with a new value.\n");
 | 
							log("used to override the existing accumulation result with a new value.\n");
 | 
				
			||||||
		log("\n");
 | 
							log("\n");
 | 
				
			||||||
		log("Use of the dedicated 'PCOUT' -> 'PCIN' path is detected for 'P' -> 'C' connections\n");
 | 
							log("Use of the dedicated 'PCOUT' -> 'PCIN' cascade path is detected for 'P' -> 'C'\n");
 | 
				
			||||||
		log("where 'P' is right-shifted by 18-bits and used as an input to the post-adder (a\n");
 | 
							log("connections (optionally, where 'P' is right-shifted by 18-bits and used as an\n");
 | 
				
			||||||
		log("pattern common for summing partial products to implement wide multiplies).\n");
 | 
							log("input to the post-adder -- a pattern common for summing partial products to\n");
 | 
				
			||||||
 | 
							log("implement wide multipliers).\n");
 | 
				
			||||||
		log("\n");
 | 
							log("\n");
 | 
				
			||||||
		log("\n");
 | 
							log("\n");
 | 
				
			||||||
		log("Experimental feature: addition/subtractions less than 12 or 24 bits with the\n");
 | 
							log("Experimental feature: addition/subtractions less than 12 or 24 bits with the\n");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -104,9 +104,9 @@ code sigA sigD
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
endcode
 | 
					endcode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
code argQ ffAD ffADcemux ffADrstmux ffADcepol ffADrstpol sigA clock ffA2 ffA2cemux ffA2rstmux ffA2cepol ffArstpol
 | 
					code argQ ffAD ffADcemux ffADrstmux ffADcepol ffADrstpol sigA clock ffA2 ffA2cemux ffA2rstmux ffA2cepol ffArstpol ffA1 ffA1cemux ffA1rstmux ffA1cepol
 | 
				
			||||||
	// Only search for ffA2 if there was a pre-adder
 | 
						// Only search for ffA2 if there was a pre-adder
 | 
				
			||||||
	//   (otherwise ffA2 would have been matched as ffA2)
 | 
						//   (otherwise ffA2 would have been matched as ffAD)
 | 
				
			||||||
	if (preAdd) {
 | 
						if (preAdd) {
 | 
				
			||||||
		if (param(dsp, \AREG).as_int() == 0) {
 | 
							if (param(dsp, \AREG).as_int() == 0) {
 | 
				
			||||||
			argQ = sigA;
 | 
								argQ = sigA;
 | 
				
			||||||
| 
						 | 
					@ -114,11 +114,13 @@ code argQ ffAD ffADcemux ffADrstmux ffADcepol ffADrstpol sigA clock ffA2 ffA2cem
 | 
				
			||||||
			if (dff) {
 | 
								if (dff) {
 | 
				
			||||||
				ffA2 = dff;
 | 
									ffA2 = dff;
 | 
				
			||||||
				clock = dffclock;
 | 
									clock = dffclock;
 | 
				
			||||||
 | 
									if (dffrstmux) {
 | 
				
			||||||
 | 
										ffA2cepol = dffcepol;
 | 
				
			||||||
 | 
										ffArstpol = dffrstpol;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
				if (dffcemux) {
 | 
									if (dffcemux) {
 | 
				
			||||||
					ffA2cemux = dffcemux;
 | 
										ffA2cemux = dffcemux;
 | 
				
			||||||
					ffA2rstmux = dffrstmux;
 | 
										ffA2rstmux = dffrstmux;
 | 
				
			||||||
					ffA2cepol = dffcepol;
 | 
					 | 
				
			||||||
					ffArstpol = dffrstpol;
 | 
					 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				sigA = dffD;
 | 
									sigA = dffD;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
| 
						 | 
					@ -134,9 +136,37 @@ code argQ ffAD ffADcemux ffADrstmux ffADcepol ffADrstpol sigA clock ffA2 ffA2cem
 | 
				
			||||||
		ffA2cepol = ffADcepol;
 | 
							ffA2cepol = ffADcepol;
 | 
				
			||||||
		ffArstpol = ffADrstpol;
 | 
							ffArstpol = ffADrstpol;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Now attempt to match A1
 | 
				
			||||||
 | 
						if (ffA2) {
 | 
				
			||||||
 | 
							argQ = sigA;
 | 
				
			||||||
 | 
							subpattern(in_dffe);
 | 
				
			||||||
 | 
							if (dff) {
 | 
				
			||||||
 | 
								if ((ffA2rstmux != nullptr) ^ (dffrstmux != nullptr))
 | 
				
			||||||
 | 
									goto ffA1_end;
 | 
				
			||||||
 | 
								if (dffrstmux) {
 | 
				
			||||||
 | 
									if (ffArstpol != dffrstpol)
 | 
				
			||||||
 | 
										goto ffA1_end;
 | 
				
			||||||
 | 
									if (port(ffA2rstmux, \S) != port(dffrstmux, \S))
 | 
				
			||||||
 | 
										goto ffA1_end;
 | 
				
			||||||
 | 
									ffA1rstmux = dffrstmux;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								ffA1 = dff;
 | 
				
			||||||
 | 
								clock = dffclock;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (dffcemux) {
 | 
				
			||||||
 | 
									ffA1cemux = dffcemux;
 | 
				
			||||||
 | 
									ffA1cepol = dffcepol;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								sigA = dffD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ffA1_end:		;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
endcode
 | 
					endcode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
code argQ ffB2 ffB2cemux ffB2rstmux ffB2cepol ffBrstpol sigB clock
 | 
					code argQ ffB2 ffB2cemux ffB2rstmux ffB2cepol ffBrstpol sigB clock ffB1 ffB1cemux ffB1rstmux ffB1cepol
 | 
				
			||||||
	if (param(dsp, \BREG).as_int() == 0) {
 | 
						if (param(dsp, \BREG).as_int() == 0) {
 | 
				
			||||||
		argQ = sigB;
 | 
							argQ = sigB;
 | 
				
			||||||
		subpattern(in_dffe);
 | 
							subpattern(in_dffe);
 | 
				
			||||||
| 
						 | 
					@ -150,6 +180,35 @@ code argQ ffB2 ffB2cemux ffB2rstmux ffB2cepol ffBrstpol sigB clock
 | 
				
			||||||
				ffBrstpol = dffrstpol;
 | 
									ffBrstpol = dffrstpol;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			sigB = dffD;
 | 
								sigB = dffD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Now attempt to match B1
 | 
				
			||||||
 | 
								if (ffB2) {
 | 
				
			||||||
 | 
									argQ = sigB;
 | 
				
			||||||
 | 
									subpattern(in_dffe);
 | 
				
			||||||
 | 
									if (dff) {
 | 
				
			||||||
 | 
										if ((ffB2rstmux != nullptr) ^ (dffrstmux != nullptr))
 | 
				
			||||||
 | 
											goto ffB1_end;
 | 
				
			||||||
 | 
										if (dffrstmux) {
 | 
				
			||||||
 | 
											if (ffBrstpol != dffrstpol)
 | 
				
			||||||
 | 
												goto ffB1_end;
 | 
				
			||||||
 | 
											if (port(ffB2rstmux, \S) != port(dffrstmux, \S))
 | 
				
			||||||
 | 
												goto ffB1_end;
 | 
				
			||||||
 | 
											ffB1rstmux = dffrstmux;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										ffB1 = dff;
 | 
				
			||||||
 | 
										clock = dffclock;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										if (dffcemux) {
 | 
				
			||||||
 | 
											ffB1cemux = dffcemux;
 | 
				
			||||||
 | 
											ffB1cepol = dffcepol;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										sigB = dffD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ffB1_end:				;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
endcode
 | 
					endcode
 | 
				
			||||||
| 
						 | 
					@ -387,6 +446,7 @@ code argD
 | 
				
			||||||
	if (ffcemux) {
 | 
						if (ffcemux) {
 | 
				
			||||||
		dffcemux = ffcemux;
 | 
							dffcemux = ffcemux;
 | 
				
			||||||
		dffcepol = ffcepol;
 | 
							dffcepol = ffcepol;
 | 
				
			||||||
 | 
							argD = port(ffcemux, ffcepol ? \B : \A);
 | 
				
			||||||
		dffD.replace(port(ffcemux, \Y), argD);
 | 
							dffD.replace(port(ffcemux, \Y), argD);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue