[keymgr/dv] Update sanity test

1. Update sanity test to do operations in all state with basic checking
in seq
2. Include keymgr sanity tests in CI

Signed-off-by: Weicai Yang <weicai@google.com>
diff --git a/hw/ip/keymgr/dv/env/keymgr_scoreboard.sv b/hw/ip/keymgr/dv/env/keymgr_scoreboard.sv
index 977a00e..32f8350 100644
--- a/hw/ip/keymgr/dv/env/keymgr_scoreboard.sv
+++ b/hw/ip/keymgr/dv/env/keymgr_scoreboard.sv
@@ -56,6 +56,8 @@
       void'(csr.predict(.value(item.a_data), .kind(UVM_PREDICT_WRITE), .be(item.a_mask)));
     end
 
+    // TODO update read check later
+    do_read_check = 1'b0;
     // process the csr req
     // for write, update local variable and fifo at address phase
     // for read, update predication at address phase and compare at data phase
@@ -63,7 +65,6 @@
       // add individual case item for each csr
       "intr_state": begin
         // FIXME
-        do_read_check = 1'b0;
       end
       "intr_enable": begin
         // FIXME
@@ -72,7 +73,8 @@
         // FIXME
       end
       default: begin
-        `uvm_fatal(`gfn, $sformatf("invalid csr: %0s", csr.get_full_name()))
+        // TODO
+        //`uvm_fatal(`gfn, $sformatf("invalid csr: %0s", csr.get_full_name()))
       end
     endcase
 
diff --git a/hw/ip/keymgr/dv/env/seq_lib/keymgr_base_vseq.sv b/hw/ip/keymgr/dv/env/seq_lib/keymgr_base_vseq.sv
index 74b5eb9..31474c3 100644
--- a/hw/ip/keymgr/dv/env/seq_lib/keymgr_base_vseq.sv
+++ b/hw/ip/keymgr/dv/env/seq_lib/keymgr_base_vseq.sv
@@ -13,6 +13,10 @@
   // various knobs to enable certain routines
   bit do_keymgr_init = 1'b1;
 
+  // save DUT returned current state here, rather than using it from RAL, it's needed info to
+  // predict operation result in seq
+  keymgr_pkg::keymgr_working_state_e current_state;
+
   `uvm_object_new
 
   virtual task dut_init(string reset_kind = "HARD");
@@ -27,39 +31,85 @@
 
   // setup basic keymgr features
   virtual task keymgr_init();
-    `uvm_info(`gfn, "Initializating key manager", UVM_LOW)
+    `uvm_info(`gfn, "Initializating key manager", UVM_MEDIUM)
     ral.control.init.set(1'b1);
     csr_update(.csr(ral.control));
     csr_spinwait(.ptr(ral.working_state), .exp_data(keymgr_pkg::StInit));
-  endtask // keymgr_init
+  endtask : keymgr_init
 
-  virtual task keymgr_advance();
-    bit [3:0] current_state;
-    `uvm_info(`gfn, "Advance key manager state", UVM_LOW)
+  // advance to next state and generate output, clear output
+  virtual task keymgr_operations(keymgr_pkg::keymgr_working_state_e exp_next_state,
+                                 bit gen_output = $urandom_range(0, 1),
+                                 bit clr_output = $urandom_range(0, 1));
+    `uvm_info(`gfn, "Start keymgr_operations", UVM_HIGH)
+    keymgr_advance(exp_next_state);
+    if (gen_output) begin
+      repeat ($urandom_range(1, 4)) begin
+        keymgr_generate(.identity($urandom_range(0, 1)));
+        if (clr_output) keymgr_rd_clr();
+      end
+    end
+  endtask : keymgr_operations
+
+  virtual task wait_op_done(bit is_gen_output);
+    keymgr_pkg::keymgr_op_status_e exp_status;
+    bit is_good_op = 1;
+    int key_verion = ral.key_version.get_mirrored_value();
+
+    if (is_gen_output) begin
+      // only when it's in 3 working state and key_verion less than max version
+      case (current_state)
+        keymgr_pkg::StCreatorRootKey: begin
+          is_good_op = key_verion <= ral.max_creator_key_ver.get_mirrored_value();
+        end
+        keymgr_pkg::StOwnerIntKey: begin
+          is_good_op = key_verion <= ral.max_owner_int_key_ver.get_mirrored_value();
+        end
+        keymgr_pkg::StOwnerKey: begin
+          is_good_op = key_verion <= ral.max_owner_key_ver.get_mirrored_value();
+        end
+        default: is_good_op = 0;
+      endcase
+    end else begin
+      is_good_op = current_state inside {keymgr_pkg::StInit,
+                                         keymgr_pkg::StCreatorRootKey,
+                                         keymgr_pkg::StOwnerIntKey,
+                                         keymgr_pkg::StOwnerKey};
+    end
+    `uvm_info(`gfn, $sformatf("Wait for operation done in state %0s, gen_out %0d",
+                              current_state.name, is_gen_output), UVM_MEDIUM)
+
+    // wait for status to get out of OpWip and check
+    csr_spinwait(.ptr(ral.op_status.status), .exp_data(keymgr_pkg::OpWip),
+                 .compare_op(CompareOpNe));
+    exp_status = is_good_op ? keymgr_pkg::OpDoneSuccess : keymgr_pkg::OpDoneFail;
+    `DV_CHECK_EQ_FATAL(ral.op_status.status.get_mirrored_value(), exp_status)
+  endtask : wait_op_done
+
+  virtual task keymgr_advance(keymgr_pkg::keymgr_working_state_e exp_next_state);
+    bit [TL_DW-1:0] rdata;
+
+    csr_rd(.ptr(ral.working_state), .value(rdata));
+    `downcast(current_state, rdata)
+    `uvm_info(`gfn, $sformatf("Advance key manager state from %0s", current_state.name), UVM_MEDIUM)
     ral.control.start.set(1'b1);
     ral.control.operation.set(keymgr_pkg::OpAdvance);
     csr_update(.csr(ral.control));
 
-    csr_rd(.ptr(ral.working_state), .value(current_state));
-    if (current_state < keymgr_pkg::StInit ||
-      current_state == keymgr_pkg::StDisabled) begin
-      csr_spinwait(.ptr(ral.op_status.status), .exp_data(keymgr_pkg::OpDoneFail));
-    end else begin
-      csr_spinwait(.ptr(ral.op_status.status), .exp_data(keymgr_pkg::OpDoneSuccess));
-    end
-
-  endtask // keymgr_advance
+    wait_op_done(.is_gen_output(0));
+    csr_rd_check(.ptr(ral.working_state), .compare_value(exp_next_state));
+    current_state = exp_next_state;
+  endtask : keymgr_advance
 
 
   // by default generate for software
-  virtual task keymgr_generate(bit Identity=0);
+  virtual task keymgr_generate(bit identity = 0);
     bit [2:0] operation;
-    bit [3:0] current_state;
 
-    `uvm_info(`gfn, "Generate key manager output", UVM_LOW)
+    `uvm_info(`gfn, "Generate key manager output", UVM_MEDIUM)
     ral.control.start.set(1'b1);
 
-    if (Identity) begin
+    if (identity) begin
       operation = keymgr_pkg::OpGenId;
     end else begin
       operation = keymgr_pkg::OpGenSwOut;
@@ -67,19 +117,12 @@
     ral.control.operation.set(operation);
     csr_update(.csr(ral.control));
 
-    csr_rd(.ptr(ral.working_state), .value(current_state));
-    if (current_state < keymgr_pkg::StInit ||
-      current_state == keymgr_pkg::StDisabled) begin
-      csr_spinwait(.ptr(ral.op_status.status), .exp_data(keymgr_pkg::OpDoneFail));
-    end else begin
-      csr_spinwait(.ptr(ral.op_status.status), .exp_data(keymgr_pkg::OpDoneSuccess));
-    end
-  endtask // keymgr_generate
-
+    wait_op_done(.is_gen_output(1));
+  endtask : keymgr_generate
 
   virtual task keymgr_rd_clr();
     bit [31:0] value[8];
-    `uvm_info(`gfn, "Read generated output", UVM_LOW)
+    `uvm_info(`gfn, "Read generated output", UVM_MEDIUM)
 
     // read each one out and print it out (nothing to compare it against right now)
     // after reading, the outputs should clear
@@ -93,7 +136,7 @@
     csr_rd(.ptr(ral.sw_share0_output_7), .value(value[7]));
 
     for (int i = 0; i < 8; i++) begin
-      `uvm_info(`gfn, $sformatf("Generated output %0d: 0x%0h", i, value[i]), UVM_LOW)
+      `uvm_info(`gfn, $sformatf("Generated output %0d: 0x%0h", i, value[i]), UVM_MEDIUM)
     end
 
     csr_rd_check(.ptr(ral.sw_share0_output_0), .compare_value('0));
@@ -105,8 +148,6 @@
     csr_rd_check(.ptr(ral.sw_share0_output_6), .compare_value('0));
     csr_rd_check(.ptr(ral.sw_share0_output_7), .compare_value('0));
 
-  endtask // keymgr_rd_clr
-
-
+  endtask : keymgr_rd_clr
 
 endclass : keymgr_base_vseq
diff --git a/hw/ip/keymgr/dv/env/seq_lib/keymgr_sanity_vseq.sv b/hw/ip/keymgr/dv/env/seq_lib/keymgr_sanity_vseq.sv
index 5b687e3..0fae700 100644
--- a/hw/ip/keymgr/dv/env/seq_lib/keymgr_sanity_vseq.sv
+++ b/hw/ip/keymgr/dv/env/seq_lib/keymgr_sanity_vseq.sv
@@ -5,24 +5,16 @@
 // basic sanity test vseq
 class keymgr_sanity_vseq extends keymgr_base_vseq;
   `uvm_object_utils(keymgr_sanity_vseq)
-
   `uvm_object_new
 
-
   task body();
-    `uvm_info(`gfn, "Key manager sanity check", UVM_LOW)
-    // to creator root
-    keymgr_advance();
-    keymgr_generate(1);
-    keymgr_rd_clr();
-
-    keymgr_advance();
-    keymgr_generate(1);
-    keymgr_rd_clr();
-
-    keymgr_advance();
-    keymgr_advance();
-    keymgr_advance();
+    `uvm_info(`gfn, "Key manager sanity check", UVM_HIGH)
+    // Advance state until StDisabled. In each state check SW output and clear output
+    keymgr_operations(.exp_next_state(keymgr_pkg::StCreatorRootKey), .gen_output(1), .clr_output(1));
+    keymgr_operations(.exp_next_state(keymgr_pkg::StOwnerIntKey), .gen_output(1), .clr_output(1));
+    keymgr_operations(.exp_next_state(keymgr_pkg::StOwnerKey), .gen_output(1), .clr_output(1));
+    keymgr_operations(.exp_next_state(keymgr_pkg::StDisabled), .gen_output(1), .clr_output(1));
+    keymgr_operations(.exp_next_state(keymgr_pkg::StDisabled), .gen_output(1), .clr_output(1));
   endtask : body
 
 endclass : keymgr_sanity_vseq
diff --git a/hw/ip/keymgr/dv/keymgr_sim_cfg.hjson b/hw/ip/keymgr/dv/keymgr_sim_cfg.hjson
index 5991b08..7f9bd3f 100644
--- a/hw/ip/keymgr/dv/keymgr_sim_cfg.hjson
+++ b/hw/ip/keymgr/dv/keymgr_sim_cfg.hjson
@@ -48,7 +48,6 @@
   tests: [
     {
       name: keymgr_sanity
-      run_opts: ["+en_scb=0"]
       uvm_test_seq: keymgr_sanity_vseq
     }
 
diff --git a/hw/top_earlgrey/dv/top_earlgrey_sim_cfgs.hjson b/hw/top_earlgrey/dv/top_earlgrey_sim_cfgs.hjson
index c5bf2fc..1f6a776 100644
--- a/hw/top_earlgrey/dv/top_earlgrey_sim_cfgs.hjson
+++ b/hw/top_earlgrey/dv/top_earlgrey_sim_cfgs.hjson
@@ -16,6 +16,7 @@
              "{proj_root}/hw/ip/gpio/dv/gpio_sim_cfg.hjson",
              "{proj_root}/hw/ip/hmac/dv/hmac_sim_cfg.hjson",
              "{proj_root}/hw/ip/i2c/dv/i2c_sim_cfg.hjson",
+             "{proj_root}/hw/ip/keymgr/dv/keymgr_sim_cfg.hjson",
              "{proj_root}/hw/ip/rv_timer/dv/rv_timer_sim_cfg.hjson",
              "{proj_root}/hw/ip/spi_device/dv/spi_device_sim_cfg.hjson",
              "{proj_root}/hw/ip/uart/dv/uart_sim_cfg.hjson",