SystemVerilog: Tips And Tricks When Working With Queues

SystemVerilog: Tips And Tricks When Working With Queues

Posted by

In this post I put together a few tips and tricks I’ve came across over the years related to SystemVerilog queues.

Access the last element of a queue

For a long time I was accessing the last element in a queue the “normal” way – using the computed index of that last element:

1
my_value = my_queue[my_queue[my_queue.size() - 1]]

However I just recently learned that I can use this very short syntax to get the last element of a queue:
1
my_value = my_queue[$]

You can even do some arithmetic operation with that $ symbol to get for example the second to last element:
1
my_value = my_queue[$ - 1]

Try it yourself in this EDA Playground example.

Sorting a queue

When I had to sort some queue the first option in my head was to implement some simple algorithm like Bubble Sort.
However, SystemVerilog queue comes with a useful and flexible function called sort().
For example if you want to sort a queue of integers in ascending order then you simply call the function sort(). For reverse sorting there is a similar function called rsort():

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int my_queue[$] = {3, 5, 4};

//sort from high to low
my_queue.rsort();

foreach(my_queue[idx]) begin
   $display("my_queue[%0d]: %0d", idx, my_queue[idx]);
end

//sort from low to high
my_queue.sort();
foreach(my_queue[idx]) begin
   $display("my_queue[%0d]: %0d", idx, my_queue[idx]);
end

Which produces the output:

1
2
3
4
5
6
my_queue[0]: 5
my_queue[1]: 4
my_queue[2]: 3
my_queue[0]: 3
my_queue[1]: 4
my_queue[2]: 5

But the big flexibility of these rsort() and sort() functions is in their “with” clause and this is best emphasize when we have to sort a queue of objects based on some field from the object’s class.
Let’s consider a simple class containg some basic information about a player:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class player;

   string name;

   int score;

   function new(string name, int score);
      this.name = name;
      this.score = score;
   endfunction

   static function player get_instance(string name, int score);
      get_instance = new(name, score);
   endfunction

   function string convert2string();
      return $sformatf("name: %0s, score: %0d", name, score);
   endfunction

endclass

Sorting a queue of players by score can be done using just one simple line of code:

1
2
3
4
5
6
7
8
9
10
11
player players[$];

players.push_back(player::get_instance(.name("Blondie"), .score(3)));
players.push_back(player::get_instance(.name("Blacky"), .score(5)));
players.push_back(player::get_instance(.name("Browny"), .score(4)));

players.sort(p) with (p.score);

foreach(players[idx]) begin
   $display("players[%0d]: %0s", idx, players[idx].convert2string());
end

The output is this:

1
2
3
players[0]: name: Blondie, score: 3
players[1]: name: Browny, score: 4
players[2]: name: Blacky, score: 5

You can try the example yourself on EDA Playground.

Searching a queue

An other extremely useful feature of the queues is their search capability.
The queues have some build-in functions which makes searching very easy and all of them have this with clause.
As in the previous example, we have a queue of players, but this time let’s make the list of players a little bit larger:

1
2
3
4
5
6
7
player players[$];

players.push_back(player::get_instance(.name("Blondie"), .score(3)));
players.push_back(player::get_instance(.name("Blacky"), .score(5)));
players.push_back(player::get_instance(.name("Pinky"), .score(6)));
players.push_back(player::get_instance(.name("Browny"), .score(5)));
players.push_back(player::get_instance(.name("Blue"), .score(9)));

Searching all the players which score equal to 5 is just one line of code:

1
2
3
4
5
6
7
8
player search_results[$];

search_results = players.find(p) with (p.score == 5);

foreach(search_results[idx]) begin
   $display("search_results[%0d]: %0s", idx,
      search_results[idx].convert2string());
end

The result is this:

1
2
search_results[0]: name: Blacky, score: 5
search_results[1]: name: Browny, score: 5

There are other similar functions very useful for searching, and all have this very useful with clause:

  • find() – returns all the elements satisfying the given expression
  • find_index() – returns the indexes of all the elements satisfying the given expression
  • find_first() – returns the first element satisfying the given expression
  • find_first_index() – returns the index of the first element satisfying the given expression
  • find_last() – returns the last element satisfying the given expression
  • find_last_index() – returns the index of the last element satisfying the given expression

You can try this example in EDA Playground.

That’s it!
If you have other tips that you want to share feel free to add them in a comment below.

Summary
SystemVerilog: Tips And Tricks When Working With Queues
Article Name
SystemVerilog: Tips And Tricks When Working With Queues
Description
Find out how you can more easily search, sort and access queues in SystemVerilog. Each of these can be accomplished in just one line of SystemVerilog code.
Author
Publisher Name
cfs-vision.com
Publisher Logo

Cristian Slav

4 Comments

  • rgarciaf071@gmail.com' rgarciaf071 says:

    HI Cristian,

    Nice and concise article as always I’d add the (in)famous sum() method along with the “with” clause for example

    int x[$] = ‘{1,4,17,3,10,55,50,10,3};
    int z;

    z=x.sum();
    $display(“sum()=%0d”,z);
    //you get 192 as result

    z=numbers.sum(it) with (it>6);
    $display(“sum with (it>6)=%0d”, z);
    //you get 0 as result

    Depending on what you want you need to do some changes

    a- Counting of then number of elements greater than 6 (note the cast to int is required to force the result as the it>6 returns a 1-bit result)

    z=x.sum() with (int'(it>6));
    $display(“Count the number of elements that are > 6 =%0d”, z);

    b- Sum of elements whose values are greater than 6

    z=x.sum() with (it>6?it:0);
    $display(“Sum the elements that are > 6 = %0d”, z);

  • gprathyusha74@gmail.come' prathyusha says:

    Hi Cristian Slav,
    I’m so happy for this article because I gained something from it.
    players.sort(p) with (p.score);
    In the above mentioned statement, ‘p’ indicates the handle for the queue of objects which are all the types of class player.
    Please let me know if i’m wrong and please give me some description on this.
    Thanks & Regards,
    Prathyusha

  • gprathyusha74@gmail.com' prathyusha says:

    Hi Cristian Slav,
    Could you please give me some description for this “players.sort(p) with (p.score)”.
    I understood in this way, where ‘p’ is the handle for the queue of objects(players) which are all are type of class player.
    Please let me know if i’m wrong.

    Thanks & Regards,
    Prathyusha Gadanchi

Leave a Reply

Your email address will not be published.