diff options
Diffstat (limited to 'passes/tests/test_autotb.cc')
-rw-r--r-- | passes/tests/test_autotb.cc | 63 |
1 files changed, 44 insertions, 19 deletions
diff --git a/passes/tests/test_autotb.cc b/passes/tests/test_autotb.cc index bb516fca..cb31056f 100644 --- a/passes/tests/test_autotb.cc +++ b/passes/tests/test_autotb.cc @@ -71,16 +71,21 @@ static std::string idy(std::string str1, std::string str2 = std::string(), std:: return id(str1); } -static void autotest(std::ostream &f, RTLIL::Design *design, int num_iter) +static void autotest(std::ostream &f, RTLIL::Design *design, int num_iter, int seed) { + f << stringf("`ifndef outfile\n"); + f << stringf("\t`define outfile \"/dev/stdout\"\n"); + f << stringf("`endif\n"); + f << stringf("module testbench;\n\n"); - f << stringf("integer i;\n\n"); + f << stringf("integer i;\n"); + f << stringf("integer file;\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_w = %u; // <-- seed value\n", seed ? seed : int(time(NULL))); f << stringf("reg [31:0] xorshift128_t;\n\n"); f << stringf("task xorshift128;\n"); f << stringf("begin\n"); @@ -150,6 +155,7 @@ static void autotest(std::ostream &f, RTLIL::Design *design, int num_iter) 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) f << stringf("\t%s <= #%d 0;\n", it->first.c_str(), ++delay_counter*2); + f << stringf("\t#%d;\n", ((2*delay_counter+99)/100)*100); 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()); @@ -157,6 +163,7 @@ static void autotest(std::ostream &f, RTLIL::Design *design, int num_iter) delay_counter = 0; 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); + f << stringf("\t#%d;\n", ((2*delay_counter+99)/100)*100); 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()); @@ -167,6 +174,7 @@ static void autotest(std::ostream &f, RTLIL::Design *design, int num_iter) continue; f << stringf("\t%s <= #%d 'b%s;\n", it->first.c_str(), ++delay_counter*2, signal_const[it->first].c_str()); } + f << stringf("\t#%d;\n", ((2*delay_counter+99)/100)*100); f << stringf("end\n"); f << stringf("endtask\n\n"); @@ -179,6 +187,7 @@ static void autotest(std::ostream &f, RTLIL::Design *design, int num_iter) 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); } + f << stringf("\t#%d;\n", ((2*delay_counter+99)/100)*100); f << stringf("end\n"); f << stringf("endtask\n\n"); @@ -206,61 +215,70 @@ static void autotest(std::ostream &f, RTLIL::Design *design, int num_iter) 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\", {"); + f << stringf("\t$fdisplay(file, \"#OUT# %%b %%b %%b %%t %%d\", {"); if (signal_in.size()) for (auto it = signal_in.begin(); it != signal_in.end(); it++) { f << stringf("%s %s", it == signal_in.begin() ? "" : ",", it->first.c_str()); int len = it->second; + header2 += ", \""; if (len > 1) header2 += "/", len--; while (len > 1) header2 += "-", len--; if (len > 0) header2 += shorthand, len--; + header2 += "\""; header1.push_back(" " + it->first); - header1.back()[0] = shorthand++; + header1.back()[0] = shorthand; + shorthand = shorthand == 'Z' ? 'A' : shorthand+1; } else { f << stringf(" 1'bx"); - header2 += "#"; + header2 += ", \"#\""; } f << stringf(" }, {"); - header2 += " "; + header2 += ", \" \""; if (signal_clk.size()) { for (auto it = signal_clk.begin(); it != signal_clk.end(); it++) { f << stringf("%s %s", it == signal_clk.begin() ? "" : ",", it->first.c_str()); int len = it->second; + header2 += ", \""; if (len > 1) header2 += "/", len--; while (len > 1) header2 += "-", len--; if (len > 0) header2 += shorthand, len--; + header2 += "\""; header1.push_back(" " + it->first); - header1.back()[0] = shorthand++; + header1.back()[0] = shorthand; + shorthand = shorthand == 'Z' ? 'A' : shorthand+1; } } else { f << stringf(" 1'bx"); - header2 += "#"; + header2 += ", \"#\""; } f << stringf(" }, {"); - header2 += " "; + header2 += ", \" \""; if (signal_out.size()) { for (auto it = signal_out.begin(); it != signal_out.end(); it++) { f << stringf("%s %s", it == signal_out.begin() ? "" : ",", it->first.c_str()); int len = it->second; + header2 += ", \""; if (len > 1) header2 += "/", len--; while (len > 1) header2 += "-", len--; if (len > 0) header2 += shorthand, len--; + header2 += "\""; header1.push_back(" " + it->first); - header1.back()[0] = shorthand++; + header1.back()[0] = shorthand; + shorthand = shorthand == 'Z' ? 'A' : shorthand+1; } } else { f << stringf(" 1'bx"); - header2 += "#"; + header2 += ", \"#\""; } f << stringf(" }, $time, i);\n"); f << stringf("end\n"); @@ -268,17 +286,17 @@ static void autotest(std::ostream &f, RTLIL::Design *design, int num_iter) f << stringf("task %s;\n", idy(mod->name.str(), "print_header").c_str()); f << stringf("begin\n"); - f << stringf("\t$display(\"#OUT#\");\n"); + f << stringf("\t$fdisplay(file, \"#OUT#\");\n"); for (auto &hdr : header1) - 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("\t$fdisplay(file, \"#OUT# %s\");\n", hdr.c_str()); + f << stringf("\t$fdisplay(file, \"#OUT#\");\n"); + f << stringf("\t$fdisplay(file, {\"#OUT# \"%s});\n", header2.c_str()); f << stringf("end\n"); f << stringf("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$fdisplay(file, \"#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()); @@ -293,9 +311,11 @@ 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"); + f << stringf("\tfile = $fopen(`outfile);\n"); 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$fclose(file);\n"); f << stringf("\t$finish;\n"); f << stringf("end\n\n"); @@ -332,8 +352,9 @@ struct TestAutotbBackend : public Backend { virtual void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) { int num_iter = 1000; + int seed = 0; - log_header("Executing TEST_AUTOTB backend (auto-generate pseudo-random test benches).\n"); + log_header(design, "Executing TEST_AUTOTB backend (auto-generate pseudo-random test benches).\n"); int argidx; for (argidx = 1; argidx < GetSize(args); argidx++) @@ -342,11 +363,15 @@ struct TestAutotbBackend : public Backend { num_iter = atoi(args[++argidx].c_str()); continue; } + if (args[argidx] == "-seed" && argidx+1 < GetSize(args)) { + seed = atoi(args[++argidx].c_str()); + continue; + } break; } extra_args(f, filename, args, argidx); - autotest(*f, design, num_iter); + autotest(*f, design, num_iter, seed); } } TestAutotbBackend; |