File: t_gate_tree.py

package info (click to toggle)
verilator 5.038-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 162,552 kB
  • sloc: cpp: 139,204; python: 20,931; ansic: 10,222; yacc: 6,000; lex: 1,925; makefile: 1,260; sh: 494; perl: 282; fortran: 22
file content (121 lines) | stat: -rwxr-xr-x 4,578 bytes parent folder | download | duplicates (2)
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
110
111
112
113
114
115
116
117
118
119
120
121
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2024 by Wilson Snyder. This program is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0

import vltest_bootstrap
import collections
import math

test.scenarios('simulator')
test.top_filename = test.obj_dir + "/t_gate_tree.v"
test.cycles = (1000000 if test.benchmark else 100)
test.sim_time = test.cycles * 10 + 1000

width = 64 * int(test.getenv_def("VERILATOR_TEST_WIDTH", "4"))
nvars = 64


def gen(filename):
    with open(filename, 'w', encoding="utf8") as fh:
        fh.write("// Generated by t_gate_tree.py\n")
        fh.write("module t (clk);\n")
        fh.write("  input clk;\n")
        fh.write("\n")
        fh.write("  integer cyc=0;\n")
        fh.write("  reg reset;\n")
        fh.write("\n")

        tree = collections.defaultdict(dict)
        fanin = 8
        stages = int(math.log(nvars) / math.log(fanin) + 0.99999) + 1
        result = 0
        for n in range(0, nvars):
            result += max(n, 1)
            if 0 not in tree:
                tree[0] = {}
            if n not in tree[0]:
                tree[0][n] = {}
            tree[0][n][n] = True
            nl = n
            for stage in range(1, stages):
                lastn = nl
                nl = int(nl / fanin)
                if stage not in tree:
                    tree[stage] = {}
                if nl not in tree[stage]:
                    tree[stage][nl] = {}
                tree[stage][nl][lastn] = True

        # pprint(tree)

        fh.write("\n")
        workingset = 0
        for stage in sorted(tree.keys()):
            for n in sorted(tree[stage].keys()):
                fh.write("   reg [" + str(width - 1) + ":0] v" + str(stage) + "_" + str(n) + ";\n")
                workingset += int(width / 8 + 7)

        fh.write("\n")
        fh.write("   always @ (posedge clk) begin\n")
        fh.write("      cyc <= cyc + 1;\n")
        fh.write("`ifdef TEST_VERBOSE\n")
        fh.write("         $write(\"[%0t] rst=%0x  v0_0=%0x  v1_0=%0x  result=%0x\\n\""
                 ", $time, reset, v0_0, v1_0, v" + str(stages - 1) + "_0);\n")
        fh.write("`endif\n")
        fh.write("      if (cyc==0) begin\n")
        fh.write("         reset <= 1;\n")
        fh.write("      end\n")
        fh.write("      else if (cyc==10) begin\n")
        fh.write("         reset <= 0;\n")
        fh.write("      end\n")
        fh.write("`ifndef SIM_CYCLES\n")
        fh.write(" `define SIM_CYCLES 99\n")
        fh.write("`endif\n")
        fh.write("      else if (cyc==`SIM_CYCLES) begin\n")
        fh.write("         if (v" + str(stages - 1) + "_0 != " + str(width) + "'d" + str(result) +
                 ") $stop;\n")
        fh.write("         $write(\"VARS=" + str(nvars) + " WIDTH=" + str(width) + " WORKINGSET=" +
                 str(int(workingset / 1024)) + "KB\\n\");\n")
        fh.write('         $write("*-* All Finished *-*\\n");' + "\n")
        fh.write('         $finish;' + "\n")
        fh.write("      end\n")
        fh.write("   end\n")

        fh.write("\n")
        for n in range(0, nvars):
            fh.write("   always @ (posedge clk)" + " v0_" + str(n) + " <= reset ? " + str(width) +
                     "'d" + str(max(n, 1)) + " : v0_" + str((int(n / fanin) * fanin) +
                                                            ((n + 1) % fanin)) + ";\n")

        for stage in sorted(tree.keys()):
            if stage == 0:
                continue
            fh.write("\n")
            for n in sorted(tree[stage].keys()):
                fh.write("   always @ (posedge clk) v" + str(stage) + "_" + str(n) + " <=")
                op = ""
                for ni in sorted(tree[stage][n].keys()):
                    fh.write(op + " v" + str(stage - 1) + "_" + str(ni))
                    op = " +"
                fh.write(";\n")

        fh.write("endmodule\n")


gen(test.top_filename)

test.compile(v_flags2=["+define+SIM_CYCLES=" + str(test.cycles)],
             verilator_flags2=["--stats --x-assign fast --x-initial fast", "-Wno-UNOPTTHREADS"])

test.execute(all_run_flags=[
    "+verilator+prof+exec+start+100",
    " +verilator+prof+exec+window+2",
    " +verilator+prof+exec+file+" + test.obj_dir + "/profile_exec.dat",
    " +verilator+prof+vlt+file+" + test.obj_dir + "/profile.vlt"])   # yapf:disable

test.passes()