diff options
Diffstat (limited to 'passes/tests')
-rw-r--r-- | passes/tests/test_abcloop.cc | 44 | ||||
-rw-r--r-- | passes/tests/test_autotb.cc | 31 | ||||
-rw-r--r-- | passes/tests/test_cell.cc | 165 |
3 files changed, 143 insertions, 97 deletions
diff --git a/passes/tests/test_abcloop.cc b/passes/tests/test_abcloop.cc index 0a0ceb1d1..09cb41954 100644 --- a/passes/tests/test_abcloop.cc +++ b/passes/tests/test_abcloop.cc @@ -21,6 +21,9 @@ #include "kernel/yosys.h" #include "kernel/satgen.h" +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + static uint32_t xorshift32_state = 123456789; static uint32_t xorshift32(uint32_t limit) { @@ -33,7 +36,7 @@ static uint32_t xorshift32(uint32_t limit) { static RTLIL::Wire *getw(std::vector<RTLIL::Wire*> &wires, RTLIL::Wire *w) { while (1) { - int idx = xorshift32(SIZE(wires)); + int idx = xorshift32(GetSize(wires)); if (wires[idx] != w && !wires[idx]->port_output) return wires[idx]; } @@ -124,28 +127,28 @@ static void test_abcloop() module->fixup_ports(); Pass::call(design, "clean"); - ezDefaultSAT ez; + ezSatPtr ez; SigMap sigmap(module); - SatGen satgen(&ez, &sigmap); + SatGen satgen(ez.get(), &sigmap); for (auto c : module->cells()) { - bool ok = satgen.importCell(c); + bool ok YS_ATTRIBUTE(unused) = satgen.importCell(c); log_assert(ok); } std::vector<int> in_vec = satgen.importSigSpec(in_sig); - std::vector<int> inverse_in_vec = ez.vec_not(in_vec); + std::vector<int> inverse_in_vec = ez->vec_not(in_vec); std::vector<int> out_vec = satgen.importSigSpec(out_sig); for (int i = 0; i < 16; i++) { std::vector<int> assumptions; - for (int j = 0; j < SIZE(in_vec); j++) + for (int j = 0; j < GetSize(in_vec); j++) assumptions.push_back((i & (1 << j)) ? in_vec.at(j) : inverse_in_vec.at(j)); std::vector<bool> results; - if (!ez.solve(out_vec, results, assumptions)) { + if (!ez->solve(out_vec, results, assumptions)) { log("No stable solution for input %d found -> recreate module.\n", i); goto recreate_module; } @@ -153,10 +156,10 @@ static void test_abcloop() for (int j = 0; j < 4; j++) truthtab[i][j] = results[j]; - assumptions.push_back(ez.vec_ne(out_vec, ez.vec_const(results))); + assumptions.push_back(ez->vec_ne(out_vec, ez->vec_const(results))); std::vector<bool> results2; - if (ez.solve(out_vec, results2, assumptions)) { + if (ez->solve(out_vec, results2, assumptions)) { log("Two stable solutions for input %d found -> recreate module.\n", i); goto recreate_module; } @@ -174,17 +177,17 @@ static void test_abcloop() log("\n"); log("Pre- and post-abc truth table:\n"); - ezDefaultSAT ez; + ezSatPtr ez; SigMap sigmap(module); - SatGen satgen(&ez, &sigmap); + SatGen satgen(ez.get(), &sigmap); for (auto c : module->cells()) { - bool ok = satgen.importCell(c); + bool ok YS_ATTRIBUTE(unused) = satgen.importCell(c); log_assert(ok); } std::vector<int> in_vec = satgen.importSigSpec(in_sig); - std::vector<int> inverse_in_vec = ez.vec_not(in_vec); + std::vector<int> inverse_in_vec = ez->vec_not(in_vec); std::vector<int> out_vec = satgen.importSigSpec(out_sig); @@ -194,14 +197,14 @@ static void test_abcloop() for (int i = 0; i < 16; i++) { std::vector<int> assumptions; - for (int j = 0; j < SIZE(in_vec); j++) + for (int j = 0; j < GetSize(in_vec); j++) assumptions.push_back((i & (1 << j)) ? in_vec.at(j) : inverse_in_vec.at(j)); for (int j = 0; j < 4; j++) truthtab2[i][j] = truthtab[i][j]; std::vector<bool> results; - if (!ez.solve(out_vec, results, assumptions)) { + if (!ez->solve(out_vec, results, assumptions)) { log("No stable solution for input %d found.\n", i); found_error = true; continue; @@ -210,10 +213,10 @@ static void test_abcloop() for (int j = 0; j < 4; j++) truthtab2[i][j] = results[j]; - assumptions.push_back(ez.vec_ne(out_vec, ez.vec_const(results))); + assumptions.push_back(ez->vec_ne(out_vec, ez->vec_const(results))); std::vector<bool> results2; - if (ez.solve(out_vec, results2, assumptions)) { + if (ez->solve(out_vec, results2, assumptions)) { log("Two stable solutions for input %d found -> recreate module.\n", i); found_error = true; } @@ -262,13 +265,13 @@ struct TestAbcloopPass : public Pass { xorshift32_state = 0; int argidx; - for (argidx = 1; argidx < SIZE(args); argidx++) + for (argidx = 1; argidx < GetSize(args); argidx++) { - if (args[argidx] == "-n" && argidx+1 < SIZE(args)) { + if (args[argidx] == "-n" && argidx+1 < GetSize(args)) { num_iter = atoi(args[++argidx].c_str()); continue; } - if (args[argidx] == "-s" && argidx+1 < SIZE(args)) { + if (args[argidx] == "-s" && argidx+1 < GetSize(args)) { xorshift32_state = atoi(args[++argidx].c_str()); continue; } @@ -283,3 +286,4 @@ struct TestAbcloopPass : public Pass { } } TestAbcloopPass; +PRIVATE_NAMESPACE_END diff --git a/passes/tests/test_autotb.cc b/passes/tests/test_autotb.cc index eed0f75f9..7c1b671c6 100644 --- a/passes/tests/test_autotb.cc +++ b/passes/tests/test_autotb.cc @@ -22,6 +22,7 @@ #include <stdio.h> #include <time.h> +USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN static std::string id(std::string internal_id) @@ -91,7 +92,7 @@ static void autotest(std::ostream &f, RTLIL::Design *design, int num_iter) f << stringf("end\n"); f << stringf("endtask\n\n"); - for (auto it = design->modules_.begin(); it != design->modules_.end(); it++) + for (auto it = design->modules_.begin(); it != design->modules_.end(); ++it) { std::map<std::string, int> signal_in; std::map<std::string, std::string> signal_const; @@ -105,7 +106,7 @@ static void autotest(std::ostream &f, RTLIL::Design *design, int num_iter) int count_ports = 0; log("Generating test bench for module `%s'.\n", it->first.c_str()); - for (auto it2 = mod->wires_.begin(); it2 != mod->wires_.end(); it2++) { + for (auto it2 = mod->wires_.begin(); it2 != mod->wires_.end(); ++it2) { RTLIL::Wire *wire = it2->second; if (wire->port_output) { count_ports++; @@ -114,8 +115,8 @@ static void autotest(std::ostream &f, RTLIL::Design *design, int num_iter) } else if (wire->port_input) { count_ports++; bool is_clksignal = wire->get_bool_attribute("\\gentb_clock"); - for (auto it3 = mod->processes.begin(); it3 != mod->processes.end(); it3++) - for (auto it4 = it3->second->syncs.begin(); it4 != it3->second->syncs.end(); it4++) { + for (auto it3 = mod->processes.begin(); it3 != mod->processes.end(); ++it3) + for (auto it4 = it3->second->syncs.begin(); it4 != it3->second->syncs.end(); ++it4) { if ((*it4)->type == RTLIL::ST0 || (*it4)->type == RTLIL::ST1) continue; RTLIL::SigSpec &signal = (*it4)->signal; @@ -134,7 +135,7 @@ static void autotest(std::ostream &f, RTLIL::Design *design, int num_iter) } } 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++) { + for (auto it2 = mod->wires_.begin(); it2 != mod->wires_.end(); ++it2) { RTLIL::Wire *wire = it2->second; if (wire->port_output || wire->port_input) f << stringf("\t.%s(%s)%s\n", id(wire->name.str()).c_str(), @@ -145,23 +146,23 @@ static void autotest(std::ostream &f, RTLIL::Design *design, int num_iter) 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++) + for (auto it = signal_in.begin(); it != signal_in.end(); ++it) 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++) + for (auto it = signal_clk.begin(); it != signal_clk.end(); ++it) 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++) { + for (auto it = signal_clk.begin(); it != signal_clk.end(); ++it) { 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++) + for (auto it = signal_in.begin(); it != signal_in.end(); ++it) 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++) { + for (auto it = signal_clk.begin(); it != signal_clk.end(); ++it) { 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++) { + for (auto it = signal_in.begin(); it != signal_in.end(); ++it) { if (signal_const.count(it->first) == 0) continue; f << stringf("\t%s <= #%d 'b%s;\n", it->first.c_str(), ++delay_counter*2, signal_const[it->first].c_str()); @@ -194,7 +195,7 @@ static void autotest(std::ostream &f, RTLIL::Design *design, int num_iter) f << stringf(" } = {"); for (auto it = signal_clk.begin(); it != signal_clk.end(); it++) 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); + f << stringf(" } ^ (%d'b1 << (xorshift128_w %% %d));\n", total_clock_bits, total_clock_bits + 1); } f << stringf("end\n"); f << stringf("endtask\n\n"); @@ -292,7 +293,7 @@ static void autotest(std::ostream &f, RTLIL::Design *design, int num_iter) 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++) + for (auto it = design->modules_.begin(); it != design->modules_.end(); ++it) if (!it->second->get_bool_attribute("\\gentb_skip")) f << stringf("\t%s;\n", idy(it->first.str(), "test").c_str()); f << stringf("\t$finish;\n"); @@ -335,9 +336,9 @@ struct TestAutotbBackend : public Backend { log_header("Executing TEST_AUTOTB backend (auto-generate pseudo-random test benches).\n"); int argidx; - for (argidx = 1; argidx < SIZE(args); argidx++) + for (argidx = 1; argidx < GetSize(args); argidx++) { - if (args[argidx] == "-n" && argidx+1 < SIZE(args)) { + if (args[argidx] == "-n" && argidx+1 < GetSize(args)) { num_iter = atoi(args[++argidx].c_str()); continue; } diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc index 1fa90b540..268f25598 100644 --- a/passes/tests/test_cell.cc +++ b/passes/tests/test_cell.cc @@ -24,6 +24,9 @@ #include "kernel/macc.h" #include <algorithm> +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + static uint32_t xorshift32_state = 123456789; static uint32_t xorshift32(uint32_t limit) { @@ -33,7 +36,7 @@ static uint32_t xorshift32(uint32_t limit) { return xorshift32_state % limit; } -static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type, std::string cell_type_flags, bool constmode) +static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type, std::string cell_type_flags, bool constmode, bool muxdiv) { RTLIL::Module *module = design->addModule("\\gold"); RTLIL::Cell *cell = module->addCell("\\UUT", cell_type); @@ -199,6 +202,13 @@ static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type, cell->setPort("\\Y", wire); } + if (muxdiv && (cell_type == "$div" || cell_type == "$mod")) { + auto b_not_zero = module->ReduceBool(NEW_ID, cell->getPort("\\B")); + auto div_out = module->addWire(NEW_ID, GetSize(cell->getPort("\\Y"))); + module->addMux(NEW_ID, RTLIL::SigSpec(0, GetSize(div_out)), div_out, b_not_zero, cell->getPort("\\Y")); + cell->setPort("\\Y", div_out); + } + if (cell_type == "$alu") { wire = module->addWire("\\CI"); @@ -210,12 +220,12 @@ static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type, cell->setPort("\\BI", wire); wire = module->addWire("\\X"); - wire->width = SIZE(cell->getPort("\\Y")); + wire->width = GetSize(cell->getPort("\\Y")); wire->port_output = true; cell->setPort("\\X", wire); wire = module->addWire("\\CO"); - wire->width = SIZE(cell->getPort("\\Y")); + wire->width = GetSize(cell->getPort("\\Y")); wire->port_output = true; cell->setPort("\\CO", wire); } @@ -227,25 +237,25 @@ static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type, { RTLIL::SigSpec sig = conn.second; - if (SIZE(sig) == 0 || sig[0].wire == nullptr || sig[0].wire->port_output) + if (GetSize(sig) == 0 || sig[0].wire == nullptr || sig[0].wire->port_output) continue; int n, m; switch (xorshift32(5)) { case 0: - n = xorshift32(SIZE(sig) + 1); + n = xorshift32(GetSize(sig) + 1); for (int i = 0; i < n; i++) sig[i] = xorshift32(2) == 1 ? RTLIL::S1 : RTLIL::S0; break; case 1: - n = xorshift32(SIZE(sig) + 1); - for (int i = n; i < SIZE(sig); i++) + n = xorshift32(GetSize(sig) + 1); + for (int i = n; i < GetSize(sig); i++) sig[i] = xorshift32(2) == 1 ? RTLIL::S1 : RTLIL::S0; break; case 2: - n = xorshift32(SIZE(sig)); - m = xorshift32(SIZE(sig)); + n = xorshift32(GetSize(sig)); + m = xorshift32(GetSize(sig)); for (int i = std::min(n, m); i < std::max(n, m); i++) sig[i] = xorshift32(2) == 1 ? RTLIL::S1 : RTLIL::S0; break; @@ -268,10 +278,10 @@ static void run_eval_test(RTLIL::Design *design, bool verbose, bool nosat, std:: RTLIL::Module *gate_mod = design->module("\\gate"); ConstEval gold_ce(gold_mod), gate_ce(gate_mod); - ezDefaultSAT ez1, ez2; + ezSatPtr ez1, ez2; SigMap sigmap(gold_mod); - SatGen satgen1(&ez1, &sigmap); - SatGen satgen2(&ez2, &sigmap); + SatGen satgen1(ez1.get(), &sigmap); + SatGen satgen2(ez2.get(), &sigmap); satgen2.model_undef = true; if (!nosat) @@ -287,19 +297,19 @@ static void run_eval_test(RTLIL::Design *design, bool verbose, bool nosat, std:: for (auto port : gold_mod->ports) { RTLIL::Wire *wire = gold_mod->wire(port); if (wire->port_input) - vlog_file << stringf(" reg [%d:0] %s;\n", SIZE(wire)-1, log_id(wire)); + vlog_file << stringf(" reg [%d:0] %s;\n", GetSize(wire)-1, log_id(wire)); else - vlog_file << stringf(" wire [%d:0] %s_expr, %s_noexpr;\n", SIZE(wire)-1, log_id(wire), log_id(wire)); + vlog_file << stringf(" wire [%d:0] %s_expr, %s_noexpr;\n", GetSize(wire)-1, log_id(wire), log_id(wire)); } vlog_file << stringf(" %s_expr uut_expr(", uut_name.c_str()); - for (int i = 0; i < SIZE(gold_mod->ports); i++) + for (int i = 0; i < GetSize(gold_mod->ports); i++) vlog_file << stringf("%s.%s(%s%s)", i ? ", " : "", log_id(gold_mod->ports[i]), log_id(gold_mod->ports[i]), gold_mod->wire(gold_mod->ports[i])->port_input ? "" : "_expr"); vlog_file << stringf(");\n"); vlog_file << stringf(" %s_expr uut_noexpr(", uut_name.c_str()); - for (int i = 0; i < SIZE(gold_mod->ports); i++) + for (int i = 0; i < GetSize(gold_mod->ports); i++) vlog_file << stringf("%s.%s(%s%s)", i ? ", " : "", log_id(gold_mod->ports[i]), log_id(gold_mod->ports[i]), gold_mod->wire(gold_mod->ports[i])->port_input ? "" : "_noexpr"); vlog_file << stringf(");\n"); @@ -327,18 +337,18 @@ static void run_eval_test(RTLIL::Design *design, bool verbose, bool nosat, std:: log_assert(gold_wire != nullptr); log_assert(gate_wire != nullptr); log_assert(gold_wire->port_input == gate_wire->port_input); - log_assert(SIZE(gold_wire) == SIZE(gate_wire)); + log_assert(GetSize(gold_wire) == GetSize(gate_wire)); if (!gold_wire->port_input) continue; RTLIL::Const in_value; - for (int i = 0; i < SIZE(gold_wire); i++) + for (int i = 0; i < GetSize(gold_wire); i++) in_value.bits.push_back(xorshift32(2) ? RTLIL::S1 : RTLIL::S0); if (xorshift32(4) == 0) { int inv_chance = 1 + xorshift32(8); - for (int i = 0; i < SIZE(gold_wire); i++) + for (int i = 0; i < GetSize(gold_wire); i++) if (xorshift32(inv_chance) == 0) in_value.bits[i] = RTLIL::Sx; } @@ -352,7 +362,7 @@ static void run_eval_test(RTLIL::Design *design, bool verbose, bool nosat, std:: gold_ce.set(gold_wire, in_value); gate_ce.set(gate_wire, in_value); - if (vlog_file.is_open() && SIZE(in_value) > 0) { + if (vlog_file.is_open() && GetSize(in_value) > 0) { vlog_file << stringf(" %s = 'b%s;\n", log_id(gold_wire), in_value.as_string().c_str()); if (!vlog_pattern_info.empty()) vlog_pattern_info += " "; @@ -371,7 +381,7 @@ static void run_eval_test(RTLIL::Design *design, bool verbose, bool nosat, std:: log_assert(gold_wire != nullptr); log_assert(gate_wire != nullptr); log_assert(gold_wire->port_output == gate_wire->port_output); - log_assert(SIZE(gold_wire) == SIZE(gate_wire)); + log_assert(GetSize(gold_wire) == GetSize(gate_wire)); if (!gold_wire->port_output) continue; @@ -386,7 +396,7 @@ static void run_eval_test(RTLIL::Design *design, bool verbose, bool nosat, std:: log_error("Failed to eval %s in gate module.\n", log_id(gate_wire)); bool gold_gate_mismatch = false; - for (int i = 0; i < SIZE(gold_wire); i++) { + for (int i = 0; i < GetSize(gold_wire); i++) { if (gold_outval[i] == RTLIL::Sx) continue; if (gold_outval[i] == gate_outval[i]) @@ -406,9 +416,9 @@ static void run_eval_test(RTLIL::Design *design, bool verbose, bool nosat, std:: if (vlog_file.is_open()) { vlog_file << stringf(" $display(\"[%s] %s expected: %%b, expr: %%b, noexpr: %%b\", %d'b%s, %s_expr, %s_noexpr);\n", - vlog_pattern_info.c_str(), log_id(gold_wire), SIZE(gold_outval), gold_outval.as_string().c_str(), log_id(gold_wire), log_id(gold_wire)); - vlog_file << stringf(" if (%s_expr !== %d'b%s) begin $display(\"ERROR\"); $finish; end\n", log_id(gold_wire), SIZE(gold_outval), gold_outval.as_string().c_str()); - vlog_file << stringf(" if (%s_noexpr !== %d'b%s) begin $display(\"ERROR\"); $finish; end\n", log_id(gold_wire), SIZE(gold_outval), gold_outval.as_string().c_str()); + vlog_pattern_info.c_str(), log_id(gold_wire), GetSize(gold_outval), gold_outval.as_string().c_str(), log_id(gold_wire), log_id(gold_wire)); + vlog_file << stringf(" if (%s_expr !== %d'b%s) begin $display(\"ERROR\"); $finish; end\n", log_id(gold_wire), GetSize(gold_outval), gold_outval.as_string().c_str()); + vlog_file << stringf(" if (%s_noexpr !== %d'b%s) begin $display(\"ERROR\"); $finish; end\n", log_id(gold_wire), GetSize(gold_outval), gold_outval.as_string().c_str()); } } @@ -423,17 +433,17 @@ static void run_eval_test(RTLIL::Design *design, bool verbose, bool nosat, std:: std::vector<int> sat1_model = satgen1.importSigSpec(out_sig); std::vector<bool> sat1_model_value; - if (!ez1.solve(sat1_model, sat1_model_value, ez1.vec_eq(sat1_in_sig, sat1_in_val))) + if (!ez1->solve(sat1_model, sat1_model_value, ez1->vec_eq(sat1_in_sig, sat1_in_val))) log_error("Evaluating sat model 1 (no undef modeling) failed!\n"); if (verbose) { log("SAT 1: "); - for (int i = SIZE(out_sig)-1; i >= 0; i--) + for (int i = GetSize(out_sig)-1; i >= 0; i--) log("%c", sat1_model_value.at(i) ? '1' : '0'); log("\n"); } - for (int i = 0; i < SIZE(out_sig); i++) { + for (int i = 0; i < GetSize(out_sig); i++) { if (out_val[i] != RTLIL::S0 && out_val[i] != RTLIL::S1) continue; if (out_val[i] == RTLIL::S0 && sat1_model_value.at(i) == false) @@ -458,18 +468,18 @@ static void run_eval_test(RTLIL::Design *design, bool verbose, bool nosat, std:: std::vector<bool> sat2_model_value; - if (!ez2.solve(sat2_model, sat2_model_value, ez2.vec_eq(sat2_in_def_sig, sat2_in_def_val), ez2.vec_eq(sat2_in_undef_sig, sat2_in_undef_val))) + if (!ez2->solve(sat2_model, sat2_model_value, ez2->vec_eq(sat2_in_def_sig, sat2_in_def_val), ez2->vec_eq(sat2_in_undef_sig, sat2_in_undef_val))) log_error("Evaluating sat model 2 (undef modeling) failed!\n"); if (verbose) { log("SAT 2: "); - for (int i = SIZE(out_sig)-1; i >= 0; i--) - log("%c", sat2_model_value.at(SIZE(out_sig) + i) ? 'x' : sat2_model_value.at(i) ? '1' : '0'); + for (int i = GetSize(out_sig)-1; i >= 0; i--) + log("%c", sat2_model_value.at(GetSize(out_sig) + i) ? 'x' : sat2_model_value.at(i) ? '1' : '0'); log("\n"); } - for (int i = 0; i < SIZE(out_sig); i++) { - if (sat2_model_value.at(SIZE(out_sig) + i)) { + for (int i = 0; i < GetSize(out_sig); i++) { + if (sat2_model_value.at(GetSize(out_sig) + i)) { if (out_val[i] != RTLIL::S0 && out_val[i] != RTLIL::S1) continue; } else { @@ -505,7 +515,7 @@ struct TestCellPass : public Pass { log("by comparing SAT solver, EVAL and TECHMAP implementations of the cell types..\n"); log("\n"); log("Run with 'all' instead of a cell type to run the test on all supported\n"); - log("cell types.\n"); + log("cell types. Use for example 'all /$add' for all cell types except $add.\n"); log("\n"); log(" -n {integer}\n"); log(" create this number of cell instances and test them (default = 100).\n"); @@ -516,12 +526,20 @@ struct TestCellPass : public Pass { log(" -f {ilang_file}\n"); log(" don't generate circuits. instead load the specified ilang file.\n"); log("\n"); + log(" -w {filename_prefix}\n"); + log(" don't test anything. just generate the circuits and write them\n"); + log(" to ilang files with the specified prefix\n"); + log("\n"); log(" -map {filename}\n"); log(" pass this option to techmap.\n"); log("\n"); - log(" -simplib\n"); + log(" -simlib\n"); log(" use \"techmap -map +/simlib.v -max_iter 2 -autoproc\"\n"); log("\n"); + log(" -muxdiv\n"); + log(" when creating test benches with dividers, create an additional mux\n"); + log(" to mask out the division-by-zero case\n"); + log("\n"); log(" -script {script_file}\n"); log(" instead of calling \"techmap\", call \"script {script_file}\".\n"); log("\n"); @@ -542,34 +560,39 @@ struct TestCellPass : public Pass { { int num_iter = 100; std::string techmap_cmd = "techmap -assert"; - std::string ilang_file; + std::string ilang_file, write_prefix; xorshift32_state = 0; std::ofstream vlog_file; + bool muxdiv = false; bool verbose = false; bool constmode = false; bool nosat = false; int argidx; - for (argidx = 1; argidx < SIZE(args); argidx++) + for (argidx = 1; argidx < GetSize(args); argidx++) { - if (args[argidx] == "-n" && argidx+1 < SIZE(args)) { + if (args[argidx] == "-n" && argidx+1 < GetSize(args)) { num_iter = atoi(args[++argidx].c_str()); continue; } - if (args[argidx] == "-s" && argidx+1 < SIZE(args)) { + if (args[argidx] == "-s" && argidx+1 < GetSize(args)) { xorshift32_state = atoi(args[++argidx].c_str()); continue; } - if (args[argidx] == "-map" && argidx+1 < SIZE(args)) { + if (args[argidx] == "-map" && argidx+1 < GetSize(args)) { techmap_cmd += " -map " + args[++argidx]; continue; } - if (args[argidx] == "-f" && argidx+1 < SIZE(args)) { + if (args[argidx] == "-f" && argidx+1 < GetSize(args)) { ilang_file = args[++argidx]; num_iter = 1; continue; } - if (args[argidx] == "-script" && argidx+1 < SIZE(args)) { + if (args[argidx] == "-w" && argidx+1 < GetSize(args)) { + write_prefix = args[++argidx]; + continue; + } + if (args[argidx] == "-script" && argidx+1 < GetSize(args)) { techmap_cmd = "script " + args[++argidx]; continue; } @@ -577,6 +600,10 @@ struct TestCellPass : public Pass { techmap_cmd = "techmap -map +/simlib.v -max_iter 2 -autoproc"; continue; } + if (args[argidx] == "-muxdiv") { + muxdiv = true; + continue; + } if (args[argidx] == "-const") { constmode = true; continue; @@ -589,7 +616,7 @@ struct TestCellPass : public Pass { verbose = true; continue; } - if (args[argidx] == "-vlog" && argidx+1 < SIZE(args)) { + if (args[argidx] == "-vlog" && argidx+1 < GetSize(args)) { vlog_file.open(args[++argidx], std::ios_base::trunc); if (!vlog_file.is_open()) log_cmd_error("Failed to open output file `%s'.\n", args[argidx].c_str()); @@ -660,7 +687,7 @@ struct TestCellPass : public Pass { cell_types["$macc"] = "*"; cell_types["$fa"] = "*"; - for (; argidx < SIZE(args); argidx++) + for (; argidx < GetSize(args); argidx++) { if (args[argidx].rfind("-", 0) == 0) log_cmd_error("Unexpected option: %s\n", args[argidx].c_str()); @@ -672,6 +699,15 @@ struct TestCellPass : public Pass { continue; } + if (args[argidx].substr(0, 1) == "/") { + std::vector<std::string> new_selected_cell_types; + for (auto it : selected_cell_types) + if (it != args[argidx].substr(1)) + new_selected_cell_types.push_back(it); + new_selected_cell_types.swap(selected_cell_types); + continue; + } + if (cell_types.count(args[argidx]) == 0) { std::string cell_type_list; int charcount = 100; @@ -681,7 +717,7 @@ struct TestCellPass : public Pass { charcount = 0; } else cell_type_list += " " + it.first; - charcount += SIZE(it.first); + charcount += GetSize(it.first); } log_cmd_error("The cell type `%s' is currently not supported. Try one of these:%s\n", args[argidx].c_str(), cell_type_list.c_str()); @@ -709,24 +745,28 @@ struct TestCellPass : public Pass { if (cell_type == "ilang") Frontend::frontend_call(design, NULL, std::string(), "ilang " + ilang_file); else - create_gold_module(design, cell_type, cell_types.at(cell_type), constmode); - Pass::call(design, stringf("copy gold gate; cd gate; %s; cd ..; opt -fast gate", techmap_cmd.c_str())); - if (!nosat) - Pass::call(design, "miter -equiv -flatten -make_outputs -ignore_gold_x gold gate miter"); - if (verbose) - Pass::call(design, "dump gate"); - Pass::call(design, "dump gold"); - if (!nosat) - Pass::call(design, "sat -verify -enable_undef -prove trigger 0 -show-inputs -show-outputs miter"); - std::string uut_name = stringf("uut_%s_%d", cell_type.substr(1).c_str(), i); - if (vlog_file.is_open()) { - Pass::call(design, stringf("copy gold %s_expr; select %s_expr", uut_name.c_str(), uut_name.c_str())); - Backend::backend_call(design, &vlog_file, "<test_cell -vlog>", "verilog -selected"); - Pass::call(design, stringf("copy gold %s_noexpr; select %s_noexpr", uut_name.c_str(), uut_name.c_str())); - Backend::backend_call(design, &vlog_file, "<test_cell -vlog>", "verilog -selected -noexpr"); - uut_names.push_back(uut_name); + create_gold_module(design, cell_type, cell_types.at(cell_type), constmode, muxdiv); + if (!write_prefix.empty()) { + Pass::call(design, stringf("write_ilang %s_%s_%05d.il", write_prefix.c_str(), cell_type.c_str()+1, i)); + } else { + Pass::call(design, stringf("copy gold gate; cd gate; %s; cd ..; opt -fast gate", techmap_cmd.c_str())); + if (!nosat) + Pass::call(design, "miter -equiv -flatten -make_outputs -ignore_gold_x gold gate miter"); + if (verbose) + Pass::call(design, "dump gate"); + Pass::call(design, "dump gold"); + if (!nosat) + Pass::call(design, "sat -verify -enable_undef -prove trigger 0 -show-inputs -show-outputs miter"); + std::string uut_name = stringf("uut_%s_%d", cell_type.substr(1).c_str(), i); + if (vlog_file.is_open()) { + Pass::call(design, stringf("copy gold %s_expr; select %s_expr", uut_name.c_str(), uut_name.c_str())); + Backend::backend_call(design, &vlog_file, "<test_cell -vlog>", "verilog -selected"); + Pass::call(design, stringf("copy gold %s_noexpr; select %s_noexpr", uut_name.c_str(), uut_name.c_str())); + Backend::backend_call(design, &vlog_file, "<test_cell -vlog>", "verilog -selected -noexpr"); + uut_names.push_back(uut_name); + } + run_eval_test(design, verbose, nosat, uut_name, vlog_file); } - run_eval_test(design, verbose, nosat, uut_name, vlog_file); delete design; } @@ -743,3 +783,4 @@ struct TestCellPass : public Pass { } } TestCellPass; +PRIVATE_NAMESPACE_END |