mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-30 19:22:31 +00:00 
			
		
		
		
	zinit: Refactor to use FfData.
This commit is contained in:
		
							parent
							
								
									63b9df8693
								
							
						
					
					
						commit
						ba0723cad7
					
				
					 1 changed files with 39 additions and 102 deletions
				
			
		|  | @ -20,10 +20,19 @@ | ||||||
| #include "kernel/yosys.h" | #include "kernel/yosys.h" | ||||||
| #include "kernel/sigtools.h" | #include "kernel/sigtools.h" | ||||||
| #include "kernel/ffinit.h" | #include "kernel/ffinit.h" | ||||||
|  | #include "kernel/ff.h" | ||||||
| 
 | 
 | ||||||
| USING_YOSYS_NAMESPACE | USING_YOSYS_NAMESPACE | ||||||
| PRIVATE_NAMESPACE_BEGIN | PRIVATE_NAMESPACE_BEGIN | ||||||
| 
 | 
 | ||||||
|  | State invert(State s) { | ||||||
|  | 	switch (s) { | ||||||
|  | 		case State::S0: return State::S1; | ||||||
|  | 		case State::S1: return State::S0; | ||||||
|  | 		default: return s; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| struct ZinitPass : public Pass { | struct ZinitPass : public Pass { | ||||||
| 	ZinitPass() : Pass("zinit", "add inverters so all FF are zero-initialized") { } | 	ZinitPass() : Pass("zinit", "add inverters so all FF are zero-initialized") { } | ||||||
| 	void help() override | 	void help() override | ||||||
|  | @ -60,123 +69,51 @@ struct ZinitPass : public Pass { | ||||||
| 			SigMap sigmap(module); | 			SigMap sigmap(module); | ||||||
| 			FfInitVals initvals(&sigmap, module); | 			FfInitVals initvals(&sigmap, module); | ||||||
| 
 | 
 | ||||||
| 			pool<IdString> dff_types = { |  | ||||||
| 								// FIXME: It would appear that supporting
 |  | ||||||
| 								//    $dffsr/$_DFFSR_* would require a new
 |  | ||||||
| 								//    cell type where S has priority over R
 |  | ||||||
| 				ID($ff), ID($dff), ID($dffe), /*ID($dffsr),*/ ID($adff), ID($adffe), |  | ||||||
| 				ID($sdff), ID($sdffe), ID($sdffce), |  | ||||||
| 				ID($_FF_), ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_), |  | ||||||
| 				/*ID($_DFFSR_NNN_), ID($_DFFSR_NNP_), ID($_DFFSR_NPN_), ID($_DFFSR_NPP_),
 |  | ||||||
| 				ID($_DFFSR_PNN_), ID($_DFFSR_PNP_), ID($_DFFSR_PPN_), ID($_DFFSR_PPP_),*/ |  | ||||||
| 				ID($_DFF_N_), ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_), |  | ||||||
| 				ID($_DFF_P_), ID($_DFF_PN0_), ID($_DFF_PN1_), ID($_DFF_PP0_), ID($_DFF_PP1_), |  | ||||||
| 				// Async set/reset
 |  | ||||||
| 				ID($_DFFE_NN0P_), ID($_DFFE_NN1P_), ID($_DFFE_NP0P_), ID($_DFFE_NP1P_), |  | ||||||
| 				ID($_DFFE_PN0P_), ID($_DFFE_PN1P_), ID($_DFFE_PP0P_), ID($_DFFE_PP1P_), |  | ||||||
| 				ID($_DFFE_NN0N_), ID($_DFFE_NN1N_), ID($_DFFE_NP0N_), ID($_DFFE_NP1N_), |  | ||||||
| 				ID($_DFFE_PN0N_), ID($_DFFE_PN1N_), ID($_DFFE_PP0N_), ID($_DFFE_PP1N_), |  | ||||||
| 				// Sync set/reset
 |  | ||||||
| 				ID($_SDFF_NN0_), ID($_SDFF_NN1_), ID($_SDFF_NP0_), ID($_SDFF_NP1_), |  | ||||||
| 				ID($_SDFF_PN0_), ID($_SDFF_PN1_), ID($_SDFF_PP0_), ID($_SDFF_PP1_), |  | ||||||
| 				ID($_SDFFE_NN0P_), ID($_SDFFE_NN1P_), ID($_SDFFE_NP0P_), ID($_SDFFE_NP1P_), |  | ||||||
| 				ID($_SDFFE_PN0P_), ID($_SDFFE_PN1P_), ID($_SDFFE_PP0P_), ID($_SDFFE_PP1P_), |  | ||||||
| 				ID($_SDFFE_NN0N_), ID($_SDFFE_NN1N_), ID($_SDFFE_NP0N_), ID($_SDFFE_NP1N_), |  | ||||||
| 				ID($_SDFFE_PN0N_), ID($_SDFFE_PN1N_), ID($_SDFFE_PP0N_), ID($_SDFFE_PP1N_), |  | ||||||
| 				ID($_SDFFCE_NN0P_), ID($_SDFFCE_NN1P_), ID($_SDFFCE_NP0P_), ID($_SDFFCE_NP1P_), |  | ||||||
| 				ID($_SDFFCE_PN0P_), ID($_SDFFCE_PN1P_), ID($_SDFFCE_PP0P_), ID($_SDFFCE_PP1P_), |  | ||||||
| 				ID($_SDFFCE_NN0N_), ID($_SDFFCE_NN1N_), ID($_SDFFCE_NP0N_), ID($_SDFFCE_NP1N_), |  | ||||||
| 				ID($_SDFFCE_PN0N_), ID($_SDFFCE_PN1N_), ID($_SDFFCE_PP0N_), ID($_SDFFCE_PP1N_) |  | ||||||
| 			}; |  | ||||||
| 
 |  | ||||||
| 			for (auto cell : module->selected_cells()) | 			for (auto cell : module->selected_cells()) | ||||||
| 			{ | 			{ | ||||||
| 				if (!dff_types.count(cell->type)) | 				if (!RTLIL::builtin_ff_cell_types().count(cell->type)) | ||||||
| 					continue; | 					continue; | ||||||
| 
 | 
 | ||||||
| 				SigSpec sig_d = sigmap(cell->getPort(ID::D)); | 				FfData ff(&initvals, cell); | ||||||
| 				SigSpec sig_q = sigmap(cell->getPort(ID::Q)); | 				if (!ff.width) | ||||||
| 
 |  | ||||||
| 				if (GetSize(sig_d) < 1 || GetSize(sig_q) < 1) |  | ||||||
| 					continue; | 					continue; | ||||||
| 
 | 
 | ||||||
| 				Const initval = initvals(sig_q); | 				// Supporting those would require a new cell type where S has priority over R.
 | ||||||
| 				Const newval = initval; | 				if (ff.has_sr) | ||||||
| 				initvals.remove_init(sig_q); | 					continue; | ||||||
| 
 | 
 | ||||||
| 				Wire *initwire = module->addWire(NEW_ID, GetSize(sig_q)); | 				Wire *new_q = module->addWire(NEW_ID, ff.width); | ||||||
| 
 | 
 | ||||||
| 				for (int i = 0; i < GetSize(initwire); i++) | 				log("FF init value for cell %s (%s): %s = %s\n", log_id(cell), log_id(cell->type), | ||||||
| 					if (initval[i] == State::S1) | 						log_signal(ff.sig_q), log_signal(ff.val_init)); | ||||||
|  | 
 | ||||||
|  | 				IdString name = cell->name; | ||||||
|  | 				module->remove(cell); | ||||||
|  | 				initvals.remove_init(ff.sig_q); | ||||||
|  | 
 | ||||||
|  | 				for (int i = 0; i < ff.width; i++) | ||||||
|  | 					if (ff.val_init[i] == State::S1) | ||||||
| 					{ | 					{ | ||||||
| 						sig_d[i] = module->NotGate(NEW_ID, sig_d[i]); | 						if (ff.has_clk || ff.has_gclk) | ||||||
| 						module->addNotGate(NEW_ID, SigSpec(initwire, i), sig_q[i]); | 							ff.sig_d[i] = module->NotGate(NEW_ID, ff.sig_d[i]); | ||||||
| 						newval[i] = State::S0; | 						if (ff.has_aload) | ||||||
|  | 							ff.sig_ad[i] = module->NotGate(NEW_ID, ff.sig_ad[i]); | ||||||
|  | 						if (ff.has_arst) | ||||||
|  | 							ff.val_arst[i] = invert(ff.val_arst[i]); | ||||||
|  | 						if (ff.has_srst) | ||||||
|  | 							ff.val_srst[i] = invert(ff.val_srst[i]); | ||||||
|  | 						module->addNotGate(NEW_ID, SigSpec(new_q, i), ff.sig_q[i]); | ||||||
|  | 						ff.val_init[i] = State::S0; | ||||||
| 					} | 					} | ||||||
| 					else | 					else | ||||||
| 					{ | 					{ | ||||||
| 						module->connect(sig_q[i], SigSpec(initwire, i)); | 						module->connect(ff.sig_q[i], SigSpec(new_q, i)); | ||||||
| 						if (all_mode) | 						if (all_mode) | ||||||
| 							newval[i] = State::S0; | 							ff.val_init[i] = State::S0; | ||||||
| 					} | 					} | ||||||
| 
 | 
 | ||||||
| 				initvals.set_init(initwire, newval); | 				ff.sig_q = new_q; | ||||||
| 
 | 				ff.emit(module, name); | ||||||
| 				log("FF init value for cell %s (%s): %s = %s\n", log_id(cell), log_id(cell->type), |  | ||||||
| 						log_signal(sig_q), log_signal(initval)); |  | ||||||
| 
 |  | ||||||
| 				cell->setPort(ID::D, sig_d); |  | ||||||
| 				cell->setPort(ID::Q, initwire); |  | ||||||
| 
 |  | ||||||
| 				if (cell->type.in(ID($adff), ID($adffe))) { |  | ||||||
| 					auto val = cell->getParam(ID::ARST_VALUE); |  | ||||||
| 					for (int i = 0; i < GetSize(initwire); i++) |  | ||||||
| 						if (initval[i] == State::S1) |  | ||||||
| 							val[i] = (val[i] == State::S1 ? State::S0 : State::S1); |  | ||||||
| 					cell->setParam(ID::ARST_VALUE, std::move(val)); |  | ||||||
| 				} |  | ||||||
| 				else if (cell->type.in(ID($sdff), ID($sdffe), ID($sdffce))) { |  | ||||||
| 					auto val = cell->getParam(ID::SRST_VALUE); |  | ||||||
| 					for (int i = 0; i < GetSize(initwire); i++) |  | ||||||
| 						if (initval[i] == State::S1) |  | ||||||
| 							val[i] = (val[i] == State::S1 ? State::S0 : State::S1); |  | ||||||
| 					cell->setParam(ID::SRST_VALUE, std::move(val)); |  | ||||||
| 				} |  | ||||||
| 				else if (initval == State::S1) { |  | ||||||
| 					std::string t = cell->type.str(); |  | ||||||
| 					if (cell->type.in(ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_), |  | ||||||
| 								ID($_DFF_PN0_), ID($_DFF_PN1_), ID($_DFF_PP0_), ID($_DFF_PP1_))) |  | ||||||
| 					{ |  | ||||||
| 						t[8] = (t[8] == '0' ? '1' : '0'); |  | ||||||
| 					} |  | ||||||
| 					else if (cell->type.in(ID($_SDFF_NN0_), ID($_SDFF_NN1_), ID($_SDFF_NP0_), ID($_SDFF_NP1_), |  | ||||||
| 								ID($_SDFF_PN0_), ID($_SDFF_PN1_), ID($_SDFF_PP0_), ID($_SDFF_PP1_))) |  | ||||||
| 					{ |  | ||||||
| 						t[9] = (t[9] == '0' ? '1' : '0'); |  | ||||||
| 					} |  | ||||||
| 					else if (cell->type.in(ID($_DFFE_NN0P_), ID($_DFFE_NN1P_), ID($_DFFE_NP0P_), ID($_DFFE_NP1P_), |  | ||||||
| 								ID($_DFFE_PN0P_), ID($_DFFE_PN1P_), ID($_DFFE_PP0P_), ID($_DFFE_PP1P_), |  | ||||||
| 								ID($_DFFE_NN0N_), ID($_DFFE_NN1N_), ID($_DFFE_NP0N_), ID($_DFFE_NP1N_), |  | ||||||
| 								ID($_DFFE_PN0N_), ID($_DFFE_PN1N_), ID($_DFFE_PP0N_), ID($_DFFE_PP1N_))) |  | ||||||
| 					{ |  | ||||||
| 						t[9] = (t[9] == '0' ? '1' : '0'); |  | ||||||
| 					} |  | ||||||
| 					else if (cell->type.in(ID($_SDFFE_NN0P_), ID($_SDFFE_NN1P_), ID($_SDFFE_NP0P_), ID($_SDFFE_NP1P_), |  | ||||||
| 								ID($_SDFFE_PN0P_), ID($_SDFFE_PN1P_), ID($_SDFFE_PP0P_), ID($_SDFFE_PP1P_), |  | ||||||
| 								ID($_SDFFE_NN0N_), ID($_SDFFE_NN1N_), ID($_SDFFE_NP0N_), ID($_SDFFE_NP1N_), |  | ||||||
| 								ID($_SDFFE_PN0N_), ID($_SDFFE_PN1N_), ID($_SDFFE_PP0N_), ID($_SDFFE_PP1N_))) |  | ||||||
| 					{ |  | ||||||
| 						t[10] = (t[10] == '0' ? '1' : '0'); |  | ||||||
| 					} |  | ||||||
| 					else if (cell->type.in(ID($_SDFFCE_NN0P_), ID($_SDFFCE_NN1P_), ID($_SDFFCE_NP0P_), ID($_SDFFCE_NP1P_), |  | ||||||
| 								ID($_SDFFCE_PN0P_), ID($_SDFFCE_PN1P_), ID($_SDFFCE_PP0P_), ID($_SDFFCE_PP1P_), |  | ||||||
| 								ID($_SDFFCE_NN0N_), ID($_SDFFCE_NN1N_), ID($_SDFFCE_NP0N_), ID($_SDFFCE_NP1N_), |  | ||||||
| 								ID($_SDFFCE_PN0N_), ID($_SDFFCE_PN1N_), ID($_SDFFCE_PP0N_), ID($_SDFFCE_PP1N_))) |  | ||||||
| 					{ |  | ||||||
| 						t[11] = (t[11] == '0' ? '1' : '0'); |  | ||||||
| 					} |  | ||||||
| 					cell->type = t; |  | ||||||
| 				} |  | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue