[prim/security] Improve the code for prim_sparse_fsm security check

According to the discussion in PR #11129, we update the enum checks from
generate block to a function.
JasperGold does support simple function syntax.

Signed-off-by: Cindy Chen <chencindy@opentitan.org>
diff --git a/hw/ip/prim/rtl/prim_assert_sec_cm.svh b/hw/ip/prim/rtl/prim_assert_sec_cm.svh
index bcc72d6..9fbbf94 100644
--- a/hw/ip/prim/rtl/prim_assert_sec_cm.svh
+++ b/hw/ip/prim/rtl/prim_assert_sec_cm.svh
@@ -24,6 +24,6 @@
   `ASSERT_ERROR_TRIGGER_ALERT(NAME_, PRIM_HIER_, ALERT_, MAX_CYCLES_, err_o)
 
 `define ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(NAME_, PRIM_HIER_, ALERT_, MAX_CYCLES_ = 7) \
-  `ASSERT_ERROR_TRIGGER_ALERT(NAME_, PRIM_HIER_, ALERT_, MAX_CYCLES_, unused_valid_st)
+  `ASSERT_ERROR_TRIGGER_ALERT(NAME_, PRIM_HIER_, ALERT_, MAX_CYCLES_, unused_err_o)
 
 `endif // PRIM_ASSERT_SEC_CM_SVH
diff --git a/hw/ip/prim/rtl/prim_sparse_fsm_flop.sv b/hw/ip/prim/rtl/prim_sparse_fsm_flop.sv
index 830cedd..a327457 100644
--- a/hw/ip/prim/rtl/prim_sparse_fsm_flop.sv
+++ b/hw/ip/prim/rtl/prim_sparse_fsm_flop.sv
@@ -18,7 +18,7 @@
   output logic [Width-1:0] state_o
 );
 
-  logic unused_valid_st;
+  logic unused_err_o;
 
   prim_flop #(
     .Width(Width),
@@ -31,21 +31,17 @@
   );
 
   `ifdef INC_ASSERT
-    StateEnumT tmp = tmp.first;
-    // An array to hold all possible enum values based on the given width.
-    StateEnumT declared_fsms [2**Width];
+  assign unused_err_o = is_undefined_state(state_o);
 
-    // Loop through all possible FSM values and store the listed StateEnumT enum value in
-    // `declared_fsms`.
-    // Ideally we can use `i < tmp.num`, but Xcelium does not support this syntax. (error msg:
-    // Hierarchical name ('tmp.num()') not allowed within a constant expression)
-    for (genvar i = 0; i < 2**Width; i++) begin : gen_declared_enum_list
-      if (i == 0) assign declared_fsms[0] = tmp;
-      else assign declared_fsms[i] = declared_fsms[i-1].next;
+  function automatic logic is_undefined_state(logic [Width-1:0] sig);
+    for (int i = 0, StateEnumT t = t.first(); i < t.num(); i += 1, t = t.next()) begin
+      if (StateEnumT'(sig) === t) return 0;
     end
-    assign unused_valid_st = !(state_o inside {declared_fsms});
+    return 1;
+  endfunction
+
   `else
-    assign unused_valid_st = 1'b1;
+    assign unused_err_o = 1'b0;
   `endif
 
   // If ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT is declared, the unused_assert_connected signal will