Sorting Queues by its type's members

I couldn’t find a way to sort a queue by it’s type members for awhile now. This is what I’m trying to do:


typedef struct {
  [63:0] bit start_addr;
  [63:0] bit size;
} mem_block_t;
...
// Lets say this queue contains 3 values:
// start_addr = 1000, size = 200
// start_addr = 200,  size = 300
// start_addr = 500,  size = 100
mem_block_t mem_block[$]; 

// Some magical queue.sort by start_addr...
// ending queue:
// start_addr = 200,  size = 300
// start_addr = 500,  size = 100
// start_addr = 1000, size = 200


Is there a way to easily do this without writing my own explicit sorting algorithm?

[EDIT1] I have written my explicit sorting algorithm for now, it isn’t actually that hard, but it would be nice if there was some kind of a short cut… Something like,

 mem_block.sort with start_addr

In reply to jimmyhuang0904:

The approach is correct. One can use “with” clause to sort for individual structure elements. A sample from IEEE 1800-2017 Section 7.12 is given as below.

struct { byte red, green, blue; } c [512];
c.sort with ( item.red ); // sort c using the red field only
c.sort( x ) with ( {x.blue, x.green} ); // sort by blue then green

Using the same above strategy, the following code should sort by start_addr:

module top();
  typedef struct  {
    bit [63:0] start_addr;
    bit [63:0] sizee;
} mem_block_t;
//...
// Lets say this queue contains 3 values:
// start_addr = 1000, size = 200
// start_addr = 200,  size = 300
// start_addr = 500,  size = 100
  mem_block_t mem_block[$]; 
 
// Some magical queue.sort by start_addr...
// ending queue:
// start_addr = 200,  size = 300
// start_addr = 500,  size = 100
// start_addr = 1000, size = 200
  initial begin
    
    mem_block.push_back('{700,200});    
    mem_block.push_back('{1000,800});    
    mem_block.push_back('{500,300});
    
    mem_block.sort(item) with (item.start_addr);
    //mem_block.sort(item) with (item.sizee); // one can sort by size also
    
    foreach(mem_block[i]) begin
      $write("mem_block[%0d].start_addr = %0d",i,mem_block[i].start_addr);
      $write("mem_block[%0d].sizee = %0d",i,mem_block[i].sizee);
      $display();
    end
  end
endmodule
// output:
mem_block[0].start_addr = 500mem_block[0].sizee = 300 
mem_block[1].start_addr = 700mem_block[1].sizee = 200 
mem_block[2].start_addr = 1000mem_block[2].sizee = 800 


In reply to sharvil111:

Wow That is exactly what I wanted!! I didn’t realize I need the item keyword (saw some examples without it).

Thanks! Replaced like 10 lines of ugly code with 1 elegant one