Friday, December 17, 2021

Passport RE-ISSUE process in India

Few days before, I applied for passport re-issue online via https://passportindia.gov.in/ website.

On 17th December 2021, I went to the passport centre at TOLICHOWKI passport centre in Hyderabad. Slot allocated to me was on 3.15 PM.

After reaching the place, the security allowed me to enter at around 3.30 PM into the office.

It has been more than a year since my passport expired. 

I was asked to submit one xerox copy of the following documents, along with the originals to verify.

1. Passport - First 2 and Last 2 pages + Page 2-3 of the passport ( effectively 3-4th page )

2. Aadhar card ( for address proof ).

One of my friend was asked to show 10th class ( matriculation or SSC ) certificate (original) at Bangalore passport office. It is better to keep it handy, in case some one asks for it.

It took around 30-40 mins for me to get a token from the counter.

After receiving the token, I was asked to visit section - A.

In section-A, a person took a photograph of mine , followed by signature on 2 papers + all fingers digital impression. After that, I was handed over few docs along with the xerox i gave earlier. Here it hardly took 5 mins. I paid 50 Rs/- here for SMS services which is optional.

With these docs at hand, I was asked to visit section - B.

In section-B, another person verified all the documents ( passport + Aadhar ), along with the originals. 5mins here as well. Now, I was asked to visit section C.

By this it was almost 4.20 PM, there are 3 counters in section -C, and only 1 was occupied, 2 other employees, went for a break and they came back after 30 mins. By 5 PM, I got a call from the counter C1, again the documents were verified, since I had a change in the address, a police verification is required, it will be scheduled in the next few days. The person at the counter punched a hole in my passport book, and I finally left the premises at 5.10 PM.

Hope this helps.....

Monday, May 31, 2021

System verilog Assertion for back to back requests

Scenario :

A system generates request at random intervals in time.

Each request must be answered  by an acknowledgement after 1 to 10 cycles from request.

Following is the code to achieve the same.



bit clk,req,ack; 
int v_req,v_ack;
 
function void inc_req(); 
  req_cnt = req_cnt + 1'b1
endfunction
 
property reqack_unique;
  int v_req;
  @(posedge clk)
  $rose(req),  v_req=req_cnt, inc_req()) |-> ##[1:10] v_req ==v_ack ##0 ack; 
endproperty
 
ap_reqack_unique: assert property(reqack_unique) v_ack = v_ack+1; 
else v_ack=v_ack+1;

Saturday, April 24, 2021

System Verilog Assertions - dynamic delays

Ben cohen provided the code for dynamic delays in verification academy forum.

I have just pasted it here...

Link :

https://verificationacademy.com/forums/systemverilog/sva-package-dynamic-and-range-delays-and-repeats

 Code :

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// Ben Cohen  December 13, 2018  
package sva_delay_repeat_range_pkg;
    // int d1, d2; 
    // bit a, b, c=1'b1; 
    // sequence q_s; a ##1 c; endsequence  
    // sequence my_sequence; e ##1 d[->1]; endsequence 
    //----------------------------------------------------------------
    // ******       DYNAMIC DELAY ##d1 **********
    // Application:  $rose(a)  |-> q_dynamic_delay(d1) ##0 my_sequence;
    sequence q_dynamic_delay(count);
        int v;
        (1, v=count) ##0 first_match((1, v=v-1'b1) [*0:$] ##1 v<=0);
    endsequence 
    //----------------------------------------------------------------
    // ******       DYNAMIC DELAY RANGE ##[d1:d2] **********
    //##[d1:d2] ##0 b; // NO sequence  followng the "b"
    // $rose(a)  |-> q_dynamic_delay_range(d1, d2, b)) 
    //                and b[->1] ##1 my_sequence;
    // $rose(a) ##0  q_dynamic_delay_range(d1, d2, b) |-> my_sequence;
    sequence q_dynamic_delay_range(int d1, d2, bit b);
        int v1, vdiff;
        (1, v1=d1, vdiff=d2-d1) ##0 q_dynamic_delay(v1)   ##0  
        first_match((1, vdiff=vdiff - 1)[*0:$] ##1 (b || vdiff<=0)) ##0 b; 
    endsequence 
    //----------------------------------------------------------------
    // ******       DYNAMIC REPEAT q_s[*d1] **********
    // Application:  $rose(a)  |-> q_dynamic_repeat(q_s, d1) ##1 my_sequence;
    sequence q_dynamic_repeat(q_s, count);
        int v=count;
        (1, v=count) ##0 first_match((q_s, v=v-1'b1) [*1:$] ##0 v<=0);
    endsequence
    //----------------------------------------------------------------
    // ******       DYNAMIC REPEAT RANGE q_s[*d1:d2] **********
    // Application:  $rose(a)  |-> (q_dynamic_repeat_range(q_s, d1, d2, b) 
    //                             and  b[->1] ##1 my_sequence // use the same "b"
    //  $rose(a)  ##1 q_dynamic_repeat_range(q_s, d1, d2, b) |->   my_sequence;
    sequence q_dynamic_repeat_range(sequence q_s, int r1, r2, bit b);
        int v, diff;
        (1, v=r1, diff=r2-r1) ##0   
        q_dynamic_repeat(q_s, v)  ##1 // repeat to r1
        first_match((q_s, diff=diff-1'b1) [*0:$] ##1 (b || diff<=0 )) ##0 b; 
    endsequence     
endpackage
 
 
import uvm_pkg::*; `include "uvm_macros.svh" 
import sva_delay_repeat_range_pkg::*;
module top; 
    timeunit 1ns;     timeprecision 100ps;  
    bit clk, a, b, c=1, w;  
    int d1=2, d2=5;  
    sequence q_s;
        a ##1 c; 
    endsequence   
    sequence my_sequence; 
        a ##1 w[->1]; 
    endsequence 
    default clocking @(posedge clk); 
    endclocking
    initial forever #10 clk=!clk;  
 
    // ******       DYNAMIC DELAY ##d1 **********
    // Application:  $rose(a)  |-> q_dynamic_delay(d1) ##0 my_sequence;
    ap_dyn_delay: assert property(@ (posedge clk) 
       $rose(a) |-> q_dynamic_delay(d1) ##0 my_sequence);  
 
    ap_fix_delay: assert property(@ (posedge clk)   
       $rose(a) |-> ##2 my_sequence); 
 
    // ******       DYNAMIC DELAY RANGE ##[d1:d2] **********
    //##[d1:d2] ##0 b; // NO sequence  followng the "b"
    // $rose(a)  |-> q_dynamic_delay_range(d1, d2, b)) 
    //                and b[->1] ##1 my_sequence;
    // $rose(a) ##0 q_dynamic_delay_range(d1, d2, b) |-> my_sequence;
    ap_dly_rng: assert property(@ (posedge clk) 
      $rose(a) |-> q_dynamic_delay_range(d1, d2, b) and b[->1] ##1 my_sequence);  
 
    ap_2to5: assert property(@ (posedge clk) 
      $rose(a) |->(##[2:5] b) and  b[->1] ##1 my_sequence);   
 
    ap_dly_rng_antc: assert property(@ (posedge clk) 
     $rose(a) ##0 q_dynamic_delay_range(d1, d2, b) |-> my_sequence);  
 
    ap_2to5_antc: assert property(@ (posedge clk) 
      $rose(a) ##0 first_match(##[2:5] b) |-> my_sequence); 
    //------------------------------------------------------------------
    // ******       DYNAMIC REPEAT q_s[*d1] **********
    // Application:  $rose(a)  |-> q_dynamic_repeat(q_s, d1) ##1 my_sequence;
    ap_rpt: assert property(@ (posedge clk) 
      $rose(a)|-> q_dynamic_repeat(q_s, d1)  ##1 my_sequence);  
 
    ap_rpt2: assert property(@ (posedge clk)  
    $rose(a)|-> q_s[*2] ##1 my_sequence);   
 
    // ******       DYNAMIC REPEAT RANGE q_s[*d1:d2] **********
    // Application:  $rose(a)  |-> (q_dynamic_repeat_range(q_s, d1, d2, b) 
    //                             and  b[->1] ##1 my_sequence // use the same "b"
    //  $rose(a)  ##1 (q_dynamic_repeat_range(q_s, d1, d2, b) |->   my_sequence;
    ap_rpt_rng: assert property(@ (posedge clk) 
      $rose(a)  |-> q_dynamic_repeat_range(q_s, d1, d2, b) 
                    and  b[->1] ##1 my_sequence);  
 
    ap_rpt_2to5: assert property(@ (posedge clk) 
      $rose(a)  |-> first_match(q_s[*2:5] ##1 b) and  b[->1] ##1 my_sequence);  
 
    ap_rpt_rng_antc: assert property(@ (posedge clk) 
      $rose(a)  ##1 q_dynamic_repeat_range(q_s, d1, d2, b) |->   my_sequence);  
 
    ap_rpt_2to5_antc: assert property(@ (posedge clk) 
      $rose(a)  ##1 first_match(q_s[*2:5] ##1 b) |->   my_sequence);
 
    initial begin 
        repeat(1000) begin 
            @(posedge clk); #2;   
            if (!randomize(a, b, c, w)  with 
            { a dist {1'b1:=1, 1'b0:=1};
            b dist {1'b1:=1, 1'b0:=1}; 
            c dist {1'b1:=1, 1'b0:=1}; 
            w dist {1'b1:=1, 1'b0:=1}; }) `uvm_error("MYERR", "randomize error");
        end 
        #1;
        repeat(1500) begin 
            @(posedge clk); #2;   
            if (!randomize(a, b, c, w)  with 
            { a dist {1'b1:=1, 1'b0:=2};
            b dist {1'b1:=3, 1'b0:=2}; 
            c dist {1'b1:=1, 1'b0:=1}; 
            w dist {1'b1:=3, 1'b0:=1}; }) `uvm_error("MYERR", "randomize error");
        end 
        $stop; 
    end 
endmodule   

 

Wednesday, April 21, 2021

Another system verilog constraint problem - Base class contraint becoming invisible

 Let us walk through the following code.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class base;
  rand bit [4:0] c;
  constraint c_x { c == 'd1; }
  
  function void display();
    this.randomize();
    $display("Base    c:%0d",c);
  endfunction
  
endclass

class derived extends base;
  rand bit [4:0] c;
  constraint c_x { c == 'd2; }
  
  function void display();
    this.randomize();
    $display("Derived c:%0d",c);
    super.display();
  endfunction
  
endclass

module top;
  derived b;
  
  initial begin
    b = new;
    repeat(2)
    b.display();
  end
endmodule
    


In the above code, we have 2 classes, base and derived.

Base class has variable 'c' and constraint 'c_x', the same is replicated in the derived class as well.

we have 'display' function which is used to randomize the variable and print the value. In the derived in addition to it , a super.display() was called to print the base class variable value.

When you have 2 constraints with the same name on the same variable, the constraint in the base class becomes invisible and is not applied when the variable is randomized.

Simulation results:

Contains Synopsys proprietary information.
Compiler version Q-2020.03-SP1-1; Runtime version Q-2020.03-SP1-1; Apr 22 00:47 2021
Derived c:2
Base c:27
Derived c:2
Base c:7
V C S S i m u l a t i o n R e p o r t

Reference ( comments by experts )

https://verificationacademy.com/forums/systemverilog/how-constraint-executed

Sunday, April 18, 2021

The importance of targetted stimulus to expose corner cases

Lets take a scenario where an Interrupt is triggered whenever a JUMBO packet is observed on a port. 

In general an interrupt service routine is performed after receiving an interrupt and the status register which indicates the interrupt is cleared by writing 1 into it.

The interrupt is serviced , the register is cleared and we wait for the next event.

What if another JUMBO packet is received at the same time a write is issued to clear the register?

Sometimes the documentation (requirement specification) is not thorough and might miss the scenario on handling such cases.

It is important for us to generate all the possible cases and see how the system behaves under such cases and report it for confirmation.

In the current context, the event that triggers the interrupt should will been given more importance and  instead of clearing the register should have retained the interrupt status ( to 1).

These corner cases sometimes take multiple iterations for us to reach the scenario ( with random stimulus ).


Wednesday, April 14, 2021

Functional coverage - Selective range coverage

There may be cases where you need to cover a range of values in a particular vector.

One such example is given below.

Address range : 0 -15 (addr)

Cover all even addresses in addr.

 

This was asked in an interview with cadence.

 

Code :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
module top;
  bit clk;
  bit [3:0] addr;

  covergroup cg_addr;
    cp: coverpoint addr[3:1] iff(addr[0] == 0);
  endgroup

  cg_addr cg;

  initial begin
    cg = new;
    clk <= 'b0;
    forever #5 clk = !clk;
  end

  initial begin
    repeat(16) begin
      @(posedge clk);
      addr++;
      cg.sample();
    end
    $display("Coverage:%0f%%",cg.get_inst_coverage());
    $finish;
  end

endmodule

 

* In the above code, we simply covered [3:1] vector range when addr[0] == 0 ( indicating that address is divisible by 2, even range ).

* We used the auto bins generated ( by default ).

 

Run the following commands:

vcs -sverilog -R cov.sv -cm line+cond+tgl


Result:

 VCS Coverage Metrics Release L-2016.06 Copyright (c) 1991-2016 by Synopsys Inc.
Coverage:0.000000%
$finish called from file "cov.sv", line 24.
$finish at simulation time                  155
---------------------------------------------------------------------------
VCS Coverage Metrics: during simulation line, cond, tgl was monitored
---------------------------------------------------------------------------
 Coverage status: End of All Coverages ...
 V C S   S i m u l a t i o n   R e p o r t
Time: 155
CPU Time:      0.400 seconds;       Data structure size:   0.0Mb

I find it weird, get_inst_coverage() shows 0%, in other simulators the result is 100%

Mentor Questa sim:

# Loading work.top(fast)
#
# vsim -voptargs=+acc=npr
# run -all
# Coverage:100.000000%
# ** Note: $finish : testbench.sv(26)
# Time: 155 ns Iteration: 1 Instance: /top
# End time: 00:16:22 on Apr 15,2021, Elapsed time: 0:00:01
# Errors: 0, Warnings: 0
Done

To generate the urgReport:

urg -dir *.vdb

firefox urgReport/grp0.html

Result:

Summary for Variable cp
CATEGORY    EXPECTED    UNCOVERED    COVERED    PERCENT
Automatically Generated Bins     8     0     8     100.00
Automatically Generated Bins for cp

Bins
NAME       COUNT       AT LEAST  
auto[0]     1     1
auto[1]     1     1
auto[2]     1     1
auto[3]     1     1
auto[4]     1     1
auto[5]     1     1
auto[6]     1     1
auto[7]     1     1 

Thursday, April 1, 2021

Fork Join_none and SV Objects

 Typically whenever we require to spawn threads using fork join_none and a for loop, we use "automatic int". This is required to pass on the correct value into the threads. Otherwise, the last value in the loop is passed on to all the threads.


What if an object is passed instead of a data_type like int?

In the below code, we have 3 scenarios

1. Using an array of objects and automatic int whilst spawning threads.

2. Using a queue

3. Not having 'automatic int' to guide the array.


CODE:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
//==================================================//
// CLASS : DATA_OBJ
// Description :
// containts data_id and data
// 
//==================================================//
class data_obj;
  int data_id;
  string data;
  
  //==================================================//
  // load_val
  // loads data_id and data
  //==================================================//
  function void load_val ( int id, string val);
    data_id = id;
    data    = val;
  endfunction
endclass

//==================================================//
// TEST_CLASS
// Description:
// Contains and array and queue
// Intention is to check the automatic function in 
// SV class
//==================================================//

class test_class;
  
  data_obj obj[3];
  data_obj obj_q[$];
  
  //==================================================//
  // LOAD_OBJ
  // Fills array and queue with data_obj objects
  //==================================================//
  function void load_obj();
    for(int i=0;i <3;i++) begin
      obj[i] = new;
      obj[i].load_val(i,"pavan");
      obj_q.push_back(obj[i]);
    end
  endfunction
  
  //==================================================//
  // SPAWN
  // Uses automatic int approach to load object into
  // print_data function
  // TRY : Try replacing 'j' with 'i'
  //==================================================//
  function void spawn();
    for(int i=0; i<3;i++) begin
      automatic int j=i;
      fork
        print_data(obj[j]);  // Replace J with I and check    
      join_none
    end
  endfunction
  
  //==================================================//
  // POP_SPAWN
  // Simply pops the data into the print_data function
  //==================================================//
  function void pop_spawn();
    for(int i=0; i<3;i++) begin
      fork
        print_data(obj_q.pop_front());      
      join_none
    end
  endfunction
  
  //==================================================//
  // Print_data
  // Prints the data
  //==================================================//
  function void print_data(data_obj obj);
    $display("OBJ ID:%0d VAL:%0s",obj.data_id,obj.data);
  endfunction
  
endclass

//==================================================//
// MODULE: TOP
//==================================================//
module top;

  test_class test_c;
  
  initial begin

    test_c = new;
    test_c.load_obj();
    test_c.spawn();      // Spawn threads using automatic int approach
    test_c.pop_spawn();  // Spawn threads using queue pop approach
    #100ns;
   
  end
endmodule: top


RESULTS:

1. Using an array of objects and automatic int whilst spawning threads.

Compiler version Q-2020.03-SP1-1; Runtime version Q-2020.03-SP1-1; Apr 1 22:21 2021
OBJ ID:0 VAL:pavan
OBJ ID:1 VAL:pavan
OBJ ID:2 VAL:pavan

 2. Using a queue

Compiler version Q-2020.03-SP1-1; Runtime version Q-2020.03-SP1-1; Apr 1 22:23 2021
OBJ ID:0 VAL:pavan
OBJ ID:1 VAL:pavan
OBJ ID:2 VAL:pavan

3. Not having 'automatic int' to guide the array.

Compiler version Q-2020.03-SP1-1; Runtime version Q-2020.03-SP1-1; Apr 1 22:24 2021

Error-[NOA] Null object access
testbench.sv, 79
The object at dereference depth 0 is being used before it was
constructed/allocated.
Please make sure that the object is allocated before using it.

#0 in \test_class::print_data at testbench.sv:79
#1 in \test_class::spawn at testbench.sv:57
#2 in top at testbench.sv:95
#3 in top

Tuesday, January 12, 2021

SYSTEM VERILOG - Interview questions



This was asked in one of the interviews I faced with a product company.

Looks simple at first glance, but sometimes these questions might catch you off-guard.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
class base;
  int a;
  
  function new ( int val );
    a = val;
  endfunction
  
  function void display();
    $display("BASE:: A:%0d",a);
  endfunction
  
endclass

class derived extends base;
  
  function new (int val);
    super.new(19);
    a = val;
  endfunction
  
  function void display();
    $display("DERIVED:: A:%0d",a);
  endfunction
  
endclass

module top;
  base b;
  derived d;
  
  initial begin
    b = new(10);
    d = new(20);
    
    b.display();
    d.display();
    
    b = d;
    b.display();
    d.display();
    
   end
  
endmodule: top


Guess the output in the following scenarioes.

  1. Without call to super.new(19) in line 19.
  2. With call to super.new(19)
    1. Without virtual method in Base class
      1. As-it-is
      2. With one line ' int a; '  added to the derived class code
    2. With adding virtual keyword in front of display() in Base class
      1. Repeat 2.1.1 and 2.1.2

=======================================================================

Answers :

1. Error-[SV-SNCIM] Super new call is missing

testbench.sv, 17
$unit
Base class constructor specification is missing in derived class 'derived'.
Please add <base class>::new arguments to 'extends' specification or add
call to 'super.new' in <derived class>::new.


1 error

2.1.1  - Without virtual and without < int a; > in base class
Compiler version Q-2020.03-SP1-1; Runtime version Q-2020.03-SP1-1; Jan 12 07:21 2021
BASE:: A:10
DERIVED:: A:20
BASE:: A:20
DERIVED:: A:20

2.1.2 - Without virtual and with < int a; > in base class

Compiler version Q-2020.03-SP1-1; Runtime version Q-2020.03-SP1-1; Jan 12 07:21 2021
BASE:: A:10
DERIVED:: A:20
BASE:: A:19
DERIVED:: A:20

2.2.1 With virtual and without < int a; > in base class

Compiler version Q-2020.03-SP1-1; Runtime version Q-2020.03-SP1-1; Jan 12 07:22 2021
BASE:: A:10
DERIVED:: A:20
DERIVED:: A:20
DERIVED:: A:20

2.2.2 With virtual and with < int a; > in base class

Compiler version Q-2020.03-SP1-1; Runtime version Q-2020.03-SP1-1; Jan 12 07:23 2021
BASE:: A:10
DERIVED:: A:20
DERIVED:: A:20
DERIVED:: A:20

Thursday, November 26, 2020

Using GDB in simulation runs to debug C-code

When we run simulations with C-models (along with RTL and SV-UVM TB ) we might want to debug the C-code to identify issues.

Here is a list of commands for GDB ( for VCS )

  1. gdb <SIMV absolute path>.
  2. break <File_name>:<Line_number>
  3. run <Simulation command line arguments>

These will allow you to to run the simulation until the debug point.

  1. For executing line by line we can use <next>
  2. For step, we can use <step>
  3. To continue till next occurrence of  break point use <continue >
  4. To print any variable with (print <var>)



Tuesday, November 17, 2020

Stuck at 0ns

Yesterday, I had an issue in one of my simulations, were the run was stuck at 0ns.Upon debug, I found an issue in the code. Although it looks obvious it takes quite a while to figure these out... Isolating the problem ....

module top;
  bit [2:0] cnt;
  initial begin
   for(cnt = 0; cnt <8;cnt++) $display("Cnt:%0d",cnt);
 end
endmodule

Look through the code, and we might feel it just prints 0...7 and the simulation stops.Once we run the code we realize that it gets stuck in an infinite loop.Reason is simple, the 'cnt' variable is a 3 bit variable, when the loop reaches 7 the 'cnt' is incremented and gets rounded of to 0, once again starting the loop , and this goes on and on.


 

Saturday, November 7, 2020

System verilog constraints and OOPs

Does constraints of a parent class apply when child class handle is passed on to the later?

Code : 

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
class parent;
  rand int a;
  rand int b;
  constraint c_a { a == 10; }
  constraint c_b { b == 100; }
  
  function void display();
    $display("Parent - A - %0d B - %0d ",a,b);
  endfunction
endclass: parent

class child extends parent;
  rand int a;
  constraint c_a { a == 20; }
  
  virtual function void display();
    $display("Child - A - %0d B - %0d ",a,b);
  endfunction
endclass

class grand_child extends child;
  
  constraint c_a { a == 30; }
  
  function void display();
    $display("Grand Child - A - %0d B- %0d ",a,b);
  endfunction
endclass


module top;
  parent      p;
  child       c;
  grand_child gc;
  
  initial begin
    p = new;
    c = new;
    gc= new;
    
    p = gc;    
    
    void'(p.randomize());
    void'(c.randomize());
    void'(gc.randomize());
    p.display();
    c.display();
    gc.display();
  end
    
  
endmodule

 

Here we have 2 cases, 

1. Case - 1 : Grand child handle 'gc' is assigned to parent handle 'p'. We have not used virtual key word in display function in parent, therefore limiting the scope to the parent int variables.

2. Case - 2 : Using virtual keyword in parent class function display(); 

Observation : 

  • You can see from the print logs, that constraint of parent class on integer 'a' is not applied. we see a random integer value displayed instead of 10.
  • Integer 'b' has constraint applied and therefore you see 100 in the print statement.
  • Reason : since parent handle now contains the handle of grand child, the handling of both constraints differ, a is overridden ( in child class you have 'int a' re-declared )
  • What if we use virtual keyword before display ? Now the scope of the display function is in grand child class, and there fore you can see 30 - 100
  • What if you remove 'int a' in child class?

Without virtual keyword ( in parent display function ):

Compiler version Q-2020.03-SP1-1; Runtime version Q-2020.03-SP1-1; Nov 7 23:53 2020
Parent - A - -1360295855 B - 100
Child - A - 20 B - 100
Grand Child - A - 30 B- 100
V C S S i m u l a t i o n R e p o r t  

With virtual keyword ( in parent display function )

Compiler version Q-2020.03-SP1-1; Runtime version Q-2020.03-SP1-1; Nov 7 23:55 2020
Grand Child - A - 30 B- 100
Child - A - 20 B - 100
Grand Child - A - 30 B- 100
V C S S i m u l a t i o n R e p o r t  

Removing 'int a' in child class ( keep the constraint )

Compiler version Q-2020.03-SP1-1; Runtime version Q-2020.03-SP1-1; Nov 8 00:15 2020
Parent - A - 30 B - 100
Child - A - 20 B - 100
Grand Child - A - 30 B- 100
V C S S i m u l a t i o n R e p o r t

Constraint to have N elements distributed in M bins

Code to distribute N elements into M bins, you add unique keyword to have each bin will have unique number of elements. class test; param...