SystemVerilog Constraints for Pascal's Triangle: SystemVerilog Interview Questions

SystemVerilog Constraints to Generate Pascal's Triangle

Welcome back to VLSI 360, your trusted resource for VLSI design, verification, and SystemVerilog tutorials! Today, we’re exploring an exciting problem: generating Pascal's Triangle using SystemVerilog with dynamic arrays and constraints. This is an excellent exercise for mastering dynamic arrays, constraints, and randomization, commonly seen in VLSI verification interviews or academic projects. We’ll walk through the provided working code, explain its logic, and share tips to help you ace your interviews or coursework. Let’s dive in!


Question: Write SystemVerilog Constraints to Generate Pascal's Triangle

Pascal's Triangle is a triangular array of numbers where each number is the sum of the two numbers directly above it. Here’s how the first few rows look:

        1
      1   1
    1   2   1
  1   3   3   1
1   4   6   4   1
  • Row 0: [1]
  • Row 1: [1, 1]
  • Row 2: [1, 2, 1]
  • Row 3: [1, 3, 3, 1]
  • And so on...
Each row ( i ) has
i+1
elements. The first and last elements of each row are always 1, and other elements are computed as:
arr[i][j] = arr[i-1][j-1] + arr[i-1][j]
Our goal is to use SystemVerilog to generate Pascal’s Triangle for a specified number of rows (e.g., 10) using dynamic 2D arrays and constraints. The provided code is verified to work, so let’s analyze it.

SystemVerilog Constraints for Pascal's Triangle

Below is the working SystemVerilog code to generate Pascal’s Triangle using a class-based approach with dynamic arrays and constraints.

parameter ROWS = 10;

class sample;
  rand int arr[][];  // 2D dynamic array for Pascal's Triangle
  int N = ROWS;      // Number of rows

  constraint sizee_cons {
    arr.size() == N;  
    foreach (arr[i]) arr[i].size() == i + 1;
  }

  constraint pascal_values {
    foreach (arr[i, j]) {
      if (j == 0 || j == i)
        arr[i][j] == 1;
      else
        arr[i][j] == arr[i-1][j-1] + arr[i-1][j];
    }
  }

  function new(int N);
    arr = new[N];
    foreach (arr[i]) arr[i] = new[i+1];
  endfunction

endclass

module top;
  sample s;
  
  initial begin
    s = new(ROWS);
    assert (s.randomize());
    foreach (s.arr[i]) begin
      $display("%0p", s.arr[i]);
    end
  end
endmodule

How It Works
Let’s break down the code to understand how it generates Pascal’s Triangle.
  1. Class Definition (sample):
    • The sample class encapsulates the logic for generating the triangle.
    • Dynamic Array: arr is a 2D dynamic array (rand int arr[][]) to store the triangle. Each row arr[i] has i+1 elements.
    • Variable N: Stores the number of rows, set to the parameter ROWS (default 10).
  2. Size Constraint (sizee_cons):
    • arr.size() == N: Ensures the array has N rows.
    • foreach (arr[i]) arr[i].size() == i + 1: Ensures each row i has i+1 elements (e.g., row 0 has 1 element, row 1 has 2 elements, etc.).
  3. Value Constraint (pascal_values):
    • foreach (arr[i, j]): Iterates over each element arr[i][j].
    • if (j == 0 || j == i): Sets the first (j == 0) and last (j == i) elements of each row to 1.
    • else arr[i][j] == arr[i-1][j-1] + arr[i-1][j]: Computes other elements as the sum of the two elements above from the previous row.
  4. Constructor (new):
    • Initializes the array with N rows: arr = new[N].
    • Allocates each row i with i+1 elements: arr[i] = new[i+1].
  5. Top Module (top):
    • Creates an instance of the sample class with ROWS rows.
    • Calls randomize() to apply the constraints and populate the triangle.
    • Displays each row using $display.

Output
Running the code with ROWS = 10 produces the following output (rows may be printed without triangular formatting due to the simple $display):
{1}
{1, 1}
{1, 2, 1}
{1, 3, 3, 1}
{1, 4, 6, 4, 1}
{1, 5, 10, 10, 5, 1}
{1, 6, 15, 20, 15, 6, 1}
{1, 7, 21, 35, 35, 21, 7, 1}
{1, 8, 28, 56, 70, 56, 28, 8, 1}
{1, 9, 36, 84, 126, 126, 84, 36, 9, 1}
This represents Pascal’s Triangle with 10 rows, correctly computed using the constraints.

Enhancing the Display (Optional)
To make the output visually resemble a triangle, you can modify the display loop in the top module:

initial begin
  s = new(ROWS);
  assert (s.randomize());
  $display("============ Pascal's Triangle (%0d rows) =============", ROWS);
  foreach (s.arr[i]) begin
    repeat (ROWS - i) $write("  ");  // Add spaces for alignment
    $display("%0p", s.arr[i]);
  end
end
This produces a more visually appealing triangle:
============ Pascal's Triangle (10 rows) =============
                    {1}
                  {1, 1}
                {1, 2, 1}
              {1, 3, 3, 1}
            {1, 4, 6, 4, 1}
          {1, 5, 10, 10, 5, 1}
        {1, 6, 15, 20, 15, 6, 1}
      {1, 7, 21, 35, 35, 21, 7, 1}
    {1, 8, 28, 56, 70, 56, 28, 8, 1}
  {1, 9, 36, 84, 126, 126, 84, 36, 9, 1}

Tips for Interviews
This problem is popular in VLSI verification interviews because it tests:
  • Dynamic arrays and their sizing.
  • Constraints for randomization.
  • Class-based programming in SystemVerilog.
  • Mathematical pattern generation.
Potential follow-up questions include:
  • Can you generate the triangle using loops instead of constraints?
  • How would you verify the triangle’s correctness programmatically?
  • Can you extract a specific row or compute binomial coefficients?
  • How would you handle overflow for large rows (e.g., use longint)?
For verification, you could add a function to check the triangle:

function void check_triangle();
  foreach (arr[i, j]) begin
    if (j == 0 || j == i) begin
      assert(arr[i][j] == 1) else $error("Edge error at arr[%0d][%0d]", i, j);
    end else begin
      assert(arr[i][j] == arr[i-1][j-1] + arr[i-1][j]) else $error("Value error at arr[%0d][%0d]", i, j);
    end
  end
endfunction

Conclusion
Generating Pascal’s Triangle in SystemVerilog is a powerful way to practice dynamic arrays, constraints, and class-based programming. The provided code is verified to work and is ideal for VLSI verification interviews or academic projects. Experiment with it by changing the number of rows or adding visual formatting for a better display.
Keep following VLSI 360 for more SystemVerilog tutorials and VLSI insights! Drop a comment if you have questions or want another topic covered. Happy coding!

Post a Comment

0 Comments