Monday, February 29, 2016

Packed and Unpacked Array : Memory Allocation

SystemVerilog stores each element in long word (32 bits). For example, following declaration will use 32 bits in the memory, although only 8 bits are really used .
Bit [7:0] a;
‘a’ is a single element with 8 bits.The memory use will be as below.


Rewriting the above declaration like following
Bit [7:0] a_unpacked [2:0];
Now 'a' become an array which contains 3 elements with the size of 8 bits each. As ‘SystemVerilog stores each element in a longword (32 bits)’. In the above declaration will look like this



The memory is not used efficiently (not well packed), but sometimes it is necessary to declare this way. It is called unpacked array. Let’s rewrite the above declaration into following way
Bit [2:0] [7:0] a_packed;
The word dimension [2:0] moved next to bit dimension [7:0]. ‘a’ is an element (note it is single element) which has 3 sets of 8 bit words. Since a single element stored in a long word, memory usage will look like this


The memory used efficiently (well packed). It is called packed array.

Friday, February 5, 2016

Why we need virtual interface? If I don't want to use it what is an alternate method.

Interface is static entity. We can not use it in dynamic entity like class. So we have a new type called virtual interface. We can bind interface with virtual interface in top module. Virtual interface will be treated like a class handle.

Let me explain.

Classes in system verilog are created at run time. Port connection between modules and creating direct reference to the dut signals are done at elaboration time. We can not do direct connection with DUT signals like that with class because as I said class are created at run time.

We need another mechanism to do that. To do the same thing work at compile and elaboration time we can use hierarchical defines. Like ,
`define PATH top.design.block1
and then the write `PATH.sig1 <= 1; in the testbench. This approach does not work when there are multiple instances of testbench objects that need to communicate multiple paths of the DUT. Another problem is that most classes are written inside SystemVerilog packages, and packages are not supposed to have any outside dependencies other than other package imports. 

So SystemVerilog, which already has dynamic references to class objects, added a dynamic reference to an interface instance and called it a virtual interface.
virtual interface variable can dynamically accept a handle to an actual interface instance. Then you can then dynamically reference members of that interface instance.

Still if you don't like virtual interface, here is another method you can use. :)

To create a class inside interface and use it. How? Let me show



package abstract_pkg;
  virtual class abstract_intf #(int awidth);
    pure virtual function void set_address(
    input logic [awidth-1:0] a);
    pure virtual task posedge_clock;
  endclass
endpackage

interface dut_itf#(int dwidth, awidth);
 logic clock,reset;
 wire [dwidth-1:0] data;
 logic [awidth-1:0] address;
  import abstract_pkg::*;
  class concrete_intf#(int width) extends abstract_intf#(width);
    function void set_address(
      input logic [width-1:0] a);
      address = a;
    endfunction
    task posedge_clock;
      @(posedge clock);
    endtask
  endclass
  concrete_intf#(awidth) c = new();
endinterface

package my_pkg;
 import abstract_pkg::*;
  class driver;
    abstract_intf#(16) c_h;
    task run;
      forever begin
      c_h.posedge_clock;
      c_h.set_address(‘h1234);
      end
    endtask
  endclass
endpackage

module testTop;
  dut_itf #(8,16) i1();
  DUT d1(.itf(i1));
  TEST t1(.itf(i1));
endmodule

module TEST();
  import my_pkg::*;
  driver d;
  initial begin
  d = (new);
  d.c_h = i1.c;
  d.run;
  end
endmodule

Here c_h is class defined in interface, which we used in driver and from it we can toggle or use interface signal. 

What is difference between reg ,wire and logic

Difference in very simple terms.

Reg = used to store value. Used in sequential assignments. It will store the value in variable until next assignments.

Wire = used for continuous assignment. Its net (network) type. used for combinational logic. Used in assign statment. It can not store the value. It will connect two port.

Logic :  Logic and reg is slightly different. Logic can also be used for continuous assignment. That mean it can be used at LHS for assign statement.
Implicitly it can be seen as


logic A; //is a shortcut for

var logic A; // This is like Reg A

And

wire A; // is a shortcut for

wire logic A; // This is like wire A


http://inst.eecs.berkeley.edu/~cs150/Documents/Nets.pdf

Wire Elements (Combinational logic) wire elements are simple wires (or busses of arbitrary width) in Verilog designs. The following are syntax rules when using wires:
1. Wire elements are used to connect input and output ports of a module instantiation together with some other element in your design.
2. Wire elements are used as inputs and outputs within an actual module declaration.
3. Wire elements must be driven by something, and cannot store a value without being driven.
4. Wire elements cannot be used as the left-hand side of an = or <= sign in an always@ block.
5. They are the only legal type on the left-hand side of an assign statement.
6. This elements are a stateless way of connecting two pieces in a Verilog-based design.
7. It can only be used to model combinational logic.

Program 1  Legal uses of the wire element

wire A , B , C , D , E ; // simple 1 -bit wide wires
wire [8:0] Wide ; // a 9 -bit wide wire
reg I ;

assign A = B & C ; // using a wire with an assign statement

always @ ( B or C ) begin
I = B | C ; // using wires on the right - hand side of an always@
// assignment
 end

 mymodule mymodule_instance (. In ( D ) ,
 . Out ( E ) ) ; // using a wire as the output of a module

Reg Elements (Combinational and Sequential logic) reg are similar to wires, but can be used to store information (‘state’) like registers. The following are syntax rules when using reg elements.
1. reg elements can be connected to the input port of a module instantiation.
2. reg elements cannot be connected to the output port of a module instantiation.
3. reg elements can be used as outputs within an actual module declaration.
4. reg elements cannot be used as inputs within an actual module declaration.
5. reg is the only legal type on the left-hand side of an always@ block = or <= sign.
6. reg is the only legal type on the left-hand side of an initial block = sign (used in Test Benches).
7. reg cannot be used on the left-hand side of an assign statement.
8. reg can be used to create registers when used in conjunction with always@(posedge Clock) blocks. 9. reg can, therefore, be used to create both combinational and sequential logic.

Program 2 Legal uses of the reg element

wire A , B ;
2 reg I , J , K ; // simple 1 -bit wide reg elements
3 reg [8:0] Wide ; // a 9 -bit wide reg element
4
5 always @ ( A or B ) begin
6 I = A | B ; // using a reg as the left - hand side of an always@
7 // assignment
8 end
9
10 initial begin // using a reg in an initial block
11 J = 1 ’ b1 ;
12 #1
13 J = 1 ’ b0 ;
14 end
15
16 always @ ( posedge Clock ) begin
17 K <= I ; // using a reg to create a positive -edge - triggered register
18 end

When wire and reg Elements are Interchangeable? 
Wire and reg elements can be used interchangeably in certain situations:
1. Both can appear on the right-hand side of assign statements and always@ block = or <= signs.
2. Both can be connected to the input ports of module instantiations.

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 : A different way of representing the value.

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 : %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);
    $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 ++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)