Friday, October 14, 2016

vim format for system verilog and matching keywords

For System Verilog color highlighting, 

augroup filetype
  " Verilog HDL
  au BufNewFile,BufRead *.bv,*.sv     set ft=verilog_systemverilog
  au BufNewFile,BufRead *.vr,*.vrh,*vri  set ft=vera
augroup END

If you want to match begin-end, case-endcase, task-endtask etc in a nested code in vim, 
here is the code required in .vimrc and enjoy vimming.
You have to download matchit.vim from online.

source /home/username/matchit.vim

:let b:match_ignorecase = 1

:let b:match_words = '\<begin\>:\<end\>'

useful link about svn or s4



One command excited me last week is “rs4 scrub”. Very interesting and useful cmd !!!


This link also says about viewspec files etc..

Tuesday, August 16, 2016

SV program for tic tac toe game

Another example of sum method in the constraint for 2D array.

module ttt;
class class1;

rand int unsigned a[3][3];
rand int unsigned i,j;

constraint c3 {(a.sum() == 5);}
constraint c4 {foreach(a[i,j]) (a[i][j] >=0 && a[i][j]<=1);}

endclass: class1

initial
begin
class1 cl = new();


repeat (10) begin
  cl.randomize();

$display("Game Over:");
$display("%d %d %d", cl.a[0][0],cl.a[0][1],cl.a[0][2]);
$display("%d %d %d", cl.a[1][0],cl.a[1][1],cl.a[1][2]);
$display("%d %d %d", cl.a[2][0],cl.a[2][1],cl.a[2][2]);
end
end

endmodule


Result:-
Game Over:
         1          1          0
         1          1          0
         0          0          1
Game Over:
         1          1          0
         1          1          0
         0          1          0
Game Over:
         0          1          0
         1          1          1
         0          0          1
Game Over:
         1          0          1
         0          0          1
         1          1          0
Game Over:
         1          0          1
         0          1          1
         0          1          0
Game Over:
         0          1          1
         0          1          0
         1          1          0
Game Over:
         0          1          1
         1          0          1
         0          0          1
Game Over:
         0          0          1
         1          1          0
         1          0          1
Game Over:
         0          0          0
         0          1          1
         1          1          1
Game Over:
         1          1          0
         1          0          1
         0          0          1

           V C S   S i m u l a t i o n   R e p o r t 

Tuesday, August 9, 2016

SV constraint program for shuffle


Here is the program to generate random array of signed integers which is shuffle of another random array.  This exhibits significance of array methods like sum,product or xor in the constraint.



class cfg_c;
  rand int signed A[];
  rand int signed B[];
 
  constraint A_B_size_cnstr{
    A.size() inside {[4:5]}; // can modify this
    B.size() == A.size();
  }
 
  constraint B_elements_cnstr{
    solve A.size() before A;
    solve B.size() before B;
    foreach(B[i])
      B[i] inside {A};    
    B.sum() == A.sum();
    (B.xor() ^ A.xor()) == 0;
    B.product() == A.product();
  }
endclass : cfg_c

module test;
  cfg_c cfg;
  initial begin
    cfg = new();
    repeat(10) begin
               cfg.randomize();
               $display("After randomization..");
               foreach(cfg.A[i])
                              $display("A[%0d] = %0d :: B[%0d] = %0d", i, cfg.A[i], i, cfg.B[i]);
    end
  end
endmodule : test


Result:-
After randomization..
A[0] = -2061227070 :: B[0] = -945796533
A[1] = 577051819 :: B[1] = -287061759
A[2] = -945796533 :: B[2] = 577051819
A[3] = -287061759 :: B[3] = -2061227070
A[4] = -1856519535 :: B[4] = -1856519535

Thursday, July 21, 2016

inheritance -- an interesting example

When a derived class inherits properties from its base class and derived class has its own properties with same name, then there will be 2 copies of those properties.
If you take a below example, class b will have 2 copies of the variable enable. So it wont print the display since the object B will be able to access derived class version of 'enable' variable and the function 'abc' checks the base class version of 'enable' variable.

class a;
bit enable;
virtual function void abc();
  if(enable)
  $display("ABC enable=%0d",enable);
endfunction
endclass

class b extends a;
bit enable;
endclass

module m;
a A;
b B,ba;
initial begin
  A=new();
  B=new();
  A.enable=1;
  B.enable=1;
  B.abc();
end

endmodule


How to fix this? 
1. Use the base class object(A) point to derived class object(B) and set the base version of 'enable' variable. Now if you call B.abc(), it will print. 

class a;
bit enable;
virtual function void abc();
  if(enable)
  $display("ABC enable=%0d",enable);
endfunction
endclass

class b extends a;
bit enable;
endclass

module m;
a A;
b B,ba;
initial begin
  B=new();
  A = B;    
  A.enable=1;
  B.enable=1;
  B.abc();
end
endmodule


2. Another solution is using static variable. Here the beauty is you don't even need to create an object of base class. 

class a;
static bit enable;
virtual function void abc();
  if(enable)
  $display("ABC enable=%0d",enable);
endfunction
endclass

class b extends a;
bit enable;
endclass

module m;
a A;
b B,ba;
initial begin
   B=new();
  A.enable=1;
  B.enable=1;
  B.abc();
end
endmodule




Saturday, July 16, 2016

fine gain process control

A process is a built-in class in System Verilog that allows one process to access and control another process once it has started. Users can declare variables of type process and safely pass them through tasks or incorporate them into other objects. The prototype for the process class is as follows:

class process;
typedef enum { FINISHED, RUNNING, WAITING, SUSPENDED, KILLED } state;
static function process self();
function state status();
function void kill();
task await();
function void suspend();
function void resume();
function void srandom( int seed );
function string get_randstate();
function void set_randstate( string state );
endclass

Sometimes we encounter the situations where we need to spawn off threads and if anyone of the thread is done, we might want to kill other threads. One straightward solution is using disable statement but that is not scalable if number of threads are more.
If you look at the following example, we spawn off 10 threads and we want to wait for 2nd thread to finish and by that time, if the other threads are not done, we want to kill it.
module process_test;
bit clk;
initial begin
   forever begin
      #10 clk = ~clk;
   end
end

task automatic spawn_threads(int N);
process job[]= new[N];
foreach(job[j])
  fork
    automatic int k=j;
    begin  
      job[k]=process::self();
      $display("Process %0d started %t",k, $time);
      repeat(10*k) @(posedge clk);
      $display("Process %0d finished %t",k, $time);
    end
  join_none

foreach (job[i])
   wait(job[i]!=null);

job[2].await();

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

initial begin
  spawn_threads(10);
  $finish();
end
endmodule

Result:-
Compiler version K-2015.09-SP2-1; Runtime version K-2015.09-SP2-1;  Jul 16 14:44 2016
Process 0 started                    0
Process 0 finished                    0
Process 1 started                    0
Process 2 started                    0
Process 3 started                    0
Process 4 started                    0
Process 5 started                    0
Process 6 started                    0
Process 7 started                    0
Process 8 started                    0
Process 9 started                    0
Process 1 finished                  190
Process 2 finished                  390
$finish called from file "test_process.sv", line 38.
$finish at simulation time                  390
           V C S   S i m u l a t i o n   R e p o r t 


This is useful not just for killing the threads but also we can suspend and resume threads based on our own conditions.




Thursday, July 14, 2016

Where Does The ::type_id::create Command Come From?

Below explanation have been extracted from (http://www.sunburst-design.com/papers/CummingsSNUG2012SV_UVM_Factories.pdf) and I found it useful to know :-).

Trying to understand the inner workings of UVM by examining the source code can be a difficult task. The myriad of intertwined macro definitions coupled with frequent polymorphic replacement and indirection of base classes with extended classes, and repeated use of similar or the same method names in different classes makes it difficult to understand how some of the UVM features actually work. There is no greater example of this indirection and confusion than the ::type_id::create command.
To understand this command, first recognize that the use of the :: operators in this command indicate that you are probably using one or more static function calls, which is indeed the case.

To better understand this command, consider the following lines of code from the creation of the tb_agent in the simple example used in this paper:
tb_driver drv; // declaration of a tb_driver handle

function void build_phase(uvm_phase phase);
super.build_phase(phase);
drv = tb_driver::type_id::create("drv", this);
...
endfunction 

This command is going to call the ::type_id::create command from the tb_driver, which happens to be code largely inherited from other macros and classes. The source of this command can be traced to the following: 
(1) tb_driver is an extension of uvm_driver, which is an extension of uvm_component, which is a derivative of uvm_object, which defines a virtual method called create() with a single input argument. So how can the tb_driver::type_id::create("drv", this) command pass two arguments to this virtual method? 
The create() method defined in the uvm_object base class and passed down to the tb_driver class IS NOT THE create() COMMAND USED IN THIS FACTORY CONSTRUCTOR! (This is a point of confusion!) 

(2) At the top of the tb_driver class definition is the macro-invocation:
`uvm_component_utils(tb_driver) 


(3) The `uvm_component_utils macro is defined in the
<uvm_src_dir>/src/macros/uvm_object_defines.svh file 


(4) In this file, `uvm_component_utils(T) is defined to be the macros:
`define uvm_component_utils(T) \
`m_uvm_component_registry_internal(T,T) \
`m_uvm_get_type_name_func(T) 


(5) In this same file, `m_uvm_component_registry_internal(T,S) is defined to be:
`define m_uvm_component_registry_internal(T,S) \
typedef uvm_component_registry #(T,`"S`") type_id; \
static function type_id get_type(); \
return type_id::get(); \
endfunction \
virtual function uvm_object_wrapper get_object_type(); \
return type_id::get(); \
endfunction


(6) And in this same file, `m_uvm_get_type_name_func(T) is defined to be:
`define m_uvm_get_type_name_func(T) \
const static string type_name = `"T`"; \
virtual function string get_type_name (); \
return type_name; \
endfunction


Doing the macro expansion, the top of the tb_driver class now includes the code:
class tb_driver extends uvm_driver #(trans);
//`uvm_component_utils(tb_driver)
//`define uvm_component_utils(T) \
// `m_uvm_component_registry_internal(T,T) \
// `m_uvm_get_type_name_func(T)
//`define m_uvm_component_registry_internal(T,S) \
typedef uvm_component_registry #(tb_driver,"tb_driver") type_id;
static function type_id get_type();
return type_id::get();
endfunction
virtual function uvm_object_wrapper get_object_type();
return type_id::get();
endfunction
//`define m_uvm_get_type_name_func(T) \
const static string type_name = "tb_driver";
virtual function string get_type_name ();
return type_name;
endfunction 


This macro added the type_id type definition, get_type() method, get_object_type() method, static type_name string, and get_type_name() method, to the tb_driver class code. The type_id type definition is part of the ::type_id::create command, and type_id is just a type definition for the class type:
uvm_component_registry #(tb_driver,"tb_driver")


(7) The uvm_component_registry parameterized class is defined in the
<uvm_src_dir>/src/base/uvm_registry.svh file 


(8) In this file, is the definition for the uvm_component_registry class. An abbreviated section of this class definition is shown below:
1 class uvm_component_registry #(type T=uvm_component, string Tname="")
2 extends uvm_object_wrapper;
3
4 typedef uvm_component_registry #(T,Tname) this_type;
5
6 virtual function uvm_component
7 create_component (string name, uvm_component parent);
8 T obj;
9 obj = new(name, parent);
10 return obj;
11 endfunction
12
13 const static string type_name = Tname;
14
15 virtual function string get_type_name();
16 return type_name;
17 endfunction
18
19 local static this_type me = get();
20
21 static function this_type get();
22 if (me == null) begin
23 uvm_factory f = uvm_factory::get();
24 me = new;
25 f.register(me);
26 end
27 return me;
28 endfunction
29
30 static function T create(string name, uvm_component parent, ...);
31 uvm_object obj;
32 uvm_factory f = uvm_factory::get();
33 ...
34 obj = f.create_component_by_type(get(),contxt,name,parent);
35 if (!$cast(create, obj)) begin
36 string msg;
37 msg = {<"... error message ...">};
38 uvm_report_fatal("FCTTYP", msg, UVM_NONE);
39 end
40 endfunction
41 ...
42 endclass 


On line 4, this_type is set to
uvm_component_registry #(tb_driver,"tb_driver") 


On line 21 is the static get() function that, if the this_type (tb_driver registry class) is null, will call the uvm_factory static get() method to create a handle for this tb_driver registry and copy that handle to the this_type handle, register the tb_driver registry with the factory and then return the handle to the caller of the get() function. The same get() function just returns the handle if it already exists. 

On line 19 is the static handle declaration for the local static this_type me declaration, which calls the static get() function (described in the preceding paragraph) to register this tb_driver registry class with the factory and assign the corresponding handle. Since this handle and the get() function are both static, they will both happen automatically when the testbench is compiled without any required user invocation. In this way, when the `uvm_component_utils() macro is called from each component, it literally registers the corresponding registry class with the factory, which makes it possible to
::type_id::create any registered component from anywhere in the testbench class components. 


Line 30 - When the uvm_component_registry #(tb_driver,"tb_driver") is compiled, the static create() command is also made statically available. The most confusing piece of the static create() command code is on line 35. It took me 2 hours to figure out this command happens to be a rather simple command, once you understand the code. Most of the function methods in the UVM base classes use the SystemVerilog return command to return the correct value from the function, but line 35 is using the old Verilog way to return a function value. 

On line 34, the factory is asked to create the requested component by type and return the component handle to a uvm_object handle (obj - declared on line 31). This handle is then cast to the correct component type, which happens to be the type of the create() function. By casting back to the function name, the cast is actually assigned back to type of the function, and the caller of this function is then given a handle to the created component. Assigning (casting) to the function name is the old Verilog way to return a function value. The new SystemVerilog way to return a value would have been to declare a handle of the function type (T), cast the uvm_object handle to declared T-type function handle, and then call return to give back the T-type function handle. Hopefully this description just saved you 2 hours! 

In any uvm_*_registry class, is the static create() function. This is the last piece of the ::type_id::create() command. This explains where this command comes from. For components, the <component_type>::type_id::create(<component_handle>, this) command comes from the uvm_component_registry class parameterized to the component type. Similarly, for transactions, the <object_type>::type_id::create(<object_handle>this) command comes from the uvm_object_registry class parameterized to the object type.

uvm_object_wrappers are the proxy (substitute, place holder) types that are actually stored in the factory. When you create a component, you have actually created a uvm_component_registry class that is an extension of the uvm_object_wrapper. When you create a transaction, you have actually created a uvm_object_registry class that is an 
extension of the uvm_object_wrapper. It is handles of these component and object extensions of the wrapper class that are actually stored in the type-based factory.