Thursday, November 4, 2010

SystemVerilog Q&A

1.  What's difference between static and automatic task/program?

    If you use static task for multiple places in your testbench,  the local variables will share the common, static storage. In this case, different threads will step on each other's values.
   By using atuotmic storage, it will make a copy of local variables and use them. Not a common static storage any more.

  e.g.  program automatic initialization;
         ......
        endprogram


2. What's the packed array and unpacked array?

    unpacked array is an array with gap between variables.

   e.g.  bit[7:0]  b_unpack[3];   // unpacked
          The system verilog simulators store each element on a 32-bit word boundary. In other words, you are using only lower 8 bits, the other 24 bits per word space is wasted.

    Packed array is an array without gap. Unpacked array is good for local individual variable access.

   e.g. bit[3:0] [7:0] bytes; // 4 bytes packed into 32 bits

    In this case, all 32 bits word are packed with 4 bytes. A packed array is handy if you need to convert to and from scalars.

3.  What's different between logic and wire?

     Logic and wire are almost the same except wire can be driven by multiple sources. Logic can only driven by single source.

Sunday, October 31, 2010

Systemverilog Assertion (SVA) 2

Working Assertion Examples:

Normal inline assertion example:


assertStateStartShortFalse:
  assert property (@(posedge clk) disable iff(!reset_n)
  (state==`START) |-> (short==FALSE))
  else $display("Error state START and short is true  ");


Normal Assertion compile with VCS with +assert option
// Assertion example for parity checking
module check_par(clk, parity, data);
input clk, parity;
input [31:0] data;

property p_check_par;
@(posedge clk)  (^(data^parity)) == 1’b0;
endproperty
a_check_par: assert property(p_check_par);
endmodule


binddata_bus check_par u1(clk, parity, data);
bindtop.mid.u1 check_par u2(clk, parity, data);

For OVL, use +define+OVL_ASSERT_ON for OVL.
 
ovl_even_parity

[#(severity_level, width, property_type, msg, coverage_level,

clock_edge, reset_polarity, gating_type)]

instance_name (clock, reset, enable, test_expr, fire);
 
ovl_even_parity top.u1(clk, reset, 1, (^(data^parity)));
 

SVA ( System verilog Assertion)

1.  What are difference between SVA and other assertions?

Answer: Systemverilog Assertions (SVA) are temporal, Declarative and formal friendly.
             Temporal : Design Variables relationship in time
             Declarative: Orthogonal to procedural form in design (describe what instead of how )
             Synthesizable: Good for dynamic and formal verification.
             SVA provides interoperability with RTL, testbench features and functional coverage.

2.  What are the benefits of using assertions?
 
Answer:      1) Improve error detection
                   2) Better observability
                   3) Shortens debug time
 
3. Who writes Assertions?

 Answer:  White box (Designers)  , Black box (DV)

4.  How many ways to connect assertion to RTL?

Answer: There are 3 ways to connect assertion to RTL: inline, Instantiation and Virtual Instantiation (bind).

             Inline Assertion:  Assertion directly put into the RTL by designer. Use compile option for synthesis.

For example: 
// A synchronous D Flip-Flop
moduledff (input logic [7:0] D, input RST_, input CLK, output logic [7:0] Q);
always @(posedge CLK)
if (!RST_) Q<= 8'h0;
else Q <= D;

// assertions
propertyd_q_property_0 (clk, rst_, q);
@(posedge clk) !rst_ |->##1(q == 8'h0);
endproperty
assert_d_q_property_0 : assert property(d_q_property_0(CLK, RST_, Q));

endmodule

Assertion Instantiation: Put assertion into another module and use it again by RTL designers.

For example:

moduledff (input logic [7:0] D, input RST_, input CLK, output logic [7:0] Q);
always @(posedge CLK)
if (!RST_) Q<= 8'h0;
else Q <= D;

// Use assertion module here
dffChecker #(8) Chk0(CLK, RST_, D, Q);

endmodule  

moduledffChecker (clk, rst_, d, q);
parameter WIDTH = 8;
input clk, rst_;
input [WIDTH-1:0] d, q;
propertyd_q_property_0;
@(posedge clk) !rst_ |->##1 (q == 8'h0);
endproperty
assert_d_q_property_0 : assert property(d_q_property_0);
endmodule

Virtual Instantiation (bind): Use bind method to connection both modules together. It's a saftest method for DV because it did not change RTLs. Plus we can use OVL for most of common checkers.

For examples:
binddff dffChecker #(8) Chk0(CLK, RST_, D, Q);

Saturday, June 5, 2010

SystemVerilog Interview Questions

1.   How many array types in SystemVerilog? How do you use them?

      array_name[ ]  dynamic array

      e.g .   dyna_arr_1 = new[100] (dyna_arr_1);
               dyna_arr_2 = new[4]('{4,5,6}); // elements are {4,5,6,0}
     
      array [5]    fixed array
      e.g.   register1 [6][7:0] = `1;
 
      array[$]   queue
     e.g.  int q[$] = { 2, 4, 8 };
             q = {};                // clear the queue (delete all items)
             e = q[0];              //  read the first (leftmost) item
             e = q[$];              //  read the last (rightmost) item 

      array[string] or array[%] associate array
     e.g.  //associative array of 4-state integers indexed by strings, default is '1.
      integer tab [string] = '{"Peter":20, "Paul":22, "Mary":23, default:-1 };
  
2)  What is the Polymorphism?

    Polymorphism allows an entity to take a variety of representations. Polymorphism means the ability to request that the same Operations  be performed by a wide range of different types of things. Effectively, this means that you can ask many different objects to perform the same action.  Override polymorphism is an override of existing code. Subclasses of existing classes are given a "replacement method" for methods in the superclass. Superclass objects may also use the replacement methods when dealing with objects of the subtype. The replacement method that a subclass provides has exactly the same signature as the original method in the superclass. 

EXAMPLE: with virtual
      class A ;
      virtual  task disp ();
                $display(" This is class A ");
           endtask
      endclass
     
      class EA extends A ;
            task disp ();
                $display(" This is Extended class A ");
            endtask
      endclass
     
      program main ;
           EA my_ea;
           A my_a;
          
           initial
           begin
                my_a = new();
                my_a.disp();
               
                my_ea = new();
                my_a = my_ea;
                my_a.disp();
           end
      endprogram

RESULTS

 This is class A
 This is Extended class A


3)  how the copy works?


Answers:  
    There are 2 types of copy. Show copy or deep copy


    For example:


    class B; 
        int 
    endclass


   

     program main;
         initial
         begin
             B b1;
             B b2;
             b1 = new();
             b1.i = 123;
             b2 = b1;                   // b1 and b2 point to the same memory. The properties did not get copied.
             $display( b2.i );
         end
     endprogram
RESULTS:

123


 A shallow copy of an object copies all of the member field values.
  program main;
          initial
          begin
              B b1;
              B b2;
              b1 = new();
              b1.i = 123;
              b2 = new b1;    // shallow copy of b1
              b2.i = 321;
              $display( b1.i );
              $display( b2.i );
          end
     endprogram
    
RESULTS:

        123
        321
 
If the value of b1 change, it will also change the value of b1. It's because it's pointing to the same memory.


To avoid this, we need to use the deep copy.


Deep Copy

A deep copy copies all fields, and makes copies of dynamically allocated memory pointed to by the fields. To make a deep copy, you must write a copy constructor and overload the assignment operator, otherwise the copy will point to the original, with disasterous consequences.


EXAMPLE:
    class A;
        int i;
    endclass
   
    class B;
        A a;

        task copy(A a);
            this.a = new a;
        endtask

    endclass
   
    program main;
        initial
        begin
            B b1;
            B b2;
            b1 = new();
            b1.a = new();
            b1.a.i = 123;
            b2 = new b1;
            b2.copy(b1.a);
            $display( b1.a.i );
            $display( b2.a.i );
            b1.a.i = 321;
            $display( b1.a.i );
            $display( b2.a.i );
           
        end
    endprogram

RESULTS:

        123
        123
        321
        123



Wednesday, June 2, 2010

New interview questions

1) There is a waveform

    in _____|====|________
    out_____|=|___|=|______

    The output is "high" when the input change the value.

    Verilog code
   
    always@(posedge clk or reset)
   begin
      if(!reset)
      begin
        in_reg <= 1'b0;    // initial value
        out      <= 1'b0;
     end
    else
    begin
             if(in != in_reg)
             begin
                      out <= 1'b1;
                      in_reg <= in;
             end
            else
                     out <= 1'b0;
    end
   end

   After synthesis, what will it be look like?

   It's like a D-FF and a XOR

   in -----D_FF------in_reg---|XOR|  ___   out
         |__________________|        |

2)   How to write a C or C++ code for Strlen

Answer:
     
    int strlen (char *s)
     begin
          for (int len =0; *s='\0'; s++)
               len++;
          return (len);
     end
  
    Use recurve way

    int strlen_r (char *s)
    begin
             if(*s='\0')  return 0;
             else  return (1 + strlen_r(s+1));   
     end
   

   
  


    

Sunday, May 30, 2010

C++ basic interview questions

1) How do you swap two integers? Without another variable?

Answer:

   example main.cpp

   void main()
   {
      int a=2, b=3;
      swap (a, b);
   }


    swap ( int &a, int &b)   // pass by reference
   {
    int tmp = a;
   a = b;
   b = tmp;
  }

   Without a third variable
   swap ( int &a, int &b)
  {
       a = a +b;   // a = 2 +3 =5
       b = a-b;    // b = 5-3 =2
       a = a -b;   // a = 5 - 2 = 3, a and b swap
   }

  template < class T>
  void swap ( T &a, T &b)
  {
                     T tmp =a;
                     a = b;
                     b = tmp;
  }
  use swap (a, b ) to call the swap. It can swap any data type.

C++ Interview algorithms questions

1) Reverse a single linked list

Answer code:

Node* ReverseList(Node ** List)       // Provide a link list
{
      // Declare 3 pointer variable
      Node *head   =  *List; 
      Node *temp2 = NULL;
      Node *temp3 =NULL;

      while(head)
     {
          *List = head; // set the head to last node
           temp2 = head->pNext;     // save the next ptr in the temp2
           head->pNext = temp3;     // change next to previous
           temp3 = head;
           head = temp2; 
      }
}

Diagram detail:

    List linked list  [ 1 ] ->;   [ 2 ] ->;   [ 3 ] ->;
               1)         *List= head;  // Set head point to the last node
               2)         temp2 = head->pNext; //   saved as temp2   ( temp2 point to ptr2 )
               3)         head ->pNext = temp3;  // at the first round, it point to the null  
               4)        temp3 = head;   // set temp3 as head   ( temp3 point to ptr1)
               5)        head = temp2;   // get back the temp2 location ( head point to ptr2 ) 
               second round
               6)         *List= head;  // Set head point to the last node ( head to ptr2 )
               7)         temp2 = head->pNext; //   saved as temp2   ( temp2 point to ptr3 )
               8)         head ->pNext = temp3;  // at the second round, it point ptr 1  
               9)         temp3 = head;   // set temp3 as head   ( temp3 point to ptr2 )

               10)        head = temp2;   // get back the temp2 location ( head point to ptr3 ) 
             
        
2) Delete a node in double linked list

Answer:
        Doubly linked lists are like singly linked lists, except each node has two pointers -- one to the next node, and one to the previous node. This makes life nice in many ways:
  • You can traverse lists forward and backward.
  • You can insert anywhere in a list easily. This includes inserting before a node, after a node, at the front of the list, and at the end of the list.
  • You can delete nodes very easily.


    void deleteNode( Node *n)
    {
      node *np = n->prev;    // set np pointer to the n->prev
      node *nn = n->next;    // set nn pointer to the n->next
      np->next = n->next;    // skip n node
     nn->prev = n->prev;    // skip n node
     delete n;
    } 

    Diagram:

    [  np ]  ->;  [ n  ] ->;  [ nn  ] ->;


 3)  Sort a linked list
 
     // Sorting in descending order
     struct node
    {
           int value;
           node* NEXT;
    }

   // start the sorting
   sort (node *head)     // pass the linklist head to the function
   {
      node* first, second, temp;   // define 3 nodes variable
      first = head;   // set first as head
      while(first!=null)   // check first is not empty link list
      {
               second = first->NEXT;
               while(second !=null )   // check the end of linked list  
               {
                         if(first->value  > second->value)
                         {
                                 temp = new node();  // allocate memory
                                temp->value = first->value;
                                first->value = second->value;
                                second->value = temp->value;
                                delete temp;   // release the memory
                          }
                         second= second->NEXT;
                }
               first=first->NEXT;
       } 
   }


4) Reverse a string
 
Answer:

     void ReverseString ( char *String)
     {
            char *Begin = String;    // set up 2 pointer, one for the beginning of the spring address
            char *End = String + strlen(String) -1;   // point to the end of the spring address
            char tempChar ='\0';    // end of line
  
            while (Begin < End)
           {
                   TempChar = *Begin;
                   *Begin = *End;
                   *End = *TempChar;
                   Begin++;
                   End--;
            }      
     }

Wednesday, April 21, 2010

SystemVerilog Interview Question 9

1)  How to kill a process in fork/join?

The kill() task terminates the given process and all its sub-processes, that is, processes spawned using fork statements by the process being killed. If the process to be terminated is not blocked waiting on some other condition, such as an event, wait expression, or a delay then the process shall be terminated at some unspecified time in the current time step.

2)  What is cross coverage ?

Cross allows keeping track of information which is received simultaneous on more than one cover point. Cross coverage is specified using the cross construct.


    program main;
    bit [0:1] y;
    bit [0:1] y_values[$]= '{1,3};
   
    bit [0:1] z;
    bit [0:1] z_values[$]= '{1,2};
   
    covergroup cg;
        cover_point_y : coverpoint y ;
        cover_point_z : coverpoint z ;
        cross_yz : cross cover_point_y,cover_point_z ;                 
    endgroup
   
    cg cg_inst = new();
    initial
       foreach(y_values[i])
       begin
           y = y_values[i];
           z = z_values[i];
           cg_inst.sample();
       end
   
    endprogram








3)  Why always block is not allowed in program block?






The program block does not allow always block. Only initial and methods are allowed, which are more controllable.

4) What is final block ?



SystemVerilog final blocks execute in an arbitrary but deterministic sequential order. This is possible because final blocks are limited to the legal set of statements allowed for functions.


EXAMPLE :
   module fini;
 
      initial
         #100 $finish;
     
      final
         $display(" END OF SIMULATION at %d ",$time);
   endmodule
RESULTS:

SystemVerilog Interview Questions 7

1)  Difference between Associative array and Dynamic array ?

Answer: 

    Dynamic arrays are useful for dealing with contiguous collections of variables whose number changes dynamically.
    e.g.            int array[];
    When the size of the collection is unknown or the data space is sparse, an associative array is a better option. In associative array, it uses the transaction names as the keys in associative array.
   e.g.            int array[string];




2)  What are the advantages of SystemVerilog DPI?


SystemVerilog introduces a new foreign language interface called the Direct Programming Interface (DPI). The DPI provides a very simple, straightforward, and efficient way to connect SystemVerilog and foreign language code unlike PLI or VPI. 




3)  What is bin?


A coverage-point bin associates a name and a count with a set of values or a sequence of value transitions. If the bin designates a set of values, the count is incremented every time the coverage point matches one of the values in the set. If the bin designates a sequence of value transitions, the count is incremented every time the coverage point matches the entire sequence of value transitions.

e.g.
program main;
    bit [0:2] y;
    bit [0:2] values[$]= '{3,5,6};
   
    covergroup cg;
      cover_point_y : coverpoint y
                      { option.auto_bin_max = 4 ; }
    endgroup
   
    cg cg_inst = new();
    initial
      foreach(values[i])
      begin
         y = values[i];
         cg_inst.sample();
      end
   
  endprogram



4) What are void functions ?


The function does not have return value


5)   What is coverage driven verification?


Coverage Driven Verification is a result oriented approach to functional verification. The manager and verification terms define  functional coverage points, and then work on the detail of process.
Used effectively coverage driven verification focuses the Verification team on measurable progress toward an agreed and comprehensive goal.



6)  Explain about pass by ref and pass by value?
Pass by value is the default method through which arguments are passed into functions and tasks. Each subroutine retains a local copy of the argument. If the arguments are changed within the subroutine declaration, the changes do not affect the caller.


In pass by reference functions and tasks directly access the specified variables passed as arguments.Its like passing pointer of the variable.


example:
task pass(int i)    //  task pass(var int i) pass by reference
{
delay(10);
i = 1;
printf(" i is changed to %d at %d\n",i,get_time(LO) );
delay(10);
i = 2;
printf(" i is changed to %d at %d\n",i,get_time(LO) );
}


7)  What is the difference between program block and module ?


The module is the basic building block in Verilog which works well for Design. However, for the testbench, a lot of effort is spent getting the environment properly initialized and synchronized, avoiding races between the design and the testbench, automating the generation of input stimuli, and reusing existing models and other infrastructure.

Systemverilog adds a new type of block called program block. Systemverilog adds a new type of block called program block. The program construct serves as a clear separator between design and testbench, and, more importantly, it specifies specialized execution semantics in the Reactive region for all elements declared within the program. Together with clocking blocks, the program construct provides for race-free interaction between the design and the testbench, and enables cycle and transaction level abstractions.







8)   Describe the difference between Code Coverage and Functional Coverage Which is more important and Why we need them.


      Code Coverage indicates the how much of RTL has been exercised. The Functional Coverage indicates which features or functions has been executed. Both of them are very important.  With only Code Coverage, it may not present the real features coverage. On the other hand, the functional coverage may miss some unused RTL coverage.








     

SystemVerilog Interview Questions 6

1)  What is the difference between $random and $urandom?

 Answer:

    The functionality of the seed arguments are different for $random and $urandom. The seed argument to $random is an inout. It updates its seed argument after each call to $random. This means the internal random number generator (RNG) state variable is a 32-bit number.

The seed argument to $urandom is an input. This seed is used to set the internal RNG to a value that is over 32-bits (typically 96-bits or greater).

In SystemVerilog, each thread has its own RNG, so only use the the seed argument on the first call to $urandom in each thread. There is also a way to set the seed without generated a random value by using the built-in process class and using the srandom() method.


class packet;
rand bit [7:0] header;

function new(int seed);
this.srandom(seed);
endfunction
endclass

initial begin
packet p=new;
p.new(33);
end


2) How do we get seed or use single seed in the VMM ?

  Method 1: Let it random by itself
   In VMM , VCS usually prints it to log file.  Recently it added a system task to get the seed, something like: $get_initial_random_seed()
  
   Use the following command to put seed back to get the same result "+nbt_random_seed=".

   Method: Fix the seed.
   The better approach is to use srandom task/function to fix the seed. We can increase the seed by 1 or use other script to generate the seed. The start seed is only start the regression. It has enough randomize with the test environment. 
   
EXAMPLE:
class Rand_seed;
 rand integer Var;
 function new (int seed);
   srandom(seed);
   $display(" SEED is initised to %0d ",seed);
 endfunction

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

program Rand_seed_p_80;
  Rand_seed rs;
  initial
  begin
    rs = new(20);
    repeat(5)
      void'(rs.randomize());
    rs = new(1);
    repeat(5)
      void'(rs.randomize());
    rs = new(20);
    repeat(5)
      void'(rs.randomize());
  end
endprogram

SystemVerilog Interview Question 5

1) What is the use of modports ?

Answer:
Modport restrict interface access within a module based on the direction declared. Directions of signals are specified as seen from the module.

e.g.
interface intf (input clk);
        logic read, enable,
        logic [7:0] addr,data;
       
        modport dut (input read,enable,addr,output data);
        modport tb (output read,enable,addr,input data);
    endinterface :intf

2) How parallel case and full cases problems are avoided in SV?

The full_case and parallel_case directives are dangerous because they tell the synthesis tool
something different about the design than what is told to the simulator.

To the Verilog simulator, full_case and parallel_case are buried inside of Verilog
comments and are completely ignored. To the synthesis tool, full_case and parallel_case
are command-directives that instruct the synthesis tools to potentially take certain actions or
perform certain optimizations that are unknown to the simulator.


A full case statement is a case statement in which all possible case-expression binary patterns
can be matched to a case item or to a case default.

e.g. Full case, sel=2'b11 will be covered by default statement.
     The x-assignment will also be treated as a don'tcare for synthesis, which may allow the synthesis tool to further optimize the synthesized design. It's the potentially causing a mismatch to occur between simulation and synthesis. To insure that the pre-synthesis and post-synthesis simulations match, the case default could assign the y-output to either a
predetermined constant value, or to one of the other multiplexer input values

module mux3c
(output reg y,
input [1:0] sel,
input a, b, c);
always @*
case (sel)
2'b00: y = a;
2'b01: y = b;
2'b10: y = c;
default: y = 1'bx;
endcase
endmodule


// Use synopsys full_case statement to create the full case , but it treated differently in simulation and synthesis.
module mux3b (y, a, b, c, sel);
(output reg y,
input [1:0] sel,
input a, b, c);
always @*
case (sel) // synopsys full_case
2'b00: y = a;
2'b01: y = b;
2'b10: y = c;
endcase
endmodule

SystemVerilog use priority modified case statement to solve the full case problem.
The biggest difference between a full_case directive and a priority modified case statement
is that the priority keyword is part of the SystemVerilog syntax that will be interpreted the
same by simulators, synthesis tools and formal verification tools. In essence, the priority case
statement is a "safe" full_case case statement.

e.g.
priority case (...)
...
endcase

A parallel case statement is a case statement in which it is only possible to match any case
expression to one and only one case item.

e.g. A parallel case statement

module intctl1b
(output reg int2, int1, int0,
input [2:0] irq );
always @* begin
{int2, int1, int0} = 3'b0;
casez (irq) // synopsys parallel_case
3'b1??: int2 = 1'b1;
3'b?1?: int1 = 1'b1;
3'b??1: int0 = 1'b1;
endcase
end
endmodule

This is an example that demonstrates that adding the parallel_case directive makes the design
smaller and faster, but in the process it also adversely changes the functionality of the design.

SystemVerilog adds the new case statement modifier called "unique."
The unique keyword shall cause the simulator to report a run-time error if a case expression is
ever found to match more than one of the case items. In essence, the unique
case statement is a "safe" parallel_case case statement.

unique case (...)
...
default: ...
endcase

Guideline: Code all intentional priority encoders using if-else-if statements. It is easier for
the typical design engineer to recognize a priority encoder when it is coded as an if-else-if
statement.

SystemVerilog interview Questions 4

1) How to call the task which is defined in parent object into derived class ?




Answer:
The super keyword is used from within a derived class to refer to members of the parent class. It is necessary to use super to access members of a parent class when those members are overridden by the derived class.

EXAMPLE:
    class parent;
        task printf();
            $display(" THIS IS PARENT CLASS ");
        endtask
    endclass
   
    class subclass extends parent;
        task printf();
            super.printf();
        endtask
    endclass
   
    program main;
   
        initial
        begin
            subclass s;
            s = new();
            s.printf();
        end
    endprogram

RESULT

 THIS IS PARENT CLASS

2)  What is the difference between rand and randc?


Answer:
rand  are standard random variables. When there are no other control on distrubution, these variables are uniformly distributed across valid values.

 randc are random cyclic that randomly iterates over all the values in the range and no value is repeated with in an iteration until every possible value has been assigned.    
 
3) What is solve...before constraint ?

Answer:
constraint order { solve a before b ;}
This guides the solver to give highest priority to a than b while picking the solution from solution space.

Answer:
4) What is the difference between fork/joins, fork/join_none fork/join_any ?

Fork Join None: The parent process continues to execute concurrently with all the processes spawned by the fork. The spawned processes do not start executing until the parent thread executes a blocking statement.

Fork Join Any:  The parent process blocks until any one of the processes spawned by this fork completes.

For Join All:   The parent process blocks until all the processes spawned by this fork complete.

Systemverilog Interview Questions 3

1) What is the difference between mailbox and queue?

Answer:

A queue is a variable-size, ordered collection of homogeneous elements. A Queue is analogous to one dimensional unpacked array that grows and shrinks automatically. Queues can be used to model a last in, first out buffer or first in, first out buffer.

// Other data type as reference
// int q[]; dynamic array
// int q[5]; fixed array
// int q[string]; associate array
// include <
// List#(integer) List1;    //


int q[$] = { 2, 4, 8 };
int p[$];
int e, pos;
e = q[0]; // read the first (leftmost) item
e = q[$]; // read the last (rightmost) item
q[0] = e; // write the first item
p = q; // read and write entire queue (copy)


A mailbox is a communication mechanism that allows messages to be exchanged between processes. Data can be sent to a mailbox by one process and retrieved by another. 


2) What data structure you used to build scoreboard?


Answer:

    In SV, we use mailbox to get data from different modules and compare the result.

class Scoreboard;

mailbox drvr2sb;
mailbox rcvr2sb;

function new(mailbox drvr2sb,mailbox rcvr2sb);
  this.drvr2sb = drvr2sb;
  this.rcvr2sb = rcvr2sb;
endfunction:new


task start();
  packet pkt_rcv,pkt_exp;
  forever
  begin
    rcvr2sb.get(pkt_rcv);
    $display(" %0d : Scorebooard : Scoreboard received a packet from receiver ",$time);
    drvr2sb.get(pkt_exp);
    if(pkt_rcv.compare(pkt_exp))
    $display(" %0d : Scoreboardd :Packet Matched ",$time);
    else
      $root.error++;
  end
endtask : start

endclass



In VMM, we use channels to connect all the modules and compare the result.


class Scoreboard extends vmm_xactor;

   Packet_channel   drvr2sb_chan;
   Packet_channel   rcvr2sb_chan;


function new(string inst = "class",
             int unsigned stream_id = -1,
             Packet_channel   drvr2sb_chan = null,
             Packet_channel   rcvr2sb_chan = null);

      super.new("sb",inst,stream_id);
   
      if(drvr2sb_chan == null)
           `vmm_fatal(this.log,"drvr2sb_channel is not constructed");
      else
           this.drvr2sb_chan = drvr2sb_chan;
     
      if(rcvr2sb_chan == null)
           `vmm_fatal(this.log,"rcvr2sb_channel is not constructed");
      else
           this.rcvr2sb_chan = rcvr2sb_chan;
     
      `vmm_note(log,"Scoreboard created ");

endfunction:new


task main();
  Packet pkt_rcv,pkt_exp;
  string msg;
  super.main();
  forever
  begin
    rcvr2sb_chan.get(pkt_rcv);
    $display(" %0d : Scoreboard : Scoreboard received a packet from receiver ",$time);
    drvr2sb_chan.get(pkt_exp);
    if(pkt_rcv.compare(pkt_exp,msg))
    $display(" %0d : Scoreboard :Packet Matched ",$time);
    else
    `vmm_error(this.log,$psprintf(" Packet MissMatched \n %s ",msg));
  end
endtask : main

endclass



3) What are the advantages of linkedlist over the queue ?
   
 Answer:


 Queue has a certain order. It's hard to insert the data within the queue. But Linkedlist can easily insert the data in any location.


4) What is the use of $cast?


Using Casting one can assign values to variables that might not ordinarily be valid because of differing data type. SystemVerilog adds 2 types of casting. Static casting and dynamic casting.


e.g.  i = int '(10.0-0.1); // static cast convert real to integer


// Dynamic casting
function int $cast( singular dest_var, singular source_exp );
or
task $cast( singular dest_var, singular source_exp );



e.g. $cast( col, 2 + 3 );

ASIC Verification Interview Questions

1)  What if design engineer and verification engineer do the same mistake in Test bench BFM(Bus Functional Model) and RTL(DUT)? How can you able to detect errors? 

 Answer:  1.   Code reviews & protocol checkers
                2.   IP gets verified in multiple environments .. like block level test bench, out of box testbench (connecting DUT back to back) , full fledged testbench using proven BFM, SoC level testbench using processor and all that etc... this all environments SHOULD be executed by diferent persons and so you should be able to catch that bug in one of this testbench ...
                3. customer will catch the problem ( worst case )

2)  If you got a failure from the customer, how do you debug this? How do you prevent it to happen again?


Answer: 1. First, try to reproduce the problem in your own environment. Try to get customer's vector, so you can inject the same vector to create the problem in house.
              2. If you confirm the problem and fix them, you should put the new assertion or test to catch the problem again. Add this new test in the future test plan, so the problem will not happen again.








Wednesday, February 17, 2010

Previous Interview Questions

1) Try to model Stack in Verilog code?

module Stack (DataIO, Reset, Push, Pop, SP, Full, Empty, Err);
//Verilog code for stack

/* declare input, output and inout ports */
inout [3:0] DataIO;
input Push,Pop,Reset;
output Empty,Err;
Full,output [2:0] SP; // Stack pointer

// declare registers
regEmpty,Err;
Full,reg [2:0] SP;
reg [3:0] Stack[7:0];
reg [3:0] DataR;

/* continuous assignment of DataIO to DataR register, with delay 0 */
wire [3:0] #(0) DataIO = DataR;

// put DataR in high impedance, so the stack can get data

always @ (negedge Pop)
begin
DataR = 4'bzzzz;
end


always @ (posedge Push or posedge Pop or posedge Reset)
begin


   if (Reset==1)
   begin
     DataR = 4'bzzzz;
     SP = 3'b0;
     Full = 0;
     Empty = 0;
     Err = 0;
  end
 
    if (Push==1) begin
      //when the stack is empty
      if (Empty==1)
      begin
         Stack[SP] = DataIO;
         Empty = 0;
         if (Err==1)
         Err=0;
      end
     else // when the stack is full
     if(full==1)
     begin
        Stack[SP] = DataIO;
        Err = 1;
     end
     else
     begin
        SP = SP +1;
        Stack [SP] = DataIO;
        if (SP == 3'b111)
            Full = 1;
     end
end  // end of push


    if(Pop==1) begin
    /* if SP indicates the last location but the stack is not empty */
     if ((SP == 3'b000) && (Empty!=1)
     begin
        DataR = Stack[SP];
        Empty = 1;
     end
     else // if the stack is emtpy
       if(Empty==1)
       begin
        DataR = Stack[SP];
        Err = 1;
       end
     else
     begin
     DataR = Stack[SP];
     if (SP != 3'b000)
        SP = SP-1;
      // if the stack is full
     if (Err==1) Err = 0;
     if (Full==1) Full = 0;
    end
 end  // end of pop
end  // end of always loop

endmodule

2) what is difference between CAM and TCAM?

First, CAM stands for Content Addressable Memory. A CAM is a special type of memory; some would say the opposite of RAM. With normal computer memory (RAM) the operating system provides an address, and receives the data stored at the supplied address. With a CAM, the operating system supplies the data, and the CAM returns a list of addresses where the data is stored, if it finds any. Furthermore, a CAM searches the entire memory in one operation, so it is considerably faster than RAM.

The most commonly implemented CAMs are called binary CAMs. They search only for ones and zeros; a simple operation. MAC address tables in switches commonly get stored inside binary CAMs. With CAMs, the operating system can find what it needs in a single operation. In this case it's the switchport that data should be sent out, based on the given MAC address,

The TCAM is a Ternary CAM. This allows the operating system to match a third state, "X." The X state is a "mask," meaning its value can be anything. This lends itself well to networking, since netmasks (define) operate this way. To calculate a subnet address we mask the bits we don't care about, and then apply the logical AND operation to the rest. Routers can store their entire routing table in these TCAMs, allowing for very quick lookups.

3) One-hot state machine vs highly encoded state machine

Answer:

     One-hot state machine: better performance, easy encode
     highly encode state machine has less bit for state parameters
 
   e.g.

  Using Single Always For Sequential, Combo And Output Logic
//==================================================== 2 // This is FSM demo program using single always 3 // for both seq and combo logic 4 // Design Name : fsm_using_single_always 5 // File Name : fsm_using_single_always.v 6 //===================================================== 7 module fsm_using_single_always (
8 clock , // clock 9 reset , // Active high, syn reset 10 req_0 , // Request 0 11 req_1 , // Request 1 12 gnt_0 , // Grant 0 13 gnt_1
14 );
15 //=============Input Ports============================= 16 input clock,reset,req_0,req_1;
17 //=============Output Ports=========================== 18 output gnt_0,gnt_1;
19 //=============Input ports Data Type=================== 20 wire clock,reset,req_0,req_1;
21 //=============Output Ports Data Type================== 22 reg gnt_0,gnt_1;
23 //=============Internal Constants====================== 24 parameter SIZE = 3 ;
25 parameter IDLE = 3'b001,GNT0 = 3'b010,GNT1 = 3'b100 ;
26 //=============Internal Variables====================== 27 reg [SIZE-1:0] state ;// Seq part of the FSM 28 reg [SIZE-1:0] next_state ;// combo part of FSM 29 //==========Code startes Here========================== 30 always @ (posedge clock)
31 begin : FSM
32 if (reset == 1'b1) begin
33 state <= #1 IDLE;
34 gnt_0 <= 0;
35 gnt_1 <= 0;
36 end else
37 case(state)
38 IDLE : if (req_0 == 1'b1) begin
39 state <= #1 GNT0;
40 gnt_0 <= 1;
41 end else if (req_1 == 1'b1) begin
42 gnt_1 <= 1;
43 state <= #1 GNT1;
44 end else begin
45 state <= #1 IDLE;
46 end
47 GNT0 : if (req_0 == 1'b1) begin
48 state <= #1 GNT0;
49 end else begin
50 gnt_0 <= 0;
51 state <= #1 IDLE;
52 end
53 GNT1 : if (req_1 == 1'b1) begin
54 state <= #1 GNT1;
55 end else begin
56 gnt_1 <= 0;
57 state <= #1 IDLE;
58 end
59 default : state <= #1 IDLE;
60 endcase
61 end
62
63 endmodule // End of Module arbiter


4) Write a perl script to read a file and then count the "ERROR=number" ? Check the number did increase.

Answer:
    First, you can use grep -f patternfile source > target to generate a new log file with ERROR=# format or directly use perl to do it.


  Assume the log file has the format  "ERROR=number" format in some lines,

   #!/usr/bin/perl
   system(grep "ERROR" logfile > error_logfile);
 
   open(IN, "error_logfile") or die "Cannot open the error_logfile!";

    while($line=) {
   chop($line);
   @err_array = split(/\d/,$line);
   $w=1;
      while ($$w<= @err_array) {
         if($err_array[$w-1] < $err_array[$w])
           {           $err_incr_cnt +=1;
           }
        else
             {         $err_decr_cnt +=1;       
             }
        $w++; 
     }  
}
   print "Total number of error = $w";
   print "Error Increment counter = $err_incr_cnt";
   print "Error Decrement counter =$err_decr_cnt;

Perl Hash examples

Example:

    #! C:\programfiles\perl\bin\perl
    print "content-type: text/html\n\n";
    %name = ('Tom',26,'Peter',51,'Jones', 23, 'John', 43);
    print "Sorted by Keys \n
";
    foreach $key (sort keys %name)
    {
      print "$key: $name{$key}
";
    }
    print "Sorted by Values \n
";
    foreach $value (sort {$name{$a} cmp $name{$b} }keys %name)
    {
      print "$value: $name{$value}
";
    }

Result:

Sorted by Keys
     John: 43
     Jones: 23
     Peter: 51
     Tom: 26
Sorted by Values
     Jones: 23
     Tom: 26
     John: 43
     Peter: 51


Regular expressions are that makes Perl an ideal language for "Practical extraction and reporting" as the name implies.To construct the regular expression, which is essentially a sequence of characters describing the pattern you would like to match.

Metacharacter      Default Behaviour
\     Quote next character
^     Match beginning-of-string
.     Match any character except newline
$     Match end-of-string
|     Alternation
()     Grouping and save subpattern
[ ]     Character class


The split() function is used to split up a string using a regular expression delimiter or a character or a string.
Syntax:

     split (string);

In the above syntax, split() function takes a "string" as the argument.
Example to split string using regular expression delimiter:

    #! C:\programfiles\perl\bin\perl
    print "content-type: text/html\n\n";
    $str1 = "how,are,you";
    $str2 = "how!!are!!you";
    $str3 = "how1are2you";
    @val1 = split(",", $str1);
    @val2 = split('!!', $str2);
    @val3 = split(/\d+/, $str3);
    print "Removed the character Comma","\n";
    print "
";
    foreach $val1 (@val1)
     {
       print "$val1\n";
     }
    print "
";
    print "Removed the string '!!'";
    print "
";
    foreach $val2 (@val2)
     {
       print "$val2\n";
     }
    print "
";
    print "Removed the decimals 1,2";
    print "
";
    foreach $val3 (@val3)
     {
       print "$val3\n";
     }

Result:

    Removed the character Comma
    how are you
    Removed the string '!!'
    how are you
    Removed the decimals 1,2
    how are you

In the above example the string "howareyou" is seperated first with a comma, then by a string "!!", at last seperated by decimals "1,2", which is removed using a regular expression "/\d+/". All these strings are split and stored in an array, then using a loop its returned one by one.

Tuesday, February 16, 2010

C++ Class example

Basic Class C++ example code

// example one
#include
#include

class Book
{
// by default, all data and function are private

int PageCount;
int CurrentPage;
public:
Book( int Numpages) ; // Constructor
~Book(){} ; // Destructor
void SetPage( int PageNumber) ;
int GetCurrentPage( void ) ;
};

Book::Book( int NumPages) {
PageCount = NumPages;
}



void Book::SetPage( int PageNumber) {
CurrentPage=PageNumber;
}

int Book::GetCurrentPage( void ) {
return CurrentPage;
}

int main() {
Book ABook(128) ;   // Call constructor() and set PageNum=128
ABook.SetPage( 56 ) ;  // Set the current page number
std::cout << "Current Page " << ABook.GetCurrentPage() << std::endl;    // print out the current page
return 0;    // call destructor
}



This example will demonstrate inheritance. This is a two class  application  with one class derived from another.

    #include
    #include

    class Point
    {
   // default private
    int x,y;
    public:
    Point(int atx,int aty ) ; // Constructor
    inline virtual ~Point() ; // Destructor
    virtual void Draw() ;
    };




    class Circle : public Point {
    int radius;
    public:
    Circle(int atx,int aty,int theRadius) ;
    inline virtual ~Circle() ;
    virtual void Draw() ;
    };


    Point ::Point(int atx,int aty) {
    x = atx;
    y = aty;
    }

    inline Point::~Point ( void ) {
    std::cout << "Point Destructor called\n";
    }

    void Point::Draw( void ) {
    std::cout << "Point::Draw point at " << x << " " << y << std::endl;
    }


    Circle::Circle(int atx,int aty,int theRadius) : Point(atx,aty) {
    radius = theRadius;
    }

    inline Circle::~Circle() {
    std::cout << "Circle Destructor called" << std::endl;
    }

    void Circle::Draw( void ) {
    Point::Draw() ;
    std::cout << "circle::Draw point " << " Radius "<< radius << std::endl;
    }

    int main() {
    Circle ACircle(10,10,5) ;
    ACircle.Draw() ;
    return 0;
    }

What is Polymorphism?

Polymorphism is a generic term that means 'many shapes'. In C++ the simplest form of Polymorphism is overloading of functions, for instance several functions called SortArray( arraytype ) where sortarray might be an array  of ints, or doubles. 

/* A base class of Shape gives rise to
two derived classes - Circle and Square.

An application called Polygon sets up an
array of Circles and Squares, and uses a
getarea method to find the area of each.

This getarea method is defined as a virtual
method in the base class, so that an array
of shapes CAN be defined on which two
different getarea methods can be run
depending on which type of shape is the
current one at the time. */

::::::::::::::
shape.h
::::::::::::::

#ifndef SHAPE
#define SHAPE 1

class Shape {
        public:
                void setsize(int owbig);
                virtual float getarea() {};
        protected:
                int givensize;
        };

#endif
::::::::::::::
shape.cpp
::::::::::::::
#include "shape.h"

void Shape::setsize(int sv) {
        givensize = sv;
        }

::::::::::::::
square.h
::::::::::::::
#include "shape.h"

class Square: public Shape {
        public:
                float getarea();
        };
::::::::::::::
square.cpp
::::::::::::::
#include "square.h"

float Square::getarea() {
        float result = givensize * givensize;
        return (result);
        }
::::::::::::::
circle.h
::::::::::::::
#include "shape.h"

class Circle: public Shape {
        public:
                float getarea();
        };
::::::::::::::
circle.cpp
::::::::::::::
#include "circle.h"

float Circle::getarea() {
        float result = 3.14159265f * givensize;
        return result;
        }
::::::::::::::
polygon.cpp
::::::::::::::
#include
#include "circle.h"
#include "square.h"

main () {

        int np = 10;
        Shape *jigsaw[np];

        for (int k=0; k
                jigsaw[k] = new Square();
                jigsaw[k+1] = new Circle();
        }
        for (int k=0; k
                jigsaw[k]->setsize(10+k);
                }
        for (int k=0; k
                float syze = jigsaw[k]->getarea();
                cout << "this is sq " << syze << endl;
                }

        return (0);
        }

Perl interview questions Part #7

1) What happens when you return a reference to a private variable?

Answer:
Perl Keeps track of your variables, whether dynamic or otherwise, and dones't free things before you're done using them.

2) How do I sort a hash by the hash value?

Answer:

#!/usr/bin/perl -w
# help sort a hash by the hash 'value', not the 'key'

sub sorthashValueDescendingNum {$grades{$b} <=> ${grades{$a}};

%grades =( student1=>90,
student2=>75,
student3=>76);

print "\n\tGRADES IN ASCENDING NUMERIC ORDER\n";
foreach $key (sort(keys(%grades))){
print "\t\t$grades{$key} \t\t$key\n";
}

print "\n\tGRADES IN DESCENDING NUMERIC ORDER\n";
foreach $key (sorthashValueDescendingNum(keys(%grades))){
print "\t\t$grades{$key} \t\t$key\n";
}

3) How to read file into hash array?

Answer:

The following little snippet of code should do exactly what you want:

open(IN, "filename")

          or die "Couldn't open file for processing: $!";
while (
) {
chomp;
$hash_table{$_} = 0;
}
close IN;

Once you've read in your values, the following single line of code
will print them all out for you:

print "$_ = $hash_table{$_}\n" foreach keys %hash_table;


4) Does Perl have reference type?

Answer:

$str="here we go"  ;  # a scalar variable
$strref = \$str;          # a reference to a scalar

@array=(1..10);       # an array
$arrayref =\@array;  # a reference to an array.

%hash=(key1=>vaule1,
             key2=>value2
);
$rhash-ref =\%hash;


4) How to initialize a hash?

Answer:
my %hash = ();    # initialize a hash
my $hash_ref = {};  # reference to empty hash

5) How to add data into hash?

Answer:
$hash{ 'key' } = 'value';    # hash

    $hash{ $key } = $value;      # hash, using variables

    $href->{ 'key' } = 'value';  # hash ref

    $href->{ $key } = $value;    # hash ref, using variables

    %hash = ( 'key1', 'value1', 'key2', 'value2', 'key3', 'value3' ); # add multiple items

    %hash = (
        key1 => 'value1',
        key2 => 'value2',
        key3 => 'value3',
    );

6) How to copy hash?

Answer:
   my %hash_copy = %hash;  # copy a hash

    my $href_copy = $href;  # copy a hash ref


7)  How to use while or for loop with Hash?


Use each within a while loop. Note that each iterates over entries in an apparently random order, but that order is guaranteed to be the same for the functions keys and values.

    while ( my ($key, $value) = each(%hash) ) {
        print "$key => $value\n";
    }


A hash reference would be only slightly different:

    while ( my ($key, $value) = each(%$hash_ref) ) {
        print "$key =>$value\n";
    }

Use keys with a for loop.

    for my $key ( keys %hash ) {
        my $value = $hash{$key};
        print "$key =>$value\n";
    }

8) What's the size of the hash?

Answer:
print "size of hash:  " . keys( %hash ) . ".\n";
 
 
Extra Hash information

Search This Blog