Friday, February 5, 2016

Setup and Hold time and clocking block in system verilog

Set up time : A time before clock edge for which input data should be stable.

Hold time : A time after clock edge for which input data should be stable.

If any of above is violated the output may go meta-stable.


In above image shaded region before dashed line is setup time. Shaded region after dashed line is hold time. Here it violates setup and hold time.



Above is timing for D flipflop. See here we do not change input in shaded (restricted) region. Input is changed before setup time and remain stable while in hold time.

In system verilog we use clocking block to avoid race condition as well setup/hold violation.

Here I am just giving an idea that how we can use clocking block

module test();
clocking cb @(posedge CLK);
  default input #setup_time output #hold_time;
  output a;
  output b;
  output c;
 
  input x;
  input y;
  input z;
endclocking

We can put clocking block inside module or program.
Here input will be sampled before #setup_time @posedge of CLK.
Output will be driven after #hold_time @posedge of CLK

Signed and Unsigned variable

Lets take example of bits (unsigned) and byte (signed) data type.

8 bit packed array of bit : bit [7:0] a (0 to 255)
byte b (-128 to 127)

module test();
  bit[7:0] a=2'h00,b=2'h01,c,bit_sum1,bit_sum2;
  byte d,byte_sum1,byte_sum2;
  initial
  begin
    c = a-b;
    d = a-b;
    bit_sum1 = c - 1;
    bit_sum2 = d -1;
    byte_sum1 = c -1;
    byte_sum2 = d - 1;
    $display("Binary Representation : %b d %b bit_sum1 %b bit_sum2 %b byte_sum1 %b byte_sum2 %b",c,d,bit_sum1,bit_sum2,byte_sum1,byte_sum2);
    $display("Decimal Representation : c %0d d %0d bit_sum1 %0d bit_sum2 %0d byte_sum1 %0d byte_sum2 %0d",c,d,bit_sum1,bit_sum2,byte_sum1,byte_sum2);
  end
endmodule
Output :

Binary Represantation: c 11111111 d 11111111 bit_sum1 11111110 bit_sum2 11111110 byte_sum1 11111110 byte_sum2 11111110
Decimal Represantation: c 255 d -1 bit_sum1 254 bit_sum2 254 byte_sum1 -2 byte_sum2 -2

Does System Verilog support Method Overriding and Method Overloading.

Method Overriding : Method of base class enhanced in derived class. Used that as virtual method. Concept of polymorphism

Method Overloading : Multiple method with same name but different signature. Different set of argument .

virtual void print(int x); 
virtual void print(bit y)

This is not supported in System Verilog.

What is difference between Mailbox and Queue.

It is very common question asked in interview.

Apparently there is not difference between queue and mailbox. Both can store data (push or put) and we can get stored data from is (pop and get.)

Difference lies when there is multiple thread (or process), putting or getting element to or from queue. For a single thread or process there is no difference between queue and mailbox.

I will show you with example below, how it affects.

Mailbox is special class (enhanced functionality of queue) in std package of system verilog. It can be bounded or unbounded. Bounded means size of mailbox is fixed, you can not put more element more than its defined size.

mailbox mbx = new(4);

Above mailbox can only store 4 element. If we try to put more element then 4 it will block the method until space is created.

Bounded Queue : Can we make that??? Yes we can mimic it as below.

task put(input int data);
  wait(q.size < 4); // test
  q.push_back(data); // set
endtask
task get(output int data);
 wait(q.size > 0); // test
  q.pop_front(data); // set 
endtask

Here we only push element if size is less than 4. If it is single thread doing this there is no difference (except we have to add wait statement).

But what mailbox is provide is : above test and set operation are performed atomically (uninterrupted). While for queue it is two different process. (test and set).

There are two problem using that queue approach.

1. The first is that when there are multiple threads waiting on the size of the queue to change, there is no guaranteed ordering which thread will wake up and proceed when the condition is satisfied. Mailboxes/semaphores guarantee that the order that the threads suspend is the same as the order they wake up (FIFO order First In/First Out). 

2. The other problem is there is no guaranteed ordering of statements between two or more concurrently running threads. It's possible for multiple threads to wake up when the queue size changes so that either q.size < 4 is true for a put(), or q.size > 0 for a get(). All the threads could execute the test and succeed, then all the threads do their set operation when only one operation should have been allowed. Mailboxes/semaphores guarantee that put() and get() act atomically so that no other thread interrupt the test and set operation. So only one thread will succeed in the put() or get().

What is difference between ++i and i++

  • ++i will increment the value of i, and then return the incremented value.
     i = 1;
     j = ++i;
     (i is 2, j is 2)
  • i++ will increment the value of i, but return the original value that i held before being incremented.
     i = 1;
     j = i++;
     (i is 2, j is 1)

What is the difference between $rose and posedge?

posedge returns event where as $rose returns a boolean value. Events cannot be used in expression, $rose can be used. 

System Verilog : Misc

Here I am Putting some small statement which I learn in day to day work.

1. If you don't write super.new inside new function of current class, the compiler itself add super.new() automatically.

2.  When a child class object is created by new constructor, its parent class (if its abstract then also) is created implicitly. Without parent child can never be exists.

3. You can inherit any method from base class. I mean you can call any method define in base class by child class handle (if it is not defined in child class. That is inheritance concept). But if in base class you have created new function (i.e constructor) with argument, you cant inherit that in child class. You need to define new again in child class with argument.

class animal;
   int age=-1;
  function new(int a = 20);
      age = a;
   endfunction : new
endclass : animal
class lion extends animal;
   //function new(int age);
      //super.new(age);
   //endfunction : new
endclass : lion
module test();
  animal a;
  lion l;
  initial
    l = new(10); // l = new() will work
endmodule

Output : 
Error-[TMAFTC] Too many arguments to function/task call
testbench.sv, 18
"lion::new(10)"
  The above function/task call is done with more arguments than needed.

Run Here :

Below will also work as new is defined in derived class but argument is not passed in super.new, since it has default value. If base class new did not had default value it would shout an error 



Output:
@@@@ age is 20
Below will give error as default value is not assigned in new.

Output:
Error-[TFAFTC] Too few arguments to function/task call testbench.sv, 15 "animal::new()" The above function/task call is not done with sufficient arguments.

3. A class variable can be declared as a rand type. Like rand class_abc abc; 
Thus when class in which class_abc is created, will call .randomize function, it will also randomize rand variable declared in class_abc.
See below example.
class base;
  rand int vari =1 ;
endclass
class obj;
  rand base baseh = new();
endclass
module test;
  obj objh = new() ;
  initial
  begin
    if(objh.randomize())
    begin
      $display(" Randomization is done ");
    end
    $display(" objh.baseh.var : %d ", objh.baseh.vari );
  end
endmodule

Output : 
 Randomization is done 
 objh.baseh.var :  -902462825 

Run Here


4. Constraint are by default virtual in nature. If any constraint with the same name is written in derived class, it will override the constraint written in base class. So If we assign derived class handle to base class, randomize method will solve constraint written in derived class.

class A;
rand integer x;
  constraint c { x > 0; }
endclass
class B extends A;
  constraint c { x < 0; }
endclass
module top();
  A a;
  B b;
  initial
    begin
      b = new();
      a=b;
      a.randomize();
      $display("@@@ %0d",a.x);
    end
endmodule

Output : 
@@@ -1223315946

Run Here
4. Mailbox and semaphore are classes defined in std package

5. intial and always block executes at time 0. If there are more than one block in a module all are executed concurrently and independently.   
6. Class can have an object of its own type.
See below code. 

class test;
  test self;
  function create_me();
    self = new();
    self.display("self");
  endfunction
  function display(string s = "this");
    $display("from function display %s",s);
  endfunction
endclass
 
module test_module();
  test test_ob;
  initial
    begin
      test_ob = new();
      test_ob.create_me();
      test_ob.display();
    end 
endmodule
Output : 
from function display self
from function display this
it has a class variable self that will eventually hold a handle that can reference another class object of the same type. This is a very common data structures like a queue or tree used in many other programming languages. Seehttp://www.cprogramming.com/tutorial/lesson18.html