summaryrefslogtreecommitdiff
path: root/passes/tests/test_autotb.cc
diff options
context:
space:
mode:
Diffstat (limited to 'passes/tests/test_autotb.cc')
-rw-r--r--passes/tests/test_autotb.cc63
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;