-----------------------Occasional Updates-----------------------
I want to share some notes about SystemVerilog, I'm a beginner at this.
Part1 Data Type:
bit : unsigned; byte: signed.
Part2 Task and Functions:
Task
task automatic my_task(input int a, int b); //automatic allocate memory dynamically when the task is called.
if (a==b)begin
my_task(a-1, b+1);
return; //end copy of task
end
global a = a;
global b = b;
endtask
automatic my_task(input int a, int b); //automatic allocate memory dynamically when the task is called.
if (a==b)begin
my_task(a-1, b+1);
return; //end copy of task
end
global a = a;
global b = b;
endtask
Function with return value:
function automatic int factorial (int n);
if(n==0) return(1);
else return(factorial(n-1)*n);
end function
automatic int factorial (int n);
if(n==0) return(1);
else return(factorial(n-1)*n);
end function
Function without return value:
function automatic void func ();
a++;
end function
reg a;
initial
func() //call function
automatic void func ();
a++;
end function
reg a;
initial
func() //call function
Function cannot enable task while task can enable function
Part3 Arrays and Queues
The key difference between a queue and an associative array is how individual elements are added or removed.
<1>. Fixed-size arrays:
int a [0:15] // 13 ints, equals to "int a[16]"
a [max_num ... 3, 2, 1, 0]
int b [0:3][0:4] euqals int b[4][5].
<2>. unpacked & packed Array:
bit [7:0] array4 [2:0]; //unpacked array declaration
bit [2:0][7:0] array5; //packed array declaration
<3>. associative array
Associative array can be used when size of array is nor know as it can be built as key/value pairs
data_type array_name [ index_type ]; //declaration
int a_array1[*] ; // associative array of integer (unspecified index)
bit [31:0] a_array2[string]; // associative array of 32-bit, indexed by string
ev_array [myClass]; //associative array of event,indexed by class
Functions:
num() --> returns the number of entries in the associative array.
delete(index) --> removes the entry at the specified index.exa_array.delete(index).
exists(index) --> returns 1 if an element exists at the specified index else returns 0.
first(var) --> assigns the value of first index to the variable var.
last(var) --> assigns the value of last index to the variable var.
next(var) --> assigns the value of next index to the variable var.
prev(var) --> assigns the value of previous index to the variable var.
<4>. Dynamic Array
(Dynamic array is useful for contiguous collection of variable that has varies member)
datatype name[]; //delare dynamic array
datatype name[] = new[<x_size>][(array)] // allocate a new array "name" with size "x_size" and type "datatype"
Resizing: <array> = new[<size>](<src_arrya>); dyn = new[j*2](fix);
if i have int a = new[100], increase size of a: a=new[200](a), the lower 100 element is original elements.
Function:
new[ ] --> allocates the storage.
size( ) --> returns the current size of a dynamic array. //int a[]=new[256]; int x=a.size(); (x=256)
delete( ) --> empties the array, resulting in a zero-sized array. //a.delete(), make array_size =0;
Example:
//declaration
bit [7:0] d_array1[ ];
int d_array2[ ];
//memory allocation
d_array1 = new[4]; //dynamic array of 4 elements
d_array2 = new[6]; //dynamic array of 6 elements
<5>. Queue
data_type queue_name[$]; //declear a queue
a [0, 1, 2, 3 ....$]
rightmost_element = a[$]//lats one; left_most_element=a[0]; //first one
a=a[1:$] //delete the leftmost element; a=a[0:$] delete the rightmost element
length = a.size a={} //clear the list
Functions:
Size(); delete();
insert() // B.insert(i,x) -> B={B[0:i-1], e, B[i:$]};
pop_front() // x=B.pop_front(), x=B[0], B=B[1:$]; remove and return first element
pop_back() // x=B.pop_back(), x=B[$], B=B[0:$-1];
push_front() //x=B.push_front(a), x={a, B}; insert the variable at front of the queue
push_back() //x=B.push_back(a), x={B, a};
FIFO: push_back() + pop_front()
Application to Design:
<1>. Interfaces:
Interfaces are defined once and used widelu, it simplifies design
Inter faces are synthsizable
Interface cannot define other module.
ModPorts
Since different users of the interface need different views(Master/Slave and Monitor/driver have opposite direction on the same signal), ModPort can help you to group signal and specify directions.
<2>. Clocking Block
Help you solve the "hole/setup" time problem
Used to specify the timing of synchronous signals with respect to the clock
Ensure that all signals are driven or sampled with same clock delay
Interfaces can contain multiple clocking blocks
example:
clocking bus @(posedge clk1);
default input #10ns output #2ns //setup time < 10, hold time <2ns
input data, ready,
enable = top.mem1.enable;
output negedge ack;
input #1 addr;
endclocking
bus @(posedge clk1);
default input #10ns output #2ns
input data, ready,
enable = top.mem1.enable;
output negedge ack;
input #1 addr;
endclocking
<3>. Program Blocks
Race condition can occur if the module is used as top-level for both design and testbench
A program block is similar to a module, used for testbench code
- sending input stimuli to the design under test (DUT),
- receiving and verifying the response for the DUT.