我目前正在尝试移植一些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,但是我找不到如果没有找到匹配,它会返回什么
有几种方法可以做到这一点。如果可以依赖于编码,则可以使用通配符定义集合,并使用通配符相等操作符或内部操作符
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
最后,如果你从头开始,我建议你看看标记的联合和它们对应的模式匹配条件语句