diff options
| author | Clifford Wolf <clifford@clifford.at> | 2014-08-23 13:54:21 +0200 | 
|---|---|---|
| committer | Clifford Wolf <clifford@clifford.at> | 2014-08-23 13:54:21 +0200 | 
| commit | 5dce303a2a2c27d50e99856b6f33467798e13020 (patch) | |
| tree | 4f32f6e720ef5bb063e48c9d5ab6bd8356c6b3d6 | |
| parent | fff12c719fc2d61e36e85f27080a4043078b0929 (diff) | |
| download | yosys-5dce303a2a2c27d50e99856b6f33467798e13020.tar.gz yosys-5dce303a2a2c27d50e99856b6f33467798e13020.tar.bz2 yosys-5dce303a2a2c27d50e99856b6f33467798e13020.zip  | |
Changed backend-api from FILE to std::ostream
| -rw-r--r-- | backends/blif/blif.cc | 96 | ||||
| -rw-r--r-- | backends/btor/btor.cc | 130 | ||||
| -rw-r--r-- | backends/edif/edif.cc | 138 | ||||
| -rw-r--r-- | backends/ilang/ilang_backend.cc | 240 | ||||
| -rw-r--r-- | backends/ilang/ilang_backend.h | 26 | ||||
| -rw-r--r-- | backends/intersynth/intersynth.cc | 14 | ||||
| -rw-r--r-- | backends/spice/spice.cc | 52 | ||||
| -rw-r--r-- | backends/verilog/verilog_backend.cc | 460 | ||||
| -rw-r--r-- | backends/verilog/verilog_backend.h | 5 | ||||
| -rw-r--r-- | kernel/log.cc | 25 | ||||
| -rw-r--r-- | kernel/register.cc | 28 | ||||
| -rw-r--r-- | kernel/register.h | 16 | ||||
| -rw-r--r-- | kernel/rtlil.cc | 11 | ||||
| -rw-r--r-- | kernel/yosys.h | 5 | ||||
| -rw-r--r-- | passes/techmap/extract.cc | 9 | ||||
| -rw-r--r-- | passes/tests/test_autotb.cc | 186 | 
16 files changed, 713 insertions, 728 deletions
diff --git a/backends/blif/blif.cc b/backends/blif/blif.cc index b9b68b979..919022abe 100644 --- a/backends/blif/blif.cc +++ b/backends/blif/blif.cc @@ -44,13 +44,13 @@ struct BlifDumperConfig  struct BlifDumper  { -	FILE *f; +	std::ostream &f;  	RTLIL::Module *module;  	RTLIL::Design *design;  	BlifDumperConfig *config;  	CellTypes ct; -	BlifDumper(FILE *f, RTLIL::Module *module, RTLIL::Design *design, BlifDumperConfig *config) : +	BlifDumper(std::ostream &f, RTLIL::Module *module, RTLIL::Design *design, BlifDumperConfig *config) :  			f(f), module(module), design(design), config(config), ct(design)  	{  	} @@ -97,8 +97,8 @@ struct BlifDumper  	void dump()  	{ -		fprintf(f, "\n"); -		fprintf(f, ".model %s\n", cstr(module->name)); +		f << stringf("\n"); +		f << stringf(".model %s\n", cstr(module->name));  		std::map<int, RTLIL::Wire*> inputs, outputs; @@ -110,33 +110,33 @@ struct BlifDumper  				outputs[wire->port_id] = wire;  		} -		fprintf(f, ".inputs"); +		f << stringf(".inputs");  		for (auto &it : inputs) {  			RTLIL::Wire *wire = it.second;  			for (int i = 0; i < wire->width; i++) -				fprintf(f, " %s", cstr(RTLIL::SigSpec(wire, i))); +				f << stringf(" %s", cstr(RTLIL::SigSpec(wire, i)));  		} -		fprintf(f, "\n"); +		f << stringf("\n"); -		fprintf(f, ".outputs"); +		f << stringf(".outputs");  		for (auto &it : outputs) {  			RTLIL::Wire *wire = it.second;  			for (int i = 0; i < wire->width; i++) -				fprintf(f, " %s", cstr(RTLIL::SigSpec(wire, i))); +				f << stringf(" %s", cstr(RTLIL::SigSpec(wire, i)));  		} -		fprintf(f, "\n"); +		f << stringf("\n");  		if (!config->impltf_mode) {  			if (!config->false_type.empty()) -				fprintf(f, ".%s %s %s=$false\n", subckt_or_gate(config->false_type), +				f << stringf(".%s %s %s=$false\n", subckt_or_gate(config->false_type),  						config->false_type.c_str(), config->false_out.c_str());  			else -				fprintf(f, ".names $false\n"); +				f << stringf(".names $false\n");  			if (!config->true_type.empty()) -				fprintf(f, ".%s %s %s=$true\n", subckt_or_gate(config->true_type), +				f << stringf(".%s %s %s=$true\n", subckt_or_gate(config->true_type),  						config->true_type.c_str(), config->true_out.c_str());  			else -				fprintf(f, ".names $true\n1\n"); +				f << stringf(".names $true\n1\n");  		}  		for (auto &cell_it : module->cells_) @@ -144,116 +144,116 @@ struct BlifDumper  			RTLIL::Cell *cell = cell_it.second;  			if (!config->icells_mode && cell->type == "$_NOT_") { -				fprintf(f, ".names %s %s\n0 1\n", +				f << stringf(".names %s %s\n0 1\n",  						cstr(cell->getPort("\\A")), cstr(cell->getPort("\\Y")));  				continue;  			}  			if (!config->icells_mode && cell->type == "$_AND_") { -				fprintf(f, ".names %s %s %s\n11 1\n", +				f << stringf(".names %s %s %s\n11 1\n",  						cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")), cstr(cell->getPort("\\Y")));  				continue;  			}  			if (!config->icells_mode && cell->type == "$_OR_") { -				fprintf(f, ".names %s %s %s\n1- 1\n-1 1\n", +				f << stringf(".names %s %s %s\n1- 1\n-1 1\n",  						cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")), cstr(cell->getPort("\\Y")));  				continue;  			}  			if (!config->icells_mode && cell->type == "$_XOR_") { -				fprintf(f, ".names %s %s %s\n10 1\n01 1\n", +				f << stringf(".names %s %s %s\n10 1\n01 1\n",  						cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")), cstr(cell->getPort("\\Y")));  				continue;  			}  			if (!config->icells_mode && cell->type == "$_MUX_") { -				fprintf(f, ".names %s %s %s %s\n1-0 1\n-11 1\n", +				f << stringf(".names %s %s %s %s\n1-0 1\n-11 1\n",  						cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")),  						cstr(cell->getPort("\\S")), cstr(cell->getPort("\\Y")));  				continue;  			}  			if (!config->icells_mode && cell->type == "$_DFF_N_") { -				fprintf(f, ".latch %s %s fe %s\n", +				f << stringf(".latch %s %s fe %s\n",  						cstr(cell->getPort("\\D")), cstr(cell->getPort("\\Q")), cstr(cell->getPort("\\C")));  				continue;  			}  			if (!config->icells_mode && cell->type == "$_DFF_P_") { -				fprintf(f, ".latch %s %s re %s\n", +				f << stringf(".latch %s %s re %s\n",  						cstr(cell->getPort("\\D")), cstr(cell->getPort("\\Q")), cstr(cell->getPort("\\C")));  				continue;  			}  			if (!config->icells_mode && cell->type == "$lut") { -				fprintf(f, ".names"); +				f << stringf(".names");  				auto &inputs = cell->getPort("\\A");  				auto width = cell->parameters.at("\\WIDTH").as_int();  				log_assert(inputs.size() == width);  				for (int i = 0; i < inputs.size(); i++) { -					fprintf(f, " %s", cstr(inputs.extract(i, 1))); +					f << stringf(" %s", cstr(inputs.extract(i, 1)));  				}  				auto &output = cell->getPort("\\Y");  				log_assert(output.size() == 1); -				fprintf(f, " %s", cstr(output)); -				fprintf(f, "\n"); +				f << stringf(" %s", cstr(output)); +				f << stringf("\n");  				auto mask = cell->parameters.at("\\LUT").as_string();  				for (int i = 0; i < (1 << width); i++) {  					if (mask[i] == '0') continue;  					for (int j = width-1; j >= 0; j--) { -						fputc((i>>j)&1 ? '1' : '0', f); +						f << ((i>>j)&1 ? '1' : '0');  					} -					fprintf(f, " %c\n", mask[i]); +					f << stringf(" %c\n", mask[i]);  				}  				continue;  			} -			fprintf(f, ".%s %s", subckt_or_gate(cell->type.str()), cstr(cell->type)); +			f << stringf(".%s %s", subckt_or_gate(cell->type.str()), cstr(cell->type));  			for (auto &conn : cell->connections())  			for (int i = 0; i < conn.second.size(); i++) {  				if (conn.second.size() == 1) -					fprintf(f, " %s", cstr(conn.first)); +					f << stringf(" %s", cstr(conn.first));  				else -					fprintf(f, " %s[%d]", cstr(conn.first), i); -				fprintf(f, "=%s", cstr(conn.second.extract(i, 1))); +					f << stringf(" %s[%d]", cstr(conn.first), i); +				f << stringf("=%s", cstr(conn.second.extract(i, 1)));  			} -			fprintf(f, "\n"); +			f << stringf("\n");  			if (config->param_mode)  				for (auto ¶m : cell->parameters) { -					fprintf(f, ".param %s ", RTLIL::id2cstr(param.first)); +					f << stringf(".param %s ", RTLIL::id2cstr(param.first));  					if (param.second.flags & RTLIL::CONST_FLAG_STRING) {  						std::string str = param.second.decode_string(); -						fprintf(f, "\""); +						f << stringf("\"");  						for (char ch : str)  							if (ch == '"' || ch == '\\') -								fprintf(f, "\\%c", ch); +								f << stringf("\\%c", ch);  							else if (ch < 32 || ch >= 127) -								fprintf(f, "\\%03o", ch); +								f << stringf("\\%03o", ch);  							else -								fprintf(f, "%c", ch); -						fprintf(f, "\"\n"); +								f << stringf("%c", ch); +						f << stringf("\"\n");  					} else -						fprintf(f, "%s\n", param.second.as_string().c_str()); +						f << stringf("%s\n", param.second.as_string().c_str());  				}  		}  		for (auto &conn : module->connections())  		for (int i = 0; i < conn.first.size(); i++)  			if (config->conn_mode) -				fprintf(f, ".conn %s %s\n", cstr(conn.second.extract(i, 1)), cstr(conn.first.extract(i, 1))); +				f << stringf(".conn %s %s\n", cstr(conn.second.extract(i, 1)), cstr(conn.first.extract(i, 1)));  			else if (!config->buf_type.empty()) -				fprintf(f, ".%s %s %s=%s %s=%s\n", subckt_or_gate(config->buf_type), config->buf_type.c_str(), config->buf_in.c_str(), cstr(conn.second.extract(i, 1)), +				f << stringf(".%s %s %s=%s %s=%s\n", subckt_or_gate(config->buf_type), config->buf_type.c_str(), config->buf_in.c_str(), cstr(conn.second.extract(i, 1)),  						config->buf_out.c_str(), cstr(conn.first.extract(i, 1)));  			else -				fprintf(f, ".names %s %s\n1 1\n", cstr(conn.second.extract(i, 1)), cstr(conn.first.extract(i, 1))); +				f << stringf(".names %s %s\n1 1\n", cstr(conn.second.extract(i, 1)), cstr(conn.first.extract(i, 1))); -		fprintf(f, ".end\n"); +		f << stringf(".end\n");  	} -	static void dump(FILE *f, RTLIL::Module *module, RTLIL::Design *design, BlifDumperConfig &config) +	static void dump(std::ostream &f, RTLIL::Module *module, RTLIL::Design *design, BlifDumperConfig &config)  	{  		BlifDumper dumper(f, module, design, &config);  		dumper.dump(); @@ -303,7 +303,7 @@ struct BlifBackend : public Backend {  		log("        do not write definitions for the $true and $false wires.\n");  		log("\n");  	} -	virtual void execute(FILE *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) +	virtual void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design)  	{  		std::string top_module_name;  		std::string buf_type, buf_in, buf_out; @@ -365,7 +365,7 @@ struct BlifBackend : public Backend {  				if (mod_it.second->get_bool_attribute("\\top"))  					top_module_name = mod_it.first.str(); -		fprintf(f, "# Generated by %s\n", yosys_version_str); +		*f << stringf("# Generated by %s\n", yosys_version_str);  		std::vector<RTLIL::Module*> mod_list; @@ -381,7 +381,7 @@ struct BlifBackend : public Backend {  				log_error("Found munmapped emories in module %s: unmapped memories are not supported in BLIF backend!\n", RTLIL::id2cstr(module->name));  			if (module->name == RTLIL::escape_id(top_module_name)) { -				BlifDumper::dump(f, module, design, config); +				BlifDumper::dump(*f, module, design, config);  				top_module_name.clear();  				continue;  			} @@ -393,7 +393,7 @@ struct BlifBackend : public Backend {  			log_error("Can't find top module `%s'!\n", top_module_name.c_str());  		for (auto module : mod_list) -			BlifDumper::dump(f, module, design, config); +			BlifDumper::dump(*f, module, design, config);  	}  } BlifBackend; diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index a81d8f159..9b770518b 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -60,7 +60,7 @@ struct WireInfoOrder  struct BtorDumper  { -	FILE *f; +	std::ostream &f;  	RTLIL::Module *module;  	RTLIL::Design *design;  	BtorDumperConfig *config; @@ -75,7 +75,7 @@ struct BtorDumper  	std::map<RTLIL::IdString, bool> basic_wires;//input wires and registers	  	RTLIL::IdString curr_cell; //current cell being dumped  	std::map<std::string, std::string> cell_type_translation, s_cell_type_translation; //RTLIL to BTOR translation -	BtorDumper(FILE *f, RTLIL::Module *module, RTLIL::Design *design, BtorDumperConfig *config) : +	BtorDumper(std::ostream &f, RTLIL::Module *module, RTLIL::Design *design, BtorDumperConfig *config) :  			f(f), module(module), design(design), config(config), ct(design), sigmap(module)  	{  		line_num=0; @@ -174,7 +174,7 @@ struct BtorDumper  				++line_num;  				line_ref[wire->name]=line_num;			  				str = stringf("%d var %d %s", line_num, wire->width, cstr(wire->name)); -				fprintf(f, "%s\n", str.c_str()); +				f << stringf("%s\n", str.c_str());  				return line_num;  			}  			else return it->second; @@ -216,13 +216,13 @@ struct BtorDumper  								wire_line = ++line_num;  								str = stringf("%d slice %d %d %d %d;1", line_num, cell_output->chunks().at(j).width,  									cell_line, start_bit-1, start_bit-cell_output->chunks().at(j).width); -								fprintf(f, "%s\n", str.c_str()); +								f << stringf("%s\n", str.c_str());  								wire_width += cell_output->chunks().at(j).width;  								if(prev_wire_line!=0)  								{  									++line_num;  									str = stringf("%d concat %d %d %d", line_num, wire_width, wire_line, prev_wire_line); -									fprintf(f, "%s\n", str.c_str()); +									f << stringf("%s\n", str.c_str());  									wire_line = line_num;  								}  							} @@ -259,7 +259,7 @@ struct BtorDumper  			int address_bits = ceil(log(memory->size)/log(2));  			str = stringf("%d array %d %d", line_num, memory->width, address_bits);  			line_ref[memory->name]=line_num;			 -			fprintf(f, "%s\n", str.c_str()); +			f << stringf("%s\n", str.c_str());  			return line_num;  		}  		else return it->second; @@ -279,7 +279,7 @@ struct BtorDumper  			++line_num;  			str = stringf("%d const %d %s", line_num, width, data_str.c_str()); -			fprintf(f, "%s\n", str.c_str()); +			f << stringf("%s\n", str.c_str());  			return line_num;  		}  		else @@ -307,7 +307,7 @@ struct BtorDumper  				++line_num;  				str = stringf("%d slice %d %d %d %d;2", line_num, chunk->width, wire_line_num,   					chunk->width + chunk->offset - 1, chunk->offset); -				fprintf(f, "%s\n", str.c_str()); +				f << stringf("%s\n", str.c_str());  				l = line_num;				   			}  		} @@ -339,7 +339,7 @@ struct BtorDumper  					w2 = s.chunks().at(i).width;  					++line_num;  					str = stringf("%d concat %d %d %d", line_num, w1+w2, l2, l1); -					fprintf(f, "%s\n", str.c_str()); +					f << stringf("%s\n", str.c_str());  					l1=line_num;  					w1+=w2;  				} @@ -361,17 +361,17 @@ struct BtorDumper  				//TODO: case the signal is signed  				++line_num;  				str = stringf ("%d zero %d", line_num, expected_width - s.size()); -				fprintf(f, "%s\n", str.c_str()); +				f << stringf("%s\n", str.c_str());  				++line_num;  				str = stringf ("%d concat %d %d %d", line_num, expected_width, line_num-1, l); -				fprintf(f, "%s\n", str.c_str()); +				f << stringf("%s\n", str.c_str());  				l = line_num;  			}  			else if(expected_width < s.size())  			{  				++line_num;  				str = stringf ("%d slice %d %d %d %d;3", line_num, expected_width, l, expected_width-1, 0); -				fprintf(f, "%s\n", str.c_str()); +				f << stringf("%s\n", str.c_str());  				l = line_num;  			}  		} @@ -397,21 +397,21 @@ struct BtorDumper  				int en_line = dump_sigspec(en, 1);  				int one_line = ++line_num;  				str = stringf("%d one 1", line_num); -				fprintf(f, "%s\n", str.c_str()); +				f << stringf("%s\n", str.c_str());  				++line_num;  				str = stringf("%d %s %d %d %d", line_num, cell_type_translation.at("$eq").c_str(), 1, en_line, one_line); -				fprintf(f, "%s\n", str.c_str()); +				f << stringf("%s\n", str.c_str());  				++line_num;  				str = stringf("%d %s %d %d %d %d", line_num, cell_type_translation.at("$mux").c_str(), 1, line_num-1,  					expr_line, one_line); -				fprintf(f, "%s\n", str.c_str()); +				f << stringf("%s\n", str.c_str());  				int cell_line = ++line_num;  				str = stringf("%d %s %d %d", line_num, cell_type_translation.at("$assert").c_str(), 1, -1*(line_num-1));  				//multiplying the line number with -1, which means logical negation  				//the reason for negative sign is that the properties in btor are given as "negation of the original property"  				//bug identified by bobosoft  				//http://www.reddit.com/r/yosys/comments/1w3xig/btor_backend_bug/ -				fprintf(f, "%s\n", str.c_str()); +				f << stringf("%s\n", str.c_str());  				line_ref[cell->name]=cell_line;  			}  			//unary cells @@ -429,13 +429,13 @@ struct BtorDumper  					cell_line = ++line_num;  					bool reduced = (cell->type == "$not" || cell->type == "$neg") ? false : true;  					str = stringf ("%d %s %d %d", cell_line, cell_type_translation.at(cell->type.str()).c_str(), reduced?output_width:w, l); -					fprintf(f, "%s\n", str.c_str()); +					f << stringf("%s\n", str.c_str());  				}  				if(output_width < w && (cell->type == "$not" || cell->type == "$neg" || cell->type == "$pos"))  				{  					++line_num;  					str = stringf ("%d slice %d %d %d %d;4", line_num, output_width, cell_line, output_width-1, 0); -					fprintf(f, "%s\n", str.c_str()); +					f << stringf("%s\n", str.c_str());  					cell_line = line_num;  				}				  				line_ref[cell->name]=cell_line; @@ -451,17 +451,17 @@ struct BtorDumper  				{  					++line_num;  					str = stringf ("%d %s %d %d", line_num, cell_type_translation.at("$reduce_or").c_str(), output_width, l); -					fprintf(f, "%s\n", str.c_str()); +					f << stringf("%s\n", str.c_str());  				}  				else if(cell->type == "$reduce_xnor")  				{  					++line_num;  					str = stringf ("%d %s %d %d", line_num, cell_type_translation.at("$reduce_xor").c_str(), output_width, l); -					fprintf(f, "%s\n", str.c_str()); +					f << stringf("%s\n", str.c_str());  				}		  				++line_num;  				str = stringf ("%d %s %d %d", line_num, cell_type_translation.at("$not").c_str(), output_width, line_num-1); -				fprintf(f, "%s\n", str.c_str()); +				f << stringf("%s\n", str.c_str());  				line_ref[cell->name]=line_num;  			}  			//binary cells @@ -497,7 +497,7 @@ struct BtorDumper  				}  				str = stringf ("%d %s %d %d %d", line_num, op.c_str(), output_width, l1, l2); -				fprintf(f, "%s\n", str.c_str()); +				f << stringf("%s\n", str.c_str());  				line_ref[cell->name]=line_num;  			} @@ -532,13 +532,13 @@ struct BtorDumper  						op = s_cell_type_translation.at("$mody");  				}  				str = stringf ("%d %s %d %d %d", line_num, op.c_str(), l1_width, l1, l2); -				fprintf(f, "%s\n", str.c_str()); +				f << stringf("%s\n", str.c_str());  				if(output_width < l1_width)  				{  					++line_num;  					str = stringf ("%d slice %d %d %d %d;5", line_num, output_width, line_num-1, output_width-1, 0); -					fprintf(f, "%s\n", str.c_str()); +					f << stringf("%s\n", str.c_str());  				}  				line_ref[cell->name]=line_num;  			} @@ -556,7 +556,7 @@ struct BtorDumper  				int l2 = dump_sigspec(&cell->getPort(RTLIL::IdString("\\B")), ceil(log(l1_width)/log(2)));  				int cell_output = ++line_num;  				str = stringf ("%d %s %d %d %d", line_num, cell_type_translation.at(cell->type.str()).c_str(), l1_width, l1, l2); -				fprintf(f, "%s\n", str.c_str()); +				f << stringf("%s\n", str.c_str());  				if(l2_width > ceil(log(l1_width)/log(2)))  				{ @@ -564,19 +564,19 @@ struct BtorDumper  					l2 = dump_sigspec(&cell->getPort(RTLIL::IdString("\\B")), l2_width);  					++line_num;  					str = stringf ("%d slice %d %d %d %d;6", line_num, extra_width, l2, l2_width-1, l2_width-extra_width); -					fprintf(f, "%s\n", str.c_str()); +					f << stringf("%s\n", str.c_str());  					++line_num;  					str = stringf ("%d one %d", line_num, extra_width); -					fprintf(f, "%s\n", str.c_str()); +					f << stringf("%s\n", str.c_str());  					int mux = ++line_num;  					str = stringf ("%d %s %d %d %d", line_num, cell_type_translation.at("$gt").c_str(), 1, line_num-2, line_num-1); -					fprintf(f, "%s\n", str.c_str()); +					f << stringf("%s\n", str.c_str());  					++line_num;  					str = stringf("%d %s %d", line_num, l1_signed && cell->type == "$sshr" ? "ones":"zero", l1_width); -					fprintf(f, "%s\n", str.c_str()); +					f << stringf("%s\n", str.c_str());  					++line_num;  					str = stringf ("%d %s %d %d %d %d", line_num, cell_type_translation.at("$mux").c_str(), l1_width, mux, line_num-1, cell_output); -					fprintf(f, "%s\n", str.c_str()); +					f << stringf("%s\n", str.c_str());  					cell_output = line_num;  				} @@ -584,7 +584,7 @@ struct BtorDumper  				{  					++line_num;  					str = stringf ("%d slice %d %d %d %d;5", line_num, output_width, cell_output, output_width-1, 0); -					fprintf(f, "%s\n", str.c_str()); +					f << stringf("%s\n", str.c_str());  					cell_output = line_num;  				}  				line_ref[cell->name] = cell_output;	 @@ -602,14 +602,14 @@ struct BtorDumper  				{  					++line_num;  					str = stringf ("%d %s %d %d", line_num, cell_type_translation.at("$reduce_or").c_str(), output_width, l1); -					fprintf(f, "%s\n", str.c_str()); +					f << stringf("%s\n", str.c_str());  					l1 = line_num;  				}  				if(l2_width > 1)  				{  					++line_num;  					str = stringf ("%d %s %d %d", line_num, cell_type_translation.at("$reduce_or").c_str(), output_width, l2); -					fprintf(f, "%s\n", str.c_str()); +					f << stringf("%s\n", str.c_str());  					l2 = line_num;  				}  				if(cell->type == "$logic_and") @@ -622,7 +622,7 @@ struct BtorDumper  					++line_num;  					str = stringf ("%d %s %d %d %d", line_num, cell_type_translation.at("$or").c_str(), output_width, l1, l2);  				} -				fprintf(f, "%s\n", str.c_str()); +				f << stringf("%s\n", str.c_str());  				line_ref[cell->name]=line_num;  			}  			//multiplexers @@ -636,7 +636,7 @@ struct BtorDumper  				++line_num;  				str = stringf ("%d %s %d %d %d %d",   					line_num, cell_type_translation.at(cell->type.str()).c_str(), output_width, s, l2, l1);//if s is 0 then l1, if s is 1 then l2 //according to the implementation of mux cell -				fprintf(f, "%s\n", str.c_str()); +				f << stringf("%s\n", str.c_str());  				line_ref[cell->name]=line_num;  			}  			//registers @@ -663,7 +663,7 @@ struct BtorDumper  						slice = ++line_num;  						str = stringf ("%d slice %d %d %d %d;", line_num, output_width, value, start_bit-1,   							start_bit-output_width); -						fprintf(f, "%s\n", str.c_str()); +						f << stringf("%s\n", str.c_str());  					}  					if(cell->type == "$dffsr")  					{ @@ -676,14 +676,14 @@ struct BtorDumper  						str = stringf ("%d %s %d %s%d %s%d %d", line_num, cell_type_translation.at("$mux").c_str(),   							output_width, sync_reset_pol ? "":"-", sync_reset, sync_reset_value_pol? "":"-",   							sync_reset_value, slice); -						fprintf(f, "%s\n", str.c_str()); +						f << stringf("%s\n", str.c_str());  						slice = line_num;  					}  					++line_num;  					str = stringf ("%d %s %d %s%d %d %d", line_num, cell_type_translation.at("$mux").c_str(),   						output_width, polarity?"":"-", cond, slice, reg); -					fprintf(f, "%s\n", str.c_str()); +					f << stringf("%s\n", str.c_str());  					int next = line_num;  					if(cell->type == "$adff")  					{ @@ -694,12 +694,12 @@ struct BtorDumper  						++line_num;  						str = stringf ("%d %s %d %s%d %d %d", line_num, cell_type_translation.at("$mux").c_str(),   							output_width, async_reset_pol ? "":"-", async_reset, async_reset_value, next); -						fprintf(f, "%s\n", str.c_str()); +						f << stringf("%s\n", str.c_str());  					}  					++line_num;  					str = stringf ("%d %s %d %d %d", line_num, cell_type_translation.at(cell->type.str()).c_str(),   						output_width, reg, next); -					fprintf(f, "%s\n", str.c_str()); +					f << stringf("%s\n", str.c_str());  				}  				line_ref[cell->name]=line_num;  			} @@ -716,7 +716,7 @@ struct BtorDumper  				int data_width = cell->parameters.at(RTLIL::IdString("\\WIDTH")).as_int();  				++line_num;  				str = stringf("%d read %d %d %d", line_num, data_width, mem, address);	 -				fprintf(f, "%s\n", str.c_str()); +				f << stringf("%s\n", str.c_str());  				line_ref[cell->name]=line_num;  			}  			else if(cell->type == "$memwr") @@ -738,22 +738,22 @@ struct BtorDumper  					str = stringf("%d one 1", line_num);  				else  					str = stringf("%d zero 1", line_num); -				fprintf(f, "%s\n", str.c_str()); +				f << stringf("%s\n", str.c_str());  				++line_num;  				str = stringf("%d eq 1 %d %d", line_num, clk, line_num-1);	 -				fprintf(f, "%s\n", str.c_str()); +				f << stringf("%s\n", str.c_str());  				++line_num;  				str = stringf("%d and 1 %d %d", line_num, line_num-1, enable);	 -				fprintf(f, "%s\n", str.c_str()); +				f << stringf("%s\n", str.c_str());  				++line_num;  				str = stringf("%d write %d %d %d %d %d", line_num, data_width, address_width, mem, address, data);	 -				fprintf(f, "%s\n", str.c_str()); +				f << stringf("%s\n", str.c_str());  				++line_num;  				str = stringf("%d acond %d %d %d %d %d", line_num, data_width, address_width, line_num-2/*enable*/, line_num-1, mem);	 -				fprintf(f, "%s\n", str.c_str());				 +				f << stringf("%s\n", str.c_str());				  				++line_num;  				str = stringf("%d anext %d %d %d %d", line_num, data_width, address_width, mem, line_num-1);	 -				fprintf(f, "%s\n", str.c_str());				 +				f << stringf("%s\n", str.c_str());				  				line_ref[cell->name]=line_num;  			}  			else if(cell->type == "$slice") @@ -769,7 +769,7 @@ struct BtorDumper  				int offset = cell->parameters.at(RTLIL::IdString("\\OFFSET")).as_int();	  				++line_num;  				str = stringf("%d %s %d %d %d %d", line_num, cell_type_translation.at(cell->type.str()).c_str(), output_width, input_line, output_width+offset-1, offset); -				fprintf(f, "%s\n", str.c_str());				 +				f << stringf("%s\n", str.c_str());				  				line_ref[cell->name]=line_num;	  			}  			else if(cell->type == "$concat") @@ -786,7 +786,7 @@ struct BtorDumper  				++line_num;  				str = stringf("%d %s %d %d %d", line_num, cell_type_translation.at(cell->type.str()).c_str(), input_a_width+input_b_width,   					input_a_line, input_b_line);	 -				fprintf(f, "%s\n", str.c_str());				 +				f << stringf("%s\n", str.c_str());				  				line_ref[cell->name]=line_num;				  			}  			curr_cell.clear(); @@ -825,12 +825,12 @@ struct BtorDumper  		int l = dump_wire(wire);  		++line_num;  		str = stringf("%d root 1 %d", line_num, l); -		fprintf(f, "%s\n", str.c_str()); +		f << stringf("%s\n", str.c_str());  	}  	void dump()  	{ -		fprintf(f, ";module %s\n", cstr(module->name)); +		f << stringf(";module %s\n", cstr(module->name));  		log("creating intermediate wires map\n");  		//creating map of intermediate wires as output of some cell @@ -893,12 +893,12 @@ struct BtorDumper  			}  		} -		fprintf(f, ";inputs\n"); +		f << stringf(";inputs\n");  		for (auto &it : inputs) {  			RTLIL::Wire *wire = it.second;  			dump_wire(wire);  		} -		fprintf(f, "\n"); +		f << stringf("\n");  		log("writing memories\n");  		for(auto mem_it = module->memories.begin(); mem_it != module->memories.end(); ++mem_it) @@ -921,19 +921,19 @@ struct BtorDumper  		for(auto it: safety)  			dump_property(it); -		fprintf(f, "\n"); +		f << stringf("\n");  		log("writing outputs info\n"); -		fprintf(f, ";outputs\n"); +		f << stringf(";outputs\n");  		for (auto &it : outputs) {  			RTLIL::Wire *wire = it.second;  			int l = dump_wire(wire); -			fprintf(f, ";%d %s", l, cstr(wire->name)); +			f << stringf(";%d %s", l, cstr(wire->name));  		} -		fprintf(f, "\n"); +		f << stringf("\n");  	} -	static void dump(FILE *f, RTLIL::Module *module, RTLIL::Design *design, BtorDumperConfig &config) +	static void dump(std::ostream &f, RTLIL::Module *module, RTLIL::Design *design, BtorDumperConfig &config)  	{  		BtorDumper dumper(f, module, design, &config);  		dumper.dump(); @@ -952,7 +952,7 @@ struct BtorBackend : public Backend {  		log("Write the current design to an BTOR file.\n");  	} -	virtual void execute(FILE *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) +	virtual void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design)  	{  		std::string top_module_name;  		std::string buf_type, buf_in, buf_out; @@ -970,10 +970,10 @@ struct BtorBackend : public Backend {  				if (mod_it.second->get_bool_attribute("\\top"))  					top_module_name = mod_it.first.str(); -		fprintf(f, "; Generated by %s\n", yosys_version_str); -		fprintf(f, ";  %s developed and maintained by Clifford Wolf <clifford@clifford.at>\n", yosys_version_str); -		fprintf(f, "; BTOR Backend developed by Ahmed Irfan <irfan@fbk.eu> - Fondazione Bruno Kessler, Trento, Italy\n"); -		fprintf(f, ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n"); +		*f << stringf("; Generated by %s\n", yosys_version_str); +		*f << stringf(";  %s developed and maintained by Clifford Wolf <clifford@clifford.at>\n", yosys_version_str); +		*f << stringf("; BTOR Backend developed by Ahmed Irfan <irfan@fbk.eu> - Fondazione Bruno Kessler, Trento, Italy\n"); +		*f << stringf(";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n");  		std::vector<RTLIL::Module*> mod_list; @@ -987,7 +987,7 @@ struct BtorBackend : public Backend {  				log_error("Found unmapped processes in module %s: unmapped processes are not supported in BTOR backend!\n", RTLIL::id2cstr(module->name));  			if (module->name == RTLIL::escape_id(top_module_name)) { -				BtorDumper::dump(f, module, design, config); +				BtorDumper::dump(*f, module, design, config);  				top_module_name.clear();  				continue;  			} @@ -999,7 +999,7 @@ struct BtorBackend : public Backend {  			log_error("Can't find top module `%s'!\n", top_module_name.c_str());  		for (auto module : mod_list) -			BtorDumper::dump(f, module, design, config); +			BtorDumper::dump(*f, module, design, config);  	}  } BtorBackend; diff --git a/backends/edif/edif.cc b/backends/edif/edif.cc index ecdfaabfc..ccedd91d2 100644 --- a/backends/edif/edif.cc +++ b/backends/edif/edif.cc @@ -103,7 +103,7 @@ struct EdifBackend : public Backend {  		log("is targeted.\n");  		log("\n");  	} -	virtual void execute(FILE *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) +	virtual void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design)  	{  		log_header("Executing EDIF backend.\n"); @@ -160,38 +160,38 @@ struct EdifBackend : public Backend {  		if (top_module_name.empty())  			log_error("No module found in design!\n"); -		fprintf(f, "(edif %s\n", EDIF_DEF(top_module_name)); -		fprintf(f, "  (edifVersion 2 0 0)\n"); -		fprintf(f, "  (edifLevel 0)\n"); -		fprintf(f, "  (keywordMap (keywordLevel 0))\n"); -		fprintf(f, "  (comment \"Generated by %s\")\n", yosys_version_str); - -		fprintf(f, "  (external LIB\n"); -		fprintf(f, "    (edifLevel 0)\n"); -		fprintf(f, "    (technology (numberDefinition))\n"); - -		fprintf(f, "    (cell GND\n"); -		fprintf(f, "      (cellType GENERIC)\n"); -		fprintf(f, "      (view VIEW_NETLIST\n"); -		fprintf(f, "        (viewType NETLIST)\n"); -		fprintf(f, "        (interface (port G (direction OUTPUT)))\n"); -		fprintf(f, "      )\n"); -		fprintf(f, "    )\n"); - -		fprintf(f, "    (cell VCC\n"); -		fprintf(f, "      (cellType GENERIC)\n"); -		fprintf(f, "      (view VIEW_NETLIST\n"); -		fprintf(f, "        (viewType NETLIST)\n"); -		fprintf(f, "        (interface (port P (direction OUTPUT)))\n"); -		fprintf(f, "      )\n"); -		fprintf(f, "    )\n"); +		*f << stringf("(edif %s\n", EDIF_DEF(top_module_name)); +		*f << stringf("  (edifVersion 2 0 0)\n"); +		*f << stringf("  (edifLevel 0)\n"); +		*f << stringf("  (keywordMap (keywordLevel 0))\n"); +		*f << stringf("  (comment \"Generated by %s\")\n", yosys_version_str); + +		*f << stringf("  (external LIB\n"); +		*f << stringf("    (edifLevel 0)\n"); +		*f << stringf("    (technology (numberDefinition))\n"); + +		*f << stringf("    (cell GND\n"); +		*f << stringf("      (cellType GENERIC)\n"); +		*f << stringf("      (view VIEW_NETLIST\n"); +		*f << stringf("        (viewType NETLIST)\n"); +		*f << stringf("        (interface (port G (direction OUTPUT)))\n"); +		*f << stringf("      )\n"); +		*f << stringf("    )\n"); + +		*f << stringf("    (cell VCC\n"); +		*f << stringf("      (cellType GENERIC)\n"); +		*f << stringf("      (view VIEW_NETLIST\n"); +		*f << stringf("        (viewType NETLIST)\n"); +		*f << stringf("        (interface (port P (direction OUTPUT)))\n"); +		*f << stringf("      )\n"); +		*f << stringf("    )\n");  		for (auto &cell_it : lib_cell_ports) { -			fprintf(f, "    (cell %s\n", EDIF_DEF(cell_it.first)); -			fprintf(f, "      (cellType GENERIC)\n"); -			fprintf(f, "      (view VIEW_NETLIST\n"); -			fprintf(f, "        (viewType NETLIST)\n"); -			fprintf(f, "        (interface\n"); +			*f << stringf("    (cell %s\n", EDIF_DEF(cell_it.first)); +			*f << stringf("      (cellType GENERIC)\n"); +			*f << stringf("      (view VIEW_NETLIST\n"); +			*f << stringf("        (viewType NETLIST)\n"); +			*f << stringf("        (interface\n");  			for (auto &port_it : cell_it.second) {  				const char *dir = "INOUT";  				if (ct.cell_known(cell_it.first)) { @@ -200,13 +200,13 @@ struct EdifBackend : public Backend {  					else if (!ct.cell_input(cell_it.first, port_it))  						dir = "OUTPUT";  				} -				fprintf(f, "          (port %s (direction %s))\n", EDIF_DEF(port_it), dir); +				*f << stringf("          (port %s (direction %s))\n", EDIF_DEF(port_it), dir);  			} -			fprintf(f, "        )\n"); -			fprintf(f, "      )\n"); -			fprintf(f, "    )\n"); +			*f << stringf("        )\n"); +			*f << stringf("      )\n"); +			*f << stringf("    )\n");  		} -		fprintf(f, "  )\n"); +		*f << stringf("  )\n");  		std::vector<RTLIL::Module*> sorted_modules; @@ -238,9 +238,9 @@ struct EdifBackend : public Backend {  		} -		fprintf(f, "  (library DESIGN\n"); -		fprintf(f, "    (edifLevel 0)\n"); -		fprintf(f, "    (technology (numberDefinition))\n"); +		*f << stringf("  (library DESIGN\n"); +		*f << stringf("    (edifLevel 0)\n"); +		*f << stringf("    (technology (numberDefinition))\n");  		for (auto module : sorted_modules)  		{  			if (module->get_bool_attribute("\\blackbox")) @@ -249,11 +249,11 @@ struct EdifBackend : public Backend {  			SigMap sigmap(module);  			std::map<RTLIL::SigSpec, std::set<std::string>> net_join_db; -			fprintf(f, "    (cell %s\n", EDIF_DEF(module->name)); -			fprintf(f, "      (cellType GENERIC)\n"); -			fprintf(f, "      (view VIEW_NETLIST\n"); -			fprintf(f, "        (viewType NETLIST)\n"); -			fprintf(f, "        (interface\n"); +			*f << stringf("    (cell %s\n", EDIF_DEF(module->name)); +			*f << stringf("      (cellType GENERIC)\n"); +			*f << stringf("      (view VIEW_NETLIST\n"); +			*f << stringf("        (viewType NETLIST)\n"); +			*f << stringf("        (interface\n");  			for (auto &wire_it : module->wires_) {  				RTLIL::Wire *wire = wire_it.second;  				if (wire->port_id == 0) @@ -264,31 +264,31 @@ struct EdifBackend : public Backend {  				else if (!wire->port_input)  					dir = "OUTPUT";  				if (wire->width == 1) { -					fprintf(f, "          (port %s (direction %s))\n", EDIF_DEF(wire->name), dir); +					*f << stringf("          (port %s (direction %s))\n", EDIF_DEF(wire->name), dir);  					RTLIL::SigSpec sig = sigmap(RTLIL::SigSpec(wire));  					net_join_db[sig].insert(stringf("(portRef %s)", EDIF_REF(wire->name)));  				} else { -					fprintf(f, "          (port (array %s %d) (direction %s))\n", EDIF_DEF(wire->name), wire->width, dir); +					*f << stringf("          (port (array %s %d) (direction %s))\n", EDIF_DEF(wire->name), wire->width, dir);  					for (int i = 0; i < wire->width; i++) {  						RTLIL::SigSpec sig = sigmap(RTLIL::SigSpec(wire, i));  						net_join_db[sig].insert(stringf("(portRef (member %s %d))", EDIF_REF(wire->name), i));  					}  				}  			} -			fprintf(f, "        )\n"); -			fprintf(f, "        (contents\n"); -			fprintf(f, "          (instance GND (viewRef VIEW_NETLIST (cellRef GND (libraryRef LIB))))\n"); -			fprintf(f, "          (instance VCC (viewRef VIEW_NETLIST (cellRef VCC (libraryRef LIB))))\n"); +			*f << stringf("        )\n"); +			*f << stringf("        (contents\n"); +			*f << stringf("          (instance GND (viewRef VIEW_NETLIST (cellRef GND (libraryRef LIB))))\n"); +			*f << stringf("          (instance VCC (viewRef VIEW_NETLIST (cellRef VCC (libraryRef LIB))))\n");  			for (auto &cell_it : module->cells_) {  				RTLIL::Cell *cell = cell_it.second; -				fprintf(f, "          (instance %s\n", EDIF_DEF(cell->name)); -				fprintf(f, "            (viewRef VIEW_NETLIST (cellRef %s%s))", EDIF_REF(cell->type), +				*f << stringf("          (instance %s\n", EDIF_DEF(cell->name)); +				*f << stringf("            (viewRef VIEW_NETLIST (cellRef %s%s))", EDIF_REF(cell->type),  						lib_cell_ports.count(cell->type) > 0 ? " (libraryRef LIB)" : "");  				for (auto &p : cell->parameters)  					if ((p.second.flags & RTLIL::CONST_FLAG_STRING) != 0) -						fprintf(f, "\n            (property %s (string \"%s\"))", EDIF_DEF(p.first), p.second.decode_string().c_str()); +						*f << stringf("\n            (property %s (string \"%s\"))", EDIF_DEF(p.first), p.second.decode_string().c_str());  					else if (p.second.bits.size() <= 32 && RTLIL::SigSpec(p.second).is_fully_def()) -						fprintf(f, "\n            (property %s (integer %u))", EDIF_DEF(p.first), p.second.as_int()); +						*f << stringf("\n            (property %s (integer %u))", EDIF_DEF(p.first), p.second.as_int());  					else {  						std::string hex_string = "";  						for (size_t i = 0; i < p.second.bits.size(); i += 4) { @@ -300,9 +300,9 @@ struct EdifBackend : public Backend {  							char digit_str[2] = { "0123456789abcdef"[digit_value], 0 };  							hex_string = std::string(digit_str) + hex_string;  						} -						fprintf(f, "\n            (property %s (string \"%s\"))", EDIF_DEF(p.first), hex_string.c_str()); +						*f << stringf("\n            (property %s (string \"%s\"))", EDIF_DEF(p.first), hex_string.c_str());  					} -				fprintf(f, ")\n"); +				*f << stringf(")\n");  				for (auto &p : cell->connections()) {  					RTLIL::SigSpec sig = sigmap(p.second);  					for (int i = 0; i < SIZE(sig); i++) @@ -320,28 +320,28 @@ struct EdifBackend : public Backend {  				for (size_t i = 0; i < netname.size(); i++)  					if (netname[i] == ' ' || netname[i] == '\\')  						netname.erase(netname.begin() + i--); -				fprintf(f, "          (net %s (joined\n", EDIF_DEF(netname)); +				*f << stringf("          (net %s (joined\n", EDIF_DEF(netname));  				for (auto &ref : it.second) -					fprintf(f, "            %s\n", ref.c_str()); +					*f << stringf("            %s\n", ref.c_str());  				if (sig.wire == NULL) {  					if (sig == RTLIL::State::S0) -						fprintf(f, "            (portRef G (instanceRef GND))\n"); +						*f << stringf("            (portRef G (instanceRef GND))\n");  					if (sig == RTLIL::State::S1) -						fprintf(f, "            (portRef P (instanceRef VCC))\n"); +						*f << stringf("            (portRef P (instanceRef VCC))\n");  				} -				fprintf(f, "          ))\n"); +				*f << stringf("          ))\n");  			} -			fprintf(f, "        )\n"); -			fprintf(f, "      )\n"); -			fprintf(f, "    )\n"); +			*f << stringf("        )\n"); +			*f << stringf("      )\n"); +			*f << stringf("    )\n");  		} -		fprintf(f, "  )\n"); +		*f << stringf("  )\n"); -		fprintf(f, "  (design %s\n", EDIF_DEF(top_module_name)); -		fprintf(f, "    (cellRef %s (libraryRef DESIGN))\n", EDIF_REF(top_module_name)); -		fprintf(f, "  )\n"); +		*f << stringf("  (design %s\n", EDIF_DEF(top_module_name)); +		*f << stringf("    (cellRef %s (libraryRef DESIGN))\n", EDIF_REF(top_module_name)); +		*f << stringf("  )\n"); -		fprintf(f, ")\n"); +		*f << stringf(")\n");  	}  } EdifBackend; diff --git a/backends/ilang/ilang_backend.cc b/backends/ilang/ilang_backend.cc index b7088f599..13d3a8e42 100644 --- a/backends/ilang/ilang_backend.cc +++ b/backends/ilang/ilang_backend.cc @@ -23,16 +23,12 @@   */  #include "ilang_backend.h" -#include "kernel/compatibility.h" -#include "kernel/register.h" -#include "kernel/log.h" -#include <string> -#include <string.h> +#include "kernel/yosys.h"  #include <errno.h>  using namespace ILANG_BACKEND; -void ILANG_BACKEND::dump_const(FILE *f, const RTLIL::Const &data, int width, int offset, bool autoint) +void ILANG_BACKEND::dump_const(std::ostream &f, const RTLIL::Const &data, int width, int offset, bool autoint)  {  	if (width < 0)  		width = data.bits.size() - offset; @@ -48,222 +44,222 @@ void ILANG_BACKEND::dump_const(FILE *f, const RTLIL::Const &data, int width, int  				}  			}  			if (val >= 0) { -				fprintf(f, "%d", val); +				f << stringf("%d", val);  				return;  			}  		} -		fprintf(f, "%d'", width); +		f << stringf("%d'", width);  		for (int i = offset+width-1; i >= offset; i--) {  			log_assert(i < (int)data.bits.size());  			switch (data.bits[i]) { -			case RTLIL::S0: fprintf(f, "0"); break; -			case RTLIL::S1: fprintf(f, "1"); break; -			case RTLIL::Sx: fprintf(f, "x"); break; -			case RTLIL::Sz: fprintf(f, "z"); break; -			case RTLIL::Sa: fprintf(f, "-"); break; -			case RTLIL::Sm: fprintf(f, "m"); break; +			case RTLIL::S0: f << stringf("0"); break; +			case RTLIL::S1: f << stringf("1"); break; +			case RTLIL::Sx: f << stringf("x"); break; +			case RTLIL::Sz: f << stringf("z"); break; +			case RTLIL::Sa: f << stringf("-"); break; +			case RTLIL::Sm: f << stringf("m"); break;  			}  		}  	} else { -		fprintf(f, "\""); +		f << stringf("\"");  		std::string str = data.decode_string();  		for (size_t i = 0; i < str.size(); i++) {  			if (str[i] == '\n') -				fprintf(f, "\\n"); +				f << stringf("\\n");  			else if (str[i] == '\t') -				fprintf(f, "\\t"); +				f << stringf("\\t");  			else if (str[i] < 32) -				fprintf(f, "\\%03o", str[i]); +				f << stringf("\\%03o", str[i]);  			else if (str[i] == '"') -				fprintf(f, "\\\""); +				f << stringf("\\\"");  			else if (str[i] == '\\') -				fprintf(f, "\\\\"); +				f << stringf("\\\\");  			else -				fputc(str[i], f); +				f << str[i];  		} -		fprintf(f, "\""); +		f << stringf("\"");  	}  } -void ILANG_BACKEND::dump_sigchunk(FILE *f, const RTLIL::SigChunk &chunk, bool autoint) +void ILANG_BACKEND::dump_sigchunk(std::ostream &f, const RTLIL::SigChunk &chunk, bool autoint)  {  	if (chunk.wire == NULL) {  		dump_const(f, chunk.data, chunk.width, chunk.offset, autoint);  	} else {  		if (chunk.width == chunk.wire->width && chunk.offset == 0) -			fprintf(f, "%s", chunk.wire->name.c_str()); +			f << stringf("%s", chunk.wire->name.c_str());  		else if (chunk.width == 1) -			fprintf(f, "%s [%d]", chunk.wire->name.c_str(), chunk.offset); +			f << stringf("%s [%d]", chunk.wire->name.c_str(), chunk.offset);  		else -			fprintf(f, "%s [%d:%d]", chunk.wire->name.c_str(), chunk.offset+chunk.width-1, chunk.offset); +			f << stringf("%s [%d:%d]", chunk.wire->name.c_str(), chunk.offset+chunk.width-1, chunk.offset);  	}  } -void ILANG_BACKEND::dump_sigspec(FILE *f, const RTLIL::SigSpec &sig, bool autoint) +void ILANG_BACKEND::dump_sigspec(std::ostream &f, const RTLIL::SigSpec &sig, bool autoint)  {  	if (sig.is_chunk()) {  		dump_sigchunk(f, sig.as_chunk(), autoint);  	} else { -		fprintf(f, "{ "); +		f << stringf("{ ");  		for (auto it = sig.chunks().rbegin(); it != sig.chunks().rend(); it++) {  			dump_sigchunk(f, *it, false); -			fprintf(f, " "); +			f << stringf(" ");  		} -		fprintf(f, "}"); +		f << stringf("}");  	}  } -void ILANG_BACKEND::dump_wire(FILE *f, std::string indent, const RTLIL::Wire *wire) +void ILANG_BACKEND::dump_wire(std::ostream &f, std::string indent, const RTLIL::Wire *wire)  {  	for (auto it = wire->attributes.begin(); it != wire->attributes.end(); it++) { -		fprintf(f, "%s" "attribute %s ", indent.c_str(), it->first.c_str()); +		f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str());  		dump_const(f, it->second); -		fprintf(f, "\n"); +		f << stringf("\n");  	} -	fprintf(f, "%s" "wire ", indent.c_str()); +	f << stringf("%s" "wire ", indent.c_str());  	if (wire->width != 1) -		fprintf(f, "width %d ", wire->width); +		f << stringf("width %d ", wire->width);  	if (wire->upto) -		fprintf(f, "upto "); +		f << stringf("upto ");  	if (wire->start_offset != 0) -		fprintf(f, "offset %d ", wire->start_offset); +		f << stringf("offset %d ", wire->start_offset);  	if (wire->port_input && !wire->port_output) -		fprintf(f, "input %d ", wire->port_id); +		f << stringf("input %d ", wire->port_id);  	if (!wire->port_input && wire->port_output) -		fprintf(f, "output %d ", wire->port_id); +		f << stringf("output %d ", wire->port_id);  	if (wire->port_input && wire->port_output) -		fprintf(f, "inout %d ", wire->port_id); -	fprintf(f, "%s\n", wire->name.c_str()); +		f << stringf("inout %d ", wire->port_id); +	f << stringf("%s\n", wire->name.c_str());  } -void ILANG_BACKEND::dump_memory(FILE *f, std::string indent, const RTLIL::Memory *memory) +void ILANG_BACKEND::dump_memory(std::ostream &f, std::string indent, const RTLIL::Memory *memory)  {  	for (auto it = memory->attributes.begin(); it != memory->attributes.end(); it++) { -		fprintf(f, "%s" "attribute %s ", indent.c_str(), it->first.c_str()); +		f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str());  		dump_const(f, it->second); -		fprintf(f, "\n"); +		f << stringf("\n");  	} -	fprintf(f, "%s" "memory ", indent.c_str()); +	f << stringf("%s" "memory ", indent.c_str());  	if (memory->width != 1) -		fprintf(f, "width %d ", memory->width); +		f << stringf("width %d ", memory->width);  	if (memory->size != 0) -		fprintf(f, "size %d ", memory->size); -	fprintf(f, "%s\n", memory->name.c_str()); +		f << stringf("size %d ", memory->size); +	f << stringf("%s\n", memory->name.c_str());  } -void ILANG_BACKEND::dump_cell(FILE *f, std::string indent, const RTLIL::Cell *cell) +void ILANG_BACKEND::dump_cell(std::ostream &f, std::string indent, const RTLIL::Cell *cell)  {  	for (auto it = cell->attributes.begin(); it != cell->attributes.end(); it++) { -		fprintf(f, "%s" "attribute %s ", indent.c_str(), it->first.c_str()); +		f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str());  		dump_const(f, it->second); -		fprintf(f, "\n"); +		f << stringf("\n");  	} -	fprintf(f, "%s" "cell %s %s\n", indent.c_str(), cell->type.c_str(), cell->name.c_str()); +	f << stringf("%s" "cell %s %s\n", indent.c_str(), cell->type.c_str(), cell->name.c_str());  	for (auto it = cell->parameters.begin(); it != cell->parameters.end(); it++) { -		fprintf(f, "%s  parameter%s %s ", indent.c_str(), (it->second.flags & RTLIL::CONST_FLAG_SIGNED) != 0 ? " signed" : "", it->first.c_str()); +		f << stringf("%s  parameter%s %s ", indent.c_str(), (it->second.flags & RTLIL::CONST_FLAG_SIGNED) != 0 ? " signed" : "", it->first.c_str());  		dump_const(f, it->second); -		fprintf(f, "\n"); +		f << stringf("\n");  	}  	for (auto it = cell->connections().begin(); it != cell->connections().end(); it++) { -		fprintf(f, "%s  connect %s ", indent.c_str(), it->first.c_str()); +		f << stringf("%s  connect %s ", indent.c_str(), it->first.c_str());  		dump_sigspec(f, it->second); -		fprintf(f, "\n"); +		f << stringf("\n");  	} -	fprintf(f, "%s" "end\n", indent.c_str()); +	f << stringf("%s" "end\n", indent.c_str());  } -void ILANG_BACKEND::dump_proc_case_body(FILE *f, std::string indent, const RTLIL::CaseRule *cs) +void ILANG_BACKEND::dump_proc_case_body(std::ostream &f, std::string indent, const RTLIL::CaseRule *cs)  {  	for (auto it = cs->actions.begin(); it != cs->actions.end(); it++)  	{ -		fprintf(f, "%s" "assign ", indent.c_str()); +		f << stringf("%s" "assign ", indent.c_str());  		dump_sigspec(f, it->first); -		fprintf(f, " "); +		f << stringf(" ");  		dump_sigspec(f, it->second); -		fprintf(f, "\n"); +		f << stringf("\n");  	}  	for (auto it = cs->switches.begin(); it != cs->switches.end(); it++)  		dump_proc_switch(f, indent, *it);  } -void ILANG_BACKEND::dump_proc_switch(FILE *f, std::string indent, const RTLIL::SwitchRule *sw) +void ILANG_BACKEND::dump_proc_switch(std::ostream &f, std::string indent, const RTLIL::SwitchRule *sw)  {  	for (auto it = sw->attributes.begin(); it != sw->attributes.end(); it++) { -		fprintf(f, "%s" "attribute %s ", indent.c_str(), it->first.c_str()); +		f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str());  		dump_const(f, it->second); -		fprintf(f, "\n"); +		f << stringf("\n");  	} -	fprintf(f, "%s" "switch ", indent.c_str()); +	f << stringf("%s" "switch ", indent.c_str());  	dump_sigspec(f, sw->signal); -	fprintf(f, "\n"); +	f << stringf("\n");  	for (auto it = sw->cases.begin(); it != sw->cases.end(); it++)  	{ -		fprintf(f, "%s  case ", indent.c_str()); +		f << stringf("%s  case ", indent.c_str());  		for (size_t i = 0; i < (*it)->compare.size(); i++) {  			if (i > 0) -				fprintf(f, ", "); +				f << stringf(", ");  			dump_sigspec(f, (*it)->compare[i]);  		} -		fprintf(f, "\n"); +		f << stringf("\n");  		dump_proc_case_body(f, indent + "    ", *it);  	} -	fprintf(f, "%s" "end\n", indent.c_str()); +	f << stringf("%s" "end\n", indent.c_str());  } -void ILANG_BACKEND::dump_proc_sync(FILE *f, std::string indent, const RTLIL::SyncRule *sy) +void ILANG_BACKEND::dump_proc_sync(std::ostream &f, std::string indent, const RTLIL::SyncRule *sy)  { -	fprintf(f, "%s" "sync ", indent.c_str()); +	f << stringf("%s" "sync ", indent.c_str());  	switch (sy->type) { -	if (0) case RTLIL::ST0: fprintf(f, "low "); -	if (0) case RTLIL::ST1: fprintf(f, "high "); -	if (0) case RTLIL::STp: fprintf(f, "posedge "); -	if (0) case RTLIL::STn: fprintf(f, "negedge "); -	if (0) case RTLIL::STe: fprintf(f, "edge "); +	if (0) case RTLIL::ST0: f << stringf("low "); +	if (0) case RTLIL::ST1: f << stringf("high "); +	if (0) case RTLIL::STp: f << stringf("posedge "); +	if (0) case RTLIL::STn: f << stringf("negedge "); +	if (0) case RTLIL::STe: f << stringf("edge ");  		dump_sigspec(f, sy->signal); -		fprintf(f, "\n"); +		f << stringf("\n");  		break; -	case RTLIL::STa: fprintf(f, "always\n"); break; -	case RTLIL::STi: fprintf(f, "init\n"); break; +	case RTLIL::STa: f << stringf("always\n"); break; +	case RTLIL::STi: f << stringf("init\n"); break;  	}  	for (auto it = sy->actions.begin(); it != sy->actions.end(); it++) { -		fprintf(f, "%s  update ", indent.c_str()); +		f << stringf("%s  update ", indent.c_str());  		dump_sigspec(f, it->first); -		fprintf(f, " "); +		f << stringf(" ");  		dump_sigspec(f, it->second); -		fprintf(f, "\n"); +		f << stringf("\n");  	}  } -void ILANG_BACKEND::dump_proc(FILE *f, std::string indent, const RTLIL::Process *proc) +void ILANG_BACKEND::dump_proc(std::ostream &f, std::string indent, const RTLIL::Process *proc)  {  	for (auto it = proc->attributes.begin(); it != proc->attributes.end(); it++) { -		fprintf(f, "%s" "attribute %s ", indent.c_str(), it->first.c_str()); +		f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str());  		dump_const(f, it->second); -		fprintf(f, "\n"); +		f << stringf("\n");  	} -	fprintf(f, "%s" "process %s\n", indent.c_str(), proc->name.c_str()); +	f << stringf("%s" "process %s\n", indent.c_str(), proc->name.c_str());  	dump_proc_case_body(f, indent + "  ", &proc->root_case);  	for (auto it = proc->syncs.begin(); it != proc->syncs.end(); it++)  		dump_proc_sync(f, indent + "  ", *it); -	fprintf(f, "%s" "end\n", indent.c_str()); +	f << stringf("%s" "end\n", indent.c_str());  } -void ILANG_BACKEND::dump_conn(FILE *f, std::string indent, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right) +void ILANG_BACKEND::dump_conn(std::ostream &f, std::string indent, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right)  { -	fprintf(f, "%s" "connect ", indent.c_str()); +	f << stringf("%s" "connect ", indent.c_str());  	dump_sigspec(f, left); -	fprintf(f, " "); +	f << stringf(" ");  	dump_sigspec(f, right); -	fprintf(f, "\n"); +	f << stringf("\n");  } -void ILANG_BACKEND::dump_module(FILE *f, std::string indent, const RTLIL::Module *module, const RTLIL::Design *design, bool only_selected, bool flag_m, bool flag_n) +void ILANG_BACKEND::dump_module(std::ostream &f, std::string indent, const RTLIL::Module *module, const RTLIL::Design *design, bool only_selected, bool flag_m, bool flag_n)  {  	bool print_header = flag_m || design->selected_whole_module(module->name);  	bool print_body = !flag_n || !design->selected_whole_module(module->name); @@ -271,12 +267,12 @@ void ILANG_BACKEND::dump_module(FILE *f, std::string indent, const RTLIL::Module  	if (print_header)  	{  		for (auto it = module->attributes.begin(); it != module->attributes.end(); it++) { -			fprintf(f, "%s" "attribute %s ", indent.c_str(), it->first.c_str()); +			f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str());  			dump_const(f, it->second); -			fprintf(f, "\n"); +			f << stringf("\n");  		} -		fprintf(f, "%s" "module %s\n", indent.c_str(), module->name.c_str()); +		f << stringf("%s" "module %s\n", indent.c_str(), module->name.c_str());  	}  	if (print_body) @@ -284,28 +280,28 @@ void ILANG_BACKEND::dump_module(FILE *f, std::string indent, const RTLIL::Module  		for (auto it = module->wires_.begin(); it != module->wires_.end(); it++)  			if (!only_selected || design->selected(module, it->second)) {  				if (only_selected) -					fprintf(f, "\n"); +					f << stringf("\n");  				dump_wire(f, indent + "  ", it->second);  			}  		for (auto it = module->memories.begin(); it != module->memories.end(); it++)  			if (!only_selected || design->selected(module, it->second)) {  				if (only_selected) -					fprintf(f, "\n"); +					f << stringf("\n");  				dump_memory(f, indent + "  ", it->second);  			}  		for (auto it = module->cells_.begin(); it != module->cells_.end(); it++)  			if (!only_selected || design->selected(module, it->second)) {  				if (only_selected) -					fprintf(f, "\n"); +					f << stringf("\n");  				dump_cell(f, indent + "  ", it->second);  			}  		for (auto it = module->processes.begin(); it != module->processes.end(); it++)  			if (!only_selected || design->selected(module, it->second)) {  				if (only_selected) -					fprintf(f, "\n"); +					f << stringf("\n");  				dump_proc(f, indent + "  ", it->second);  			} @@ -323,7 +319,7 @@ void ILANG_BACKEND::dump_module(FILE *f, std::string indent, const RTLIL::Module  			}  			if (show_conn) {  				if (only_selected && first_conn_line) -					fprintf(f, "\n"); +					f << stringf("\n");  				dump_conn(f, indent + "  ", it->first, it->second);  				first_conn_line = false;  			} @@ -331,10 +327,10 @@ void ILANG_BACKEND::dump_module(FILE *f, std::string indent, const RTLIL::Module  	}  	if (print_header) -		fprintf(f, "%s" "end\n", indent.c_str()); +		f << stringf("%s" "end\n", indent.c_str());  } -void ILANG_BACKEND::dump_design(FILE *f, const RTLIL::Design *design, bool only_selected, bool flag_m, bool flag_n) +void ILANG_BACKEND::dump_design(std::ostream &f, const RTLIL::Design *design, bool only_selected, bool flag_m, bool flag_n)  {  	int init_autoidx = autoidx; @@ -352,14 +348,14 @@ void ILANG_BACKEND::dump_design(FILE *f, const RTLIL::Design *design, bool only_  	if (!only_selected || flag_m) {  		if (only_selected) -			fprintf(f, "\n"); -		fprintf(f, "autoidx %d\n", autoidx); +			f << stringf("\n"); +		f << stringf("autoidx %d\n", autoidx);  	}  	for (auto it = design->modules_.begin(); it != design->modules_.end(); it++) {  		if (!only_selected || design->selected(it->second)) {  			if (only_selected) -				fprintf(f, "\n"); +				f << stringf("\n");  			dump_module(f, "", it->second, design, only_selected, flag_m, flag_n);  		}  	} @@ -382,7 +378,7 @@ struct IlangBackend : public Backend {  		log("        only write selected parts of the design.\n");  		log("\n");  	} -	virtual void execute(FILE *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) +	virtual void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design)  	{  		bool selected = false; @@ -400,8 +396,8 @@ struct IlangBackend : public Backend {  		extra_args(f, filename, args, argidx);  		log("Output filename: %s\n", filename.c_str()); -		fprintf(f, "# Generated by %s\n", yosys_version_str); -		ILANG_BACKEND::dump_design(f, design, selected, true, false); +		*f << stringf("# Generated by %s\n", yosys_version_str); +		ILANG_BACKEND::dump_design(*f, design, selected, true, false);  	}  } IlangBackend; @@ -461,25 +457,27 @@ struct DumpPass : public Pass {  		}  		extra_args(args, argidx, design); -		FILE *f = NULL; -		char *buf_ptr; -		size_t buf_size; +		std::ostream *f; +		std::stringstream buf;  		if (!filename.empty()) { -			f = fopen(filename.c_str(), append ? "a" : "w"); -			if (f == NULL) +			std::ofstream *ff = new std::ofstream; +			ff->open(filename.c_str(), append ? std::ofstream::app : std::ofstream::trunc); +			if (ff->fail()) { +				delete ff;  				log_error("Can't open file `%s' for writing: %s\n", filename.c_str(), strerror(errno)); +			} +			f = ff;  		} else { -			f = open_memstream(&buf_ptr, &buf_size); +			f = &buf;  		} -		ILANG_BACKEND::dump_design(f, design, true, flag_m, flag_n); - -		fclose(f); +		ILANG_BACKEND::dump_design(*f, design, true, flag_m, flag_n); -		if (filename.empty()) { -			log("%s", buf_ptr); -			free(buf_ptr); +		if (!filename.empty()) { +			delete f; +		} else { +			log("%s", buf.str().c_str());  		}  	}  } DumpPass; diff --git a/backends/ilang/ilang_backend.h b/backends/ilang/ilang_backend.h index b0fec4889..138e10efb 100644 --- a/backends/ilang/ilang_backend.h +++ b/backends/ilang/ilang_backend.h @@ -31,19 +31,19 @@  YOSYS_NAMESPACE_BEGIN  namespace ILANG_BACKEND { -	void dump_const(FILE *f, const RTLIL::Const &data, int width = -1, int offset = 0, bool autoint = true); -	void dump_sigchunk(FILE *f, const RTLIL::SigChunk &chunk, bool autoint = true); -	void dump_sigspec(FILE *f, const RTLIL::SigSpec &sig, bool autoint = true); -	void dump_wire(FILE *f, std::string indent, const RTLIL::Wire *wire); -	void dump_memory(FILE *f, std::string indent, const RTLIL::Memory *memory); -	void dump_cell(FILE *f, std::string indent, const RTLIL::Cell *cell); -	void dump_proc_case_body(FILE *f, std::string indent, const RTLIL::CaseRule *cs); -	void dump_proc_switch(FILE *f, std::string indent, const RTLIL::SwitchRule *sw); -	void dump_proc_sync(FILE *f, std::string indent, const RTLIL::SyncRule *sy); -	void dump_proc(FILE *f, std::string indent, const RTLIL::Process *proc); -	void dump_conn(FILE *f, std::string indent, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right); -	void dump_module(FILE *f, std::string indent, const RTLIL::Module *module, const RTLIL::Design *design, bool only_selected, bool flag_m = true, bool flag_n = false); -	void dump_design(FILE *f, const RTLIL::Design *design, bool only_selected, bool flag_m = true, bool flag_n = false); +	void dump_const(std::ostream &f, const RTLIL::Const &data, int width = -1, int offset = 0, bool autoint = true); +	void dump_sigchunk(std::ostream &f, const RTLIL::SigChunk &chunk, bool autoint = true); +	void dump_sigspec(std::ostream &f, const RTLIL::SigSpec &sig, bool autoint = true); +	void dump_wire(std::ostream &f, std::string indent, const RTLIL::Wire *wire); +	void dump_memory(std::ostream &f, std::string indent, const RTLIL::Memory *memory); +	void dump_cell(std::ostream &f, std::string indent, const RTLIL::Cell *cell); +	void dump_proc_case_body(std::ostream &f, std::string indent, const RTLIL::CaseRule *cs); +	void dump_proc_switch(std::ostream &f, std::string indent, const RTLIL::SwitchRule *sw); +	void dump_proc_sync(std::ostream &f, std::string indent, const RTLIL::SyncRule *sy); +	void dump_proc(std::ostream &f, std::string indent, const RTLIL::Process *proc); +	void dump_conn(std::ostream &f, std::string indent, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right); +	void dump_module(std::ostream &f, std::string indent, const RTLIL::Module *module, const RTLIL::Design *design, bool only_selected, bool flag_m = true, bool flag_n = false); +	void dump_design(std::ostream &f, const RTLIL::Design *design, bool only_selected, bool flag_m = true, bool flag_n = false);  }  YOSYS_NAMESPACE_END diff --git a/backends/intersynth/intersynth.cc b/backends/intersynth/intersynth.cc index 9faed77c9..97ead3c64 100644 --- a/backends/intersynth/intersynth.cc +++ b/backends/intersynth/intersynth.cc @@ -69,7 +69,7 @@ struct IntersynthBackend : public Backend {  		log("http://www.clifford.at/intersynth/\n");  		log("\n");  	} -	virtual void execute(FILE *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) +	virtual void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design)  	{  		log_header("Executing INTERSYNTH backend.\n");  		log_push(); @@ -198,15 +198,15 @@ struct IntersynthBackend : public Backend {  		}  		if (!flag_notypes) { -			fprintf(f, "### Connection Types\n"); +			*f << stringf("### Connection Types\n");  			for (auto code : conntypes_code) -				fprintf(f, "%s", code.c_str()); -			fprintf(f, "\n### Cell Types\n"); +				*f << stringf("%s", code.c_str()); +			*f << stringf("\n### Cell Types\n");  			for (auto code : celltypes_code) -				fprintf(f, "%s", code.c_str()); +				*f << stringf("%s", code.c_str());  		} -		fprintf(f, "\n### Netlists\n"); -		fprintf(f, "%s", netlists_code.c_str()); +		*f << stringf("\n### Netlists\n"); +		*f << stringf("%s", netlists_code.c_str());  		for (auto lib : libs)  			delete lib; diff --git a/backends/spice/spice.cc b/backends/spice/spice.cc index be0086ffd..b057063cd 100644 --- a/backends/spice/spice.cc +++ b/backends/spice/spice.cc @@ -24,24 +24,24 @@  #include "kernel/log.h"  #include <string> -static void print_spice_net(FILE *f, RTLIL::SigBit s, std::string &neg, std::string &pos, std::string &ncpf, int &nc_counter) +static void print_spice_net(std::ostream &f, RTLIL::SigBit s, std::string &neg, std::string &pos, std::string &ncpf, int &nc_counter)  {  	if (s.wire) {  		if (s.wire->width > 1) -			fprintf(f, " %s[%d]", RTLIL::id2cstr(s.wire->name), s.offset); +			f << stringf(" %s[%d]", RTLIL::id2cstr(s.wire->name), s.offset);  		else -			fprintf(f, " %s", RTLIL::id2cstr(s.wire->name)); +			f << stringf(" %s", RTLIL::id2cstr(s.wire->name));  	} else {  		if (s == RTLIL::State::S0) -			fprintf(f, " %s", neg.c_str()); +			f << stringf(" %s", neg.c_str());  		else if (s == RTLIL::State::S1) -			fprintf(f, " %s", pos.c_str()); +			f << stringf(" %s", pos.c_str());  		else -			fprintf(f, " %s%d", ncpf.c_str(), nc_counter++); +			f << stringf(" %s%d", ncpf.c_str(), nc_counter++);  	}  } -static void print_spice_module(FILE *f, RTLIL::Module *module, RTLIL::Design *design, std::string &neg, std::string &pos, std::string &ncpf, bool big_endian) +static void print_spice_module(std::ostream &f, RTLIL::Module *module, RTLIL::Design *design, std::string &neg, std::string &pos, std::string &ncpf, bool big_endian)  {  	SigMap sigmap(module);  	int cell_counter = 0, conn_counter = 0, nc_counter = 0; @@ -49,7 +49,7 @@ static void print_spice_module(FILE *f, RTLIL::Module *module, RTLIL::Design *de  	for (auto &cell_it : module->cells_)  	{  		RTLIL::Cell *cell = cell_it.second; -		fprintf(f, "X%d", cell_counter++); +		f << stringf("X%d", cell_counter++);  		std::vector<RTLIL::SigSpec> port_sigs; @@ -94,15 +94,15 @@ static void print_spice_module(FILE *f, RTLIL::Module *module, RTLIL::Design *de  			}  		} -		fprintf(f, " %s\n", RTLIL::id2cstr(cell->type)); +		f << stringf(" %s\n", RTLIL::id2cstr(cell->type));  	}  	for (auto &conn : module->connections())  	for (int i = 0; i < conn.first.size(); i++) { -		fprintf(f, "V%d", conn_counter++); +		f << stringf("V%d", conn_counter++);  		print_spice_net(f, conn.first.extract(i, 1), neg, pos, ncpf, nc_counter);  		print_spice_net(f, conn.second.extract(i, 1), neg, pos, ncpf, nc_counter); -		fprintf(f, " DC 0\n"); +		f << stringf(" DC 0\n");  	}  } @@ -133,7 +133,7 @@ struct SpiceBackend : public Backend {  		log("        set the specified module as design top module\n");  		log("\n");  	} -	virtual void execute(FILE *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) +	virtual void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design)  	{  		std::string top_module_name;  		RTLIL::Module *top_module = NULL; @@ -174,8 +174,8 @@ struct SpiceBackend : public Backend {  				if (mod_it.second->get_bool_attribute("\\top"))  					top_module_name = mod_it.first.str(); -		fprintf(f, "* SPICE netlist generated by %s\n", yosys_version_str); -		fprintf(f, "\n"); +		*f << stringf("* SPICE netlist generated by %s\n", yosys_version_str); +		*f << stringf("\n");  		for (auto module_it : design->modules_)  		{ @@ -203,31 +203,31 @@ struct SpiceBackend : public Backend {  				ports.at(wire->port_id-1) = wire;  			} -			fprintf(f, ".SUBCKT %s", RTLIL::id2cstr(module->name)); +			*f << stringf(".SUBCKT %s", RTLIL::id2cstr(module->name));  			for (RTLIL::Wire *wire : ports) {  				log_assert(wire != NULL);  				if (wire->width > 1) {  					for (int i = 0; i < wire->width; i++) -						fprintf(f, " %s[%d]", RTLIL::id2cstr(wire->name), big_endian ? wire->width - 1 - i : i); +						*f << stringf(" %s[%d]", RTLIL::id2cstr(wire->name), big_endian ? wire->width - 1 - i : i);  				} else -					fprintf(f, " %s", RTLIL::id2cstr(wire->name)); +					*f << stringf(" %s", RTLIL::id2cstr(wire->name));  			} -			fprintf(f, "\n"); -			print_spice_module(f, module, design, neg, pos, ncpf, big_endian); -			fprintf(f, ".ENDS %s\n\n", RTLIL::id2cstr(module->name)); +			*f << stringf("\n"); +			print_spice_module(*f, module, design, neg, pos, ncpf, big_endian); +			*f << stringf(".ENDS %s\n\n", RTLIL::id2cstr(module->name));  		}  		if (!top_module_name.empty()) {  			if (top_module == NULL)  				log_error("Can't find top module `%s'!\n", top_module_name.c_str()); -			print_spice_module(f, top_module, design, neg, pos, ncpf, big_endian); -			fprintf(f, "\n"); +			print_spice_module(*f, top_module, design, neg, pos, ncpf, big_endian); +			*f << stringf("\n");  		} -		fprintf(f, "************************\n"); -		fprintf(f, "* end of SPICE netlist *\n"); -		fprintf(f, "************************\n"); -		fprintf(f, "\n"); +		*f << stringf("************************\n"); +		*f << stringf("* end of SPICE netlist *\n"); +		*f << stringf("************************\n"); +		*f << stringf("\n");  	}  } SpiceBackend; diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index f6095a5aa..d1fa55b94 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -150,7 +150,7 @@ bool is_reg_wire(RTLIL::SigSpec sig, std::string ®_name)  	return true;  } -void dump_const(FILE *f, const RTLIL::Const &data, int width = -1, int offset = 0, bool no_decimal = false, bool set_signed = false) +void dump_const(std::ostream &f, const RTLIL::Const &data, int width = -1, int offset = 0, bool no_decimal = false, bool set_signed = false)  {  	if (width < 0)  		width = data.bits.size() - offset; @@ -166,112 +166,112 @@ void dump_const(FILE *f, const RTLIL::Const &data, int width = -1, int offset =  				if (data.bits[i] == RTLIL::S1)  					val |= 1 << (i - offset);  			} -			fprintf(f, "32'%sd%d", set_signed ? "s" : "", val); +			f << stringf("32'%sd%d", set_signed ? "s" : "", val);  		} else {  	dump_bits: -			fprintf(f, "%d'%sb", width, set_signed ? "s" : ""); +			f << stringf("%d'%sb", width, set_signed ? "s" : "");  			if (width == 0) -				fprintf(f, "0"); +				f << stringf("0");  			for (int i = offset+width-1; i >= offset; i--) {  				log_assert(i < (int)data.bits.size());  				switch (data.bits[i]) { -				case RTLIL::S0: fprintf(f, "0"); break; -				case RTLIL::S1: fprintf(f, "1"); break; -				case RTLIL::Sx: fprintf(f, "x"); break; -				case RTLIL::Sz: fprintf(f, "z"); break; -				case RTLIL::Sa: fprintf(f, "z"); break; +				case RTLIL::S0: f << stringf("0"); break; +				case RTLIL::S1: f << stringf("1"); break; +				case RTLIL::Sx: f << stringf("x"); break; +				case RTLIL::Sz: f << stringf("z"); break; +				case RTLIL::Sa: f << stringf("z"); break;  				case RTLIL::Sm: log_error("Found marker state in final netlist.");  				}  			}  		}  	} else { -		fprintf(f, "\""); +		f << stringf("\"");  		std::string str = data.decode_string();  		for (size_t i = 0; i < str.size(); i++) {  			if (str[i] == '\n') -				fprintf(f, "\\n"); +				f << stringf("\\n");  			else if (str[i] == '\t') -				fprintf(f, "\\t"); +				f << stringf("\\t");  			else if (str[i] < 32) -				fprintf(f, "\\%03o", str[i]); +				f << stringf("\\%03o", str[i]);  			else if (str[i] == '"') -				fprintf(f, "\\\""); +				f << stringf("\\\"");  			else if (str[i] == '\\') -				fprintf(f, "\\\\"); +				f << stringf("\\\\");  			else -				fputc(str[i], f); +				f << str[i];  		} -		fprintf(f, "\""); +		f << stringf("\"");  	}  } -void dump_sigchunk(FILE *f, const RTLIL::SigChunk &chunk, bool no_decimal = false) +void dump_sigchunk(std::ostream &f, const RTLIL::SigChunk &chunk, bool no_decimal = false)  {  	if (chunk.wire == NULL) {  		dump_const(f, chunk.data, chunk.width, chunk.offset, no_decimal);  	} else {  		if (chunk.width == chunk.wire->width && chunk.offset == 0) { -			fprintf(f, "%s", id(chunk.wire->name).c_str()); +			f << stringf("%s", id(chunk.wire->name).c_str());  		} else if (chunk.width == 1) {  			if (chunk.wire->upto) -				fprintf(f, "%s[%d]", id(chunk.wire->name).c_str(), (chunk.wire->width - chunk.offset - 1) + chunk.wire->start_offset); +				f << stringf("%s[%d]", id(chunk.wire->name).c_str(), (chunk.wire->width - chunk.offset - 1) + chunk.wire->start_offset);  			else -				fprintf(f, "%s[%d]", id(chunk.wire->name).c_str(), chunk.offset + chunk.wire->start_offset); +				f << stringf("%s[%d]", id(chunk.wire->name).c_str(), chunk.offset + chunk.wire->start_offset);  		} else {  			if (chunk.wire->upto) -				fprintf(f, "%s[%d:%d]", id(chunk.wire->name).c_str(), +				f << stringf("%s[%d:%d]", id(chunk.wire->name).c_str(),  						(chunk.wire->width - (chunk.offset + chunk.width - 1) - 1) + chunk.wire->start_offset,  						(chunk.wire->width - chunk.offset - 1) + chunk.wire->start_offset);  			else -				fprintf(f, "%s[%d:%d]", id(chunk.wire->name).c_str(), +				f << stringf("%s[%d:%d]", id(chunk.wire->name).c_str(),  						(chunk.offset + chunk.width - 1) + chunk.wire->start_offset,  						chunk.offset + chunk.wire->start_offset);  		}  	}  } -void dump_sigspec(FILE *f, const RTLIL::SigSpec &sig) +void dump_sigspec(std::ostream &f, const RTLIL::SigSpec &sig)  {  	if (sig.is_chunk()) {  		dump_sigchunk(f, sig.as_chunk());  	} else { -		fprintf(f, "{ "); +		f << stringf("{ ");  		for (auto it = sig.chunks().rbegin(); it != sig.chunks().rend(); it++) {  			if (it != sig.chunks().rbegin()) -				fprintf(f, ", "); +				f << stringf(", ");  			dump_sigchunk(f, *it, true);  		} -		fprintf(f, " }"); +		f << stringf(" }");  	}  } -void dump_attributes(FILE *f, std::string indent, std::map<RTLIL::IdString, RTLIL::Const> &attributes, char term = '\n') +void dump_attributes(std::ostream &f, std::string indent, std::map<RTLIL::IdString, RTLIL::Const> &attributes, char term = '\n')  {  	if (noattr)  		return;  	for (auto it = attributes.begin(); it != attributes.end(); it++) { -		fprintf(f, "%s" "%s %s", indent.c_str(), attr2comment ? "/*" : "(*", id(it->first).c_str()); -		fprintf(f, " = "); +		f << stringf("%s" "%s %s", indent.c_str(), attr2comment ? "/*" : "(*", id(it->first).c_str()); +		f << stringf(" = ");  		dump_const(f, it->second); -		fprintf(f, " %s%c", attr2comment ? "*/" : "*)", term); +		f << stringf(" %s%c", attr2comment ? "*/" : "*)", term);  	}  } -void dump_wire(FILE *f, std::string indent, RTLIL::Wire *wire) +void dump_wire(std::ostream &f, std::string indent, RTLIL::Wire *wire)  {  	dump_attributes(f, indent, wire->attributes);  #if 0  	if (wire->port_input && !wire->port_output) -		fprintf(f, "%s" "input %s", indent.c_str(), reg_wires.count(wire->name) ? "reg " : ""); +		f << stringf("%s" "input %s", indent.c_str(), reg_wires.count(wire->name) ? "reg " : "");  	else if (!wire->port_input && wire->port_output) -		fprintf(f, "%s" "output %s", indent.c_str(), reg_wires.count(wire->name) ? "reg " : ""); +		f << stringf("%s" "output %s", indent.c_str(), reg_wires.count(wire->name) ? "reg " : "");  	else if (wire->port_input && wire->port_output) -		fprintf(f, "%s" "inout %s", indent.c_str(), reg_wires.count(wire->name) ? "reg " : ""); +		f << stringf("%s" "inout %s", indent.c_str(), reg_wires.count(wire->name) ? "reg " : "");  	else -		fprintf(f, "%s" "%s ", indent.c_str(), reg_wires.count(wire->name) ? "reg" : "wire"); +		f << stringf("%s" "%s ", indent.c_str(), reg_wires.count(wire->name) ? "reg" : "wire");  	if (wire->width != 1) -		fprintf(f, "[%d:%d] ", wire->width - 1 + wire->start_offset, wire->start_offset); -	fprintf(f, "%s;\n", id(wire->name).c_str()); +		f << stringf("[%d:%d] ", wire->width - 1 + wire->start_offset, wire->start_offset); +	f << stringf("%s;\n", id(wire->name).c_str());  #else  	// do not use Verilog-2k "outut reg" syntax in verilog export  	std::string range = ""; @@ -282,30 +282,30 @@ void dump_wire(FILE *f, std::string indent, RTLIL::Wire *wire)  			range = stringf(" [%d:%d]", wire->width - 1 + wire->start_offset, wire->start_offset);  	}  	if (wire->port_input && !wire->port_output) -		fprintf(f, "%s" "input%s %s;\n", indent.c_str(), range.c_str(), id(wire->name).c_str()); +		f << stringf("%s" "input%s %s;\n", indent.c_str(), range.c_str(), id(wire->name).c_str());  	if (!wire->port_input && wire->port_output) -		fprintf(f, "%s" "output%s %s;\n", indent.c_str(), range.c_str(), id(wire->name).c_str()); +		f << stringf("%s" "output%s %s;\n", indent.c_str(), range.c_str(), id(wire->name).c_str());  	if (wire->port_input && wire->port_output) -		fprintf(f, "%s" "inout%s %s;\n", indent.c_str(), range.c_str(), id(wire->name).c_str()); +		f << stringf("%s" "inout%s %s;\n", indent.c_str(), range.c_str(), id(wire->name).c_str());  	if (reg_wires.count(wire->name)) -		fprintf(f, "%s" "reg%s %s;\n", indent.c_str(), range.c_str(), id(wire->name).c_str()); +		f << stringf("%s" "reg%s %s;\n", indent.c_str(), range.c_str(), id(wire->name).c_str());  	else if (!wire->port_input && !wire->port_output) -		fprintf(f, "%s" "wire%s %s;\n", indent.c_str(), range.c_str(), id(wire->name).c_str()); +		f << stringf("%s" "wire%s %s;\n", indent.c_str(), range.c_str(), id(wire->name).c_str());  #endif  } -void dump_memory(FILE *f, std::string indent, RTLIL::Memory *memory) +void dump_memory(std::ostream &f, std::string indent, RTLIL::Memory *memory)  {  	dump_attributes(f, indent, memory->attributes); -	fprintf(f, "%s" "reg [%d:0] %s [%d:0];\n", indent.c_str(), memory->width-1, id(memory->name).c_str(), memory->size-1); +	f << stringf("%s" "reg [%d:0] %s [%d:0];\n", indent.c_str(), memory->width-1, id(memory->name).c_str(), memory->size-1);  } -void dump_cell_expr_port(FILE *f, RTLIL::Cell *cell, std::string port, bool gen_signed = true) +void dump_cell_expr_port(std::ostream &f, RTLIL::Cell *cell, std::string port, bool gen_signed = true)  {  	if (gen_signed && cell->parameters.count("\\" + port + "_SIGNED") > 0 && cell->parameters["\\" + port + "_SIGNED"].as_bool()) { -		fprintf(f, "$signed("); +		f << stringf("$signed(");  		dump_sigspec(f, cell->getPort("\\" + port)); -		fprintf(f, ")"); +		f << stringf(")");  	} else  		dump_sigspec(f, cell->getPort("\\" + port));  } @@ -346,107 +346,107 @@ no_special_reg_name:  	}  } -void dump_cell_expr_uniop(FILE *f, std::string indent, RTLIL::Cell *cell, std::string op) +void dump_cell_expr_uniop(std::ostream &f, std::string indent, RTLIL::Cell *cell, std::string op)  { -	fprintf(f, "%s" "assign ", indent.c_str()); +	f << stringf("%s" "assign ", indent.c_str());  	dump_sigspec(f, cell->getPort("\\Y")); -	fprintf(f, " = %s ", op.c_str()); +	f << stringf(" = %s ", op.c_str());  	dump_attributes(f, "", cell->attributes, ' ');  	dump_cell_expr_port(f, cell, "A", true); -	fprintf(f, ";\n"); +	f << stringf(";\n");  } -void dump_cell_expr_binop(FILE *f, std::string indent, RTLIL::Cell *cell, std::string op) +void dump_cell_expr_binop(std::ostream &f, std::string indent, RTLIL::Cell *cell, std::string op)  { -	fprintf(f, "%s" "assign ", indent.c_str()); +	f << stringf("%s" "assign ", indent.c_str());  	dump_sigspec(f, cell->getPort("\\Y")); -	fprintf(f, " = "); +	f << stringf(" = ");  	dump_cell_expr_port(f, cell, "A", true); -	fprintf(f, " %s ", op.c_str()); +	f << stringf(" %s ", op.c_str());  	dump_attributes(f, "", cell->attributes, ' ');  	dump_cell_expr_port(f, cell, "B", true); -	fprintf(f, ";\n"); +	f << stringf(";\n");  } -bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell) +bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)  {  	if (cell->type == "$_NOT_") { -		fprintf(f, "%s" "assign ", indent.c_str()); +		f << stringf("%s" "assign ", indent.c_str());  		dump_sigspec(f, cell->getPort("\\Y")); -		fprintf(f, " = "); -		fprintf(f, "~"); +		f << stringf(" = "); +		f << stringf("~");  		dump_attributes(f, "", cell->attributes, ' ');  		dump_cell_expr_port(f, cell, "A", false); -		fprintf(f, ";\n"); +		f << stringf(";\n");  		return true;  	}  	if (cell->type.in("$_AND_", "$_NAND_", "$_OR_", "$_NOR_", "$_XOR_", "$_XNOR_")) { -		fprintf(f, "%s" "assign ", indent.c_str()); +		f << stringf("%s" "assign ", indent.c_str());  		dump_sigspec(f, cell->getPort("\\Y")); -		fprintf(f, " = "); +		f << stringf(" = ");  		if (cell->type.in("$_NAND_", "$_NOR_", "$_XNOR_")) -			fprintf(f, "~("); +			f << stringf("~(");  		dump_cell_expr_port(f, cell, "A", false); -		fprintf(f, " "); +		f << stringf(" ");  		if (cell->type.in("$_AND_", "$_NAND_")) -			fprintf(f, "&"); +			f << stringf("&");  		if (cell->type.in("$_OR_", "$_NOR_")) -			fprintf(f, "|"); +			f << stringf("|");  		if (cell->type.in("$_XOR_", "$_XNOR_")) -			fprintf(f, "^"); +			f << stringf("^");  		dump_attributes(f, "", cell->attributes, ' '); -		fprintf(f, " "); +		f << stringf(" ");  		dump_cell_expr_port(f, cell, "B", false);  		if (cell->type.in("$_NAND_", "$_NOR_", "$_XNOR_")) -			fprintf(f, ")"); -		fprintf(f, ";\n"); +			f << stringf(")"); +		f << stringf(";\n");  		return true;  	}  	if (cell->type == "$_MUX_") { -		fprintf(f, "%s" "assign ", indent.c_str()); +		f << stringf("%s" "assign ", indent.c_str());  		dump_sigspec(f, cell->getPort("\\Y")); -		fprintf(f, " = "); +		f << stringf(" = ");  		dump_cell_expr_port(f, cell, "S", false); -		fprintf(f, " ? "); +		f << stringf(" ? ");  		dump_attributes(f, "", cell->attributes, ' ');  		dump_cell_expr_port(f, cell, "B", false); -		fprintf(f, " : "); +		f << stringf(" : ");  		dump_cell_expr_port(f, cell, "A", false); -		fprintf(f, ";\n"); +		f << stringf(";\n");  		return true;  	}  	if (cell->type.in("$_AOI3_", "$_OAI3_")) { -		fprintf(f, "%s" "assign ", indent.c_str()); +		f << stringf("%s" "assign ", indent.c_str());  		dump_sigspec(f, cell->getPort("\\Y")); -		fprintf(f, " = ~(("); +		f << stringf(" = ~((");  		dump_cell_expr_port(f, cell, "A", false); -		fprintf(f, cell->type == "$_AOI3_" ? " & " : " | "); +		f << stringf(cell->type == "$_AOI3_" ? " & " : " | ");  		dump_cell_expr_port(f, cell, "B", false); -		fprintf(f, cell->type == "$_AOI3_" ? ") |" : ") &"); +		f << stringf(cell->type == "$_AOI3_" ? ") |" : ") &");  		dump_attributes(f, "", cell->attributes, ' '); -		fprintf(f, " "); +		f << stringf(" ");  		dump_cell_expr_port(f, cell, "C", false); -		fprintf(f, ");\n"); +		f << stringf(");\n");  		return true;  	}  	if (cell->type.in("$_AOI4_", "$_OAI4_")) { -		fprintf(f, "%s" "assign ", indent.c_str()); +		f << stringf("%s" "assign ", indent.c_str());  		dump_sigspec(f, cell->getPort("\\Y")); -		fprintf(f, " = ~(("); +		f << stringf(" = ~((");  		dump_cell_expr_port(f, cell, "A", false); -		fprintf(f, cell->type == "$_AOI4_" ? " & " : " | "); +		f << stringf(cell->type == "$_AOI4_" ? " & " : " | ");  		dump_cell_expr_port(f, cell, "B", false); -		fprintf(f, cell->type == "$_AOI4_" ? ") |" : ") &"); +		f << stringf(cell->type == "$_AOI4_" ? ") |" : ") &");  		dump_attributes(f, "", cell->attributes, ' '); -		fprintf(f, " ("); +		f << stringf(" (");  		dump_cell_expr_port(f, cell, "C", false); -		fprintf(f, cell->type == "$_AOI4_" ? " & " : " | "); +		f << stringf(cell->type == "$_AOI4_" ? " & " : " | ");  		dump_cell_expr_port(f, cell, "D", false); -		fprintf(f, "));\n"); +		f << stringf("));\n");  		return true;  	} @@ -456,33 +456,33 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell)  		bool out_is_reg_wire = is_reg_wire(cell->getPort("\\Q"), reg_name);  		if (!out_is_reg_wire) -			fprintf(f, "%s" "reg %s;\n", indent.c_str(), reg_name.c_str()); +			f << stringf("%s" "reg %s;\n", indent.c_str(), reg_name.c_str());  		dump_attributes(f, indent, cell->attributes); -		fprintf(f, "%s" "always @(%sedge ", indent.c_str(), cell->type[6] == 'P' ? "pos" : "neg"); +		f << stringf("%s" "always @(%sedge ", indent.c_str(), cell->type[6] == 'P' ? "pos" : "neg");  		dump_sigspec(f, cell->getPort("\\C"));  		if (cell->type[7] != '_') { -			fprintf(f, " or %sedge ", cell->type[7] == 'P' ? "pos" : "neg"); +			f << stringf(" or %sedge ", cell->type[7] == 'P' ? "pos" : "neg");  			dump_sigspec(f, cell->getPort("\\R"));  		} -		fprintf(f, ")\n"); +		f << stringf(")\n");  		if (cell->type[7] != '_') { -			fprintf(f, "%s" "  if (%s", indent.c_str(), cell->type[7] == 'P' ? "" : "!"); +			f << stringf("%s" "  if (%s", indent.c_str(), cell->type[7] == 'P' ? "" : "!");  			dump_sigspec(f, cell->getPort("\\R")); -			fprintf(f, ")\n"); -			fprintf(f, "%s" "    %s <= %c;\n", indent.c_str(), reg_name.c_str(), cell->type[8]); -			fprintf(f, "%s" "  else\n", indent.c_str()); +			f << stringf(")\n"); +			f << stringf("%s" "    %s <= %c;\n", indent.c_str(), reg_name.c_str(), cell->type[8]); +			f << stringf("%s" "  else\n", indent.c_str());  		} -		fprintf(f, "%s" "    %s <= ", indent.c_str(), reg_name.c_str()); +		f << stringf("%s" "    %s <= ", indent.c_str(), reg_name.c_str());  		dump_cell_expr_port(f, cell, "D", false); -		fprintf(f, ";\n"); +		f << stringf(";\n");  		if (!out_is_reg_wire) { -			fprintf(f, "%s" "assign ", indent.c_str()); +			f << stringf("%s" "assign ", indent.c_str());  			dump_sigspec(f, cell->getPort("\\Q")); -			fprintf(f, " = %s;\n", reg_name.c_str()); +			f << stringf(" = %s;\n", reg_name.c_str());  		}  		return true; @@ -496,36 +496,36 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell)  		bool out_is_reg_wire = is_reg_wire(cell->getPort("\\Q"), reg_name);  		if (!out_is_reg_wire) -			fprintf(f, "%s" "reg %s;\n", indent.c_str(), reg_name.c_str()); +			f << stringf("%s" "reg %s;\n", indent.c_str(), reg_name.c_str());  		dump_attributes(f, indent, cell->attributes); -		fprintf(f, "%s" "always @(%sedge ", indent.c_str(), pol_c == 'P' ? "pos" : "neg"); +		f << stringf("%s" "always @(%sedge ", indent.c_str(), pol_c == 'P' ? "pos" : "neg");  		dump_sigspec(f, cell->getPort("\\C")); -		fprintf(f, " or %sedge ", pol_s == 'P' ? "pos" : "neg"); +		f << stringf(" or %sedge ", pol_s == 'P' ? "pos" : "neg");  		dump_sigspec(f, cell->getPort("\\S")); -		fprintf(f, " or %sedge ", pol_r == 'P' ? "pos" : "neg"); +		f << stringf(" or %sedge ", pol_r == 'P' ? "pos" : "neg");  		dump_sigspec(f, cell->getPort("\\R")); -		fprintf(f, ")\n"); +		f << stringf(")\n"); -		fprintf(f, "%s" "  if (%s", indent.c_str(), pol_r == 'P' ? "" : "!"); +		f << stringf("%s" "  if (%s", indent.c_str(), pol_r == 'P' ? "" : "!");  		dump_sigspec(f, cell->getPort("\\R")); -		fprintf(f, ")\n"); -		fprintf(f, "%s" "    %s <= 0;\n", indent.c_str(), reg_name.c_str()); +		f << stringf(")\n"); +		f << stringf("%s" "    %s <= 0;\n", indent.c_str(), reg_name.c_str()); -		fprintf(f, "%s" "  else if (%s", indent.c_str(), pol_s == 'P' ? "" : "!"); +		f << stringf("%s" "  else if (%s", indent.c_str(), pol_s == 'P' ? "" : "!");  		dump_sigspec(f, cell->getPort("\\S")); -		fprintf(f, ")\n"); -		fprintf(f, "%s" "    %s <= 1;\n", indent.c_str(), reg_name.c_str()); +		f << stringf(")\n"); +		f << stringf("%s" "    %s <= 1;\n", indent.c_str(), reg_name.c_str()); -		fprintf(f, "%s" "  else\n", indent.c_str()); -		fprintf(f, "%s" "    %s <= ", indent.c_str(), reg_name.c_str()); +		f << stringf("%s" "  else\n", indent.c_str()); +		f << stringf("%s" "    %s <= ", indent.c_str(), reg_name.c_str());  		dump_cell_expr_port(f, cell, "D", false); -		fprintf(f, ";\n"); +		f << stringf(";\n");  		if (!out_is_reg_wire) { -			fprintf(f, "%s" "assign ", indent.c_str()); +			f << stringf("%s" "assign ", indent.c_str());  			dump_sigspec(f, cell->getPort("\\Q")); -			fprintf(f, " = %s;\n", reg_name.c_str()); +			f << stringf(" = %s;\n", reg_name.c_str());  		}  		return true; @@ -581,16 +581,16 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell)  	if (cell->type == "$mux")  	{ -		fprintf(f, "%s" "assign ", indent.c_str()); +		f << stringf("%s" "assign ", indent.c_str());  		dump_sigspec(f, cell->getPort("\\Y")); -		fprintf(f, " = "); +		f << stringf(" = ");  		dump_sigspec(f, cell->getPort("\\S")); -		fprintf(f, " ? "); +		f << stringf(" ? ");  		dump_attributes(f, "", cell->attributes, ' ');  		dump_sigspec(f, cell->getPort("\\B")); -		fprintf(f, " : "); +		f << stringf(" : ");  		dump_sigspec(f, cell->getPort("\\A")); -		fprintf(f, ";\n"); +		f << stringf(";\n");  		return true;  	} @@ -600,82 +600,82 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell)  		int s_width = cell->getPort("\\S").size();  		std::string func_name = cellname(cell); -		fprintf(f, "%s" "function [%d:0] %s;\n", indent.c_str(), width-1, func_name.c_str()); -		fprintf(f, "%s" "  input [%d:0] a;\n", indent.c_str(), width-1); -		fprintf(f, "%s" "  input [%d:0] b;\n", indent.c_str(), s_width*width-1); -		fprintf(f, "%s" "  input [%d:0] s;\n", indent.c_str(), s_width-1); +		f << stringf("%s" "function [%d:0] %s;\n", indent.c_str(), width-1, func_name.c_str()); +		f << stringf("%s" "  input [%d:0] a;\n", indent.c_str(), width-1); +		f << stringf("%s" "  input [%d:0] b;\n", indent.c_str(), s_width*width-1); +		f << stringf("%s" "  input [%d:0] s;\n", indent.c_str(), s_width-1);  		dump_attributes(f, indent + "  ", cell->attributes);  		if (cell->type != "$pmux_safe" && !noattr) -			fprintf(f, "%s" "  (* parallel_case *)\n", indent.c_str()); -		fprintf(f, "%s" "  casez (s)", indent.c_str()); +			f << stringf("%s" "  (* parallel_case *)\n", indent.c_str()); +		f << stringf("%s" "  casez (s)", indent.c_str());  		if (cell->type != "$pmux_safe") -			fprintf(f, noattr ? " // synopsys parallel_case\n" : "\n"); +			f << stringf(noattr ? " // synopsys parallel_case\n" : "\n");  		for (int i = 0; i < s_width; i++)  		{ -			fprintf(f, "%s" "    %d'b", indent.c_str(), s_width); +			f << stringf("%s" "    %d'b", indent.c_str(), s_width);  			for (int j = s_width-1; j >= 0; j--) -				fprintf(f, "%c", j == i ? '1' : cell->type == "$pmux_safe" ? '0' : '?'); +				f << stringf("%c", j == i ? '1' : cell->type == "$pmux_safe" ? '0' : '?'); -			fprintf(f, ":\n"); -			fprintf(f, "%s" "      %s = b[%d:%d];\n", indent.c_str(), func_name.c_str(), (i+1)*width-1, i*width); +			f << stringf(":\n"); +			f << stringf("%s" "      %s = b[%d:%d];\n", indent.c_str(), func_name.c_str(), (i+1)*width-1, i*width);  		} -		fprintf(f, "%s" "    default:\n", indent.c_str()); -		fprintf(f, "%s" "      %s = a;\n", indent.c_str(), func_name.c_str()); +		f << stringf("%s" "    default:\n", indent.c_str()); +		f << stringf("%s" "      %s = a;\n", indent.c_str(), func_name.c_str()); -		fprintf(f, "%s" "  endcase\n", indent.c_str()); -		fprintf(f, "%s" "endfunction\n", indent.c_str()); +		f << stringf("%s" "  endcase\n", indent.c_str()); +		f << stringf("%s" "endfunction\n", indent.c_str()); -		fprintf(f, "%s" "assign ", indent.c_str()); +		f << stringf("%s" "assign ", indent.c_str());  		dump_sigspec(f, cell->getPort("\\Y")); -		fprintf(f, " = %s(", func_name.c_str()); +		f << stringf(" = %s(", func_name.c_str());  		dump_sigspec(f, cell->getPort("\\A")); -		fprintf(f, ", "); +		f << stringf(", ");  		dump_sigspec(f, cell->getPort("\\B")); -		fprintf(f, ", "); +		f << stringf(", ");  		dump_sigspec(f, cell->getPort("\\S")); -		fprintf(f, ");\n"); +		f << stringf(");\n");  		return true;  	}  	if (cell->type == "$slice")  	{ -		fprintf(f, "%s" "assign ", indent.c_str()); +		f << stringf("%s" "assign ", indent.c_str());  		dump_sigspec(f, cell->getPort("\\Y")); -		fprintf(f, " = "); +		f << stringf(" = ");  		dump_sigspec(f, cell->getPort("\\A")); -		fprintf(f, " >> %d;\n", cell->parameters.at("\\OFFSET").as_int()); +		f << stringf(" >> %d;\n", cell->parameters.at("\\OFFSET").as_int());  		return true;  	}  	if (cell->type == "$bu0")  	{ -		fprintf(f, "%s" "assign ", indent.c_str()); +		f << stringf("%s" "assign ", indent.c_str());  		dump_sigspec(f, cell->getPort("\\Y"));  		if (cell->parameters["\\A_SIGNED"].as_bool()) { -			fprintf(f, " = $signed("); +			f << stringf(" = $signed(");  			dump_sigspec(f, cell->getPort("\\A")); -			fprintf(f, ");\n"); +			f << stringf(");\n");  		} else { -			fprintf(f, " = { 1'b0, "); +			f << stringf(" = { 1'b0, ");  			dump_sigspec(f, cell->getPort("\\A")); -			fprintf(f, " };\n"); +			f << stringf(" };\n");  		}  		return true;  	}  	if (cell->type == "$concat")  	{ -		fprintf(f, "%s" "assign ", indent.c_str()); +		f << stringf("%s" "assign ", indent.c_str());  		dump_sigspec(f, cell->getPort("\\Y")); -		fprintf(f, " = { "); +		f << stringf(" = { ");  		dump_sigspec(f, cell->getPort("\\B")); -		fprintf(f, " , "); +		f << stringf(" , ");  		dump_sigspec(f, cell->getPort("\\A")); -		fprintf(f, " };\n"); +		f << stringf(" };\n");  		return true;  	} @@ -697,34 +697,34 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell)  		bool out_is_reg_wire = is_reg_wire(cell->getPort("\\Q"), reg_name);  		if (!out_is_reg_wire) -			fprintf(f, "%s" "reg [%d:0] %s;\n", indent.c_str(), cell->parameters["\\WIDTH"].as_int()-1, reg_name.c_str()); +			f << stringf("%s" "reg [%d:0] %s;\n", indent.c_str(), cell->parameters["\\WIDTH"].as_int()-1, reg_name.c_str()); -		fprintf(f, "%s" "always @(%sedge ", indent.c_str(), pol_clk ? "pos" : "neg"); +		f << stringf("%s" "always @(%sedge ", indent.c_str(), pol_clk ? "pos" : "neg");  		dump_sigspec(f, sig_clk);  		if (cell->type == "$adff") { -			fprintf(f, " or %sedge ", pol_arst ? "pos" : "neg"); +			f << stringf(" or %sedge ", pol_arst ? "pos" : "neg");  			dump_sigspec(f, sig_arst);  		} -		fprintf(f, ")\n"); +		f << stringf(")\n");  		if (cell->type == "$adff") { -			fprintf(f, "%s" "  if (%s", indent.c_str(), pol_arst ? "" : "!"); +			f << stringf("%s" "  if (%s", indent.c_str(), pol_arst ? "" : "!");  			dump_sigspec(f, sig_arst); -			fprintf(f, ")\n"); -			fprintf(f, "%s" "    %s <= ", indent.c_str(), reg_name.c_str()); +			f << stringf(")\n"); +			f << stringf("%s" "    %s <= ", indent.c_str(), reg_name.c_str());  			dump_sigspec(f, val_arst); -			fprintf(f, ";\n"); -			fprintf(f, "%s" "  else\n", indent.c_str()); +			f << stringf(";\n"); +			f << stringf("%s" "  else\n", indent.c_str());  		} -		fprintf(f, "%s" "    %s <= ", indent.c_str(), reg_name.c_str()); +		f << stringf("%s" "    %s <= ", indent.c_str(), reg_name.c_str());  		dump_cell_expr_port(f, cell, "D", false); -		fprintf(f, ";\n"); +		f << stringf(";\n");  		if (!out_is_reg_wire) { -			fprintf(f, "%s" "assign ", indent.c_str()); +			f << stringf("%s" "assign ", indent.c_str());  			dump_sigspec(f, cell->getPort("\\Q")); -			fprintf(f, " = %s;\n", reg_name.c_str()); +			f << stringf(" = %s;\n", reg_name.c_str());  		}  		return true; @@ -736,7 +736,7 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell)  	return false;  } -void dump_cell(FILE *f, std::string indent, RTLIL::Cell *cell) +void dump_cell(std::ostream &f, std::string indent, RTLIL::Cell *cell)  {  	if (cell->type[0] == '$' && !noexpr) {  		if (dump_cell_expr(f, indent, cell)) @@ -744,26 +744,26 @@ void dump_cell(FILE *f, std::string indent, RTLIL::Cell *cell)  	}  	dump_attributes(f, indent, cell->attributes); -	fprintf(f, "%s" "%s", indent.c_str(), id(cell->type, false).c_str()); +	f << stringf("%s" "%s", indent.c_str(), id(cell->type, false).c_str());  	if (cell->parameters.size() > 0) { -		fprintf(f, " #("); +		f << stringf(" #(");  		for (auto it = cell->parameters.begin(); it != cell->parameters.end(); it++) {  			if (it != cell->parameters.begin()) -				fprintf(f, ","); -			fprintf(f, "\n%s  .%s(", indent.c_str(), id(it->first).c_str()); +				f << stringf(","); +			f << stringf("\n%s  .%s(", indent.c_str(), id(it->first).c_str());  			bool is_signed = (it->second.flags & RTLIL::CONST_FLAG_SIGNED) != 0;  			dump_const(f, it->second, -1, 0, !is_signed, is_signed); -			fprintf(f, ")"); +			f << stringf(")");  		} -		fprintf(f, "\n%s" ")", indent.c_str()); +		f << stringf("\n%s" ")", indent.c_str());  	}  	std::string cell_name = cellname(cell);  	if (cell_name != id(cell->name)) -		fprintf(f, " %s /* %s */ (", cell_name.c_str(), id(cell->name).c_str()); +		f << stringf(" %s /* %s */ (", cell_name.c_str(), id(cell->name).c_str());  	else -		fprintf(f, " %s (", cell_name.c_str()); +		f << stringf(" %s (", cell_name.c_str());  	bool first_arg = true;  	std::set<RTLIL::IdString> numbered_ports; @@ -774,9 +774,9 @@ void dump_cell(FILE *f, std::string indent, RTLIL::Cell *cell)  			if (it->first != str)  				continue;  			if (!first_arg) -				fprintf(f, ","); +				f << stringf(",");  			first_arg = false; -			fprintf(f, "\n%s  ", indent.c_str()); +			f << stringf("\n%s  ", indent.c_str());  			dump_sigspec(f, it->second);  			numbered_ports.insert(it->first);  			goto found_numbered_port; @@ -788,86 +788,86 @@ void dump_cell(FILE *f, std::string indent, RTLIL::Cell *cell)  		if (numbered_ports.count(it->first))  			continue;  		if (!first_arg) -			fprintf(f, ","); +			f << stringf(",");  		first_arg = false; -		fprintf(f, "\n%s  .%s(", indent.c_str(), id(it->first).c_str()); +		f << stringf("\n%s  .%s(", indent.c_str(), id(it->first).c_str());  		if (it->second.size() > 0)  			dump_sigspec(f, it->second); -		fprintf(f, ")"); +		f << stringf(")");  	} -	fprintf(f, "\n%s" ");\n", indent.c_str()); +	f << stringf("\n%s" ");\n", indent.c_str());  } -void dump_conn(FILE *f, std::string indent, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right) +void dump_conn(std::ostream &f, std::string indent, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right)  { -	fprintf(f, "%s" "assign ", indent.c_str()); +	f << stringf("%s" "assign ", indent.c_str());  	dump_sigspec(f, left); -	fprintf(f, " = "); +	f << stringf(" = ");  	dump_sigspec(f, right); -	fprintf(f, ";\n"); +	f << stringf(";\n");  } -void dump_proc_switch(FILE *f, std::string indent, RTLIL::SwitchRule *sw); +void dump_proc_switch(std::ostream &f, std::string indent, RTLIL::SwitchRule *sw); -void dump_case_body(FILE *f, std::string indent, RTLIL::CaseRule *cs, bool omit_trailing_begin = false) +void dump_case_body(std::ostream &f, std::string indent, RTLIL::CaseRule *cs, bool omit_trailing_begin = false)  {  	int number_of_stmts = cs->switches.size() + cs->actions.size();  	if (!omit_trailing_begin && number_of_stmts >= 2) -		fprintf(f, "%s" "begin\n", indent.c_str()); +		f << stringf("%s" "begin\n", indent.c_str());  	for (auto it = cs->actions.begin(); it != cs->actions.end(); it++) {  		if (it->first.size() == 0)  			continue; -		fprintf(f, "%s  ", indent.c_str()); +		f << stringf("%s  ", indent.c_str());  		dump_sigspec(f, it->first); -		fprintf(f, " = "); +		f << stringf(" = ");  		dump_sigspec(f, it->second); -		fprintf(f, ";\n"); +		f << stringf(";\n");  	}  	for (auto it = cs->switches.begin(); it != cs->switches.end(); it++)  		dump_proc_switch(f, indent + "  ", *it);  	if (!omit_trailing_begin && number_of_stmts == 0) -		fprintf(f, "%s  /* empty */;\n", indent.c_str()); +		f << stringf("%s  /* empty */;\n", indent.c_str());  	if (omit_trailing_begin || number_of_stmts >= 2) -		fprintf(f, "%s" "end\n", indent.c_str()); +		f << stringf("%s" "end\n", indent.c_str());  } -void dump_proc_switch(FILE *f, std::string indent, RTLIL::SwitchRule *sw) +void dump_proc_switch(std::ostream &f, std::string indent, RTLIL::SwitchRule *sw)  {  	if (sw->signal.size() == 0) { -		fprintf(f, "%s" "begin\n", indent.c_str()); +		f << stringf("%s" "begin\n", indent.c_str());  		for (auto it = sw->cases.begin(); it != sw->cases.end(); it++) {  			if ((*it)->compare.size() == 0)  				dump_case_body(f, indent + "  ", *it);  		} -		fprintf(f, "%s" "end\n", indent.c_str()); +		f << stringf("%s" "end\n", indent.c_str());  		return;  	} -	fprintf(f, "%s" "casez (", indent.c_str()); +	f << stringf("%s" "casez (", indent.c_str());  	dump_sigspec(f, sw->signal); -	fprintf(f, ")\n"); +	f << stringf(")\n");  	for (auto it = sw->cases.begin(); it != sw->cases.end(); it++) { -		fprintf(f, "%s  ", indent.c_str()); +		f << stringf("%s  ", indent.c_str());  		if ((*it)->compare.size() == 0) -			fprintf(f, "default"); +			f << stringf("default");  		else {  			for (size_t i = 0; i < (*it)->compare.size(); i++) {  				if (i > 0) -					fprintf(f, ", "); +					f << stringf(", ");  				dump_sigspec(f, (*it)->compare[i]);  			}  		} -		fprintf(f, ":\n"); +		f << stringf(":\n");  		dump_case_body(f, indent + "    ", *it);  	} -	fprintf(f, "%s" "endcase\n", indent.c_str()); +	f << stringf("%s" "endcase\n", indent.c_str());  }  void case_body_find_regs(RTLIL::CaseRule *cs) @@ -883,7 +883,7 @@ void case_body_find_regs(RTLIL::CaseRule *cs)  	}  } -void dump_process(FILE *f, std::string indent, RTLIL::Process *proc, bool find_regs = false) +void dump_process(std::ostream &f, std::string indent, RTLIL::Process *proc, bool find_regs = false)  {  	if (find_regs) {  		case_body_find_regs(&proc->root_case); @@ -896,7 +896,7 @@ void dump_process(FILE *f, std::string indent, RTLIL::Process *proc, bool find_r  		return;  	} -	fprintf(f, "%s" "always @* begin\n", indent.c_str()); +	f << stringf("%s" "always @* begin\n", indent.c_str());  	dump_case_body(f, indent, &proc->root_case, true);  	std::string backup_indent = indent; @@ -907,23 +907,23 @@ void dump_process(FILE *f, std::string indent, RTLIL::Process *proc, bool find_r  		indent = backup_indent;  		if (sync->type == RTLIL::STa) { -			fprintf(f, "%s" "always @* begin\n", indent.c_str()); +			f << stringf("%s" "always @* begin\n", indent.c_str());  		} else { -			fprintf(f, "%s" "always @(", indent.c_str()); +			f << stringf("%s" "always @(", indent.c_str());  			if (sync->type == RTLIL::STp || sync->type == RTLIL::ST1) -				fprintf(f, "posedge "); +				f << stringf("posedge ");  			if (sync->type == RTLIL::STn || sync->type == RTLIL::ST0) -				fprintf(f, "negedge "); +				f << stringf("negedge ");  			dump_sigspec(f, sync->signal); -			fprintf(f, ") begin\n"); +			f << stringf(") begin\n");  		}  		std::string ends = indent + "end\n";  		indent += "  ";  		if (sync->type == RTLIL::ST0 || sync->type == RTLIL::ST1) { -			fprintf(f, "%s" "if (%s", indent.c_str(), sync->type == RTLIL::ST0 ? "!" : ""); +			f << stringf("%s" "if (%s", indent.c_str(), sync->type == RTLIL::ST0 ? "!" : "");  			dump_sigspec(f, sync->signal); -			fprintf(f, ") begin\n"); +			f << stringf(") begin\n");  			ends = indent + "end\n" + ends;  			indent += "  ";  		} @@ -932,9 +932,9 @@ void dump_process(FILE *f, std::string indent, RTLIL::Process *proc, bool find_r  			for (size_t j = 0; j < proc->syncs.size(); j++) {  				RTLIL::SyncRule *sync2 = proc->syncs[j];  				if (sync2->type == RTLIL::ST0 || sync2->type == RTLIL::ST1) { -					fprintf(f, "%s" "if (%s", indent.c_str(), sync2->type == RTLIL::ST1 ? "!" : ""); +					f << stringf("%s" "if (%s", indent.c_str(), sync2->type == RTLIL::ST1 ? "!" : "");  					dump_sigspec(f, sync2->signal); -					fprintf(f, ") begin\n"); +					f << stringf(") begin\n");  					ends = indent + "end\n" + ends;  					indent += "  ";  				} @@ -944,24 +944,24 @@ void dump_process(FILE *f, std::string indent, RTLIL::Process *proc, bool find_r  		for (auto it = sync->actions.begin(); it != sync->actions.end(); it++) {  			if (it->first.size() == 0)  				continue; -			fprintf(f, "%s  ", indent.c_str()); +			f << stringf("%s  ", indent.c_str());  			dump_sigspec(f, it->first); -			fprintf(f, " <= "); +			f << stringf(" <= ");  			dump_sigspec(f, it->second); -			fprintf(f, ";\n"); +			f << stringf(";\n");  		} -		fprintf(f, "%s", ends.c_str()); +		f << stringf("%s", ends.c_str());  	}  } -void dump_module(FILE *f, std::string indent, RTLIL::Module *module) +void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module)  {  	reg_wires.clear();  	reset_auto_counter(module);  	active_module = module; -	fprintf(f, "\n"); +	f << stringf("\n");  	for (auto it = module->processes.begin(); it != module->processes.end(); it++)  		dump_process(f, indent + "  ", it->second, true); @@ -995,7 +995,7 @@ void dump_module(FILE *f, std::string indent, RTLIL::Module *module)  	}  	dump_attributes(f, indent, module->attributes); -	fprintf(f, "%s" "module %s(", indent.c_str(), id(module->name, false).c_str()); +	f << stringf("%s" "module %s(", indent.c_str(), id(module->name, false).c_str());  	bool keep_running = true;  	for (int port_id = 1; keep_running; port_id++) {  		keep_running = false; @@ -1003,14 +1003,14 @@ void dump_module(FILE *f, std::string indent, RTLIL::Module *module)  			RTLIL::Wire *wire = it->second;  			if (wire->port_id == port_id) {  				if (port_id != 1) -					fprintf(f, ", "); -				fprintf(f, "%s", id(wire->name).c_str()); +					f << stringf(", "); +				f << stringf("%s", id(wire->name).c_str());  				keep_running = true;  				continue;  			}  		}  	} -	fprintf(f, ");\n"); +	f << stringf(");\n");  	for (auto it = module->wires_.begin(); it != module->wires_.end(); it++)  		dump_wire(f, indent + "  ", it->second); @@ -1027,7 +1027,7 @@ void dump_module(FILE *f, std::string indent, RTLIL::Module *module)  	for (auto it = module->connections().begin(); it != module->connections().end(); it++)  		dump_conn(f, indent + "  ", it->first, it->second); -	fprintf(f, "%s" "endmodule\n", indent.c_str()); +	f << stringf("%s" "endmodule\n", indent.c_str());  	active_module = NULL;  } @@ -1068,7 +1068,7 @@ struct VerilogBackend : public Backend {  		log("        not at all.\n");  		log("\n");  	} -	virtual void execute(FILE *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) +	virtual void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design)  	{  		log_header("Executing Verilog backend.\n"); @@ -1137,7 +1137,7 @@ struct VerilogBackend : public Backend {  		}  		extra_args(f, filename, args, argidx); -		fprintf(f, "/* Generated by %s */\n", yosys_version_str); +		*f << stringf("/* Generated by %s */\n", yosys_version_str);  		for (auto it = design->modules_.begin(); it != design->modules_.end(); it++) {  			if (it->second->get_bool_attribute("\\blackbox") != blackboxes)  				continue; @@ -1147,7 +1147,7 @@ struct VerilogBackend : public Backend {  				continue;  			}  			log("Dumping module `%s'.\n", it->first.c_str()); -			dump_module(f, "", it->second); +			dump_module(*f, "", it->second);  		}  		reg_ct.clear(); diff --git a/backends/verilog/verilog_backend.h b/backends/verilog/verilog_backend.h index c40830ef2..7e6ef5ab9 100644 --- a/backends/verilog/verilog_backend.h +++ b/backends/verilog/verilog_backend.h @@ -29,11 +29,10 @@  #ifndef VERILOG_BACKEND_H  #define VERILOG_BACKEND_H -#include "kernel/rtlil.h" -#include <stdio.h> +#include "kernel/yosys.h"  namespace VERILOG_BACKEND { -	void verilog_backend(FILE *f, std::vector<std::string> args, RTLIL::Design *design); +	void verilog_backend(std::ostream &f, std::vector<std::string> args, RTLIL::Design *design);  }  #endif diff --git a/kernel/log.cc b/kernel/log.cc index b742a5495..2b4b5db5b 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -210,20 +210,14 @@ void log_dump_val_worker(RTLIL::SigSpec v) {  const char *log_signal(const RTLIL::SigSpec &sig, bool autoint)  { -	char *ptr; -	size_t size; - -	FILE *f = open_memstream(&ptr, &size); -	ILANG_BACKEND::dump_sigspec(f, sig, autoint); -	fputc(0, f); -	fclose(f); +	std::stringstream buf; +	ILANG_BACKEND::dump_sigspec(buf, sig, autoint);  	if (string_buf_size < 100)  		string_buf_size++;  	else  		string_buf.pop_front(); -	string_buf.push_back(ptr); -	free(ptr); +	string_buf.push_back(buf.str());  	return string_buf.back().c_str();  } @@ -239,16 +233,9 @@ const char *log_id(RTLIL::IdString str)  void log_cell(RTLIL::Cell *cell, std::string indent)  { -	char *ptr; -	size_t size; - -	FILE *f = open_memstream(&ptr, &size); -	ILANG_BACKEND::dump_cell(f, indent, cell); -	fputc(0, f); -	fclose(f); - -	log("%s", ptr); -	free(ptr); +	std::stringstream buf; +	ILANG_BACKEND::dump_cell(buf, indent, cell); +	log("%s", buf.str().c_str());  }  // --------------------------------------------------- diff --git a/kernel/register.cc b/kernel/register.cc index a9e21e6dd..95ed0cbd1 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -423,15 +423,15 @@ Backend::~Backend()  void Backend::execute(std::vector<std::string> args, RTLIL::Design *design)  { -	FILE *f = NULL; +	std::ostream *f = NULL;  	auto state = pre_execute();  	execute(f, std::string(), args, design);  	post_execute(state); -	if (f != stdout) -		fclose(f); +	if (f != &std::cout) +		delete f;  } -void Backend::extra_args(FILE *&f, std::string &filename, std::vector<std::string> args, size_t argidx) +void Backend::extra_args(std::ostream *&f, std::string &filename, std::vector<std::string> args, size_t argidx)  {  	bool called_with_fp = f != NULL; @@ -446,14 +446,18 @@ void Backend::extra_args(FILE *&f, std::string &filename, std::vector<std::strin  		if (arg == "-") {  			filename = "<stdout>"; -			f = stdout; +			f = &std::cout;  			continue;  		}  		filename = arg; -		f = fopen(filename.c_str(), "w"); -		if (f == NULL) +		std::ofstream *ff = new std::ofstream; +		ff->open(filename.c_str(), std::ofstream::trunc); +		if (ff->fail()) { +			delete ff;  			log_cmd_error("Can't open output file `%s' for writing: %s\n", filename.c_str(), strerror(errno)); +		} +		f = ff;  	}  	if (called_with_fp) @@ -463,11 +467,11 @@ void Backend::extra_args(FILE *&f, std::string &filename, std::vector<std::strin  	if (f == NULL) {  		filename = "<stdout>"; -		f = stdout; +		f = &std::cout;  	}  } -void Backend::backend_call(RTLIL::Design *design, FILE *f, std::string filename, std::string command) +void Backend::backend_call(RTLIL::Design *design, std::ostream *f, std::string filename, std::string command)  {  	std::vector<std::string> args;  	char *s = strdup(command.c_str()); @@ -477,7 +481,7 @@ void Backend::backend_call(RTLIL::Design *design, FILE *f, std::string filename,  	backend_call(design, f, filename, args);  } -void Backend::backend_call(RTLIL::Design *design, FILE *f, std::string filename, std::vector<std::string> args) +void Backend::backend_call(RTLIL::Design *design, std::ostream *f, std::string filename, std::vector<std::string> args)  {  	if (args.size() == 0)  		return; @@ -491,9 +495,9 @@ void Backend::backend_call(RTLIL::Design *design, FILE *f, std::string filename,  		backend_register[args[0]]->execute(f, filename, args, design);  		backend_register[args[0]]->post_execute(state);  	} else if (filename == "-") { -		FILE *f_stdout = stdout; // workaround for OpenBSD 'stdout' implementation +		std::ostream *f_cout = &std::cout;  		auto state = backend_register[args[0]]->pre_execute(); -		backend_register[args[0]]->execute(f_stdout, "<stdout>", args, design); +		backend_register[args[0]]->execute(f_cout, "<stdout>", args, design);  		backend_register[args[0]]->post_execute(state);  	} else {  		if (!filename.empty()) diff --git a/kernel/register.h b/kernel/register.h index d7e4281c2..f2c6ad29e 100644 --- a/kernel/register.h +++ b/kernel/register.h @@ -17,15 +17,11 @@   *   */ +#include "kernel/yosys.h" +  #ifndef REGISTER_H  #define REGISTER_H -#include "kernel/yosys.h" -#include <stdio.h> -#include <string> -#include <vector> -#include <map> -  YOSYS_NAMESPACE_BEGIN  struct Pass @@ -94,12 +90,12 @@ struct Backend : Pass  	virtual void run_register();  	virtual ~Backend();  	virtual void execute(std::vector<std::string> args, RTLIL::Design *design) OVERRIDE FINAL; -	virtual void execute(FILE *&f, std::string filename,  std::vector<std::string> args, RTLIL::Design *design) = 0; +	virtual void execute(std::ostream *&f, std::string filename,  std::vector<std::string> args, RTLIL::Design *design) = 0; -	void extra_args(FILE *&f, std::string &filename, std::vector<std::string> args, size_t argidx); +	void extra_args(std::ostream *&f, std::string &filename, std::vector<std::string> args, size_t argidx); -	static void backend_call(RTLIL::Design *design, FILE *f, std::string filename, std::string command); -	static void backend_call(RTLIL::Design *design, FILE *f, std::string filename, std::vector<std::string> args); +	static void backend_call(RTLIL::Design *design, std::ostream *f, std::string filename, std::string command); +	static void backend_call(RTLIL::Design *design, std::ostream *f, std::string filename, std::vector<std::string> args);  };  // implemented in passes/cmds/select.cc diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 22bff7bdb..28a451345 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -412,17 +412,12 @@ namespace {  		void error(int linenr)  		{ -			char *ptr; -			size_t size; - -			FILE *f = open_memstream(&ptr, &size); -			ILANG_BACKEND::dump_cell(f, "  ", cell); -			fputc(0, f); -			fclose(f); +			std::stringstream buf; +			ILANG_BACKEND::dump_cell(buf, "  ", cell);  			log_error("Found error in internal cell %s%s%s (%s) at %s:%d:\n%s",  					module ? module->name.c_str() : "", module ? "." : "", -					cell->name.c_str(), cell->type.c_str(), __FILE__, linenr, ptr); +					cell->name.c_str(), cell->type.c_str(), __FILE__, linenr, buf.str().c_str());  		}  		int param(const char *name) diff --git a/kernel/yosys.h b/kernel/yosys.h index c6cbcabc9..bfadb5ffc 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -45,6 +45,11 @@  #include <functional>  #include <initializer_list> +#include <sstream> +#include <fstream> +#include <ostream> +#include <iostream> +  #include <stdarg.h>  #include <stdlib.h>  #include <string.h> diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc index ebf4d77fc..eaa0f9fa3 100644 --- a/passes/techmap/extract.cc +++ b/passes/techmap/extract.cc @@ -747,11 +747,12 @@ struct ExtractPass : public Pass {  				}  			} -			FILE *f = fopen(mine_outfile.c_str(), "wt"); -			if (f == NULL) +			std::ofstream f; +			f.open(mine_outfile.c_str(), std::ofstream::trunc); +			if (f.fail())  				log_error("Can't open output file `%s'.\n", mine_outfile.c_str()); -			Backend::backend_call(map, f, mine_outfile, "ilang"); -			fclose(f); +			Backend::backend_call(map, &f, mine_outfile, "ilang"); +			f.close();  		}  		delete map; diff --git a/passes/tests/test_autotb.cc b/passes/tests/test_autotb.cc index d26002277..eed0f75f9 100644 --- a/passes/tests/test_autotb.cc +++ b/passes/tests/test_autotb.cc @@ -70,26 +70,26 @@ static std::string idy(std::string str1, std::string str2 = std::string(), std::  	return id(str1);  } -static void autotest(FILE *f, RTLIL::Design *design, int num_iter) +static void autotest(std::ostream &f, RTLIL::Design *design, int num_iter)  { -	fprintf(f, "module testbench;\n\n"); +	f << stringf("module testbench;\n\n"); -	fprintf(f, "integer i;\n\n"); +	f << stringf("integer i;\n\n"); -	fprintf(f, "reg [31:0] xorshift128_x = 123456789;\n"); -	fprintf(f, "reg [31:0] xorshift128_y = 362436069;\n"); -	fprintf(f, "reg [31:0] xorshift128_z = 521288629;\n"); -	fprintf(f, "reg [31:0] xorshift128_w = %u; // <-- seed value\n", int(time(NULL))); -	fprintf(f, "reg [31:0] xorshift128_t;\n\n"); -	fprintf(f, "task xorshift128;\n"); -	fprintf(f, "begin\n"); -	fprintf(f, "\txorshift128_t = xorshift128_x ^ (xorshift128_x << 11);\n"); -	fprintf(f, "\txorshift128_x = xorshift128_y;\n"); -	fprintf(f, "\txorshift128_y = xorshift128_z;\n"); -	fprintf(f, "\txorshift128_z = xorshift128_w;\n"); -	fprintf(f, "\txorshift128_w = xorshift128_w ^ (xorshift128_w >> 19) ^ xorshift128_t ^ (xorshift128_t >> 8);\n"); -	fprintf(f, "end\n"); -	fprintf(f, "endtask\n\n"); +	f << stringf("reg [31:0] xorshift128_x = 123456789;\n"); +	f << stringf("reg [31:0] xorshift128_y = 362436069;\n"); +	f << stringf("reg [31:0] xorshift128_z = 521288629;\n"); +	f << stringf("reg [31:0] xorshift128_w = %u; // <-- seed value\n", int(time(NULL))); +	f << stringf("reg [31:0] xorshift128_t;\n\n"); +	f << stringf("task xorshift128;\n"); +	f << stringf("begin\n"); +	f << stringf("\txorshift128_t = xorshift128_x ^ (xorshift128_x << 11);\n"); +	f << stringf("\txorshift128_x = xorshift128_y;\n"); +	f << stringf("\txorshift128_y = xorshift128_z;\n"); +	f << stringf("\txorshift128_z = xorshift128_w;\n"); +	f << stringf("\txorshift128_w = xorshift128_w ^ (xorshift128_w >> 19) ^ xorshift128_t ^ (xorshift128_t >> 8);\n"); +	f << stringf("end\n"); +	f << stringf("endtask\n\n");  	for (auto it = design->modules_.begin(); it != design->modules_.end(); it++)  	{ @@ -110,7 +110,7 @@ static void autotest(FILE *f, RTLIL::Design *design, int num_iter)  			if (wire->port_output) {  				count_ports++;  				signal_out[idy("sig", mod->name.str(), wire->name.str())] = wire->width; -				fprintf(f, "wire [%d:0] %s;\n", wire->width-1, idy("sig", mod->name.str(), wire->name.str()).c_str()); +				f << stringf("wire [%d:0] %s;\n", wire->width-1, idy("sig", mod->name.str(), wire->name.str()).c_str());  			} else if (wire->port_input) {  				count_ports++;  				bool is_clksignal = wire->get_bool_attribute("\\gentb_clock"); @@ -130,85 +130,85 @@ static void autotest(FILE *f, RTLIL::Design *design, int num_iter)  					if (wire->attributes.count("\\gentb_constant") != 0)  						signal_const[idy("sig", mod->name.str(), wire->name.str())] = wire->attributes["\\gentb_constant"].as_string();  				} -				fprintf(f, "reg [%d:0] %s;\n", wire->width-1, idy("sig", mod->name.str(), wire->name.str()).c_str()); +				f << stringf("reg [%d:0] %s;\n", wire->width-1, idy("sig", mod->name.str(), wire->name.str()).c_str());  			}  		} -		fprintf(f, "%s %s(\n", id(mod->name.str()).c_str(), idy("uut", mod->name.str()).c_str()); +		f << stringf("%s %s(\n", id(mod->name.str()).c_str(), idy("uut", mod->name.str()).c_str());  		for (auto it2 = mod->wires_.begin(); it2 != mod->wires_.end(); it2++) {  			RTLIL::Wire *wire = it2->second;  			if (wire->port_output || wire->port_input) -				fprintf(f, "\t.%s(%s)%s\n", id(wire->name.str()).c_str(), +				f << stringf("\t.%s(%s)%s\n", id(wire->name.str()).c_str(),  						idy("sig", mod->name.str(), wire->name.str()).c_str(), --count_ports ? "," : "");  		} -		fprintf(f, ");\n\n"); +		f << stringf(");\n\n"); -		fprintf(f, "task %s;\n", idy(mod->name.str(), "reset").c_str()); -		fprintf(f, "begin\n"); +		f << stringf("task %s;\n", idy(mod->name.str(), "reset").c_str()); +		f << stringf("begin\n");  		int delay_counter = 0;  		for (auto it = signal_in.begin(); it != signal_in.end(); it++) -			fprintf(f, "\t%s <= #%d 0;\n", it->first.c_str(), ++delay_counter*2); +			f << stringf("\t%s <= #%d 0;\n", it->first.c_str(), ++delay_counter*2);  		for (auto it = signal_clk.begin(); it != signal_clk.end(); it++) -			fprintf(f, "\t%s <= #%d 0;\n", it->first.c_str(), ++delay_counter*2); +			f << stringf("\t%s <= #%d 0;\n", it->first.c_str(), ++delay_counter*2);  		for (auto it = signal_clk.begin(); it != signal_clk.end(); it++) { -			fprintf(f, "\t#100; %s <= 1;\n", it->first.c_str()); -			fprintf(f, "\t#100; %s <= 0;\n", it->first.c_str()); +			f << stringf("\t#100; %s <= 1;\n", it->first.c_str()); +			f << stringf("\t#100; %s <= 0;\n", it->first.c_str());  		}  		delay_counter = 0;  		for (auto it = signal_in.begin(); it != signal_in.end(); it++) -			fprintf(f, "\t%s <= #%d ~0;\n", it->first.c_str(), ++delay_counter*2); +			f << stringf("\t%s <= #%d ~0;\n", it->first.c_str(), ++delay_counter*2);  		for (auto it = signal_clk.begin(); it != signal_clk.end(); it++) { -			fprintf(f, "\t#100; %s <= 1;\n", it->first.c_str()); -			fprintf(f, "\t#100; %s <= 0;\n", it->first.c_str()); +			f << stringf("\t#100; %s <= 1;\n", it->first.c_str()); +			f << stringf("\t#100; %s <= 0;\n", it->first.c_str());  		}  		delay_counter = 0;  		for (auto it = signal_in.begin(); it != signal_in.end(); it++) {  			if (signal_const.count(it->first) == 0)  				continue; -			fprintf(f, "\t%s <= #%d 'b%s;\n", it->first.c_str(), ++delay_counter*2, signal_const[it->first].c_str()); +			f << stringf("\t%s <= #%d 'b%s;\n", it->first.c_str(), ++delay_counter*2, signal_const[it->first].c_str());  		} -		fprintf(f, "end\n"); -		fprintf(f, "endtask\n\n"); +		f << stringf("end\n"); +		f << stringf("endtask\n\n"); -		fprintf(f, "task %s;\n", idy(mod->name.str(), "update_data").c_str()); -		fprintf(f, "begin\n"); +		f << stringf("task %s;\n", idy(mod->name.str(), "update_data").c_str()); +		f << stringf("begin\n");  		delay_counter = 0;  		for (auto it = signal_in.begin(); it != signal_in.end(); it++) {  			if (signal_const.count(it->first) > 0)  				continue; -			fprintf(f, "\txorshift128;\n"); -			fprintf(f, "\t%s <= #%d { xorshift128_x, xorshift128_y, xorshift128_z, xorshift128_w };\n", it->first.c_str(), ++delay_counter*2); +			f << stringf("\txorshift128;\n"); +			f << stringf("\t%s <= #%d { xorshift128_x, xorshift128_y, xorshift128_z, xorshift128_w };\n", it->first.c_str(), ++delay_counter*2);  		} -		fprintf(f, "end\n"); -		fprintf(f, "endtask\n\n"); +		f << stringf("end\n"); +		f << stringf("endtask\n\n"); -		fprintf(f, "task %s;\n", idy(mod->name.str(), "update_clock").c_str()); -		fprintf(f, "begin\n"); +		f << stringf("task %s;\n", idy(mod->name.str(), "update_clock").c_str()); +		f << stringf("begin\n");  		if (signal_clk.size()) { -			fprintf(f, "\txorshift128;\n"); -			fprintf(f, "\t{"); +			f << stringf("\txorshift128;\n"); +			f << stringf("\t{");  			int total_clock_bits = 0;  			for (auto it = signal_clk.begin(); it != signal_clk.end(); it++) { -				fprintf(f, "%s %s", it == signal_clk.begin() ? "" : ",", it->first.c_str()); +				f << stringf("%s %s", it == signal_clk.begin() ? "" : ",", it->first.c_str());  				total_clock_bits += it->second;  			} -			fprintf(f, " } = {"); +			f << stringf(" } = {");  			for (auto it = signal_clk.begin(); it != signal_clk.end(); it++) -				fprintf(f, "%s %s", it == signal_clk.begin() ? "" : ",", it->first.c_str()); -			fprintf(f, " } ^ (%d'b1 << (xorshift128_w %% %d));\n", total_clock_bits, total_clock_bits); +				f << stringf("%s %s", it == signal_clk.begin() ? "" : ",", it->first.c_str()); +			f << stringf(" } ^ (%d'b1 << (xorshift128_w %% %d));\n", total_clock_bits, total_clock_bits);  		} -		fprintf(f, "end\n"); -		fprintf(f, "endtask\n\n"); +		f << stringf("end\n"); +		f << stringf("endtask\n\n");  		char shorthand = 'A';  		std::vector<std::string> header1;  		std::string header2 = ""; -		fprintf(f, "task %s;\n", idy(mod->name.str(), "print_status").c_str()); -		fprintf(f, "begin\n"); -		fprintf(f, "\t$display(\"#OUT# %%b %%b %%b %%t %%d\", {"); +		f << stringf("task %s;\n", idy(mod->name.str(), "print_status").c_str()); +		f << stringf("begin\n"); +		f << stringf("\t$display(\"#OUT# %%b %%b %%b %%t %%d\", {");  		if (signal_in.size())  			for (auto it = signal_in.begin(); it != signal_in.end(); it++) { -				fprintf(f, "%s %s", it == signal_in.begin() ? "" : ",", it->first.c_str()); +				f << stringf("%s %s", it == signal_in.begin() ? "" : ",", it->first.c_str());  				int len = it->second;  				if (len > 1)  					header2 += "/", len--; @@ -220,14 +220,14 @@ static void autotest(FILE *f, RTLIL::Design *design, int num_iter)  				header1.back()[0] = shorthand++;  			}  		else { -			fprintf(f, " 1'bx"); +			f << stringf(" 1'bx");  			header2 += "#";  		} -		fprintf(f, " }, {"); +		f << stringf(" }, {");  		header2 += " ";  		if (signal_clk.size()) {  			for (auto it = signal_clk.begin(); it != signal_clk.end(); it++) { -				fprintf(f, "%s %s", it == signal_clk.begin() ? "" : ",", it->first.c_str()); +				f << stringf("%s %s", it == signal_clk.begin() ? "" : ",", it->first.c_str());  				int len = it->second;  				if (len > 1)  					header2 += "/", len--; @@ -239,14 +239,14 @@ static void autotest(FILE *f, RTLIL::Design *design, int num_iter)  				header1.back()[0] = shorthand++;  			}  		} else { -			fprintf(f, " 1'bx"); +			f << stringf(" 1'bx");  			header2 += "#";  		} -		fprintf(f, " }, {"); +		f << stringf(" }, {");  		header2 += " ";  		if (signal_out.size()) {  			for (auto it = signal_out.begin(); it != signal_out.end(); it++) { -				fprintf(f, "%s %s", it == signal_out.begin() ? "" : ",", it->first.c_str()); +				f << stringf("%s %s", it == signal_out.begin() ? "" : ",", it->first.c_str());  				int len = it->second;  				if (len > 1)  					header2 += "/", len--; @@ -258,47 +258,47 @@ static void autotest(FILE *f, RTLIL::Design *design, int num_iter)  				header1.back()[0] = shorthand++;  			}  		} else { -			fprintf(f, " 1'bx"); +			f << stringf(" 1'bx");  			header2 += "#";  		} -		fprintf(f, " }, $time, i);\n"); -		fprintf(f, "end\n"); -		fprintf(f, "endtask\n\n"); +		f << stringf(" }, $time, i);\n"); +		f << stringf("end\n"); +		f << stringf("endtask\n\n"); -		fprintf(f, "task %s;\n", idy(mod->name.str(), "print_header").c_str()); -		fprintf(f, "begin\n"); -		fprintf(f, "\t$display(\"#OUT#\");\n"); +		f << stringf("task %s;\n", idy(mod->name.str(), "print_header").c_str()); +		f << stringf("begin\n"); +		f << stringf("\t$display(\"#OUT#\");\n");  		for (auto &hdr : header1) -			fprintf(f, "\t$display(\"#OUT#   %s\");\n", hdr.c_str()); -		fprintf(f, "\t$display(\"#OUT#\");\n"); -		fprintf(f, "\t$display(\"#OUT# %s\");\n", header2.c_str()); -		fprintf(f, "end\n"); -		fprintf(f, "endtask\n\n"); +			f << stringf("\t$display(\"#OUT#   %s\");\n", hdr.c_str()); +		f << stringf("\t$display(\"#OUT#\");\n"); +		f << stringf("\t$display(\"#OUT# %s\");\n", header2.c_str()); +		f << stringf("end\n"); +		f << stringf("endtask\n\n"); -		fprintf(f, "task %s;\n", idy(mod->name.str(), "test").c_str()); -		fprintf(f, "begin\n"); -		fprintf(f, "\t$display(\"#OUT#\\n#OUT# ==== %s ====\");\n", idy(mod->name.str()).c_str()); -		fprintf(f, "\t%s;\n", idy(mod->name.str(), "reset").c_str()); -		fprintf(f, "\tfor (i=0; i<%d; i=i+1) begin\n", num_iter); -		fprintf(f, "\t\tif (i %% 20 == 0) %s;\n", idy(mod->name.str(), "print_header").c_str()); -		fprintf(f, "\t\t#100; %s;\n", idy(mod->name.str(), "update_data").c_str()); -		fprintf(f, "\t\t#100; %s;\n", idy(mod->name.str(), "update_clock").c_str()); -		fprintf(f, "\t\t#100; %s;\n", idy(mod->name.str(), "print_status").c_str()); -		fprintf(f, "\tend\n"); -		fprintf(f, "end\n"); -		fprintf(f, "endtask\n\n"); +		f << stringf("task %s;\n", idy(mod->name.str(), "test").c_str()); +		f << stringf("begin\n"); +		f << stringf("\t$display(\"#OUT#\\n#OUT# ==== %s ====\");\n", idy(mod->name.str()).c_str()); +		f << stringf("\t%s;\n", idy(mod->name.str(), "reset").c_str()); +		f << stringf("\tfor (i=0; i<%d; i=i+1) begin\n", num_iter); +		f << stringf("\t\tif (i %% 20 == 0) %s;\n", idy(mod->name.str(), "print_header").c_str()); +		f << stringf("\t\t#100; %s;\n", idy(mod->name.str(), "update_data").c_str()); +		f << stringf("\t\t#100; %s;\n", idy(mod->name.str(), "update_clock").c_str()); +		f << stringf("\t\t#100; %s;\n", idy(mod->name.str(), "print_status").c_str()); +		f << stringf("\tend\n"); +		f << stringf("end\n"); +		f << stringf("endtask\n\n");  	} -	fprintf(f, "initial begin\n"); -	fprintf(f, "\t// $dumpfile(\"testbench.vcd\");\n"); -	fprintf(f, "\t// $dumpvars(0, testbench);\n"); +	f << stringf("initial begin\n"); +	f << stringf("\t// $dumpfile(\"testbench.vcd\");\n"); +	f << stringf("\t// $dumpvars(0, testbench);\n");  	for (auto it = design->modules_.begin(); it != design->modules_.end(); it++)  		if (!it->second->get_bool_attribute("\\gentb_skip")) -			fprintf(f, "\t%s;\n", idy(it->first.str(), "test").c_str()); -	fprintf(f, "\t$finish;\n"); -	fprintf(f, "end\n\n"); +			f << stringf("\t%s;\n", idy(it->first.str(), "test").c_str()); +	f << stringf("\t$finish;\n"); +	f << stringf("end\n\n"); -	fprintf(f, "endmodule\n"); +	f << stringf("endmodule\n");  }  struct TestAutotbBackend : public Backend { @@ -328,7 +328,7 @@ struct TestAutotbBackend : public Backend {  		log("        number of iterations the test bench shuld run (default = 1000)\n");  		log("\n");  	} -	virtual void execute(FILE *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) +	virtual void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design)  	{  		int num_iter = 1000; @@ -345,7 +345,7 @@ struct TestAutotbBackend : public Backend {  		}  		extra_args(f, filename, args, argidx); -		autotest(f, design, num_iter); +		autotest(*f, design, num_iter);  	}  } TestAutotbBackend;  | 
