[dv] Support WO, RO type for mem

Clean up failures in chip_mem_walk
1. Update reggen&topgen to support WO, RO type for mem
2. Update memory rom, eflash to RO
3. Override uvm_mem::configure to support WO type

Signed-off-by: Weicai Yang <weicai@google.com>
diff --git a/hw/dv/sv/dv_lib/dv_base_mem.sv b/hw/dv/sv/dv_lib/dv_base_mem.sv
index 5d4db40..09768e5 100644
--- a/hw/dv/sv/dv_lib/dv_base_mem.sv
+++ b/hw/dv/sv/dv_lib/dv_base_mem.sv
@@ -5,12 +5,46 @@
 // base register reg class which will be used to generate the reg mem
 class dv_base_mem extends uvm_mem;
 
+  // uvm_mem::m_access is local variable. Create it again in order to use "access" in current class
+  local string m_access;
+
   function new(string           name,
                longint unsigned size,
                int unsigned     n_bits,
                string           access = "RW",
                int              has_coverage = UVM_NO_COVERAGE);
     super.new(name, size, n_bits, access, has_coverage);
+    m_access = access;
   endfunction : new
 
+  // rewrite this function to support "WO" access type for mem
+  function void configure(uvm_reg_block  parent,
+                          string         hdl_path="");
+     if (parent == null)
+       `uvm_fatal("REG/NULL_PARENT","configure: parent argument is null")
+
+     set_parent(parent);
+
+     if (!(m_access inside {"RW", "RO", "WO"})) begin
+        `uvm_error("RegModel", {"Memory '",get_full_name(),"' can only be RW, RO or WO"})
+     end
+
+     begin
+        uvm_mem_mam_cfg cfg = new;
+
+        cfg.n_bytes      = ((get_n_bits() - 1) / 8) + 1;
+        cfg.start_offset = 0;
+        cfg.end_offset   = get_size() - 1;
+
+        cfg.mode     = uvm_mem_mam::GREEDY;
+        cfg.locality = uvm_mem_mam::BROAD;
+
+        mam = new(get_full_name(), cfg, this);
+     end
+
+     parent.add_mem(this);
+
+     if (hdl_path != "") add_hdl_path_slice(hdl_path, -1, -1);
+  endfunction: configure
+
 endclass
diff --git a/hw/top_earlgrey/data/top_earlgrey.hjson b/hw/top_earlgrey/data/top_earlgrey.hjson
index dc805f5..ef1acc8 100644
--- a/hw/top_earlgrey/data/top_earlgrey.hjson
+++ b/hw/top_earlgrey/data/top_earlgrey.hjson
@@ -157,6 +157,7 @@
       reset_connections: {rst_ni: "sys"},
       type: "rom",
       base_addr: "0x00008000",
+      swaccess: "ro",
       size: "0x4000"
     },
     { name: "ram_main",
@@ -170,6 +171,7 @@
       reset_connections: {rst_ni: "lc"},
       type: "eflash",
       base_addr: "0x20000000",
+      swaccess: "ro",
       size: "0x80000",
       inter_signal_list: [
         { struct: "flash",    // flash_req_t, flash_rsp_t
diff --git a/util/reggen/uvm_reg.sv.tpl b/util/reggen/uvm_reg.sv.tpl
index 89844de..49fca9e 100644
--- a/util/reggen/uvm_reg.sv.tpl
+++ b/util/reggen/uvm_reg.sv.tpl
@@ -116,7 +116,7 @@
     function new(string           name = "${gen_dv.mcname(block, w)}",
                  longint unsigned size = ${mem_size},
                  int unsigned     n_bits = ${mem_n_bits},
-                 string           access = "RW"/* TODO:"${mem_right}"*/,
+                 string           access = "${mem_right}",
                  int              has_coverage = UVM_NO_COVERAGE);
       super.new(name, size, n_bits, access, has_coverage);
     endfunction : new
diff --git a/util/topgen.py b/util/topgen.py
index 25c244a..c424653 100755
--- a/util/topgen.py
+++ b/util/topgen.py
@@ -371,8 +371,10 @@
             mem.name = item["name"]
             mem.base_addr = int(item["base_addr"], 0)
             mem.limit_addr = int(item["base_addr"], 0) + int(item["size"], 0)
-            # TODO: need to add mem access info for memories in topcfg
-            mem.dvrights = "RW"
+            if "swaccess" in item.keys():
+                mem.dvrights = item["swaccess"]
+            else:
+                mem.dvrights = "RW"
             mem.n_bits = top_block.width
             top_block.wins.append(mem)