Changed backend-api from FILE to std::ostream
authorClifford Wolf <clifford@clifford.at>
Sat, 23 Aug 2014 11:54:21 +0000 (13:54 +0200)
committerClifford Wolf <clifford@clifford.at>
Sat, 23 Aug 2014 11:54:21 +0000 (13:54 +0200)
16 files changed:
backends/blif/blif.cc
backends/btor/btor.cc
backends/edif/edif.cc
backends/ilang/ilang_backend.cc
backends/ilang/ilang_backend.h
backends/intersynth/intersynth.cc
backends/spice/spice.cc
backends/verilog/verilog_backend.cc
backends/verilog/verilog_backend.h
kernel/log.cc
kernel/register.cc
kernel/register.h
kernel/rtlil.cc
kernel/yosys.h
passes/techmap/extract.cc
passes/tests/test_autotb.cc

index b9b68b979092ac67103d44dece91f9304e810d1e..919022abee963e0bce92e8b4936449a2fea27318 100644 (file)
@@ -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 &param : 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;
 
index a81d8f159b7441a9a76c3174cf0e00324f0b52aa..9b770518be3fac3bf8562eeffab07bff6b184bc6 100644 (file)
@@ -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;
 
index ecdfaabfc9de705276c43c23050340cbb9c8fafe..ccedd91d2da4a969598fabc44c271d1c60d2e8eb 100644 (file)
@@ -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;
 
index b7088f599473f1ebaef863093a88ba052cb9452f..13d3a8e42d136699ff729ebc7dd59a9ef606e49a 100644 (file)
  */
 
 #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;
index b0fec4889134aed5955d31f3fd9df39f2fd8ba59..138e10efbf191042f5ea89445c04fbdae5483497 100644 (file)
 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
index 9faed77c9d11dbb29b144b8de83ab56bdeaae957..97ead3c64efa58901eea6310d2408d3eb2bb2ecb 100644 (file)
@@ -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;
index be0086ffd3fb5f7cb38ffe7af8bc6cbff65477bc..b057063cd27e3bfc5927376efbdb9f8cc736dafa 100644 (file)
 #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;
 
index f6095a5aa8b9978219dbe60b58637a67c637caf9..d1fa55b9450d5ebb02f3ae3a4ea2f6a71a3b2aac 100644 (file)
@@ -150,7 +150,7 @@ bool is_reg_wire(RTLIL::SigSpec sig, std::string &reg_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();
index c40830ef214effbddca13bf3544de7c7a3b037d5..7e6ef5ab93aad10b02f7b3d661cb6ad64680eba0 100644 (file)
 #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
index b742a5495b7be0be69e6df7a7268cacd9e0ad8a8..2b4b5db5bf9d5ea17c5193203ef2162606ab29a2 100644 (file)
@@ -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());
 }
 
 // ---------------------------------------------------
index a9e21e6dd5114ac475c25156e3bd3b624b4740ad..95ed0cbd1a7e6ea99b53d62d85f7882a2a09877d 100644 (file)
@@ -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())
index d7e4281c205edad1e2379528b1e74dda75ef2371..f2c6ad29e5e340d8ae69c147478c31c30fa9901b 100644 (file)
  *
  */
 
+#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
index 22bff7bdb3944acac1f509d45321e0f92a65fd04..28a45134564c3b8c1b2fd2b3db9a2f8b86b8c2d1 100644 (file)
@@ -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)
index c6cbcabc99a9611e587fff5feefba2241d7bbd84..bfadb5ffc0212688c9661d550a46ef6a999a690e 100644 (file)
 #include <functional>
 #include <initializer_list>
 
+#include <sstream>
+#include <fstream>
+#include <ostream>
+#include <iostream>
+
 #include <stdarg.h>
 #include <stdlib.h>
 #include <string.h>
index ebf4d77fc3149d3d64d6415a8559321cc7666735..eaa0f9fa386ac9b7fce67b19ce61dd5f02f36d78 100644 (file)
@@ -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;
index d260022776e365e48da4c18c91981863d4b6f896..eed0f75f9ca088130159b5fa83bc4c083b5d5c1a 100644 (file)
@@ -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;