SV - OOP Concepts (object-oriented programming)
Reference:
http://www.verificationguide.com/p/systemverilog-classes_23.html
class
A class is a description of some group of things that have something in common
<1>. Construct
class sv_class; //class properties
int x;
task set(int i); x = i;
endtask
function int get();
return x;
endfunction
endclass; //class properties
int x;
task set(int i); x = i;
endtask
function int get();
return x;
endfunction
endclass
module sv_constructor;
sv_class class_1; // create handle 1class_1 = new(); // construct object
sv_class class_1; // create handle 1class_1 = new(); // construct object
endmodule
class只有经过了new()函数才真正开辟了内存,否则只是一个空的、没有实际存在, 若在class中未实现new()函数,
则会有系统默认new()
<2>. 'This' keyword
Solve ambiguity when the class can faction has the same variable name:
class packet;
//class properties
bit [31:0] addr;
bit [31:0] data;
bit write;
string pkt_type;
//constructor
function new(bit [31:0] addr,data,bit write,string pkt_type);
this.addr = addr;
this.data = data;
this.write = write;
this.pkt_type = pkt_type;
endfunction
//method to display class prperties
function void display();
$display("---------------------------------------------------------");
$display("\t addr = %0h",addr);
$display("\t data = %0h",data);
$display("\t write = %0h",write);
$display("\t pkt_type = %0s",pkt_type);
$display("---------------------------------------------------------");
endfunction
endclass
<3>. Classes Inheritance
You can use a child class to access parents class:
If two functions in the child class and parents class have the same function name. The function in the parent class will be overridden. Add "super" to the child function can solve this problem
class parent_class;
bit [31:0] addr;
function display();
$display("Addr = %0d",addr);
endfunction
endclass
class child_class extends parent_class;
bit [31:0] data;
function display();
super.display();
$display("Data = %0d",data);
endfunction
endclass
module inheritence;
initial begin
child_class c=new();
c.addr = 10;
c.data = 20;
c.display();
end
endmodule
Randomization and Constraints
module test_rand;
typedef enum{SM, MED, LRG}, trans_len // SM = 0, MED = 1, LRG = 2;
class transaction;
rand bit [19:0] addr;
rand tras_len len;
rand bit [3:0] byte_len
rand bit wr_or_ed_b;
constraint c1{wr_or_ed_b -> len !=LRG;}
constraint c2{(len==SM) -> (byte_len <=4;)}
constraint c3{(len==MED) -> (byte_len >4 && byte_len <= 8;)}
virtual function string tostring()
return sformat("%5H: %s %d bytes", addr,(wr_or_rd_b)?"WR":"RD", byte_len);
endfunction
endclass
Threads and Inter-Process
<1>. For-Join
Sequential statements are placed inside a begin/end block and executed in sequential order within the block. However, the blocks themselves are executed concurrently. Verilog statements outside any processing block are interpreted as concurrent statements and different procedural blocks execute concurrently.
Fork-Join will start all the processes inside it parallel and wait for the completion of all the processes.
module fork_join;
initial begin
fork
//Process-1
begin
$display($time,"\tProcess-1 Started");
#5;
$display($time,"\tProcess-1 Finished");
end
//Process-2
begin
$display($time,"\tProcess-2 Started");
#20;
$display($time,"\tProcess-2 Finished");
end
join
$finish;
end
endmodule
Result: 0 Process-1 Started
0 Process-2 Started
5 Process-1 Finished
20 Process-2 Finished
- Fork-Join_any will be unblocked after the completion of any of the Process.
- Fork-Join_none: Processes inside the fork-join_none block will be started at the same time, fork block will not wait for the completion of Process inside the fork-join_none.
<2>. Mailbox
A mailbox is a communication mechanism that allows messages to be exchanged between processes
Allow generator and driver running asynchronously and independently.
syntax: mailbox m = new(); //Unbounded mailbox m = new(5); //bounded
new() | Create a mailbox |
put() | Place a message in a mailbox |
try_put() | Try to place a message in a mailbox without blocking |
get() /peek() | Retrieve a message from a mailbox (peek only make copy) |
try_get() /try_peek() | Try to retrieve a message from a mailbox without blocking |
num() | Return the number of messages in the mailbox |
<3>. Synchronization - Events & Semaphores
Events are static objects useful for synchronization between the process.
module events_ex;
event ev_1; //declaring event ev_1
initial begin
fork
begin //process-1, triggers the event
#40;
$display($time,"\tTriggering The Event");
->ev_1; //trigger
end
begin //process-2, wait for the event to trigger
$display($time,"\tWaiting for the Event to trigger");
@(ev_1.triggered); //wait for trigger
$display($time,"\tEvent triggered");
end
join
end
endmodule
Result: 0 Waiting for the Event to trigger
40 Triggering The Event
40 Event triggered
Semaphores are used for shared resources access control.
new() | Create a semaphore with a specified number of keys |
get() | Obtain one or more keys from the bucket |
put() | Return one or more keys into the bucket |
try_get() | Try to obtain one or more keys without blocking |
module semaphore_ex;
semaphore sema; //declaring semaphore sema
initial begin
sema=new(1); //creating sema with '1' key
fork
display(); //process-1
display(); //process-2
join
end
//display method
task automatic display();
sema.get(); //getting '1' key from sema
$display($time,"\tCurent Simulation Time");
#30;
sema.put(); //putting '1' key to sema
endtask
endmodule
Result: 0 Current Simulation Time
30 Current Simulation Time