Before moving to SystemVerilog concepts, we will look into what is Verification? What is verified? Why do we need to verify it? How to Verify?
We need to verify the design to make sure that the design is an accurate representation of the specification without any bugs. Verification is carried out to ensure the correctness of design, to avoid surprises at a later time, to avoid a re-spin of the chip and to enter the market on time with good quality.
In the process of verification, we are going to verify modules, SOC’s (System On Chip) by driving the input to check the design behavior. we should check the behavior of the design by driving correct and an error input, in both cases need to observe the design as it is behaving as expected, if not then there will be a bug.
In verification, we use the Testbench/Verification environment to determine the correctness of the design under test (DUT).
below is the functionality of the Testbench/Verification environment,
Generate stimulus
Apply stimulus to the DUT
Capture the response
Check for the correctness
Measure progress against the overall verification goals
SystemVerilog concepts and methods are explained in the upcoming chapters. The content herein the SystemVerilog tutorial is just for quick reference, for more detailed explanation refer to SystemVerilog LRM.
100+ easy understanding, compilation error-free example codes.
While going through the tutorial no need to copy example code to your simulator, Just One Click for the execution of example codes. All the example codes are saved in the EDA playground.
Thanks to doulos for providing the free access and an option to share the codes on (EDA playground).
Unique constraint can be used to generate unique values across the variables, generate unique elements in an array (Fixed Size Array, Dynamic Array, Associative array and Queue) .
In below example the variables (var_1, var_2 and var_3) are constrained using keyword unique, On randomization which leads to generation of unique values to the variables.
Same way to an array (array), random unique elements can be generated by constraining array with unique keyword.
class unique_elements;
rand bit [3:0] var_1,var_2,var_3;
rand bit [7:0] array[6];
constraint array_c {unique {array};}
function void display();
$display("var_1 = %p",var_1);
$display("var_2 = %p",var_2);
$display("var_3 = %p",var_3);
$display("array = %p",array);
endfunction
endclass
program unique_elements_randomization;
unique_elements pkt;
initial begin
pkt = new();
pkt.randomize();
pkt.display();
end
endprogram
module test;
function string get_time();
int file_pointer;
//Stores time and date to file sys_time
void'($system("date +%X--%x > sys_time"));
//Open the file sys_time with read access
file_pointer = $fopen("sys_time","r");
//assin the value from file to variable
void'($fscanf(file_pointer,"%s",get_time));
//close the file
$fclose(file_pointer);
void'($system("rm sys_time"));
endfunction
initial begin
$display("Current System Time is %s",get_time());
end
endmodule
try_next_item();
This is a non-blocking variant of the get_next_item() method. It will return a null pointer if there is no REQ sequence_item available in the sequencer.
If seq_item is not available on the exection of try_next_item, it returns null; So on execution of req.print(); simulator will give a NULL pointer dereference error.
Best practice to use try_next_item();
seq_item_port.try_next_item(req);
if(req != null) begin
req.print();
drive(req); //drive logic
seq_item_port.item_done();
end
Example on Using try_next_item();
Below is one of the scenario where i come acroos the real use case of try_next_item();
In this Sequence item consists of multiple pkt’s to be driven,
class pkt_type;
rand int pkt_id;
...
...
endclass
class seq_item extends uvm_seq_item;
...
rand pkt_type pkt[];
...
...
endclass
Here pkt is dynamic array, it can be 1 to ‘n’ number. On every randomization all the 1 to n pkt’s will get same pkt_id;
As per the design implementation (DUT), the next pkt of same pkt_id can be driven only after getting the completion for previously driven pkt with same pkt_id. and its allowed to drive the pkt with different pkt_id. (Getting the completion for the pkt may take some time, so it is allowed to drive other pkt’s)
Below is one of the way to implement the same,
while(1) begin
if(comp_q.size()>0) begin //comp_q => completions are sampled and corresponding pkt_id is pushed to comp_q
tmp = comp_q.pop_front();
drive_pkt(tmp_pkt[tmp]); //next pkt with the pkt_id will be driven
...
...
end
else begin
seq_item_port.try_next_item(req);
if(req!=null) begin
drive_pkt(req);
if(req.pkt.size()>1) tmp_pkt[req.pkt.pkt_id] = req; //req with multiple pkt's are stored for further processing
seq_item_port.item_done();
end
end
We use cookies to ensure that we give you the best experience on our website. If you continue to use this site we will assume that you are happy with it.Ok