Established as per the Section 2(f) of the UGC Act, 1956
Approved by AICTE, COA and BCI, New Delhi
        Introduction to ASIC Design and
        Verification using System Verilog
       S C H O O L O F E L E C T R O N I C S A N D C O M M U N I C AT I O N
       ENGINEERING
       D r. A . R a g a n n a
   4/03/2023
COURSE OVERVIEW
 This course aims to give an in-depth introduction to the System Verilog which is
  an enhancement to the Verilog hardware description language (HDL). It also
  discusses the benefits of the new features, and demonstrates how design and
  verification can be more efficient and effective when using System Verilog
  constructs.
COURSE OBJECTIVES
The objectives of this course are:
1. To study the verification methodologies and basic concepts of System Verilog.
2. Study the different kinds of procedural statements of System Verilog.
3. Study the basic concepts of OOPs
4. To understand connecting of design and testbench.
COURSE OUTCOMES(CO’S)
On successful completion of this course; the student shall be able to:
1. Understand the Verification of a DUT and use different kinds of data types in
   System Verilog.
2. Analyze and test the System Verilog routines and procedural statements.
3. Understand and apply the basic concepts of OOPs in System Verilog.
4. Analyze the usefulness of a driver, monitor, checker, test cases in a verification
   environment.
COURSE CONTENT
UNIT 2: System Verilog Introduction, Procedural Statements, Tasks, Functions, and
Void Functions, Task and Function Overview, Routine Arguments, Returning from a
Routine, Local Data Storage, Time Values.
REFERENCE BOOKS
1. System Verilog for Verification: A Guide to Learning the Test-bench Language
   Features, Chris Spear, Publisher: Springer-Verlog New York, Inc. Secaucus, NJ,
   USA, 2006
2. Donald Thomas, “Logic Design and Verification Using System Verilog”, Create
   Space Independent Publishing Platform, 2014.
3. Language Reference Manual for System Verilog.
PROCEDURAL STATEMENTS AND ROUTINES
Introduction
   As you verify your design, you need to write a great deal of code, most of which
    is in tasks and functions.
   SystemVerilog introduces many incremental improvements to make this easier by
    making the language look more like C, especially around argument passing.
   If you have a background in software engineering, these additions should be very
    familiar.
    PROCEDURAL STATEMENTS AND ROUTINES
Procedural Statements
   SystemVerilog adopts many operators and statements from C and C++.
   You can declare a loop variable inside a for loop that then restricts the scope of the loop
    variable and can prevent some coding bugs.
   The increment ++ and decrement -- operators are available in both pre- and post- form.
   If you have a label on a begin or fork statement, you can put the same label on the
    matching end or join statement.
EXAMPLE 3-1 NEW PROCEDURAL STATEMENTS AND OPERATORS
     initial
     begin : example
     integer array[10], sum, j;
     // Declare i in for statement
     for (int i=0; i<10; i++) // Increment i
     array[i] = i;
     // Add up values in the array
     sum = array[9];
     j=8;
     do // do...while loop
     sum += array[j]; // Accumulate
     while (j--); // Test if j=0
     $display("Sum=%4d", sum); // %4d - specify width
     end : example // End label
EXAMPLE 3-2 USING BREAK AND CONTINUE WHILE READING A FILE
      initial begin
      logic [127:0] cmd;
      integer file, c;
      file = $fopen("commands.txt", "r");
      while (!$feof(file)) begin
      c = $fscanf(file, "%s", cmd);
      case (cmd)
      "": continue; // Blank line - skip to loop end
      "done": break; // Done - leave loop
      // Process other commands here
      ...
      endcase // case(cmd)
      end
      $fclose(file);
      End
FUNCTION
   Bigger designs are better arranged in smaller functional blocks.
   It facilitates debugging and reorganization.
   Functions and tasks plays:
      A well defined structure with a separate identity
      They can hide some variables
      They can be repeatedly invoked within the module
 A function is like a subroutine or a procedure in a program.
 It is defined separately within a module and can be called whenever
  necessary.
FUNCTION
   Task and Function are used to break up large procedures into smaller ones which helps to
    make life easier for developing and maintaining Verilog code. In this way, common
    procedures need to be written only once and can execute from different places. Both task and
    function are called from always or initial block and contain only behavioural statements.
   Functions provide a means of splitting code into small parts that are frequently used in a
    model.
   Functions are declared with in a module, and can be called from continuous assignment,
    always block or other functions. In a continuous assignment, they are evaluated when any of
    its declared inputs change
FUNCTION
FUNCTIONS
TASKS
TASKS
TASKS
TASKS, FUNCTIONS, AND VOID FUNCTIONS
   A function cannot have a delay,         Example 3-3 Ignoring a function’s return
    #100, a blocking statement such as      value
    @(posedge clock) or wait(ready),
    or call a task.                            void’(my_func(42));
                                            Example 3-4 Void function for debug
   In System Verilog, if you want to
                                            function void print_state(...);
    call a function and ignore its return
    value, cast the result to void.         $display("@%0d: state = %0s", $time,
                                            cur_state.name);
                                            Endfunction
TASK AND FUNCTION OVERVIEW
Routine begin...end removed
   The first improvement you may notice in
                                                    Example 3-5 Simple task without begin...end
    SystemVerilog is that begin...end blocks are
                                                    task multiple_lines;
    optional, while Verilog-1995 required them on
    all but single line routines.                   $display("First line");
   The task / endtask and function / endfunction   $display("Second line");
    keywords are enough to define the routine       endtask : multiple_lines
    boundaries.
   The task / endtask and function / endfunction
    keywords are enough to define the routine
    boundaries.
    ROUTINE ARGUMENTS
    a) C-style Routine Arguments
Example 3-6 Verilog-1995 routine arguments
task mytask2;
output [31:0] x;
reg [31:0] x;
input y;
                                             Example 3-7 C-style routine arguments
...
                                             task mytask1 (output logic [31:0] x,
Endtask
                                             input logic y);
                                             ...
                                             Endtask
  ROUTINE ARGUMENTS
b) Argument Direction
Example 3-8 Verbose Verilog-style routine arguments
task T3;
input a, b;
logic a, b;
output [15:0] u, v;
                                             Example 3-9 Routine arguments with sticky
bit [15:0] u, v;
                                             types
...
Endtask
                                             task T3(a, b, output bit [15:0] u, v);
                                                 Example 3-11 Using    ref across threads
      ROUTINE ARGUMENTS                           
                                                 task bus_read(input logic [31:0] addr,
                                                 ref logic [31:0] data);
c) Advanced Argument Types                       // Request bus and drive address
  Example 3-10 Passing arrays using ref          bus.request = 1’b1;
                                                 @(posedge bus.grant) bus.addr = addr;
  and const
                                                 // Wait for data from memory   
                                                 @(posedge bus.enable) data = bus.data;
  function void print_sum (const ref int a[]);
                                                 // Release bus and wait for grant
  int sum = 0;                                   bus.request = 1’b0;
  for (int i=0; i<a.size; i++) begin             @(negedge bus.grant);
  sum += a[i];                                   endtask
  $display("The sum of the arrays is ", sum);    logic [31:0] addr, data;
  Endfunction                                    initial
                                                 fork
                                                 bus_read(addr, data);
                                                 begin
                                                 @data; // Trigger on data change
                                                 $display("Read %h from bus", data);
                                                 end
                                                 join
  ROUTINE ARGUMENTS           Example 3-12 Function with default
                              argument values                               
d). Default Argument Values   function void print_sum (ref int a[],
                              input int start = 0,
                              input int end = -1);
                              int sum = 0, last;
                              if (last == -1 || last > a.size)
                              last = a.size;
                              for (int i=start; i<last; i++) begin
                              sum += a[i];
                              $display("The sum of the arrays is ", sum);
                              Endtask
ROUTINE ARGUMENTS
d). Default Argument Values
              Example 3-13 Using default argument values
                             print_sum(a); // Sum a[0:size-1] – default
              print_sum(a, 2, 5); // Sum a[2:5]
              print_sum(a, 1); // Start at 1
              print_sum(a,, 3); // Sum a[0:3]
              print_sum(); // error: a has no default
ROUTINE ARGUMENTS
e. Common Coding Errors
Example 3-14 Original task header
task sticky(int a, b);
                Example 3-15 Task header with additional array
                argument
                task sticky(ref int array[50],
                int a, b); // What direction are these?
                                          Example 3-16 Task header with additional array
                                          argument
                                          task sticky(ref int array[50],
                                          input int a, b); // Be explicit
    ROUTINE ARGUMENTS
                              Example 3-17 Return in a task
                              task load_array(int len, ref int array[]);
f. Returning from a Routine   if (len <= 0) begin
                              $display("Bad len");
                              return;
                              end
                              // Code for the rest of the task
                              ...
                              Endtask
                                A return statement        can simplify your functions.
                               Example 3-18 Return in a function
                              function bit transmit(...);
                              // Send transaction
                              ...
                              return ~ifc.cb.error; // Return status: 0=error
                              endfunction
LOCAL DATA STORAGE
• When Verilog was created in the 1980s, its primary goal
  was describing hardware. Because of this, all objects in the
  language were statically allocated.
• In particular, routine arguments and local variables were
  stored in a fixed location, rather than pushing them on a
  stack like other programming languages.
    LOCAL DATA STORAGE
                                                   Specifying automatic storage in program blocks
1.Automatic storage
                                                   program automatic test;
• In Verilog-1995, if you tried to call a task
                                                   task wait_for_mem(input [31:0] addr,
   from multiple places in your testbench, the
   local variables shared common, static           expect_data,
   storage, and so the different threads stepped   output success);
   on each other’s values.                         while (bus.addr !== addr)
                                                   @(bus.addr);
•   In Verilog-2001 you can specify that tasks,    success = (bus.data == expect_data);
    functions, and modules use automatic
                                                   endtask
    storage, which causes the simulator to use
                                                   ...
    the stack for local variables.
                                                   Endprogram
     LOCAL DATA STORAGE
2. Variable initialization
                                 Static initialization bug
                                 program initialization; // Buggy version
A similar problem occurs         task check_bus;
when you try to initialize a     repeat (5) @(posedge clock);
local     variable     in    a   if (bus_cmd == ‘READ) begin
declaration, as it is actually   // When is local_addr initialized?
initialized at the start of      reg [7:0] local_addr = addr<<2; // Bug
simulation.                      $display("Local Addr = %h", local_addr);
                                 end
                                 endtask
                                 endprogram
                                   Example 3-22 Time literals and $timeformat
    TIME VALUES
                                   module timing;
                                   timeunit 1ns;
•   SystemVerilog has several      timeprecision 1ps;
    new constructs to allow you    initial begin
    to unambiguously specify
    time values in your system.    $timeformat(-9, 3, "ns", 8);
                                   #1 $display("@%t", $realtime); // @1.000ns
Time units and precision
• When you rely on the
                                   #2ns $display("@%t", $realtime); // @3.000ns
   ‘timescale          compiler    #0.1ns $display("@%t", $realtime); //
   directive, you must compile     @3.100ns
   the files in the proper order   #41ps $display("@%t, $realtime); // @3.141ns
   to be sure all the delays use
                                   end
   the proper scale and
   precision.                      endmodule
    LOCAL DATA STORAGE                     Example 3-22 Time literals and $timeformat
                                           module timing;
                                           timeunit 1ns;
Time literals
                                           timeprecision 1ps;
   SystemVerilog      allows   you   to   initial begin
    unambiguously specify a time value     $timeformat(-9, 3, "ns", 8);
    plus units. Your code can use delays   #1 $display("@%t", $realtime); // @1.000ns
    such as 0.1ns or 20ps. Just remember
    to use timeunit and timeprecision or   #2ns $display("@%t", $realtime); // @3.000ns
    ‘timescale. You can make your code     #0.1ns $display("@%t", $realtime); //
    even more time aware by using the      @3.100ns
    classic Verilog $timeformat and        #41ps $display("@%t, $realtime); // @3.141ns
    $realtime routines
                                           end
                                           endmodule