Use of regular expression for string comparison

How to compare string with regular expression using SV/UVM constructs? I tried to use uvm_re_match(re, string) function but it did not work. Below code snippet always gives mismatch without uvm_glob_to_re() and always matches with the method uncommented.

module top;

   import uvm_pkg::*;
   `include "uvm_macros.svh"

   string name = "C Trip";
   string re = "C T.*";

   initial
   begin
      automatic bit success;

      //re = uvm_glob_to_re(re);
      success = uvm_re_match(re, name);

      if(success)
         $display("Match Detected");
      else
         $display("Match not Detected");


      $display("End of Test");
      $finish;
   end

endmodule

In reply to MayurKubavat:

The value returned by uvm_re_match is an error code from regexec. So 0 is in fact successful.

In reply to dave_59:

In reply to MayurKubavat:
The value returned by uvm_re_match is an error code from regexec. So 0 is in fact successful.

Dave.
I have asked the same question. I am thinking it would be great if UVM can add one line of explanation on uvm_re_match(), instead of users have to look into the code or C code to figure it out. IMHO.

In reply to dave_59:

Awesome! That code actually worked. Thank you.

   initial
   begin
      automatic bit error_code;
 
      //re = uvm_glob_to_re(re);
      error_code = uvm_re_match(re, name);
 
      if(error_code == 0)
         $display("Match Detected");
      else
         $display("Match not Detected");

In reply to VE:

In reply to dave_59:
Dave.
I have asked the same question. I am thinking it would be great if UVM can add one line of explanation on uvm_re_match(), instead of users have to look into the code or C code to figure it out. IMHO.

Yes. That would be helpful. I also tried doing comparison as below, but its misleading.

      // Does not work
      if(uvm_re_match(re, name))
         $display("Match Detected");
 
      // Works
      if(!uvm_re_match(re, name))
         $display("Match Detected");

In reply to dave_59:

When using +define+UVM_NO_DPI compile option with uvm-1.2 source code. Above code still does not work.

I see there’s a Verilog version for uvm_re_match(string re, string str) function. I’ll try debug this later…

In reply to MayurKubavat:

Another undocumented feature is when you use +UVM_NO_DPI, umm_re_match uses Glob style matching instead of RE.

BTW, most tools have extended SystemVerilog with a built-in string.match() method. Check your tool’s user manual.

In reply to dave_59:

Hi Dave,
thanks for your answers,i have another question regarding regular expressions in systemverilog.
Is it possible to extract a group (%1,%2 …) from the regular expression to another string?
I mean if you have: “abc(de)fg” and you want just “de” using regular expressions in another string how would you do this?. (please assume that the regular expressions are needed because of a complex string)

I know that we have str.substr(startposition, endposition); to extract strings, maybe that can be done somehow with that function using a loop. “uvm_re_match(re, name);” does not provide you the index of the match which would be very helpful.
Looking forward your answer

In reply to JA:

Check your tool’s user manual for extensions to string methods.

In reply to dave_59:

Thanks Dave, i will look.

Another point that may somebody find useful is that we can use $system and file exchange to use LINUX regular expression and other LINUX commands. I know that is not a efficient way to work with strings, but if you need to do it only once at the beginning of your simulation it could be worth it.

For example, here some functions to extract information from LINUX, like the time of simulation, pwd and space left. The extraction of the interesting data is done with a combination of commands in LINUX and systemverilog.
e.g. “df -kh --output=avail .| grep -v Avail”

From that idea, then you could use “sed*/awk”, to work with the strings and regular expression.


static function string pve_get_systemtime(bit epoch = 0);
        int fd;
        string localtime;
        string cmd = "date";

        if(epoch)
            cmd = {cmd, " +%s"};

        void'($system({cmd, " > localtime.23025524522"})); // temp file
        fd = $fopen("localtime.23025524522", "r");
        void'($fgets (localtime, fd));

        if(localtime.substr(localtime.len()-1, localtime.len()-1) == "\n")
            localtime = localtime.substr(0, localtime.len()-2);

        $fclose(fd);
        void'($system("rm localtime.23025524522")); // delete file
        return localtime;
    endfunction


    static function string pve_get_systempwd();
        int fd;
        string pwd_str;
        string cmd = "pwd";

        void'($system({cmd, " > pwd.23025524522"})); // temp file
        fd = $fopen("pwd.23025524522", "r");
        void'($fgets (pwd_str, fd));


        if(pwd_str.substr(pwd_str.len()-1, pwd_str.len()-1) == "\n")
            pwd_str = pwd_str.substr(0, pwd_str.len()-2);

        $fclose(fd);
        void'($system("rm pwd.23025524522")); // delete file
        return pwd_str;
    endfunction

    static function string pve_get_systemfreespace(string on_current_path="");
        int fd;
        automatic int prevpos = 0;
        string freespace_str;
        string cmd = "df -kh --output=avail";

        cmd = {cmd, " ",on_current_path, " | grep -v Avail"};

        void'($system({cmd, " > availspace.23025524522"})); // temp file
        fd = $fopen("availspace.23025524522", "r");
        void'($fgets (freespace_str, fd));


        if(freespace_str.substr(freespace_str.len()-1, freespace_str.len()-1) == "\n")
            freespace_str = freespace_str.substr(0, freespace_str.len()-2);


        $fclose(fd);
        void'($system("rm availspace.23025524522")); // delete file
        return freespace_str;
    endfunction