检查变量是否是枚举集合的一部分的最佳方法?

Best way to check if variable is part of collection of enums?

我目前正在尝试移植一些 Specman 代码,这些代码根据变量是否是枚举的一部分采取某些操作。在 Specman 中,代码看起来像这样:

define COMP_STATES do_add, do_sub;
define WAIT_STATES wait_X, wait_Y;
defube RUN_STATES  run_X, run_Y;

type my_states : [
    do_add = 3'b000;
    do_sub = 3'b001;
    wait_X = 3'b010;
    wait_Y = 3'b011;
    run_X  = 3'b100;
    run_Y  = 3'b101;
] (bits:3);

之后:

if(state in [COMP_STATES, RUN_STATES]){
    /* DO STUFF */
} else if(state in [WAIT_STATES]){
    /* DO STUFF */
}

我现在想在 SystemVerilog 中执行此操作,但遇到了一些障碍。我目前最好的方法是使用数组:

my_state which_state[$] = {`COMP_STATES, `RUN_STATES};
int indexes[$]  = which_state.get_index( index ) where ( index == state );
int num_indexes = indexes.size(); //If state doesn't exist in my_state then the returned array of indexes will be empty.
if(num_indexes > 0) begin /* DO STUFF */ end

但总得有更优雅简洁的方式吧? find_first_index 浮现在脑海中,但我找不到 return 以防找不到匹配项。

有几种方法可以做到这一点。如果可以依赖编码,则可以使用通配符定义集合并使用通配符相等运算符或内部运算符

let COMP_STATES = 3'b00?; // or parameter COMP_STATES = 3'b00?;
let RUN_STATES = 3'b01?; // or parameter RUN_STATES = 3'b01?;
let WAIT_STATES = 3'b10?; // or parameter WAIT_STATES = 3'b10?;

if (my_states inside {COMP_STATES,RUN_STATES})
   ...
else if (my_state ==? WAIT_STATES)
   ...

或者您可以创建一个表达式

module top;
   enum bit [2:0] {
           do_add = 3'b000,
           do_sub = 3'b001,
           wait_X = 3'b010,
           wait_Y = 3'b011,
           run_X  = 3'b100,
           run_Y  = 3'b101
          } my_states;
   let COMP_STATES = my_states inside {do_add, do_sub};
   let WAIT_STATES = my_states inside {wait_X, wait_Y};
   let RUN_STATES =  my_states inside {run_X, run_Y};

   initial repeat(20) begin
      std::randomize(my_states);
      $write (my_states.name());
      case(1)
    COMP_STATES, RUN_STATES:
      $display("=comp,run");
    WAIT_STATES:
      $display("-wait");
      endcase
   end
endmodule

最后,如果您是从头开始,我建议您查看 标记的联合 及其相应的 模式匹配条件语句