From ae33a1ceb12c9e22e905c1f2ebc940914ff357bb Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Thu, 21 Jun 2018 20:27:33 -0400 Subject: [PATCH] Tests: Add t_gate_tree test --- test_regress/t/t_gate_tree.pl | 123 ++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100755 test_regress/t/t_gate_tree.pl diff --git a/test_regress/t/t_gate_tree.pl b/test_regress/t/t_gate_tree.pl new file mode 100755 index 000000000..6abeb224b --- /dev/null +++ b/test_regress/t/t_gate_tree.pl @@ -0,0 +1,123 @@ +#!/usr/bin/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. +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"], + ); + +execute( + check_finished => 1, + ); + +ok(1); +1;