[dv/otp] scb checking for lc_token

This PR add a function to check if otp output the correct lc_unlock
token value.

Signed-off-by: Cindy Chen <chencindy@google.com>
diff --git a/hw/ip/otp_ctrl/dv/env/otp_ctrl_scoreboard.sv b/hw/ip/otp_ctrl/dv/env/otp_ctrl_scoreboard.sv
index 6e27cd9..c2045ad 100644
--- a/hw/ip/otp_ctrl/dv/env/otp_ctrl_scoreboard.sv
+++ b/hw/ip/otp_ctrl/dv/env/otp_ctrl_scoreboard.sv
@@ -56,6 +56,7 @@
     super.run_phase(phase);
     fork
       process_backdoor_mem_clear();
+      process_lc_token_req();
     join_none
   endtask
 
@@ -90,6 +91,21 @@
     end
   endtask
 
+  virtual task process_lc_token_req();
+    forever begin
+      push_pull_item#(.HostDataWidth(lc_ctrl_pkg::LcTokenWidth)) rcv_item;
+      bit [SCRAMBLE_DATA_SIZE-1:0] exp_data_0, exp_data_1;
+      lc_token_fifo.get(rcv_item);
+      exp_data_0 = present_encode_with_final_const(.data(RndCnstDigestIVDefault[1]),
+                                                   .key(rcv_item.h_data),
+                                                   .final_const(RndCnstDigestConstDefault[1]));
+      exp_data_1 = present_encode_with_final_const(.data(exp_data_0),
+                                                   .key(rcv_item.h_data),
+                                                   .final_const(RndCnstDigestConstDefault[1]));
+      `DV_CHECK_EQ(rcv_item.d_data, {exp_data_1, exp_data_0}, "lc_token_encode_mismatch")
+    end
+  endtask
+
   virtual task process_tl_access(tl_seq_item item, tl_channels_e channel = DataChannel);
     uvm_reg csr;
     bit     do_read_check     = 1'b1;
@@ -371,6 +387,20 @@
     descramble_data = output_data[NUM_ROUND-1];
   endfunction
 
+  // this function go through present encode algo twice:
+  // one with input key, one with a final constant
+  // this is mainly used for unlock token hashing
+  virtual function bit [SCRAMBLE_DATA_SIZE-1:0] present_encode_with_final_const(
+                                                bit [SCRAMBLE_DATA_SIZE-1:0] data,
+                                                bit [SCRAMBLE_KEY_SIZE-1:0]  key,
+                                                bit [SCRAMBLE_KEY_SIZE-1:0]  final_const);
+    bit [NUM_ROUND-1:0] [SCRAMBLE_DATA_SIZE-1:0] enc_array;
+    crypto_dpi_present_pkg::sv_dpi_present_encrypt(data, key, key_size_80, enc_array);
+    crypto_dpi_present_pkg::sv_dpi_present_encrypt(enc_array[NUM_ROUND-1], final_const,
+                                                   key_size_80, enc_array);
+    present_encode_with_final_const = enc_array[NUM_ROUND-1];
+  endfunction
+
   function bit [TL_AW-1:0] get_normalized_dai_addr();
     bit [TL_DW-1:0] dai_addr = ral.direct_access_address.get_mirrored_value();
     get_normalized_dai_addr = is_secret(dai_addr) ? dai_addr >> 3 << 1 : dai_addr >> 2;