#----------------------------------------------------------------------------- # File : vhdlTemp.pl # Author : Ryan Herbst, ryan@amaroq.com # Created : 07/26/2004 #----------------------------------------------------------------------------- # Description: # This script will read in the passed VHDL file and add a # template to the file called from lemmy. # # Script is called from within lemmy. The line on which the script is # called contains instructions that are processed by the perl script. # The top level module in the VHDL source must be the same as the file name. # # To create a component template: # c Module # # To create a list of signals for the module # s Module # # To create a instantiation for the module # i Module # #----------------------------------------------------------------------------- # Copyright (c) 2004 by Ryan Herbst. All rights reserved. #----------------------------------------------------------------------------- # Modification history: # 07/16/2004: created. #----------------------------------------------------------------------------- # Get current line contents $Lemmy->GetLineContent(0); $in = $Lemmy->LineContent; # Extract command @ins = split (/ /,$in); # Get File Name $command = $ins[0]; $src_file = "$ins[1].vhd"; # Open VHDL source file $res = open(DAT, $src_file); if ( ! $res ) { $Lemmy->DoAddText("Could not open file: $src_file\n",1,1); exit; } @raw_data=; close(DAT); # Setup two arrays, one contains the full signal declaration line and # the second contains only the signal name my @sig_line; my @sig_name; my $ent_name; my $sig_len = 0; # Variable to track the state my $state = 0; # Go through each line in the file foreach $src_line (@raw_data) { # Strip Leading spaces $src_line =~ s/^\s*//; # Strip Trailing spaces $src_line =~ s/\s*$//; # Skip all lines starting with a comment or empty lines if ( $src_line =~ /^\-\-/ || length($src_line) < 1) { next; }; # Split the line into words @words = split (/ /,$src_line); # Are we still looking for the entity declaration if ( $state < 5 ) { # process each word individually foreach $word (@words) { # State 0, looking for the word entity if ( $state == 0 ) { if ( $word =~ /entity/i ) { $state = 1; } } # State 1, extract entity name elsif ( $state == 1 ) { $ent_name = $word; $state = 2; } # State 2, look for 'is' elsif ( $state == 2 ) { if ( $word !~ /is/i ) { die("Error. Expecting is and got $word\n"); } $state = 3; } # State 3, look for 'port' elsif ( $state == 3 ) { if ( $word =~ /port/i ) { $state = 4; } } # State 4, look for '(' elsif ( $state == 4 ) { if ( $word !~ /\(/i ) { die("Error. Expecting ( and got $word\n"); } $state = 5; } } } # Now we extract port names, assume each port singal declration # is on its own line elsif ( $state == 5 ) { # check for end of port declaration if ( $src_line =~ /^\)\;/ ) { $state = 6; } else { # Get signal line push(@sig_line,$src_line); push(@sig_name,$words[0]); # is signal the longest name so far? if ( length($words[0]) > $sig_len ) { $sig_len = length($words[0]); } } } } # Determine which command to execute # Component if ( $command =~ /^c$/ ) { # component template $Lemmy->DoAddText(" component $ent_name\n",1,1); $Lemmy->DoAddText(" port (\n",1,1); # Add each port foreach $port (@sig_line) { $Lemmy->DoAddText(" $port\n",1,1); } # End the component $Lemmy->DoAddText(" );\n",1,1); $Lemmy->DoAddText(" end component;\n\n",1,1); } # Add signal list elsif ( $command =~ /^s$/ ) { # Add each signal foreach $port (@sig_line) { $sig_line = $port; $sig_line =~ s/: in\s*/: /i; $sig_line =~ s/: out\s*/: /i; $sig_line =~ s/: buffer\s*/: /i; $sig_line =~ s/: inout\s*/: /i; $Lemmy->DoAddText(" signal $sig_line\n",1,1); } } # Add instantiation elsif ( $command =~ /^i$/ ) { # Next block is an instantiation $Lemmy->DoAddText(" BlockName: $ent_name port map (\n",1,1); # variables to help formating my $fill_cnt = 0; my $sig_cnt = 0; my $tot_cnt = 0; my $pline = ""; # Add each signal foreach $port (@sig_name) { # Increment counter $tot_cnt = $tot_cnt + 1; # Determine fill size $fill_cnt = $sig_len - length($port); # Print leading spaces if first value if ( $sig_cnt == 0 ) { $pline .= " "; } # Print signal name $pline .= "$port"; # Print fill spaces for ( $i=0; $i < $fill_cnt; $i++ ) { $pline .= " ";} # Repeat signal name $pline .= " => $port"; # Stop if this is the last signal if ( $tot_cnt == @sig_name ) { $pline .= "\n"; $Lemmy->DoAddText($pline,1,1); $pline = ""; } else { # Print fill spaces if first value if ( $sig_cnt == 0 ) { $pline .= ", "; for ( $i=0; $i < $fill_cnt; $i++ ) { $pline .= " ";} $sig_cnt = 1; } # Otherwise end line else { $pline .= ",\n"; $Lemmy->DoAddText($pline,1,1); $pline = ""; $sig_cnt = 0; } } } # Close Out $Lemmy->DoAddText(" );\n",1,1); } else { $Lemmy->DoAddText("Invalid Command\n",1,1); }