[aes/dv] updated dv to support RTL changes

Signed-off-by: Rasmus Madsen <rasmus.madsen@wdc.com>
diff --git a/hw/ip/aes/data/aes_testplan.hjson b/hw/ip/aes/data/aes_testplan.hjson
index 94fd5cf..12a2272 100644
--- a/hw/ip/aes/data/aes_testplan.hjson
+++ b/hw/ip/aes/data/aes_testplan.hjson
@@ -85,7 +85,7 @@
             Exercise trigger and clear registers at random times to make sure we handle the different cornercases correctly.
             Example of a cornercases clearing data input or data output before the data is consumed or the DUT finishes an operation.'''
       milestone: V2
-      tests: []
+      tests: ["aes_clear"]
     }
     {
       name: nist_test_vectors
diff --git a/hw/ip/aes/dv/env/aes_env_pkg.sv b/hw/ip/aes/dv/env/aes_env_pkg.sv
index 0881587..a3f1294 100644
--- a/hw/ip/aes/dv/env/aes_env_pkg.sv
+++ b/hw/ip/aes/dv/env/aes_env_pkg.sv
@@ -28,10 +28,8 @@
   typedef enum int { AES_CFG=0, AES_DATA=1, AES_ERR_INJ=2 } aes_item_type_e;
 
   typedef struct packed {
-    bit          data_out;
-    bit          data_in;
-    bit          iv;
-    bit          key;
+    bit          dataout;
+    bit          key_iv_data_in;
   } clear_t;
 
   typedef struct packed {
diff --git a/hw/ip/aes/dv/env/aes_message_item.sv b/hw/ip/aes/dv/env/aes_message_item.sv
index 8369a0e..a952de2 100644
--- a/hw/ip/aes/dv/env/aes_message_item.sv
+++ b/hw/ip/aes/dv/env/aes_message_item.sv
@@ -199,8 +199,6 @@
       output_cleared = { output_cleared, item.data_was_cleared, item.data_was_cleared,
                         item.data_was_cleared, item.data_was_cleared};
     end
-
-
   endfunction // add_data_item
 
 
diff --git a/hw/ip/aes/dv/env/aes_scoreboard.sv b/hw/ip/aes/dv/env/aes_scoreboard.sv
index ff75e85..af66900 100644
--- a/hw/ip/aes/dv/env/aes_scoreboard.sv
+++ b/hw/ip/aes/dv/env/aes_scoreboard.sv
@@ -88,22 +88,23 @@
       case (1)
         // add individual case item for each csr
         (!uvm_re_match("ctrl_shadowed", csr_name)): begin
-          input_item.manual_op = item.a_data[10];
-          input_item.key_len   = item.a_data[9:7];
-          `downcast(input_item.operation, item.a_data[0]);
-          input_item.valid = 1'b1;
-          case (item.a_data[6:1])
-            6'b00_0001:  input_item.mode = AES_ECB;
-            6'b00_0010:  input_item.mode = AES_CBC;
-            6'b00_0100:  input_item.mode = AES_CFB;
-            6'b00_1000:  input_item.mode = AES_OFB;
-            6'b01_0000:  input_item.mode = AES_CTR;
-            6'b10_0000:  input_item.mode = AES_NONE;
-            default:     input_item.mode = AES_NONE;
-          endcase // case item.a_data[4:1]
-          input_item.clean();
-          input_item.start_item = 1;
-
+          if (write) begin
+            input_item.manual_op = item.a_data[10];
+            input_item.key_len   = item.a_data[9:7];
+            `downcast(input_item.operation, item.a_data[0]);
+            input_item.valid = 1'b1;
+            case (item.a_data[6:1])
+              6'b00_0001:  input_item.mode = AES_ECB;
+              6'b00_0010:  input_item.mode = AES_CBC;
+              6'b00_0100:  input_item.mode = AES_CFB;
+              6'b00_1000:  input_item.mode = AES_OFB;
+              6'b01_0000:  input_item.mode = AES_CTR;
+              6'b10_0000:  input_item.mode = AES_NONE;
+              default:     input_item.mode = AES_NONE;
+            endcase // case item.a_data[4:1]
+            input_item.clean();
+            input_item.start_item = 1;
+          end
         end
 
         (!uvm_re_match("key_share0*", csr_name)): begin
@@ -161,9 +162,10 @@
           // this is seen as the beginning of a new message
           if (!input_item.start_item) begin
             input_item.start_item = 1;
+            input_item.split_item = 1;
             `uvm_info(`gfn, $sformatf("splitting message"), UVM_MEDIUM)
           end
-          `uvm_info(`gfn, $sformatf("\n\t ----clearing KEY"), UVM_MEDIUM)
+          `uvm_info(`gfn, $sformatf("\n\t ----| clearing KEY"), UVM_MEDIUM)
           `uvm_info(`gfn, $sformatf("\n\t ----| clearing IV"), UVM_MEDIUM)
           `uvm_info(`gfn, $sformatf("\n\t ----| clearing DATA_IN"), UVM_MEDIUM)
         end
@@ -293,8 +295,8 @@
               end
             end else begin
               // verify that all 4 data_in and all 8 and all 4 IV  key are clean
-              `uvm_info(`gfn, $sformatf("\n\t ----|data_inv_vld?  %b, key clean ? %b",input_item.data_in_valid(), input_item.key_clean(1,0)),
-                                       UVM_MEDIUM)
+              `uvm_info(`gfn, $sformatf("\n\t ----|data_inv_vld?  %b, key clean ? %b",input_item.data_in_valid(),
+                                        input_item.key_clean(1,0)),UVM_MEDIUM)
               if (input_item.data_in_valid() && input_item.key_clean(1,0) && input_item.iv_clean(1,0)) begin
                 //clone and add to ref and rec data fifo
                 ok_to_fwd = 1;
@@ -312,10 +314,16 @@
       if (ok_to_fwd) begin
         ok_to_fwd = 0;
         `downcast(input_clone, input_item.clone());
-        `uvm_info(`gfn, $sformatf("\n\t AES INPUT ITEM RECEIVED - \n %s", input_clone.convert2string()),
+        `uvm_info(`gfn, $sformatf("\n\t AES INPUT ITEM RECEIVED - \n %s \n\t split message: %0b",
+                                   input_clone.convert2string(), input_clone.split_item),
                                   UVM_MEDIUM)
         rcv_item_q.push_front(input_clone);
         input_item.clean();
+        // only reset the split here
+        // in the case the reset comes after data input
+        // having it in clean will reset it when the ctrl
+        // is written
+        input_item.split_item = 0;
       end
     end
 
@@ -356,6 +364,10 @@
           // and no output is ready
           // there won't be a response for this item
           // reset/clear was triggered
+          `uvm_info(`gfn, $sformatf("\n\t ---| Status read: \n\t idle %0b \n\t output lost %0b  ",
+                          get_field_val(ral.status.idle, item.d_data),
+                          get_field_val(ral.status.output_lost, item.d_data)), UVM_MEDIUM)
+          
           if (get_field_val(ral.status.idle, item.d_data) &&
               get_field_val(ral.status.output_lost, item.d_data)) begin
             if (rcv_item_q.size() != 0) begin
@@ -366,7 +378,7 @@
         end
       endcase // case (csr.get_name())
 
-      if (output_item.data_out_valid()) begin
+      if (output_item.data_out_valid() || output_item.data_was_cleared) begin
         // if data_out is read multipletimes in a row we should not pop input more than once
         if (rcv_item_q.size() == 0) begin
           output_item                    = new();
@@ -375,6 +387,13 @@
           complete_item                  = rcv_item_q.pop_back();
           complete_item.data_out         = output_item.data_out;
           complete_item.data_was_cleared = output_item.data_was_cleared;
+          // if message was split and data was read out.
+          // we will have one more message than expected.
+          if (complete_item.split_item) begin
+            cfg.split_cnt++;
+            `uvm_info(`gfn, $sformatf("\n\t ----| incrementing split count now at: %d",
+                      cfg.split_cnt), UVM_MEDIUM)
+          end
 
           `downcast(complete_clone, complete_item.clone());
           item_fifo.put(complete_clone);
@@ -495,7 +514,7 @@
           `uvm_fatal(`gfn, $sformatf(" # %0d  \n\t %s \n", good_cnt, txt))
           end
         end
-        `uvm_info(`gfn, $sformatf("\n\t ----|   MESSAGE #%0d MATCHED    |-----", good_cnt),
+        `uvm_info(`gfn, $sformatf("\n\t ----|   MESSAGE #%0d MATCHED  %s  |-----", good_cnt, msg.aes_mode.name() ),
                                   UVM_MEDIUM)
         good_cnt++;
       end else begin
@@ -534,6 +553,8 @@
 
   virtual task wait_fifo_empty();
     `uvm_info(`gfn, $sformatf("item fifo entries %d", item_fifo.num()), UVM_MEDIUM)
+    `uvm_info(`gfn, $sformatf("rcv_queue entries %d", rcv_item_q.size()), UVM_MEDIUM)
+    `uvm_info(`gfn, $sformatf("msg fifo entries %d", msg_fifo.num()), UVM_MEDIUM)
     wait (rcv_item_q.size() == 0);
     wait (item_fifo.num()   == 0);
     wait (msg_fifo.num()    == 0);
diff --git a/hw/ip/aes/dv/env/aes_seq_item.sv b/hw/ip/aes/dv/env/aes_seq_item.sv
index 3cac6a5..d27f2b2 100644
--- a/hw/ip/aes/dv/env/aes_seq_item.sv
+++ b/hw/ip/aes/dv/env/aes_seq_item.sv
@@ -62,6 +62,8 @@
 
   // indicate message start  in manual mode
   bit             start_item       = 0;
+  // indicate a message was split in two with this item.
+  bit             split_item       = 0;
 
 
   ///////////////////////////////////////
@@ -104,10 +106,8 @@
 
     clr_reg_dist_select == 0 ->            clear_reg == 0;
     clr_reg_dist_select == 1 ->            $countones(clear_reg) > 1;
-    clr_reg_dist_select == 2 -> clear_reg dist {     1  :/ clear_reg_pct/4,
-                                                     2  :/ clear_reg_pct/4,
-                                                     4  :/ clear_reg_pct/4,
-                                                     8  :/ clear_reg_pct/4
+    clr_reg_dist_select == 2 -> clear_reg dist {     1  :/ clear_reg_pct/2,
+                                                     2  :/ clear_reg_pct/2
                                                 };
 
   }
@@ -259,7 +259,7 @@
     iv_vld       = '0;
     key_vld      = '{default: '0};
     data_out_vld = '0;
-    start_item   = 0;
+    start_item   =  0;
   endfunction // clean
 
 
@@ -285,6 +285,7 @@
     aes_mode         = rhs_.aes_mode;
     clear_reg        = rhs_.clear_reg;
     start_item       = rhs_.start_item;
+    split_item       = rhs_.split_item;
     data_was_cleared = rhs_.data_was_cleared;
   endfunction // copy
 
diff --git a/hw/ip/aes/dv/env/seq_lib/aes_base_vseq.sv b/hw/ip/aes/dv/env/seq_lib/aes_base_vseq.sv
index 12e9bac..ebd4a66 100644
--- a/hw/ip/aes/dv/env/seq_lib/aes_base_vseq.sv
+++ b/hw/ip/aes/dv/env/seq_lib/aes_base_vseq.sv
@@ -62,17 +62,14 @@
   virtual task clear_regs(clear_t clr_vector);
     string txt="";
     bit [TL_DW:0] reg_val = '0;
-
-    txt = $sformatf("\n data_out: \t %0b", clr_vector.data_out);
-    txt = {txt, $sformatf("\n data_in: \t %0b", clr_vector.data_in)};
-    txt = {txt, $sformatf("\n data_iv: \t %0b", clr_vector.iv)};
-    txt = {txt, $sformatf("\n data_key: \t %0b", clr_vector.key)};
+    txt = {txt, $sformatf("\n data_out: \t %0b", clr_vector.dataout)};
+    txt = {txt, $sformatf("\n key_iv_data_in: \t %0b", clr_vector.key_iv_data_in)};
     txt = {txt, $sformatf("\n vector: \t %0b", clr_vector)};
     `uvm_info(`gfn, $sformatf("%s",txt), UVM_MEDIUM)
 
     ral.trigger.set(0);
-    ral.trigger.key_iv_data_in_clear.set(|clr_vector[2:0]);
-    ral.trigger.data_out_clear.set(clr_vector.data_out);
+    ral.trigger.key_iv_data_in_clear.set(clr_vector.key_iv_data_in);
+    ral.trigger.data_out_clear.set(clr_vector.dataout);
     csr_update(ral.trigger);
   endtask // clear_registers
 
@@ -98,7 +95,6 @@
 
   virtual task set_key_len(bit [2:0] key_len);
     ral.ctrl_shadowed.key_len.set(key_len);
-    `uvm_info(`gfn, $sformatf("Writing Key LEN: %b", key_len), UVM_LOW)
     csr_update(.csr(ral.ctrl_shadowed), .en_shadow_wr(1'b1), .blocking(1));
   endtask
 
@@ -368,6 +364,7 @@
     // the manual operation should be included in the unbalanced =1 also
     if (new_msg) setup_dut(cfg_item);
     if (unbalanced == 0 || manual_operation) begin
+       data_item = new();
       while (aes_item_queue.size() > 0) begin
         status_fsm(cfg_item, data_item, new_msg, manual_operation, 0, status);
         if (status.input_ready) begin
@@ -381,6 +378,8 @@
       end
     end else begin
 
+      data_item = new();
+
       while ((aes_item_queue.size() > 0) || (read_queue.size() > 0)) begin
         // get the status to make sure we can provide data - but don't wait for output //
         status_fsm(cfg_item, data_item, new_msg, manual_operation, 0, status);
@@ -467,6 +466,7 @@
     bit                   done        = 0;
     string                txt         = "";
 
+    txt = "\n Entering FSM";
     // enable get status when provided with an empty Item.
     if (data_item.mode === 'X) begin
       csr_rd(.ptr(ral.status), .value(status), .blocking(is_blocking));
@@ -476,6 +476,7 @@
     while(!done && (data_item.mode != AES_NONE)) begin
       //read the status register to see that we have triggered the operation
       csr_rd(.ptr(ral.status), .value(status), .blocking(is_blocking));
+      txt = {txt, "\n ----|reading STATUS", status2string(status)};
       // check status and act accordingly //
       if (status.alert_fatal_fault) begin
         // stuck pull reset //
@@ -485,9 +486,12 @@
           if (status.output_valid && read_output) begin
             read_data(data_item.data_out, is_blocking);
             txt = {txt, $sformatf("\n\t ----| status state 0 ")};
+            done = 1;
+          end else if (!read_output) begin
+            done = 1; // get more data
+          end else begin
+            try_recover(cfg_item, data_item, manual_operation);
           end
-          done = 1;
-
         end else if (status.idle && !status.input_ready) begin
           // state 1 //
           // if data ready just read and return
@@ -497,30 +501,9 @@
           end else begin
             // if data is not ready the DUT is missing
             // KEY and IV - or the configuration
-            csr_rd(.ptr(ral.ctrl_shadowed), .value(ctrl), .blocking(is_blocking));
-            ral.ctrl_shadowed.operation.set(cfg_item.operation);
-            ral.ctrl_shadowed.mode.set(cfg_item.mode);
-            ral.ctrl_shadowed.key_len.set(cfg_item.key_len);
-            ral.ctrl_shadowed.manual_operation.set(cfg_item.manual_op);
-
-            if (ral.ctrl_shadowed.get_mirrored_value() != ctrl) begin
-              `uvm_info(`gfn, $sformatf("\n\t ----| configuration does not match actual - re-confguring"), UVM_LOW)
-              txt = { txt, $sformatf("\n\t ----| configuration does not match actual - re-confguring")};
-              csr_update(.csr(ral.ctrl_shadowed), .en_shadow_wr(1'b1), .blocking(is_blocking));
-            end else begin
-              // key and IV missing clear all and rewrite (a soon to come update will merge
-              // the clear options into a single bit)
-              clear_regs(4'b1111);
-              // wait for idle
-              csr_spinwait(.ptr(ral.status.idle) , .exp_data(1'b1));
-              write_key(cfg_item.key, is_blocking);
-              write_iv(cfg_item.iv, is_blocking);
-              add_data(data_item.data_in, is_blocking);
-              if (manual_operation) trigger();
-            end
+            try_recover(cfg_item, data_item, manual_operation);
             txt = {txt, $sformatf("\n\t ----| status state 1 ")};
           end
-
         end else if (status.output_valid) begin
           // state 2 //
           // data ready to be read out
@@ -549,13 +532,42 @@
           txt = {txt, $sformatf("\n ----| OUTPUT_VALID %0b",status.output_valid)};
           `uvm_fatal(`gfn, $sformatf("\n\t %s",txt))
         end
-        `uvm_info(`gfn, $sformatf("\n\t %s",txt), UVM_MEDIUM)
       end // else: !if(status.alert_fatal_fault)
     end // while (!done)
-
+    `uvm_info(`gfn, $sformatf("\n\t %s",txt), UVM_MEDIUM)
   endtask // transmit_fsm
 
 
+  virtual task try_recover(
+    aes_seq_item        cfg_item,         // sequence item with configuraton
+    aes_seq_item        data_item,        // sequence item with data to process
+    bit                 manual_operation
+    );
+    // if data is not ready the DUT is missing
+    // KEY and IV - or the configuration
+    ctrl_reg_t            ctrl;
+    bit                   is_blocking = ~cfg_item.do_b2b;
+
+    csr_rd(.ptr(ral.ctrl_shadowed), .value(ctrl), .blocking(is_blocking));
+    ral.ctrl_shadowed.operation.set(cfg_item.operation);
+    ral.ctrl_shadowed.mode.set(cfg_item.mode);
+    ral.ctrl_shadowed.key_len.set(cfg_item.key_len);
+    ral.ctrl_shadowed.manual_operation.set(cfg_item.manual_op);
+    // key and IV missing clear all and rewrite (a soon to come update will merge
+    // the clear options into a single bit)
+
+    clear_regs(2'b11);
+    // wait for idle
+    csr_spinwait(.ptr(ral.status.idle), .exp_data(1'b1));
+    csr_update(.csr(ral.ctrl_shadowed), .en_shadow_wr(1'b1), .blocking(is_blocking));
+    csr_spinwait(.ptr(ral.status.idle), .exp_data(1'b1));
+    write_key(cfg_item.key, is_blocking);
+    write_iv(cfg_item.iv, is_blocking);
+    add_data(data_item.data_in, is_blocking);
+    if (manual_operation) trigger();
+  endtask // try_recover
+
+
   virtual task send_msg_queue (
      bit unbalanced,                         // uses the probablilites to randomize if we read or write
      int read_prob,                          // chance of reading an availabout output
@@ -657,4 +669,18 @@
       `uvm_info(`gfn, $sformatf("%s", print_item.convert2string()), UVM_MEDIUM)
     end
   endfunction // aes_print_item_queue
+
+
+  function string status2string(status_t status);
+    string txt="";
+    txt ={txt, $sformatf("\n\t ---| IDLE:          %0b", status.idle)};
+    txt ={txt, $sformatf("\n\t ---| STALL:         %0b", status.stall)};
+    txt ={txt, $sformatf("\n\t ---| Output Lost:   %0b", status.output_lost)};
+    txt ={txt, $sformatf("\n\t ---| Output Valid:  %0b", status.output_valid)};
+    txt ={txt, $sformatf("\n\t ---| Input Ready:   %0b", status.input_ready)};
+    txt ={txt, $sformatf("\n\t ---| Alert - Recov: %0b", status.alert_recov_ctrl_update_err)};
+    txt ={txt, $sformatf("\n\t ---| Alert -Fatal:  %0b", status.alert_fatal_fault)};
+    return txt;
+  endfunction // status2string
+
 endclass : aes_base_vseq
diff --git a/hw/ip/aes/dv/tests/aes_clear_test.sv b/hw/ip/aes/dv/tests/aes_clear_test.sv
index 3fdf30f..28f5387 100644
--- a/hw/ip/aes/dv/tests/aes_clear_test.sv
+++ b/hw/ip/aes/dv/tests/aes_clear_test.sv
@@ -43,7 +43,7 @@
     cfg.fixed_iv_en              = 0;
 
     cfg.random_data_key_iv_order = 1;
-    cfg.clear_reg_pct            = 100;
+    cfg.clear_reg_pct            = 80;
 
     `DV_CHECK_RANDOMIZE_FATAL(cfg)
   endfunction