Saturday, 18 June 2016

Task inside Interface

interface simple_bus (input logic clk); // Define the interface
  logic req, gnt;
  logic [7:0] addr, data;
  logic [1:0] mode;
  logic start, rdy;

modport slave(input req, addr, mode, start, clk,
               output gnt, rdy,
               ref data,
               import slaveRead,slaveWrite);
             
//import into module that uses the modport
modport master(input gnt, rdy, clk,
               output req, addr, mode, start,
               ref data,
               import masterRead,masterWrite);
             
//import into module that uses the modport
task masterRead(input logic[7:0] raddr=8'h0); // masterRead method
  $display("Inside Master_Read");
endtask
             
task slaveRead;
  $display("Inside Slave_Read");
endtask
           
task masterWrite(input logic [7:0] waddr=8'h0);
  $display("Inside Master_Write");
endtask
             
task slaveWrite;
  $display("Inside Slave_Write");
endtask
             
endinterface: simple_bus
             
             
module mod (interface i)               ;
  always@(posedge i.clk) begin
     i.slaveRead;
     i.masterRead;
     i.slaveWrite;
     i.masterWrite;
   end              
endmodule
               
module top;
  logic clk = 0;
   simple_bus sb_intf(clk); // Instantiate the interface
   mod m (sb_intf.master) ;

   always #5 clk=!clk;
                 
   initial begin
      #50 $finish;                  
   end                                  

endmodule
Process Control in System Verilog


module test;

  task automatic do_n_way( int N );
  process job[] = new [N];
  foreach(job[j]) begin
    fork
      automatic int k = j;
      begin
        job[k] = process::self();      
        #(5+k);
      end
    join_none
  end

  foreach(job[j]) // wait for all processes to start
    wait( job[j] != null);

  $display("All JOB Started !!",$time);

    job[1].suspend();
 
    job[1].resume();  

    job[1].await();
 
    foreach(job[j]) begin
      if(job[j].status != process::FINISHED )
        job[j].kill();  
    end  
  endtask

  initial begin
    do_n_way(3);
  end

endmodule

//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
/////////////////////Fork JoinExample///////////////////////////
//////////////////////////////////////////////////////////////////////////
module test;

  task automatic do_n_way( int N );
  process job[] = new [N];
  foreach(job[j]) begin
    fork
      automatic int k = j;
      begin
        job[k] = process::self();      
        #(5+k);
      end
    join_none
  end

  foreach(job[j]) // wait for all processes to start
    wait( job[j] != null);

  $display("All JOB Done !!",$time);

    job[1].suspend();
    #15
    job[1].resume();  

    job[0].await();
    //job[1].await();
 
    foreach(job[j]) begin
      if(job[j].status != process::FINISHED )begin
        $display("JOb[%0d] killed with status::%0d @%t",j,job[j].status,$time);
        job[j].kill();  
      end
    end  
 
    foreach(job[j]) begin
      $display("JOb[%0d] status ::%0d  @%t",j,job[j].status,$time);
    end
 
  endtask

  initial begin
   fork  //Try using without fork
    do_n_way(3);
    do_n_way(4);
   join
  end

endmodule


//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////AWAIT Example///////////////////////////
//////////////////////////////////////////////////////////////////////////
module test;

  task automatic do_n_way( int N );
  process job[] = new [N];
  foreach(job[j]) begin
    fork
      automatic int k = j;
      begin
        job[k] = process::self();      
        #(5+k);
      end
    join_none
  end

  foreach(job[j]) // wait for all processes to start
    wait( job[j] != null);

  $display("All JOB Done !!",$time);

    job[1].suspend();
    #15
    job[1].resume();  

    job[0].await();
    job[1].await();
 
    foreach(job[j]) begin
      if(job[j].status != process::FINISHED )begin
        $display("JOb[%0d] killed with status :: ",j,job[j].status);
        job[j].kill();  
      end
    end  
 
    foreach(job[j]) begin
      $display("JOb[%0d] status :: ",j,job[j].status);
    end
 
  endtask

  initial begin
    do_n_way(3);
  end


endmodule  

Monday, 11 April 2016

Binding Multiclock Domain Assertion

///////////////////////////////////////////////////////////
/////////////////// DFF module/////////////////////
///////////////////////////////////////////////////////////
module dff(
           input wire din,clk,rstn,
           output reg qout
          );
         
always@(posedge clk,negedge rstn)
  begin
    if(~rstn)
      qout<=0;
    else
      qout<=din;
  end
endmodule

///////////////////////////////////////////////////////////
/////////////////// DUT module////////////////////
///////////////////////////////////////////////////////////
module DUT (
            input rst1,rst2,clk1,clk2,in1,in2,in3,
            output  out
           );  

  wire qout1,qout2,and_out;

  dff dff1(.din(in1),.clk(clk1),.rstn(rst1),.qout(qout1));  
  assign and_out=qout1 & in2;

  dff dff2(.din(and_out),.clk(clk2),.rstn(rst2),.qout(qout2));  
  assign out=qout2 | in3;          

endmodule

///////////////////////////////////////////////////////////
/////////////////// ASSERTION Module////////
///////////////////////////////////////////////////////////
module dut_assertions(
                      input  wire rst1,rst2,clk1,clk2,in1,in2,in3,out
            );
reg val1,val2,val3;
 
 //sequence seq1(val1,val2); 
  //@(posedge clk1)
  //(1'b1,val1=in1) ##0(1'b1,val2=in2);
 //endsequence

  sequence seq1;
   (1,assign12_t);
  endsequence

 //sequence seq2(val3);
  //@(posedge clk2)
  //(1'b1,val3=in3);
 //endsequence

  sequence seq2;
   (1,assign3_t);
  endsequence

//property p(val1,val2,val3);
 //(@(posedge clk1) disable iff (!rst1) (rst1 throughout seq1(val1,val2))) |->  (@(posedge clk2) disable iff (!rst2) (rst2 throughout seq2(val3)));
//endproperty

  property p;
    (@(posedge clk1)  (rst1 throughout seq1)) ##1  (@(posedge clk2) (rst2 throughout seq2));
  endproperty

//assert property (p(val1,val2,val3))  begin
  assert property (p)  begin
///////////////////////////////////////////////////////////
//// Assertion Action Block Verifying DUT functionality////
///////////////////////////////////////////////////////////
  case({val1,val2,val3})
    3'b000,3'b010,3'b100 :
       begin
         if(!out)
           $display("DUT check passed for %b Out1=%b",{val1,val2,val3},out);
         else
           $error("DUT check failed for %b Out1=%b",{val1,val2,val3},out);    
       end
    3'b001,3'b011,3'b101,3'b110,3'b111 :
       begin
         if(out)
           $display("DUT check passed for %b Out2=%b",{val1,val2,val3},out);
         else
           $error("DUT check failed for %b Out2=%b",{val1,val2,val3},out);    
        end
   endcase
end
else  begin
  $error("Assertion failed");    
end
/////////////////////////////////////////////////////////////
////// Task holding values of in1 and in2////
/////////////////////////////////////////////////////////////
 task assign12_t;
   $display($time,"val1:%b ,val2:%b ,val3:%b",in1,in2,in3);
   val1=in1;
   val2=in2;  
 endtask
/////////////////////////////////////////////////////////////////
//////// Task holding values of in3 /////////////////
//////////////////////////////////////////////////////////////////
 task assign3_t;
   $display($time,"val1:%b, val2:%b ,val3:%b",in1,in2,in3);
   val3=in3;  
 endtask
   
endmodule
 
/////////////////////////////////////////////////////////////////////////
/////Binding DUT and ASSERTION Module//////////
//////////////////////////////////////////////////////////////////////////
module bind_assertion ();
  //bind DUT dut_assertions DUT_ASSERT(.rst1(rst1),.rst2(rst2),.clk1(clk1),.clk2(clk2),.in1(in1),.in2(in2),.in3(in3),.out(out));
  bind DUT dut_assertions DUT_ASSERT(.*);

endmodule


///////////////////////////////////////////////////////////////////////////
////////////////// DUT TEST MODULE ////////////////////////
///////////////////////////////////////////////////////////////////////////
module test;
  reg rst1,rst2,clk1,clk2,in1,in2,in3;
  wire out;              

  DUT dut_inst(.rst1(rst1),.rst2(rst2),.clk1(clk1),.clk2(clk2),.in1(in1),.in2(in2),.in3(in3),.out(out));
  //DUT dut_inst(.*);

always #5 clk1=~clk1;
always #10 clk2=~clk2;

initial begin
  clk1=0;clk2=0;
  rst1=1;rst2=1;
  in1=0;in2=1;in3=1;
  #10 rst2=0;

  #15 rst2=1;
  #10 rst1=0;
  #15 rst1=1;
  in1=0;in2=0;in3=0;
  #50 $finish;
end    
endmodule






Wednesday, 6 April 2016

 Generating Unique Random Values for Array.
 [Supported in IEEE 1800-2012] 


1). Randomizing all 32 members of array ,each member with 16 bit width

   class  random_unique_array_c;
       rand bit [15:0] uniq_arr [31:0];
       constraint  unique_cnstnt {unique {uniq_arr };}
   endcalss : random_unique_array_c


2). Randomizing all 32 members of array ,each member with 16 bit width, with exclusion of  some values.

   class  random_unique_array_c;
       rand bit [15:0] uniq_arr [31:0];
               bit [15:0] exclude_val [ ] = {3,6,9};
       constraint  unique_cnstnt {unique {uniq_arr,exclude_val,12 };}   //uniq_arr will not have values
   endcalss : random_unique_array_c                                                     //3,6,9,12



For more info see IEEE 1800-2012 LRM  section  18.5.5 "Uniqueness constraints"


Monday, 7 December 2015

Static Variable Example

class test; 
  static int count=0;
  int id;
 
  function new();
    id=count++;
  endfunction
 
endclass


module test1;
  test t1;
 
  initial
    begin
      for(int i=0;i<5;i++)begin
        t1=new;
        $display("id : %0d , count : %0d",t1.id,t1.count);
      end     
    end
 
endmodule


OUTPUT:
id : 0 , count : 1
id : 1 , count : 2
id : 2 , count : 3
id : 3 , count : 4
id : 4 , count : 5



Saturday, 5 December 2015

1.Dynamic array of queue
2.Queue of queue
3.Associative array of queue



module array_of_queue;

typedef int qint_t[$];

// dynamic array of queues
qint_t DAq[]; // same as int DAq[][$];

// queue of queues
qint_t Qq[$]; // same as int Qq[$][$];

// associative array of queues
qint_t AAq[string]; // same as int AAq[string][$];

initial begin

// 1).Dynamic array of 5 queues
DAq = new[5];
// Push something onto one of the queues
DAq[3].push_back(7);
// initialize another queue with three entries
DAq[0] = {1,2,3,4,5};
  $display("%p",DAq);

// 2).Queue of queues -two
  Qq= '{'{1,2},'{3,4,5}};
Qq.push_back(qint_t'{6,7});
Qq[2].push_back(1);
  $display("%p",Qq);

// 3).Associative array of queues

AAq["one"] = {};
AAq["two"] = {1,2,3,4};
AAq["one"].push_back(5);
  $display("%p",AAq);
end

endmodule
-------------------------------------------------------------------------
OUTPUT:

'{'{1, 2, 3, 4, 5} , '{}, '{}, '{7} , '{}}
'{'{1, 2} , '{3, 4, 5} , '{6, 7, 1} }
'{"one":'{5} , "two":'{1, 2, 3, 4} } 


Wednesday, 28 October 2015

linux  grep  command with logical OR/AND operation


->OR  Operation
grep -nrl --color 'TOM \| DICK \|  HARRY' --include="*.txt"  *
grep -nrl --color 'sav2_base_test\|run_phase\|main_phase' --include="*.txt" * | wc -l                                    
This command lists TXT file names containing any of these keywords TOM , DICK or HARRY anywhere in file.

->AND Operation
grep -l  TOM * --include="*.txt" | xargs grep -l DICK | xargs grep -l HARRY 
grep -l  TOM * --include="*.txt" | xargs grep -l DICK | xargs grep -l HARRY | wc -l

This command lists TXT file names containing all of these keywords TOM , DICK or HARRY anywhere in file.


-->Find particular keyword and replace by other keyword in all files of given directory
find . -type f -exec sed -i 's/TOM/TOMMY/g' {} +
 
This command replaces all keywords TOM by TOMMY in all files of current directory.
For more info visit.
http://unix.stackexchange.com/questions/112023/how-can-i-replace-a-string-in-a-files 

Wednesday, 26 August 2015

System Verilog Queue Example

module queues;
byte qu [$] ;

initial
  begin
    qu.push_front(1);
    qu.push_front(2);
    qu.push_front(3);
    qu.push_back(4);
    qu.push_back(5);

    foreach(qu[i])begin
      $display(i,qu[i]);
    end

    qu.delete(3);                                          //Delete element at index 3

    $display(" %d ",qu.pop_front() );       // pop_front operation removes first element
    $display(" %d ",qu.size() );

    foreach(qu[i])begin
      $display(i,qu[i]);
    end

    $display(" %d ",qu.pop_back() );    // pop_back operation removes last element

    foreach(qu[i])begin
      $display(i,qu[i]);
    end

  $display(" %d ",qu.size() );
  end
endmodule

OUTPUT:

0 3
1 2
2 1
3 4
4 5

3
//pop front

0 2
1 1
2 5

5 //pop back

0 2
1 1

2

Monday, 22 June 2015

System Verilog Process

How to disable particular process of fork...join,executing multiple processes in parallel.


class a;
  int v;

  task t1();
    for(int i=0;i<10;i++) begin
      #1 v=i;
      $display("I value=%0d",v);
    end
  endtask:t1
 
   task t2();
     for(int i=10;i<20;i++)begin
       #1 v=i;
       $display("I value=%0d",v);
     end 
  endtask :t2
 
  task t3();
    process job_id[2];                                 //Process Identifier
    fork
       begin:t1p
         job_id[0] = process::self();
         t1();
       end 
       begin:t2p
         job_id[1] = process::self();
         t2();
       end 
       begin:t3p
         int j;
         forever begin
           @(v)begin
           $display($time,"forever",j);
           j++;
             if(v==14)begin
               job_id[0].kill();                         //Kill process executing task t1();
             $display("Entered");
             //disable t1p;
             break;
          end
         end
          
         end
       end 
    join
  endtask :t3     
 
endclass:a


module test();
  a a1;
  initial
    begin
      a1=new();
      a1.t3();     
    end
endmodule

Note:-Why can't simple disable ...fork statement can be used....?????

Wednesday, 22 April 2015

Linux Grep Command


grep "literal_string" filename
 
grep "string" FILE_PATTERN
 
grep -i "string" FILE
 
grep "REGEX" filename
 
grep -iw "is" demo_file
 
grep -A <N> "string" FILENAME
 
grep -B <N> "string" FILENAME
 
grep -C 2 "Example" demo_text 

export GREP_OPTIONS='--color=auto' GREP_COLOR='100;8'
grep this demo_file
 
grep -r "DJ" * 

grep -v "go" demo_text
 
grep -v -e "pattern" -e "pattern"
 
grep -c "pattern" filename
 
grep -v -c this demo_file
 
grep -l this demo_*
 
grep -o "is.*line" demo_file
 
grep -o -b "pattern" file
 
grep -n "go" demo_text 

Friday, 30 May 2014

Skew,Global Skew,Local Skew,Useful Skew

Skew
• The difference in the arrival of clock signal at the clock pin of different flops.
• Three types of skews are defined: Local skew and Global skew and Useful skew.

Local skew
 The difference in the arrival of clock signal at the clock pin of related flops.

Global skew
The difference in the arrival of clock signal at the clock pin of non related flops.

Useful skew
If clock is skewed intentionally to improve setup slack then it is known as useful skew.

Useful skew is a concept of delaying the capturing flip-flop clock path, this approach helps in meeting setup requirement with in the launch and capture timing path. But the hold-requirement has to be met for the design.

Skew can be positive or negative.
 When data and clock are routed in same direction then it is Positive skew.
 When data and clock are routed in opposite then it is negative skew.


ASIC FLOW vs PHYSICAL DESIGN FLOW


ASIC flow is completely from scratch to end flow i.e. It includes market research, Architecture specification ,RTL coding  and Logic synthesis and other many more phases.


On otherhand  Physical Design flow in simple terms is Netlist to GDS II(Graphic Database System) flow.
Below figure will help you to understand the difference clearly.