From be5dab87fd49f0095678d7b69d35a8456a641178 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 31 Dec 2013 14:29:29 +0100 Subject: Now using BLIF as ABC input format --- passes/abc/abc.cc | 91 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 54 insertions(+), 37 deletions(-) (limited to 'passes') diff --git a/passes/abc/abc.cc b/passes/abc/abc.cc index 5965ffa17..1e7c66e14 100644 --- a/passes/abc/abc.cc +++ b/passes/abc/abc.cc @@ -21,6 +21,10 @@ // 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); -- cgit v1.2.3