76 f <<
stringf(
"module testbench;\n\n");
80 f <<
stringf(
"reg [31:0] xorshift128_x = 123456789;\n");
81 f <<
stringf(
"reg [31:0] xorshift128_y = 362436069;\n");
82 f <<
stringf(
"reg [31:0] xorshift128_z = 521288629;\n");
83 f <<
stringf(
"reg [31:0] xorshift128_w = %u; // <-- seed value\n",
int(
time(
NULL)));
84 f <<
stringf(
"reg [31:0] xorshift128_t;\n\n");
85 f <<
stringf(
"task xorshift128;\n");
87 f <<
stringf(
"\txorshift128_t = xorshift128_x ^ (xorshift128_x << 11);\n");
88 f <<
stringf(
"\txorshift128_x = xorshift128_y;\n");
89 f <<
stringf(
"\txorshift128_y = xorshift128_z;\n");
90 f <<
stringf(
"\txorshift128_z = xorshift128_w;\n");
91 f <<
stringf(
"\txorshift128_w = xorshift128_w ^ (xorshift128_w >> 19) ^ xorshift128_t ^ (xorshift128_t >> 8);\n");
97 std::map<std::string, int> signal_in;
98 std::map<std::string, std::string> signal_const;
99 std::map<std::string, int> signal_clk;
100 std::map<std::string, int> signal_out;
104 if (mod->get_bool_attribute(
"\\gentb_skip"))
108 log(
"Generating test bench for module `%s'.\n", it->first.c_str());
109 for (
auto it2 = mod->
wires_.begin(); it2 != mod->
wires_.end(); it2++) {
117 bool is_clksignal = wire->get_bool_attribute(
"\\gentb_clock");
119 for (
auto it4 = it3->second->syncs.begin(); it4 != it3->second->syncs.end(); it4++) {
123 for (
auto &c : signal.
chunks())
127 if (is_clksignal && wire->attributes.count(
"\\gentb_constant") == 0) {
131 if (wire->attributes.count(
"\\gentb_constant") != 0)
132 signal_const[
idy(
"sig", mod->
name.
str(), wire->
name.
str())] = wire->attributes[
"\\gentb_constant"].as_string();
138 for (
auto it2 = mod->
wires_.begin(); it2 != mod->
wires_.end(); it2++) {
142 idy(
"sig", mod->
name.
str(), wire->
name.
str()).c_str(), --count_ports ?
"," :
"");
148 int delay_counter = 0;
149 for (
auto it = signal_in.begin(); it != signal_in.end(); it++)
150 f <<
stringf(
"\t%s <= #%d 0;\n", it->first.c_str(), ++delay_counter*2);
151 for (
auto it = signal_clk.begin(); it != signal_clk.end(); it++)
152 f <<
stringf(
"\t%s <= #%d 0;\n", it->first.c_str(), ++delay_counter*2);
153 for (
auto it = signal_clk.begin(); it != signal_clk.end(); it++) {
154 f <<
stringf(
"\t#100; %s <= 1;\n", it->first.c_str());
155 f <<
stringf(
"\t#100; %s <= 0;\n", it->first.c_str());
158 for (
auto it = signal_in.begin(); it != signal_in.end(); it++)
159 f <<
stringf(
"\t%s <= #%d ~0;\n", it->first.c_str(), ++delay_counter*2);
160 for (
auto it = signal_clk.begin(); it != signal_clk.end(); it++) {
161 f <<
stringf(
"\t#100; %s <= 1;\n", it->first.c_str());
162 f <<
stringf(
"\t#100; %s <= 0;\n", it->first.c_str());
165 for (
auto it = signal_in.begin(); it != signal_in.end(); it++) {
166 if (signal_const.count(it->first) == 0)
168 f <<
stringf(
"\t%s <= #%d 'b%s;\n", it->first.c_str(), ++delay_counter*2, signal_const[it->first].c_str());
176 for (
auto it = signal_in.begin(); it != signal_in.end(); it++) {
177 if (signal_const.count(it->first) > 0)
179 f <<
stringf(
"\txorshift128;\n");
180 f <<
stringf(
"\t%s <= #%d { xorshift128_x, xorshift128_y, xorshift128_z, xorshift128_w };\n", it->first.c_str(), ++delay_counter*2);
187 if (signal_clk.size()) {
188 f <<
stringf(
"\txorshift128;\n");
190 int total_clock_bits = 0;
191 for (
auto it = signal_clk.begin(); it != signal_clk.end(); it++) {
192 f <<
stringf(
"%s %s", it == signal_clk.begin() ?
"" :
",", it->first.c_str());
193 total_clock_bits += it->second;
196 for (
auto it = signal_clk.begin(); it != signal_clk.end(); it++)
197 f <<
stringf(
"%s %s", it == signal_clk.begin() ?
"" :
",", it->first.c_str());
198 f <<
stringf(
" } ^ (%d'b1 << (xorshift128_w %% %d));\n", total_clock_bits, total_clock_bits);
203 char shorthand =
'A';
204 std::vector<std::string> header1;
205 std::string header2 =
"";
209 f <<
stringf(
"\t$display(\"#OUT# %%b %%b %%b %%t %%d\", {");
210 if (signal_in.size())
211 for (
auto it = signal_in.begin(); it != signal_in.end(); it++) {
212 f <<
stringf(
"%s %s", it == signal_in.begin() ?
"" :
",", it->first.c_str());
213 int len = it->second;
215 header2 +=
"/", len--;
217 header2 +=
"-", len--;
219 header2 += shorthand, len--;
220 header1.push_back(
" " + it->first);
221 header1.back()[0] = shorthand++;
229 if (signal_clk.size()) {
230 for (
auto it = signal_clk.begin(); it != signal_clk.end(); it++) {
231 f <<
stringf(
"%s %s", it == signal_clk.begin() ?
"" :
",", it->first.c_str());
232 int len = it->second;
234 header2 +=
"/", len--;
236 header2 +=
"-", len--;
238 header2 += shorthand, len--;
239 header1.push_back(
" " + it->first);
240 header1.back()[0] = shorthand++;
248 if (signal_out.size()) {
249 for (
auto it = signal_out.begin(); it != signal_out.end(); it++) {
250 f <<
stringf(
"%s %s", it == signal_out.begin() ?
"" :
",", it->first.c_str());
251 int len = it->second;
253 header2 +=
"/", len--;
255 header2 +=
"-", len--;
257 header2 += shorthand, len--;
258 header1.push_back(
" " + it->first);
259 header1.back()[0] = shorthand++;
265 f <<
stringf(
" }, $time, i);\n");
271 f <<
stringf(
"\t$display(\"#OUT#\");\n");
272 for (
auto &hdr : header1)
273 f <<
stringf(
"\t$display(\"#OUT# %s\");\n", hdr.c_str());
274 f <<
stringf(
"\t$display(\"#OUT#\");\n");
275 f <<
stringf(
"\t$display(\"#OUT# %s\");\n", header2.c_str());
281 f <<
stringf(
"\t$display(\"#OUT#\\n#OUT# ==== %s ====\");\n",
idy(mod->
name.
str()).c_str());
283 f <<
stringf(
"\tfor (i=0; i<%d; i=i+1) begin\n", num_iter);
284 f <<
stringf(
"\t\tif (i %% 20 == 0) %s;\n",
idy(mod->
name.
str(),
"print_header").c_str());
293 f <<
stringf(
"initial begin\n");
294 f <<
stringf(
"\t// $dumpfile(\"testbench.vcd\");\n");
295 f <<
stringf(
"\t// $dumpvars(0, testbench);\n");
296 for (
auto it = design->
modules_.begin(); it != design->
modules_.end(); it++)
297 if (!it->second->get_bool_attribute(
"\\gentb_skip"))
298 f <<
stringf(
"\t%s;\n",
idy(it->first.str(),
"test").c_str());
std::string stringf(const char *fmt,...)
std::map< RTLIL::IdString, RTLIL::Wire * > wires_
std::map< RTLIL::IdString, RTLIL::Process * > processes
std::map< RTLIL::IdString, RTLIL::Module * > modules_
void log(const char *format,...)
static std::string idy(std::string str1, std::string str2=std::string(), std::string str3=std::string())
const std::vector< RTLIL::SigChunk > & chunks() const