mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-20 14:20:32 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			504 lines
		
	
	
	
		
			15 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			504 lines
		
	
	
	
		
			15 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
|  *  yosys -- Yosys Open SYnthesis Suite
 | |
|  *
 | |
|  *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 | |
|  *
 | |
|  *  Permission to use, copy, modify, and/or distribute this software for any
 | |
|  *  purpose with or without fee is hereby granted, provided that the above
 | |
|  *  copyright notice and this permission notice appear in all copies.
 | |
|  *
 | |
|  *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | |
|  *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | |
|  *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | |
|  *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | |
|  *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 | |
|  *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 | |
|  *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | |
|  *
 | |
|  *  ---
 | |
|  *
 | |
|  *  A very simple and straightforward backend for the RTLIL text
 | |
|  *  representation (as understood by the 'ilang' frontend).
 | |
|  *
 | |
|  */
 | |
| 
 | |
| #include "ilang_backend.h"
 | |
| #include "kernel/yosys.h"
 | |
| #include <errno.h>
 | |
| 
 | |
| USING_YOSYS_NAMESPACE
 | |
| using namespace ILANG_BACKEND;
 | |
| YOSYS_NAMESPACE_BEGIN
 | |
| 
 | |
| 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;
 | |
| 	if ((data.flags & RTLIL::CONST_FLAG_STRING) == 0 || width != (int)data.bits.size()) {
 | |
| 		if (width == 32 && autoint) {
 | |
| 			int32_t val = 0;
 | |
| 			for (int i = 0; i < width; i++) {
 | |
| 				log_assert(offset+i < (int)data.bits.size());
 | |
| 				switch (data.bits[offset+i]) {
 | |
| 				case RTLIL::S0: break;
 | |
| 				case RTLIL::S1: val |= 1 << i; break;
 | |
| 				default: val = -1; break;
 | |
| 				}
 | |
| 			}
 | |
| 			if (val >= 0) {
 | |
| 				f << stringf("%d", val);
 | |
| 				return;
 | |
| 			}
 | |
| 		}
 | |
| 		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: 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 {
 | |
| 		f << stringf("\"");
 | |
| 		std::string str = data.decode_string();
 | |
| 		for (size_t i = 0; i < str.size(); i++) {
 | |
| 			if (str[i] == '\n')
 | |
| 				f << stringf("\\n");
 | |
| 			else if (str[i] == '\t')
 | |
| 				f << stringf("\\t");
 | |
| 			else if (str[i] < 32)
 | |
| 				f << stringf("\\%03o", str[i]);
 | |
| 			else if (str[i] == '"')
 | |
| 				f << stringf("\\\"");
 | |
| 			else if (str[i] == '\\')
 | |
| 				f << stringf("\\\\");
 | |
| 			else
 | |
| 				f << str[i];
 | |
| 		}
 | |
| 		f << stringf("\"");
 | |
| 	}
 | |
| }
 | |
| 
 | |
| 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)
 | |
| 			f << stringf("%s", chunk.wire->name.c_str());
 | |
| 		else if (chunk.width == 1)
 | |
| 			f << stringf("%s [%d]", chunk.wire->name.c_str(), chunk.offset);
 | |
| 		else
 | |
| 			f << stringf("%s [%d:%d]", chunk.wire->name.c_str(), chunk.offset+chunk.width-1, chunk.offset);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| 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 {
 | |
| 		f << stringf("{ ");
 | |
| 		for (auto it = sig.chunks().rbegin(); it != sig.chunks().rend(); ++it) {
 | |
| 			dump_sigchunk(f, *it, false);
 | |
| 			f << stringf(" ");
 | |
| 		}
 | |
| 		f << stringf("}");
 | |
| 	}
 | |
| }
 | |
| 
 | |
| void ILANG_BACKEND::dump_wire(std::ostream &f, std::string indent, const RTLIL::Wire *wire)
 | |
| {
 | |
| 	for (auto &it : wire->attributes) {
 | |
| 		f << stringf("%s" "attribute %s ", indent.c_str(), it.first.c_str());
 | |
| 		dump_const(f, it.second);
 | |
| 		f << stringf("\n");
 | |
| 	}
 | |
| 	f << stringf("%s" "wire ", indent.c_str());
 | |
| 	if (wire->width != 1)
 | |
| 		f << stringf("width %d ", wire->width);
 | |
| 	if (wire->upto)
 | |
| 		f << stringf("upto ");
 | |
| 	if (wire->start_offset != 0)
 | |
| 		f << stringf("offset %d ", wire->start_offset);
 | |
| 	if (wire->port_input && !wire->port_output)
 | |
| 		f << stringf("input %d ", wire->port_id);
 | |
| 	if (!wire->port_input && wire->port_output)
 | |
| 		f << stringf("output %d ", wire->port_id);
 | |
| 	if (wire->port_input && wire->port_output)
 | |
| 		f << stringf("inout %d ", wire->port_id);
 | |
| 	f << stringf("%s\n", wire->name.c_str());
 | |
| }
 | |
| 
 | |
| void ILANG_BACKEND::dump_memory(std::ostream &f, std::string indent, const RTLIL::Memory *memory)
 | |
| {
 | |
| 	for (auto &it : memory->attributes) {
 | |
| 		f << stringf("%s" "attribute %s ", indent.c_str(), it.first.c_str());
 | |
| 		dump_const(f, it.second);
 | |
| 		f << stringf("\n");
 | |
| 	}
 | |
| 	f << stringf("%s" "memory ", indent.c_str());
 | |
| 	if (memory->width != 1)
 | |
| 		f << stringf("width %d ", memory->width);
 | |
| 	if (memory->size != 0)
 | |
| 		f << stringf("size %d ", memory->size);
 | |
| 	if (memory->start_offset != 0)
 | |
| 		f << stringf("offset %d ", memory->start_offset);
 | |
| 	f << stringf("%s\n", memory->name.c_str());
 | |
| }
 | |
| 
 | |
| void ILANG_BACKEND::dump_cell(std::ostream &f, std::string indent, const RTLIL::Cell *cell)
 | |
| {
 | |
| 	for (auto &it : cell->attributes) {
 | |
| 		f << stringf("%s" "attribute %s ", indent.c_str(), it.first.c_str());
 | |
| 		dump_const(f, it.second);
 | |
| 		f << stringf("\n");
 | |
| 	}
 | |
| 	f << stringf("%s" "cell %s %s\n", indent.c_str(), cell->type.c_str(), cell->name.c_str());
 | |
| 	for (auto &it : cell->parameters) {
 | |
| 		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);
 | |
| 		f << stringf("\n");
 | |
| 	}
 | |
| 	for (auto &it : cell->connections()) {
 | |
| 		f << stringf("%s  connect %s ", indent.c_str(), it.first.c_str());
 | |
| 		dump_sigspec(f, it.second);
 | |
| 		f << stringf("\n");
 | |
| 	}
 | |
| 	f << stringf("%s" "end\n", indent.c_str());
 | |
| }
 | |
| 
 | |
| 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)
 | |
| 	{
 | |
| 		f << stringf("%s" "assign ", indent.c_str());
 | |
| 		dump_sigspec(f, it->first);
 | |
| 		f << stringf(" ");
 | |
| 		dump_sigspec(f, it->second);
 | |
| 		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(std::ostream &f, std::string indent, const RTLIL::SwitchRule *sw)
 | |
| {
 | |
| 	for (auto it = sw->attributes.begin(); it != sw->attributes.end(); ++it) {
 | |
| 		f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str());
 | |
| 		dump_const(f, it->second);
 | |
| 		f << stringf("\n");
 | |
| 	}
 | |
| 
 | |
| 	f << stringf("%s" "switch ", indent.c_str());
 | |
| 	dump_sigspec(f, sw->signal);
 | |
| 	f << stringf("\n");
 | |
| 
 | |
| 	for (auto it = sw->cases.begin(); it != sw->cases.end(); ++it)
 | |
| 	{
 | |
| 		f << stringf("%s  case ", indent.c_str());
 | |
| 		for (size_t i = 0; i < (*it)->compare.size(); i++) {
 | |
| 			if (i > 0)
 | |
| 				f << stringf(", ");
 | |
| 			dump_sigspec(f, (*it)->compare[i]);
 | |
| 		}
 | |
| 		f << stringf("\n");
 | |
| 
 | |
| 		dump_proc_case_body(f, indent + "    ", *it);
 | |
| 	}
 | |
| 
 | |
| 	f << stringf("%s" "end\n", indent.c_str());
 | |
| }
 | |
| 
 | |
| void ILANG_BACKEND::dump_proc_sync(std::ostream &f, std::string indent, const RTLIL::SyncRule *sy)
 | |
| {
 | |
| 	f << stringf("%s" "sync ", indent.c_str());
 | |
| 	switch (sy->type) {
 | |
| 	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);
 | |
| 		f << stringf("\n");
 | |
| 		break;
 | |
| 	case RTLIL::STa: f << stringf("always\n"); break;
 | |
| 	case RTLIL::STg: f << stringf("global\n"); break;
 | |
| 	case RTLIL::STi: f << stringf("init\n"); break;
 | |
| 	}
 | |
| 
 | |
| 	for (auto it = sy->actions.begin(); it != sy->actions.end(); ++it) {
 | |
| 		f << stringf("%s  update ", indent.c_str());
 | |
| 		dump_sigspec(f, it->first);
 | |
| 		f << stringf(" ");
 | |
| 		dump_sigspec(f, it->second);
 | |
| 		f << stringf("\n");
 | |
| 	}
 | |
| }
 | |
| 
 | |
| 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) {
 | |
| 		f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str());
 | |
| 		dump_const(f, it->second);
 | |
| 		f << stringf("\n");
 | |
| 	}
 | |
| 	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);
 | |
| 	f << stringf("%s" "end\n", indent.c_str());
 | |
| }
 | |
| 
 | |
| void ILANG_BACKEND::dump_conn(std::ostream &f, std::string indent, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right)
 | |
| {
 | |
| 	f << stringf("%s" "connect ", indent.c_str());
 | |
| 	dump_sigspec(f, left);
 | |
| 	f << stringf(" ");
 | |
| 	dump_sigspec(f, right);
 | |
| 	f << stringf("\n");
 | |
| }
 | |
| 
 | |
| void ILANG_BACKEND::dump_module(std::ostream &f, std::string indent, RTLIL::Module *module, 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);
 | |
| 
 | |
| 	if (print_header)
 | |
| 	{
 | |
| 		for (auto it = module->attributes.begin(); it != module->attributes.end(); ++it) {
 | |
| 			f << stringf("%s" "attribute %s ", indent.c_str(), it->first.c_str());
 | |
| 			dump_const(f, it->second);
 | |
| 			f << stringf("\n");
 | |
| 		}
 | |
| 
 | |
| 		f << stringf("%s" "module %s\n", indent.c_str(), module->name.c_str());
 | |
| 
 | |
| 		if (!module->avail_parameters.empty()) {
 | |
| 			if (only_selected)
 | |
| 				f << stringf("\n");
 | |
| 			for (auto &p : module->avail_parameters)
 | |
| 				f << stringf("%s" "  parameter %s\n", indent.c_str(), p.c_str());
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	if (print_body)
 | |
| 	{
 | |
| 		for (auto it : module->wires())
 | |
| 			if (!only_selected || design->selected(module, it)) {
 | |
| 				if (only_selected)
 | |
| 					f << stringf("\n");
 | |
| 				dump_wire(f, indent + "  ", it);
 | |
| 			}
 | |
| 
 | |
| 		for (auto it : module->memories)
 | |
| 			if (!only_selected || design->selected(module, it.second)) {
 | |
| 				if (only_selected)
 | |
| 					f << stringf("\n");
 | |
| 				dump_memory(f, indent + "  ", it.second);
 | |
| 			}
 | |
| 
 | |
| 		for (auto it : module->cells())
 | |
| 			if (!only_selected || design->selected(module, it)) {
 | |
| 				if (only_selected)
 | |
| 					f << stringf("\n");
 | |
| 				dump_cell(f, indent + "  ", it);
 | |
| 			}
 | |
| 
 | |
| 		for (auto it : module->processes)
 | |
| 			if (!only_selected || design->selected(module, it.second)) {
 | |
| 				if (only_selected)
 | |
| 					f << stringf("\n");
 | |
| 				dump_proc(f, indent + "  ", it.second);
 | |
| 			}
 | |
| 
 | |
| 		bool first_conn_line = true;
 | |
| 		for (auto it = module->connections().begin(); it != module->connections().end(); ++it) {
 | |
| 			bool show_conn = !only_selected;
 | |
| 			if (only_selected) {
 | |
| 				RTLIL::SigSpec sigs = it->first;
 | |
| 				sigs.append(it->second);
 | |
| 				for (auto &c : sigs.chunks()) {
 | |
| 					if (c.wire == NULL || !design->selected(module, c.wire))
 | |
| 						continue;
 | |
| 					show_conn = true;
 | |
| 				}
 | |
| 			}
 | |
| 			if (show_conn) {
 | |
| 				if (only_selected && first_conn_line)
 | |
| 					f << stringf("\n");
 | |
| 				dump_conn(f, indent + "  ", it->first, it->second);
 | |
| 				first_conn_line = false;
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	if (print_header)
 | |
| 		f << stringf("%s" "end\n", indent.c_str());
 | |
| }
 | |
| 
 | |
| void ILANG_BACKEND::dump_design(std::ostream &f, RTLIL::Design *design, bool only_selected, bool flag_m, bool flag_n)
 | |
| {
 | |
| #ifndef NDEBUG
 | |
| 	int init_autoidx = autoidx;
 | |
| #endif
 | |
| 
 | |
| 	if (!flag_m) {
 | |
| 		int count_selected_mods = 0;
 | |
| 		for (auto it = design->modules_.begin(); it != design->modules_.end(); ++it) {
 | |
| 			if (design->selected_whole_module(it->first))
 | |
| 				flag_m = true;
 | |
| 			if (design->selected(it->second))
 | |
| 				count_selected_mods++;
 | |
| 		}
 | |
| 		if (count_selected_mods > 1)
 | |
| 			flag_m = true;
 | |
| 	}
 | |
| 
 | |
| 	if (!only_selected || flag_m) {
 | |
| 		if (only_selected)
 | |
| 			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)
 | |
| 				f << stringf("\n");
 | |
| 			dump_module(f, "", it->second, design, only_selected, flag_m, flag_n);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	log_assert(init_autoidx == autoidx);
 | |
| }
 | |
| 
 | |
| YOSYS_NAMESPACE_END
 | |
| PRIVATE_NAMESPACE_BEGIN
 | |
| 
 | |
| struct IlangBackend : public Backend {
 | |
| 	IlangBackend() : Backend("ilang", "write design to ilang file") { }
 | |
| 	virtual void help()
 | |
| 	{
 | |
| 		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
 | |
| 		log("\n");
 | |
| 		log("    write_ilang [filename]\n");
 | |
| 		log("\n");
 | |
| 		log("Write the current design to an 'ilang' file. (ilang is a text representation\n");
 | |
| 		log("of a design in yosys's internal format.)\n");
 | |
| 		log("\n");
 | |
| 		log("    -selected\n");
 | |
| 		log("        only write selected parts of the design.\n");
 | |
| 		log("\n");
 | |
| 	}
 | |
| 	virtual void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design)
 | |
| 	{
 | |
| 		bool selected = false;
 | |
| 
 | |
| 		log_header(design, "Executing ILANG backend.\n");
 | |
| 
 | |
| 		size_t argidx;
 | |
| 		for (argidx = 1; argidx < args.size(); argidx++) {
 | |
| 			std::string arg = args[argidx];
 | |
| 			if (arg == "-selected") {
 | |
| 				selected = true;
 | |
| 				continue;
 | |
| 			}
 | |
| 			break;
 | |
| 		}
 | |
| 		extra_args(f, filename, args, argidx);
 | |
| 
 | |
| 		design->sort();
 | |
| 
 | |
| 		log("Output filename: %s\n", filename.c_str());
 | |
| 		*f << stringf("# Generated by %s\n", yosys_version_str);
 | |
| 		ILANG_BACKEND::dump_design(*f, design, selected, true, false);
 | |
| 	}
 | |
| } IlangBackend;
 | |
| 
 | |
| struct DumpPass : public Pass {
 | |
| 	DumpPass() : Pass("dump", "print parts of the design in ilang format") { }
 | |
| 	virtual void help()
 | |
| 	{
 | |
| 		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
 | |
| 		log("\n");
 | |
| 		log("    dump [options] [selection]\n");
 | |
| 		log("\n");
 | |
| 		log("Write the selected parts of the design to the console or specified file in\n");
 | |
| 		log("ilang format.\n");
 | |
| 		log("\n");
 | |
| 		log("    -m\n");
 | |
| 		log("        also dump the module headers, even if only parts of a single\n");
 | |
| 		log("        module is selected\n");
 | |
| 		log("\n");
 | |
| 		log("    -n\n");
 | |
| 		log("        only dump the module headers if the entire module is selected\n");
 | |
| 		log("\n");
 | |
| 		log("    -o <filename>\n");
 | |
| 		log("        write to the specified file.\n");
 | |
| 		log("\n");
 | |
| 		log("    -a <filename>\n");
 | |
| 		log("        like -outfile but append instead of overwrite\n");
 | |
| 		log("\n");
 | |
| 	}
 | |
| 	virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
 | |
| 	{
 | |
| 		std::string filename;
 | |
| 		bool flag_m = false, flag_n = false, append = false;
 | |
| 
 | |
| 		size_t argidx;
 | |
| 		for (argidx = 1; argidx < args.size(); argidx++)
 | |
| 		{
 | |
| 			std::string arg = args[argidx];
 | |
| 			if ((arg == "-o" || arg == "-outfile") && argidx+1 < args.size()) {
 | |
| 				filename = args[++argidx];
 | |
| 				append = false;
 | |
| 				continue;
 | |
| 			}
 | |
| 			if ((arg == "-a" || arg == "-append") && argidx+1 < args.size()) {
 | |
| 				filename = args[++argidx];
 | |
| 				append = true;
 | |
| 				continue;
 | |
| 			}
 | |
| 			if (arg == "-m") {
 | |
| 				flag_m = true;
 | |
| 				continue;
 | |
| 			}
 | |
| 			if (arg == "-n") {
 | |
| 				flag_n = true;
 | |
| 				continue;
 | |
| 			}
 | |
| 			break;
 | |
| 		}
 | |
| 		extra_args(args, argidx, design);
 | |
| 
 | |
| 		std::ostream *f;
 | |
| 		std::stringstream buf;
 | |
| 
 | |
| 		if (!filename.empty()) {
 | |
| 			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 = &buf;
 | |
| 		}
 | |
| 
 | |
| 		ILANG_BACKEND::dump_design(*f, design, true, flag_m, flag_n);
 | |
| 
 | |
| 		if (!filename.empty()) {
 | |
| 			delete f;
 | |
| 		} else {
 | |
| 			log("%s", buf.str().c_str());
 | |
| 		}
 | |
| 	}
 | |
| } DumpPass;
 | |
| 
 | |
| PRIVATE_NAMESPACE_END
 |