├── module ├── lib │ └── .placeholder ├── MANIFEST ├── Changes ├── t │ └── SystemVerilogTools.t ├── Makefile.PL ├── README ├── scripts │ └── update.pl └── in │ └── SystemVerilogTools.pm ├── .gitignore ├── README └── scripts ├── sv_tb.pl ├── sv_ucf.pl ├── sv_inst.pl ├── sv_mod_low.pl ├── sv_mod_top.pl └── svtools.pl /module/lib/.placeholder: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jwwebbopen/SystemVerilogTools/HEAD/.gitignore -------------------------------------------------------------------------------- /module/MANIFEST: -------------------------------------------------------------------------------- 1 | Changes 2 | Makefile.PL 3 | MANIFEST 4 | README 5 | t/SystemVerilogTools.t 6 | in/SystemVerilogTools.pm 7 | scripts/update.pl 8 | -------------------------------------------------------------------------------- /module/Changes: -------------------------------------------------------------------------------- 1 | Revision history for Perl extension SystemVerilogTools. 2 | 3 | 0.01 Sun Jul 21 14:03:03 2012 4 | - original version; created by h2xs 1.23 with options 5 | -AXc -n SystemVerilogTools 6 | 7 | -------------------------------------------------------------------------------- /module/t/SystemVerilogTools.t: -------------------------------------------------------------------------------- 1 | # Before `make install' is performed this script should be runnable with 2 | # `make test'. After `make install' it should work as `perl SystemVerilogTools.t' 3 | 4 | ######################### 5 | 6 | # change 'tests => 1' to 'tests => last_test_to_print'; 7 | 8 | use Test::More tests => 1; 9 | BEGIN { use_ok('SystemVerilogTools') }; 10 | 11 | ######################### 12 | 13 | # Insert your test code below, the Test::More module is use()ed here so read 14 | # its man page ( perldoc Test::More ) for help writing this test script. 15 | 16 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | #****************************************************************** 2 | # 3 | # README module 4 | # 5 | #****************************************************************** 6 | # 7 | # created on: 07/21/2012 8 | # created by: jwwebb 9 | # last edit on: $DateTime: $ 10 | # last edit by: $Author: $ 11 | # revision: $Revision: $ 12 | # comments: Generated 13 | # 14 | #****************************************************************** 15 | # 16 | # Copyright (c) 2012, Jeremy W. Webb 17 | # All rights reserved. 18 | # 19 | # Redistribution and use in source and binary forms, with or without 20 | # modification, are permitted provided that the following conditions 21 | # are met: 22 | # 23 | # 1. Redistributions of source code must retain the above copyright 24 | # notice, this list of conditions and the following disclaimer. 25 | # 2. Redistributions in binary form must reproduce the above copyright 26 | # notice, this list of conditions and the following disclaimer in 27 | # the documentation and/or other materials provided with the 28 | # distribution. 29 | # 30 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 31 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 32 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 33 | # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 34 | # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 35 | # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 36 | # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 37 | # OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 38 | # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 39 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 40 | # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 41 | # DAMAGE. 42 | # 43 | # The views and conclusions contained in the software and documentation 44 | # are those of the authors and should not be interpreted as representing 45 | # official policies, either expressed or implied, of the FreeBSD Project. 46 | # 47 | #****************************************************************** 48 | 49 | Anyone who designs with SystemVerilog has probably grown tired of generating 50 | module instantiations in a hierarchical design, or creating a new top level 51 | or lower level SystemVerilog module. I have generated a few Perl Scripts that 52 | will automatically generate the module instantiations, top level module, and 53 | lower level module for you. These Perl Scripts can be invoked from within 54 | VI/VIM/GVIM, or a DOS Command Window. If you invoke them from within VI, the 55 | script output will be printed in the current file. If you invoke them from 56 | within a DOS, Cygwin, or Bash Command Window, then you will have to either 57 | cut and paste into your SystemVerilog file or pipe the output to a new file. 58 | 59 | The company name in the header of each generated file can be customized during 60 | the installation of the SystemVerilogTools Perl Module. Each Perl script used 61 | to generate SystemVerilog modules will insert the custom company name in the 62 | header of the module. 63 | -------------------------------------------------------------------------------- /module/Makefile.PL: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | #****************************************************************** 4 | # 5 | # Makefile.pl module 6 | # 7 | #****************************************************************** 8 | # 9 | # created on: 07/21/2012 10 | # created by: jwwebb 11 | # last edit on: 07/21/2012 12 | # last edit by: jwwebb 13 | # 14 | #****************************************************************** 15 | # Revision List: 16 | # 17 | # 1.0 07/21/2012 Initial release 18 | # 19 | # Please report bugs, errors, etc. 20 | #****************************************************************** 21 | # Generate Installation Makefile 22 | # 23 | # This utility is intended to generate installation Makefile. 24 | # 25 | #****************************************************************** 26 | # 27 | # Copyright (c) 2012, Jeremy W. Webb 28 | # All rights reserved. 29 | # 30 | # Redistribution and use in source and binary forms, with or without 31 | # modification, are permitted provided that the following conditions 32 | # are met: 33 | # 34 | # 1. Redistributions of source code must retain the above copyright 35 | # notice, this list of conditions and the following disclaimer. 36 | # 2. Redistributions in binary form must reproduce the above copyright 37 | # notice, this list of conditions and the following disclaimer in 38 | # the documentation and/or other materials provided with the 39 | # distribution. 40 | # 41 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 42 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 43 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 44 | # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 45 | # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 46 | # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 47 | # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 48 | # OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 49 | # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 50 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 51 | # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 52 | # DAMAGE. 53 | # 54 | # The views and conclusions contained in the software and documentation 55 | # are those of the authors and should not be interpreted as representing 56 | # official policies, either expressed or implied, of the FreeBSD Project. 57 | # 58 | #****************************************************************** 59 | 60 | #****************************************************************** 61 | # CPAN Modules 62 | #****************************************************************** 63 | #use 5.010000; 64 | use ExtUtils::MakeMaker; 65 | 66 | #****************************************************************** 67 | # Update Company Name in ./in/VerilogTools.pm 68 | #****************************************************************** 69 | system("./scripts/update.pl -C"); 70 | 71 | #****************************************************************** 72 | # Generate Makefile 73 | #****************************************************************** 74 | WriteMakefile( 75 | NAME => 'SystemVerilogTools', 76 | VERSION_FROM => 'lib/SystemVerilogTools.pm', # finds $VERSION 77 | PREREQ_PM => {}, # e.g., Module::Name => 1.1 78 | ($] >= 5.005 ? ## Add these new keywords supported since 5.005 79 | (ABSTRACT_FROM => 'lib/SystemVerilogTools.pm', # retrieve abstract from module 80 | AUTHOR => 'Jeremy Webb ') : ()), 81 | ); 82 | printf("\n"); 83 | 84 | -------------------------------------------------------------------------------- /module/README: -------------------------------------------------------------------------------- 1 | SystemVerilogTools version 0.01 2 | =============================== 3 | 4 | NAME 5 | 6 | SystemVerilogTools - Package to parse and create SystemVerilog files 7 | 8 | VERSION 9 | 10 | Version 1.0 11 | 12 | ABSTRACT 13 | 14 | SystemVerilogTools - Package to parse and create SystemVerilog files 15 | 16 | SYNOPSIS 17 | 18 | use SystemVerilogTools; 19 | 20 | #****************************************************************** 21 | # Initialize SystemVerilog Hash: 22 | #****************************************************************** 23 | my (%svH, $sv_rH); 24 | $svH{ 'username' } = $author; 25 | $svH{ 'file' } = $file; 26 | $svH{ 'day' } = $day; 27 | $svH{ 'month' } = $month; 28 | $svH{ 'year' } = $year; 29 | $svH{ 'debug' } = $debug; 30 | 31 | # Generate Top-Level Module 32 | $sv_rH = genSVTopModule(\%svH); 33 | 34 | # Generate Low-Level Module 35 | $sv_rH = genSVLowModule(\%svH); 36 | 37 | # Generate Module Instantiateion 38 | $sv_rH = printModInst(\%svH); 39 | 40 | # Generate UCF File from Module 41 | $sv_rH = genUCFFile(\%svH); 42 | 43 | # Generate Test Benches 44 | $sv_rH = genTBTestFile(\%svH); 45 | 46 | DESCRIPTION 47 | 48 | The SystemVerilogTools is used to generate or parse SystemVerilog files. 49 | 50 | printModInst: 51 | 52 | The sub-routine printModInst() will print out the SystemVerilog module 53 | instantiation. The SystemVerilog module must use an ANSI-C style module 54 | declaration. An example module instantiation is shown below: 55 | 56 | mymodule _mymodule (.clk (clk), 57 | .data_in (data_in), 58 | .rst_n (rst_n), 59 | 60 | .data_out (data_out)); 61 | 62 | genTBTestFile: 63 | 64 | The sub-routine genTBTestFile() will generate a set of Test Bench 65 | files based on the SystemVerilog module provided by the user. For 66 | example, if the user provides a SystemVerilog module called 'mymodule' 67 | then the following files will be generated: 68 | 69 | - top.sv 70 | - test_mymodule.sv 71 | 72 | The file 'top.sv' instantiates both the UUT (mymodule.sv) and the 73 | Test Bench (test_mymodule.sv). All nets labeled with either 'clk' or 74 | 'clock' will be generated using an always block in the following form: 75 | 76 | // clk generators 77 | initial begin 78 | clk <= 1'b1; 79 | end 80 | 81 | // Generate clock: 82 | always #4 clk <= ~clk; 83 | 84 | All nets in the 'mymodule.sv' file are declared in the 'top.sv' file. 85 | 86 | The file 'test_mymodule.sv' contains the same number of i/o as 87 | 'mymodule.sv' with inputs and outputs swapped, except for clock 88 | signals. 89 | 90 | genUCFFile: 91 | 92 | The sub-routine genUCFFile() will generate a Xilinx User Constraints File (UCF) 93 | based on the SystemVerilog module provided by the user. For 94 | example, if the user provides a SystemVerilog module called 'mymodule' 95 | then the following files will be generated: 96 | 97 | - mymodule.ucf 98 | 99 | The file 'mymodule.ucf' inserts net location and IO Standard declarations 100 | for all I/O in 'mymodule.sv'. The location keyword 'LOC' defaults to empty, 101 | and the 'IOSTANDARD' defaults to 'LVCMOS33'. 102 | 103 | genSVLowModule: 104 | 105 | The sub-routine genSVLowModule() will generate an empty lower-level SystemVerilog 106 | module. A standard header is used containing an empty description and the 107 | new module name. The module contains 3 input signals: clk, rst_n, and data_in[15:0]. 108 | The module also contains 1 output signal: data_out[15:0]. 109 | 110 | genSVTopModule: 111 | 112 | The sub-routine genSVTopModule() will generate an empty top-level SystemVerilog 113 | module. A standard header is used containing an empty description and the 114 | new module name. The module contains 3 input signals: clk, rst_n, and data_in[15:0]. 115 | The module also contains 1 output signal: data_out[15:0]. 116 | 117 | EXPORT 118 | 119 | None at the moment. 120 | 121 | INSTALLATION 122 | 123 | perl Makefile.PL # build the Makefile 124 | make # build the package 125 | make install # Install package 126 | 127 | SEE ALSO 128 | 129 | Example scripts can be accessed at the following website: 130 | 131 | * http://www.jwebb-design.com/ee/howto/using_perl_with_sv.shtml 132 | 133 | AUTHOR 134 | 135 | Jeremy Webb, Ejwwebb@jwebb-design.com 136 | 137 | BUGS 138 | 139 | Please report any bugs or feature requests to the author. 140 | 141 | COPYRIGHT AND LICENSE 142 | 143 | Copyright (C) 2012 by Jeremy Webb 144 | 145 | -------------------------------------------------------------------------------- /scripts/sv_tb.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | #****************************************************************** 4 | # vim:ts=8:sw=8:expandtab:cindent 5 | #****************************************************************** 6 | # 7 | # sv_tb.pl module 8 | # 9 | #****************************************************************** 10 | # 11 | # created on: 07/21/2012 12 | # created by: jwwebb 13 | # last edit on: $DateTime: $ 14 | # last edit by: $Author: $ 15 | # revision: $Revision: $ 16 | # comments: Generated 17 | # 18 | #****************************************************************** 19 | # Revision List: 20 | # 21 | # 1.0 07/21/2012 Initial release 22 | # 23 | #****************************************************************** 24 | # SystemVerilog Tools Module 25 | # 26 | # This utility is intended to make designing with SystemVerilog 27 | # simpler. This utility supports the following options: 28 | # 29 | # Usage: svtools.pl [-h] [-v] [-t] [-f ] 30 | # 31 | # -h Print this help message. 32 | # -v Verbose: Print Debug Information. 33 | # -t Generate SystemVerilog Test Bench. 34 | # -f SystemVerilog input file. 35 | # 36 | # Example of Module Instantiation: 37 | # 38 | # svtools.pl -t -f sample.v 39 | # 40 | # Save this file in your home 'bin' directory. 41 | # 42 | #****************************************************************** 43 | # 44 | # Copyright (c) 2012, Jeremy W. Webb 45 | # All rights reserved. 46 | # 47 | # Redistribution and use in source and binary forms, with or without 48 | # modification, are permitted provided that the following conditions 49 | # are met: 50 | # 51 | # 1. Redistributions of source code must retain the above copyright 52 | # notice, this list of conditions and the following disclaimer. 53 | # 2. Redistributions in binary form must reproduce the above copyright 54 | # notice, this list of conditions and the following disclaimer in 55 | # the documentation and/or other materials provided with the 56 | # distribution. 57 | # 58 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 59 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 60 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 61 | # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 62 | # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 63 | # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 64 | # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 65 | # OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 66 | # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 67 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 68 | # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 69 | # DAMAGE. 70 | # 71 | # The views and conclusions contained in the software and documentation 72 | # are those of the authors and should not be interpreted as representing 73 | # official policies, either expressed or implied, of the FreeBSD Project. 74 | # 75 | #****************************************************************** 76 | 77 | #****************************************************************** 78 | # CPAN Modules 79 | #****************************************************************** 80 | use strict; 81 | use warnings; 82 | use Getopt::Std; 83 | 84 | #****************************************************************** 85 | # Custom Modules 86 | #****************************************************************** 87 | use SystemVerilogTools qw( genTBTestFile ); 88 | 89 | #****************************************************************** 90 | # Constants and Variables: 91 | #****************************************************************** 92 | my (%svH, $sv_rH); 93 | my (%opts)=(); 94 | my ($file); 95 | my ($debug); 96 | 97 | #****************************************************************** 98 | # Retrieve command line argument 99 | #****************************************************************** 100 | getopts('hvtf:',\%opts); 101 | 102 | my $optslen = scalar( keys %opts ); 103 | print("Number of Options on Command-Line: $optslen\n") if $opts{v}; 104 | # check for valid combination of command-line arguments 105 | if ( $opts{h} || !$opts{f} || !($opts{t}) || ($optslen eq "0") ) { 106 | print_usage(); 107 | exit; 108 | } 109 | 110 | # parse command-line arguments 111 | $file = $opts{f}; 112 | $debug = $opts{v}; 113 | 114 | #****************************************************************** 115 | # Make Date int MM/DD/YYYY 116 | #****************************************************************** 117 | my $year = 0; 118 | my $month = 0; 119 | my $day = 0; 120 | ($day, $month, $year) = (localtime)[3,4,5]; 121 | 122 | #****************************************************************** 123 | # Grab username from PC: 124 | #****************************************************************** 125 | my $author= "$^O user"; 126 | if ($^O =~ /mswin/i) { 127 | $author= $ENV{USERNAME} if defined $ENV{USERNAME}; 128 | } else { 129 | $author = getlogin(); 130 | } 131 | 132 | #****************************************************************** 133 | # Initialize Verilog Hash: 134 | #****************************************************************** 135 | $svH{ 'username' } = $author; 136 | $svH{ 'file' } = $file; 137 | $svH{ 'day' } = $day; 138 | $svH{ 'month' } = $month; 139 | $svH{ 'year' } = $year; 140 | $svH{ 'debug' } = $debug; 141 | 142 | #****************************************************************** 143 | # Generate Test Bench File: 144 | #****************************************************************** 145 | if ($opts{t}) { 146 | $sv_rH = genTBTestFile(\%svH); 147 | } 148 | 149 | 150 | exit; 151 | 152 | #****************************************************************** 153 | # Generic Error and Exit routine 154 | #****************************************************************** 155 | 156 | sub dienice { 157 | my($errmsg) = @_; 158 | print"$errmsg\n"; 159 | exit; 160 | } 161 | 162 | sub print_usage { 163 | my ($usage); 164 | $usage = "\nUsage: $0 [-h] [-v] [-t] [-f ]\n"; 165 | $usage .= "\n"; 166 | $usage .= "\t-h\t\tPrint this help message.\n"; 167 | $usage .= "\t-v\t\tVerbose: Print Debug Information.\n"; 168 | $usage .= "\t-t\t\tGenerate SystemVerilog Test Bench.\n"; 169 | $usage .= "\t-f \tSystemVerilog input file.\n"; 170 | $usage .= "\n"; 171 | $usage .= "\tExample of Module Instantiation:\n"; 172 | $usage .= "\t\t$0 -t -f sample.v \n"; 173 | $usage .= "\n"; 174 | print($usage); 175 | return; 176 | } 177 | 178 | -------------------------------------------------------------------------------- /scripts/sv_ucf.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | #****************************************************************** 4 | # vim:ts=8:sw=8:expandtab:cindent 5 | #****************************************************************** 6 | # 7 | # sv_ucf.pl module 8 | # 9 | #****************************************************************** 10 | # 11 | # created on: 07/21/2012 12 | # created by: jwwebb 13 | # last edit on: $DateTime: $ 14 | # last edit by: $Author: $ 15 | # revision: $Revision: $ 16 | # comments: Generated 17 | # 18 | #****************************************************************** 19 | # Revision List: 20 | # 21 | # 1.0 07/21/2012 Initial release 22 | # 23 | #****************************************************************** 24 | # SystemVerilog Tools Module 25 | # 26 | # This utility is intended to make designing with SystemVerilog 27 | # simpler. This utility supports the following options: 28 | # 29 | # Usage: svtools.pl [-h] [-v] [-u] [-f ] 30 | # 31 | # -h Print this help message. 32 | # -v Verbose: Print Debug Information. 33 | # -u Generate UCF file from SystemVerilog file. 34 | # -f SystemVerilog input file. 35 | # 36 | # Example of Module Instantiation: 37 | # 38 | # svtools.pl -u -f sample.v 39 | # 40 | # Save this file in your home 'bin' directory. 41 | # 42 | #****************************************************************** 43 | # 44 | # Copyright (c) 2012, Jeremy W. Webb 45 | # All rights reserved. 46 | # 47 | # Redistribution and use in source and binary forms, with or without 48 | # modification, are permitted provided that the following conditions 49 | # are met: 50 | # 51 | # 1. Redistributions of source code must retain the above copyright 52 | # notice, this list of conditions and the following disclaimer. 53 | # 2. Redistributions in binary form must reproduce the above copyright 54 | # notice, this list of conditions and the following disclaimer in 55 | # the documentation and/or other materials provided with the 56 | # distribution. 57 | # 58 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 59 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 60 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 61 | # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 62 | # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 63 | # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 64 | # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 65 | # OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 66 | # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 67 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 68 | # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 69 | # DAMAGE. 70 | # 71 | # The views and conclusions contained in the software and documentation 72 | # are those of the authors and should not be interpreted as representing 73 | # official policies, either expressed or implied, of the FreeBSD Project. 74 | # 75 | #****************************************************************** 76 | 77 | #****************************************************************** 78 | # CPAN Modules 79 | #****************************************************************** 80 | use strict; 81 | use warnings; 82 | use Getopt::Std; 83 | 84 | #****************************************************************** 85 | # Custom Modules 86 | #****************************************************************** 87 | use SystemVerilogTools qw( genUCFFile ); 88 | 89 | #****************************************************************** 90 | # Constants and Variables: 91 | #****************************************************************** 92 | my (%svH, $sv_rH); 93 | my (%opts)=(); 94 | my ($file); 95 | my ($debug); 96 | 97 | #****************************************************************** 98 | # Retrieve command line argument 99 | #****************************************************************** 100 | getopts('hvuf:',\%opts); 101 | 102 | my $optslen = scalar( keys %opts ); 103 | print("Number of Options on Command-Line: $optslen\n") if $opts{v}; 104 | # check for valid combination of command-line arguments 105 | if ( $opts{h} || !$opts{f} || !($opts{u}) || ($optslen eq "0") ) { 106 | print_usage(); 107 | exit; 108 | } 109 | 110 | # parse command-line arguments 111 | $file = $opts{f}; 112 | $debug = $opts{v}; 113 | 114 | #****************************************************************** 115 | # Make Date int MM/DD/YYYY 116 | #****************************************************************** 117 | my $year = 0; 118 | my $month = 0; 119 | my $day = 0; 120 | ($day, $month, $year) = (localtime)[3,4,5]; 121 | 122 | #****************************************************************** 123 | # Grab username from PC: 124 | #****************************************************************** 125 | my $author= "$^O user"; 126 | if ($^O =~ /mswin/i) { 127 | $author= $ENV{USERNAME} if defined $ENV{USERNAME}; 128 | } else { 129 | $author = getlogin(); 130 | } 131 | 132 | #****************************************************************** 133 | # Initialize Verilog Hash: 134 | #****************************************************************** 135 | $svH{ 'username' } = $author; 136 | $svH{ 'file' } = $file; 137 | $svH{ 'day' } = $day; 138 | $svH{ 'month' } = $month; 139 | $svH{ 'year' } = $year; 140 | $svH{ 'debug' } = $debug; 141 | 142 | #****************************************************************** 143 | # Generate UCF File: 144 | #****************************************************************** 145 | if ($opts{u}) { 146 | $sv_rH = genUCFFile(\%svH); 147 | } 148 | 149 | exit; 150 | 151 | #****************************************************************** 152 | # Generic Error and Exit routine 153 | #****************************************************************** 154 | 155 | sub dienice { 156 | my($errmsg) = @_; 157 | print"$errmsg\n"; 158 | exit; 159 | } 160 | 161 | sub print_usage { 162 | my ($usage); 163 | $usage = "\nUsage: $0 [-h] [-v] [-u] [-f ]\n"; 164 | $usage .= "\n"; 165 | $usage .= "\t-h\t\tPrint this help message.\n"; 166 | $usage .= "\t-v\t\tVerbose: Print Debug Information.\n"; 167 | $usage .= "\t-u\t\tGenerate UCF file from SystemVerilog file.\n"; 168 | $usage .= "\t-f \tSystemVerilog input file.\n"; 169 | $usage .= "\n"; 170 | $usage .= "\tExample of Module Instantiation:\n"; 171 | $usage .= "\t\t$0 -u -f sample.v \n"; 172 | $usage .= "\n"; 173 | print($usage); 174 | return; 175 | } 176 | 177 | -------------------------------------------------------------------------------- /scripts/sv_inst.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | #****************************************************************** 4 | # vim:ts=8:sw=8:expandtab:cindent 5 | #****************************************************************** 6 | # 7 | # sv_inst.pl module 8 | # 9 | #****************************************************************** 10 | # 11 | # created on: 07/21/2012 12 | # created by: jwwebb 13 | # last edit on: $DateTime: $ 14 | # last edit by: $Author: $ 15 | # revision: $Revision: $ 16 | # comments: Generated 17 | # 18 | #****************************************************************** 19 | # Revision List: 20 | # 21 | # 1.0 07/21/2012 Initial release 22 | # 23 | #****************************************************************** 24 | # SystemVerilog Tools Module 25 | # 26 | # This utility is intended to make designing with SystemVerilog 27 | # simpler. This utility supports the following options: 28 | # 29 | # Usage: svtools.pl [-h] [-v] [-i] [-f ] 30 | # 31 | # -h Print this help message. 32 | # -v Verbose: Print Debug Information. 33 | # -i Generate SystemVerilog Instantiation. 34 | # -f SystemVerilog input file. 35 | # 36 | # Example of Module Instantiation: 37 | # 38 | # svtools.pl -i -f sample.v 39 | # 40 | # Save this file in your home 'bin' directory. 41 | # 42 | #****************************************************************** 43 | # 44 | # Copyright (c) 2012, Jeremy W. Webb 45 | # All rights reserved. 46 | # 47 | # Redistribution and use in source and binary forms, with or without 48 | # modification, are permitted provided that the following conditions 49 | # are met: 50 | # 51 | # 1. Redistributions of source code must retain the above copyright 52 | # notice, this list of conditions and the following disclaimer. 53 | # 2. Redistributions in binary form must reproduce the above copyright 54 | # notice, this list of conditions and the following disclaimer in 55 | # the documentation and/or other materials provided with the 56 | # distribution. 57 | # 58 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 59 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 60 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 61 | # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 62 | # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 63 | # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 64 | # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 65 | # OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 66 | # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 67 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 68 | # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 69 | # DAMAGE. 70 | # 71 | # The views and conclusions contained in the software and documentation 72 | # are those of the authors and should not be interpreted as representing 73 | # official policies, either expressed or implied, of the FreeBSD Project. 74 | # 75 | #****************************************************************** 76 | 77 | #****************************************************************** 78 | # CPAN Modules 79 | #****************************************************************** 80 | use strict; 81 | use warnings; 82 | use Getopt::Std; 83 | 84 | #****************************************************************** 85 | # Custom Modules 86 | #****************************************************************** 87 | use SystemVerilogTools qw( printModInst ); 88 | 89 | #****************************************************************** 90 | # Constants and Variables: 91 | #****************************************************************** 92 | my (%svH, $sv_rH); 93 | my (%opts)=(); 94 | my ($file); 95 | my ($debug); 96 | 97 | #****************************************************************** 98 | # Retrieve command line argument 99 | #****************************************************************** 100 | getopts('hvif:',\%opts); 101 | 102 | my $optslen = scalar( keys %opts ); 103 | print("Number of Options on Command-Line: $optslen\n") if $opts{v}; 104 | # check for valid combination of command-line arguments 105 | if ( $opts{h} || !$opts{f} || !($opts{i}) || ($optslen eq "0") ) { 106 | print_usage(); 107 | exit; 108 | } 109 | 110 | # parse command-line arguments 111 | $file = $opts{f}; 112 | $debug = $opts{v}; 113 | 114 | #****************************************************************** 115 | # Make Date int MM/DD/YYYY 116 | #****************************************************************** 117 | my $year = 0; 118 | my $month = 0; 119 | my $day = 0; 120 | ($day, $month, $year) = (localtime)[3,4,5]; 121 | 122 | #****************************************************************** 123 | # Grab username from PC: 124 | #****************************************************************** 125 | my $author= "$^O user"; 126 | if ($^O =~ /mswin/i) { 127 | $author= $ENV{USERNAME} if defined $ENV{USERNAME}; 128 | } else { 129 | $author = getlogin(); 130 | } 131 | 132 | #****************************************************************** 133 | # Initialize Verilog Hash: 134 | #****************************************************************** 135 | $svH{ 'username' } = $author; 136 | $svH{ 'file' } = $file; 137 | $svH{ 'day' } = $day; 138 | $svH{ 'month' } = $month; 139 | $svH{ 'year' } = $year; 140 | $svH{ 'debug' } = $debug; 141 | 142 | #****************************************************************** 143 | # Print Module Declaration: 144 | #****************************************************************** 145 | if ($opts{i}) { 146 | $sv_rH = printModInst(\%svH); 147 | print("\n\n"); 148 | } 149 | 150 | 151 | exit; 152 | 153 | #****************************************************************** 154 | # Generic Error and Exit routine 155 | #****************************************************************** 156 | 157 | sub dienice { 158 | my($errmsg) = @_; 159 | print"$errmsg\n"; 160 | exit; 161 | } 162 | 163 | sub print_usage { 164 | my ($usage); 165 | $usage = "\nUsage: $0 [-h] [-v] [-i] [-f ]\n"; 166 | $usage .= "\n"; 167 | $usage .= "\t-h\t\tPrint this help message.\n"; 168 | $usage .= "\t-v\t\tVerbose: Print Debug Information.\n"; 169 | $usage .= "\t-i\t\tGenerate SystemVerilog Instantiation.\n"; 170 | $usage .= "\t-f \tSystemVerilog input file.\n"; 171 | $usage .= "\n"; 172 | $usage .= "\tExample of Module Instantiation:\n"; 173 | $usage .= "\t\t$0 -i -f sample.v \n"; 174 | $usage .= "\n"; 175 | print($usage); 176 | return; 177 | } 178 | 179 | -------------------------------------------------------------------------------- /scripts/sv_mod_low.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | #****************************************************************** 4 | # vim:ts=8:sw=8:expandtab:cindent 5 | #****************************************************************** 6 | # 7 | # sv_mod_low.pl module 8 | # 9 | #****************************************************************** 10 | # 11 | # created on: 07/21/2012 12 | # created by: jwwebb 13 | # last edit on: $DateTime: $ 14 | # last edit by: $Author: $ 15 | # revision: $Revision: $ 16 | # comments: Generated 17 | # 18 | #****************************************************************** 19 | # Revision List: 20 | # 21 | # 1.0 07/21/2012 Initial release 22 | # 23 | #****************************************************************** 24 | # SystemVerilog Tools Module 25 | # 26 | # This utility is intended to make designing with SystemVerilog 27 | # simpler. This utility supports the following options: 28 | # 29 | # Usage: svtools.pl [-h] [-v] [-z] [-f ] 30 | # 31 | # -h Print this help message. 32 | # -v Verbose: Print Debug Information. 33 | # -z Generate new SystemVerilog low-level module file from Template. 34 | # -f SystemVerilog input file. 35 | # 36 | # Example of Module Instantiation: 37 | # 38 | # svtools.pl -z -f sample.v 39 | # 40 | # Save this file in your home 'bin' directory. 41 | # 42 | #****************************************************************** 43 | # 44 | # Copyright (c) 2012, Jeremy W. Webb 45 | # All rights reserved. 46 | # 47 | # Redistribution and use in source and binary forms, with or without 48 | # modification, are permitted provided that the following conditions 49 | # are met: 50 | # 51 | # 1. Redistributions of source code must retain the above copyright 52 | # notice, this list of conditions and the following disclaimer. 53 | # 2. Redistributions in binary form must reproduce the above copyright 54 | # notice, this list of conditions and the following disclaimer in 55 | # the documentation and/or other materials provided with the 56 | # distribution. 57 | # 58 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 59 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 60 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 61 | # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 62 | # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 63 | # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 64 | # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 65 | # OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 66 | # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 67 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 68 | # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 69 | # DAMAGE. 70 | # 71 | # The views and conclusions contained in the software and documentation 72 | # are those of the authors and should not be interpreted as representing 73 | # official policies, either expressed or implied, of the FreeBSD Project. 74 | # 75 | #****************************************************************** 76 | 77 | #****************************************************************** 78 | # CPAN Modules 79 | #****************************************************************** 80 | use strict; 81 | use warnings; 82 | use Getopt::Std; 83 | 84 | #****************************************************************** 85 | # Custom Modules 86 | #****************************************************************** 87 | use SystemVerilogTools qw( genSVLowModule ); 88 | 89 | #****************************************************************** 90 | # Constants and Variables: 91 | #****************************************************************** 92 | my (%svH, $sv_rH); 93 | my (%opts)=(); 94 | my ($file); 95 | my ($debug); 96 | 97 | #****************************************************************** 98 | # Retrieve command line argument 99 | #****************************************************************** 100 | getopts('hvf:z',\%opts); 101 | 102 | my $optslen = scalar( keys %opts ); 103 | print("Number of Options on Command-Line: $optslen\n") if $opts{v}; 104 | # check for valid combination of command-line arguments 105 | if ( $opts{h} || !$opts{f} || !($opts{z}) || ($optslen eq "0") ) { 106 | print_usage(); 107 | exit; 108 | } 109 | 110 | # parse command-line arguments 111 | $file = $opts{f}; 112 | $debug = $opts{v}; 113 | 114 | #****************************************************************** 115 | # Make Date int MM/DD/YYYY 116 | #****************************************************************** 117 | my $year = 0; 118 | my $month = 0; 119 | my $day = 0; 120 | ($day, $month, $year) = (localtime)[3,4,5]; 121 | 122 | #****************************************************************** 123 | # Grab username from PC: 124 | #****************************************************************** 125 | my $author= "$^O user"; 126 | if ($^O =~ /mswin/i) { 127 | $author= $ENV{USERNAME} if defined $ENV{USERNAME}; 128 | } else { 129 | $author = getlogin(); 130 | } 131 | 132 | #****************************************************************** 133 | # Initialize Verilog Hash: 134 | #****************************************************************** 135 | $svH{ 'username' } = $author; 136 | $svH{ 'file' } = $file; 137 | $svH{ 'day' } = $day; 138 | $svH{ 'month' } = $month; 139 | $svH{ 'year' } = $year; 140 | $svH{ 'debug' } = $debug; 141 | 142 | #****************************************************************** 143 | # Generate Lower SystemVerilog Module: 144 | #****************************************************************** 145 | if ($opts{z}) { 146 | print("Filename: $opts{f}\n") if $debug; 147 | $sv_rH = genSVLowModule(\%svH); 148 | } 149 | 150 | exit; 151 | 152 | #****************************************************************** 153 | # Generic Error and Exit routine 154 | #****************************************************************** 155 | 156 | sub dienice { 157 | my($errmsg) = @_; 158 | print"$errmsg\n"; 159 | exit; 160 | } 161 | 162 | sub print_usage { 163 | my ($usage); 164 | $usage = "\nUsage: $0 [-h] [-v] [z] [-f ]\n"; 165 | $usage .= "\n"; 166 | $usage .= "\t-h\t\tPrint this help message.\n"; 167 | $usage .= "\t-v\t\tVerbose: Print Debug Information.\n"; 168 | $usage .= "\t-z\t\tGenerate new SystemVerilog low-level module file from Template.\n"; 169 | $usage .= "\t-f \tSystemVerilog input file.\n"; 170 | $usage .= "\n"; 171 | $usage .= "\tExample of Module Instantiation:\n"; 172 | $usage .= "\t\t$0 -z -f sample.v \n"; 173 | $usage .= "\n"; 174 | print($usage); 175 | return; 176 | } 177 | 178 | -------------------------------------------------------------------------------- /scripts/sv_mod_top.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | #****************************************************************** 4 | # vim:ts=8:sw=8:expandtab:cindent 5 | #****************************************************************** 6 | # 7 | # sv_mod_top.pl module 8 | # 9 | #****************************************************************** 10 | # 11 | # created on: 07/21/2012 12 | # created by: jwwebb 13 | # last edit on: $DateTime: $ 14 | # last edit by: $Author: $ 15 | # revision: $Revision: $ 16 | # comments: Generated 17 | # 18 | #****************************************************************** 19 | # Revision List: 20 | # 21 | # 1.0 07/21/2012 Initial release 22 | # 23 | #****************************************************************** 24 | # SystemVerilog Tools Module 25 | # 26 | # This utility is intended to make designing with SystemVerilog 27 | # simpler. This utility supports the following options: 28 | # 29 | # Usage: svtools.pl [-h] [-v] [-a] [-f ] 30 | # 31 | # -h Print this help message. 32 | # -v Verbose: Print Debug Information. 33 | # -a Generate new SystemVerilog top-level module file from Template. 34 | # -f SystemVerilog input file. 35 | # 36 | # Example of Module Instantiation: 37 | # 38 | # svtools.pl -a -f sample.v 39 | # 40 | # Save this file in your home 'bin' directory. 41 | # 42 | #****************************************************************** 43 | # 44 | # Copyright (c) 2012, Jeremy W. Webb 45 | # All rights reserved. 46 | # 47 | # Redistribution and use in source and binary forms, with or without 48 | # modification, are permitted provided that the following conditions 49 | # are met: 50 | # 51 | # 1. Redistributions of source code must retain the above copyright 52 | # notice, this list of conditions and the following disclaimer. 53 | # 2. Redistributions in binary form must reproduce the above copyright 54 | # notice, this list of conditions and the following disclaimer in 55 | # the documentation and/or other materials provided with the 56 | # distribution. 57 | # 58 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 59 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 60 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 61 | # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 62 | # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 63 | # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 64 | # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 65 | # OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 66 | # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 67 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 68 | # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 69 | # DAMAGE. 70 | # 71 | # The views and conclusions contained in the software and documentation 72 | # are those of the authors and should not be interpreted as representing 73 | # official policies, either expressed or implied, of the FreeBSD Project. 74 | # 75 | #****************************************************************** 76 | 77 | #****************************************************************** 78 | # CPAN Modules 79 | #****************************************************************** 80 | use strict; 81 | use warnings; 82 | use Getopt::Std; 83 | 84 | #****************************************************************** 85 | # Custom Modules 86 | #****************************************************************** 87 | use SystemVerilogTools qw( genSVTopModule ); 88 | 89 | #****************************************************************** 90 | # Constants and Variables: 91 | #****************************************************************** 92 | my (%svH, $sv_rH); 93 | my (%opts)=(); 94 | my ($file); 95 | my ($debug); 96 | 97 | #****************************************************************** 98 | # Retrieve command line argument 99 | #****************************************************************** 100 | getopts('hvf:a',\%opts); 101 | 102 | my $optslen = scalar( keys %opts ); 103 | print("Number of Options on Command-Line: $optslen\n") if $opts{v}; 104 | # check for valid combination of command-line arguments 105 | if ( $opts{h} || !$opts{f} || !($opts{a}) || ($optslen eq "0") ) { 106 | print_usage(); 107 | exit; 108 | } 109 | 110 | # parse command-line arguments 111 | $file = $opts{f}; 112 | $debug = $opts{v}; 113 | 114 | #****************************************************************** 115 | # Make Date int MM/DD/YYYY 116 | #****************************************************************** 117 | my $year = 0; 118 | my $month = 0; 119 | my $day = 0; 120 | ($day, $month, $year) = (localtime)[3,4,5]; 121 | 122 | #****************************************************************** 123 | # Grab username from PC: 124 | #****************************************************************** 125 | my $author= "$^O user"; 126 | if ($^O =~ /mswin/i) { 127 | $author= $ENV{USERNAME} if defined $ENV{USERNAME}; 128 | } else { 129 | $author = getlogin(); 130 | } 131 | 132 | #****************************************************************** 133 | # Initialize Verilog Hash: 134 | #****************************************************************** 135 | $svH{ 'username' } = $author; 136 | $svH{ 'file' } = $file; 137 | $svH{ 'day' } = $day; 138 | $svH{ 'month' } = $month; 139 | $svH{ 'year' } = $year; 140 | $svH{ 'debug' } = $debug; 141 | 142 | #****************************************************************** 143 | # Generate Top-Level SystemVerilog Module: 144 | #****************************************************************** 145 | if ($opts{a}) { 146 | print("Filename: $opts{f}\n") if $debug; 147 | $sv_rH = genSVTopModule(\%svH); 148 | } 149 | 150 | exit; 151 | 152 | #****************************************************************** 153 | # Generic Error and Exit routine 154 | #****************************************************************** 155 | 156 | sub dienice { 157 | my($errmsg) = @_; 158 | print"$errmsg\n"; 159 | exit; 160 | } 161 | 162 | sub print_usage { 163 | my ($usage); 164 | $usage = "\nUsage: $0 [-h] [-v] [-a] [-f ]\n"; 165 | $usage .= "\n"; 166 | $usage .= "\t-h\t\tPrint this help message.\n"; 167 | $usage .= "\t-v\t\tVerbose: Print Debug Information.\n"; 168 | $usage .= "\t-a\t\tGenerate new SystemVerilog top-level module file from Template.\n"; 169 | $usage .= "\t-f \tSystemVerilog input file.\n"; 170 | $usage .= "\n"; 171 | $usage .= "\tExample of Module Instantiation:\n"; 172 | $usage .= "\t\t$0 -a -f sample.v \n"; 173 | $usage .= "\n"; 174 | print($usage); 175 | return; 176 | } 177 | 178 | -------------------------------------------------------------------------------- /scripts/svtools.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | #****************************************************************** 4 | # vim:ts=8:sw=8:expandtab:cindent 5 | #****************************************************************** 6 | # 7 | # svtools.pl module 8 | # 9 | #****************************************************************** 10 | # 11 | # created on: 07/21/2012 12 | # created by: jwwebb 13 | # last edit on: $DateTime: $ 14 | # last edit by: $Author: $ 15 | # revision: $Revision: $ 16 | # comments: Generated 17 | # 18 | #****************************************************************** 19 | # Revision List: 20 | # 21 | # 1.0 07/21/2012 Initial release 22 | # 23 | #****************************************************************** 24 | # SystemVerilog Tools Module 25 | # 26 | # This utility is intended to make designing with SystemVerilog 27 | # simpler. This utility supports the following options: 28 | # 29 | # Usage: svtools.pl [-h] [-v] [-i|-t|-u|-a|-z] [-f ] 30 | # 31 | # -h Print this help message. 32 | # -v Verbose: Print Debug Information. 33 | # -i Generate SystemVerilog Instantiation. 34 | # -t Generate SystemVerilog Test Bench. 35 | # -u Generate UCF file from SystemVerilog file. 36 | # -a Generate new SystemVerilog top-level module file from Template. 37 | # -z Generate new SystemVerilog low-level module file from Template. 38 | # -f SystemVerilog input file. 39 | # 40 | # Example of Module Instantiation: 41 | # 42 | # svtools.pl -i -f sample.v 43 | # svtools.pl -a -f sample.v 44 | # svtools.pl -z -f sample.v 45 | # svtools.pl -t -f sample.v 46 | # svtools.pl -u -f sample.v 47 | # 48 | # Save this file in your home 'bin' directory. 49 | # 50 | #****************************************************************** 51 | # 52 | # Copyright (c) 2012, Jeremy W. Webb 53 | # All rights reserved. 54 | # 55 | # Redistribution and use in source and binary forms, with or without 56 | # modification, are permitted provided that the following conditions 57 | # are met: 58 | # 59 | # 1. Redistributions of source code must retain the above copyright 60 | # notice, this list of conditions and the following disclaimer. 61 | # 2. Redistributions in binary form must reproduce the above copyright 62 | # notice, this list of conditions and the following disclaimer in 63 | # the documentation and/or other materials provided with the 64 | # distribution. 65 | # 66 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 67 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 68 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 69 | # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 70 | # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 71 | # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 72 | # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 73 | # OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 74 | # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 75 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 76 | # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 77 | # DAMAGE. 78 | # 79 | # The views and conclusions contained in the software and documentation 80 | # are those of the authors and should not be interpreted as representing 81 | # official policies, either expressed or implied, of the FreeBSD Project. 82 | # 83 | #****************************************************************** 84 | 85 | #****************************************************************** 86 | # CPAN Modules 87 | #****************************************************************** 88 | use strict; 89 | use warnings; 90 | use Getopt::Std; 91 | 92 | #****************************************************************** 93 | # Custom Modules 94 | #****************************************************************** 95 | use SystemVerilogTools qw( printModInst 96 | genTBTestFile 97 | genUCFFile 98 | genSVLowModule 99 | genSVTopModule ); 100 | 101 | #****************************************************************** 102 | # Constants and Variables: 103 | #****************************************************************** 104 | my (%svH, $sv_rH); 105 | my (%opts)=(); 106 | my ($file); 107 | my ($debug); 108 | 109 | #****************************************************************** 110 | # Retrieve command line argument 111 | #****************************************************************** 112 | getopts('hvituf:az',\%opts); 113 | 114 | my $optslen = scalar( keys %opts ); 115 | print("Number of Options on Command-Line: $optslen\n") if $opts{v}; 116 | # check for valid combination of command-line arguments 117 | if ( $opts{h} || !$opts{f} || !($opts{i} || $opts{t} || $opts{u} || $opts{a} || $opts{z}) || ($optslen eq "0") ) { 118 | print_usage(); 119 | exit; 120 | } 121 | 122 | # parse command-line arguments 123 | $file = $opts{f}; 124 | $debug = $opts{v}; 125 | 126 | #****************************************************************** 127 | # Make Date int MM/DD/YYYY 128 | #****************************************************************** 129 | my $year = 0; 130 | my $month = 0; 131 | my $day = 0; 132 | ($day, $month, $year) = (localtime)[3,4,5]; 133 | 134 | #****************************************************************** 135 | # Grab username from PC: 136 | #****************************************************************** 137 | my $author= "$^O user"; 138 | if ($^O =~ /mswin/i) { 139 | $author= $ENV{USERNAME} if defined $ENV{USERNAME}; 140 | } else { 141 | $author = getlogin(); 142 | } 143 | 144 | #****************************************************************** 145 | # Initialize Verilog Hash: 146 | #****************************************************************** 147 | $svH{ 'username' } = $author; 148 | $svH{ 'file' } = $file; 149 | $svH{ 'day' } = $day; 150 | $svH{ 'month' } = $month; 151 | $svH{ 'year' } = $year; 152 | $svH{ 'debug' } = $debug; 153 | 154 | #****************************************************************** 155 | # Generate Top-Level SystemVerilog Module: 156 | #****************************************************************** 157 | if ($opts{a}) { 158 | print("Filename: $opts{f}\n") if $debug; 159 | $sv_rH = genSVTopModule(\%svH); 160 | } 161 | 162 | #****************************************************************** 163 | # Generate Lower SystemVerilog Module: 164 | #****************************************************************** 165 | if ($opts{z}) { 166 | print("Filename: $opts{f}\n") if $debug; 167 | $sv_rH = genSVLowModule(\%svH); 168 | } 169 | 170 | #****************************************************************** 171 | # Print Module Declaration: 172 | #****************************************************************** 173 | if ($opts{i}) { 174 | $sv_rH = printModInst(\%svH); 175 | print("\n\n"); 176 | } 177 | 178 | #****************************************************************** 179 | # Generate UCF File: 180 | #****************************************************************** 181 | if ($opts{u}) { 182 | $sv_rH = genUCFFile(\%svH); 183 | } 184 | 185 | #****************************************************************** 186 | # Generate Test Bench File: 187 | #****************************************************************** 188 | if ($opts{t}) { 189 | $sv_rH = genTBTestFile(\%svH); 190 | } 191 | 192 | 193 | exit; 194 | 195 | #****************************************************************** 196 | # Generic Error and Exit routine 197 | #****************************************************************** 198 | 199 | sub dienice { 200 | my($errmsg) = @_; 201 | print"$errmsg\n"; 202 | exit; 203 | } 204 | 205 | sub print_usage { 206 | my ($usage); 207 | $usage = "\nUsage: $0 [-h] [-v] [-i|-t|-u|-a|-z] [-f ]\n"; 208 | $usage .= "\n"; 209 | $usage .= "\t-h\t\tPrint this help message.\n"; 210 | $usage .= "\t-v\t\tVerbose: Print Debug Information.\n"; 211 | $usage .= "\t-i\t\tGenerate SystemVerilog Instantiation.\n"; 212 | $usage .= "\t-t\t\tGenerate SystemVerilog Test Bench.\n"; 213 | $usage .= "\t-u\t\tGenerate UCF file from SystemVerilog file.\n"; 214 | $usage .= "\t-a\t\tGenerate new SystemVerilog top-level module file from Template.\n"; 215 | $usage .= "\t-z\t\tGenerate new SystemVerilog low-level module file from Template.\n"; 216 | $usage .= "\t-f \tSystemVerilog input file.\n"; 217 | $usage .= "\n"; 218 | $usage .= "\tExample of Module Instantiation:\n"; 219 | $usage .= "\t\t$0 -i -f sample.v \n"; 220 | $usage .= "\n"; 221 | print($usage); 222 | return; 223 | } 224 | 225 | -------------------------------------------------------------------------------- /module/scripts/update.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | #****************************************************************** 4 | # 5 | # update.pl module 6 | # 7 | #****************************************************************** 8 | # 9 | # created on: 07/21/2012 10 | # created by: jwwebb 11 | # last edit on: 07/21/2012 12 | # last edit by: jwwebb 13 | # 14 | #****************************************************************** 15 | # Revision List: 16 | # 17 | # 1.0 07/21/2012 Initial release 18 | # 19 | # Please report bugs, errors, etc. 20 | #****************************************************************** 21 | # Update Company Name 22 | # 23 | # This utility is intended to do the following: 24 | # 25 | # * update COMPANY string with user's company name. 26 | # 27 | # * Usage: 28 | # 29 | # The "update" script can be called as shown below: 30 | # 31 | # * Update the Version Register: ./update -C 32 | # 33 | # Entering just "./update" will cause the program to print out the 34 | # usage information: 35 | # 36 | # Usage: ./update [-h] [-v] [-C] 37 | # 38 | # -h Print Help. 39 | # -v Verbose: Print Debug Information. 40 | # -C Update Company Name. 41 | # 42 | # Example: 43 | # ./update -v -C 44 | # 45 | #****************************************************************** 46 | # 47 | # Copyright (c) 2012, Jeremy W. Webb 48 | # All rights reserved. 49 | # 50 | # Redistribution and use in source and binary forms, with or without 51 | # modification, are permitted provided that the following conditions 52 | # are met: 53 | # 54 | # 1. Redistributions of source code must retain the above copyright 55 | # notice, this list of conditions and the following disclaimer. 56 | # 2. Redistributions in binary form must reproduce the above copyright 57 | # notice, this list of conditions and the following disclaimer in 58 | # the documentation and/or other materials provided with the 59 | # distribution. 60 | # 61 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 62 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 63 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 64 | # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 65 | # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 66 | # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 67 | # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 68 | # OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 69 | # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 70 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 71 | # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 72 | # DAMAGE. 73 | # 74 | # The views and conclusions contained in the software and documentation 75 | # are those of the authors and should not be interpreted as representing 76 | # official policies, either expressed or implied, of the FreeBSD Project. 77 | # 78 | #****************************************************************** 79 | 80 | #****************************************************************** 81 | # CPAN Modules 82 | #****************************************************************** 83 | use strict; 84 | use warnings; 85 | use Getopt::Std; 86 | use Data::Dumper; 87 | use POSIX; 88 | use Time::tm; 89 | use Time::Local; 90 | use File::stat; 91 | use SDBM_File; # Simple database 92 | use Term::ANSIColor; # For colorizing text 93 | 94 | #****************************************************************** 95 | # Constants and Variables: 96 | #****************************************************************** 97 | my (%opts)=(); 98 | my ($company); 99 | my ($test); 100 | my ($debug); 101 | my (%fpgaH, $fpga_rH); 102 | 103 | #****************************************************************** 104 | # Retrieve command line argument 105 | #****************************************************************** 106 | getopts('hvCt',\%opts); 107 | 108 | #check for valid combination command-line arguments 109 | if ($opts{h} || (!$opts{C} && !$opts{t}) ) { 110 | print_usage(); 111 | exit; 112 | } 113 | 114 | # parse command-line arguments 115 | $company = $opts{C}; 116 | $test = $opts{t}; 117 | $debug = $opts{v}; 118 | 119 | #****************************************************************** 120 | # Stuff input options into a Hash: 121 | #****************************************************************** 122 | $fpgaH{ 'debug' } = $debug; 123 | $fpgaH{ 'pIfile' } = "./in/SystemVerilogTools.pm"; 124 | $fpgaH{ 'pOfile' } = "./lib/SystemVerilogTools.pm"; 125 | 126 | #****************************************************************** 127 | # Persistent data 128 | #****************************************************************** 129 | my(%persistent_data); # Pre-declare hash 130 | my($user)=$ENV{'USER'}; 131 | my($persistent_datafile)=$user."_svtools_persistent_data"; 132 | tie(%persistent_data, 'SDBM_File', "/tmp/$persistent_datafile", 133 | O_RDWR|O_CREAT, 0666) || die "Couldn't tie file! $!\n"; 134 | 135 | #****************************************************************** 136 | # Set Company Name: 137 | #****************************************************************** 138 | if ($company) { 139 | $fpga_rH = modCompany(\%fpgaH); 140 | } 141 | 142 | if ($test) { 143 | $fpga_rH = getCompany(\%fpgaH); 144 | } 145 | 146 | exit; 147 | 148 | #****************************************************************** 149 | # Generic Error and Exit routine 150 | #****************************************************************** 151 | 152 | sub dienice { 153 | my($errmsg) = @_; 154 | print"$errmsg\n"; 155 | exit; 156 | } 157 | 158 | sub print_usage { 159 | my ($usage); 160 | $usage = "\nUsage: $0 [-h] [-v] [-C]\n"; 161 | $usage .= "\n"; 162 | $usage .= "\t-h\t\tPrint Help.\n"; 163 | $usage .= "\t-v\t\tVerbose: Print Debug Information.\n"; 164 | $usage .= "\t-C\t\tUpdate Company Name.\n"; 165 | $usage .= "\n"; 166 | $usage .= "\tExample:\n"; 167 | $usage .= "\t\t$0 -v -C\n"; 168 | $usage .= "\n"; 169 | print($usage); 170 | return; 171 | } 172 | 173 | sub getCompany { 174 | #****************************************************************** 175 | # Get Company Name: 176 | # 177 | # The sub-routine getCompany() will ask the user for a Company Name, 178 | # if no input is provided a default name of "My Company Name" will 179 | # be used. 180 | # 181 | # Usage: $fpga_rH = getCompany(\%fpgaH); 182 | # 183 | #****************************************************************** 184 | my ($fpga_rH) = shift; # Read user's variable. 185 | my (%fpgaH) = %{ $fpga_rH }; # De-reference hash. 186 | my ($debug) = $fpgaH{'debug'}; # Print out Debug Info. 187 | 188 | #****************************************************************** 189 | # Get Company Name from User: 190 | #****************************************************************** 191 | my $companyUser = Get_Input( "CompanyName","Enter company name","text","My Company Name"); 192 | $fpgaH{ 'companyName' } = $companyUser; 193 | printf("Company Name: %s\n", $fpgaH{'companyName'}) if $debug; 194 | 195 | #****************************************************************** 196 | # Return data to user 197 | #****************************************************************** 198 | return \%fpgaH; 199 | } 200 | 201 | sub getFile { 202 | #****************************************************************** 203 | # Get Input File: 204 | # 205 | # The sub-routine getFile() will open the input file, which is either a 206 | # binary or text file and read its contents into an array. It will also 207 | # determine the file length. The following parameters are created 208 | # 209 | # * filedata: @vdata1A 210 | # * fileLen: scalar(@vdata1A) 211 | # 212 | # Usage: $fpga_rH = getFile(\%fpgaH); 213 | # 214 | #****************************************************************** 215 | my ($fpga_rH) = shift; # Read user's variable. 216 | my (%fpgaH) = %{ $fpga_rH }; # De-reference hash. 217 | my ($file) = $fpgaH{'pIfile'}; # File Name 218 | my ($debug) = $fpgaH{'debug'}; # Print out Debug Info. 219 | 220 | #-------------------------------------------------------------------------- 221 | # Open the reg_defines.h file, and read the results into an array for 222 | # manipulating the data array. Close file when done. 223 | #-------------------------------------------------------------------------- 224 | open(inF, "<", $file) or dienice ("$file open failed"); 225 | my (@vdata1A) = ; 226 | close(inF); 227 | 228 | print("** Chomp input file line endings **\n") if $debug; 229 | print scalar(@vdata1A), "\n" if $debug; 230 | foreach my $j (@vdata1A) { 231 | chomp($j); 232 | $j =~ s/\r//; 233 | #print("$j\n") if $debug; 234 | } 235 | 236 | push (@{ $fpgaH{ 'pm_in' } }, @vdata1A); 237 | 238 | $fpgaH{ 'pm_lines' } = scalar(@{ $fpgaH{ 'pm_in' } }); 239 | 240 | print("\n\n") if $debug; 241 | print("Total number of lines: $fpgaH{ 'pm_lines' }\n") if $debug; 242 | print("\n\n") if $debug; 243 | 244 | #****************************************************************** 245 | # Return data to user 246 | #****************************************************************** 247 | return \%fpgaH; 248 | } 249 | 250 | sub parseFile { 251 | #****************************************************************** 252 | # Parse HDL File 253 | # 254 | # The sub-routine parseFile() will parse the input HDL File 255 | # and overwrite the following information: 256 | # 257 | # DATESTAMP 258 | # 259 | # Usage: $fpga_rH = parseFile(\%fpgaH); 260 | # 261 | #****************************************************************** 262 | my ($fpga_rH) = shift; # Read user's variable. 263 | my (%fpgaH) = %{ $fpga_rH }; # De-reference hash. 264 | my ($debug) = $fpgaH{'debug'}; # Print out Debug Info. 265 | 266 | #****************************************************************** 267 | # Search through $file for keywords. 268 | #****************************************************************** 269 | my ($i) = 0; 270 | 271 | for ($i=0; $i < $fpgaH{ 'pm_lines' }; $i++) { 272 | if (${ $fpgaH{ 'pm_in' } }[$i] =~ m/COMPANY/) { 273 | ${ $fpgaH{ 'pm_in' } }[$i] =~ s/COMPANY/$fpgaH{'companyName'}/; 274 | } 275 | } 276 | 277 | #print Dumper($fpgaH{'pm_in'}) if $debug; 278 | for (my $i=0; $i < $fpgaH{ 'pm_lines' }; $i++) { 279 | print(${ $fpgaH{ 'pm_in' } }[$i]) if $debug; 280 | printf("\n") if $debug; 281 | } 282 | 283 | #****************************************************************** 284 | # Return data to user 285 | #****************************************************************** 286 | return \%fpgaH; 287 | } 288 | 289 | sub writeFile { 290 | #****************************************************************** 291 | # Write Out Perl File: 292 | # 293 | # The sub-routine writeFile() will print the contents of the Perl 294 | # files into a new local file. 295 | # 296 | # Usage: $fpga_rH = writeFile($fpgaH); 297 | # 298 | #****************************************************************** 299 | my ($fpga_rH) = shift; # Read user's variable. 300 | my (%fpgaH) = %{ $fpga_rH }; # De-reference hash. 301 | my ($file) = $fpgaH{'pOfile'}; # File Name 302 | my ($debug) = $fpgaH{'debug'}; # Print out Debug Info. 303 | 304 | #****************************************************************** 305 | # Write HDL to File 306 | #****************************************************************** 307 | open(outF, ">", $file) or dienice ("$file open failed"); 308 | my ($i) = 0; 309 | for ($i=0; $i < $fpgaH{ 'pm_lines' }; $i++) { 310 | print outF ${ $fpgaH{ 'pm_in' } }[$i]; 311 | printf(outF "\n"); 312 | } 313 | close(outF); 314 | 315 | #****************************************************************** 316 | # Return data to user 317 | #****************************************************************** 318 | return \%fpgaH; 319 | } 320 | 321 | sub modCompany { 322 | #****************************************************************** 323 | # Modify Perl Module File: 324 | # 325 | # The sub-routine modCompany() will modify the company name in the 326 | # VerilogTools.pm file and write the file back out. 327 | # 328 | # Usage: $fpga_rH = modCompany($fpga_rH); 329 | # 330 | #****************************************************************** 331 | my ($fpga_rH) = shift; # Read user's variable. 332 | my (%fpgaH) = %{ $fpga_rH }; # De-reference hash. 333 | my ($debug) = $fpgaH{'debug'}; # Print out Debug Info. 334 | 335 | #****************************************************************** 336 | # Check to see if lib/VerilogTools.pm file exists and delete: 337 | #****************************************************************** 338 | printf("\n"); 339 | if (-e $fpgaH{'pOfile'}) { 340 | printf("Cleaning lib/ directory!!\n"); 341 | system("rm -f $fpgaH{'pOfile'}"); 342 | } 343 | #****************************************************************** 344 | # Calculate FPGA Date: 345 | #****************************************************************** 346 | $fpga_rH = getCompany(\%fpgaH); 347 | #****************************************************************** 348 | # Get File: 349 | #****************************************************************** 350 | $fpga_rH = getFile($fpga_rH); 351 | #****************************************************************** 352 | # Modify File: 353 | #****************************************************************** 354 | $fpga_rH = parseFile($fpga_rH); 355 | #****************************************************************** 356 | # Write File: 357 | #****************************************************************** 358 | $fpga_rH = writeFile($fpga_rH); 359 | 360 | #****************************************************************** 361 | # Return data to user 362 | #****************************************************************** 363 | return \%fpgaH; 364 | } 365 | 366 | 367 | 368 | ############################################################################## 369 | # 370 | # Get_Input - program for querrying user. 371 | # 372 | # Note: This subroutine uses the global hash called "%persistent_data" to 373 | # store/retrieve data. 374 | # 375 | # Input Types: 376 | # -> "number" 377 | # -> "pwr" 378 | # -> "freq" 379 | # -> "voltage" 380 | # -> "current" 381 | # -> "time" 382 | # -> "deg" 383 | # -> "text" 384 | # 385 | # Example Usage: 386 | # my($input)=Get_Input("Fmin","Enter Min Input Freq","freq",undef,1); 387 | # 388 | ############################################################################## 389 | sub Get_Input { 390 | my($variable)=shift; # Read user variable 391 | my($message)=shift || "Enter Min Number"; # Read user message 392 | my($input_type)=shift || "number"; # Read user input type 393 | my($def_value)=shift || undef; # Read user default value 394 | my($prec)=shift || 0; # Read user precision 395 | 396 | ########################################################################## 397 | # 398 | # Sub-routine variables 399 | # 400 | ########################################################################## 401 | my($string); # Set asside variable 402 | 403 | ########################################################################## 404 | # 405 | # Establish some default values if we have nothing... 406 | # 407 | ########################################################################## 408 | if ($input_type =~ /freq/i) { 409 | $def_value = (defined $def_value ? $def_value : 1e9 ); 410 | } elsif ($input_type =~ /current/i) { 411 | $def_value = (defined $def_value ? $def_value : 1e-3 ); 412 | } elsif ($input_type =~ /text/i) { 413 | $def_value = (defined $def_value ? $def_value : "Default" ); 414 | } else { 415 | $def_value = (defined $def_value ? $def_value : 0.0 ); 416 | } 417 | 418 | $persistent_data{$variable}=$def_value if 419 | !defined $persistent_data{$variable}; 420 | 421 | ########################################################################## 422 | # ...or use last values entered as new defaults 423 | ########################################################################## 424 | my($Value)=$persistent_data{$variable}; 425 | 426 | ########################################################################## 427 | # Ask user for input 428 | ########################################################################## 429 | my($input); # Pre-declare variable 430 | 431 | if ($input_type =~ /number|time/i) { 432 | $string = color('bold yellow').$Value. 433 | color('reset'); # Colorize string 434 | printf STDERR "$message [$string]:\n-> "; # Query user 435 | $input = scalar <>; # Get input 436 | chomp($input); # Remove newline 437 | if ($input !~ /^ *$/){ # Blank line? 438 | $input =~ s/^\s+//; # Nope, clean up 439 | $input =~ s/\s+$//; # Nope, clean up 440 | $input += 0.0; # Force number interp 441 | $persistent_data{$variable}=$input; # Store for later use 442 | $Value=$input; # Use as input 443 | } 444 | 445 | } elsif ($input_type =~ /pwr$/i) { 446 | $string = color('bold yellow').sprintf("%.${prec}f dBm",$Value). 447 | color('reset'); # Colorize string 448 | printf STDERR "$message [$string]:\n -> "; # Query user 449 | $input = scalar <>; # Get input 450 | chomp($input); # Remove newline 451 | if ($input !~ /^ *$/){ # Blank line? 452 | $input =~ s/^\s+//; # Nope, clean up 453 | $input =~ s/\s+$//; # Nope, clean up 454 | $input =~ s/dbm?//i; # Nope, clean up 455 | $input += 0.0; # Force number interp 456 | $persistent_data{$variable}=$input; # Store for later use 457 | $Value=$input; # Use as input 458 | } 459 | 460 | } elsif ($input_type =~ /pwrrel/i) { 461 | $string = color('bold yellow').sprintf("%.${prec}f dB",$Value). 462 | color('reset'); # Colorize string 463 | printf STDERR "$message [$string]:\n -> "; # Query user 464 | $input = scalar <>; # Get input 465 | chomp($input); # Remove newline 466 | if ($input !~ /^ *$/){ # Blank line? 467 | $input =~ s/^\s+//; # Nope, clean up 468 | $input =~ s/\s+$//; # Nope, clean up 469 | $input =~ s/dbm?//i; # Nope, clean up 470 | $input += 0.0; # Force number interp 471 | $persistent_data{$variable}=$input; # Store for later use 472 | $Value=$input; # Use as input 473 | } 474 | 475 | } elsif ($input_type =~ /freq/i) { 476 | $string = color('bold yellow').Suffix($Value,"Hz",$prec). 477 | color('reset'); # Colorize string 478 | printf STDERR "$message [$string]:\n -> "; # Query user 479 | $input = scalar <>; # Get input 480 | chomp($input); # Remove newline 481 | if ($input !~ /^ *$/){ # Blank line? 482 | $input =~ s/^\s+//; # Nope, clean up 483 | $input =~ s/\s+$//; # Nope, clean up 484 | $input =~ s/^(\S+)\s*gh?z?.*$/$1e9/i; # Nope, clean up 485 | $input =~ s/^(\S+)\s*mh?z?.*$/$1e6/i; # Nope, clean up 486 | $input =~ s/^(\S+)\s*kh?z?.*$/$1e3/i; # Nope, clean up 487 | $input =~ s/^(\S+)\s*hz.*$/$1/i; # Nope, clean up 488 | $input += 0.0; # Force number interp 489 | $persistent_data{$variable}=$input; # Store for later use 490 | $Value=$input; # Use as input 491 | } 492 | 493 | } elsif ($input_type =~ /bps/i) { 494 | $string = color('bold yellow').Suffix($Value,"bps",$prec). 495 | color('reset'); # Colorize string 496 | printf STDERR "$message [$string]:\n -> "; # Query user 497 | $input = scalar <>; # Get input 498 | chomp($input); # Remove newline 499 | if ($input !~ /^ *$/){ # Blank line? 500 | $input =~ s/^\s+//; # Nope, clean up 501 | $input =~ s/\s+$//; # Nope, clean up 502 | $input =~ s/^(\S+)\s*gb?p?s?.*$/$1e9/i; # Nope, clean up 503 | $input =~ s/^(\S+)\s*mb?p?s?.*$/$1e6/i; # Nope, clean up 504 | $input =~ s/^(\S+)\s*kb?p?s?.*$/$1e3/i; # Nope, clean up 505 | $input =~ s/^(\S+)\s*b?p?s?.*$/$1/i; # Nope, clean up 506 | $input += 0.0; # Force number interp 507 | $persistent_data{$variable}=$input; # Store for later use 508 | $Value=$input; # Use as input 509 | } 510 | 511 | } elsif ($input_type =~ /volt/i) { 512 | $string = color('bold yellow').Suffix($Value,"V",$prec). 513 | color('reset'); # Colorize string 514 | printf STDERR "$message [$string]:\n -> "; # Query user 515 | $input = scalar <>; # Get input 516 | chomp($input); # Remove newline 517 | if ($input !~ /^ *$/){ # Blank line? 518 | $input =~ s/^\s+//; # Nope, clean up 519 | $input =~ s/\s+$//; # Nope, clean up 520 | $input =~ s/v//i; # Nope, clean up 521 | $input += 0.0; # Force number interp 522 | $persistent_data{$variable}=$input; # Store for later use 523 | $Value=$input; # Use as input 524 | } 525 | 526 | } elsif ($input_type =~ /current/i) { 527 | $string = color('bold yellow').Suffix($Value,"A",$prec). 528 | color('reset'); # Colorize string 529 | printf STDERR "$message [$string]:\n -> "; # Query user 530 | $input = scalar <>; # Get input 531 | chomp($input); # Remove newline 532 | if ($input !~ /^ *$/){ # Blank line? 533 | $input =~ s/^\s+//; # Nope, clean up 534 | $input =~ s/\s+$//; # Nope, clean up 535 | $input =~ s/^(\S+)\s*ma?.*$/$1e-3/i; # Nope, clean up 536 | $input += 0.0; # Force number interp 537 | $persistent_data{$variable}=$input; # Store for later use 538 | $Value=$input; # Use as input 539 | } 540 | 541 | } elsif ($input_type =~ /text/i) { 542 | $string = color('bold yellow').$Value. 543 | color('reset'); # Colorize string 544 | printf STDERR "$message [$string]:\n -> "; # Query user 545 | $input = scalar <>; # Get input 546 | chomp($input); # Remove newline 547 | if ($input !~ /^ *$/){ # Blank line? 548 | $input =~ s/^\s+//; # Nope, clean up 549 | $input =~ s/\s+$//; # Nope, clean up 550 | $persistent_data{$variable}=$input; # Store for later use 551 | $Value=$input; # Use as input 552 | } 553 | 554 | } elsif ($input_type =~ /deg/i) { 555 | $string = color('bold yellow').$Value." Deg". 556 | color('reset'); # Colorize string 557 | printf STDERR "$message [$string]:\n -> "; # Query user 558 | $input = scalar <>; # Get input 559 | chomp($input); # Remove newline 560 | if ($input !~ /^ *$/){ # Blank line? 561 | $input =~ s/^\s+//; # Nope, clean up 562 | $input =~ s/\s+$//; # Nope, clean up 563 | $persistent_data{$variable}=$input; # Store for later use 564 | $Value=$input; # Use as input 565 | } 566 | 567 | } elsif ($input_type =~ /nodef/i) { 568 | printf STDERR "$message:\n -> "; # Query user 569 | $input = scalar <>; # Get input 570 | chomp($input); # Remove newline 571 | if ($input !~ /^ *$/){ # Blank line? 572 | $input =~ s/^\s+//; # Nope, clean up 573 | $input =~ s/\s+$//; # Nope, clean up 574 | $persistent_data{$variable}=$input; # Store for later use 575 | $Value=$input; # Use as input 576 | } 577 | 578 | } 579 | 580 | ########################################################################## 581 | # Return user value to caller 582 | ########################################################################## 583 | return $Value; 584 | 585 | } 586 | 587 | 588 | -------------------------------------------------------------------------------- /module/in/SystemVerilogTools.pm: -------------------------------------------------------------------------------- 1 | package SystemVerilogTools; 2 | 3 | #****************************************************************** 4 | # vim:tw=160:softtabstop=8:shiftwidth=8:cindent:syn=perl: 5 | #****************************************************************** 6 | # 7 | # SystemVerilogTools.pm 8 | # 9 | #****************************************************************** 10 | # 11 | # created on: 07/21/2012 12 | # created by: jwwebb 13 | # last edit on: $DateTime: $ 14 | # last edit by: $Author: $ 15 | # revision: $Revision: $ 16 | # comments: Generated 17 | # 18 | #****************************************************************** 19 | # Revision List: 20 | # 21 | # 1.0 07/21/2012 Initial release 22 | # 23 | #****************************************************************** 24 | # SystemVerilogTools 25 | # 26 | # This package is intended to parse and create SystemVerilog files. 27 | # 28 | #****************************************************************** 29 | 30 | use strict; 31 | use warnings; 32 | use diagnostics; 33 | use Exporter; 34 | use vars qw($VERSION @ISA @EXPORT ); # @EXPORT_OK %EXPORT_TAGS); 35 | 36 | $VERSION = '0.01'; 37 | @ISA = qw(Exporter); 38 | @EXPORT = qw( printModInst 39 | genTBTestFile 40 | genUCFFile 41 | genSVLowModule 42 | genSVTopModule ); 43 | #@EXPORT_OK = qw(&func1); 44 | #%EXPORT_TAGS = ( DEFAULT => [qw(&func1)], 45 | # Both => [qw(&func1 &func2)]); 46 | 47 | 48 | 49 | 1; 50 | 51 | sub getFile { 52 | #------------------------------------------------------------------------------ 53 | # Get SystemVerilog File: 54 | # 55 | # The sub-routine getFile() will open the SystemVerilog file 56 | # and read its contents into an array. It will also determine 57 | # the file length. The following parameters are created 58 | # 59 | # * filedata: @vdataA 60 | # * fileLen: scalar(@vdataA) 61 | # 62 | # Usage: $sv_rH = getFile(\%svH); 63 | # 64 | #------------------------------------------------------------------------------ 65 | my ($sv_rH) = shift; # Read in user's variable. 66 | my (%svH) = %{ $sv_rH }; # De-reference hash. 67 | my ($debug) = $svH{'debug'}; # Print out Debug Info. 68 | 69 | #------------------------------------------------------------------------------ 70 | # Open the SystemVerilog file, and read the results into an array 71 | # for manipulating the data array. Strip new lines and carriage returns from 72 | # remove string array, and initialize for loop variables. Close file when done. 73 | #------------------------------------------------------------------------------ 74 | open(inF, "<", $svH{ 'file' }) or dienice ("$svH{ 'file' } open failed"); 75 | my @svdataA = ; 76 | close(inF); 77 | 78 | # Strip newlines 79 | foreach my $i (@svdataA) { 80 | chomp($i); # Remove any \n line-feeds. 81 | $i =~ s/\r//g; # Remove any \r carriage-returns. 82 | } 83 | push (@{ $svH{ 'filedata' } }, @svdataA); 84 | 85 | #------------------------------------------------------------------------------ 86 | # Determine number of lines, and set beginning for loop index. 87 | #------------------------------------------------------------------------------ 88 | $svH{ 'fileLen' } = scalar(@{ $svH{ 'filedata' } }); # number of lines in Verilog file 89 | 90 | print("\n\n") if $debug; 91 | print("Total number of lines: $svH{ 'fileLen' }\n") if $debug; 92 | print("\n\n") if $debug; 93 | 94 | #------------------------------------------------------------------------------ 95 | # Return data to user 96 | #------------------------------------------------------------------------------ 97 | return \%svH; 98 | } 99 | 100 | sub parseFile { 101 | #------------------------------------------------------------------------------ 102 | # Parse SystemVerilog File: 103 | # 104 | # The sub-routine parseFile() will search through the 105 | # input SystemVerilog File and retrieve line numbers for 106 | # the following parameters: 107 | # 108 | # * modFound: 'module' 109 | # * pCFound: ');' 110 | # * paramFound: '#(' 111 | # * paramEndFound: ')' 112 | # * endModFound: 'endmodule' 113 | # 114 | # Usage: $sv_rH = parseFile(\%svH); 115 | # 116 | #------------------------------------------------------------------------------ 117 | my ($sv_rH) = shift; # Read in user's variable. 118 | my (%svH) = %{ $sv_rH }; # De-reference hash. 119 | my ($debug) = $svH{'debug'}; # Print out Debug Info. 120 | 121 | my ($modfound) = ""; 122 | my ($pcfound) = ""; 123 | my ($paramfound) = ""; 124 | my ($paramendfound) = ""; 125 | my ($endmodfound) = ""; 126 | 127 | #------------------------------------------------------------------------------ 128 | # Search through $file for keywords. 129 | #------------------------------------------------------------------------------ 130 | my $j = -1; 131 | for ($j=0; $j < $svH{ 'fileLen' }; $j++) { 132 | # Search for: 'module' 133 | if (${ $svH{ 'filedata' } }[$j] =~ m/^module/) { 134 | $modfound = $j; 135 | print("'module' Line Number: $modfound\n") if $debug; 136 | } 137 | # Search for: ');' 138 | if (($pcfound eq "") and (${ $svH{ 'filedata' } }[$j] =~ m/\x29\x3b/)) { 139 | $pcfound = $j; 140 | print("'\)\;' Line Number: $pcfound\n") if $debug; 141 | } 142 | # Search for: '#(' 143 | if (($paramfound eq "") and (${ $svH{ 'filedata' } }[$j] =~ m/\x23\x28/)) { 144 | $paramfound = $j; 145 | print("'\#\(' Line Number: $paramfound\n") if $debug; 146 | } 147 | # Search for: ')' 148 | if (($paramfound ne "") and ($paramendfound eq "") and (${ $svH{ 'filedata' } }[$j] =~ m/\x29/)) { 149 | $paramendfound = $j; 150 | print("'\)' Line Number: $paramendfound\n") if $debug; 151 | } 152 | # Search for: 'endmodule' 153 | if (${ $svH{ 'filedata' } }[$j] =~ m/^endmodule/) { 154 | $endmodfound = $j; 155 | print("'endmodule' Line Number: $endmodfound\n") if $debug; 156 | $j = $svH{ 'fileLen' }; 157 | } 158 | } 159 | 160 | $svH{ 'modFound' } = $modfound; 161 | $svH{ 'pCFound' } = $pcfound; 162 | $svH{ 'paramFound' } = $paramfound; 163 | $svH{ 'paramEndFound' } = $paramendfound; 164 | $svH{ 'endModFound' } = $endmodfound; 165 | 166 | #------------------------------------------------------------------------------ 167 | # Return data to user 168 | #------------------------------------------------------------------------------ 169 | return \%svH; 170 | } 171 | 172 | sub getModDecl { 173 | #------------------------------------------------------------------------------ 174 | # Get Module Declaration from SystemVerilog File: 175 | # 176 | # The sub-routine getModDecl() will search through the 177 | # input SystemVerilog File and extract the Module Declaration 178 | # into an array. Push the array into the Verilog Hash. 179 | # 180 | # * modFound: 'module' 181 | # * pCFound: ');' 182 | # * paramFound: '#(' 183 | # * paramEndFound: ')' 184 | # * endModFound: 'endmodule' 185 | # 186 | # Usage: $sv_rH = getModDecl($sv_rH); 187 | # 188 | #------------------------------------------------------------------------------ 189 | my ($sv_rH) = shift; # Read in user's variable. 190 | my (%svH) = %{ $sv_rH }; # De-reference hash. 191 | my ($debug) = $svH{'debug'}; # Print out Debug Info. 192 | 193 | #------------------------------------------------------------------------------ 194 | # Push contents between 'module' and ending paren '\)\;' into an array. 195 | #------------------------------------------------------------------------------ 196 | my ($k) = -1; 197 | my (@modDeclTmpA); 198 | my ($modFound) = $svH{ 'modFound' }; # "module" keyword found. 199 | my ($pCFound) = $svH{ 'pCFound' }; # ");" Parenthesis Found 200 | for ($k = $modFound; $k <= $pCFound; $k++) { 201 | push(@modDeclTmpA, ${ $svH{ 'filedata' } }[$k]); 202 | } 203 | 204 | #------------------------------------------------------------------------------ 205 | # Clear out trailing comments and indentation spaces and tabs. 206 | #------------------------------------------------------------------------------ 207 | foreach my $n (@modDeclTmpA) { 208 | $n =~ s/^.*?input/input/g; #strip spaces up to input. 209 | $n =~ s/^.*?output/output/g; #strip spaces up to output. 210 | $n =~ s/^.*?inout/inout/g; #strip spaces up to inout. 211 | $n =~ s/\x2f\x2f.*//; #strip any trailing //comment 212 | $n =~ s/\/\*.*\*\///; #strip embedded comments 213 | $n =~ s/.*\x29\x3b/\x29\x3b/; #strip spaces or tabs up to ");" 214 | #print("$n\n"); 215 | } 216 | 217 | #------------------------------------------------------------------------------ 218 | # Print out cleaned module declaration. 219 | #------------------------------------------------------------------------------ 220 | foreach my $m (@modDeclTmpA) { 221 | if ($m =~ m/\S+/) { 222 | push(@{ $svH{ 'modDecl' } }, $m); 223 | print("$m\n") if $debug; 224 | } 225 | } 226 | 227 | #------------------------------------------------------------------------------ 228 | # Return data to user 229 | #------------------------------------------------------------------------------ 230 | return \%svH; 231 | 232 | } 233 | 234 | sub getModName { 235 | #------------------------------------------------------------------------------ 236 | # Get Module Name from Module Declaration: 237 | # 238 | # The sub-routine getModName() will search through the 239 | # Module Declaration and extract the following information: 240 | # 241 | # * modName 242 | # * Parameterized: "yes" or "no" 243 | # 244 | # Usage: $sv_rH = getModName($sv_rH); 245 | # 246 | #------------------------------------------------------------------------------ 247 | my ($sv_rH) = shift; # Read in user's variable. 248 | my (%svH) = %{ $sv_rH }; # De-reference hash. 249 | my ($debug) = $svH{'debug'}; # Print out Debug Info. 250 | 251 | #------------------------------------------------------------------------------ 252 | # Strip off the Module name: 253 | #------------------------------------------------------------------------------ 254 | print("\n\n") if $debug; 255 | my ($crap1); 256 | my ($crap2); 257 | my ($modname); 258 | ($crap1, $modname, $crap2) = (${ $svH{ 'modDecl' } }[0] =~ /(\S+\s+)(\S+)(.*)/); 259 | $svH{ 'modName' } = $modname; 260 | print("Module Name: $svH{ 'modName' }\n") if $debug; 261 | 262 | if (($svH{ 'paramFound' } eq "") or ($svH{ 'paramFound' } > $svH{ 'pCFound' })) { 263 | $svH{ 'Parameterized' } = "no"; 264 | print("Is this a parameterizable module? $svH{ 'Parameterized' }\n") if $debug; 265 | } else { 266 | $svH{ 'Parameterized' } = "yes"; 267 | print("Is this a parameterizable module? $svH{ 'Parameterized' }\n") if $debug; 268 | } 269 | 270 | #------------------------------------------------------------------------------ 271 | # Return data to user 272 | #------------------------------------------------------------------------------ 273 | return \%svH; 274 | 275 | } 276 | 277 | sub getModIO { 278 | #------------------------------------------------------------------------------ 279 | # Get Module I/O from Module Declaration: 280 | # 281 | # The sub-routine getModIO() will search through the 282 | # Module Declaration and extract the input, inout, and 283 | # output signal names. The following paramters are created: 284 | # 285 | # * modIO 286 | # * modIn 287 | # * modOut 288 | # 289 | # Usage: $sv_rH = getModIO($sv_rH); 290 | # 291 | #------------------------------------------------------------------------------ 292 | my ($sv_rH) = shift; # Read in user's variable. 293 | my (%svH) = %{ $sv_rH }; # De-reference hash. 294 | my ($debug) = $svH{'debug'}; # Print out Debug Info. 295 | 296 | #------------------------------------------------------------------------------ 297 | # Get Module Declaration: 298 | # 299 | # * Store Module Declaration array in a temporary array. 300 | # * Determine the number of ports. 301 | # 302 | #------------------------------------------------------------------------------ 303 | my (@modDeclA) = @{ $svH{ 'modDecl' } }; # Module Decl for parsing ports. 304 | my (@paramA) = @{ $svH{ 'modDecl' } }; # Module Decl for parsing parameters. 305 | my ($modLen) = scalar(@modDeclA); 306 | 307 | #------------------------------------------------------------------------------ 308 | # Get Inputs, InOuts, and Outputs and store each in their respective arrays. 309 | #------------------------------------------------------------------------------ 310 | my ($line) = -1; 311 | my (@allportsonlyA); 312 | my ($allportsonlyA_Len); 313 | my (@allportsA); 314 | my ($allportsA_Len); 315 | 316 | # Push lines from the module declaration that match input, inout, or output into 317 | # an arrays: 318 | for ($line = 1; $line < ($modLen-1); $line++) { 319 | if ($modDeclA[$line] =~ m/\s*(input|output|inout).*/) { 320 | push(@allportsA, $modDeclA[$line]); 321 | } 322 | } 323 | 324 | $allportsA_Len = scalar(@allportsA); 325 | print("Port Length: $allportsA_Len\n") if $debug; 326 | 327 | @allportsonlyA = @allportsA; 328 | $allportsonlyA_Len = scalar(@allportsonlyA); 329 | print("Line Length: $allportsonlyA_Len\n") if $debug; 330 | 331 | # Strip off all information except the port name for all ports: 332 | foreach my $i (@allportsonlyA) { 333 | $i =~ s/\s*(input|output|inout)\s*//; 334 | $i =~ s/\s*signed\s*//; 335 | $i =~ s/\s*(logic|reg|wire)\s*//; 336 | $i =~ s/\s*\x5b.*\x5d\s*//; 337 | $i =~ s/\s+$//; 338 | $i =~ s/,//; 339 | print("$i\n") if ($debug); 340 | 341 | } 342 | for ($line = 1; $line < ($allportsA_Len-1); $line++) { 343 | print("Line: $allportsA[$line]\n") if $debug; 344 | print("Port: $allportsonlyA[$line]\n") if $debug; 345 | } 346 | 347 | #------------------------------------------------------------------------------ 348 | # Get Parameters and Values. Calculate width of each port. 349 | #------------------------------------------------------------------------------ 350 | my (%allportsHoH) = (); 351 | my ($param, $crap2, $paramval, $crap3); 352 | my (%paramHoH) = (); # Parameter Hash: param = paramval. 353 | my ($msb, $colon, $lsb); # MSB:LSB. 354 | my ($width); # Port Width. 355 | my ($tempLine); 356 | my ($direction); # Port Direction: input, inout, or output. 357 | my ($wrl); # Wire, Register, or Logic. 358 | if ($svH{ 'Parameterized' } =~ m/yes/) { 359 | foreach my $j (@paramA) { 360 | if ($j =~ m/parameter/) { 361 | $j =~ s/.*parameter\s+//; 362 | ($param, $crap2, $paramval, $crap3) = ($j =~ /(\S+)(\s+=\s+)(\S+)([,\x29].*)/); 363 | $paramHoH{ $param }{ 'parameter' } = $param; 364 | $paramHoH{ $param }{ 'value' } = $paramval; 365 | print("Parameter: $paramHoH{ $param }{ 'parameter' }\n") if $debug; 366 | print("Parameter Value: $paramHoH{ $param }{ 'value' }\n") if $debug; 367 | } 368 | } 369 | for ($line = 0; $line < ($allportsA_Len); $line++) { 370 | if ($allportsA[$line] =~ m/\x5b/) { 371 | # Determine port direction: 372 | if ($allportsA[$line] =~ m/input/) { 373 | $direction = "input"; 374 | } elsif ($allportsA[$line] =~ m/inout/) { 375 | $direction = "inout"; 376 | } elsif ($allportsA[$line] =~ m/output/) { 377 | $direction = "output"; 378 | } 379 | if ($allportsA[$line] =~ m/wire/) { 380 | $wrl = "wire"; 381 | } elsif ($allportsA[$line] =~ m/reg/) { 382 | $wrl = "reg"; 383 | } elsif ($allportsA[$line] =~ m/logic/) { 384 | $wrl = "logic"; 385 | } 386 | $tempLine = $allportsA[$line]; 387 | $tempLine =~ s/\s+/ /g; 388 | $tempLine =~ s/,//; 389 | $tempLine =~ s/\s+$//; 390 | $allportsA[$line] =~ s/.*\x5b//; 391 | $allportsA[$line] =~ s/\x5d.*//; 392 | ($msb, $colon, $lsb) = ($allportsA[$line] =~ /(\S+)(:)(\S+)/); 393 | #print("MSB: $msb, LSB: $lsb\n"); 394 | for my $key ( sort(keys %paramHoH) ) { 395 | #print("$key => $paramHoH{$key}{'value'}\n") if $debug; 396 | if ($msb =~ m/$paramHoH{$key}{'parameter'}/) { 397 | print("Key: $paramHoH{$key}{'parameter'}\n") if $debug; 398 | print("Value: $paramHoH{$key}{'value'}\n") if $debug; 399 | my $param_minus_1 = ($paramHoH{$key}{'value'}-1); 400 | if ($msb =~ /\x28/) { 401 | $msb =~ s/\x28$paramHoH{$key}{'parameter'}-1\x29/$param_minus_1/; 402 | } else { 403 | $msb =~ s/$paramHoH{$key}{'parameter'}-1/$param_minus_1/; 404 | } 405 | } 406 | } 407 | $width = ($msb+1); 408 | $allportsHoH{$allportsonlyA[$line]}{'port'} = $allportsonlyA[$line]; 409 | $allportsHoH{$allportsonlyA[$line]}{'width'} = $width; 410 | $allportsHoH{$allportsonlyA[$line]}{'direction'} = $direction; 411 | $allportsHoH{$allportsonlyA[$line]}{'wrl'} = $wrl; 412 | print("Line: $tempLine, MSB: $msb, LSB: $lsb, Width: $width, Direction: $direction\n") if $debug; 413 | } else { 414 | # Determine port direction: 415 | if ($allportsA[$line] =~ m/input/) { 416 | $direction = "input"; 417 | } elsif ($allportsA[$line] =~ m/inout/) { 418 | $direction = "inout"; 419 | } elsif ($allportsA[$line] =~ m/output/) { 420 | $direction = "output"; 421 | } 422 | if ($allportsA[$line] =~ m/wire/) { 423 | $wrl = "wire"; 424 | } elsif ($allportsA[$line] =~ m/reg/) { 425 | $wrl = "reg"; 426 | } elsif ($allportsA[$line] =~ m/logic/) { 427 | $wrl = "logic"; 428 | } 429 | $tempLine = $allportsA[$line]; 430 | $tempLine =~ s/\s+/ /g; 431 | $tempLine =~ s/,//; 432 | $tempLine =~ s/\s+$//; 433 | $width = 1; 434 | $allportsHoH{$allportsonlyA[$line]}{'port'} = $allportsonlyA[$line]; 435 | $allportsHoH{$allportsonlyA[$line]}{'width'} = $width; 436 | $allportsHoH{$allportsonlyA[$line]}{'direction'} = $direction; 437 | $allportsHoH{$allportsonlyA[$line]}{'wrl'} = $wrl; 438 | print("Line: $tempLine, Width: $width, Direction: $direction\n") if $debug; 439 | } 440 | } 441 | print("\n\n") if $debug; 442 | } else { 443 | for ($line = 0; $line < ($allportsA_Len); $line++) { 444 | if ($allportsA[$line] =~ m/\x5b/) { 445 | # Determine port direction: 446 | if ($allportsA[$line] =~ m/input/) { 447 | $direction = "input"; 448 | } elsif ($allportsA[$line] =~ m/inout/) { 449 | $direction = "inout"; 450 | } elsif ($allportsA[$line] =~ m/output/) { 451 | $direction = "output"; 452 | } 453 | if ($allportsA[$line] =~ m/wire/) { 454 | $wrl = "wire"; 455 | } elsif ($allportsA[$line] =~ m/reg/) { 456 | $wrl = "reg"; 457 | } elsif ($allportsA[$line] =~ m/logic/) { 458 | $wrl = "logic"; 459 | } 460 | $tempLine = $allportsA[$line]; 461 | $tempLine =~ s/(\s+)/ /; 462 | $tempLine =~ s/,//; 463 | $tempLine =~ s/\s+$//; 464 | $allportsA[$line] =~ s/.*\x5b//; 465 | $allportsA[$line] =~ s/\x5d.*//; 466 | ($msb, $colon, $lsb) = ($allportsA[$line] =~ /(\S+)(:)(\S+)/); 467 | $width = ($msb+1); 468 | $allportsHoH{$allportsonlyA[$line]}{'port'} = $allportsonlyA[$line]; 469 | $allportsHoH{$allportsonlyA[$line]}{'width'} = $width; 470 | $allportsHoH{$allportsonlyA[$line]}{'direction'} = $direction; 471 | $allportsHoH{$allportsonlyA[$line]}{'wrl'} = $wrl; 472 | print("Line: $tempLine, MSB: $msb, LSB: $lsb, Width: $width, Direction: $direction\n") if $debug; 473 | } else { 474 | # Determine port direction: 475 | if ($allportsA[$line] =~ m/input/) { 476 | $direction = "input"; 477 | } elsif ($allportsA[$line] =~ m/inout/) { 478 | $direction = "inout"; 479 | } elsif ($allportsA[$line] =~ m/output/) { 480 | $direction = "output"; 481 | } 482 | if ($allportsA[$line] =~ m/wire/) { 483 | $wrl = "wire"; 484 | } elsif ($allportsA[$line] =~ m/reg/) { 485 | $wrl = "reg"; 486 | } elsif ($allportsA[$line] =~ m/logic/) { 487 | $wrl = "logic"; 488 | } 489 | $tempLine = $allportsA[$line]; 490 | $tempLine =~ s/\s+/ /g; 491 | $tempLine =~ s/,//; 492 | $tempLine =~ s/\s+$//; 493 | $width = 1; 494 | $allportsHoH{$allportsonlyA[$line]}{'port'} = $allportsonlyA[$line]; 495 | $allportsHoH{$allportsonlyA[$line]}{'width'} = $width; 496 | $allportsHoH{$allportsonlyA[$line]}{'direction'} = $direction; 497 | $allportsHoH{$allportsonlyA[$line]}{'wrl'} = $wrl; 498 | print("Line: $tempLine, Width: $width, Direction: $direction\n") if $debug; 499 | } 500 | } 501 | print("\n\n") if $debug; 502 | } 503 | 504 | %{ $svH{ 'modParams' } } = %paramHoH; 505 | %{ $svH{ 'modIO' } } = %allportsHoH; 506 | 507 | #------------------------------------------------------------------------------ 508 | # Return data to user 509 | #------------------------------------------------------------------------------ 510 | return \%svH; 511 | 512 | } 513 | 514 | sub genModInst { 515 | #------------------------------------------------------------------------------ 516 | # Generate Module Instantiation: 517 | # 518 | # The sub-routine genModInst() will generate the SystemVerilog module 519 | # instantiation. An example module instantiation is shown below: 520 | # 521 | # freq_meas _freq_meas (.clk50mhz (clk50mhz), 522 | # .rst_n (rst_n), 523 | # .clk_in (clk_in), 524 | # .cnt_rm_ref_lmt (cnt_rm_ref_lmt), 525 | # .cnt_fm_ref_lmt (cnt_fm_ref_lmt), 526 | # .rm_d1_out (rm_d1_out), 527 | # .rm_d2_out (rm_d2_out), 528 | # .rm_done (rm_done), 529 | # .fm_d1_out (fm_d1_out), 530 | # .fm_d2_out (fm_d2_out), 531 | # .fm_done (fm_done)); 532 | # 533 | # Usage: $sv_rH = genModInst($sv_rH); 534 | # 535 | #------------------------------------------------------------------------------ 536 | my ($sv_rH) = shift; # Read in user's variable. 537 | my (%svH) = %{ $sv_rH }; # De-reference hash. 538 | my ($debug) = $svH{'debug'}; # Print out Debug Info. 539 | 540 | #------------------------------------------------------------------------------ 541 | # Get Module IO Ports Array: 542 | # 543 | # * Assign to temporary array. 544 | # * Determine number of IO Ports. 545 | # 546 | #------------------------------------------------------------------------------ 547 | # Copy the Parameter Hash to a local hash: 548 | my (%allportsHoH) = %{ $svH{ 'modIO' } }; 549 | my (@ioports) = (); 550 | my (@inports) = (); 551 | my (@outports) = (); 552 | # Push lines from the module declaration that match input, inout, or output into 553 | # their respective arrays: 554 | for my $key ( sort(keys %allportsHoH) ) { 555 | if ($allportsHoH{$key}{'direction'} =~ m/input/) { 556 | push(@inports, $allportsHoH{$key}{'port'}); 557 | } elsif ($allportsHoH{$key}{'direction'} =~ m/inout/) { 558 | push(@ioports, $allportsHoH{$key}{'port'}); 559 | } elsif ($allportsHoH{$key}{'direction'} =~ m/output/) { 560 | push(@outports, $allportsHoH{$key}{'port'}); 561 | } 562 | } 563 | my ($numioports) = scalar(@ioports); 564 | my ($numinports) = scalar(@inports); 565 | my ($numoutports) = scalar(@outports); 566 | print("Number of IO Ports: $numioports\n") if $debug; 567 | print("Number of In Ports: $numinports\n") if $debug; 568 | print("Number of Out Ports: $numoutports\n") if $debug; 569 | 570 | #------------------------------------------------------------------------------ 571 | # Get Module Name: 572 | #------------------------------------------------------------------------------ 573 | my ($modname) = $svH{ 'modName' }; 574 | 575 | if ( ($numinports eq 0) and ($numioports eq 0) and ($numoutports eq 0) ) { 576 | print("* Error: Cannot create instantiation of module '$modname'.\n Verify module uses an ANSI-C Type Module Declaration.\n"); 577 | exit; 578 | } else { 579 | 580 | #------------------------------------------------------------------------------ 581 | # Print out Module Instantiation: 582 | #------------------------------------------------------------------------------ 583 | my ($indent_spaces) = ""; 584 | my ($modinst) = ""; 585 | $modinst = "// *** Instantiate the $modname module ***\n"; 586 | if ($svH{ 'Parameterized' } =~ m/yes/) { 587 | #---------------------------------------------------------------------- 588 | # Assemble First Line of Instantiation: 589 | #---------------------------------------------------------------------- 590 | # Copy the Parameter Hash to a local hash: 591 | my (%paramHoH) = %{ $svH{ 'modParams' } }; 592 | # Determine number of parameters: 593 | my ($paramHoH_Size) = 0; 594 | $paramHoH_Size += scalar keys %paramHoH; # method 1: explicit scalar context 595 | print("Size of Hash: $paramHoH_Size\n") if $debug; 596 | # Start building up the first line of the instantiation: 597 | my ($modinst_line1) = "$modname #("; 598 | for my $key ( sort(keys %paramHoH) ) { 599 | print("Parameter Size Count: $paramHoH_Size\n") if $debug; 600 | if ($paramHoH_Size <= 1) { 601 | # If we're on the last parameter, 602 | # don't add a ", " (i.e., a comma followed by a space). 603 | $modinst_line1 .= ".$paramHoH{$key}{'parameter'}($paramHoH{$key}{'value'})"; 604 | } else { 605 | $modinst_line1 .= ".$paramHoH{$key}{'parameter'}($paramHoH{$key}{'value'}), "; 606 | } 607 | $paramHoH_Size -= 1; 608 | } 609 | $modinst_line1 .= ") _$modname"; 610 | $modinst_line1 = sprintf("$modinst_line1 ("); 611 | 612 | #---------------------------------------------------------------------- 613 | # Determine number of indent spaces: 614 | # 615 | # * Tab Space = 8 616 | # * Create string with correct numer of indent spaces. 617 | # 618 | #---------------------------------------------------------------------- 619 | my ($tmpinst_len) = length($modinst_line1); 620 | print("Number of Indent Spaces: $tmpinst_len\n") if $debug; 621 | my ($i) = 0; 622 | my (@indent); 623 | for ($i = 0; $i < $tmpinst_len; $i++) { 624 | push(@indent, " "); 625 | } 626 | $indent_spaces = join("",@indent); 627 | $modinst .= "$modinst_line1"; 628 | } else { 629 | #---------------------------------------------------------------------- 630 | # Assemble First Line of Instantiation: 631 | #---------------------------------------------------------------------- 632 | my ($modinst_line1) = "$modname _$modname ("; 633 | 634 | #---------------------------------------------------------------------- 635 | # Determine number of indent spaces: 636 | # 637 | # * Tab Space = 8 638 | # * Assemble first line of Module Instantiation. 639 | # * Create string with correct numer of indent spaces. 640 | # 641 | #---------------------------------------------------------------------- 642 | my ($tmpinst_len) = length($modinst_line1); 643 | print("Number of Indent Spaces: $tmpinst_len\n") if $debug; 644 | my ($i) = 0; 645 | my (@indent); 646 | for ($i = 0; $i < $tmpinst_len; $i++) { 647 | push(@indent, " "); 648 | } 649 | $indent_spaces = join("",@indent); 650 | $modinst .= "$modinst_line1"; 651 | } 652 | 653 | # Sort In,I/O,Out Array of Net Names Alphabetically: 654 | @inports = sort(@inports); 655 | @ioports = sort(@ioports); 656 | @outports = sort(@outports); 657 | 658 | # Create Clock Hash: 659 | my (%clkH); 660 | my (%clk_rH); 661 | 662 | # Find clock net(s): 663 | my (@clk_indexA) = (); 664 | my ($i) = 0; 665 | for ($i = 0; $i < $numinports; $i++) { 666 | if ($inports[$i] =~ m/clk/i) { 667 | print("Clk Index: $i\n") if $debug; 668 | push(@clk_indexA, $i); 669 | } 670 | } 671 | push (@{ $clkH{ 'clk_indexA' } }, @clk_indexA); 672 | 673 | # Find min clk_net index: 674 | my (@clk_index_sortedA) = (); 675 | @clk_index_sortedA = sort {$a <=> $b} @clk_indexA; 676 | print("Clock Net (minimum index): ") if $debug; 677 | if (defined $clk_index_sortedA[0]) { 678 | print("$clk_index_sortedA[0]\n") if $debug; 679 | } else { 680 | print("NA\n") if $debug; 681 | } 682 | my ($clk_len) = scalar(@clk_index_sortedA); 683 | print("Number of Clock Nets: $clk_len\n") if $debug; 684 | push (@{ $clkH{ 'clk_index_sortedA' } }, @clk_index_sortedA); 685 | $clkH{ 'clk_indexA_Len' } = $clk_len; 686 | $clkH{ 'debug' } = $debug; 687 | 688 | # Print out the "clock inputs" in the instantiation: 689 | my ($c) = 0; 690 | for ($c = 0; $c < $clk_len; $c++) { 691 | if ($c eq 0) { 692 | $modinst .= ".$inports[$clk_index_sortedA[$c]] ($inports[$clk_index_sortedA[$c]]),\n"; 693 | } else { 694 | $modinst .= "$indent_spaces.$inports[$clk_index_sortedA[$c]] ($inports[$clk_index_sortedA[$c]]),\n"; 695 | } 696 | } 697 | 698 | # Print out the remainder of the "inputs" in the instantiation: 699 | my ($j) = 0; 700 | for ($j = 0; $j < $numinports; $j++) { 701 | # Assign current index to clock hash: 702 | $clkH{ 'j' } = $j; 703 | 704 | # Check current index against all clock indices: 705 | if ((&checkClkIndex(\%clkH)) eq 0) { 706 | $modinst .= "$indent_spaces.$inports[$j] ($inports[$j]),\n"; 707 | } 708 | } 709 | 710 | # Print out the "inouts" in the instantiation: 711 | if ($numioports > 0) { 712 | $modinst .= "\n"; 713 | for ($j = 0; $j < $numioports; $j++) { 714 | $modinst .= "$indent_spaces.$ioports[$j] ($ioports[$j]),\n"; 715 | } 716 | } 717 | 718 | $modinst .= "\n"; 719 | 720 | # Print out the "outputs" in the instantiation: 721 | for ($j = 0; $j < $numoutports; $j++) { 722 | if ($j eq ($numoutports-1)) { 723 | $modinst .= "$indent_spaces.$outports[$j] ($outports[$j]));\n"; 724 | } else { 725 | $modinst .= "$indent_spaces.$outports[$j] ($outports[$j]),\n"; 726 | } 727 | } 728 | 729 | $svH{ 'modInst' } = $modinst; 730 | } 731 | 732 | 733 | #------------------------------------------------------------------------------ 734 | # Return data to user 735 | #------------------------------------------------------------------------------ 736 | return \%svH; 737 | 738 | } 739 | 740 | sub checkClkIndex { 741 | #------------------------------------------------------------------------------ 742 | # Check Input Port Index Against Clock Indices: 743 | # 744 | # The sub-routine checkClkIndex() will check the current input port index 745 | # against all identified clock indices. It will set a flag high if it matches, 746 | # or leave it low if no match has occured. 747 | # 748 | # 749 | # Usage: $clk_rH = checkClkIndex(\%clkH); 750 | # 751 | #------------------------------------------------------------------------------ 752 | my ($clk_rH) = shift; # Read in user's variable. 753 | 754 | my (%clkH) = %{ $clk_rH }; 755 | my $len = $clkH{ 'clk_indexA_Len'}; 756 | my $debug = $clkH{ 'debug' }; 757 | my $index = $clkH{ 'j' }; 758 | 759 | my (@clk_index_sortedA); 760 | push(@clk_index_sortedA, @{$clkH{ 'clk_index_sortedA' }}); 761 | 762 | print("Index: $index\n") if $debug; 763 | print("Clk Index Len: $len\n") if $debug; 764 | 765 | my ($cnt) = 0; 766 | my ($yes_or_no) = 0; # Default No 767 | my ($i) = 0; 768 | for ($i = 0; $i < $len; $i++) { 769 | if ($index eq $clk_index_sortedA[$i]) { 770 | $cnt += 1; 771 | print("Clk Index: $clk_index_sortedA[$i]\n") if $debug; 772 | } 773 | } 774 | if ($cnt > 0) { 775 | $yes_or_no = 1; 776 | } 777 | 778 | #------------------------------------------------------------------------------ 779 | # Return data to user 780 | #------------------------------------------------------------------------------ 781 | return $yes_or_no; 782 | } 783 | 784 | sub printModInst { 785 | #------------------------------------------------------------------------------ 786 | # Print Module Instantiation: 787 | # 788 | # The sub-routine printModInst() will print out the SystemVerilog module 789 | # instantiation. An example module instantiation is shown below: 790 | # 791 | # freq_meas _freq_meas (.clk50mhz (clk50mhz), 792 | # .rst_n (rst_n), 793 | # .clk_in (clk_in), 794 | # .cnt_rm_ref_lmt (cnt_rm_ref_lmt), 795 | # .cnt_fm_ref_lmt (cnt_fm_ref_lmt), 796 | # .rm_d1_out (rm_d1_out), 797 | # .rm_d2_out (rm_d2_out), 798 | # .rm_done (rm_done), 799 | # .fm_d1_out (fm_d1_out), 800 | # .fm_d2_out (fm_d2_out), 801 | # .fm_done (fm_done)); 802 | # 803 | # Usage: $sv_rH = printModInst($sv_rH); 804 | # 805 | #------------------------------------------------------------------------------ 806 | my ($sv_rH) = shift; # Read in user's variable. 807 | my (%svH) = %{ $sv_rH }; # De-reference hash. 808 | my ($debug) = $svH{'debug'}; # Print out Debug Info. 809 | 810 | #------------------------------------------------------------------------------ 811 | # Open $file and stuff it into an array. 812 | #------------------------------------------------------------------------------ 813 | $sv_rH = getFile($sv_rH); 814 | 815 | #------------------------------------------------------------------------------ 816 | # Search through $file for keywords. 817 | #------------------------------------------------------------------------------ 818 | $sv_rH = parseFile($sv_rH); 819 | 820 | #------------------------------------------------------------------------------ 821 | # Get Module Declaration: 822 | #------------------------------------------------------------------------------ 823 | $sv_rH = getModDecl($sv_rH); 824 | 825 | #------------------------------------------------------------------------------ 826 | # Get Module Name: 827 | #------------------------------------------------------------------------------ 828 | $sv_rH = getModName($sv_rH); 829 | 830 | #------------------------------------------------------------------------------ 831 | # Get Module I/O: 832 | #------------------------------------------------------------------------------ 833 | $sv_rH = getModIO($sv_rH); 834 | 835 | #------------------------------------------------------------------------------ 836 | # Generate Module Instantiation: 837 | #------------------------------------------------------------------------------ 838 | $sv_rH = genModInst($sv_rH); 839 | 840 | %svH = %{ $sv_rH }; # De-reference Verilog hash. 841 | 842 | my $modinst = $svH{ 'modInst' }; 843 | print("$modinst"); 844 | 845 | #------------------------------------------------------------------------------ 846 | # Return data to user 847 | #------------------------------------------------------------------------------ 848 | return \%svH; 849 | 850 | } 851 | 852 | sub genTBTop { 853 | #------------------------------------------------------------------------------ 854 | # Print Test Bench Top Module Header: 855 | # 856 | # The sub-routine genTBTop() will generate the SystemVerilog test bench top module. 857 | # 858 | # Usage: $sv_rH = genTBTop($sv_rH); 859 | # 860 | #------------------------------------------------------------------------------ 861 | my ($sv_rH) = shift; # Read in user's variable. 862 | 863 | my (%svH) = %{ $sv_rH }; # De-reference Verilog hash. 864 | 865 | my $file_sv = $svH{'file'}; 866 | my $tbTestFile = $svH{ 'tbTestFile' }; 867 | my $modinst = $svH{ 'modInst' }; 868 | my $day = $svH{'day'}; 869 | my $month = $svH{'month'}; 870 | my $username = $svH{'username'}; 871 | my $year = $svH{'year'}; 872 | my ($debug) = $svH{'debug'}; # Print out Debug Info. 873 | 874 | # Fix month, day, year: 875 | my $monthR = $month+1; 876 | my $yearR = $year+1900; 877 | 878 | # Get Filename: 879 | # strip .sv from filename 880 | my $file = $file_sv; 881 | $file =~ s/\x2esv//; 882 | $file =~ s/\x2e//g; 883 | $file =~ s/\x2f//g; 884 | my $tbTopFile = join ".","top","sv"; 885 | 886 | #------------------------------------------------------------------------------ 887 | # Generate Test Module Instantiation 888 | #------------------------------------------------------------------------------ 889 | #------------------------------------------------------------------------------ 890 | #------------------------------------------------------------------------------ 891 | # Get Module IO Ports Array: 892 | # 893 | # * Assign to temporary array. 894 | # * Determine number of IO Ports. 895 | # 896 | #------------------------------------------------------------------------------ 897 | # Copy the Parameter Hash to a local hash: 898 | my (%allportsHoH) = %{ $svH{ 'modIO' } }; 899 | my (@ioports) = (); 900 | my (@clkports) = (); 901 | my (@inports) = (); 902 | my (@outports) = (); 903 | # Push lines from the module declaration that match input, inout, or output into 904 | # their respective arrays: 905 | for my $key ( sort(keys %allportsHoH) ) { 906 | if ($allportsHoH{$key}{'direction'} =~ m/input/) { 907 | if ($allportsHoH{$key}{'port'} =~ m/(clk|clock|CLK)/) { 908 | push(@inports, $allportsHoH{$key}{'port'}); 909 | push(@clkports, $allportsHoH{$key}{'port'}); 910 | } else { 911 | push(@outports, $allportsHoH{$key}{'port'}); 912 | } 913 | } elsif ($allportsHoH{$key}{'direction'} =~ m/inout/) { 914 | push(@ioports, $allportsHoH{$key}{'port'}); 915 | } elsif ($allportsHoH{$key}{'direction'} =~ m/output/) { 916 | push(@inports, $allportsHoH{$key}{'port'}); 917 | } 918 | } 919 | my ($numioports) = scalar(@ioports); 920 | my ($numinports) = scalar(@inports); 921 | my ($numoutports) = scalar(@outports); 922 | print("Number of IO Ports: $numioports\n") if $debug; 923 | print("Number of In Ports: $numinports\n") if $debug; 924 | print("Number of Out Ports: $numoutports\n") if $debug; 925 | 926 | #------------------------------------------------------------------------------ 927 | # Get Module Name: 928 | #------------------------------------------------------------------------------ 929 | my ($modname) = $svH{ 'modName' }; 930 | my $test_modname = join "_", "test", $modname; 931 | 932 | #------------------------------------------------------------------------------ 933 | # Print out Module Instantiation: 934 | #------------------------------------------------------------------------------ 935 | my ($indent_spaces) = ""; 936 | my ($TestModInst) = ""; 937 | $TestModInst = "// ** Instantiate the Test module **\n"; 938 | # if ($svH{ 'Parameterized' } =~ m/yes/) { 939 | # #---------------------------------------------------------------------- 940 | # # Assemble First Line of Instantiation: 941 | # #---------------------------------------------------------------------- 942 | # # Copy the Parameter Hash to a local hash: 943 | # my (%paramHoH) = %{ $svH{ 'modParams' } }; 944 | # # Determine number of parameters: 945 | # my ($paramHoH_Size) = 0; 946 | # $paramHoH_Size += scalar keys %paramHoH; # method 1: explicit scalar context 947 | # print("Size of Hash: $paramHoH_Size\n") if $debug; 948 | # # Start building up the first line of the instantiation: 949 | # my ($modinst_line1) = "$modname #("; 950 | # for my $key ( keys %paramHoH ) { 951 | # print("Parameter Size Count: $paramHoH_Size\n") if $debug; 952 | # if ($paramHoH_Size <= 1) { 953 | # # If we're on the last parameter, 954 | # # don't add a ", " (i.e., a comma followed by a space). 955 | # $modinst_line1 .= ".$paramHoH{$key}{'parameter'}($paramHoH{$key}{'value'})"; 956 | # } else { 957 | # $modinst_line1 .= ".$paramHoH{$key}{'parameter'}($paramHoH{$key}{'value'}), "; 958 | # } 959 | # $paramHoH_Size -= 1; 960 | # } 961 | # $modinst_line1 .= ") test"; 962 | # $modinst_line1 = sprintf("$modinst_line1 ("); 963 | # 964 | # #---------------------------------------------------------------------- 965 | # # Determine number of indent spaces: 966 | # # 967 | # # * Tab Space = 8 968 | # # * Create string with correct numer of indent spaces. 969 | # # 970 | # #---------------------------------------------------------------------- 971 | # my ($tmpinst_len) = length($modinst_line1); 972 | # print("Number of Indent Spaces: $tmpinst_len\n") if $debug; 973 | # my ($i) = 0; 974 | # my (@indent); 975 | # for ($i = 0; $i < $tmpinst_len; $i++) { 976 | # push(@indent, " "); 977 | # } 978 | # $indent_spaces = join("",@indent); 979 | # $TestModInst .= "$modinst_line1"; 980 | # } else { 981 | #---------------------------------------------------------------------- 982 | # Assemble First Line of Instantiation: 983 | #---------------------------------------------------------------------- 984 | my ($modinst_line1) = "$test_modname test ("; 985 | 986 | #---------------------------------------------------------------------- 987 | # Determine number of indent spaces: 988 | # 989 | # * Tab Space = 8 990 | # * Assemble first line of Module Instantiation. 991 | # * Create string with correct numer of indent spaces. 992 | # 993 | #---------------------------------------------------------------------- 994 | my ($tmpinst_len) = length($modinst_line1); 995 | print("Number of Indent Spaces: $tmpinst_len\n") if $debug; 996 | my ($i) = 0; 997 | my (@indent); 998 | for ($i = 0; $i < $tmpinst_len; $i++) { 999 | push(@indent, " "); 1000 | } 1001 | $indent_spaces = join("",@indent); 1002 | $TestModInst .= "$modinst_line1"; 1003 | # } 1004 | 1005 | # Sort In,I/O,Out Array of Net Names Alphabetically: 1006 | @inports = sort(@inports); 1007 | @ioports = sort(@ioports); 1008 | @outports = sort(@outports); 1009 | 1010 | # Create Clock Hash: 1011 | my (%clkH); 1012 | my (%clk_rH); 1013 | 1014 | # Find clock net(s): 1015 | my (@clk_indexA) = (); 1016 | my ($u) = 0; 1017 | for ($u = 0; $u < $numinports; $u++) { 1018 | if ($inports[$u] =~ m/clk/i) { 1019 | print("Clk Index: $u\n") if $debug; 1020 | push(@clk_indexA, $u); 1021 | } 1022 | } 1023 | push (@{ $clkH{ 'clk_indexA' } }, @clk_indexA); 1024 | 1025 | # Find min clk_net index: 1026 | my (@clk_index_sortedA) = (); 1027 | @clk_index_sortedA = sort {$a <=> $b} @clk_indexA; 1028 | print("Clock Net (minimum index): ") if $debug; 1029 | if (defined $clk_index_sortedA[0]) { 1030 | print("$clk_index_sortedA[0]\n") if $debug; 1031 | } else { 1032 | print("NA\n") if $debug; 1033 | } 1034 | my ($clk_len) = scalar(@clk_index_sortedA); 1035 | print("Number of Clock Nets: $clk_len\n") if $debug; 1036 | push (@{ $clkH{ 'clk_index_sortedA' } }, @clk_index_sortedA); 1037 | $clkH{ 'clk_indexA_Len' } = $clk_len; 1038 | $clkH{ 'debug' } = $debug; 1039 | 1040 | # Print out the "clock inputs" in the instantiation: 1041 | my ($c) = 0; 1042 | for ($c = 0; $c < $clk_len; $c++) { 1043 | if ($c eq 0) { 1044 | $TestModInst .= ".$inports[$clk_index_sortedA[$c]] ($inports[$clk_index_sortedA[$c]]),\n"; 1045 | } else { 1046 | $TestModInst .= "$indent_spaces.$inports[$clk_index_sortedA[$c]] ($inports[$clk_index_sortedA[$c]]),\n"; 1047 | } 1048 | } 1049 | 1050 | # Print out the remainder of the "inputs" in the instantiation: 1051 | my ($v) = 0; 1052 | for ($v = 0; $v < $numinports; $v++) { 1053 | # Assign current index to clock hash: 1054 | $clkH{ 'j' } = $v; 1055 | 1056 | # Check current index against all clock indices: 1057 | if ((&checkClkIndex(\%clkH)) eq 0) { 1058 | $TestModInst .= "$indent_spaces.$inports[$v] ($inports[$v]),\n"; 1059 | } 1060 | } 1061 | 1062 | # Print out the "inouts" in the instantiation: 1063 | if ($numioports > 0) { 1064 | $TestModInst .= "\n"; 1065 | for ($v = 0; $v < $numioports; $v++) { 1066 | $TestModInst .= "$indent_spaces.$ioports[$v] ($ioports[$v]),\n"; 1067 | } 1068 | } 1069 | $TestModInst .= "\n"; 1070 | # Print out the "outputs" in the instantiation: 1071 | for ($v = 0; $v < $numoutports; $v++) { 1072 | if ($v eq ($numoutports-1)) { 1073 | $TestModInst .= "$indent_spaces.$outports[$v] ($outports[$v]));\n"; 1074 | } else { 1075 | $TestModInst .= "$indent_spaces.$outports[$v] ($outports[$v]),\n"; 1076 | } 1077 | } 1078 | 1079 | $svH{ 'TestModInst' } = $TestModInst; 1080 | 1081 | #------------------------------------------------------------------------------ 1082 | # Generate: Clocks 1083 | #------------------------------------------------------------------------------ 1084 | my ($clkgen1) = ""; 1085 | my ($clkgen2) = ""; 1086 | 1087 | foreach my $i (@clkports) { 1088 | $clkgen1 .= " $i <= 1'b1;\n"; 1089 | $clkgen2 .= "always #4 $i <= ~$i;\n"; 1090 | } 1091 | 1092 | $clkgen1 =~ s/\n$//; 1093 | $clkgen2 =~ s/\n$//; 1094 | 1095 | #------------------------------------------------------------------------------ 1096 | # Generate the Input portion of the Module Declarations: 1097 | #------------------------------------------------------------------------------ 1098 | #my (%allportsHoH) = %{ $svH{ 'modIO' } }; 1099 | my (@iolines) = (); 1100 | my (@inlines) = (); 1101 | my (@outlines) = (); 1102 | my ($msb) = 0; 1103 | my ($lsb) = 0; 1104 | my ($templine) = ""; 1105 | # Push lines from the module declaration that match input, inout, or output into 1106 | # their respective arrays: 1107 | for my $key ( sort(keys %allportsHoH) ) { 1108 | if ($allportsHoH{$key}{'port'} =~ m/(clk|clock|CLK)/) { 1109 | $templine = "logic $allportsHoH{$key}{'port'};\n"; 1110 | push(@inlines, $templine); 1111 | print("Clock: $templine\n") if $debug; 1112 | } 1113 | } 1114 | 1115 | for my $key ( sort(keys %allportsHoH) ) { 1116 | if ($allportsHoH{$key}{'direction'} eq "input") { 1117 | if ($allportsHoH{$key}{'width'} > 1) { 1118 | $msb = $allportsHoH{$key}{'width'}; 1119 | $msb -= 1; 1120 | $templine = "logic [$msb:$lsb] $allportsHoH{$key}{'port'};\n"; 1121 | push(@inlines, $templine); 1122 | print("Input: $templine\n") if $debug; 1123 | } elsif(($allportsHoH{$key}{'width'} == 1) and !($allportsHoH{$key}{'port'} =~ m/(clk|clock|CLK)/)) { 1124 | $templine = "logic $allportsHoH{$key}{'port'};\n"; 1125 | push(@inlines, $templine); 1126 | print("Input: $templine\n") if $debug; 1127 | } 1128 | } 1129 | } 1130 | 1131 | for my $key ( sort(keys %allportsHoH) ) { 1132 | if ($allportsHoH{$key}{'direction'} eq "inout") { 1133 | if ($allportsHoH{$key}{'width'} > 1) { 1134 | $msb = $allportsHoH{$key}{'width'}; 1135 | $msb -= 1; 1136 | $templine = "wire [$msb:$lsb] $allportsHoH{$key}{'port'};\n"; 1137 | push(@iolines, $templine); 1138 | print("InOut: $templine\n") if $debug; 1139 | } else { 1140 | $templine = "wire $allportsHoH{$key}{'port'};\n"; 1141 | push(@iolines, $templine); 1142 | print("InOut: $templine\n") if $debug; 1143 | } 1144 | } 1145 | } 1146 | 1147 | for my $key ( sort(keys %allportsHoH) ) { 1148 | if ($allportsHoH{$key}{'direction'} eq "output") { 1149 | if ($allportsHoH{$key}{'width'} > 1) { 1150 | $msb = $allportsHoH{$key}{'width'}; 1151 | $msb -= 1; 1152 | $templine = "logic [$msb:$lsb] $allportsHoH{$key}{'port'};\n"; 1153 | push(@outlines, $templine); 1154 | print("Output: $templine\n") if $debug; 1155 | } else { 1156 | $templine = "logic $allportsHoH{$key}{'port'};\n"; 1157 | push(@outlines, $templine); 1158 | print("Output: $templine\n") if $debug; 1159 | } 1160 | } 1161 | } 1162 | 1163 | my ($inDecl) = join("",@inlines); 1164 | my ($ioDecl) = join("",@iolines); 1165 | my ($outDecl) = join("",@outlines); 1166 | 1167 | print("\n\nInput Declarations: \n$inDecl") if $debug; 1168 | print("InOut Declarations: \n$ioDecl") if $debug; 1169 | print("Output Declarations: \n$outDecl\n") if $debug; 1170 | 1171 | #------------------------------------------------------------------------------ 1172 | # Build up Top-Level Test Bench File. 1173 | #------------------------------------------------------------------------------ 1174 | my $tbTopBody=<<"EOF"; 1175 | /****************************************************************************** 1176 | vim:tw=160:softtabstop=4:shiftwidth=4:et:syn=verilog: 1177 | ******************************************************************************* 1178 | 1179 | $tbTopFile module 1180 | 1181 | ******************************************************************************* 1182 | 1183 | COMPANY Confidential Copyright � $yearR 1184 | 1185 | ******************************************************************************* 1186 | 1187 | created on: $monthR/$day/$yearR 1188 | created by: $username 1189 | last edit on: \$DateTime: \$ 1190 | last edit by: \$Author: \$ 1191 | revision: \$Revision: \$ 1192 | comments: Generated 1193 | 1194 | ******************************************************************************* 1195 | //Project// (//Number//) 1196 | 1197 | This module tests the $file_sv module. 1198 | 1199 | ******************************************************************************/ 1200 | `include "../../../$file_sv" 1201 | `include "$tbTestFile" 1202 | `timescale 1ns/1ps 1203 | 1204 | module top; // top-level netlist to connect testbench to dut 1205 | 1206 | timeunit 1ns; timeprecision 1ps; 1207 | 1208 | // *** Input to UUT *** 1209 | $inDecl 1210 | // *** Inouts to UUT *** 1211 | $ioDecl 1212 | // *** Outputs from UUT *** 1213 | $outDecl 1214 | 1215 | $modinst 1216 | 1217 | $TestModInst 1218 | 1219 | 1220 | // clk generators 1221 | initial begin 1222 | $clkgen1 1223 | end 1224 | 1225 | // Generate clock: 1226 | $clkgen2 1227 | 1228 | 1229 | endmodule : top 1230 | 1231 | 1232 | EOF 1233 | 1234 | $svH{ 'tbTopFile' } = $tbTopFile; 1235 | $svH{ 'tbTopBody' } = $tbTopBody; 1236 | 1237 | #------------------------------------------------------------------------------ 1238 | # Return data to user 1239 | #------------------------------------------------------------------------------ 1240 | return \%svH; 1241 | 1242 | } 1243 | 1244 | sub genTBTestHeader { 1245 | #------------------------------------------------------------------------------ 1246 | # Print Test Bench Module Header: 1247 | # 1248 | # The sub-routine printTBHeader() will print out the SystemVerilog test bench 1249 | # module instantiation. 1250 | # 1251 | # Usage: $sv_rH = printTBHeader($sv_rH); 1252 | # 1253 | #------------------------------------------------------------------------------ 1254 | my ($sv_rH) = shift; # Read in user's variable. 1255 | my (%svH) = %{ $sv_rH }; # De-reference hash. 1256 | my $file_sv = $svH{'file'}; 1257 | my $day = $svH{'day'}; 1258 | my $month = $svH{'month'}; 1259 | my $username = $svH{'username'}; 1260 | my $year = $svH{'year'}; 1261 | my ($debug) = $svH{'debug'}; # Print out Debug Info. 1262 | 1263 | # Fix month, day, year: 1264 | my $monthR = $month+1; 1265 | my $yearR = $year+1900; 1266 | 1267 | # Get Filename: 1268 | # strip .v from filename 1269 | my $file = $file_sv; 1270 | $file =~ s/\x2esv//; 1271 | $file =~ s/\x2e//g; 1272 | $file =~ s/\x2f//g; 1273 | my $test_file = join "_", "test", $file; 1274 | my $tbTestFile = join ".",$test_file,"sv"; 1275 | 1276 | my $tbTestHead=<<"EOF"; 1277 | /****************************************************************************** 1278 | vim:tw=160:softtabstop=4:shiftwidth=4:et:syn=verilog: 1279 | ******************************************************************************* 1280 | 1281 | $tbTestFile module 1282 | 1283 | ******************************************************************************* 1284 | 1285 | COMPANY Confidential Copyright � $yearR 1286 | 1287 | ******************************************************************************* 1288 | 1289 | created on: $monthR/$day/$yearR 1290 | created by: $username 1291 | last edit on: \$DateTime: \$ 1292 | last edit by: \$Author: \$ 1293 | revision: \$Revision: \$ 1294 | comments: Generated 1295 | 1296 | ******************************************************************************* 1297 | //Project// (//Number//) 1298 | 1299 | This module implements the test bench for the $file_sv module. 1300 | 1301 | // enter detailed description here; 1302 | 1303 | 1304 | ******************************************************************************/ 1305 | `timescale 1ns/1ps 1306 | 1307 | 1308 | EOF 1309 | 1310 | $svH{ 'tbTestFile' } = $tbTestFile; 1311 | $svH{ 'tbTestHead' } = $tbTestHead; 1312 | 1313 | #------------------------------------------------------------------------------ 1314 | # 1315 | # Return data to user 1316 | # 1317 | #------------------------------------------------------------------------------ 1318 | return \%svH; 1319 | 1320 | } 1321 | 1322 | sub genTBTestBody { 1323 | #------------------------------------------------------------------------------ 1324 | # Print Test Bench Module Body: 1325 | # 1326 | # The sub-routine printTBBody() will print out the body of the SystemVerilog 1327 | # module test bench. 1328 | # 1329 | # Usage: $sv_rH = printTBBody($sv_rH); 1330 | # 1331 | #------------------------------------------------------------------------------ 1332 | my ($sv_rH) = shift; # Read in user's variable. 1333 | my (%svH) = %{ $sv_rH }; # De-reference hash. 1334 | my $modname = $svH{ 'modName' }; 1335 | my $test_modname = join "_", "test", $modname; 1336 | my ($debug) = $svH{'debug'}; # Print out Debug Info. 1337 | 1338 | #---------------------------------------------------------------------- 1339 | # Determine number of indent spaces: 1340 | # 1341 | # * Tab Space = 8 1342 | # * Create string with correct numer of indent spaces. 1343 | # 1344 | #---------------------------------------------------------------------- 1345 | my ($indent_spaces) = ""; 1346 | my ($modinst_line1) = "module $test_modname (/"; 1347 | my ($tmpinst_len) = length($modinst_line1); 1348 | print("Number of Indent Spaces: $tmpinst_len\n") if $debug; 1349 | my ($i) = 0; 1350 | my (@indent); 1351 | for ($i = 0; $i < $tmpinst_len; $i++) { 1352 | push(@indent, " "); 1353 | } 1354 | $indent_spaces = join("",@indent); 1355 | $indent_spaces =~ s/ //; 1356 | my $indentCparen = $indent_spaces; 1357 | $indentCparen =~ s/ //; 1358 | 1359 | #------------------------------------------------------------------------------ 1360 | # Generate the Input portion of the Module Declarations: 1361 | #------------------------------------------------------------------------------ 1362 | my (%allportsHoH) = %{ $svH{ 'modIO' } }; 1363 | my (@iolines) = (); 1364 | my (@inlines) = (); 1365 | my (@outlines) = (); 1366 | my ($msb) = 0; 1367 | my ($lsb) = 0; 1368 | my ($templine) = ""; 1369 | # Push lines from the module declaration that match input, inout, or output into 1370 | # their respective arrays: 1371 | for my $key ( sort(keys %allportsHoH) ) { 1372 | if ($allportsHoH{$key}{'port'} =~ m/(clk|clock|CLK)/) { 1373 | $templine = "$indent_spaces input logic $allportsHoH{$key}{'port'},\n"; 1374 | push(@inlines, $templine); 1375 | print("Clock: $templine\n") if $debug; 1376 | } 1377 | } 1378 | 1379 | for my $key ( sort(keys %allportsHoH) ) { 1380 | if ($allportsHoH{$key}{'direction'} eq "input") { 1381 | if ($allportsHoH{$key}{'width'} > 1) { 1382 | $msb = $allportsHoH{$key}{'width'}; 1383 | $msb -= 1; 1384 | $templine = "$indent_spaces output logic [$msb:$lsb] $allportsHoH{$key}{'port'},\n"; 1385 | push(@outlines, $templine); 1386 | print("Input: $templine\n") if $debug; 1387 | } elsif(($allportsHoH{$key}{'width'} == 1) and !($allportsHoH{$key}{'port'} =~ m/(clk|clock|CLK)/)) { 1388 | $templine = "$indent_spaces output logic $allportsHoH{$key}{'port'},\n"; 1389 | push(@outlines, $templine); 1390 | print("Input: $templine\n") if $debug; 1391 | } 1392 | } 1393 | } 1394 | 1395 | for my $key ( sort(keys %allportsHoH) ) { 1396 | if ($allportsHoH{$key}{'direction'} eq "inout") { 1397 | if ($allportsHoH{$key}{'width'} > 1) { 1398 | $msb = $allportsHoH{$key}{'width'}; 1399 | $msb -= 1; 1400 | $templine = "$indent_spaces inout wire [$msb:$lsb] $allportsHoH{$key}{'port'},\n"; 1401 | push(@iolines, $templine); 1402 | print("InOut: $templine\n") if $debug; 1403 | } else { 1404 | $templine = "$indent_spaces inout wire $allportsHoH{$key}{'port'},\n"; 1405 | push(@iolines, $templine); 1406 | print("InOut: $templine\n") if $debug; 1407 | } 1408 | } 1409 | } 1410 | 1411 | for my $key ( sort(keys %allportsHoH) ) { 1412 | if ($allportsHoH{$key}{'direction'} eq "output") { 1413 | if ($allportsHoH{$key}{'width'} > 1) { 1414 | $msb = $allportsHoH{$key}{'width'}; 1415 | $msb -= 1; 1416 | $templine = "$indent_spaces input logic [$msb:$lsb] $allportsHoH{$key}{'port'},\n"; 1417 | push(@inlines, $templine); 1418 | print("Output: $templine\n") if $debug; 1419 | } else { 1420 | $templine = "$indent_spaces input logic $allportsHoH{$key}{'port'},\n"; 1421 | push(@inlines, $templine); 1422 | print("Output: $templine\n") if $debug; 1423 | } 1424 | } 1425 | } 1426 | 1427 | my ($inDecl) = join("",@inlines); 1428 | my ($ioDecl) = join("",@iolines); 1429 | my ($outDecl) = join("",@outlines); 1430 | $outDecl =~ s/,\n$//; 1431 | 1432 | print("\n\nInput Declarations: \n$inDecl") if $debug; 1433 | print("InOut Declarations: \n$ioDecl") if $debug; 1434 | print("Output Declarations: \n$outDecl\n") if $debug; 1435 | 1436 | #------------------------------------------------------------------------------ 1437 | # Build up Test Bench Module Body: 1438 | #------------------------------------------------------------------------------ 1439 | my $tbTestBody=<<"EOF"; 1440 | module $test_modname (//** Inputs ** 1441 | $inDecl 1442 | $indent_spaces //** InOuts ** 1443 | $ioDecl 1444 | $indent_spaces //** Outputs ** 1445 | $outDecl 1446 | $indentCparen ); 1447 | 1448 | // *** Local Variable Declarations *** 1449 | // Local Parameter Declarations: 1450 | // N/A 1451 | // Local Logic Declarations: 1452 | // N/A 1453 | // Local Event Declarations: 1454 | event start_Monitor; 1455 | 1456 | // *** Local Integer Declarations *** 1457 | integer results_file; // for writing signal values 1458 | 1459 | // initial block 1460 | initial 1461 | begin 1462 | #1; 1463 | \$timeformat(-9, 0, " ns", 9); 1464 | 1465 | /*************************************************************************/ 1466 | /** 1467 | Open results file, write header: 1468 | 1469 | 1. Setup top-level results file. 1470 | 1471 | **************************************************************************/ 1472 | // open results file, write header 1473 | results_file=\$fopen("../out/top_results.txt"); 1474 | \$fdisplay(results_file, " $test_modname testbench results"); 1475 | \$fwrite(results_file, "\\n"); 1476 | DisplayHeader; 1477 | 1478 | /*************************************************************************/ 1479 | /** 1480 | Initialize signals: 1481 | 1482 | 1. Set Default Variables 1483 | 2. Force registers to safe state 1484 | 1485 | **************************************************************************/ 1486 | // initialize signals 1487 | \$display("Initialize Signals"); 1488 | rst <= 0; 1489 | 1490 | VarClockDelay(.delay(100)); 1491 | ->start_Monitor; //trigger routine to monitor 1492 | CpuReset; 1493 | 1494 | // Add more test bench stuff here 1495 | 1496 | \$fclose(results_file); 1497 | \$stop; 1498 | end 1499 | 1500 | // Add more test bench stuff here as well 1501 | always 1502 | begin: Monitor 1503 | \$timeformat(-9, 0, " ns", 9); 1504 | \@(start_Monitor) 1505 | forever @(negedge clk) 1506 | begin 1507 | \$fstrobe(results_file,"At \%%t: \\t\%%h\\t\%%h",\$realtime, data_in, data_out); 1508 | end 1509 | end 1510 | 1511 | 1512 | // Test Bench Tasks 1513 | task DisplayHeader; 1514 | \$fdisplay(results_file," data_in data_out "); 1515 | \$fdisplay(results_file," ============================"); 1516 | endtask 1517 | 1518 | /****************************************************************************/ 1519 | /** 1520 | * CpuReset - Perform a board level reset. 1521 | * 1522 | * \@param none 1523 | * 1524 | * \@return none 1525 | * 1526 | * \@note 1527 | * 1528 | *****************************************************************************/ 1529 | task CpuReset; 1530 | begin 1531 | \$display("Perform a Reset"); 1532 | \@ (posedge clk); 1533 | \$display("Set Reset High"); 1534 | rst = 1; 1535 | \@ (posedge clk); 1536 | \$display("Wait for 10 clock cycles"); 1537 | repeat(10) @ (posedge clk); 1538 | \$display("Set Reset Low"); 1539 | rst = 0; 1540 | \@ (posedge clk); 1541 | end 1542 | endtask 1543 | 1544 | 1545 | /****************************************************************************/ 1546 | /** 1547 | * VarClockDelay - Variable delay block in increments of clk. 1548 | * 1549 | * \@param delay - Number of Clock Cyles to Insert. 1550 | * 1551 | * \@return none 1552 | * 1553 | * \@note 1554 | * 1555 | * This task allows delay to be added between test bench code without 1556 | * ending on a non-integer multiple of the clock. 1557 | * 1558 | *****************************************************************************/ 1559 | task VarClockDelay (input int delay); 1560 | string delay_str; 1561 | begin 1562 | delay_str.itoa(delay); 1563 | \$display("Wait for \%%s clock cycles", delay_str); 1564 | for(int i=0; i < delay; i++) 1565 | begin 1566 | \@ (posedge clk); 1567 | end 1568 | end 1569 | endtask 1570 | 1571 | endmodule : $test_modname 1572 | 1573 | EOF 1574 | 1575 | $svH{ 'tbmodName' } = $test_modname; 1576 | $svH{ 'tbTestBody' } = $tbTestBody; 1577 | 1578 | #------------------------------------------------------------------------------ 1579 | # Return data to user 1580 | #------------------------------------------------------------------------------ 1581 | return \%svH; 1582 | 1583 | } 1584 | 1585 | sub genTBTestFile { 1586 | #------------------------------------------------------------------------------ 1587 | # Generate the SystemVerilog Test Bench: 1588 | # 1589 | # The sub-routine genTBTestFile() will generate a set of Test Bench 1590 | # files based on the SystemVerilog module provided by the user. For 1591 | # example, if the user provides a SystemVerilog module called 'mymodule' 1592 | # then the following files will be generated: 1593 | # 1594 | # - top.sv 1595 | # - test_mymodule.sv 1596 | # 1597 | # The file 'top.sv' instantiates both the UUT (mymodule.sv) and the 1598 | # Test Bench (test_mymodule.sv). All nets labeled with either 'clk' or 1599 | # 'clock' will be generated using an always block in the following form: 1600 | # 1601 | # // clk generators 1602 | # initial begin 1603 | # clk <= 1'b1; 1604 | # end 1605 | # 1606 | # // Generate clock: 1607 | # always #4 clk <= ~clk; 1608 | # 1609 | # All nets in the 'mymodule.sv' file are declared in the top.v file. 1610 | # 1611 | # The file 'test_mymodule.sv' contains the same number of i/o as 1612 | # 'mymodule.sv' with inputs and outputs swapped, except for clock 1613 | # signals. 1614 | # 1615 | # Usage: $sv_rH = genTBTestFile(\%svH); 1616 | # 1617 | #------------------------------------------------------------------------------ 1618 | my ($sv_rH) = shift; # Read in user's variable. 1619 | my (%svH) = %{ $sv_rH }; # De-reference hash. 1620 | my ($debug) = $svH{'debug'}; # Print out Debug Info. 1621 | 1622 | #------------------------------------------------------------------------------ 1623 | # Open $file and stuff it into an array. 1624 | #------------------------------------------------------------------------------ 1625 | $sv_rH = getFile($sv_rH); 1626 | 1627 | #------------------------------------------------------------------------------ 1628 | # Search through $file for keywords. 1629 | #------------------------------------------------------------------------------ 1630 | $sv_rH = parseFile($sv_rH); 1631 | 1632 | #------------------------------------------------------------------------------ 1633 | # Get Module Declaration: 1634 | #------------------------------------------------------------------------------ 1635 | $sv_rH = getModDecl($sv_rH); 1636 | 1637 | #------------------------------------------------------------------------------ 1638 | # Get Module Name: 1639 | #------------------------------------------------------------------------------ 1640 | $sv_rH = getModName($sv_rH); 1641 | 1642 | #------------------------------------------------------------------------------ 1643 | # Get Module I/O: 1644 | #------------------------------------------------------------------------------ 1645 | $sv_rH = getModIO($sv_rH); 1646 | 1647 | #------------------------------------------------------------------------------ 1648 | # Generate Module Instantiation: 1649 | #------------------------------------------------------------------------------ 1650 | $sv_rH = genModInst($sv_rH); 1651 | 1652 | #------------------------------------------------------------------------------ 1653 | # Generate Header and Body of Test Bench File 1654 | #------------------------------------------------------------------------------ 1655 | $sv_rH = genTBTestHeader($sv_rH); 1656 | $sv_rH = genTBTestBody($sv_rH); 1657 | $sv_rH = genTBTop($sv_rH); 1658 | %svH = %{ $sv_rH }; # De-reference Verilog hash. 1659 | 1660 | #------------------------------------------------------------------------------ 1661 | # Get Filename, Header and Body of UCF File 1662 | #------------------------------------------------------------------------------ 1663 | my $tbTestFile = $svH{ 'tbTestFile' }; 1664 | my $tbTestHead = $svH{ 'tbTestHead' };; 1665 | my $tbTestBody = $svH{ 'tbTestBody' };; 1666 | my $tbTopFile = $svH{ 'tbTopFile' }; 1667 | my $tbTopBody = $svH{ 'tbTopBody' };; 1668 | 1669 | 1670 | #------------------------------------------------------------------------------ 1671 | # Create File Handle for the new UCF file, and check for existing file. 1672 | #------------------------------------------------------------------------------ 1673 | open(outF, ">", $tbTestFile) or dienice ("$tbTestFile open failed"); 1674 | 1675 | #------------------------------------------------------------------------------ 1676 | # Print Header and Body to UCF File Handle 1677 | #------------------------------------------------------------------------------ 1678 | printf(outF "$tbTestHead"); 1679 | printf(outF "$tbTestBody"); 1680 | printf(outF "\n\n"); 1681 | 1682 | close(outF); 1683 | 1684 | #------------------------------------------------------------------------------ 1685 | # Create File Handle for the new UCF file, and check for existing file. 1686 | #------------------------------------------------------------------------------ 1687 | open(out2F, ">", $tbTopFile) or dienice ("$tbTopFile open failed"); 1688 | 1689 | #------------------------------------------------------------------------------ 1690 | # Print Header and Body to UCF File Handle 1691 | #------------------------------------------------------------------------------ 1692 | printf(out2F "$tbTopBody"); 1693 | printf(out2F "\n\n"); 1694 | 1695 | close(out2F); 1696 | 1697 | print("\n"); 1698 | print("Test Bench File(s): $tbTestFile and $tbTopFile are ready for use.\n"); 1699 | print("\n"); 1700 | 1701 | #------------------------------------------------------------------------------ 1702 | # Return data to user 1703 | #------------------------------------------------------------------------------ 1704 | return \%svH; 1705 | } 1706 | 1707 | sub genUCFHeader { 1708 | #------------------------------------------------------------------------------ 1709 | # Print UCF File Header: 1710 | # 1711 | # The sub-routine printUCFHeader() will print out the UCF File Header. 1712 | # 1713 | # Usage: $sv_rH = printUCFHeader($sv_rH); 1714 | # 1715 | #------------------------------------------------------------------------------ 1716 | my ($sv_rH) = shift; # Read in user's variable. 1717 | 1718 | my (%svH) = %{ $sv_rH }; # De-reference Verilog hash. 1719 | 1720 | my $file_sv = $svH{'file'}; 1721 | my $day = $svH{'day'}; 1722 | my $month = $svH{'month'}; 1723 | my $username = $svH{'username'}; 1724 | my $year = $svH{'year'}; 1725 | my ($debug) = $svH{'debug'}; # Print out Debug Info. 1726 | 1727 | # Fix month, day, year: 1728 | my $monthR = $month+1; 1729 | my $yearR = $year+1900; 1730 | 1731 | # Get Filename: 1732 | # strip .v from filename 1733 | my $file = $file_sv; 1734 | $file =~ s/\x2esv//; 1735 | $file =~ s/\x2e//g; 1736 | $file =~ s/\x2f//g; 1737 | my $ucf_file = join ".",$file,"ucf"; 1738 | 1739 | my $ucfhead=<<"EOF"; 1740 | #****************************************************************** 1741 | # 1742 | # $ucf_file module 1743 | # 1744 | #****************************************************************** 1745 | # 1746 | # COMPANY Confidential Copyright � $yearR 1747 | # 1748 | #****************************************************************** 1749 | # 1750 | # created on: $monthR/$day/$yearR 1751 | # created by: $username 1752 | # last edit on: \$DateTime: \$ 1753 | # last edit by: \$Author: \$ 1754 | # revision: \$Revision: \$ 1755 | # comments: Generated 1756 | # 1757 | # board name: Board 1758 | # board number: Pxxx 1759 | # board revision: A 1760 | # device mpn: XC3S1400A-4FGG484C 1761 | # 1762 | #****************************************************************** 1763 | 1764 | #-------------------------------------- 1765 | # T I M I N G C O N S T R A I N T S 1766 | #-------------------------------------- 1767 | # N/A 1768 | 1769 | #-------------------------------------- 1770 | # I P C O R E C O N S T R A I N T S 1771 | #-------------------------------------- 1772 | # N/A 1773 | 1774 | #------------------------------------------------- 1775 | # P L A C E & R O U T E C O N S T R A I N T S 1776 | #------------------------------------------------- 1777 | # N/A 1778 | 1779 | #--------------------------------------------------- 1780 | # T I M I N G I G N O R E C O N S T R A I N T S 1781 | #--------------------------------------------------- 1782 | # N/A 1783 | 1784 | EOF 1785 | 1786 | $svH{ 'ucffile' } = $ucf_file; 1787 | $svH{ 'ucfhead' } = $ucfhead; 1788 | 1789 | #------------------------------------------------------------------------------ 1790 | # Return data to user 1791 | #------------------------------------------------------------------------------ 1792 | return \%svH; 1793 | 1794 | } 1795 | 1796 | 1797 | sub genUCFBody { 1798 | #------------------------------------------------------------------------------ 1799 | # Print UCF Body: 1800 | # 1801 | # The sub-routine printUCFBody() will print out the body of the UCF File. 1802 | # 1803 | # Usage: $sv_rH = printUCFBody($sv_rH); 1804 | # 1805 | #------------------------------------------------------------------------------ 1806 | my ($sv_rH) = shift; # Read in user's variable. 1807 | my (%svH) = %{ $sv_rH }; # De-reference hash. 1808 | 1809 | 1810 | #------------------------------------------------------------------------------ 1811 | # Build up Test Bench Module Body: 1812 | #------------------------------------------------------------------------------ 1813 | 1814 | my $ucfbody=<<"EOF"; 1815 | #-------------------------------------- 1816 | # P I N A S S I G N M E N T S 1817 | #-------------------------------------- 1818 | 1819 | EOF 1820 | my (%allportsHoH) = %{ $svH{ 'modIO' } }; 1821 | my ($msb) = 0; 1822 | my ($i) = 0; 1823 | # Push lines from the module declaration that match input, inout, or output into 1824 | # their respective arrays: 1825 | 1826 | for my $key ( sort (keys %allportsHoH) ) { 1827 | if ($allportsHoH{$key}{'direction'} =~ m/input/) { 1828 | if ($allportsHoH{$key}{'width'} > 1) { 1829 | $msb = $allportsHoH{$key}{'width'}; 1830 | for ($i = 0; $i < $msb; $i++) { 1831 | $ucfbody .= "NET \"$allportsHoH{$key}{'port'}\[$i\]\"\t\tLOC = \"\" | IOSTANDARD = LVCMOS33;\n"; 1832 | } 1833 | } else { 1834 | $ucfbody .= "NET \"$allportsHoH{$key}{'port'}\"\t\tLOC = \"\" | IOSTANDARD = LVCMOS33;\n"; 1835 | } 1836 | } elsif ($allportsHoH{$key}{'direction'} =~ m/inout/) { 1837 | if ($allportsHoH{$key}{'width'} > 1) { 1838 | $msb = $allportsHoH{$key}{'width'}; 1839 | for ($i = 0; $i < $msb; $i++) { 1840 | $ucfbody .= "NET \"$allportsHoH{$key}{'port'}\[$i\]\"\t\tLOC = \"\" | IOSTANDARD = LVCMOS33;\n"; 1841 | } 1842 | } else { 1843 | $ucfbody .= "NET \"$allportsHoH{$key}{'port'}\"\t\tLOC = \"\" | IOSTANDARD = LVCMOS33;\n"; 1844 | } 1845 | } elsif ($allportsHoH{$key}{'direction'} =~ m/output/) { 1846 | if ($allportsHoH{$key}{'width'} > 1) { 1847 | $msb = $allportsHoH{$key}{'width'}; 1848 | for ($i = 0; $i < $msb; $i++) { 1849 | $ucfbody .= "NET \"$allportsHoH{$key}{'port'}\[$i\]\"\t\tLOC = \"\" | IOSTANDARD = LVCMOS33;\n"; 1850 | } 1851 | } else { 1852 | $ucfbody .= "NET \"$allportsHoH{$key}{'port'}\"\t\tLOC = \"\" | IOSTANDARD = LVCMOS33;\n"; 1853 | } 1854 | } 1855 | } 1856 | 1857 | $svH{ 'ucfbody' } = $ucfbody; 1858 | 1859 | #------------------------------------------------------------------------------ 1860 | # Return data to user 1861 | #------------------------------------------------------------------------------ 1862 | return \%svH; 1863 | 1864 | } 1865 | 1866 | sub genUCFFile { 1867 | #------------------------------------------------------------------------------ 1868 | # Generate Xilinx UCF File: 1869 | # 1870 | # The sub-routine genUCFFile() will generate a Xilinx User Constraints File (UCF) 1871 | # based on the SystemVerilog module provided by the user. For 1872 | # example, if the user provides a Verilog HDL module called 'mymodule' 1873 | # then the following files will be generated: 1874 | # 1875 | # - mymodule.ucf 1876 | # 1877 | # The file 'mymodule.ucf' inserts net location and IO Standard declarations 1878 | # for all I/O in 'mymodule.sv'. The location keyword 'LOC' defaults to empty, 1879 | # and the 'IOSTANDARD' defaults to 'LVCMOS33'. 1880 | # 1881 | # Usage: $sv_rH = genUCFFile(\%svH); 1882 | # 1883 | #------------------------------------------------------------------------------ 1884 | my ($sv_rH) = shift; # Read in user's variable. 1885 | my (%svH) = %{ $sv_rH }; # De-reference hash. 1886 | my ($debug) = $svH{'debug'}; # Print out Debug Info. 1887 | 1888 | #------------------------------------------------------------------------------ 1889 | # Open $file and stuff it into an array. 1890 | #------------------------------------------------------------------------------ 1891 | $sv_rH = getFile($sv_rH); 1892 | 1893 | #------------------------------------------------------------------------------ 1894 | # Search through $file for keywords. 1895 | #------------------------------------------------------------------------------ 1896 | $sv_rH = parseFile($sv_rH); 1897 | 1898 | #------------------------------------------------------------------------------ 1899 | # Get Module Declaration: 1900 | #------------------------------------------------------------------------------ 1901 | $sv_rH = getModDecl($sv_rH); 1902 | 1903 | #------------------------------------------------------------------------------ 1904 | # Get Module Name: 1905 | #------------------------------------------------------------------------------ 1906 | $sv_rH = getModName($sv_rH); 1907 | 1908 | #------------------------------------------------------------------------------ 1909 | # Get Module I/O: 1910 | #------------------------------------------------------------------------------ 1911 | $sv_rH = getModIO($sv_rH); 1912 | 1913 | #------------------------------------------------------------------------------ 1914 | # Generate Header and Body of UCF File 1915 | #------------------------------------------------------------------------------ 1916 | $sv_rH = genUCFHeader($sv_rH); 1917 | $sv_rH = genUCFBody($sv_rH); 1918 | %svH = %{ $sv_rH }; # De-reference Verilog hash. 1919 | 1920 | #------------------------------------------------------------------------------ 1921 | # Get Filename, Header and Body of UCF File 1922 | #------------------------------------------------------------------------------ 1923 | my $ucf_file = $svH{ 'ucffile' }; 1924 | my $ucfhead = $svH{ 'ucfhead' };; 1925 | my $ucfbody = $svH{ 'ucfbody' };; 1926 | 1927 | 1928 | #------------------------------------------------------------------------------ 1929 | # Create File Handle for the new UCF file, and check for existing file. 1930 | #------------------------------------------------------------------------------ 1931 | open(outF, ">", $ucf_file) or dienice ("$ucf_file open failed"); 1932 | 1933 | #------------------------------------------------------------------------------ 1934 | # Print Header and Body to UCF File Handle 1935 | #------------------------------------------------------------------------------ 1936 | printf(outF "$ucfhead"); 1937 | printf(outF "$ucfbody"); 1938 | printf(outF "\n\n"); 1939 | 1940 | close(outF); 1941 | 1942 | print("\n"); 1943 | print("UCF File: $ucf_file is ready for use.\n"); 1944 | print("\n"); 1945 | 1946 | #------------------------------------------------------------------------------ 1947 | # Return data to user 1948 | #------------------------------------------------------------------------------ 1949 | return \%svH; 1950 | } 1951 | 1952 | sub genSVLowModule { 1953 | #------------------------------------------------------------------------------ 1954 | # Generate SystemVerilog Lower Module File: 1955 | # 1956 | # The sub-routine genSVLowModule() will generate an empty lower-level 1957 | # SystemVerilog module. A standard header is used containing an empty description 1958 | # and the new module name. The module contains 3 input signals: clk, rst_n, 1959 | # and data_in[15:0]. The module also contains 1 output signal: data_out[15:0]. 1960 | # 1961 | # Usage: $sv_rH = genSVLowModule($sv_rH); 1962 | # 1963 | #------------------------------------------------------------------------------ 1964 | my ($sv_rH) = shift; # Read in user's variable. 1965 | my (%svH) = %{ $sv_rH }; # De-reference hash. 1966 | my $file_sv = $svH{'file'}; 1967 | my $day = $svH{'day'}; 1968 | my $month = $svH{'month'}; 1969 | my $username = $svH{'username'}; 1970 | my $year = $svH{'year'}; 1971 | my ($debug) = $svH{'debug'}; # Print out Debug Info. 1972 | 1973 | # Fix month, day, year: 1974 | my $monthR = $month+1; 1975 | my $yearR = $year+1900; 1976 | 1977 | # Get Filename: 1978 | # strip .v from filename 1979 | my $modname = $file_sv; 1980 | $modname =~ s/\x2esv//; 1981 | $modname =~ s/\x2e//g; 1982 | $modname =~ s/\x2f//g; 1983 | 1984 | #---------------------------------------------------------------------- 1985 | # Determine number of indent spaces: 1986 | # 1987 | # * Tab Space = 8 1988 | # * Create string with correct numer of indent spaces. 1989 | # 1990 | #---------------------------------------------------------------------- 1991 | my ($indent_spaces) = ""; 1992 | my ($modinst_line1) = "module $modname (/"; 1993 | my ($tmpinst_len) = length($modinst_line1); 1994 | print("Number of Indent Spaces: $tmpinst_len\n") if $debug; 1995 | my ($i) = 0; 1996 | my (@indent); 1997 | for ($i = 0; $i < $tmpinst_len; $i++) { 1998 | push(@indent, " "); 1999 | } 2000 | $indent_spaces = join("",@indent); 2001 | $indent_spaces =~ s/ //; 2002 | my $indentCparen = $indent_spaces; 2003 | $indentCparen =~ s/ //; 2004 | 2005 | 2006 | my $svLowHead=<<"HEAD"; 2007 | /****************************************************************************** 2008 | vim:tw=160:softtabstop=4:shiftwidth=4:et:syn=verilog: 2009 | ******************************************************************************* 2010 | 2011 | $file_sv module 2012 | 2013 | ******************************************************************************* 2014 | 2015 | COMPANY Confidential Copyright � $yearR 2016 | 2017 | ******************************************************************************* 2018 | 2019 | created on: $monthR/$day/$yearR 2020 | created by: $username 2021 | last edit on: \$DateTime: \$ 2022 | last edit by: \$Author: \$ 2023 | revision: \$Revision: \$ 2024 | comments: Generated 2025 | 2026 | ******************************************************************************* 2027 | //Project// (//Number//) 2028 | 2029 | This module implements the ... in the //name// fpga. 2030 | 2031 | // enter detailed description here; 2032 | 2033 | 2034 | ******************************************************************************/ 2035 | `timescale 1ns/1ps 2036 | 2037 | module $modname (// *** Inputs *** 2038 | HEAD 2039 | 2040 | $svLowHead .= "$indent_spaces input logic clk, // System Clock (xxx MHz)\n"; 2041 | $svLowHead .= "$indent_spaces input logic rst_n, // System Reset (Active Low)\n"; 2042 | $svLowHead .= "$indent_spaces input logic [15:0] data_in, // Data In.\n"; 2043 | $svLowHead .= "\n"; 2044 | $svLowHead .= "$indent_spaces // *** Outputs ***\n"; 2045 | $svLowHead .= "$indent_spaces output logic [15:0] data_out // Data Out.\n"; 2046 | $svLowHead .= "$indentCparen );\n"; 2047 | $svLowHead .= "\n"; 2048 | $svLowHead .= "\n"; 2049 | $svLowHead .= "// *** Local Variable Declarations ***\n"; 2050 | $svLowHead .= "// Local Parameter Declarations:\n"; 2051 | $svLowHead .= "// N/A\n"; 2052 | $svLowHead .= "// Local Logic Declarations:\n"; 2053 | $svLowHead .= "// N/A\n"; 2054 | $svLowHead .= "\n"; 2055 | $svLowHead .= "endmodule : $modname\n"; 2056 | 2057 | 2058 | $svH{ 'svLowHead' } = $svLowHead; 2059 | 2060 | #------------------------------------------------------------------------------ 2061 | # Create File Handle for the new SystemVerilog file, and check for existing file. 2062 | #------------------------------------------------------------------------------ 2063 | if (-e $file_sv) { 2064 | print("Oops! A file called '$file_sv' already exists.\n"); 2065 | exit 1; 2066 | } else { 2067 | open(outF, ">", $file_sv); 2068 | 2069 | #---------------------------------------------------------------------- 2070 | # Print Header and Body to UCF File Handle 2071 | #---------------------------------------------------------------------- 2072 | printf(outF "$svLowHead"); 2073 | printf(outF "\n\n"); 2074 | 2075 | close(outF); 2076 | 2077 | print("\nNew SystemVerilog File: $file_sv is ready for use.\n\n"); 2078 | } 2079 | 2080 | #------------------------------------------------------------------------------ 2081 | # Return data to user 2082 | #------------------------------------------------------------------------------ 2083 | return \%svH; 2084 | 2085 | } 2086 | 2087 | sub genSVTopModule { 2088 | #------------------------------------------------------------------------------ 2089 | # Generate SystemVerilog Top-Level Module File: 2090 | # 2091 | # The sub-routine genSVTopModule() will generate an empty top-level 2092 | # SystemVerilog module. A standard header is used containing an empty description 2093 | # and the new module name. The module contains 3 input signals: clk, rst_n, 2094 | # and data_in[15:0]. The module also contains 1 output signal: data_out[15:0]. 2095 | # 2096 | # Usage: $sv_rH = genSVTopModule($sv_rH); 2097 | # 2098 | #------------------------------------------------------------------------------ 2099 | my ($sv_rH) = shift; # Read in user's variable. 2100 | my (%svH) = %{ $sv_rH }; # De-reference hash. 2101 | my $file_sv = $svH{'file'}; 2102 | my $day = $svH{'day'}; 2103 | my $month = $svH{'month'}; 2104 | my $username = $svH{'username'}; 2105 | my $year = $svH{'year'}; 2106 | my ($debug) = $svH{'debug'}; # Print out Debug Info. 2107 | 2108 | # Fix month, day, year: 2109 | my $monthR = $month+1; 2110 | my $yearR = $year+1900; 2111 | 2112 | # Get Filename: 2113 | # strip .v from filename 2114 | my $modname = $file_sv; 2115 | $modname =~ s/\x2esv//; 2116 | $modname =~ s/\x2e//g; 2117 | $modname =~ s/\x2f//g; 2118 | 2119 | #---------------------------------------------------------------------- 2120 | # Determine number of indent spaces: 2121 | # 2122 | # * Tab Space = 8 2123 | # * Create string with correct numer of indent spaces. 2124 | # 2125 | #---------------------------------------------------------------------- 2126 | my ($indent_spaces) = ""; 2127 | my ($modinst_line1) = "module $modname (/"; 2128 | my ($tmpinst_len) = length($modinst_line1); 2129 | print("Number of Indent Spaces: $tmpinst_len\n") if $debug; 2130 | my ($i) = 0; 2131 | my (@indent); 2132 | for ($i = 0; $i < $tmpinst_len; $i++) { 2133 | push(@indent, " "); 2134 | } 2135 | $indent_spaces = join("",@indent); 2136 | $indent_spaces =~ s/ //; 2137 | my $indentCparen = $indent_spaces; 2138 | $indentCparen =~ s/ //; 2139 | 2140 | my $svTopHead=<<"HEAD"; 2141 | /****************************************************************************** 2142 | vim:tw=160:softtabstop=4:shiftwidth=4:et:syn=verilog: 2143 | ******************************************************************************* 2144 | 2145 | $file_sv module 2146 | 2147 | ******************************************************************************* 2148 | 2149 | COMPANY Confidential Copyright � $yearR 2150 | 2151 | ******************************************************************************* 2152 | 2153 | created on: $monthR/$day/$yearR 2154 | created by: $username 2155 | last edit on: \$DateTime: \$ 2156 | last edit by: \$Author: \$ 2157 | revision: \$Revision: \$ 2158 | comments: Generated 2159 | 2160 | board name: //Name// Board 2161 | board number: Pxxx 2162 | board revision: A 2163 | device mpn: XCxxxx-4FG676C 2164 | 2165 | ******************************************************************************* 2166 | //Project// (//Number//) 2167 | 2168 | This module is the top level for the $modname FPGA 2169 | on the ... board for the //Project//. 2170 | 2171 | This design performs the following functions: 2172 | 2173 | // enter functions here; 2174 | 2175 | The sub-modules included in this design are: 2176 | 2177 | // enter sub-modules here; 2178 | 2179 | The physical constraints file for the ... FPGA is in the 2180 | file: 2181 | 2182 | $modname.ucf 2183 | 2184 | ******************************************************************************/ 2185 | `timescale 1ns/1ps 2186 | 2187 | module $modname (// *** Inputs *** 2188 | HEAD 2189 | 2190 | $svTopHead .= "$indent_spaces input logic clk, // System Clock (xxx MHz)\n"; 2191 | $svTopHead .= "$indent_spaces input logic rst_n, // System Reset (Active Low)\n"; 2192 | $svTopHead .= "$indent_spaces input logic [15:0] data_in, // Data In.\n"; 2193 | $svTopHead .= "\n"; 2194 | $svTopHead .= "$indent_spaces // *** Outputs ***\n"; 2195 | $svTopHead .= "$indent_spaces output logic [15:0] data_out // Data Out.\n"; 2196 | $svTopHead .= "$indentCparen );\n"; 2197 | $svTopHead .= "\n"; 2198 | $svTopHead .= "\n"; 2199 | $svTopHead .= "// *** Local Variable Declarations ***\n"; 2200 | $svTopHead .= "// Local Parameter Declarations:\n"; 2201 | $svTopHead .= "// N/A\n"; 2202 | $svTopHead .= "// Local Logic Declarations:\n"; 2203 | $svTopHead .= "// N/A\n"; 2204 | $svTopHead .= "\n"; 2205 | $svTopHead .= "endmodule : $modname\n"; 2206 | 2207 | 2208 | $svH{ 'svTopHead' } = $svTopHead; 2209 | 2210 | #------------------------------------------------------------------------------ 2211 | # Create File Handle for the new SystemVerilog file, and check for existing file. 2212 | #------------------------------------------------------------------------------ 2213 | if (-e $file_sv) { 2214 | print("Oops! A file called '$file_sv' already exists.\n"); 2215 | exit 1; 2216 | } else { 2217 | open(outF, ">", $file_sv); 2218 | 2219 | #---------------------------------------------------------------------- 2220 | # Print Header and Body to UCF File Handle 2221 | #---------------------------------------------------------------------- 2222 | printf(outF "$svTopHead"); 2223 | printf(outF "\n\n"); 2224 | 2225 | close(outF); 2226 | 2227 | print("\nNew SystemVerilog File: $file_sv is ready for use.\n\n"); 2228 | } 2229 | 2230 | #------------------------------------------------------------------------------ 2231 | # Return data to user 2232 | #------------------------------------------------------------------------------ 2233 | return \%svH; 2234 | 2235 | } 2236 | 2237 | 2238 | 2239 | =pod 2240 | 2241 | =head1 NAME 2242 | 2243 | SystemVerilogTools - Package to parse and create SystemVerilog files 2244 | 2245 | =head1 VERSION 2246 | 2247 | Version 1.0 2248 | 2249 | =head1 ABSTRACT 2250 | 2251 | SystemVerilogTools - Package to parse and create SystemVerilog files 2252 | 2253 | =head1 SYNOPSIS 2254 | 2255 | use SystemVerilogTools; 2256 | 2257 | #****************************************************************** 2258 | # Initialize SystemVerilog Hash: 2259 | #****************************************************************** 2260 | my (%svH, $sv_rH); 2261 | $svH{ 'username' } = $author; 2262 | $svH{ 'file' } = $file; 2263 | $svH{ 'day' } = $day; 2264 | $svH{ 'month' } = $month; 2265 | $svH{ 'year' } = $year; 2266 | $svH{ 'debug' } = $debug; 2267 | 2268 | # Generate Top-Level Module 2269 | $sv_rH = genSVTopModule(\%svH); 2270 | 2271 | # Generate Low-Level Module 2272 | $sv_rH = genSVLowModule(\%svH); 2273 | 2274 | # Generate Module Instantiateion 2275 | $sv_rH = printModInst(\%svH); 2276 | 2277 | # Generate UCF File from Module 2278 | $sv_rH = genUCFFile(\%svH); 2279 | 2280 | # Generate Test Benches 2281 | $sv_rH = genTBTestFile(\%svH); 2282 | 2283 | =head1 DESCRIPTION 2284 | 2285 | The SystemVerilogTools is used to generate or parse SystemVerilog files. 2286 | 2287 | =head2 printModInst: 2288 | 2289 | The sub-routine printModInst() will print out the SystemVerilog module 2290 | instantiation. The SystemVerilog module must use an ANSI-C style module 2291 | declaration. An example module instantiation is shown below: 2292 | 2293 | mymodule _mymodule (.clk (clk), 2294 | .data_in (data_in), 2295 | .rst_n (rst_n), 2296 | 2297 | .data_out (data_out)); 2298 | 2299 | =head2 genTBTestFile: 2300 | 2301 | The sub-routine genTBTestFile() will generate a set of Test Bench 2302 | files based on the SystemVerilog module provided by the user. For 2303 | example, if the user provides a SystemVerilog module called 'mymodule' 2304 | then the following files will be generated: 2305 | 2306 | - top.sv 2307 | - test_mymodule.sv 2308 | 2309 | The file 'top.sv' instantiates both the UUT (mymodule.sv) and the 2310 | Test Bench (test_mymodule.sv). All nets labeled with either 'clk' or 2311 | 'clock' will be generated using an always block in the following form: 2312 | 2313 | // clk generators 2314 | initial begin 2315 | clk <= 1'b1; 2316 | end 2317 | 2318 | // Generate clock: 2319 | always #4 clk <= ~clk; 2320 | 2321 | All nets in the 'mymodule.sv' file are declared in the 'top.sv' file. 2322 | 2323 | The file 'test_mymodule.sv' contains the same number of i/o as 2324 | 'mymodule.sv' with inputs and outputs swapped, except for clock 2325 | signals. 2326 | 2327 | =head2 genUCFFile: 2328 | 2329 | The sub-routine genUCFFile() will generate a Xilinx User Constraints File (UCF) 2330 | based on the SystemVerilog module provided by the user. For 2331 | example, if the user provides a SystemVerilog module called 'mymodule' 2332 | then the following files will be generated: 2333 | 2334 | - mymodule.ucf 2335 | 2336 | The file 'mymodule.ucf' inserts net location and IO Standard declarations 2337 | for all I/O in 'mymodule.sv'. The location keyword 'LOC' defaults to empty, 2338 | and the 'IOSTANDARD' defaults to 'LVCMOS33'. 2339 | 2340 | =head2 genSVLowModule: 2341 | 2342 | The sub-routine genSVLowModule() will generate an empty lower-level SystemVerilog 2343 | module. A standard header is used containing an empty description and the 2344 | new module name. The module contains 3 input signals: clk, rst_n, and data_in[15:0]. 2345 | The module also contains 1 output signal: data_out[15:0]. 2346 | 2347 | =head2 genSVTopModule: 2348 | 2349 | The sub-routine genSVTopModule() will generate an empty top-level SystemVerilog 2350 | module. A standard header is used containing an empty description and the 2351 | new module name. The module contains 3 input signals: clk, rst_n, and data_in[15:0]. 2352 | The module also contains 1 output signal: data_out[15:0]. 2353 | 2354 | =head2 EXPORT 2355 | 2356 | None at the moment. 2357 | 2358 | =head1 INSTALLATION 2359 | 2360 | perl Makefile.PL # build the Makefile 2361 | make # build the package 2362 | make install # Install package 2363 | 2364 | =head1 SEE ALSO 2365 | 2366 | Example scripts can be accessed at the following website: 2367 | 2368 | * http://www.jwebb-design.com/ee/howto/using_perl_with_sv.shtml 2369 | 2370 | =head1 AUTHOR 2371 | 2372 | Jeremy Webb, Ejeremy.webb@jwebb-consulting.com 2373 | 2374 | =head1 BUGS 2375 | 2376 | Please report any bugs or feature requests to the author. 2377 | 2378 | =head1 COPYRIGHT AND LICENSE 2379 | 2380 | Copyright (C) 2009-2017 by Jeremy Webb 2381 | 2382 | =cut 2383 | --------------------------------------------------------------------------------