verilator/test_regress/t/t_gate_tree.pl
Geza Lore b1b5b5dfe2 Improve run-time profiling
The --prof-threads option has been split into two independent options:
1. --prof-exec, for collecting verilator_gantt and other execution
related profiling data, and
2. --prof-pgo, for collecting data needed for PGO

The implementation of execution profiling is extricated from
VlThreadPool and is now a separate class VlExecutionProfiler. This means
--prof-exec can now be used for single-threaded models (though it does
not measure a lot of things just yet). For consistency VerilatedProfiler
is renamed VlPgoProfiler. Both VlExecutionProfiler and VlPgoProfiler are
in verilated_profiler.{h/cpp}, but can be used completely independently.

Also re-worked the execution profile format so it now only emits events
without holding onto any temporaries. This is in preparation for some
future optimizations that would be hindered by the introduction of function
locals via AstText.

Also removed the Barrier event. Clearing the profile buffers is not
notably more expensive as the profiling records are trivially
destructible.
2022-03-27 15:57:30 +02:00

131 lines
4.3 KiB
Perl
Executable File

#!/usr/bin/env perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 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
use IO::File;
#use Data::Dumper;
use strict;
use vars qw($Self);
scenarios(simulator => 1);
my $width = 64 * ($ENV{VERILATOR_TEST_WIDTH} || 4);
my $vars = 64;
$Self->{cycles} = ($Self->{benchmark} ? 1_000_000 : 100);
$Self->{sim_time} = $Self->{cycles} * 10 + 1000;
sub gen {
my $filename = shift;
my $fh = IO::File->new(">$filename");
$fh->print("// Generated by t_gate_tree.pl\n");
$fh->print("module t (clk);\n");
$fh->print(" input clk;\n");
$fh->print("\n");
$fh->print(" integer cyc=0;\n");
$fh->print(" reg reset;\n");
$fh->print("\n");
my %tree;
my $fanin = 8;
my $stages = int(log($vars) / log($fanin) + 0.99999) + 1;
my $result = 0;
for (my $n = 0; $n < $vars; $n++) {
$result += ($n || 1);
$tree{0}{$n}{$n} = 1;
my $nl = $n;
for (my $stage=1; $stage < $stages; $stage++) {
my $lastn = $nl;
$nl = int($nl / $fanin);
$tree{$stage}{$nl}{$lastn} = 1;
}
}
#print Dumper(\%tree);
$fh->print("\n");
my $workingset = 0;
foreach my $stage (sort { $a <=> $b} keys %tree) {
foreach my $n (sort { $a <=> $b} keys %{$tree{$stage}}) {
$fh->print( " reg [" . ($width - 1) . ":0] v${stage}_${n};\n");
$workingset += int($width/8 + 7);
}
}
$fh->print("\n");
$fh->print(" always @ (posedge clk) begin\n");
$fh->print(" cyc <= cyc + 1;\n");
$fh->print("`ifdef TEST_VERBOSE\n");
$fh->print(" \$write(\"[%0t] rst=%0x v0_0=%0x v1_0=%0x result=%0x\\n\""
.", \$time, reset, v0_0, v1_0, v" . ($stages - 1) . "_0);\n");
$fh->print("`endif\n");
$fh->print(" if (cyc==0) begin\n");
$fh->print(" reset <= 1;\n");
$fh->print(" end\n");
$fh->print(" else if (cyc==10) begin\n");
$fh->print(" reset <= 0;\n");
$fh->print(" end\n");
$fh->print("`ifndef SIM_CYCLES\n");
$fh->print(" `define SIM_CYCLES 99\n");
$fh->print("`endif\n");
$fh->print(" else if (cyc==`SIM_CYCLES) begin\n");
$fh->print(" if (v" . ($stages - 1) . "_0 != ${width}'d${result}) \$stop;\n");
$fh->print(" \$write(\"VARS=${vars} WIDTH=${width}"
." WORKINGSET=" . (int($workingset / 1024)) . "KB\\n\");\n");
$fh->print(' $write("*-* All Finished *-*\n");', "\n");
$fh->print(' $finish;', "\n");
$fh->print(" end\n");
$fh->print(" end\n");
$fh->print("\n");
for (my $n=0; $n<$vars; $n++) {
$fh->print(" always @ (posedge clk)"
. " v0_${n} <= reset ? ${width}'d" . (${n} || 1) . " : v0_"
. ((int($n / $fanin) * $fanin) + (($n + 1) % $fanin)) . ";\n");
}
foreach my $stage (sort {$a<=>$b} keys %tree) {
next if $stage == 0;
$fh->print("\n");
foreach my $n (sort {$a<=>$b} keys %{$tree{$stage}}) {
$fh->print(" always @ (posedge clk)"
. " v${stage}_${n} <=");
my $op = "";
foreach my $ni (sort {$a<=>$b} keys %{$tree{$stage}{$n}}) {
$fh->print($op . " v" . (${stage} - 1) . "_${ni}");
$op = " +";
}
$fh->print(";\n");
}
}
$fh->print("endmodule\n");
}
top_filename("$Self->{obj_dir}/t_gate_tree.v");
gen($Self->{top_filename});
compile(
v_flags2 => ["+define+SIM_CYCLES=$Self->{cycles}",],
verilator_flags2=>["--stats --x-assign fast --x-initial fast",
"-Wno-UNOPTTHREADS"],
);
execute(
all_run_flags => ["+verilator+prof+exec+start+100",
" +verilator+prof+exec+window+2",
" +verilator+prof+exec+file+$Self->{obj_dir}/profile_exec.dat",
" +verilator+prof+vlt+file+$Self->{obj_dir}/profile.vlt",
],
check_finished => 1,
);
ok(1);
1;