Now using BLIF as ABC input format
authorClifford Wolf <clifford@clifford.at>
Tue, 31 Dec 2013 13:29:29 +0000 (14:29 +0100)
committerClifford Wolf <clifford@clifford.at>
Tue, 31 Dec 2013 13:29:29 +0000 (14:29 +0100)
passes/abc/abc.cc

index 5965ffa17406c7e115ec73403fdfd60d93aa1142..1e7c66e1442da90b51bfb84af74e46e3b46367d6 100644 (file)
 // Berkeley Logic Synthesis and Verification Group, ABC: A System for Sequential Synthesis and Verification
 // http://www.eecs.berkeley.edu/~alanmi/abc/
 
+// [[CITE]] Berkeley Logic Interchange Format (BLIF)
+// University of California. Berkeley. July 28, 1992
+// http://www.ece.cmu.edu/~ee760/760docs/blif.pdf
+
 // [[CITE]] Kahn's Topological sorting algorithm
 // Kahn, Arthur B. (1962), "Topological sorting of large networks", Communications of the ACM 5 (11): 558–562, doi:10.1145/368996.369025
 // http://en.wikipedia.org/wiki/Topological_sorting
@@ -339,7 +343,7 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std
        if (!cleanup)
                tempdir_name[0] = tempdir_name[4] = '_';
        char *p = mkdtemp(tempdir_name);
-       log_header("Extracting gate netlist of module `%s' to `%s/input.v'..\n", module->name.c_str(), tempdir_name);
+       log_header("Extracting gate netlist of module `%s' to `%s/input.blif'..\n", module->name.c_str(), tempdir_name);
        if (p == NULL)
                log_error("For some reason mkdtemp() failed!\n");
 
@@ -362,60 +366,73 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std
        
        handle_loops();
 
-       if (asprintf(&p, "%s/input.v", tempdir_name) < 0) abort();
+       if (asprintf(&p, "%s/input.blif", tempdir_name) < 0) abort();
        FILE *f = fopen(p, "wt");
        if (f == NULL)
                log_error("Opening %s for writing failed: %s\n", p, strerror(errno));
        free(p);
 
-       fprintf(f, "module netlist (");
-       bool first = true;
+       fprintf(f, ".model netlist\n");
+
+       int count_input = 0;
+       fprintf(f, ".inputs");
        for (auto &si : signal_list) {
-               if (!si.is_port)
+               if (!si.is_port || si.type >= 0)
                        continue;
-               if (!first)
-                       fprintf(f, ", ");
-               fprintf(f, "n%d", si.id);
-               first = false;
+               fprintf(f, " n%d", si.id);
+               count_input++;
        }
-       fprintf(f, "); // %s\n", module->name.c_str());
+       fprintf(f, "\n");
 
-       int count_input = 0, count_output = 0;
+       int count_output = 0;
+       fprintf(f, ".outputs");
        for (auto &si : signal_list) {
-               if (si.is_port) {
-                       if (si.type >= 0)
-                               count_output++;
-                       else
-                               count_input++;
-               }
-               fprintf(f, "%s n%d; // %s\n", si.is_port ? si.type >= 0 ?
-                               "output" : "input" : "wire", si.id, log_signal(si.sig));
+               if (!si.is_port || si.type < 0)
+                       continue;
+               fprintf(f, " n%d", si.id);
+               count_output++;
        }
+       fprintf(f, "\n");
+
+       for (auto &si : signal_list)
+               fprintf(f, "# n%-5d %s\n", si.id, log_signal(si.sig));
+
        for (auto &si : signal_list) {
                assert(si.sig.width == 1 && si.sig.chunks.size() == 1);
-               if (si.sig.chunks[0].wire == NULL)
-                       fprintf(f, "assign n%d = %c;\n", si.id, si.sig.chunks[0].data.bits[0] == RTLIL::State::S1 ? '1' : '0');
+               if (si.sig.chunks[0].wire == NULL) {
+                       fprintf(f, ".names n%d\n", si.id);
+                       if (si.sig.chunks[0].data.bits[0] == RTLIL::State::S1)
+                               fprintf(f, "1\n");
+               }
        }
 
        int count_gates = 0;
        for (auto &si : signal_list) {
-               if (si.type == 'n')
-                       fprintf(f, "not (n%d, n%d);\n", si.id, si.in1);
-               else if (si.type == 'a')
-                       fprintf(f, "and (n%d, n%d, n%d);\n", si.id, si.in1, si.in2);
-               else if (si.type == 'o')
-                       fprintf(f, "or (n%d, n%d, n%d);\n", si.id, si.in1, si.in2);
-               else if (si.type == 'x')
-                       fprintf(f, "xor (n%d, n%d, n%d);\n", si.id, si.in1, si.in2);
-               else if (si.type == 'm')
-                       fprintf(f, "assign n%d = n%d ? n%d : n%d;\n", si.id, si.in3, si.in2, si.in1);
-               else if (si.type >= 0)
+               if (si.type == 'n') {
+                       fprintf(f, ".names n%d n%d\n", si.in1, si.id);
+                       fprintf(f, "0 1\n");
+               } else if (si.type == 'a') {
+                       fprintf(f, ".names n%d n%d n%d\n", si.in1, si.in2, si.id);
+                       fprintf(f, "11 1\n");
+               } else if (si.type == 'o') {
+                       fprintf(f, ".names n%d n%d n%d\n", si.in1, si.in2, si.id);
+                       fprintf(f, "-1 1\n");
+                       fprintf(f, "1- 1\n");
+               } else if (si.type == 'x') {
+                       fprintf(f, ".names n%d n%d n%d\n", si.in1, si.in2, si.id);
+                       fprintf(f, "01 1\n");
+                       fprintf(f, "10 1\n");
+               } else if (si.type == 'm') {
+                       fprintf(f, ".names n%d n%d n%d n%d\n", si.in1, si.in2, si.in3, si.id);
+                       fprintf(f, "1-0 1\n");
+                       fprintf(f, "-11 1\n");
+               } else if (si.type >= 0)
                        abort();
                if (si.type >= 0)
                        count_gates++;
        }
 
-       fprintf(f, "endmodule\n");
+       fprintf(f, ".end\n");
        fclose(f);
 
        log("Extracted %d gates and %zd wires to a netlist network with %d inputs and %d outputs.\n",
@@ -456,7 +473,7 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std
                int buffer_pos = 0;
                if (!liberty_file.empty()) {
                        buffer_pos += snprintf(buffer+buffer_pos, 1024-buffer_pos,
-                                       "%s -s -c 'read_verilog %s/input.v; read_lib %s; ",
+                                       "%s -s -c 'read_blif %s/input.blif; read_lib %s; ",
                                        exe_file.c_str(), tempdir_name, liberty_file.c_str());
                        if (!constr_file.empty())
                                buffer_pos += snprintf(buffer+buffer_pos, 1024-buffer_pos,
@@ -469,16 +486,16 @@ static void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std
                } else
                if (!script_file.empty())
                        buffer_pos += snprintf(buffer+buffer_pos, 1024-buffer_pos,
-                                       "%s -s -c 'read_verilog %s/input.v; source %s; ",
+                                       "%s -s -c 'read_blif %s/input.blif; source %s; ",
                                        exe_file.c_str(), tempdir_name, script_file.c_str());
                else
                if (lut_mode)
                        buffer_pos += snprintf(buffer+buffer_pos, 1024-buffer_pos,
-                                       "%s -s -c 'read_verilog %s/input.v; read_lut %s/lutdefs.txt; strash; balance; dch; if; ",
+                                       "%s -s -c 'read_blif %s/input.blif; read_lut %s/lutdefs.txt; strash; balance; dch; if; ",
                                        exe_file.c_str(), tempdir_name, tempdir_name);
                else
                        buffer_pos += snprintf(buffer+buffer_pos, 1024-buffer_pos,
-                                       "%s -s -c 'read_verilog %s/input.v; read_library %s/stdcells.genlib; strash; balance; dch; map; ",
+                                       "%s -s -c 'read_blif %s/input.blif; read_library %s/stdcells.genlib; strash; balance; dch; map; ",
                                        exe_file.c_str(), tempdir_name, tempdir_name);
                buffer_pos += snprintf(buffer+buffer_pos, 1024-buffer_pos, "write_blif %s/output.blif' 2>&1", tempdir_name);