<commit_before>---
layout: post
author: shankar_arora
title: SystemVerilog Inline Constraint Gotcha
excerpt: ""
modified: 2014-11-10
tags: [systemverilog, constraints, randomize with, variable hiding]
comments: true
image:
  feature: #sample-image-5.jpg
  credit: #WeGraphics
  creditlink: #http://wegraphics.net/downloads/free-ultimate-blurred-background-pack/
---

SystemVerilog UVM sequence generates interesting scenerios by randomizing and constraining the data items of the sequence item class.  Generally, the constraints are specified in the sequence item class. But SystemVerilog allows you to add in-line contraints in the sequence body, by using `randomize() with` construct. These in-line constraints are applied in addition to the constraints specified in the sequence item class.

{% codeblock lang:systemverilog %}
// Sequence item class
class seq_item extends uvm_sequence_item;
  rand [31:0] addr;
  rand [31:0] data;
endclass

// Sequence class
class seq extends uvm_sequence#(seq_item);
  bit [31:0] addr;

  task body();
    seq_item trans;
    bit [31:0] addr = 32'h11001100;
    assert(trans.randomize()
      with { trans.addr == addr; });
  endtask
endclass
{% endcodeblock %}

Surprisingly! The above code generates address 'hbfdf5196' in my case.

The problem arises when you try to make `seq_item` address equal to the address in the calling sequence class using the above in-line constraint. The result is undesirable since the constraint will  actually cause the `seq_item` address (trans.addr) to be equal to itself. This gotcha in SystemVerilog arises because we have addr as a variable defined in both `seq_item` class as well as the `seq` class. SystemVerilog scoping rules pick the variable which is part of the object being randomized.

The SystemVerilog P1800-2012 LRM (see page 495) states that:

> Unqualified names in an unrestricted in-lined constraint block
> are then resolved by searching first in the scope of the
> randomize() with object class followed by a search of the
> scope containing the method call—the local scope.

In order to overcome the above problem we can prefix "local::" before the address of sequence class `seq`. Thus, we could modify the code as:

{% codeblock lang:systemverilog %}
// Sequence item class
class seq_item extends uvm_sequence_item;
  rand [31:0] addr;
  rand [31:0] data;
endclass

// Sequence class
class seq extends uvm_sequence#(seq_item);
  bit [31:0] addr;

  task body();
    seq_item trans;
    bit [31:0] addr = 32'h11001100;
    assert(trans.randomize()
      with { trans.addr == local::addr; });
  endtask
endclass
{% endcodeblock %}

The above code generates the following address:

```
 # Name     Type           Size     Value
 # trans    seq_item       -       @636
 # addr     integral       32      'h11001100

```

This statement makes sure that the constraint solver looks for the address following the local:: only in the local scope (i.e. the address in the sequence class "seq"). So, now the constraint will be the desired one which states that while randoming the address of `seq_item`, the constraint solver should make sure that the address of the seq_item should be equal to the address in the sequence `seq`.<commit_msg>fixed a couple of more issues with inline constraint gotcha post.<commit_after>---
layout: post
author: shankar_arora
title: SystemVerilog Inline Constraint Gotcha
excerpt: ""
modified: 2014-11-10
tags: [systemverilog, constraints, randomize with, variable hiding]
comments: true
image:
  feature: #sample-image-5.jpg
  credit: #WeGraphics
  creditlink: #http://wegraphics.net/downloads/free-ultimate-blurred-background-pack/
---

SystemVerilog UVM sequence generates interesting scenerios by randomizing and constraining the data items of the sequence item class.  Generally, the constraints are specified in the sequence item class. But SystemVerilog allows you to add in-line contraints in the sequence body, by using `randomize() with` construct. These in-line constraints are applied in addition to the constraints specified in the sequence item class.

{% codeblock lang:systemverilog %}
// Sequence item class
class seq_item extends uvm_sequence_item;
  rand [31:0] addr;
  rand [31:0] data;
endclass

// Sequence class
class seq extends uvm_sequence#(seq_item);
  bit [31:0] addr;

  task body();
    seq_item trans;
    bit [31:0] addr = 32'h11001100;
    assert(trans.randomize() with { trans.addr == addr; });
  endtask
endclass
{% endcodeblock %}

The above code generated a transaction with `addr` as `hbfdf5196`. What did the solver do with the inline `this.addr == addr` constraint?

The problem arises when you try to make `seq_item` address equal to the address in the calling sequence class using the above in-line constraint. The result is undesirable since the constraint will  actually cause the `seq_item` address (trans.addr) to be equal to itself. This gotcha in SystemVerilog arises because we have `addr` as a variable defined in both `seq_item` class as well as the `seq` class. SystemVerilog scoping rules pick the variable which is part of the object being randomized.

The SystemVerilog P1800-2012 LRM (see page 495) states that:

> Unqualified names in an unrestricted in-lined constraint block
> are then resolved by searching first in the scope of the
> randomize() with object class followed by a search of the
> scope containing the method call—the local scope.

In order to overcome the above problem we can prefix `local::` before the address of sequence class `seq`. Thus, we could modify the code as:

{% codeblock lang:systemverilog %}
// Sequence item class
class seq_item extends uvm_sequence_item;
  rand [31:0] addr;
  rand [31:0] data;
endclass

// Sequence class
class seq extends uvm_sequence#(seq_item);
  bit [31:0] addr;

  task body();
    seq_item trans;
    bit [31:0] addr = 32'h11001100;
    assert(trans.randomize()
      with { trans.addr == local::addr; });
  endtask
endclass
{% endcodeblock %}

The above code generates the following address:

```
 # Name     Type           Size     Value
 # trans    seq_item       -       @636
 # addr     integral       32      'h11001100

```

This statement makes sure that the constraint solver looks for the address following the local:: only in the local scope (i.e. the address in the sequence class `seq`). So, now the constraint will be the desired one which states that while randoming the address of `seq_item`, the constraint solver should make sure that the address of the seq_item should be equal to the address in the sequence `seq`.
{'fraction_non_alphanumeric': 0.0730260155180283, 'fraction_numerical': 0.02464628023733455, 'mean_word_length': 4.115953307392996, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '529439', 'n_tokens_mistral': 1952, 'n_tokens_neox': 1794, 'n_words': 852}