This commit is contained in:
Wilson Snyder 2016-09-30 18:14:42 -04:00
parent 1e4c3751e1
commit bd28945374
1 changed files with 135 additions and 135 deletions

View File

@ -19,8 +19,8 @@ require 5.006_001;
use warnings; use warnings;
BEGIN { BEGIN {
if ($ENV{DIRPROJECT} && $ENV{DIRPROJECT_PERL_BOOT}) { if ($ENV{DIRPROJECT} && $ENV{DIRPROJECT_PERL_BOOT}) {
# Magic to allow author testing of perl packages in local directory # Magic to allow author testing of perl packages in local directory
require $ENV{DIRPROJECT}."/".$ENV{DIRPROJECT_PERL_BOOT}; require $ENV{DIRPROJECT}."/".$ENV{DIRPROJECT_PERL_BOOT};
} }
} }
@ -71,16 +71,16 @@ foreach my $sw (@ARGV) {
Getopt::Long::config ("no_auto_abbrev","pass_through"); Getopt::Long::config ("no_auto_abbrev","pass_through");
if (! GetOptions ( if (! GetOptions (
# Major operating modes # Major operating modes
"help" => \&usage, "help" => \&usage,
"debug:s" => \&debug, "debug:s" => \&debug,
# "version!" => \&version, # Also passthru'ed # "version!" => \&version, # Also passthru'ed
# Switches # Switches
"gdb!" => \$opt_gdb, "gdb!" => \$opt_gdb,
"gdbbt!" => \$opt_gdbbt, "gdbbt!" => \$opt_gdbbt,
# Additional parameters # Additional parameters
"<>" => sub {}, # Ignored "<>" => sub {}, # Ignored
)) { )) {
pod2usage(-exitstatus=>2, -verbose=>0); pod2usage(-exitstatus=>2, -verbose=>0);
} }
@ -92,22 +92,22 @@ if ($opt_gdbbt && !gdb_works()) {
if ($opt_gdb) { if ($opt_gdb) {
# Generic GDB interactive # Generic GDB interactive
run (("gdb"||$ENV{VERILATOR_GDB}) run (("gdb"||$ENV{VERILATOR_GDB})
." ".verilator_bin() ." ".verilator_bin()
." -ex 'run ".join(' ',@Opt_Verilator_Sw)."'" ." -ex 'run ".join(' ',@Opt_Verilator_Sw)."'"
." -ex 'set width 0'" ." -ex 'set width 0'"
." -ex 'bt'"); ." -ex 'bt'");
} elsif ($opt_gdbbt && $Debug) { } elsif ($opt_gdbbt && $Debug) {
# Run under GDB to get gdbbt # Run under GDB to get gdbbt
run ("gdb" run ("gdb"
." ".verilator_bin() ." ".verilator_bin()
." --batch --quiet --return-child-result" ." --batch --quiet --return-child-result"
." -ex 'run ".join(' ',@Opt_Verilator_Sw)."'" ." -ex 'run ".join(' ',@Opt_Verilator_Sw)."'"
." -ex 'set width 0'" ." -ex 'set width 0'"
." -ex 'bt'"); ." -ex 'bt'");
} else { } else {
# Normal, non gdb # Normal, non gdb
run (verilator_bin() run (verilator_bin()
." ".join(' ',@Opt_Verilator_Sw)); ." ".join(' ',@Opt_Verilator_Sw));
} }
#---------------------------------------------------------------------- #----------------------------------------------------------------------
@ -130,23 +130,23 @@ sub verilator_bin {
my $bin = ""; my $bin = "";
# Use VERILATOR_ROOT if defined, else assume verilator_bin is in the search path # Use VERILATOR_ROOT if defined, else assume verilator_bin is in the search path
my $basename = ($ENV{VERILATOR_BIN} my $basename = ($ENV{VERILATOR_BIN}
|| ($Debug ? "verilator_bin_dbg" : "verilator_bin")); || ($Debug ? "verilator_bin_dbg" : "verilator_bin"));
if (defined($ENV{VERILATOR_ROOT})) { if (defined($ENV{VERILATOR_ROOT})) {
my $dir = $ENV{VERILATOR_ROOT}; my $dir = $ENV{VERILATOR_ROOT};
if (-x "$dir/bin/$basename") { # From a "make install" into VERILATOR_ROOT if (-x "$dir/bin/$basename") { # From a "make install" into VERILATOR_ROOT
$bin = "$dir/bin/$basename"; $bin = "$dir/bin/$basename";
} else { } else {
$bin = "$dir/$basename"; # From pointing to kit directory $bin = "$dir/$basename"; # From pointing to kit directory
} }
} else { } else {
if (-x "$RealBin/$basename") { if (-x "$RealBin/$basename") {
$bin = "$RealBin/$basename"; # From path/to/verilator with verilator_bin installed $bin = "$RealBin/$basename"; # From path/to/verilator with verilator_bin installed
} else { } else {
$bin = $basename; # Find in PATH $bin = $basename; # Find in PATH
} }
# Note we don't look under bin/$basename which would be right if running # Note we don't look under bin/$basename which would be right if running
# in the kit dir. Running that would likely break, since # in the kit dir. Running that would likely break, since
# VERILATOR_ROOT wouldn't be set and Verilator won't find internal files. # VERILATOR_ROOT wouldn't be set and Verilator won't find internal files.
} }
return $bin; return $bin;
} }
@ -158,10 +158,10 @@ sub verilator_bin {
sub gdb_works { sub gdb_works {
$! = undef; # Cleanup -x $! = undef; # Cleanup -x
system("gdb /bin/echo" system("gdb /bin/echo"
." --batch-silent --quiet --return-child-result" ." --batch-silent --quiet --return-child-result"
." -ex 'run -n'" # `echo -n` ." -ex 'run -n'" # `echo -n`
." -ex 'set width 0'" ." -ex 'set width 0'"
." -ex 'bt'"); ." -ex 'bt'");
my $status = $?; my $status = $?;
return $status==0; return $status==0;
} }
@ -174,23 +174,23 @@ sub run {
system($command); system($command);
my $status = $?; my $status = $?;
if ($status) { if ($status) {
if ($! =~ /no such file or directory/i) { if ($! =~ /no such file or directory/i) {
warn "%Error: verilator: Misinstalled, or VERILATOR_ROOT might need to be in environment\n"; warn "%Error: verilator: Misinstalled, or VERILATOR_ROOT might need to be in environment\n";
} }
if ($Debug) { # For easy rerunning if ($Debug) { # For easy rerunning
warn "%Error: export VERILATOR_ROOT=".($ENV{VERILATOR_ROOT}||"")."\n"; warn "%Error: export VERILATOR_ROOT=".($ENV{VERILATOR_ROOT}||"")."\n";
warn "%Error: $command\n"; warn "%Error: $command\n";
} }
if ($status & 127) { if ($status & 127) {
if (($status & 127) == 8 || ($status & 127) == 11) { # SIGFPA or SIGSEGV if (($status & 127) == 8 || ($status & 127) == 11) { # SIGFPA or SIGSEGV
warn "%Error: Verilator internal fault, sorry. Consider trying --debug --gdbbt\n" if !$Debug; warn "%Error: Verilator internal fault, sorry. Consider trying --debug --gdbbt\n" if !$Debug;
} elsif (($status & 127) == 6) { # SIGABRT } elsif (($status & 127) == 6) { # SIGABRT
warn "%Error: Verilator aborted. Consider trying --debug --gdbbt\n" if !$Debug; warn "%Error: Verilator aborted. Consider trying --debug --gdbbt\n" if !$Debug;
} else { } else {
warn "%Error: Verilator threw signal $status. Consider trying --debug --gdbbt\n" if !$Debug; warn "%Error: Verilator threw signal $status. Consider trying --debug --gdbbt\n" if !$Debug;
} }
} }
die "%Error: Command Failed $command\n"; die "%Error: Command Failed $command\n";
} }
} }
@ -324,7 +324,7 @@ descriptions in the next sections for more information.
--public Debugging; see docs --public Debugging; see docs
-pvalue+<name>=<value> Overwrite toplevel parameter -pvalue+<name>=<value> Overwrite toplevel parameter
--report-unoptflat Extra diagnostics for UNOPTFLAT --report-unoptflat Extra diagnostics for UNOPTFLAT
--savable Enable model save-restore --savable Enable model save-restore
--sc Create SystemC output --sc Create SystemC output
--stats Create statistics file --stats Create statistics file
--stats-vars Provide statistics on variables --stats-vars Provide statistics on variables
@ -1336,7 +1336,7 @@ We'll compile this example into C++.
#include "Vour.h" #include "Vour.h"
#include "verilated.h" #include "verilated.h"
int main(int argc, char **argv, char **env) { int main(int argc, char **argv, char **env) {
Verilated::commandArgs(argc, argv); Verilated::commandArgs(argc, argv);
Vour* top = new Vour; Vour* top = new Vour;
while (!Verilated::gotFinish()) { top->eval(); } while (!Verilated::gotFinish()) { top->eval(); }
delete top; delete top;
@ -1400,7 +1400,7 @@ This is an example similar to the above, but using SystemC.
cat <<EOF >sc_main.cpp cat <<EOF >sc_main.cpp
#include "Vour.h" #include "Vour.h"
int sc_main(int argc, char **argv) { int sc_main(int argc, char **argv) {
Verilated::commandArgs(argc, argv); Verilated::commandArgs(argc, argv);
sc_clock clk ("clk",10, 0.5, 3, true); sc_clock clk ("clk",10, 0.5, 3, true);
Vour* top; Vour* top;
top = new Vour("top"); // SP_CELL (top, Vour); top = new Vour("top"); // SP_CELL (top, Vour);
@ -1529,42 +1529,42 @@ All output files are placed in the output directory name specified with the
Verilator creates the following files in the output directory: Verilator creates the following files in the output directory:
{prefix}.mk // Make include file for compiling {prefix}.mk // Make include file for compiling
{prefix}_classes.mk // Make include file with class names {prefix}_classes.mk // Make include file with class names
For -cc and -sc mode, it also creates: For -cc and -sc mode, it also creates:
{prefix}.cpp // Top level C++ file {prefix}.cpp // Top level C++ file
{prefix}.h // Top level header {prefix}.h // Top level header
{prefix}{each_verilog_module}.cpp // Lower level internal C++ files {prefix}{each_verilog_module}.cpp // Lower level internal C++ files
{prefix}{each_verilog_module}.h // Lower level internal header files {prefix}{each_verilog_module}.h // Lower level internal header files
In certain optimization modes, it also creates: In certain optimization modes, it also creates:
{prefix}__Dpi.h // DPI import and export declarations {prefix}__Dpi.h // DPI import and export declarations
{prefix}__Inlines.h // Inline support functions {prefix}__Inlines.h // Inline support functions
{prefix}__Slow.cpp // Constructors and infrequent routines {prefix}__Slow.cpp // Constructors and infrequent routines
{prefix}__Syms.cpp // Global symbol table C++ {prefix}__Syms.cpp // Global symbol table C++
{prefix}__Syms.h // Global symbol table header {prefix}__Syms.h // Global symbol table header
{prefix}__Trace.cpp // Wave file generation code (--trace) {prefix}__Trace.cpp // Wave file generation code (--trace)
{prefix}__cdc.txt // Clock Domain Crossing checks (--cdc) {prefix}__cdc.txt // Clock Domain Crossing checks (--cdc)
{prefix}__stats.txt // Statistics (--stats) {prefix}__stats.txt // Statistics (--stats)
It also creates internal files that can be mostly ignored: It also creates internal files that can be mostly ignored:
{each_verilog_module}.vpp // Post-processed verilog (--debug) {each_verilog_module}.vpp // Post-processed verilog (--debug)
{prefix}.flags_vbin // Verilator dependencies {prefix}.flags_vbin // Verilator dependencies
{prefix}.flags_vpp // Pre-processor dependencies {prefix}.flags_vpp // Pre-processor dependencies
{prefix}__verFiles.dat // Timestamps for skip-identical {prefix}__verFiles.dat // Timestamps for skip-identical
{prefix}{misc}.d // Make dependencies (-MMD) {prefix}{misc}.d // Make dependencies (-MMD)
{prefix}{misc}.dot // Debugging graph files (--debug) {prefix}{misc}.dot // Debugging graph files (--debug)
{prefix}{misc}.tree // Debugging files (--debug) {prefix}{misc}.tree // Debugging files (--debug)
After running Make, the C++ compiler should produce the following: After running Make, the C++ compiler should produce the following:
{prefix} // Final executable (w/--exe argument) {prefix} // Final executable (w/--exe argument)
{prefix}__ALL.a // Library of all Verilated objects {prefix}__ALL.a // Library of all Verilated objects
{prefix}{misc}.o // Intermediate objects {prefix}{misc}.o // Intermediate objects
=head1 ENVIRONMENT =head1 ENVIRONMENT
@ -1659,46 +1659,46 @@ simulation executable.
The user must write the top level of the simulation. Here's a simple The user must write the top level of the simulation. Here's a simple
example: example:
#include <verilated.h> // Defines common routines #include <verilated.h> // Defines common routines
#include "Vtop.h" // From Verilating "top.v" #include "Vtop.h" // From Verilating "top.v"
Vtop *top; // Instantiation of module Vtop *top; // Instantiation of module
vluint64_t main_time = 0; // Current simulation time vluint64_t main_time = 0; // Current simulation time
// This is a 64-bit integer to reduce wrap over issues and // This is a 64-bit integer to reduce wrap over issues and
// allow modulus. You can also use a double, if you wish. // allow modulus. You can also use a double, if you wish.
double sc_time_stamp () { // Called by $time in Verilog double sc_time_stamp () { // Called by $time in Verilog
return main_time; // converts to double, to match return main_time; // converts to double, to match
// what SystemC does // what SystemC does
} }
int main(int argc, char** argv) { int main(int argc, char** argv) {
Verilated::commandArgs(argc, argv); // Remember args Verilated::commandArgs(argc, argv); // Remember args
top = new Vtop; // Create instance top = new Vtop; // Create instance
top->reset_l = 0; // Set some inputs top->reset_l = 0; // Set some inputs
while (!Verilated::gotFinish()) { while (!Verilated::gotFinish()) {
if (main_time > 10) { if (main_time > 10) {
top->reset_l = 1; // Deassert reset top->reset_l = 1; // Deassert reset
} }
if ((main_time % 10) == 1) { if ((main_time % 10) == 1) {
top->clk = 1; // Toggle clock top->clk = 1; // Toggle clock
} }
if ((main_time % 10) == 6) { if ((main_time % 10) == 6) {
top->clk = 0; top->clk = 0;
} }
top->eval(); // Evaluate model top->eval(); // Evaluate model
cout << top->out << endl; // Read a output cout << top->out << endl; // Read a output
main_time++; // Time passes... main_time++; // Time passes...
} }
top->final(); // Done simulating top->final(); // Done simulating
// // (Though this example doesn't get here) // // (Though this example doesn't get here)
delete top; delete top;
} }
Note signals are read and written as member variables of the lower module. Note signals are read and written as member variables of the lower module.
You call the eval() method to evaluate the model. When the simulation is You call the eval() method to evaluate the model. When the simulation is
@ -1928,8 +1928,8 @@ VerilatedVpi::callValueCbs().
... ...
while (time passes) { while (time passes) {
... ...
topp->eval(); topp->eval();
VerilatedVpi::callValueCbs(); VerilatedVpi::callValueCbs();
} }
@ -1973,10 +1973,10 @@ underneath NC:
cd obj_dir cd obj_dir
ncsc_run \ ncsc_run \
sc_main.cpp \ sc_main.cpp \
Vour__ALLcls.cpp \ Vour__ALLcls.cpp \
Vour__ALLsup.cpp \ Vour__ALLsup.cpp \
verilated.cpp verilated.cpp
For larger designs you'll want to automate this using makefiles, which pull For larger designs you'll want to automate this using makefiles, which pull
the names of the .cpp files to compile in from the make variables generated the names of the .cpp files to compile in from the make variables generated
@ -2493,7 +2493,7 @@ such as $stop, $finish and $display. That is, you cannot use hierarchical
references, events or similar features of the Verilog language. It also references, events or similar features of the Verilog language. It also
simulates as Synopsys's Design Compiler would; namely a block of the form: simulates as Synopsys's Design Compiler would; namely a block of the form:
always @ (x) y = x & z; always @ (x) y = x & z;
This will recompute y when there is even a potential for change in x or a This will recompute y when there is even a potential for change in x or a
change in z, that is when the flops computing x or z evaluate (which is change in z, that is when the flops computing x or z evaluate (which is
@ -2837,9 +2837,9 @@ Warnings may be disabled in three ways. First, when the warning is
printed it will include a warning code. Simply surround the offending printed it will include a warning code. Simply surround the offending
line with a warn_off/warn_on pair: line with a warn_off/warn_on pair:
// verilator lint_off UNSIGNED // verilator lint_off UNSIGNED
if (`DEF_THAT_IS_EQ_ZERO <= 3) $stop; if (`DEF_THAT_IS_EQ_ZERO <= 3) $stop;
// verilator lint_on UNSIGNED // verilator lint_on UNSIGNED
Second, warnings may be disabled using a configuration file with a lint_off Second, warnings may be disabled using a configuration file with a lint_off
command. This is useful when a script is suppressing warnings and the command. This is useful when a script is suppressing warnings and the
@ -2937,10 +2937,10 @@ were used, the simulator would have to copy large arrays every cycle. (In
smaller loops, loop unrolling allows the delayed assignment to work, though smaller loops, loop unrolling allows the delayed assignment to work, though
it's a bit slower than a non-delayed assignment.) Here's an example it's a bit slower than a non-delayed assignment.) Here's an example
always @ (posedge clk) always @ (posedge clk)
if (~reset_l) begin if (~reset_l) begin
for (i=0; i<`ARRAY_SIZE; i++) begin for (i=0; i<`ARRAY_SIZE; i++) begin
array[i] = 0; // Non-delayed for verilator array[i] = 0; // Non-delayed for verilator
end end
This message is only seen on large or complicated loops because Verilator This message is only seen on large or complicated loops because Verilator
@ -3398,9 +3398,9 @@ A recommended style for unused nets is to put at the bottom of a file code
similar to the following: similar to the following:
wire _unused_ok = &{1'b0, wire _unused_ok = &{1'b0,
sig_not_used_a, sig_not_used_a,
sig_not_used_yet_b, // To be fixed sig_not_used_yet_b, // To be fixed
1'b0}; 1'b0};
The reduction AND and constant zeros mean the net will always be zero, so The reduction AND and constant zeros mean the net will always be zero, so
won't use simulation time. The redundant leading and trailing zeros avoid won't use simulation time. The redundant leading and trailing zeros avoid
@ -3437,11 +3437,11 @@ unwidthed. Verilator considers zero to be any width needed.
Concatenate leading zeros when doing arithmetic. In the statement Concatenate leading zeros when doing arithmetic. In the statement
wire [5:0] plus_one = from[5:0] + 6'd1 + carry[0]; wire [5:0] plus_one = from[5:0] + 6'd1 + carry[0];
The best fix, which clarifies intent and will also make all tools happy is: The best fix, which clarifies intent and will also make all tools happy is:
wire [5:0] plus_one = from[5:0] + 6'd1 + {5'd0,carry[0]}; wire [5:0] plus_one = from[5:0] + 6'd1 + {5'd0,carry[0]};
Ignoring this warning will only suppress the lint check, it will simulate Ignoring this warning will only suppress the lint check, it will simulate
correctly. correctly.
@ -3639,7 +3639,7 @@ trace file if you want all data to land in the same output file.
tfp->open ("obj_dir/t_trace_ena_cc/simx.vcd"); tfp->open ("obj_dir/t_trace_ena_cc/simx.vcd");
... ...
sc_start(1); sc_start(1);
... ...
tfp->close(); tfp->close();
} }