image/svg+xml
  • Contents
      • Back
      • Digital Basics
      • Verilog
      • Verification
      • SystemVerilog
      • UVM
Most Popular
Verification
  Testbench Evolution
  Constraint Random Verification
  Verification Techniques
  Verification Plan
  Code Coverage

Verilog
  Data Types
  Basic Constructs
  Behavioral Modeling
  Gate Modeling
  Simulation Basics
  Design Examples

SystemVerilog
  Data Types
  Class
  Interface
  Constraints and more!
  Testbench Examples

UVM
  Sequences
  Testbench Components
  TLM Tutorial
  Register Model Tutorial
  Testbench Examples

Digital Fundamentals
  Binary Arithmetic
  Boolean Logic
  Karnaugh Maps
  Combinational Logic
  Sequential Logic




SystemVerilog Clocking Blocks Part II

Clocking blocks allow inputs to be sampled and outputs to be driven at a specified clock event. If an input skew is mentioned for a clocking block, then all input signals within that block will be sampled at skew time units before the clock event. If an output skew is mentioned for a clocking block, then all output signals in that block will be driven skew time units after the corresponding clock event.

Read more: SystemVerilog Clocking Blocks Part II

SystemVerilog fork join_any

In a simple SystemVerilog fork join, the main thread waits until all the child threads have finished execution. This means the fork will hang the simulation if any of the child threads run forever and never complete. SystemVerilog also provides a variation to the original with a fork and join_any.

A fork and join_any will allow the main thread to resume execution of further statements that lie after the fork, if any one of the child threads complete. If five threads are launched, the main thread will resume execution only when any one of the five threads finish execution. Once the main thread resumes operation, the remaining four threads that were launched will continue to run in the background.

Syntax


	fork
		// Thread 1
		// Thread 2
		// ...
		// Thread N
	join_any

fork join_any Example


module tb;
	initial begin
      $display ("[%0t] Main Thread: Fork join going to start", $time);
		fork
          print (20, "Thread1_0");
          print (30, "Thread1_1");
          print (10, "Thread2");              
        join_any
      $display ("[%0t] Main Thread: Fork join has finished", $time);
	end
  
  // Note that this task needs to be automatic
  task automatic print (int _time, string t_name);
    #(_time) $display ("[%0t] %s", $time, t_name);
  endtask
endmodule
 Simulation Log
ncsim> run
[0] Main Thread: Fork join going to start
[10] Thread2
[10] Main Thread: Fork join has finished
[20] Thread1_0
[30] Thread1_1
ncsim: *W,RNQUIE: Simulation is complete.

Nested fork join_any


module tb;
	initial begin
      $display ("[%0t] Main Thread: Fork join going to start", $time);
		fork
			fork
              print (20, "Thread1_0");
              print (30, "Thread1_1");
            join_any
          print (10, "Thread2");              
        join_any
      $display ("[%0t] Main Thread: Fork join has finished", $time);
	end
  
  // Note that this task has to be automatic
  task automatic print (int _time, string t_name);
    #(_time) $display ("[%0t] %s", $time, t_name);
  endtask
endmodule
 Simulation Log
ncsim> run
[0] Main Thread: Fork join going to start
[10] Thread2
[10] Main Thread: Fork join has finished
[20] Thread1_0
[30] Thread1_1
ncsim: *W,RNQUIE: Simulation is complete.
ncsim> exit

SystemVerilog foreach loop

SystemVerilog arrays are data structures that allow storage of many values in a single variable. A foreach loop is only used to iterate over such arrays and is the easiest and simplest way to do so.

Syntax

The foreach loop iterates through each index starting from 0. If there are multiple statements within the foreach loop, they have to be enclosed with begin and end keywords like all other procedural blocks.


	foreach(<variable>[<iterator>])
		// Single statement
		
	foreach(<variable>[<iterator>]) begin
		// Multiple statements
	end

Example #1: Single dimensional Arrays


module tb;
	int array[5] = '{1, 2, 3, 4, 5};
	int sum;
	
	initial begin
		// Here, "i" is the iterator and can be named as anything you like
		// Iterate through each element from index 0 to end using a foreach
		// loop.
		foreach (array[i])
			$display ("array[%0d] = %0d", i, array[i]);
		
		// Multiple statements in foreach loop requires begin end
		// Here, we are calculating the sum of all numbers in the array
		// And because there are 2 statements within foreach there should
		// be a begin-end
		foreach (array[l_index]) begin
			sum += array[l_index];
			$display ("array[%0d] = %0d, sum = %0d", l_index, array[l_index], sum);
		end
	end
endmodule
 Simulation Log
ncsim> run
array[0] = 1
array[1] = 2
array[2] = 3
array[3] = 4
array[4] = 5
array[0] = 1, sum = 1
array[1] = 2, sum = 3
array[2] = 3, sum = 6
array[3] = 4, sum = 10
array[4] = 5, sum = 15
ncsim: *W,RNQUIE: Simulation is complete.

Note that foreach is just a shorter version to the following for loop:


	for (int i = 0; i < $size(array); i++) begin
		// Statements inside the for loop
	end

Example #2: Multidimensional Arrays


module tb;
  int md_array [5][2] = '{'{1,2}, '{3,4}, '{5,6}, '{7,8}, '{9,10}};
	
	initial begin
      // First iterate through the first dimension using "i"
      foreach (md_array[i])
        // For each element in first dimension "i", iterate through the
        // second dimension using "j"
        foreach (md_array[i][j])
          $display("md_array[%0d][%0d] = %0d", i, j, md_array[i][j]);      
	end
endmodule
 Simulation Log
ncsim> run
md_array[0][0] = 1
md_array[0][1] = 2
md_array[1][0] = 3
md_array[1][1] = 4
md_array[2][0] = 5
md_array[2][1] = 6
md_array[3][0] = 7
md_array[3][1] = 8
md_array[4][0] = 9
md_array[4][1] = 10
ncsim: *W,RNQUIE: Simulation is complete.

Click here to learn more about other loops in SystemVerilog !

SystemVerilog for loop

A for loop in SystemVerilog repeats a given set of statements multiple times until the given expression is not satisfied. Like all other procedural blocks, the for loop requires multiple statements within it to be enclosed by begin and end keywords.

Syntax

For loop controls execution of its statements using a three step approach:

  1. Initialize the variables that affect how many times the loop is run
  2. Before executing the loop, check to see if the condition is true
  3. The modifier is executed at the end of each iteration, and jumps to step 2.


	for ( [initialization]; <condition>; [modifier])
		// Single statement
		
	for ( [initialization]; <condition>; [modifier]) begin
		// Multiple statements
	end

Example #1 - Array Iteration

In this example, we will iterate through a string array and print out its contents. The array array is initialized with 5 different names of fruits.

The for loop initialization declares a local variable called i that represents index of any element in the array. The conditional expression checks that i is less than size of the array. The modifier increments the value of i so that every iteration of the for loop operates on a different index.


module tb;
	string array [5] = '{"apple", "orange", "pear", "blueberry", "lemon"};
	
	initial begin
		for (int i = 0; i < $size(array); i++)
			$display ("array[%0d] = %s", i, array[i]);
	end
endmodule
 Simulation Log
ncsim> run
array[0] = apple
array[1] = orange
array[2] = pear
array[3] = blueberry
array[4] = lemon
ncsim: *W,RNQUIE: Simulation is complete.

Example #2 - Multiple Initializations

There can be multiple initializations done in the first part of a for loop. In the code shown below, variables i and j are both initialized as soon as the for loop is entered. To keep the example interesting, the index of each string pointed to by j is replaced by 0.


module tb;
	string array [5] = '{"apple", "orange", "pear", "blueberry", "lemon"};
	
	initial begin
      for (int i = 0, j = 2; i < $size(array); i++) begin
			array[i][j] = "0";
        $display ("array[%0d] = %s, %0dth index replaced by 0", i, array[i], j);
		end
	end
endmodule
 Simulation Log
ncsim> run
array[0] = ap0le, 2th index replaced by 0
array[1] = or0nge, 2th index replaced by 0
array[2] = pe0r, 2th index replaced by 0
array[3] = bl0eberry, 2th index replaced by 0
array[4] = le0on, 2th index replaced by 0
ncsim: *W,RNQUIE: Simulation is complete.

Example #3 - Adding multiple modifiers

In the code shown below, j is decremented after each iteration of the for loop along with incrementing i.


module tb;
	string array [5] = '{"apple", "orange", "pear", "blueberry", "lemon"};
	
	initial begin
      for (int i = 0, j = array[i].len() - 1; i <  $size(array); i++, j--) begin
			array[i][j] = "0";
        $display ("array[%0d] = %s, %0dth index replaced by 0", i, array[i], j);
		end
	end
endmodule
 Simulation Log
ncsim> run
array[0] = appl0, 4th index replaced by 0
array[1] = ora0ge, 3th index replaced by 0
array[2] = pe0r, 2th index replaced by 0
array[3] = b0ueberry, 1th index replaced by 0
array[4] = 0emon, 0th index replaced by 0
ncsim: *W,RNQUIE: Simulation is complete.

Verilog Testbench Simulation

Verilog is a hardware description language and there is no requirement for designers to simulate their RTL designs to be able to convert them into logic gates. So what is the need to simulate?

testbench-setup

Simulation is a technique of applying different input stimulus to the design at different times to check if the RTL code behaves the intended way. Essentially, simulation is a well-followed technique to verify the robustness of the design. It is also similar to how a fabricated chip will be used in the real world and how it reacts to different inputs.

For example, the design above represents a positive edge detector with inputs clock and signal which are evaluated at periodic intervals to find the output pe as shown. Simulation allows us to view the timing diagram of related signals to understand how the design description in Verilog actually behaves.

timing-diagram

There are several EDA companies that develop simulators capable of figuring out the outputs for various inputs to the design. Verilog is defined in terms of a discrete event execution model and different simulators are free to use different algorithms to provide the user with a consistent set of results. The Verilog code is divided into multiple processes and threads and may be evaluated at different times in the course of a simulation, which will be touched upon later.

Example

The testbench called tb is a container to hold a design module. However, in this example we have not used any design instances. There are two variables or signals that can be assigned certain values at specific times. clk represents a clock which is generated within the testbench. This is done by the always statement by alternating the clock's value after every 5ns. The initial block contains a set of statements that assign different values to both the signals at different times.


module tb;
  reg clk;
  reg sig;
 
  // Clock generation 
  // Process starts at time 0ns and loops after every 5ns
  always #5 clk = ~clk;   
 
  // Initial block : Process starts at time 0ns
  initial begin            
    // This system task will print out the signal values everytime they change
    $monitor("Time = %0t clk = %0d sig = %0d", $time, clk, sig);
    
    // Also called stimulus, we simply assign different values to the variables
    // after some simulation "delay"
    sig = 0;
    #5 clk = 0;        // Assign clk to 0 at time 5ns
    #15  sig = 1;      // Assign sig to 1 at time 20ns (#5 + #15)
    #20  sig = 0;      // Assign sig to 0 at time 40ns (#5 + #15 + #20)
    #15  sig = 1;      // Assign sig to 1 at time 55ns (#5 + #15 + #20 + #15)
    #10  sig = 0;      // Assign sig to 0 at time 65ns (#5 + #15 + #20 + #15 + #10)
    #20 $finish;       // Finish simulation at time 85ns
  end
endmodule

The simulator provides the following output after execution of the above testbench.

 Simulation Log
ncsim> run
Time = 0 clk = x sig = 0
Time = 5 clk = 0 sig = 0
Time = 10 clk = 1 sig = 0
Time = 15 clk = 0 sig = 0
Time = 20 clk = 1 sig = 1
Time = 25 clk = 0 sig = 1
Time = 30 clk = 1 sig = 1
Time = 35 clk = 0 sig = 1
Time = 40 clk = 1 sig = 0
Time = 45 clk = 0 sig = 0
Time = 50 clk = 1 sig = 0
Time = 55 clk = 0 sig = 1
Time = 60 clk = 1 sig = 1
Time = 65 clk = 0 sig = 0
Time = 70 clk = 1 sig = 0
Time = 75 clk = 0 sig = 0
Time = 80 clk = 1 sig = 0
Simulation complete via $finish(1) at time 85 NS + 0

Read more: Verilog Testbench Simulation

  1. Verilog Display Tasks
  2. Verilog syntax
  3. Verilog Blocking & Non-Blocking
  4. Design Abstraction Layers
  5. ASIC Design Flow

Page 25 of 63

  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
Interview Questions
  Verilog Interview Set 1
  Verilog Interview Set 2
  Verilog Interview Set 3
  Verilog Interview Set 4
  Verilog Interview Set 5

  SystemVerilog Interview Set 1
  SystemVerilog Interview Set 2
  SystemVerilog Interview Set 3
  SystemVerilog Interview Set 4
  SystemVerilog Interview Set 5

  UVM Interview Set 1
  UVM Interview Set 2
  UVM Interview Set 3
  UVM Interview Set 4
Related Topics
  Digital Fundamentals
  Verilog Tutorial

  Verification
  SystemVerilog Tutorial
  UVM Tutorial
  • Verilog Testbench
  • Verilog Coding Style Effect
  • Verilog Conditional Statements
  • Verilog Interview Set 10
  • Synchronous FIFO
  • SystemVerilog Interview Set 10
  • SystemVerilog Interview Set 9
  • SystemVerilog Interview Set 8
  • SystemVerilog Interview Set 7
  • SystemVerilog Interview Set 6
  • UVM Singleton Object
  • UVM Component [uvm_component]
  • UVM Object [uvm_object]
  • UVM Root [uvm_root]
  • UVM Interview Set 4
© 2015 - 2023 ChipVerify
Terms and Conditions | DMCA.com Protection Status