summaryrefslogtreecommitdiff
path: root/tests/fsm/generate.py
blob: b5b4626dfb8e95b8a1b5bde50d3f986377031cea (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#!/usr/bin/python

from __future__ import division
from __future__ import print_function

import sys
import random
from contextlib import contextmanager

# set to 'True' to compare verific with yosys
test_verific = False

@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_expr(variables):
    c = random.choice(['bin', 'uni', 'var', 'const'])
    if c == 'bin':
        op = random.choice(['+', '-', '*', '<', '<=', '==', '!=', '>=', '>', '<<', '>>', '<<<', '>>>', '|', '&', '^', '~^', '||', '&&'])
        return "(%s %s %s)" % (random_expr(variables), op, random_expr(variables))
    if c == 'uni':
        op = random.choice(['+', '-', '~', '|', '&', '^', '~^', '!', '$signed', '$unsigned'])
        return "%s(%s)" % (op, random_expr(variables))
    if c == 'var':
        return random.choice(variables)
    if c == 'const':
        bits = random.randint(1, 32)
        return "%d'd%s" % (bits, random.randint(0, 2**bits-1))
    raise AssertionError

for idx in range(50):
    with file('temp/uut_%05d.v' % idx, 'w') as f, redirect_stdout(f):
        rst2 = random.choice([False, True])
        if rst2:
            print('module uut_%05d(clk, rst1, rst2, rst, a, b, c, x, y, z);' % (idx))
            print('  input clk, rst1, rst2;')
            print('  output rst;')
            print('  assign rst = rst1 || rst2;')
        else:
            print('module uut_%05d(clk, rst, a, b, c, x, y, z);' % (idx))
            print('  input clk, rst;')
        variables=['a', 'b', 'c', 'x', 'y', 'z']
        print('  input%s [%d:0] a;' % (random.choice(['', ' signed']), random.randint(0, 31)))
        print('  input%s [%d:0] b;' % (random.choice(['', ' signed']), random.randint(0, 31)))
        print('  input%s [%d:0] c;' % (random.choice(['', ' signed']), random.randint(0, 31)))
        print('  output reg%s [%d:0] x;' % (random.choice(['', ' signed']), random.randint(0, 31)))
        print('  output reg%s [%d:0] y;' % (random.choice(['', ' signed']), random.randint(0, 31)))
        print('  output reg%s [%d:0] z;' % (random.choice(['', ' signed']), random.randint(0, 31)))
        state_bits = random.randint(5, 16);
        print('  %sreg [%d:0] state;' % (random.choice(['', '(* fsm_encoding = "one-hot" *)',
                '(* fsm_encoding = "binary" *)']), state_bits-1))
        states=[]
        for i in range(random.randint(2, 10)):
            n = random.randint(0, 2**state_bits-1)
            if n not in states:
                states.append(n)
        print('  always @(posedge clk) begin')
        print('    if (%s) begin' % ('rst1' if rst2 else 'rst'))
        print('      x <= %d;' % random.randint(0, 2**31-1))
        print('      y <= %d;' % random.randint(0, 2**31-1))
        print('      z <= %d;' % random.randint(0, 2**31-1))
        print('      state <= %d;' % random.choice(states))
        print('    end else begin')
        print('      case (state)')
        for state in states:
            print('        %d: begin' % state)
            for var in ('x', 'y', 'z'):
                print('            %s <= %s;' % (var, random_expr(variables)))
            next_states = states[:]
            for i in range(random.randint(0, len(states))):
                next_state = random.choice(next_states)
                next_states.remove(next_state)
                print('            if ((%s) %s (%s)) state <= %s;' % (random_expr(variables),
                        random.choice(['<', '<=', '>=', '>']), random_expr(variables), next_state))
            print('          end')
        print('      endcase')
        if rst2:
            print('      if (rst2) begin')
            print('        x <= a;')
            print('        y <= b;')
            print('        z <= c;')
            print('        state <= %d;' % random.choice(states))
            print('      end')
        print('    end')
        print('  end')
        print('endmodule')
    with file('temp/uut_%05d.ys' % idx, 'w') as f, redirect_stdout(f):
        if test_verific:
            print('read_verilog temp/uut_%05d.v' % idx)
            print('proc;; rename uut_%05d gold' % idx)
            print('verific -vlog2k temp/uut_%05d.v' % idx)
            print('verific -import uut_%05d' % idx)
            print('rename uut_%05d gate' % idx)
        else:
            print('read_verilog temp/uut_%05d.v' % idx)
            print('proc;;')
            print('copy uut_%05d gold' % idx)
            print('rename uut_%05d gate' % idx)
            print('cd gate')
            print('opt; wreduce; share%s; opt; fsm;;' % random.choice(['', ' -aggressive']))
            print('cd ..')
        print('miter -equiv -flatten -ignore_gold_x -make_outputs -make_outcmp gold gate miter')
        print('sat -verify-no-timeout -timeout 20 -seq 5 -set-at 1 %s_rst 1 -prove trigger 0 -prove-skip 1 -show-inputs -show-outputs miter' % ('gold' if rst2 else 'in'))