[dv, sw_logger_if] Improve tool compability

The following enhancements are made:
- Introduce `arg_t` as a combined packed array to display args with all
format specifiers, including integral and string types
- Add MAX_ARGS param to make implementation a bit more robust
- Simplify how string arg indices are indicated - use a simple bit
vector instead of associative array
- Move macro defs closer to where they are used

The side effect of the first bullet is at runtime, there is no need to
know if the arg is a string or of integral type. The conditional
argument to `$sformatf` worked with VCS but not with other tools. The
simplification now works for all tools.

Signed-off-by: Srikrishna Iyer <sriyer@google.com>
diff --git a/hw/dv/sv/sw_logger_if/sw_logger_if.sv b/hw/dv/sv/sw_logger_if/sw_logger_if.sv
index 2e3b374..647b4e2 100644
--- a/hw/dv/sv/sw_logger_if/sw_logger_if.sv
+++ b/hw/dv/sv/sw_logger_if/sw_logger_if.sv
@@ -2,42 +2,6 @@
 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
 // SPDX-License-Identifier: Apache-2.0
 
-// shortcuts for use in switching # of args to insert in formatted string
-`define _USE_STR_ARG(n) (sw_log.str_arg.exists(``n``) ? sw_log.str_arg[``n``] : sw_log.arg[``n``])
-`define _1_ARGS         `_USE_STR_ARG(0)
-`define _2_ARGS         `_1_ARGS, `_USE_STR_ARG(1)
-`define _3_ARGS         `_2_ARGS, `_USE_STR_ARG(2)
-`define _4_ARGS         `_3_ARGS, `_USE_STR_ARG(3)
-`define _5_ARGS         `_4_ARGS, `_USE_STR_ARG(4)
-`define _6_ARGS         `_5_ARGS, `_USE_STR_ARG(5)
-`define _7_ARGS         `_6_ARGS, `_USE_STR_ARG(6)
-`define _8_ARGS         `_7_ARGS, `_USE_STR_ARG(7)
-`define _9_ARGS         `_8_ARGS, `_USE_STR_ARG(8)
-`define _10_ARGS        `_9_ARGS, `_USE_STR_ARG(9)
-`define _11_ARGS        `_10_ARGS, `_USE_STR_ARG(10)
-`define _12_ARGS        `_11_ARGS, `_USE_STR_ARG(11)
-`define _13_ARGS        `_12_ARGS, `_USE_STR_ARG(12)
-`define _14_ARGS        `_13_ARGS, `_USE_STR_ARG(13)
-`define _15_ARGS        `_14_ARGS, `_USE_STR_ARG(14)
-`define _16_ARGS        `_15_ARGS, `_USE_STR_ARG(15)
-`define _17_ARGS        `_16_ARGS, `_USE_STR_ARG(16)
-`define _18_ARGS        `_17_ARGS, `_USE_STR_ARG(17)
-`define _19_ARGS        `_18_ARGS, `_USE_STR_ARG(18)
-`define _20_ARGS        `_19_ARGS, `_USE_STR_ARG(19)
-`define _21_ARGS        `_20_ARGS, `_USE_STR_ARG(20)
-`define _22_ARGS        `_21_ARGS, `_USE_STR_ARG(21)
-`define _23_ARGS        `_22_ARGS, `_USE_STR_ARG(22)
-`define _24_ARGS        `_23_ARGS, `_USE_STR_ARG(23)
-`define _25_ARGS        `_24_ARGS, `_USE_STR_ARG(24)
-`define _26_ARGS        `_25_ARGS, `_USE_STR_ARG(25)
-`define _27_ARGS        `_26_ARGS, `_USE_STR_ARG(26)
-`define _28_ARGS        `_27_ARGS, `_USE_STR_ARG(27)
-`define _29_ARGS        `_28_ARGS, `_USE_STR_ARG(28)
-`define _30_ARGS        `_29_ARGS, `_USE_STR_ARG(29)
-`define _31_ARGS        `_30_ARGS, `_USE_STR_ARG(30)
-`define _32_ARGS        `_31_ARGS, `_USE_STR_ARG(31)
-`define _ADD_ARGS(n)    `_``n``_ARGS
-
 interface sw_logger_if #(
   // width of the data bus
   parameter int unsigned AddrDataWidth = 32
@@ -64,11 +28,11 @@
   logic data_valid;
   assign data_valid = wr_valid && (addr == sw_log_addr);
 
-  // Enable signal to turn on/off logging at runtime.
+  // Enable signal to turn the logging on/off at runtime.
   bit enable = 1'b1;
 
   // types
-  // log & rodata database files for parsing, associated with the sw_name
+  // Log & rodata database files for parsing, associated with the sw_name.
   string sw_log_db_files[string];
   string sw_rodata_db_files[string];
 
@@ -91,17 +55,23 @@
     LogVerbosityDebug
   } log_verbosity_e;
 
-  // struct to hold the complete log data
+  // Max number of args as format specifiers supported.
+  localparam int unsigned MAX_ARGS = 32;
+
+  // Use 1024 byte packed array for storing args (integral data or string).
+  typedef bit [1024*8-1:0] arg_t;
+
+  // Holds the log data structure.
   typedef struct {
-    string          name;         // Name of the SW image.
-    log_severity_e  severity;
-    log_verbosity_e verbosity;
-    string          file;         // Name of the C file invoking the log.
-    int             line;         // Line no in the C file from where the log originated.
-    int             nargs;        // Number of args provided to the format string.
-    addr_data_t     arg[];        // actual arg values
-    string          str_arg[int]; // some args are strings - this AA holds it
-    string          format;       // formatted string
+    string             name;         // Name of the SW image.
+    log_severity_e     severity;     // There are 4 - info, warining, error and fatal.
+    log_verbosity_e    verbosity;    // Verbosity of info logs - currently unsupported.
+    string             file;         // Name of the C file invoking the log.
+    int                line;         // Line no in the C file from where the log originated.
+    int                nargs;        // Number of args provided to the format string.
+    arg_t              arg[];        // Actual arg values
+    bit [MAX_ARGS-1:0] str_arg_idx;  // Indicates which arg indices are string (%s).
+    string             format;       // Format string.
   } sw_log_t;
 
   // bit to enable writing the logs to a separate file (disabled by default)
@@ -202,19 +172,12 @@
         sw_log.line = field.atoi();
         void'(get_sw_log_field(fd, "nargs", field));
         sw_log.nargs = field.atoi();
+        `DV_CHECK_LE_FATAL(sw_log.nargs, MAX_ARGS, , $sformatf("%m"))
         sw_log.arg = new[sw_log.nargs];
         void'(get_sw_log_field(fd, "format", field));
-        // Replace CRs in the middle of the string with NLs.
         sw_log.format = replace_cr_with_nl(field);
         void'(get_sw_log_field(fd, "str_arg_idx", field));
-
-        begin
-          int indices[$];
-          get_str_arg_indices(field, indices);
-          foreach (indices[i]) begin
-            sw_log.str_arg[indices[i]] = "";
-          end
-        end
+        sw_log.str_arg_idx = get_str_arg_indices(field);
 
         if (sw_logs.exists(sw) && sw_logs[sw].exists(addr)) begin
           `dv_warning($sformatf("Log entry for addr %0x already exists:\nOld: %p\nNew: %p",
@@ -300,13 +263,14 @@
     return 1'b0;
   endfunction
 
-  // Parse list if indices that have string args (in string format as space separated values
-  // and return a queue of corresponding integers.
-  function automatic void get_str_arg_indices(string list, ref int indices[$]);
+  // Parse list of indices that have string args (in string format as space separated values.
+  //
+  // Returns a 33-bit vector indicting the bit indices which contain string args.
+  function automatic bit [MAX_ARGS-1:0] get_str_arg_indices(string list);
     int i;
     int start = 0;
-    indices.delete();
-    if (list == "") return;
+    bit [MAX_ARGS-1:0] indices;
+    if (list == "") return indices;
     for (i = 0; i < list.len(); i++) begin
       if (list.getc(i) == " " && i == start) begin
         start++;
@@ -314,14 +278,15 @@
       end
       else if (list.getc(i) == " ") begin
         string index = list.substr(start, i - 1);
-        indices.push_back(index.atoi());
+        indices[index.atoi()] = 1'b1;
         start = i + 1;
       end
     end
     if (start < i) begin
       string index = list.substr(start, i - 1);
-      indices.push_back(index.atoi());
+      indices[index.atoi()] = 1'b1;
     end
+    return indices;
   endfunction
 
   // replace carriage return in the middle of the string with newline.
@@ -384,18 +349,20 @@
         if (sw_logs[sw].exists(addr)) begin
           bit rst_occurred;
           fork
-            begin
+            begin: isolation_thread
               fork
                 // get args
                 for (int i = 0; i < sw_logs[sw][addr].nargs; i++) begin
+                  addr_data_t addr_data;
                   wait(addr_data_q.size() > 0);
-                  sw_logs[sw][addr].arg[i] = addr_data_q.pop_front();
-                  // Check if this is an str arg
-                  if (sw_logs[sw][addr].str_arg.exists(i)) begin
-                    // The arg[i] received is the addr in rodata where the string resides.
-                    sw_logs[sw][addr].str_arg[i] = get_str_at_addr(sw, sw_logs[sw][addr].arg[i]);
-                    `dv_info($sformatf("String arg at addr %0h: %0s", sw_logs[sw][addr].arg[i],
-                                       sw_logs[sw][addr].str_arg[i]), UVM_DEBUG)
+                  addr_data = addr_data_q.pop_front();
+                  if (sw_logs[sw][addr].str_arg_idx[i]) begin
+                    // addr_data is the address of the string in rodata. Retrieve it.
+                    sw_logs[sw][addr].arg[i] = arg_t'(get_str_at_addr(sw, addr_data));
+                    `dv_info($sformatf("String arg at addr %0h: %0s", addr_data,
+                                       sw_logs[sw][addr].arg[i]), UVM_LOW)
+                  end else begin
+                    sw_logs[sw][addr].arg[i] = addr_data;
                   end
                 end
                 begin
@@ -405,7 +372,7 @@
                 end
               join_any
               disable fork;
-            end
+            end: isolation_thread
           join
           if (rst_occurred) continue;
           print_sw_log(sw_logs[sw][addr]);
@@ -423,6 +390,42 @@
                     $sformatf("%0d", sw_log.line), ")"};
     end
 
+    // Shortcuts for use in switching # of args to insert in formatted string.
+    `define _USE_STR_ARG(n) sw_log.arg[``n``]
+    `define _1_ARGS         `_USE_STR_ARG(0)
+    `define _2_ARGS         `_1_ARGS, `_USE_STR_ARG(1)
+    `define _3_ARGS         `_2_ARGS, `_USE_STR_ARG(2)
+    `define _4_ARGS         `_3_ARGS, `_USE_STR_ARG(3)
+    `define _5_ARGS         `_4_ARGS, `_USE_STR_ARG(4)
+    `define _6_ARGS         `_5_ARGS, `_USE_STR_ARG(5)
+    `define _7_ARGS         `_6_ARGS, `_USE_STR_ARG(6)
+    `define _8_ARGS         `_7_ARGS, `_USE_STR_ARG(7)
+    `define _9_ARGS         `_8_ARGS, `_USE_STR_ARG(8)
+    `define _10_ARGS        `_9_ARGS, `_USE_STR_ARG(9)
+    `define _11_ARGS        `_10_ARGS, `_USE_STR_ARG(10)
+    `define _12_ARGS        `_11_ARGS, `_USE_STR_ARG(11)
+    `define _13_ARGS        `_12_ARGS, `_USE_STR_ARG(12)
+    `define _14_ARGS        `_13_ARGS, `_USE_STR_ARG(13)
+    `define _15_ARGS        `_14_ARGS, `_USE_STR_ARG(14)
+    `define _16_ARGS        `_15_ARGS, `_USE_STR_ARG(15)
+    `define _17_ARGS        `_16_ARGS, `_USE_STR_ARG(16)
+    `define _18_ARGS        `_17_ARGS, `_USE_STR_ARG(17)
+    `define _19_ARGS        `_18_ARGS, `_USE_STR_ARG(18)
+    `define _20_ARGS        `_19_ARGS, `_USE_STR_ARG(19)
+    `define _21_ARGS        `_20_ARGS, `_USE_STR_ARG(20)
+    `define _22_ARGS        `_21_ARGS, `_USE_STR_ARG(21)
+    `define _23_ARGS        `_22_ARGS, `_USE_STR_ARG(22)
+    `define _24_ARGS        `_23_ARGS, `_USE_STR_ARG(23)
+    `define _25_ARGS        `_24_ARGS, `_USE_STR_ARG(24)
+    `define _26_ARGS        `_25_ARGS, `_USE_STR_ARG(25)
+    `define _27_ARGS        `_26_ARGS, `_USE_STR_ARG(26)
+    `define _28_ARGS        `_27_ARGS, `_USE_STR_ARG(27)
+    `define _29_ARGS        `_28_ARGS, `_USE_STR_ARG(28)
+    `define _30_ARGS        `_29_ARGS, `_USE_STR_ARG(29)
+    `define _31_ARGS        `_30_ARGS, `_USE_STR_ARG(30)
+    `define _32_ARGS        `_31_ARGS, `_USE_STR_ARG(31)
+    `define _ADD_ARGS(n)    `_``n``_ARGS
+
     // construct formatted string based on args
     case (sw_log.nargs)
        0: ;
@@ -461,6 +464,41 @@
       default: `dv_fatal($sformatf("UNSUPPORTED: nargs = %0d (only 0:32 allowed)", sw_log.nargs))
     endcase
 
+    `undef _USE_STR_ARG
+    `undef _1_ARGS
+    `undef _2_ARGS
+    `undef _3_ARGS
+    `undef _4_ARGS
+    `undef _5_ARGS
+    `undef _6_ARGS
+    `undef _7_ARGS
+    `undef _8_ARGS
+    `undef _9_ARGS
+    `undef _10_ARGS
+    `undef _11_ARGS
+    `undef _12_ARGS
+    `undef _13_ARGS
+    `undef _14_ARGS
+    `undef _15_ARGS
+    `undef _16_ARGS
+    `undef _17_ARGS
+    `undef _18_ARGS
+    `undef _19_ARGS
+    `undef _20_ARGS
+    `undef _21_ARGS
+    `undef _22_ARGS
+    `undef _23_ARGS
+    `undef _24_ARGS
+    `undef _25_ARGS
+    `undef _26_ARGS
+    `undef _27_ARGS
+    `undef _28_ARGS
+    `undef _29_ARGS
+    `undef _30_ARGS
+    `undef _31_ARGS
+    `undef _32_ARGS
+    `undef _ADD_ARGS
+
     begin
 `ifdef UVM
       uvm_verbosity level;
@@ -493,39 +531,3 @@
   endfunction
 
 endinterface
-
-// undefine previously defined macros
-`undef _USE_STR_ARG
-`undef _1_ARGS
-`undef _2_ARGS
-`undef _3_ARGS
-`undef _4_ARGS
-`undef _5_ARGS
-`undef _6_ARGS
-`undef _7_ARGS
-`undef _8_ARGS
-`undef _9_ARGS
-`undef _10_ARGS
-`undef _11_ARGS
-`undef _12_ARGS
-`undef _13_ARGS
-`undef _14_ARGS
-`undef _15_ARGS
-`undef _16_ARGS
-`undef _17_ARGS
-`undef _18_ARGS
-`undef _19_ARGS
-`undef _20_ARGS
-`undef _21_ARGS
-`undef _22_ARGS
-`undef _23_ARGS
-`undef _24_ARGS
-`undef _25_ARGS
-`undef _26_ARGS
-`undef _27_ARGS
-`undef _28_ARGS
-`undef _29_ARGS
-`undef _30_ARGS
-`undef _31_ARGS
-`undef _32_ARGS
-`undef _ADD_ARGS