Specman 中是否有内置方法可以为我提供枚举变量的第一个、最后一个和下一个值的值?例如:
type color_e: [blue, green, red, yellow, orange];`
var color: color_e;
color = <want to assign first value of color_e>; //blue
…
color = <next value>; //which is green
您可以使用 all_values() 方法,该方法返回枚举类型的所有值的列表。然后,您可以根据需要使用列表。
例子:
type color : [RED, BLUE, GREEN];
extend color : [BLACK, CYAN];
extend sys {
run() is also {
var x : color;
foreach in all_values(color) {
x = it;
print x;
};
};
};
Running the test ...
x = RED
x = BLUE
x = GREEN
x = BLACK
x = CYAN
另一种可能的解决方案(除了all_values()
)是反射。给定 a rf_enum
,我们可以调用它的get_items()
方法来获取所有枚举项的列表。
但是,反射解决方案 和 之间存在一些差异,了解这些差异all_values()
很重要。一个区别是,如果某些枚举项被赋予明确的数值,不一定按升序,则将按all_values()
升序返回值,但rf_enum.get_items()
将按声明的顺序返回项。例如,如果我们有:
type foo: [A=5, B, C=1, D];
然后all_values(foo)
将返回 C、D、A、B(按此顺序 - 根据各自的数值 1、2、5、6),但rf_manager.get_type_by_name("foo").as_a(rf_enum).get_items()
将返回 A、B、C、D。如果要获得排序的反射结果通过数值,您可以执行例如rf_manager.get_type_by_name("foo").as_a(rf_enum).get_items().sort(it.get_value())
.
另一个区别是,当我们有多个基于彼此的枚举类型,具有不同的生成子范围时,all_values()
对于特定类型,将仅返回属于该类型生成范围的值,但rf_enum.get_items()
将返回所有项目。例如:
type t1: [A, B, C, D];
type t2: t1[A..B];
type t3: t2;
extend t2: [E];
在此示例中,rf_enum.get_items()
将为 t1、t2 或 t3 中的任何一个返回 A、B、C、D、E。但是all_values()
会根据每种类型的生成范围给出不同的结果。all_values(t1)
将返回 A、B、C、D;all_values(t2)
将返回 A、B、E;并将all_values(t3)
返回 A,B。
我得到了以下反射解决方案,但如果有更简单的方法,我会更胜一筹。
<'
----------------------------------------------------------------------
-- Define an enumerated type and populate
----------------------------------------------------------------------
type color_e : [blue, green, red, yellow, orange];
----------------------------------------------------------------------
-- Extend sys
----------------------------------------------------------------------
extend sys {
----------------------------------------------------------------------
-- Use the reflection facility to get the number of labels in an
-- enumerated type
----------------------------------------------------------------------
get_num_labels(enum_item: string) : int is {
var size : int; -- number of labels defined in the enumerated type
-- Find the type if defined
for each (t) in rf_manager.get_user_types() {
if t is a rf_enum and t.get_name() == enum_item {
-- return the size of the list
result = t.as_a(rf_enum).get_items().size();
}; // if t is a rf_en...
}; // for each (t) in...
}; // get_num_labels( ...
----------------------------------------------------------------------
-- Use the reflection facility to return the value of the
-- label defined in an enumerated type at a particular index
----------------------------------------------------------------------
get_enum_label_value(enum_item: string, idx: int) : int is {
var size : int; -- number of labels defined in the enumerated type
-- Find the type if defined
for each (t) in rf_manager.get_user_types() {
if t is a rf_enum and t.get_name() == enum_item {
-- get the size of the list
size = get_num_labels(enum_item);
-- return the value of the item in the list at the specified index if legal
if (idx < size) {
result = t.as_a(rf_enum).get_items()[idx].get_value();
} else {
dut_errorf("Index requested is greater than the number of labels in the enumerated type %s\n",enum_item);
};
}; // if t is a rf_en...
}; // for each (t) in...
}; // get_enum_label_value( ...
----------------------------------------------------------------------
-- Extend the run phase
----------------------------------------------------------------------
run() is also {
var color : color_e;
var size : int;
size = get_num_labels("color_e");
messagef (NONE, "Enumerated type color_e has %d labels, and they are...\n", size);
for i from 0 to (size-1) {
color = get_enum_label_value("color_e",i).as_a(color_e);
messagef (NONE, "%s\n", color);
}; -- for
}; // run is also
}; // extend sys
'>