Featured post

Top 5 books to refer for a VHDL beginner

VHDL (VHSIC-HDL, Very High-Speed Integrated Circuit Hardware Description Language) is a hardware description language used in electronic des...

Showing posts with label Perl Script. Show all posts
Showing posts with label Perl Script. Show all posts

Monday, 10 August 2020

Useful Vim plug-in for efficient coding in Perl

Think of a plug-in with which you can do the following while coding a Perl script:

  • Auto addition of file header
  • Easy addition of function/frame comment
  • Quick inclusion of default code snippet
  • Performing syntax check
  • Reading documentation about a function
  • Converting a full code block to comment, and vice versa
  • Help to speed up the code writing with consistency in coding.
One-stop solution for all these things is a perl-support vim plug-in

The Perl-Support Vim Plugin – Perl-IDE offers the easiest way to do all of the above, saving a lot of time and keystrokes.

We have already discussed in an earlier article regarding Use of Scripting languages in VLSI

We will be covering the following in this article

1. How to install perl-support plugin to use it with VIM.

2. Powerful features of the Perl-support plugin.


Steps to install Perl-Support VIM Plug-in


1. Download the plugin from the vim.org website.

Click here to download to go to the download page

Alternatively use below command

cd /usr/src/
wget http://www.vim.org/scripts/download_script.php?src_id=9701

2. Copy the zip archive perl-support.zip to $HOME/.vim and run below command

  unzip perl-support.zip

This command will create following files:

  $HOME/.vim/autoload/mmtemplates/...

  $HOME/.vim/doc/...

  $HOME/.vim/plugin/perl-support.vim

3. Loading of plug-in files must be enabled in $HOME/.vimrc. If not use previously

  filetype plugin on

Create .vimrc if there is none or use the files in $HOME/.vim/perl-support/rc as a starting point.


After done with installation lets get to know about

The Powerful Features of Perl-support


1. Add Automatic Header to *.pl file whenever you create a new file

2. Insert statements

3. Insert frequently used statements

4. Insert special variables

5. insert code snippets and manage templates

6. Run a profiler

7.  Run the script, check the syntax, start the debugger

8. Make integration


Details of all these can be found at 



Thursday, 6 August 2020

Use of Scripting languages in VLSI


Very often we come across questions from VLSI engineers that "Which scripting language should a VLSI engineer should learn?".

Well, Shell, Tcl, Perl, and Python are the scripting languages that are commonly used for VLSI front end/back end design automation and related applications. 

TCL: Tcl (pronounced "tickle" or as an initialism) is a high-level, general-purpose, interpreted, dynamic programming language

PERL: Practical Extraction and Reporting Language

PYTHON: Python is a dynamic, object-oriented, high-level programming language that can be used for many kinds of software development/scripting.

Shell Scripting: A shell script is a computer program designed to be run by the Unix/Linux shell which could be one of the following:

The Bourne Shell / The C Shell / The Korn Shell / The GNU Bourne-Again Shell

A shell is a command-line interpreter and typical operations performed by shell scripts include file manipulation, program execution, and printing text.
 
Perl has been in use for several years, but python is increasingly becoming more popular. In the past, we have already shared out views on the advantages of Python. Ref: Advantages of Python over Perl

Tcl is also used mostly for tool interfaces as several EDA tools support that.

If you know any kind of programming, learning a new scripting language will be easy.

Following are some commonly used applications of scripting languages in VLSI:
  • Front end RTL/Testbench code compilation and simulation flows
  • Automation of running tests in regressions, generating reports, analyzing failures, debug automation
  • Connectivity checks, netlist parsing, automatic generation/modification any RTL module/stubs, etc
  • Synthesis, P&R tools interfacing, and back end flow.
  • Several project management utilities - regression pass rates, trends, bug charts, etc - that helps in tracking projects
  • Any other task that is repetitive in workflow and can be automated.
Here is a complete comparison of TCL, PYTHON and PERL.

Monday, 21 November 2016

Advantages of Python over Perl

In the new competitive generation of chip designing where Time-to-Market is so critical and also the complexity of designs is increasing exponentially.  Adding to that it is also observed that the Verification is always considered the longest pole and takes nearly 70% of the chip design life cycle. Hence any opportunity to automate a  task that is repeatable more than once is considered of most importance to improve the verification productivity. This is where  “scripting” skills are highly valuable for any  Verification engineer.

After many years of writing design and verification automation scripts in Perl and Python, we would like to throw some light on the advantages of using Python.

Maintainability

As we all know, Perl is easy to write but hard to read, especially when someone else has written it. There are multiple ways of writing the same code. Add to this fact that many engineers take pride in writing highly obfuscated Perl that is a pain for others to read.

Maintainability is a critical aspect of any engineering project. Throwing away code and rewriting it is a productivity loss. Unfortunately, this happens a lot with Perl.

Python, on the other hand, has a clean syntax and typically there is only one way of doing what you want. Python code is hence much more readable. Even people who have never written Python code ever can understand it, as the syntax is very “pseudo-code” like. It is also easier to functionalize and modularize code in Python as the language naturally encourages this.

Re-usability

Perl is designed for use and throw. You write something in Perl, run it and then forget about it. It is very difficult to extend the functionality of a Perl script. Typically you would not have organized your code into functions, as Perl syntax does not encourage that. When you try adding some functionality to your Perl script you realize that re-writing it completely is better than re-using the earlier script and extending it.

Python syntax encourages re-usability. The mindset is different. When you write code in Python, you write with future re-usability in mind. This is really tough to do in Perl. Perl encourages shortcuts.

Scale

Writing large pieces of code (more than 50k lines) in Perl exposes the weaknesses in the language. Maintainability, performance, and packaging are big issues. Can I package my application in a way that doesn’t require users to download and install modules used by the application?

Perl encourages users to download and install modules as needed. IT departments are not comfortable with upgrading Perl installations on thousands of server farm nodes. It would be an IT nightmare.

Python distributions, on the other hand, come with a majority of the module libraries included. Also, Python allows the packaging of applications so users do not have to manually download and install all module and library dependencies needed to run an application.

Final words

Perl is great at some things. For example, it has fantastic regular expression capabilities (it can even combine multiple regexp’s and match all of them together!). Perl is a worthy successor to awk.

Bottom line:  For use and throw scripts, Perl is great. But, if your code needs to be checked into a version control system and will potentially be modified by other people, I would prefer Python over Perl.

Saturday, 1 June 2013

Keep Environment Variables when Using SUDO

Recently we were developing a script in perl where we need to specify the environment variable UVM_LIBRARY_PATH = ../examples/UVM1.10, but when we run the code with sudo script/server, it doesn't run because that library path is not in root's env.

Its very easy to keep the env variables even while running the script with SUDO. All you need to do is modify your /etc/sudoers file

search following lines

Defaults    env_reset
Defaults env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR \
LS_COLORS MAIL PS1 PS2 QTDIR USERNAME \
LANG LC_ADDRESS LC_CTYPE LC_COLLATE LC_IDENTIFICATION \
LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME
LC_PAPER LC_TELEPHONE LC_TIME LC_ALL LANGUAGE LINGUAS \
_XKB_CHARSET XAUTHORITY"

Add env variable eg. UVM_LIBRARY_PATH. in our case we have

Defaults    env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR \
LS_COLORS MAIL PS1 PS2 QTDIR USERNAME \
LANG LC_ADDRESS LC_CTYPE LC_COLLATE LC_IDENTIFICATION \
LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME
LC_PAPER LC_TELEPHONE LC_TIME LC_ALL LANGUAGE LINGUAS \
_XKB_CHARSET XAUTHORITY UVM_LIBRARY_PATH"

Save your file and run the script.









Get free daily email updates!



Follow us!


Tuesday, 8 January 2013

Creating .lib file from Verilog netlist

Creating a dummy .lib file is something every physical design engineer has done now and then. If you have a verilog model of the block available, your task gets easier. The following script automates .lib generation from your verilog netlist. Use this as a dummy .lib to get your design flow going or use it as a template for your analog blocks for modifying the values.

Customize, edit and use. The script creates a simple Data Structure. So any modification can be done pretty easily. The script parses the verilog for the module name specified, and collects the ports & directions. In the .lib file written out, a default capacitance and transition value is specified. This is a good starting point for your blocks.

Usage: create_lib <verilog_netlist> <module_name> [transition_value] [capacitance_value]

#!/usr/bin/perl

use strict;

if ($#ARGV < 1 ) {
    print "usage: create_lib <verilog_netlist> <module_name> \n";
    exit;
}

my $netlist = $ARGV[0] ;
my $module  = $ARGV[1] ;
my $tran = 2.5 ;
my $cap = 0.001;
my $signal_level = "VDD" ;

if(defined $ARGV[2]) {$tran = $ARGV[2];}
if(defined $ARGV[3]) {$cap = $ARGV[3];}
if(defined $ARGV[4]) {$signal_level = $ARGV[4];}

my $FF;
my $FO;
open $FF, "< $ARGV[0]" or die "Can't open $ARGV[0] : $!";
open $FO, ">$module.lib" or die "Can't open $module.lib for write : $!";

my $db = createTopLevelDB();
createDotLib($db,$FO);

sub createDotLib
{
    my $topLevelDBRef = shift;
    my $FO = shift ;   
    ### Header
    print $FO "library\($topLevelDBRef->{'design'}->{'cell'}\) {\n";
    print $FO "\n /* unit attributes */\n";
    print $FO "  time_unit : \"1ns\"\;\n";
    print $FO "  voltage_unit : \"1V\"\;\n";
    print $FO "  current_unit : \"1uA\"\;\n";
    print $FO "  pulling_resistance_unit : \"1kohm\"\;\n";
    print $FO "  leakage_power_unit : \"1nW\"\;\n";
    print $FO "  capacitive_load_unit\(1,pf\)\;\n\n";
    foreach my $direction (keys(%{$topLevelDBRef->{'bus'}})) {
        foreach my $bus_type (keys %{$topLevelDBRef->{'bus'}->{$direction}}) {
            my @bus_width =  split(/_/, $bus_type);
            my $bus_hi = $bus_width[1] ;
            my $bus_lo = $bus_width[2] ;
            my $bus_width = $bus_hi+1-$bus_lo;
            print $FO " type \($bus_type\) { \n";
            print $FO "   base_type : array ; \n" ;
                print $FO "   data_type : bit  \n" ;;
                print $FO "   bit_width : $bus_width   \n" ;;
                print $FO "   bit_from : $bus_hi  \n" ;;
                print $FO "   bit_to : $bus_lo ; \n" ;
                print $FO "   downto : true ; \n" ;
                print $FO " } \n" ;
        }
    }
    print $FO "\n  cell\($topLevelDBRef->{'design'}->{'cell'}\) {\n";
    foreach my $direction (keys(%{$topLevelDBRef->{'pins'}})) {
        foreach my $pin_name (@{$topLevelDBRef->{'pins'}->{$direction}}) {
            print $FO ("    pin\($pin_name\) { \n");
            print $FO ("\tdirection : $direction ;\n");
            if($direction eq "input") {
                print $FO ("\tmax_transition : $tran;\n");
            }
            print $FO ("\tcapacitance : $cap; \n");     
            print $FO ("    } \n") ;
        }
    }
    foreach my $direction (keys(%{$topLevelDBRef->{'bus'}})) {
        foreach my $bus_type (keys %{$topLevelDBRef->{'bus'}->{$direction}}) {
            my @bus_width =  split(/_/, $bus_type);
            my $bus_hi = $bus_width[1] ;
            my $bus_lo = $bus_width[2] ;
            foreach my $bus_name (@{$topLevelDBRef->{'bus'}->{$direction}{$bus_type}}) {
                                        chomp($bus_name);
                print "BUS $bus_name : $bus_type : $direction \n" ;
                print $FO ("    bus\($bus_name\) { \n");
                print $FO ("\tbus_type : $bus_type ;\n");
                print $FO ("\tdirection : $direction ;\n");
                if($direction eq "input") {
                    print $FO ("\tmax_transition : $tran;\n");
                }   
                for(my $i=$bus_lo; $i<=$bus_hi; $i++) {
                    print $FO ("\tpin\($bus_name\[$i\]\) { \n");
                    print $FO ("\t\tcapacitance : $cap; \n"); 
                    print $FO ("\t} \n") ;
                }
                print $FO ("    } \n") ;
            }
        }
    }
    print $FO ("  } \n") ;
    print $FO ("} \n") ;
}

sub createTopLevelDB
{
    my $find_top_module = 0;
    my %topLevelDB = () ;
    my %pins = () ;
    my %bus = () ;
    my @input_pins ;
    my @output_pins ;
    my @inout_pins ;
    my @bus_types ;
    my %input_bus = () ;
    my %output_bus = () ;
    my %inout_bus = () ;
    my %design = ();
    $design{'cell'} = $module;
    $design{'tran'} = $tran;
    $design{'cap'} = $cap;
    $design{'signal_level'} = $signal_level;
    while(my $line = <$FF>) {
        last if($find_top_module == 1);
        if($line=~/module\s+$module/) {
            $find_top_module = 1 ;
            while(my $line = <$FF>) {
                next if($line =~ "\s*//" );
                chomp($line);
                if ($line =~/input\s+/ ) {
                    $line=~s/\s*input\s+//;
                    $line=~s/;//;
                    if($line =~/\[(\d+):(\d+)\]/) {
                        my $bus_type = "bus_$1_$2";
                        $line=~s/\[(\d+):(\d+)\]//;
                        my @line =  split(/,/, $line);
                        unless(grep {$_ eq $bus_type} @bus_types) { 
                            push(@bus_types,$bus_type);
                        }
                        foreach my $pin (@line) {
                            $pin=~s/\s+//;
                            push(@{$input_bus{$bus_type}}, $pin );
                        }
                    }
                    else {
                        my @line =  split(/,/, $line);
                        foreach my $pin (@line) {
                            $pin=~s/\s+//;
                            push(@input_pins, $pin);
                        }
                    }
                }
                if ($line =~/output\s+/ ) {
                    $line=~s/\s*output\s+//;
                    $line=~s/;//;
                    if($line =~/\[(\d+):(\d+)\]/) {
                        my $bus_type = "bus_$1_$2";
                        $line=~s/\[(\d+):(\d+)\]//;
                        my @line =  split(/,/, $line);
                        unless(grep {$_ eq $bus_type} @bus_types) { 
                            push(@bus_types,$bus_type);
                        }
                        foreach my $pin (@line) {
                            $pin=~s/\s+//;
                            push(@{$output_bus{$bus_type}}, $pin );
                        }
                    }
                    else {
                        my @line =  split(/,/, $line);
                        foreach my $pin (@line) {
                            $pin=~s/\s+//;
                            push(@output_pins, $pin);
                        }
                    }

                }
                if ($line =~/inout\s+/ ) {
                    $line=~s/\s*inout\s+//;
                    $line=~s/;//;
                    if($line =~/\[(\d+):(\d+)\]/) {
                        my $bus_type = "bus_$1_$2";
                        $line=~s/\[(\d+):(\d+)\]//;
                        my @line =  split(/,/, $line);
                        unless(grep {$_ eq $bus_type} @bus_types) { 
                            push(@bus_types,$bus_type);
                        }
                        foreach my $pin (@line) {
                            $pin=~s/\s+//;
                            push(@{$inout_bus{$bus_type}}, $pin );
                        }
                    }
                    else {
                        my @line =  split(/,/, $line);
                        foreach my $pin (@line) {
                            $pin=~s/\s+//;
                            push(@inout_pins, $pin);
                        }
                    }

                }

                last if($line=~/endmodule/);
            }

        }
    }
    $pins{'input'} = \@input_pins;
    $pins{'output'} = \@output_pins;
    $pins{'inout'} = \@inout_pins;
    $bus{'input'} = \%input_bus;
    $bus{'output'} = \%output_bus;
    $bus{'inout'} = \%inout_bus;
    $topLevelDB{'pins'} = \%pins;
    $topLevelDB{'bus'} = \%bus;
    $topLevelDB{'design'} = \%design;
    return \%topLevelDB;
}