Friday, January 29, 2016

egrep-xargs-sed combo effect


Debugging is very significant part of verification engineer's life. In the fast paced SoC world, parsing through the logfile and quickly understanding the problem is the key. Also sometimes we may need to collect the data (say performance numbers) by parsing the list of logfiles. Almost the laborious tasks has become the part of verification.

egrep, xargs, sed are very powerful commands which can do wonders for that matter.

Now here the scenario is to find the list of files which don't have the below line and insert that at second line of those files.
// vim: tabstop=3 expandtab shiftwidth=3 softtabstop=3

2 steps for this.
1. We have to find the list of the files which don't have that line(pattern) using egrep.  -L option gives the file names only instead of lines. In general it is better to use egrep than grep.
egrep "vim: tabstop" -L *

2. We need to feed that file list to sed command which will insert that line. Here "1 a" will append that patter after the first line.

egrep "vim: tabstop" -L * | xargs sed -i '1 a // vim: tabstop=3 expandtab shiftwidth=3 softtabstop=3'

xargs is used to pass the file list from egrep to sed.  Just | alone is not enough.

Or we can try like this:-
sed -i '1 a // vim: tabstop=3 expandtab shiftwidth=3 softtabstop=3' `egrep "vim: tabstop" * -L`


Above is just an example.
There are lot of things that we could from the command line instead of writing a script.



Thursday, January 28, 2016

multi line replacement using perl

I want to find all the files in a dir which has the below multi-line pattern
// *
// *
 and replace with 
// *

Typically we might end up in situation like this.. So instead of  writing a script for this, we can make life easier with perl one liner...

perl -0777 -i -pe 's/\/\/ \*\s*\n\/\/ \*\s*\n/\/\/ *\n/g' *

-pie is your standard "replace in place" command-line sequence, and -0777 causes perl to slurp files whole.

Wednesday, January 27, 2016

power of dos2unix

One of the common things occur in our source files is ^M character insertion at the end of the line.
Tricky thing is you can't find this in vim/grep if you search for it.

dos2unix command is the boon for these kind of operations.

dos2unix  filename.sv

Else we can try like below..

sed -i 's/^M$//' filename.sv

Tuesday, January 26, 2016

usefulness of wait fork


We might face the situation where we need to spawn different threads on different sequencers or components and wait for all threads to finish. Immediate idea comes to mind is fork-join but look at the scenario here:-
for(int index=0;index<14;index++)begin
    automatic int idx=index;
    fork
        begin
            `uvm_do_on(sequence_inst,p_sequencer.my_sqr[idx]);
        end
    join_none;
end
And it works fine, except that I'd like to use "join" (all) instead of "join_none" since I have to wait for all the sequences to be completed before continuing the test case.
if we use "join", it looks like the sequences are not forked, but launched one after the other...

What we need to do is to add a wait fork statement after the for loop. This block the current thread until all child threads have completed. You have to be careful if there are any other earlier fork_join_none statements that you do not want to wait for them to finish. If there are, the you need to create an isolating thread.
fork 
  begin : isolating_thread
    for(int index=0;index<14;index++)begin : for_loop
 
      fork
      automatic int idx=index;
        begin
            `uvm_do_on(sequence_inst,p_sequencer.my_sqr[idx]);
        end
      join_none;
    end : for_loop
  wait fork;
  end : isolating_thread
join

Monday, January 25, 2016

some hacks to make life easier..

1. Typically when we switch between laptop to dell monitor, it is better to resize the VNC.
To resize the VNC without creating another VNC session, we can use xrandr. I generally use aliases to switch between laptop and monitor.
alias dellsize "xrandr -s 1920x1080"
alias lapsize "xrandr -s 1360x768

2. If we make set of TB/RTL changes in our local dir and if we want to review one by one against the SVN database, below command will be very useful.
svn diff --diff-cmd tkdiff


3. Vim tips:-

:g/pattern/z#.5|echo "==========" Display context (5 lines) for all occurrences of a pattern.
:g/pattern/normal@c Perform macro recorded at c on all the lines containing the pattern
:v/./,/./-j Merge all blank lines into single blank line
:g/^/m0 Reverse the file
:g/pattern/t$ Copy all the lines matching pattern to the end of the file
0"ay0:g/<pattern>/y A Yank all lines matching a pattern to register 'a'
:g/^/pu _ Double space the file
:.,$g/^\d/exe "normal! \<C-A>" Increment numbers from current line to end-of-document by one (this assumes the default behavior of Ctrl-A to increment a number; you might need :unmap <C-A> on Windows). 
:g/DEBUG/exe "norm! I/*\<Esc>A*/\<Esc>" Comment lines containing "DEBUG" statements in a C program.
:let i=0 | 'a,'bg/xyz/s/xyz/\=i/ | let i=i+1
Insert incremental numbers
:%s/\d\+/\=(submatch(0)+3)/
Increment all the integers by constant
:registers or :reg c Will display the contents of all the registers
:%s/^.*$/\U&/g Changing to Upper case letters
:%s/^.*$/\L&/g Changing to Lower case letters



4. Command line:-
perl -pi -e ’s/lookFor/replaceWith/g’ *.fileExtensionSingle line replace script
perl -n -e 'if ( /<tag/ .. /<\/tag/)' -e '{ print "$.:$_"; }' file.xmlMatch all the patterns from <tag> to </tag> and print
ls abc* | sed 's/\(abc_\)\(.*\)/cp "\1\2" "\2"/' |shCopy files with removing some prefix
echo | mutt -s "simple mail sending perl script but not working" -a send_mail.pl tgunasekaran@micron.comSending mail from Linux server with attachment file
pwd | rev | awk -F \/ '{print $1}' | revExtracting current directory from PWD
bcMathematical calculator in Linux

sed -i".bak" '/max_errors/d' *.pyRemove the line containing max_errors from all *py files. Then remove all *.bak files

Friday, January 22, 2016

starting_phase for uvm sequence

The sequence can be run using 2 methods in UVM.
1. By setting the seq as default_sequence on a specific sequencer

uvm_config_db #(uvm_object_wrapper)::set (this, "env.misc_vsqr.main_phase", "default_sequence",
         test_seq);


2. By starting the seq on a specific sequencer
 test_seq.start(env.misc_vsqr);

Each sequence will have starting_phase and this needs to be passed with correct phase from where it has been called. In default_sequence method, this is taken care as we mention the phase while setting in the config_db.

Whereas in start method, we have to pass explicitly like below:-
test_seq.starting_phase = this.starting_phase;   //If you invoke from uvm_component
test_seq.starting_phase = parent_sequence.starting_phase;   //If you invoke from another uvm_sequence

then, you can call the start method.

Thursday, January 21, 2016

difference between randomize(obj) and obj.randomize

If we randomize the object of a class using obj.randomize(), it will only consider the constraints of that class. Whereas if we pass the object to the randomize() function(equivalent to obj.randomize_with()), it will also consider the constraints pertinent to that object in the parent class. In the below example, test is the parent class to class config. The config class variable (b_v) is constrained in the test class and it will take effect if we pass the object of config class to randomize() in the test class.  


class config;
rand int b_v;
constraint b_c {  b_v inside {[1:5]}; }
function new();
endfunction

function void post_randomize();
  $display("post_randomize b_v=%0d",b_v);
endfunction
endclass : config

class test;
rand int a_v;
constraint b_a_c {  cfg.b_v==5;  }
config cfg;
function new();
  cfg =new();
endfunction

function void build_phase();
  $display("A build_phase");
  randomize(cfg);
  $display("b_v=%0d",cfg.b_v);
  cfg.randomize();
  $display("b_v=%0d",cfg.b_v);
  randomize(cfg);
  $display("b_v=%0d",cfg.b_v);
  cfg.randomize();
  $display("b_v=%0d",cfg.b_v);
endfunction

endclass : test

module test_randomize;
test A;
initial begin
 A=new();
 A.build_phase();
end
endmodule


Answer:-
A build_phase
post_randomize b_v=5
b_v=5
post_randomize b_v=3
b_v=3
post_randomize b_v=5
b_v=5
post_randomize b_v=1
b_v=1