mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 13:29:12 +00:00 
			
		
		
		
	Added make_temp_{file,dir}() and remove_directory() APIs
This commit is contained in:
		
							parent
							
								
									9b4d171e37
								
							
						
					
					
						commit
						0b9282a779
					
				
					 4 changed files with 116 additions and 49 deletions
				
			
		| 
						 | 
				
			
			@ -120,15 +120,8 @@ struct Vhdl2verilogPass : public Pass {
 | 
			
		|||
		if (top_entity.empty())
 | 
			
		||||
			log_cmd_error("Missing -top option.\n");
 | 
			
		||||
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
		#warning Fixme: The vhdl2veriog command has not been ported to win32.
 | 
			
		||||
		log_cmd_error("The vhdl2veriog command has not been ported to win32.\n");
 | 
			
		||||
#else
 | 
			
		||||
		char tempdir_name[] = "/tmp/yosys-vhdl2verilog-XXXXXX";
 | 
			
		||||
		char *p = mkdtemp(tempdir_name);
 | 
			
		||||
		log("Using temp directory %s.\n", tempdir_name);
 | 
			
		||||
		if (p == NULL)
 | 
			
		||||
			log_error("For some reason mkdtemp() failed!\n");
 | 
			
		||||
		std::string tempdir_name = make_temp_dir("/tmp/yosys-vhdl2verilog-XXXXXX");
 | 
			
		||||
		log("Using temp directory %s.\n", tempdir_name.c_str());
 | 
			
		||||
 | 
			
		||||
		if (!out_file.empty() && out_file[0] != '/') {
 | 
			
		||||
			char pwd[PATH_MAX];
 | 
			
		||||
| 
						 | 
				
			
			@ -139,7 +132,7 @@ struct Vhdl2verilogPass : public Pass {
 | 
			
		|||
			out_file = pwd + ("/" + out_file);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		FILE *f = fopen(stringf("%s/files.list", tempdir_name).c_str(), "wt");
 | 
			
		||||
		FILE *f = fopen(stringf("%s/files.list", tempdir_name.c_str()).c_str(), "wt");
 | 
			
		||||
		while (argidx < args.size()) {
 | 
			
		||||
			std::string file = args[argidx++];
 | 
			
		||||
			if (file.empty())
 | 
			
		||||
| 
						 | 
				
			
			@ -160,7 +153,7 @@ struct Vhdl2verilogPass : public Pass {
 | 
			
		|||
		std::string command = "exec 2>&1; ";
 | 
			
		||||
		if (!vhdl2verilog_dir.empty())
 | 
			
		||||
			command += stringf("cd '%s'; . ./setup_env.sh; ", vhdl2verilog_dir.c_str());
 | 
			
		||||
		command += stringf("cd '%s'; vhdl2verilog -out '%s' -filelist files.list -top '%s'%s", tempdir_name,
 | 
			
		||||
		command += stringf("cd '%s'; vhdl2verilog -out '%s' -filelist files.list -top '%s'%s", tempdir_name.c_str(),
 | 
			
		||||
				out_file.empty() ? "vhdl2verilog_output.v" : out_file.c_str(), top_entity.c_str(), extra_opts.c_str());
 | 
			
		||||
 | 
			
		||||
		log("Running '%s'..\n", command.c_str());
 | 
			
		||||
| 
						 | 
				
			
			@ -171,18 +164,15 @@ struct Vhdl2verilogPass : public Pass {
 | 
			
		|||
 | 
			
		||||
		if (out_file.empty()) {
 | 
			
		||||
			std::ifstream ff;
 | 
			
		||||
			ff.open(stringf("%s/vhdl2verilog_output.v", tempdir_name).c_str());
 | 
			
		||||
			ff.open(stringf("%s/vhdl2verilog_output.v", tempdir_name.c_str()).c_str());
 | 
			
		||||
			if (ff.fail())
 | 
			
		||||
				log_error("Can't open vhdl2verilog output file `vhdl2verilog_output.v'.\n");
 | 
			
		||||
			Frontend::frontend_call(design, &ff, stringf("%s/vhdl2verilog_output.v", tempdir_name), "verilog");
 | 
			
		||||
			Frontend::frontend_call(design, &ff, stringf("%s/vhdl2verilog_output.v", tempdir_name.c_str()), "verilog");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		log_header("Removing temp directory `%s':\n", tempdir_name);
 | 
			
		||||
		if (run_command(stringf("rm -rf '%s'", tempdir_name).c_str()) != 0)
 | 
			
		||||
			log_error("Execution of \"rm -rf '%s'\" failed!\n", tempdir_name);
 | 
			
		||||
 | 
			
		||||
		log_header("Removing temp directory `%s':\n", tempdir_name.c_str());
 | 
			
		||||
		remove_directory(tempdir_name);
 | 
			
		||||
		log_pop();
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
} Vhdl2verilogPass;
 | 
			
		||||
 
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,6 +34,7 @@
 | 
			
		|||
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
#include <dirent.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
 | 
			
		||||
YOSYS_NAMESPACE_BEGIN
 | 
			
		||||
| 
						 | 
				
			
			@ -204,7 +205,96 @@ int run_command(const std::string &command, std::function<void(const std::string
 | 
			
		|||
	int ret = pclose(f);
 | 
			
		||||
	if (ret < 0)
 | 
			
		||||
		return -1;
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
	return ret;
 | 
			
		||||
#else
 | 
			
		||||
	return WEXITSTATUS(ret);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string make_temp_file(std::string template_str)
 | 
			
		||||
{
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
	if (template_str.rfind("/tmp/", 0) == 0) {
 | 
			
		||||
		char path[MAX_PATH+1];
 | 
			
		||||
		GetTempPath(MAX_PATH+1, path);
 | 
			
		||||
		template_str = stringf("%s\\%s", path, template_str.c_str() + 5);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	size_t pos = template_str.rfind("XXXXXX");
 | 
			
		||||
	log_assert(pos != std::string::npos);
 | 
			
		||||
 | 
			
		||||
	while (1) {
 | 
			
		||||
		for (int i = 0; i < 6; i++) {
 | 
			
		||||
			static std::string y = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
 | 
			
		||||
			static uint32_t x = 314159265 ^ time(NULL);
 | 
			
		||||
			x ^= x << 13, x ^= x >> 17, x ^= x << 5;
 | 
			
		||||
			template_str[pos+i] = y[x % y.size()];
 | 
			
		||||
		}
 | 
			
		||||
		if (access(template_str.c_str(), F_OK) != 0)
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
#else
 | 
			
		||||
	size_t pos = template_str.rfind("XXXXXX");
 | 
			
		||||
	log_assert(pos != std::string::npos);
 | 
			
		||||
 | 
			
		||||
	int suffixlen = GetSize(template_str) - pos - 6;
 | 
			
		||||
 | 
			
		||||
	char *p = strdup(template_str.c_str());
 | 
			
		||||
	close(mkstemps(p, suffixlen));
 | 
			
		||||
	template_str = p;
 | 
			
		||||
	free(p);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	return template_str;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string make_temp_dir(std::string template_str)
 | 
			
		||||
{
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
	template_str = make_temp_file(template_str);
 | 
			
		||||
	mkdir(template_str.c_str());
 | 
			
		||||
	return template_str;
 | 
			
		||||
#else
 | 
			
		||||
	size_t pos = template_str.rfind("XXXXXX");
 | 
			
		||||
	log_assert(pos != std::string::npos);
 | 
			
		||||
 | 
			
		||||
	int suffixlen = GetSize(template_str) - pos - 6;
 | 
			
		||||
	log_assert(suffixlen == 0);
 | 
			
		||||
 | 
			
		||||
	char *p = strdup(template_str.c_str());
 | 
			
		||||
	mkdtemp(p, suffixlen);
 | 
			
		||||
	template_str = p;
 | 
			
		||||
	free(p);
 | 
			
		||||
 | 
			
		||||
	return template_str;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void remove_directory(std::string dirname)
 | 
			
		||||
{
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
	run_command(stringf("rmdir /s /q \"%s\"", dirname.c_str()));
 | 
			
		||||
#else
 | 
			
		||||
	struct stat stbuf;
 | 
			
		||||
	struct dirent **namelist;
 | 
			
		||||
	int n = scandir(dirname.c_str(), &namelist, nullptr, alphasort);
 | 
			
		||||
	log_assert(n >= 0);
 | 
			
		||||
	for (int i = 0; i < n; i++) {
 | 
			
		||||
		if (strcmp(namelist[i]->d_name, ".") && strcmp(namelist[i]->d_name, "..")) {
 | 
			
		||||
			buffer = stringf("%s/%s", dirname.c_str(), namelist[i]->d_name);
 | 
			
		||||
			if (!stat(buffer.c_str(), &stbuf) && S_ISREG(stbuf.st_mode)) {
 | 
			
		||||
				log("Removing `%s'.\n", buffer.c_str());
 | 
			
		||||
				remove(buffer.c_str());
 | 
			
		||||
			} else
 | 
			
		||||
				remove_directory(buffer);
 | 
			
		||||
		}
 | 
			
		||||
		free(namelist[i]);
 | 
			
		||||
	}
 | 
			
		||||
	free(namelist);
 | 
			
		||||
	log("Removing `%s'.\n", dirname.c_str());
 | 
			
		||||
	rmdir(dirname.c_str());
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int GetSize(RTLIL::Wire *wire)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -88,6 +88,9 @@ std::string next_token(std::string &text, const char *sep);
 | 
			
		|||
bool patmatch(const char *pattern, const char *string);
 | 
			
		||||
int readsome(std::istream &f, char *s, int n);
 | 
			
		||||
int run_command(const std::string &command, std::function<void(const std::string&)> process_line = std::function<void(const std::string&)>());
 | 
			
		||||
std::string make_temp_file(std::string template_str = "/tmp/yosys_XXXXXX");
 | 
			
		||||
std::string make_temp_dir(std::string template_str = "/tmp/yosys_XXXXXX");
 | 
			
		||||
void remove_directory(std::string dirname);
 | 
			
		||||
 | 
			
		||||
template<typename T> int GetSize(const T &obj) { return obj.size(); }
 | 
			
		||||
int GetSize(RTLIL::Wire *wire);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -553,13 +553,11 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
 | 
			
		|||
	clk_polarity = true;
 | 
			
		||||
	clk_sig = RTLIL::SigSpec();
 | 
			
		||||
 | 
			
		||||
	char tempdir_name[] = "/tmp/yosys-abc-XXXXXX";
 | 
			
		||||
	std::string tempdir_name = "/tmp/yosys-abc-XXXXXX";
 | 
			
		||||
	if (!cleanup)
 | 
			
		||||
		tempdir_name[0] = tempdir_name[4] = '_';
 | 
			
		||||
	char *p = mkdtemp(tempdir_name);
 | 
			
		||||
	log_header("Extracting gate netlist of module `%s' to `%s/input.blif'..\n", module->name.c_str(), tempdir_name);
 | 
			
		||||
	if (p == NULL)
 | 
			
		||||
		log_error("For some reason mkdtemp() failed!\n");
 | 
			
		||||
	tempdir_name = make_temp_dir(tempdir_name);
 | 
			
		||||
	log_header("Extracting gate netlist of module `%s' to `%s/input.blif'..\n", module->name.c_str(), tempdir_name.c_str());
 | 
			
		||||
 | 
			
		||||
	std::string abc_command;
 | 
			
		||||
	if (!script_file.empty()) {
 | 
			
		||||
| 
						 | 
				
			
			@ -589,10 +587,10 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
 | 
			
		|||
		for (size_t i = 0; i+1 < abc_command.size(); i++)
 | 
			
		||||
			if (abc_command[i] == ';' && abc_command[i+1] == ' ')
 | 
			
		||||
				abc_command[i+1] = '\n';
 | 
			
		||||
		FILE *f = fopen(stringf("%s/abc.script", tempdir_name).c_str(), "wt");
 | 
			
		||||
		FILE *f = fopen(stringf("%s/abc.script", tempdir_name.c_str()).c_str(), "wt");
 | 
			
		||||
		fprintf(f, "%s\n", abc_command.c_str());
 | 
			
		||||
		fclose(f);
 | 
			
		||||
		abc_command = stringf("source %s/abc.script", tempdir_name);
 | 
			
		||||
		abc_command = stringf("source %s/abc.script", tempdir_name.c_str());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (clk_str.empty()) {
 | 
			
		||||
| 
						 | 
				
			
			@ -653,7 +651,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
 | 
			
		|||
	
 | 
			
		||||
	handle_loops();
 | 
			
		||||
 | 
			
		||||
	std::string buffer = stringf("%s/input.blif", tempdir_name);
 | 
			
		||||
	std::string buffer = stringf("%s/input.blif", tempdir_name.c_str());
 | 
			
		||||
	FILE *f = fopen(buffer.c_str(), "wt");
 | 
			
		||||
	if (f == NULL)
 | 
			
		||||
		log_error("Opening %s for writing failed: %s\n", buffer.c_str(), strerror(errno));
 | 
			
		||||
| 
						 | 
				
			
			@ -764,7 +762,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
 | 
			
		|||
	{
 | 
			
		||||
		log_header("Executing ABC.\n");
 | 
			
		||||
 | 
			
		||||
		buffer = stringf("%s/stdcells.genlib", tempdir_name);
 | 
			
		||||
		buffer = stringf("%s/stdcells.genlib", 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));
 | 
			
		||||
| 
						 | 
				
			
			@ -786,7 +784,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
 | 
			
		|||
		fclose(f);
 | 
			
		||||
 | 
			
		||||
		if (lut_mode) {
 | 
			
		||||
			buffer = stringf("%s/lutdefs.txt", tempdir_name);
 | 
			
		||||
			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));
 | 
			
		||||
| 
						 | 
				
			
			@ -798,18 +796,18 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
 | 
			
		|||
		buffer = stringf("%s -s -c '", exe_file.c_str());
 | 
			
		||||
		if (!liberty_file.empty()) {
 | 
			
		||||
			buffer += stringf("read_blif %s/input.blif; read_lib -w %s; ",
 | 
			
		||||
					tempdir_name, liberty_file.c_str());
 | 
			
		||||
					tempdir_name.c_str(), liberty_file.c_str());
 | 
			
		||||
			if (!constr_file.empty())
 | 
			
		||||
				buffer += stringf("read_constr -v %s; ", constr_file.c_str());
 | 
			
		||||
			buffer += abc_command + "; ";
 | 
			
		||||
		} else
 | 
			
		||||
		if (lut_mode)
 | 
			
		||||
			buffer += stringf("read_blif %s/input.blif; read_lut %s/lutdefs.txt; %s; ",
 | 
			
		||||
					tempdir_name, tempdir_name, abc_command.c_str());
 | 
			
		||||
					tempdir_name.c_str(), tempdir_name.c_str(), abc_command.c_str());
 | 
			
		||||
		else
 | 
			
		||||
			buffer += stringf("read_blif %s/input.blif; read_library %s/stdcells.genlib; %s; ",
 | 
			
		||||
					tempdir_name, tempdir_name, abc_command.c_str());
 | 
			
		||||
		buffer += stringf("write_blif %s/output.blif' 2>&1", tempdir_name);
 | 
			
		||||
					tempdir_name.c_str(), tempdir_name.c_str(), abc_command.c_str());
 | 
			
		||||
		buffer += stringf("write_blif %s/output.blif' 2>&1", tempdir_name.c_str());
 | 
			
		||||
 | 
			
		||||
		log("%s\n", buffer.c_str());
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -818,7 +816,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
 | 
			
		|||
		if (ret != 0)
 | 
			
		||||
			log_error("ABC: execution of command \"%s\" failed: return code %d.\n", buffer.c_str(), ret);
 | 
			
		||||
 | 
			
		||||
		buffer = stringf("%s/%s", tempdir_name, "output.blif");
 | 
			
		||||
		buffer = stringf("%s/%s", tempdir_name.c_str(), "output.blif");
 | 
			
		||||
		f = fopen(buffer.c_str(), "rt");
 | 
			
		||||
		if (f == NULL)
 | 
			
		||||
			log_error("Can't open ABC output file `%s'.\n", buffer.c_str());
 | 
			
		||||
| 
						 | 
				
			
			@ -991,22 +989,8 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
 | 
			
		|||
 | 
			
		||||
	if (cleanup)
 | 
			
		||||
	{
 | 
			
		||||
		log_header("Removing temp directory `%s':\n", tempdir_name);
 | 
			
		||||
 | 
			
		||||
		struct dirent **namelist;
 | 
			
		||||
		int n = scandir(tempdir_name, &namelist, 0, alphasort);
 | 
			
		||||
		log_assert(n >= 0);
 | 
			
		||||
		for (int i = 0; i < n; i++) {
 | 
			
		||||
			if (strcmp(namelist[i]->d_name, ".") && strcmp(namelist[i]->d_name, "..")) {
 | 
			
		||||
				buffer = stringf("%s/%s", tempdir_name, namelist[i]->d_name);
 | 
			
		||||
				log("Removing `%s'.\n", buffer.c_str());
 | 
			
		||||
				remove(buffer.c_str());
 | 
			
		||||
			}
 | 
			
		||||
			free(namelist[i]);
 | 
			
		||||
		}
 | 
			
		||||
		free(namelist);
 | 
			
		||||
		log("Removing `%s'.\n", tempdir_name);
 | 
			
		||||
		rmdir(tempdir_name);
 | 
			
		||||
		log_header("Removing temp directory `%s':\n", tempdir_name.c_str());
 | 
			
		||||
		remove_directory(tempdir_name);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	log_pop();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue