检查变量是否是枚举集合的一部分的最佳方法?
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
最后,如果您是从头开始,我建议您查看 标记的联合 及其相应的 模式匹配条件语句
我目前正在尝试移植一些 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
最后,如果您是从头开始,我建议您查看 标记的联合 及其相应的 模式匹配条件语句