mirror of
https://github.com/verilator/verilator.git
synced 2025-01-19 12:54:02 +00:00
122 lines
4.5 KiB
Python
Executable File
122 lines
4.5 KiB
Python
Executable File
#!/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()
|