[keymgr/dv] update stress_all with reset

Enhance keymgr_kmac_agent to handle reset
Fix issues on checking sw_bind_en and err_code

Signed-off-by: Weicai Yang <weicai@google.com>
diff --git a/hw/dv/sv/keymgr_kmac_agent/keymgr_kmac_device_driver.sv b/hw/dv/sv/keymgr_kmac_agent/keymgr_kmac_device_driver.sv
index d0d557a..d03ed54 100644
--- a/hw/dv/sv/keymgr_kmac_agent/keymgr_kmac_device_driver.sv
+++ b/hw/dv/sv/keymgr_kmac_agent/keymgr_kmac_device_driver.sv
@@ -32,16 +32,16 @@
       rsp.set_id_info(req);
       `uvm_info(`gfn, $sformatf("rcvd item:\n%0s", req.sprint()), UVM_HIGH)
 
-      repeat (rsp.rsp_delay) begin
-        if (cfg.vif.rst_n) @(cfg.vif.device_cb);
-      end
+      `DV_SPINWAIT_EXIT(repeat (rsp.rsp_delay) @(cfg.vif.device_cb);,
+                        wait(!cfg.vif.rst_n))
 
       cfg.vif.device_cb.rsp_done          <= 1;
       cfg.vif.device_cb.rsp_digest_share0 <= rsp.rsp_digest_share0;
       cfg.vif.device_cb.rsp_digest_share1 <= rsp.rsp_digest_share1;
       cfg.vif.device_cb.rsp_error         <= rsp.rsp_error;
 
-      if (cfg.vif.rst_n) @(cfg.vif.device_cb);
+      `DV_SPINWAIT_EXIT(@(cfg.vif.device_cb);,
+                        wait(!cfg.vif.rst_n))
       invalidate_signals();
 
       `uvm_info(`gfn, "item sent", UVM_HIGH)
diff --git a/hw/dv/sv/keymgr_kmac_agent/keymgr_kmac_monitor.sv b/hw/dv/sv/keymgr_kmac_agent/keymgr_kmac_monitor.sv
index 4908e26..756298c 100644
--- a/hw/dv/sv/keymgr_kmac_agent/keymgr_kmac_monitor.sv
+++ b/hw/dv/sv/keymgr_kmac_agent/keymgr_kmac_monitor.sv
@@ -31,12 +31,21 @@
     data_fifo = new("data_fifo", this);
   endfunction
 
-  task run_phase(uvm_phase phase);
-    super.run_phase(phase);
+  virtual protected task collect_trans(uvm_phase phase);
+    forever fork
+      begin : isolation_fork
+        fork
+          process_trans();
+          @(negedge cfg.vif.rst_n);
+        join_any
+        disable fork;
+        process_reset();
+      end : isolation_fork
+    join
   endtask
 
   // collect transactions forever - already forked in dv_base_moditor::run_phase
-  virtual protected task collect_trans(uvm_phase phase);
+  virtual protected task process_trans();
     forever begin
       keymgr_kmac_item req = keymgr_kmac_item::type_id::create("req");
       keymgr_kmac_item rsp;
@@ -49,6 +58,7 @@
 
         data_fifo.get(data_item);
         {data, strb, last} = data_item.h_data;
+        ok_to_end = 0;
 
         while (strb > 0) begin
           if (strb[0]) req.byte_data_q.push_back(data[7:0]);
@@ -67,7 +77,15 @@
       rsp.rsp_digest_share1 = cfg.vif.rsp_digest_share1;
       rsp_port.write(rsp);
       `uvm_info(`gfn, $sformatf("Write rsp item:\n%0s", rsp.sprint()), UVM_HIGH)
+      ok_to_end = 1;
     end
   endtask
 
+  virtual protected task process_reset();
+    `uvm_info(`gfn, $sformatf("Reset occurs"), UVM_MEDIUM)
+    ok_to_end = 1;
+    @(posedge cfg.vif.rst_n);
+    data_fifo.flush();
+  endtask
+
 endclass
diff --git a/hw/ip/keymgr/dv/env/keymgr_scoreboard.sv b/hw/ip/keymgr/dv/env/keymgr_scoreboard.sv
index 704435d..ffb2545 100644
--- a/hw/ip/keymgr/dv/env/keymgr_scoreboard.sv
+++ b/hw/ip/keymgr/dv/env/keymgr_scoreboard.sv
@@ -95,10 +95,15 @@
         process_kmac_data_rsp(item);
       end
       forever begin
-        wait(!cfg.under_reset);
         wait(cfg.keymgr_vif.keymgr_en != lc_ctrl_pkg::On);
+        // when Keymgr_en is Off, sw_binding_en is 0.
+        // will be back to default value (1) when Keymgr_en = On
+        void'(ral.sw_binding_en.predict(.value(0)));
+
         if (current_state != keymgr_pkg::StReset) wipe_hw_keys();
+
         wait(cfg.keymgr_vif.keymgr_en == lc_ctrl_pkg::On);
+        void'(ral.sw_binding_en.predict(.value(1)));
       end
     join_none
   endtask
@@ -292,6 +297,8 @@
         return;
       end else if (`gmv(ral.sw_binding_en) == 0 && csr.get_name() inside {"sw_binding_0",
                "sw_binding_1", "sw_binding_2", "sw_binding_3"}) begin
+        `uvm_info(`gfn, $sformatf("Reg write to %0s is ignored due to sw_binding_en=0",
+                                  csr.get_name()), UVM_MEDIUM)
         return;
       end else begin
         void'(csr.predict(.value(item.a_data), .kind(UVM_PREDICT_WRITE), .be(item.a_mask)));
@@ -316,7 +323,7 @@
           end
         end
       end
-      "intr_enable, err_code": begin
+      "intr_enable", "err_code", "sw_binding_en": begin
         // no speical handle is needed
       end
       "intr_test": begin
@@ -461,7 +468,8 @@
       keymgr_pkg::StCreatorRootKey: return `gmv(ral.max_creator_key_ver);
       keymgr_pkg::StOwnerIntKey:    return `gmv(ral.max_owner_int_key_ver);
       keymgr_pkg::StOwnerKey:       return `gmv(ral.max_owner_key_ver);
-      default: `uvm_fatal(`gfn, $sformatf("unexpected state %s", current_state.name))
+      // for the other state, max is 0
+      default: return 0;
     endcase
   endfunction
 
@@ -482,34 +490,43 @@
   endfunction
 
   virtual function bit [TL_DW-1:0] get_err_code();
-    keymgr_pkg::keymgr_ops_e op = get_operation();
-    bit [TL_DW-1:0]          err_code;
+    bit [TL_DW-1:0] err_code;
 
-    err_code[keymgr_pkg::ErrInvalidIn] = get_hw_invalid_input();
+    err_code[keymgr_pkg::ErrInvalidOp] = get_op_error();
+    err_code[keymgr_pkg::ErrInvalidIn] = get_hw_invalid_input() | get_sw_invalid_input();
 
+    return err_code;
+  endfunction
+
+  virtual function bit get_op_error();
     case (current_state)
       keymgr_pkg::StReset: begin
-        if (op != keymgr_pkg::OpAdvance) begin
-          err_code[keymgr_pkg::ErrInvalidOp] = 1;
+        if (get_operation() != keymgr_pkg::OpAdvance) begin
+          return 1;
         end
       end
       keymgr_pkg::StInit: begin
-        if (!(op inside {keymgr_pkg::OpAdvance, keymgr_pkg::OpDisable})) begin
-          err_code[keymgr_pkg::ErrInvalidOp] = 1;
+        if (!(get_operation() inside {keymgr_pkg::OpAdvance, keymgr_pkg::OpDisable})) begin
+          return 1;
         end
       end
       keymgr_pkg::StCreatorRootKey, keymgr_pkg::StOwnerIntKey, keymgr_pkg::StOwnerKey: begin
-        if (op inside {keymgr_pkg::OpGenSwOut, keymgr_pkg::OpGenHwOut} &&
-            get_sw_invalid_input()) begin
-          err_code[keymgr_pkg::ErrInvalidIn] = 1;
-        end
+        // no operation error
       end
       keymgr_pkg::StDisabled: begin
-        err_code[keymgr_pkg::ErrInvalidOp] = 1;
+        return 1;
       end
       default: `uvm_fatal(`gfn, $sformatf("unexpected state %s", current_state.name))
     endcase
-    return err_code;
+    return 0;
+  endfunction
+
+  virtual function bit get_sw_invalid_input();
+    if (get_operation() inside {keymgr_pkg::OpGenSwOut, keymgr_pkg::OpGenHwOut}) begin
+      return get_current_max_version() < `gmv(ral.key_version);
+    end else begin
+      return 0;
+    end
   endfunction
 
   // HW invalid input checks as following
@@ -524,7 +541,7 @@
   virtual function bit get_hw_invalid_input();
     bit is_err;
 
-    if (current_internal_key inside {0, '1}) begin
+    if (current_internal_key inside {0, '1} && current_state != keymgr_pkg::StReset) begin
       is_err = 1;
     end
 
@@ -563,10 +580,6 @@
     return is_err;
   endfunction
 
-  virtual function bit get_sw_invalid_input();
-    return get_current_max_version() < `gmv(ral.key_version);
-  endfunction
-
   // in normal operational states, invalid command etc lead to random data for gen-out OP
   virtual function bit get_is_kmac_data_correct();
     bit [TL_DW-1:0] err_code = get_err_code();
@@ -787,6 +800,11 @@
     sw_data_a_array.delete();
     hw_data_a_array.delete();
     cfg.keymgr_vif.reset();
+
+    // when Keymgr_en is Off, sw_binding_en is 0
+    if (cfg.keymgr_vif.keymgr_en != lc_ctrl_pkg::On) begin
+      void'(ral.sw_binding_en.predict(.value(0)));
+    end
   endfunction
 
   function void check_phase(uvm_phase phase);
diff --git a/hw/ip/keymgr/dv/env/seq_lib/keymgr_stress_all_vseq.sv b/hw/ip/keymgr/dv/env/seq_lib/keymgr_stress_all_vseq.sv
index 4e8c450..5cd88fb 100644
--- a/hw/ip/keymgr/dv/env/seq_lib/keymgr_stress_all_vseq.sv
+++ b/hw/ip/keymgr/dv/env/seq_lib/keymgr_stress_all_vseq.sv
@@ -16,9 +16,11 @@
                           "keymgr_sideload_vseq",
                           "keymgr_random_vseq",
                           "keymgr_direct_to_disabled_vseq",
+                          "keymgr_sw_invalid_input_vseq"
                           // TODO, add this later
+                          // "keymgr_hwsw_invalid_input_vseq",
                           //"keymgr_lc_disable_vseq",
-                          "keymgr_invalid_kmac_input_vseq"};
+                          };
     for (int i = 1; i <= num_trans; i++) begin
       uvm_sequence     seq;
       keymgr_base_vseq keymgr_vseq;