diff options
Diffstat (limited to 'tests/realmath')
-rw-r--r-- | tests/realmath/.gitignore | 1 | ||||
-rw-r--r-- | tests/realmath/generate.py | 91 | ||||
-rwxr-xr-x | tests/realmath/run-test.sh | 24 |
3 files changed, 116 insertions, 0 deletions
diff --git a/tests/realmath/.gitignore b/tests/realmath/.gitignore new file mode 100644 index 000000000..9c595a6fb --- /dev/null +++ b/tests/realmath/.gitignore @@ -0,0 +1 @@ +temp diff --git a/tests/realmath/generate.py b/tests/realmath/generate.py new file mode 100644 index 000000000..972021dc8 --- /dev/null +++ b/tests/realmath/generate.py @@ -0,0 +1,91 @@ +#!/usr/bin/python + +from __future__ import division +from __future__ import print_function + +import sys +import random +from contextlib import contextmanager + +@contextmanager +def redirect_stdout(new_target): + old_target, sys.stdout = sys.stdout, new_target + try: + yield new_target + finally: + sys.stdout = old_target + +def random_expression(depth = 3, maxparam = 0): + def recursion(): + return random_expression(depth = depth-1, maxparam = maxparam) + if depth == 0: + if maxparam != 0 and random.randint(0, 1) != 0: + return 'p%02d' % random.randint(0, maxparam-1) + return random.choice([ '%e', '%f', '%g' ]) % random.uniform(-2, +2) + if random.randint(0, 4) == 0: + return recursion() + random.choice([ ' < ', ' <= ', ' == ', ' != ', ' >= ', ' > ' ]) + recursion() + ' ? ' + recursion() + ' : ' + recursion() + op_prefix = [ '+(', '-(' ] + op_infix = [ ' + ', ' - ', ' * ', ' / ' ] + op_func1 = [ '$ln', '$log10', '$exp', '$sqrt', '$floor', '$ceil', '$sin', '$cos', '$tan', '$asin', '$acos', '$atan', '$sinh', '$cosh', '$tanh', '$asinh', '$acosh', '$atanh' ] + op_func2 = [ '$pow', '$atan2', '$hypot' ] + op = random.choice(op_prefix + op_infix + op_func1 + op_func2) + if op in op_prefix: + return op + recursion() + ')' + if op in op_infix: + return '(' + recursion() + op + recursion() + ')' + if op in op_func1: + return op + '(' + recursion() + ')' + if op in op_func2: + return op + '(' + recursion() + ', ' + recursion() + ')' + raise + +for idx in range(100): + with file('temp/uut_%05d.v' % idx, 'w') as f, redirect_stdout(f): + print('module uut_%05d(output [63:0] %s);\n' % (idx, ', '.join(['y%02d' % i for i in range(100)]))) + for i in range(30): + if idx < 10: + print('localparam p%02d = %s;' % (i, random_expression())) + else: + print('localparam%s p%02d = %s;' % (random.choice(['', ' real', ' integer']), i, random_expression())) + for i in range(30, 60): + if idx < 10: + print('localparam p%02d = %s;' % (i, random_expression(maxparam = 30))) + else: + print('localparam%s p%02d = %s;' % (random.choice(['', ' real', ' integer']), i, random_expression(maxparam = 30))) + for i in range(100): + print('assign y%02d = 65536 * (%s);' % (i, random_expression(maxparam = 60))) + print('endmodule') + with file('temp/uut_%05d.ys' % idx, 'w') as f, redirect_stdout(f): + print('read_verilog uut_%05d.v' % idx) + print('rename uut_%05d uut_%05d_syn' % (idx, idx)) + print('write_verilog uut_%05d_syn.v' % idx) + with file('temp/uut_%05d_tb.v' % idx, 'w') as f, redirect_stdout(f): + print('module uut_%05d_tb;\n' % idx) + print('wire [63:0] %s;' % (', '.join(['r%02d' % i for i in range(100)]))) + print('wire [63:0] %s;' % (', '.join(['s%02d' % i for i in range(100)]))) + print('uut_%05d ref(%s);' % (idx, ', '.join(['r%02d' % i for i in range(100)]))) + print('uut_%05d_syn syn(%s);' % (idx, ', '.join(['s%02d' % i for i in range(100)]))) + print('task compare_ref_syn;') + print(' input [7:0] i;') + print(' input [63:0] r, s;') + print(' reg [64*8-1:0] buffer;') + print(' integer j;') + print(' begin') + print(' if (-1 <= $signed(r-s) && $signed(r-s) <= +1) begin') + print(' // $display("%d: %b %b", i, r, s);') + print(' end else if (r === s) begin ') + print(' // $display("%d: %b %b", i, r, s);') + print(' end else begin ') + print(' for (j = 0; j < 64; j = j+1)') + print(' buffer[j*8 +: 8] = r[j] !== s[j] ? "^" : " ";') + print(' $display("\\n%3d: %b %b", i, r, s);') + print(' $display(" %s %s", buffer, buffer);') + print(' end') + print(' end') + print('endtask') + print('initial begin #1;') + for i in range(100): + print(' compare_ref_syn(%2d, r%02d, s%02d);' % (i, i, i)) + print('end') + print('endmodule') + diff --git a/tests/realmath/run-test.sh b/tests/realmath/run-test.sh new file mode 100755 index 000000000..b8e222ad6 --- /dev/null +++ b/tests/realmath/run-test.sh @@ -0,0 +1,24 @@ +#!/bin/bash +set -e + +rm -rf temp +mkdir -p temp +echo "generating tests.." +python generate.py + +cd temp +echo "running tests.." +for ((i = 0; i < 100; i++)); do + echo -n "[$i]" + idx=$( printf "%05d" $i ) + ../../../yosys -q uut_${idx}.ys + iverilog -o uut_${idx}_tb uut_${idx}_tb.v uut_${idx}.v uut_${idx}_syn.v + ./uut_${idx}_tb | tee uut_${idx}.err + if test -s uut_${idx}.err; then + echo "Note: Make sure that 'iverilog' is an up-to-date git checkout of icarus verilog." + exit 1 + fi + rm -f uut_${idx}.err +done +echo + |