mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 05:19:11 +00:00 
			
		
		
		
	dff2dffe: Add option for unmap to only remove DFFE with low CE signal use
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
This commit is contained in:
		
							parent
							
								
									ab97eddee9
								
							
						
					
					
						commit
						8d3ab626ea
					
				
					 1 changed files with 36 additions and 1 deletions
				
			
		| 
						 | 
					@ -263,10 +263,14 @@ struct Dff2dffePass : public Pass {
 | 
				
			||||||
		log("more feedback paths to $dffe cells. It also works on gate-level cells such as\n");
 | 
							log("more feedback paths to $dffe cells. It also works on gate-level cells such as\n");
 | 
				
			||||||
		log("$_DFF_P_, $_DFF_N_ and $_MUX_.\n");
 | 
							log("$_DFF_P_, $_DFF_N_ and $_MUX_.\n");
 | 
				
			||||||
		log("\n");
 | 
							log("\n");
 | 
				
			||||||
		log("    -unmap\n");
 | 
							log("    -unmap");
 | 
				
			||||||
		log("        operate in the opposite direction: replace $dffe cells with combinations\n");
 | 
							log("        operate in the opposite direction: replace $dffe cells with combinations\n");
 | 
				
			||||||
		log("        of $dff and $mux cells. the options below are ignore in unmap mode.\n");
 | 
							log("        of $dff and $mux cells. the options below are ignore in unmap mode.\n");
 | 
				
			||||||
		log("\n");
 | 
							log("\n");
 | 
				
			||||||
 | 
							log("    -unmap-mince N\n");
 | 
				
			||||||
 | 
							log("        Same as -unmap but only unmap $dffe where the clock enable port\n");
 | 
				
			||||||
 | 
							log("        signal is used by less $dffe than the specified number\n");
 | 
				
			||||||
 | 
							log("\n");
 | 
				
			||||||
		log("    -direct <internal_gate_type> <external_gate_type>\n");
 | 
							log("    -direct <internal_gate_type> <external_gate_type>\n");
 | 
				
			||||||
		log("        map directly to external gate type. <internal_gate_type> can\n");
 | 
							log("        map directly to external gate type. <internal_gate_type> can\n");
 | 
				
			||||||
		log("        be any internal gate-level FF cell (except $_DFFE_??_). the\n");
 | 
							log("        be any internal gate-level FF cell (except $_DFFE_??_). the\n");
 | 
				
			||||||
| 
						 | 
					@ -289,6 +293,7 @@ struct Dff2dffePass : public Pass {
 | 
				
			||||||
		log_header(design, "Executing DFF2DFFE pass (transform $dff to $dffe where applicable).\n");
 | 
							log_header(design, "Executing DFF2DFFE pass (transform $dff to $dffe where applicable).\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		bool unmap_mode = false;
 | 
							bool unmap_mode = false;
 | 
				
			||||||
 | 
							int min_ce_use = -1;
 | 
				
			||||||
		dict<IdString, IdString> direct_dict;
 | 
							dict<IdString, IdString> direct_dict;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		size_t argidx;
 | 
							size_t argidx;
 | 
				
			||||||
| 
						 | 
					@ -297,6 +302,11 @@ struct Dff2dffePass : public Pass {
 | 
				
			||||||
				unmap_mode = true;
 | 
									unmap_mode = true;
 | 
				
			||||||
				continue;
 | 
									continue;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								if (args[argidx] == "-unmap-mince" && argidx + 1 < args.size()) {
 | 
				
			||||||
 | 
									unmap_mode = true;
 | 
				
			||||||
 | 
									min_ce_use = std::stoi(args[++argidx]);
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			if (args[argidx] == "-direct" && argidx + 2 < args.size()) {
 | 
								if (args[argidx] == "-direct" && argidx + 2 < args.size()) {
 | 
				
			||||||
				string direct_from = RTLIL::escape_id(args[++argidx]);
 | 
									string direct_from = RTLIL::escape_id(args[++argidx]);
 | 
				
			||||||
				string direct_to = RTLIL::escape_id(args[++argidx]);
 | 
									string direct_to = RTLIL::escape_id(args[++argidx]);
 | 
				
			||||||
| 
						 | 
					@ -343,8 +353,21 @@ struct Dff2dffePass : public Pass {
 | 
				
			||||||
			if (!mod->has_processes_warn())
 | 
								if (!mod->has_processes_warn())
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				if (unmap_mode) {
 | 
									if (unmap_mode) {
 | 
				
			||||||
 | 
										SigMap sigmap(mod);
 | 
				
			||||||
					for (auto cell : mod->selected_cells()) {
 | 
										for (auto cell : mod->selected_cells()) {
 | 
				
			||||||
						if (cell->type == "$dffe") {
 | 
											if (cell->type == "$dffe") {
 | 
				
			||||||
 | 
												if (min_ce_use >= 0) {
 | 
				
			||||||
 | 
													int ce_use = 0;
 | 
				
			||||||
 | 
													for (auto cell_other : mod->selected_cells()) {
 | 
				
			||||||
 | 
														if (cell_other->type != cell->type)
 | 
				
			||||||
 | 
															continue;
 | 
				
			||||||
 | 
														if (sigmap(cell->getPort("\\EN")) == sigmap(cell_other->getPort("\\EN")))
 | 
				
			||||||
 | 
															ce_use++;
 | 
				
			||||||
 | 
													}
 | 
				
			||||||
 | 
													if (ce_use >= min_ce_use)
 | 
				
			||||||
 | 
														continue;
 | 
				
			||||||
 | 
												}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							RTLIL::SigSpec tmp = mod->addWire(NEW_ID, GetSize(cell->getPort("\\D")));
 | 
												RTLIL::SigSpec tmp = mod->addWire(NEW_ID, GetSize(cell->getPort("\\D")));
 | 
				
			||||||
							mod->addDff(NEW_ID, cell->getPort("\\CLK"), tmp, cell->getPort("\\Q"), cell->getParam("\\CLK_POLARITY").as_bool());
 | 
												mod->addDff(NEW_ID, cell->getPort("\\CLK"), tmp, cell->getPort("\\Q"), cell->getParam("\\CLK_POLARITY").as_bool());
 | 
				
			||||||
							if (cell->getParam("\\EN_POLARITY").as_bool())
 | 
												if (cell->getParam("\\EN_POLARITY").as_bool())
 | 
				
			||||||
| 
						 | 
					@ -355,6 +378,18 @@ struct Dff2dffePass : public Pass {
 | 
				
			||||||
							continue;
 | 
												continue;
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
						if (cell->type.substr(0, 7) == "$_DFFE_") {
 | 
											if (cell->type.substr(0, 7) == "$_DFFE_") {
 | 
				
			||||||
 | 
												if (min_ce_use >= 0) {
 | 
				
			||||||
 | 
													int ce_use = 0;
 | 
				
			||||||
 | 
													for (auto cell_other : mod->selected_cells()) {
 | 
				
			||||||
 | 
														if (cell_other->type != cell->type)
 | 
				
			||||||
 | 
															continue;
 | 
				
			||||||
 | 
														if (sigmap(cell->getPort("\\E")) == sigmap(cell_other->getPort("\\E")))
 | 
				
			||||||
 | 
															ce_use++;
 | 
				
			||||||
 | 
													}
 | 
				
			||||||
 | 
													if (ce_use >= min_ce_use)
 | 
				
			||||||
 | 
														continue;
 | 
				
			||||||
 | 
												}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							bool clk_pol = cell->type.substr(7, 1) == "P";
 | 
												bool clk_pol = cell->type.substr(7, 1) == "P";
 | 
				
			||||||
							bool en_pol = cell->type.substr(8, 1) == "P";
 | 
												bool en_pol = cell->type.substr(8, 1) == "P";
 | 
				
			||||||
							RTLIL::SigSpec tmp = mod->addWire(NEW_ID);
 | 
												RTLIL::SigSpec tmp = mod->addWire(NEW_ID);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue