mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-03 21:09:12 +00:00 
			
		
		
		
	Only write out stdcells/lutcosts once for all ABC runs
This commit is contained in:
		
							parent
							
								
									13b3418a7f
								
							
						
					
					
						commit
						222f457a04
					
				
					 1 changed files with 82 additions and 59 deletions
				
			
		| 
						 | 
				
			
			@ -119,6 +119,7 @@ bool cmos_cost;
 | 
			
		|||
 | 
			
		||||
struct AbcConfig
 | 
			
		||||
{
 | 
			
		||||
	std::string global_tempdir_name;
 | 
			
		||||
	std::string script_file;
 | 
			
		||||
	std::string exe_file;
 | 
			
		||||
	std::vector<std::string> liberty_files;
 | 
			
		||||
| 
						 | 
				
			
			@ -878,9 +879,9 @@ void AbcModuleState::prepare_module(RTLIL::Design *design, RTLIL::Module *module
 | 
			
		|||
			abc_script += stringf("read_constr -v \"%s\"; ", config.constr_file);
 | 
			
		||||
	} else
 | 
			
		||||
	if (!config.lut_costs.empty())
 | 
			
		||||
		abc_script += stringf("read_lut %s/lutdefs.txt; ", tempdir_name);
 | 
			
		||||
		abc_script += stringf("read_lut %s/lutdefs.txt; ", config.global_tempdir_name);
 | 
			
		||||
	else
 | 
			
		||||
		abc_script += stringf("read_library %s/stdcells.genlib; ", tempdir_name);
 | 
			
		||||
		abc_script += stringf("read_library %s/stdcells.genlib; ", config.global_tempdir_name);
 | 
			
		||||
 | 
			
		||||
	if (!config.script_file.empty()) {
 | 
			
		||||
		const std::string &script_file = config.script_file;
 | 
			
		||||
| 
						 | 
				
			
			@ -1112,65 +1113,8 @@ void AbcModuleState::run_abc()
 | 
			
		|||
 | 
			
		||||
	log("Extracted %d gates and %d wires to a netlist network with %d inputs and %d outputs.\n",
 | 
			
		||||
			count_gates, GetSize(signal_list), count_input, count_output);
 | 
			
		||||
	log_push();
 | 
			
		||||
	if (count_output > 0)
 | 
			
		||||
	{
 | 
			
		||||
		auto &cell_cost = cmos_cost ? CellCosts::cmos_gate_cost() : CellCosts::default_gate_cost();
 | 
			
		||||
 | 
			
		||||
		buffer = stringf("%s/stdcells.genlib", tempdir_name);
 | 
			
		||||
		f = fopen(buffer.c_str(), "wt");
 | 
			
		||||
		if (f == nullptr)
 | 
			
		||||
			log_error("Opening %s for writing failed: %s\n", buffer, strerror(errno));
 | 
			
		||||
		fprintf(f, "GATE ZERO    1 Y=CONST0;\n");
 | 
			
		||||
		fprintf(f, "GATE ONE     1 Y=CONST1;\n");
 | 
			
		||||
		fprintf(f, "GATE BUF    %d Y=A;                  PIN * NONINV  1 999 1 0 1 0\n", cell_cost.at(ID($_BUF_)));
 | 
			
		||||
		fprintf(f, "GATE NOT    %d Y=!A;                 PIN * INV     1 999 1 0 1 0\n", cell_cost.at(ID($_NOT_)));
 | 
			
		||||
		if (enabled_gates.count("AND"))
 | 
			
		||||
			fprintf(f, "GATE AND    %d Y=A*B;                PIN * NONINV  1 999 1 0 1 0\n", cell_cost.at(ID($_AND_)));
 | 
			
		||||
		if (enabled_gates.count("NAND"))
 | 
			
		||||
			fprintf(f, "GATE NAND   %d Y=!(A*B);             PIN * INV     1 999 1 0 1 0\n", cell_cost.at(ID($_NAND_)));
 | 
			
		||||
		if (enabled_gates.count("OR"))
 | 
			
		||||
			fprintf(f, "GATE OR     %d Y=A+B;                PIN * NONINV  1 999 1 0 1 0\n", cell_cost.at(ID($_OR_)));
 | 
			
		||||
		if (enabled_gates.count("NOR"))
 | 
			
		||||
			fprintf(f, "GATE NOR    %d Y=!(A+B);             PIN * INV     1 999 1 0 1 0\n", cell_cost.at(ID($_NOR_)));
 | 
			
		||||
		if (enabled_gates.count("XOR"))
 | 
			
		||||
			fprintf(f, "GATE XOR    %d Y=(A*!B)+(!A*B);      PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at(ID($_XOR_)));
 | 
			
		||||
		if (enabled_gates.count("XNOR"))
 | 
			
		||||
			fprintf(f, "GATE XNOR   %d Y=(A*B)+(!A*!B);      PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at(ID($_XNOR_)));
 | 
			
		||||
		if (enabled_gates.count("ANDNOT"))
 | 
			
		||||
			fprintf(f, "GATE ANDNOT %d Y=A*!B;               PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at(ID($_ANDNOT_)));
 | 
			
		||||
		if (enabled_gates.count("ORNOT"))
 | 
			
		||||
			fprintf(f, "GATE ORNOT  %d Y=A+!B;               PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at(ID($_ORNOT_)));
 | 
			
		||||
		if (enabled_gates.count("AOI3"))
 | 
			
		||||
			fprintf(f, "GATE AOI3   %d Y=!((A*B)+C);         PIN * INV     1 999 1 0 1 0\n", cell_cost.at(ID($_AOI3_)));
 | 
			
		||||
		if (enabled_gates.count("OAI3"))
 | 
			
		||||
			fprintf(f, "GATE OAI3   %d Y=!((A+B)*C);         PIN * INV     1 999 1 0 1 0\n", cell_cost.at(ID($_OAI3_)));
 | 
			
		||||
		if (enabled_gates.count("AOI4"))
 | 
			
		||||
			fprintf(f, "GATE AOI4   %d Y=!((A*B)+(C*D));     PIN * INV     1 999 1 0 1 0\n", cell_cost.at(ID($_AOI4_)));
 | 
			
		||||
		if (enabled_gates.count("OAI4"))
 | 
			
		||||
			fprintf(f, "GATE OAI4   %d Y=!((A+B)*(C+D));     PIN * INV     1 999 1 0 1 0\n", cell_cost.at(ID($_OAI4_)));
 | 
			
		||||
		if (enabled_gates.count("MUX"))
 | 
			
		||||
			fprintf(f, "GATE MUX    %d Y=(A*B)+(S*B)+(!S*A); PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at(ID($_MUX_)));
 | 
			
		||||
		if (enabled_gates.count("NMUX"))
 | 
			
		||||
			fprintf(f, "GATE NMUX   %d Y=!((A*B)+(S*B)+(!S*A)); PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at(ID($_NMUX_)));
 | 
			
		||||
		if (map_mux4)
 | 
			
		||||
			fprintf(f, "GATE MUX4   %d Y=(!S*!T*A)+(S*!T*B)+(!S*T*C)+(S*T*D); PIN * UNKNOWN 1 999 1 0 1 0\n", 2*cell_cost.at(ID($_MUX_)));
 | 
			
		||||
		if (map_mux8)
 | 
			
		||||
			fprintf(f, "GATE MUX8   %d Y=(!S*!T*!U*A)+(S*!T*!U*B)+(!S*T*!U*C)+(S*T*!U*D)+(!S*!T*U*E)+(S*!T*U*F)+(!S*T*U*G)+(S*T*U*H); PIN * UNKNOWN 1 999 1 0 1 0\n", 4*cell_cost.at(ID($_MUX_)));
 | 
			
		||||
		if (map_mux16)
 | 
			
		||||
			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*cell_cost.at(ID($_MUX_)));
 | 
			
		||||
		fclose(f);
 | 
			
		||||
 | 
			
		||||
		if (!config.lut_costs.empty()) {
 | 
			
		||||
			buffer = stringf("%s/lutdefs.txt", tempdir_name);
 | 
			
		||||
			f = fopen(buffer.c_str(), "wt");
 | 
			
		||||
			if (f == nullptr)
 | 
			
		||||
				log_error("Opening %s for writing failed: %s\n", buffer, strerror(errno));
 | 
			
		||||
			for (int i = 0; i < GetSize(config.lut_costs); i++)
 | 
			
		||||
				fprintf(f, "%d %d.00 1.00\n", i+1, config.lut_costs.at(i));
 | 
			
		||||
			fclose(f);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		buffer = stringf("\"%s\" -s -f %s/abc.script 2>&1", config.exe_file, tempdir_name);
 | 
			
		||||
		log("Running ABC command: %s\n", replace_tempdir(buffer, tempdir_name, config.show_tempdir));
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1231,6 +1175,65 @@ void AbcModuleState::run_abc()
 | 
			
		|||
	log("Don't call ABC as there is nothing to map.\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void emit_global_input_files(const AbcConfig &config)
 | 
			
		||||
{
 | 
			
		||||
	if (!config.lut_costs.empty()) {
 | 
			
		||||
		std::string buffer = stringf("%s/lutdefs.txt", config.global_tempdir_name.c_str());
 | 
			
		||||
		FILE *f = fopen(buffer.c_str(), "wt");
 | 
			
		||||
		if (f == nullptr)
 | 
			
		||||
			log_error("Opening %s for writing failed: %s\n", buffer.c_str(), strerror(errno));
 | 
			
		||||
		for (int i = 0; i < GetSize(config.lut_costs); i++)
 | 
			
		||||
			fprintf(f, "%d %d.00 1.00\n", i+1, config.lut_costs.at(i));
 | 
			
		||||
		fclose(f);
 | 
			
		||||
	} else {
 | 
			
		||||
		auto &cell_cost = cmos_cost ? CellCosts::cmos_gate_cost() : CellCosts::default_gate_cost();
 | 
			
		||||
 | 
			
		||||
		std::string buffer = stringf("%s/stdcells.genlib", config.global_tempdir_name.c_str());
 | 
			
		||||
		FILE *f = fopen(buffer.c_str(), "wt");
 | 
			
		||||
		if (f == nullptr)
 | 
			
		||||
			log_error("Opening %s for writing failed: %s\n", buffer.c_str(), strerror(errno));
 | 
			
		||||
		fprintf(f, "GATE ZERO    1 Y=CONST0;\n");
 | 
			
		||||
		fprintf(f, "GATE ONE     1 Y=CONST1;\n");
 | 
			
		||||
		fprintf(f, "GATE BUF    %d Y=A;                  PIN * NONINV  1 999 1 0 1 0\n", cell_cost.at(ID($_BUF_)));
 | 
			
		||||
		fprintf(f, "GATE NOT    %d Y=!A;                 PIN * INV     1 999 1 0 1 0\n", cell_cost.at(ID($_NOT_)));
 | 
			
		||||
		if (enabled_gates.count("AND"))
 | 
			
		||||
			fprintf(f, "GATE AND    %d Y=A*B;                PIN * NONINV  1 999 1 0 1 0\n", cell_cost.at(ID($_AND_)));
 | 
			
		||||
		if (enabled_gates.count("NAND"))
 | 
			
		||||
			fprintf(f, "GATE NAND   %d Y=!(A*B);             PIN * INV     1 999 1 0 1 0\n", cell_cost.at(ID($_NAND_)));
 | 
			
		||||
		if (enabled_gates.count("OR"))
 | 
			
		||||
			fprintf(f, "GATE OR     %d Y=A+B;                PIN * NONINV  1 999 1 0 1 0\n", cell_cost.at(ID($_OR_)));
 | 
			
		||||
		if (enabled_gates.count("NOR"))
 | 
			
		||||
			fprintf(f, "GATE NOR    %d Y=!(A+B);             PIN * INV     1 999 1 0 1 0\n", cell_cost.at(ID($_NOR_)));
 | 
			
		||||
		if (enabled_gates.count("XOR"))
 | 
			
		||||
			fprintf(f, "GATE XOR    %d Y=(A*!B)+(!A*B);      PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at(ID($_XOR_)));
 | 
			
		||||
		if (enabled_gates.count("XNOR"))
 | 
			
		||||
			fprintf(f, "GATE XNOR   %d Y=(A*B)+(!A*!B);      PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at(ID($_XNOR_)));
 | 
			
		||||
		if (enabled_gates.count("ANDNOT"))
 | 
			
		||||
			fprintf(f, "GATE ANDNOT %d Y=A*!B;               PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at(ID($_ANDNOT_)));
 | 
			
		||||
		if (enabled_gates.count("ORNOT"))
 | 
			
		||||
			fprintf(f, "GATE ORNOT  %d Y=A+!B;               PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at(ID($_ORNOT_)));
 | 
			
		||||
		if (enabled_gates.count("AOI3"))
 | 
			
		||||
			fprintf(f, "GATE AOI3   %d Y=!((A*B)+C);         PIN * INV     1 999 1 0 1 0\n", cell_cost.at(ID($_AOI3_)));
 | 
			
		||||
		if (enabled_gates.count("OAI3"))
 | 
			
		||||
			fprintf(f, "GATE OAI3   %d Y=!((A+B)*C);         PIN * INV     1 999 1 0 1 0\n", cell_cost.at(ID($_OAI3_)));
 | 
			
		||||
		if (enabled_gates.count("AOI4"))
 | 
			
		||||
			fprintf(f, "GATE AOI4   %d Y=!((A*B)+(C*D));     PIN * INV     1 999 1 0 1 0\n", cell_cost.at(ID($_AOI4_)));
 | 
			
		||||
		if (enabled_gates.count("OAI4"))
 | 
			
		||||
			fprintf(f, "GATE OAI4   %d Y=!((A+B)*(C+D));     PIN * INV     1 999 1 0 1 0\n", cell_cost.at(ID($_OAI4_)));
 | 
			
		||||
		if (enabled_gates.count("MUX"))
 | 
			
		||||
			fprintf(f, "GATE MUX    %d Y=(A*B)+(S*B)+(!S*A); PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at(ID($_MUX_)));
 | 
			
		||||
		if (enabled_gates.count("NMUX"))
 | 
			
		||||
			fprintf(f, "GATE NMUX   %d Y=!((A*B)+(S*B)+(!S*A)); PIN * UNKNOWN 1 999 1 0 1 0\n", cell_cost.at(ID($_NMUX_)));
 | 
			
		||||
		if (map_mux4)
 | 
			
		||||
			fprintf(f, "GATE MUX4   %d Y=(!S*!T*A)+(S*!T*B)+(!S*T*C)+(S*T*D); PIN * UNKNOWN 1 999 1 0 1 0\n", 2*cell_cost.at(ID($_MUX_)));
 | 
			
		||||
		if (map_mux8)
 | 
			
		||||
			fprintf(f, "GATE MUX8   %d Y=(!S*!T*!U*A)+(S*!T*!U*B)+(!S*T*!U*C)+(S*T*!U*D)+(!S*!T*U*E)+(S*!T*U*F)+(!S*T*U*G)+(S*T*U*H); PIN * UNKNOWN 1 999 1 0 1 0\n", 4*cell_cost.at(ID($_MUX_)));
 | 
			
		||||
		if (map_mux16)
 | 
			
		||||
			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*cell_cost.at(ID($_MUX_)));
 | 
			
		||||
		fclose(f);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AbcModuleState::extract(AbcSigMap &assign_map, RTLIL::Design *design, RTLIL::Module *module)
 | 
			
		||||
{
 | 
			
		||||
	if (!did_run_abc) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1811,6 +1814,13 @@ struct AbcPass : public Pass {
 | 
			
		|||
		config.show_tempdir = design->scratchpad_get_bool("abc.showtmp", false);
 | 
			
		||||
		markgroups = design->scratchpad_get_bool("abc.markgroups", markgroups);
 | 
			
		||||
 | 
			
		||||
		if (config.cleanup)
 | 
			
		||||
			config.global_tempdir_name = get_base_tmpdir() + "/";
 | 
			
		||||
		else
 | 
			
		||||
			config.global_tempdir_name = "_tmp_";
 | 
			
		||||
		config.global_tempdir_name += proc_program_prefix() + "yosys-abc-XXXXXX";
 | 
			
		||||
		config.global_tempdir_name = make_temp_dir(config.global_tempdir_name);
 | 
			
		||||
 | 
			
		||||
		if (design->scratchpad_get_bool("abc.debug")) {
 | 
			
		||||
			config.cleanup = false;
 | 
			
		||||
			config.show_tempdir = true;
 | 
			
		||||
| 
						 | 
				
			
			@ -2139,6 +2149,8 @@ struct AbcPass : public Pass {
 | 
			
		|||
			// enabled_gates.insert("NMUX");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		emit_global_input_files(config);
 | 
			
		||||
 | 
			
		||||
		for (auto mod : design->selected_modules())
 | 
			
		||||
		{
 | 
			
		||||
			if (mod->processes.size() > 0) {
 | 
			
		||||
| 
						 | 
				
			
			@ -2164,9 +2176,12 @@ struct AbcPass : public Pass {
 | 
			
		|||
 | 
			
		||||
				AbcModuleState state(config, initvals);
 | 
			
		||||
				state.prepare_module(design, mod, assign_map, cells, dff_mode, clk_str);
 | 
			
		||||
				log_push();
 | 
			
		||||
				log_header(design, "Executing ABC.\n");
 | 
			
		||||
				state.run_abc();
 | 
			
		||||
				state.extract(assign_map, design, mod);
 | 
			
		||||
				state.finish();
 | 
			
		||||
				log_pop();
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2335,12 +2350,20 @@ struct AbcPass : public Pass {
 | 
			
		|||
				state.srst_polarity = std::get<6>(it.first);
 | 
			
		||||
				state.srst_sig = assign_map(std::get<7>(it.first));
 | 
			
		||||
				state.prepare_module(design, mod, assign_map, it.second, !state.clk_sig.empty(), "$");
 | 
			
		||||
				log_push();
 | 
			
		||||
				log_header(design, "Executing ABC.\n");
 | 
			
		||||
				state.run_abc();
 | 
			
		||||
				state.extract(assign_map, design, mod);
 | 
			
		||||
				state.finish();
 | 
			
		||||
				log_pop();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (config.cleanup) {
 | 
			
		||||
			log("Removing global temp directory.\n");
 | 
			
		||||
			remove_directory(config.global_tempdir_name);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		log_pop();
 | 
			
		||||
	}
 | 
			
		||||
} AbcPass;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue