mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-30 19:22:31 +00:00 
			
		
		
		
	Added "abc -luts" option, Improved Xilinx logic mapping
This commit is contained in:
		
							parent
							
								
									9251553592
								
							
						
					
					
						commit
						17372d8abd
					
				
					 2 changed files with 39 additions and 15 deletions
				
			
		|  | @ -592,7 +592,7 @@ struct abc_output_filter | |||
| }; | ||||
| 
 | ||||
| void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::string script_file, std::string exe_file, | ||||
| 		std::string liberty_file, std::string constr_file, bool cleanup, int lut_mode, int lut_mode2, bool dff_mode, std::string clk_str, | ||||
| 		std::string liberty_file, std::string constr_file, bool cleanup, vector<int> lut_costs, bool dff_mode, std::string clk_str, | ||||
| 		bool keepff, std::string delay_target, bool fast_mode, const std::vector<RTLIL::Cell*> &cells, bool show_tempdir) | ||||
| { | ||||
| 	module = current_module; | ||||
|  | @ -626,7 +626,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin | |||
| 		if (!constr_file.empty()) | ||||
| 			abc_script += stringf("read_constr -v %s; ", constr_file.c_str()); | ||||
| 	} else | ||||
| 	if (lut_mode) | ||||
| 	if (!lut_costs.empty()) | ||||
| 		abc_script += stringf("read_lut %s/lutdefs.txt; ", tempdir_name.c_str()); | ||||
| 	else | ||||
| 		abc_script += stringf("read_library %s/stdcells.genlib; ", tempdir_name.c_str()); | ||||
|  | @ -642,7 +642,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin | |||
| 					abc_script += script_file[i]; | ||||
| 		} else | ||||
| 			abc_script += stringf("source %s", script_file.c_str()); | ||||
| 	} else if (lut_mode) | ||||
| 	} else if (!lut_costs.empty()) | ||||
| 		abc_script += fast_mode ? ABC_FAST_COMMAND_LUT : ABC_COMMAND_LUT; | ||||
| 	else if (!liberty_file.empty()) | ||||
| 		abc_script += constr_file.empty() ? (fast_mode ? ABC_FAST_COMMAND_LIB : ABC_COMMAND_LIB) : (fast_mode ? ABC_FAST_COMMAND_CTR : ABC_COMMAND_CTR); | ||||
|  | @ -868,15 +868,13 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin | |||
| 			fprintf(f, "GATE MUX16 %d Y=(!S*!T*!U*!V*A)+(S*!T*!U*!V*B)+(!S*T*!U*!V*C)+(S*T*!U*!V*D)+(!S*!T*U*!V*E)+(S*!T*U*!V*F)+(!S*T*U*!V*G)+(S*T*U*!V*H)+(!S*!T*!U*V*I)+(S*!T*!U*V*J)+(!S*T*!U*V*K)+(S*T*!U*V*L)+(!S*!T*U*V*M)+(S*!T*U*V*N)+(!S*T*U*V*O)+(S*T*U*V*P); PIN * UNKNOWN 1 999 1 0 1 0\n", 8*get_cell_cost("$_MUX_")); | ||||
| 		fclose(f); | ||||
| 
 | ||||
| 		if (lut_mode) { | ||||
| 		if (!lut_costs.empty()) { | ||||
| 			buffer = stringf("%s/lutdefs.txt", tempdir_name.c_str()); | ||||
| 			f = fopen(buffer.c_str(), "wt"); | ||||
| 			if (f == NULL) | ||||
| 				log_error("Opening %s for writing failed: %s\n", buffer.c_str(), strerror(errno)); | ||||
| 			for (int i = 0; i < lut_mode; i++) | ||||
| 				fprintf(f, "%d 1.00 1.00\n", i+1); | ||||
| 			for (int i = lut_mode; i < lut_mode2; i++) | ||||
| 				fprintf(f, "%d %d.00 1.00\n", i+1, 2 << (i - lut_mode)); | ||||
| 			for (int i = 0; i < GetSize(lut_costs); i++) | ||||
| 				fprintf(f, "%d %d.00 1.00\n", i+1, lut_costs.at(i)); | ||||
| 			fclose(f); | ||||
| 		} | ||||
| 
 | ||||
|  | @ -894,7 +892,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin | |||
| 		if (ifs.fail()) | ||||
| 			log_error("Can't open ABC output file `%s'.\n", buffer.c_str()); | ||||
| 
 | ||||
| 		bool builtin_lib = liberty_file.empty() && script_file.empty() && !lut_mode; | ||||
| 		bool builtin_lib = liberty_file.empty() && script_file.empty() && lut_costs.empty(); | ||||
| 		RTLIL::Design *mapped_design = new RTLIL::Design; | ||||
| 		parse_blif(mapped_design, ifs, builtin_lib ? "\\DFF" : "\\_dff_"); | ||||
| 
 | ||||
|  | @ -1238,6 +1236,10 @@ struct AbcPass : public Pass { | |||
| 		log("        the area cost doubles with each additional input bit. the delay cost\n"); | ||||
| 		log("        is still constant for all lut widths.\n"); | ||||
| 		log("\n"); | ||||
| 		log("    -luts <cost1>,<cost2>,<cost3>,<sizeN>:<cost4-N>,..\n"); | ||||
| 		log("        generate netlist using luts. Use the specified costs for luts with 1,\n"); | ||||
| 		log("        2, 3, .. inputs.\n"); | ||||
| 		log("\n"); | ||||
| 		// log("    -mux4, -mux8, -mux16\n");
 | ||||
| 		// log("        try to extract 4-input, 8-input, and/or 16-input muxes\n");
 | ||||
| 		// log("        (ignored when used with -liberty or -lut)\n");
 | ||||
|  | @ -1291,7 +1293,7 @@ struct AbcPass : public Pass { | |||
| 		std::string script_file, liberty_file, constr_file, clk_str, delay_target; | ||||
| 		bool fast_mode = false, dff_mode = false, keepff = false, cleanup = true; | ||||
| 		bool show_tempdir = false; | ||||
| 		int lut_mode = 0, lut_mode2 = 0; | ||||
| 		vector<int> lut_costs; | ||||
| 		markgroups = false; | ||||
| 
 | ||||
| 		map_mux4 = false; | ||||
|  | @ -1341,6 +1343,7 @@ struct AbcPass : public Pass { | |||
| 			if (arg == "-lut" && argidx+1 < args.size()) { | ||||
| 				string arg = args[++argidx]; | ||||
| 				size_t pos = arg.find_first_of(':'); | ||||
| 				int lut_mode = 0, lut_mode2 = 0; | ||||
| 				if (pos != string::npos) { | ||||
| 					lut_mode = atoi(arg.substr(0, pos).c_str()); | ||||
| 					lut_mode2 = atoi(arg.substr(pos+1).c_str()); | ||||
|  | @ -1348,6 +1351,27 @@ struct AbcPass : public Pass { | |||
| 					lut_mode = atoi(arg.c_str()); | ||||
| 					lut_mode2 = lut_mode; | ||||
| 				} | ||||
| 				lut_costs.clear(); | ||||
| 				for (int i = 0; i < lut_mode; i++) | ||||
| 					lut_costs.push_back(1); | ||||
| 				for (int i = lut_mode; i < lut_mode2; i++) | ||||
| 					lut_costs.push_back(2 << (i - lut_mode)); | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (arg == "-luts" && argidx+1 < args.size()) { | ||||
| 				lut_costs.clear(); | ||||
| 				for (auto &tok : split_tokens(args[++argidx], ",")) { | ||||
| 					auto parts = split_tokens(tok, ":"); | ||||
| 					if (GetSize(parts) == 0 && !lut_costs.empty()) | ||||
| 						lut_costs.push_back(lut_costs.back()); | ||||
| 					else if (GetSize(parts) == 1) | ||||
| 						lut_costs.push_back(atoi(parts.at(0).c_str())); | ||||
| 					else if (GetSize(parts) == 2) | ||||
| 						while (GetSize(lut_costs) < atoi(parts.at(0).c_str())) | ||||
| 							lut_costs.push_back(atoi(parts.at(1).c_str())); | ||||
| 					else | ||||
| 						log_cmd_error("Invalid -luts syntax.\n"); | ||||
| 				} | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (arg == "-mux4") { | ||||
|  | @ -1414,7 +1438,7 @@ struct AbcPass : public Pass { | |||
| 		} | ||||
| 		extra_args(args, argidx, design); | ||||
| 
 | ||||
| 		if (lut_mode != 0 && !liberty_file.empty()) | ||||
| 		if (!lut_costs.empty() && !liberty_file.empty()) | ||||
| 			log_cmd_error("Got -lut and -liberty! This two options are exclusive.\n"); | ||||
| 		if (!constr_file.empty() && liberty_file.empty()) | ||||
| 			log_cmd_error("Got -constr but no -liberty!\n"); | ||||
|  | @ -1423,7 +1447,7 @@ struct AbcPass : public Pass { | |||
| 			if (mod->processes.size() > 0) | ||||
| 				log("Skipping module %s as it contains processes.\n", log_id(mod)); | ||||
| 			else if (!dff_mode || !clk_str.empty()) | ||||
| 				abc_module(design, mod, script_file, exe_file, liberty_file, constr_file, cleanup, lut_mode, lut_mode2, dff_mode, clk_str, keepff, delay_target, fast_mode, mod->selected_cells(), show_tempdir); | ||||
| 				abc_module(design, mod, script_file, exe_file, liberty_file, constr_file, cleanup, lut_costs, dff_mode, clk_str, keepff, delay_target, fast_mode, mod->selected_cells(), show_tempdir); | ||||
| 			else | ||||
| 			{ | ||||
| 				assign_map.set(mod); | ||||
|  | @ -1567,7 +1591,7 @@ struct AbcPass : public Pass { | |||
| 					clk_sig = assign_map(std::get<1>(it.first)); | ||||
| 					en_polarity = std::get<2>(it.first); | ||||
| 					en_sig = assign_map(std::get<3>(it.first)); | ||||
| 					abc_module(design, mod, script_file, exe_file, liberty_file, constr_file, cleanup, lut_mode, lut_mode2, | ||||
| 					abc_module(design, mod, script_file, exe_file, liberty_file, constr_file, cleanup, lut_costs, | ||||
| 							!clk_sig.empty(), "$", keepff, delay_target, fast_mode, it.second, show_tempdir); | ||||
| 					assign_map.set(mod); | ||||
| 				} | ||||
|  |  | |||
|  | @ -97,7 +97,7 @@ struct SynthXilinxPass : public Pass { | |||
| 		log("        opt -fast\n"); | ||||
| 		log("\n"); | ||||
| 		log("    map_luts:\n"); | ||||
| 		log("        abc -lut 5:8 [-dff]\n"); | ||||
| 		log("        abc -luts 2:2,3,6:5,10,20 [-dff]\n"); | ||||
| 		log("        clean\n"); | ||||
| 		log("\n"); | ||||
| 		log("    map_cells:\n"); | ||||
|  | @ -204,7 +204,7 @@ struct SynthXilinxPass : public Pass { | |||
| 
 | ||||
| 		if (check_label(active, run_from, run_to, "map_luts")) | ||||
| 		{ | ||||
| 			Pass::call(design, "abc -lut 6:8" + string(retime ? " -dff" : "")); | ||||
| 			Pass::call(design, "abc -luts 2:2,3,6:5,10,20" + string(retime ? " -dff" : "")); | ||||
| 			Pass::call(design, "clean"); | ||||
| 		} | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue